+++ /dev/null
-diff -Nru libxml2-2.3.0/HTMLparser.c libxml2-2.3.0.new/HTMLparser.c
---- libxml2-2.3.0/HTMLparser.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/HTMLparser.c Thu Jan 1 01:00:00 1970
-@@ -1,4966 +0,0 @@
--/*
-- * HTMLparser.c : an HTML 4.0 non-verifying parser
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_HTML_ENABLED
--#include <stdio.h>
--#include <string.h>
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_SYS_STAT_H
--#include <sys/stat.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_ZLIB_H
--#include <zlib.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/parserInternals.h>
--#include <libxml/xmlerror.h>
--#include <libxml/HTMLparser.h>
--#include <libxml/entities.h>
--#include <libxml/encoding.h>
--#include <libxml/valid.h>
--#include <libxml/xmlIO.h>
--
--#define HTML_MAX_NAMELEN 1000
--#define HTML_PARSER_BIG_BUFFER_SIZE 1000
--#define HTML_PARSER_BUFFER_SIZE 100
--
--/* #define DEBUG */
--/* #define DEBUG_PUSH */
--
--int htmlOmittedDefaultValue = 1;
--
--/************************************************************************
-- * *
-- * Parser stacks related functions and macros *
-- * *
-- ************************************************************************/
--
--/*
-- * Generic function for accessing stacks in the Parser Context
-- */
--
--#define PUSH_AND_POP(scope, type, name) \
--scope int html##name##Push(htmlParserCtxtPtr ctxt, type value) { \
-- if (ctxt->name##Nr >= ctxt->name##Max) { \
-- ctxt->name##Max *= 2; \
-- ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-- ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-- if (ctxt->name##Tab == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "realloc failed !\n"); \
-- return(0); \
-- } \
-- } \
-- ctxt->name##Tab[ctxt->name##Nr] = value; \
-- ctxt->name = value; \
-- return(ctxt->name##Nr++); \
--} \
--scope type html##name##Pop(htmlParserCtxtPtr ctxt) { \
-- type ret; \
-- if (ctxt->name##Nr < 0) return(0); \
-- ctxt->name##Nr--; \
-- if (ctxt->name##Nr < 0) return(0); \
-- if (ctxt->name##Nr > 0) \
-- ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-- else \
-- ctxt->name = NULL; \
-- ret = ctxt->name##Tab[ctxt->name##Nr]; \
-- ctxt->name##Tab[ctxt->name##Nr] = 0; \
-- return(ret); \
--} \
--
--PUSH_AND_POP(extern, xmlNodePtr, node)
--PUSH_AND_POP(extern, xmlChar*, name)
--
--/*
-- * Macros for accessing the content. Those should be used only by the parser,
-- * and not exported.
-- *
-- * Dirty macros, i.e. one need to make assumption on the context to use them
-- *
-- * CUR_PTR return the current pointer to the xmlChar to be parsed.
-- * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
-- * in ISO-Latin or UTF-8, and the current 16 bit value if compiled
-- * in UNICODE mode. This should be used internally by the parser
-- * only to compare to ASCII values otherwise it would break when
-- * running with UTF-8 encoding.
-- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-- * to compare on ASCII based substring.
-- * UPP(n) returns the n'th next xmlChar converted to uppercase. Same as CUR
-- * it should be used only to compare on ASCII based substring.
-- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-- * strings within the parser.
-- *
-- * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
-- *
-- * CURRENT Returns the current char value, with the full decoding of
-- * UTF-8 if we are using this mode. It returns an int.
-- * NEXT Skip to the next character, this does the proper decoding
-- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-- * COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
-- */
--
--#define UPPER (toupper(*ctxt->input->cur))
--
--#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val)
--
--#define NXT(val) ctxt->input->cur[(val)]
--
--#define UPP(val) (toupper(ctxt->input->cur[(val)]))
--
--#define CUR_PTR ctxt->input->cur
--
--#define SHRINK xmlParserInputShrink(ctxt->input)
--
--#define GROW xmlParserInputGrow(ctxt->input, INPUT_CHUNK)
--
--#define CURRENT ((int) (*ctxt->input->cur))
--
--#define SKIP_BLANKS htmlSkipBlankChars(ctxt)
--
--/* Inported from XML */
--
--/* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
--#define CUR ((int) (*ctxt->input->cur))
--#define NEXT xmlNextChar(ctxt),ctxt->nbChars++
--
--#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
--#define NXT(val) ctxt->input->cur[(val)]
--#define CUR_PTR ctxt->input->cur
--
--
--#define NEXTL(l) do { \
-- if (*(ctxt->input->cur) == '\n') { \
-- ctxt->input->line++; ctxt->input->col = 1; \
-- } else ctxt->input->col++; \
-- ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \
-- } while (0)
--
--/************
-- \
-- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
-- if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
-- ************/
--
--#define CUR_CHAR(l) htmlCurrentChar(ctxt, &l)
--#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
--
--#define COPY_BUF(l,b,i,v) \
-- if (l == 1) b[i++] = (xmlChar) v; \
-- else i += xmlCopyChar(l,&b[i],v)
--
--/**
-- * htmlCurrentChar:
-- * @ctxt: the HTML parser context
-- * @len: pointer to the length of the char read
-- *
-- * The current char value, if using UTF-8 this may actaully span multiple
-- * bytes in the input buffer. Implement the end of line normalization:
-- * 2.11 End-of-Line Handling
-- * If the encoding is unspecified, in the case we find an ISO-Latin-1
-- * char, then the encoding converter is plugged in automatically.
-- *
-- * Returns the current char value and its lenght
-- */
--
--int
--htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
-- if (ctxt->instate == XML_PARSER_EOF)
-- return(0);
--
-- if (ctxt->token != 0) {
-- *len = 0;
-- return(ctxt->token);
-- }
-- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-- /*
-- * We are supposed to handle UTF8, check it's valid
-- * From rfc2044: encoding of the Unicode values on UTF-8:
-- *
-- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-- * 0000 0000-0000 007F 0xxxxxxx
-- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- *
-- * Check for the 0x110000 limit too
-- */
-- const unsigned char *cur = ctxt->input->cur;
-- unsigned char c;
-- unsigned int val;
--
-- c = *cur;
-- if (c & 0x80) {
-- if (cur[1] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if ((cur[1] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xe0) == 0xe0) {
--
-- if (cur[2] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if ((cur[2] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xf0) == 0xf0) {
-- if (cur[3] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if (((c & 0xf8) != 0xf0) ||
-- ((cur[3] & 0xc0) != 0x80))
-- goto encoding_error;
-- /* 4-byte code */
-- *len = 4;
-- val = (cur[0] & 0x7) << 18;
-- val |= (cur[1] & 0x3f) << 12;
-- val |= (cur[2] & 0x3f) << 6;
-- val |= cur[3] & 0x3f;
-- } else {
-- /* 3-byte code */
-- *len = 3;
-- val = (cur[0] & 0xf) << 12;
-- val |= (cur[1] & 0x3f) << 6;
-- val |= cur[2] & 0x3f;
-- }
-- } else {
-- /* 2-byte code */
-- *len = 2;
-- val = (cur[0] & 0x1f) << 6;
-- val |= cur[1] & 0x3f;
-- }
-- if (!IS_CHAR(val)) {
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Char 0x%X out of allowed range\n", val);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(val);
-- } else {
-- /* 1-byte code */
-- *len = 1;
-- return((int) *ctxt->input->cur);
-- }
-- }
-- /*
-- * Assume it's a fixed lenght encoding (1) with
-- * a compatibke encoding for the ASCII set, since
-- * XML constructs only use < 128 chars
-- */
-- *len = 1;
-- if ((int) *ctxt->input->cur < 0x80)
-- return((int) *ctxt->input->cur);
--
-- /*
-- * Humm this is bad, do an automatic flow conversion
-- */
-- xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- return(xmlCurrentChar(ctxt, len));
--
--encoding_error:
-- /*
-- * If we detect an UTF8 error that probably mean that the
-- * input encoding didn't get properly advertized in the
-- * declaration header. Report the error and switch the encoding
-- * to ISO-Latin-1 (if you don't like this policy, just declare the
-- * encoding !)
-- */
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-- ctxt->sax->error(ctxt->userData,
-- "Input is not proper UTF-8, indicate encoding !\n");
-- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- ctxt->input->cur[0], ctxt->input->cur[1],
-- ctxt->input->cur[2], ctxt->input->cur[3]);
-- }
--
-- ctxt->charset = XML_CHAR_ENCODING_8859_1;
-- *len = 1;
-- return((int) *ctxt->input->cur);
--}
--
--/**
-- * htmlNextChar:
-- * @ctxt: the HTML parser context
-- *
-- * Skip to the next char input char.
-- */
--
--void
--htmlNextChar(htmlParserCtxtPtr ctxt) {
-- if (ctxt->instate == XML_PARSER_EOF)
-- return;
-- if ((*ctxt->input->cur == 0) &&
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
-- xmlPopInput(ctxt);
-- } else {
-- if (*(ctxt->input->cur) == '\n') {
-- ctxt->input->line++; ctxt->input->col = 1;
-- } else ctxt->input->col++;
-- ctxt->input->cur++;
-- ctxt->nbChars++;
-- if (*ctxt->input->cur == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- }
--}
--
--/**
-- * htmlSkipBlankChars:
-- * @ctxt: the HTML parser context
-- *
-- * skip all blanks character found at that point in the input streams.
-- *
-- * Returns the number of space chars skipped
-- */
--
--int
--htmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
-- int res = 0;
--
-- while (IS_BLANK(*(ctxt->input->cur))) {
-- if ((*ctxt->input->cur == 0) &&
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
-- xmlPopInput(ctxt);
-- } else {
-- if (*(ctxt->input->cur) == '\n') {
-- ctxt->input->line++; ctxt->input->col = 1;
-- } else ctxt->input->col++;
-- ctxt->input->cur++;
-- ctxt->nbChars++;
-- if (*ctxt->input->cur == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- }
-- res++;
-- }
-- return(res);
--}
--
--
--
--/************************************************************************
-- * *
-- * The list of HTML elements and their properties *
-- * *
-- ************************************************************************/
--
--/*
-- * Start Tag: 1 means the start tag can be ommited
-- * End Tag: 1 means the end tag can be ommited
-- * 2 means it's forbidden (empty elements)
-- * Depr: this element is deprecated
-- * DTD: 1 means that this element is valid only in the Loose DTD
-- * 2 means that this element is valid only in the Frameset DTD
-- *
-- * Name,Start Tag,End Tag, Empty, Depr., DTD, Description
-- */
--htmlElemDesc html40ElementTable[] = {
--{ "a", 0, 0, 0, 0, 0, "anchor " },
--{ "abbr", 0, 0, 0, 0, 0, "abbreviated form" },
--{ "acronym", 0, 0, 0, 0, 0, "" },
--{ "address", 0, 0, 0, 0, 0, "information on author " },
--{ "applet", 0, 0, 0, 1, 1, "java applet " },
--{ "area", 0, 2, 1, 0, 0, "client-side image map area " },
--{ "b", 0, 0, 0, 0, 0, "bold text style" },
--{ "base", 0, 2, 1, 0, 0, "document base uri " },
--{ "basefont", 0, 2, 1, 1, 1, "base font size " },
--{ "bdo", 0, 0, 0, 0, 0, "i18n bidi over-ride " },
--{ "big", 0, 0, 0, 0, 0, "large text style" },
--{ "blockquote", 0, 0, 0, 0, 0, "long quotation " },
--{ "body", 1, 1, 0, 0, 0, "document body " },
--{ "br", 0, 2, 1, 0, 0, "forced line break " },
--{ "button", 0, 0, 0, 0, 0, "push button " },
--{ "caption", 0, 0, 0, 0, 0, "table caption " },
--{ "center", 0, 0, 0, 1, 1, "shorthand for div align=center " },
--{ "cite", 0, 0, 0, 0, 0, "citation" },
--{ "code", 0, 0, 0, 0, 0, "computer code fragment" },
--{ "col", 0, 2, 1, 0, 0, "table column " },
--{ "colgroup", 0, 1, 0, 0, 0, "table column group " },
--{ "dd", 0, 1, 0, 0, 0, "definition description " },
--{ "del", 0, 0, 0, 0, 0, "deleted text " },
--{ "dfn", 0, 0, 0, 0, 0, "instance definition" },
--{ "dir", 0, 0, 0, 1, 1, "directory list" },
--{ "div", 0, 0, 0, 0, 0, "generic language/style container"},
--{ "dl", 0, 0, 0, 0, 0, "definition list " },
--{ "dt", 0, 1, 0, 0, 0, "definition term " },
--{ "em", 0, 0, 0, 0, 0, "emphasis" },
--{ "fieldset", 0, 0, 0, 0, 0, "form control group " },
--{ "font", 0, 0, 0, 1, 1, "local change to font " },
--{ "form", 0, 0, 0, 0, 0, "interactive form " },
--{ "frame", 0, 2, 1, 0, 2, "subwindow " },
--{ "frameset", 0, 0, 0, 0, 2, "window subdivision" },
--{ "h1", 0, 0, 0, 0, 0, "heading " },
--{ "h2", 0, 0, 0, 0, 0, "heading " },
--{ "h3", 0, 0, 0, 0, 0, "heading " },
--{ "h4", 0, 0, 0, 0, 0, "heading " },
--{ "h5", 0, 0, 0, 0, 0, "heading " },
--{ "h6", 0, 0, 0, 0, 0, "heading " },
--{ "head", 1, 1, 0, 0, 0, "document head " },
--{ "hr", 0, 2, 1, 0, 0, "horizontal rule " },
--{ "html", 1, 1, 0, 0, 0, "document root element " },
--{ "i", 0, 0, 0, 0, 0, "italic text style" },
--{ "iframe", 0, 0, 0, 0, 1, "inline subwindow " },
--{ "img", 0, 2, 1, 0, 0, "embedded image " },
--{ "input", 0, 2, 1, 0, 0, "form control " },
--{ "ins", 0, 0, 0, 0, 0, "inserted text" },
--{ "isindex", 0, 2, 1, 1, 1, "single line prompt " },
--{ "kbd", 0, 0, 0, 0, 0, "text to be entered by the user" },
--{ "label", 0, 0, 0, 0, 0, "form field label text " },
--{ "legend", 0, 0, 0, 0, 0, "fieldset legend " },
--{ "li", 0, 1, 0, 0, 0, "list item " },
--{ "link", 0, 2, 1, 0, 0, "a media-independent link " },
--{ "map", 0, 0, 0, 0, 0, "client-side image map " },
--{ "menu", 0, 0, 0, 1, 1, "menu list " },
--{ "meta", 0, 2, 1, 0, 0, "generic metainformation " },
--{ "noframes", 0, 0, 0, 0, 2, "alternate content container for non frame-based rendering " },
--{ "noscript", 0, 0, 0, 0, 0, "alternate content container for non script-based rendering " },
--{ "object", 0, 0, 0, 0, 0, "generic embedded object " },
--{ "ol", 0, 0, 0, 0, 0, "ordered list " },
--{ "optgroup", 0, 0, 0, 0, 0, "option group " },
--{ "option", 0, 1, 0, 0, 0, "selectable choice " },
--{ "p", 0, 1, 0, 0, 0, "paragraph " },
--{ "param", 0, 2, 1, 0, 0, "named property value " },
--{ "pre", 0, 0, 0, 0, 0, "preformatted text " },
--{ "q", 0, 0, 0, 0, 0, "short inline quotation " },
--{ "s", 0, 0, 0, 1, 1, "strike-through text style" },
--{ "samp", 0, 0, 0, 0, 0, "sample program output, scripts, etc." },
--{ "script", 0, 0, 0, 0, 0, "script statements " },
--{ "select", 0, 0, 0, 0, 0, "option selector " },
--{ "small", 0, 0, 0, 0, 0, "small text style" },
--{ "span", 0, 0, 0, 0, 0, "generic language/style container " },
--{ "strike", 0, 0, 0, 1, 1, "strike-through text" },
--{ "strong", 0, 0, 0, 0, 0, "strong emphasis" },
--{ "style", 0, 0, 0, 0, 0, "style info " },
--{ "sub", 0, 0, 0, 0, 0, "subscript" },
--{ "sup", 0, 0, 0, 0, 0, "superscript " },
--{ "table", 0, 0, 0, 0, 0, " " },
--{ "tbody", 1, 1, 0, 0, 0, "table body " },
--{ "td", 0, 1, 0, 0, 0, "table data cell" },
--{ "textarea", 0, 0, 0, 0, 0, "multi-line text field " },
--{ "tfoot", 0, 1, 0, 0, 0, "table footer " },
--{ "th", 0, 1, 0, 0, 0, "table header cell" },
--{ "thead", 0, 1, 0, 0, 0, "table header " },
--{ "title", 0, 0, 0, 0, 0, "document title " },
--{ "tr", 0, 1, 0, 0, 0, "table row " },
--{ "tt", 0, 0, 0, 0, 0, "teletype or monospaced text style" },
--{ "u", 0, 0, 0, 1, 1, "underlined text style" },
--{ "ul", 0, 0, 0, 0, 0, "unordered list " },
--{ "var", 0, 0, 0, 0, 0, "instance of a variable or program argument" },
--};
--
--/*
-- * start tags that imply the end of a current element
-- * any tag of each line implies the end of the current element if the type of
-- * that element is in the same line
-- */
--char *htmlEquEnd[] = {
--"dt", "dd", "li", "option", NULL,
--"h1", "h2", "h3", "h4", "h5", "h6", NULL,
--"ol", "menu", "dir", "address", "pre", "listing", "xmp", NULL,
--NULL
--};
--/*
-- * acording the HTML DTD, HR should be added to the 2nd line above, as it
-- * is not allowed within a H1, H2, H3, etc. But we should tolerate that case
-- * because many documents contain rules in headings...
-- */
--
--/*
-- * start tags that imply the end of current element
-- */
--char *htmlStartClose[] = {
--"form", "form", "p", "hr", "h1", "h2", "h3", "h4", "h5", "h6",
-- "dl", "ul", "ol", "menu", "dir", "address", "pre",
-- "listing", "xmp", "head", NULL,
--"head", "p", NULL,
--"title", "p", NULL,
--"body", "head", "style", "link", "title", "p", NULL,
--"li", "p", "h1", "h2", "h3", "h4", "h5", "h6", "dl", "address",
-- "pre", "listing", "xmp", "head", "li", NULL,
--"hr", "p", "head", NULL,
--"h1", "p", "head", NULL,
--"h2", "p", "head", NULL,
--"h3", "p", "head", NULL,
--"h4", "p", "head", NULL,
--"h5", "p", "head", NULL,
--"h6", "p", "head", NULL,
--"dir", "p", "head", NULL,
--"address", "p", "head", "ul", NULL,
--"pre", "p", "head", "ul", NULL,
--"listing", "p", "head", NULL,
--"xmp", "p", "head", NULL,
--"blockquote", "p", "head", NULL,
--"dl", "p", "dt", "menu", "dir", "address", "pre", "listing",
-- "xmp", "head", NULL,
--"dt", "p", "menu", "dir", "address", "pre", "listing", "xmp",
-- "head", "dd", NULL,
--"dd", "p", "menu", "dir", "address", "pre", "listing", "xmp",
-- "head", "dt", NULL,
--"ul", "p", "head", "ol", "menu", "dir", "address", "pre",
-- "listing", "xmp", NULL,
--"ol", "p", "head", "ul", NULL,
--"menu", "p", "head", "ul", NULL,
--"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", NULL,
--"div", "p", "head", NULL,
--"noscript", "p", "head", NULL,
--"center", "font", "b", "i", "p", "head", NULL,
--"a", "a", NULL,
--"caption", "p", NULL,
--"colgroup", "caption", "colgroup", "col", "p", NULL,
--"col", "caption", "col", "p", NULL,
--"table", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", "pre",
-- "listing", "xmp", "a", NULL,
--"th", "th", "td", NULL,
--"td", "th", "td", "p", NULL,
--"tr", "th", "td", "tr", "caption", "col", "colgroup", "p", NULL,
--"thead", "caption", "col", "colgroup", NULL,
--"tfoot", "th", "td", "tr", "caption", "col", "colgroup", "thead",
-- "tbody", "p", NULL,
--"tbody", "th", "td", "tr", "caption", "col", "colgroup", "thead",
-- "tfoot", "tbody", "p", NULL,
--"optgroup", "option", NULL,
--"option", "option", NULL,
--"fieldset", "legend", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6",
-- "pre", "listing", "xmp", "a", NULL,
--NULL
--};
--
--/*
-- * The list of HTML elements which are supposed not to have
-- * CDATA content and where a p element will be implied
-- *
-- * TODO: extend that list by reading the HTML SGML DtD on
-- * implied paragraph
-- */
--static char *htmlNoContentElements[] = {
-- "html",
-- "head",
-- "body",
-- NULL
--};
--
--/*
-- * The list of HTML attributes which are of content %Script;
-- * NOTE: when adding ones, check htmlIsScriptAttribute() since
-- * it assumes the name starts with 'on'
-- */
--static char *htmlScriptAttributes[] = {
-- "onclick",
-- "ondblclick",
-- "onmousedown",
-- "onmouseup",
-- "onmouseover",
-- "onmousemove",
-- "onmouseout",
-- "onkeypress",
-- "onkeydown",
-- "onkeyup",
-- "onload",
-- "onunload",
-- "onfocus",
-- "onblur",
-- "onsubmit",
-- "onrest",
-- "onchange",
-- "onselect"
--};
--
--
--static char** htmlStartCloseIndex[100];
--static int htmlStartCloseIndexinitialized = 0;
--
--/************************************************************************
-- * *
-- * functions to handle HTML specific data *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlInitAutoClose:
-- *
-- * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
-- * This is not reentrant. Call xmlInitParser() once before processing in
-- * case of use in multithreaded programs.
-- */
--void
--htmlInitAutoClose(void) {
-- int index, i = 0;
--
-- if (htmlStartCloseIndexinitialized) return;
--
-- for (index = 0;index < 100;index ++) htmlStartCloseIndex[index] = NULL;
-- index = 0;
-- while ((htmlStartClose[i] != NULL) && (index < 100 - 1)) {
-- htmlStartCloseIndex[index++] = &htmlStartClose[i];
-- while (htmlStartClose[i] != NULL) i++;
-- i++;
-- }
-- htmlStartCloseIndexinitialized = 1;
--}
--
--/**
-- * htmlTagLookup:
-- * @tag: The tag name in lowercase
-- *
-- * Lookup the HTML tag in the ElementTable
-- *
-- * Returns the related htmlElemDescPtr or NULL if not found.
-- */
--htmlElemDescPtr
--htmlTagLookup(const xmlChar *tag) {
-- int i;
--
-- for (i = 0; i < (sizeof(html40ElementTable) /
-- sizeof(html40ElementTable[0]));i++) {
-- if (xmlStrEqual(tag, BAD_CAST html40ElementTable[i].name))
-- return(&html40ElementTable[i]);
-- }
-- return(NULL);
--}
--
--/**
-- * htmlCheckAutoClose:
-- * @newtag: The new tag name
-- * @oldtag: The old tag name
-- *
-- * Checks wether the new tag is one of the registered valid tags for closing old.
-- * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
-- *
-- * Returns 0 if no, 1 if yes.
-- */
--int
--htmlCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
-- int i, index;
-- char **close = NULL;
--
-- if (htmlStartCloseIndexinitialized == 0) htmlInitAutoClose();
--
-- /* inefficient, but not a big deal */
-- for (index = 0; index < 100;index++) {
-- close = htmlStartCloseIndex[index];
-- if (close == NULL) return(0);
-- if (xmlStrEqual(BAD_CAST *close, newtag)) break;
-- }
--
-- i = close - htmlStartClose;
-- i++;
-- while (htmlStartClose[i] != NULL) {
-- if (xmlStrEqual(BAD_CAST htmlStartClose[i], oldtag)) {
-- return(1);
-- }
-- i++;
-- }
-- return(0);
--}
--
--/**
-- * htmlAutoCloseOnClose:
-- * @ctxt: an HTML parser context
-- * @newtag: The new tag name
-- *
-- * The HTmL DtD allows an ending tag to implicitely close other tags.
-- */
--void
--htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
-- htmlElemDescPtr info;
-- xmlChar *oldname;
-- int i;
--
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Close of %s stack: %d elements\n", newtag, ctxt->nameNr);
-- for (i = 0;i < ctxt->nameNr;i++)
-- xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
--#endif
--
-- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
-- if (xmlStrEqual(newtag, ctxt->nameTab[i])) break;
-- }
-- if (i < 0) return;
--
-- while (!xmlStrEqual(newtag, ctxt->name)) {
-- info = htmlTagLookup(ctxt->name);
-- if ((info == NULL) || (info->endTag == 1)) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: %s closes %s\n", newtag, ctxt->name);
--#endif
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Opening and ending tag mismatch: %s and %s\n",
-- newtag, ctxt->name);
-- ctxt->wellFormed = 0;
-- }
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, ctxt->name);
-- oldname = htmlnamePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- }
--}
--
--/**
-- * htmlAutoClose:
-- * @ctxt: an HTML parser context
-- * @newtag: The new tag name or NULL
-- *
-- * The HTmL DtD allows a tag to implicitely close other tags.
-- * The list is kept in htmlStartClose array. This function is
-- * called when a new tag has been detected and generates the
-- * appropriates closes if possible/needed.
-- * If newtag is NULL this mean we are at the end of the resource
-- * and we should check
-- */
--void
--htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
-- xmlChar *oldname;
-- while ((newtag != NULL) && (ctxt->name != NULL) &&
-- (htmlCheckAutoClose(newtag, ctxt->name))) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: %s closes %s\n", newtag, ctxt->name);
--#endif
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, ctxt->name);
-- oldname = htmlnamePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- }
-- if (newtag == NULL) {
-- htmlAutoCloseOnClose(ctxt, BAD_CAST"head");
-- htmlAutoCloseOnClose(ctxt, BAD_CAST"body");
-- htmlAutoCloseOnClose(ctxt, BAD_CAST"html");
-- }
-- while ((newtag == NULL) && (ctxt->name != NULL) &&
-- ((xmlStrEqual(ctxt->name, BAD_CAST"head")) ||
-- (xmlStrEqual(ctxt->name, BAD_CAST"body")) ||
-- (xmlStrEqual(ctxt->name, BAD_CAST"html")))) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: EOF closes %s\n", ctxt->name);
--#endif
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, ctxt->name);
-- oldname = htmlnamePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- }
--
--}
--
--/**
-- * htmlAutoCloseTag:
-- * @doc: the HTML document
-- * @name: The tag name
-- * @elem: the HTML element
-- *
-- * The HTmL DtD allows a tag to implicitely close other tags.
-- * The list is kept in htmlStartClose array. This function checks
-- * if the element or one of it's children would autoclose the
-- * given tag.
-- *
-- * Returns 1 if autoclose, 0 otherwise
-- */
--int
--htmlAutoCloseTag(htmlDocPtr doc, const xmlChar *name, htmlNodePtr elem) {
-- htmlNodePtr child;
--
-- if (elem == NULL) return(1);
-- if (xmlStrEqual(name, elem->name)) return(0);
-- if (htmlCheckAutoClose(elem->name, name)) return(1);
-- child = elem->children;
-- while (child != NULL) {
-- if (htmlAutoCloseTag(doc, name, child)) return(1);
-- child = child->next;
-- }
-- return(0);
--}
--
--/**
-- * htmlIsAutoClosed:
-- * @doc: the HTML document
-- * @elem: the HTML element
-- *
-- * The HTmL DtD allows a tag to implicitely close other tags.
-- * The list is kept in htmlStartClose array. This function checks
-- * if a tag is autoclosed by one of it's child
-- *
-- * Returns 1 if autoclosed, 0 otherwise
-- */
--int
--htmlIsAutoClosed(htmlDocPtr doc, htmlNodePtr elem) {
-- htmlNodePtr child;
--
-- if (elem == NULL) return(1);
-- child = elem->children;
-- while (child != NULL) {
-- if (htmlAutoCloseTag(doc, elem->name, child)) return(1);
-- child = child->next;
-- }
-- return(0);
--}
--
--/**
-- * htmlCheckImplied:
-- * @ctxt: an HTML parser context
-- * @newtag: The new tag name
-- *
-- * The HTML DtD allows a tag to exists only implicitely
-- * called when a new tag has been detected and generates the
-- * appropriates implicit tags if missing
-- */
--void
--htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
-- if (!htmlOmittedDefaultValue)
-- return;
-- if (xmlStrEqual(newtag, BAD_CAST"html"))
-- return;
-- if (ctxt->nameNr <= 0) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Implied element html: pushed html\n");
--#endif
-- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"html"));
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-- ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
-- }
-- if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
-- return;
-- if ((ctxt->nameNr <= 1) &&
-- ((xmlStrEqual(newtag, BAD_CAST"script")) ||
-- (xmlStrEqual(newtag, BAD_CAST"style")) ||
-- (xmlStrEqual(newtag, BAD_CAST"meta")) ||
-- (xmlStrEqual(newtag, BAD_CAST"link")) ||
-- (xmlStrEqual(newtag, BAD_CAST"title")) ||
-- (xmlStrEqual(newtag, BAD_CAST"base")))) {
-- /*
-- * dropped OBJECT ... i you put it first BODY will be
-- * assumed !
-- */
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Implied element head: pushed head\n");
--#endif
-- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"head"));
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-- ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
-- } else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
-- (!xmlStrEqual(newtag, BAD_CAST"frame")) &&
-- (!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
-- int i;
-- for (i = 0;i < ctxt->nameNr;i++) {
-- if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
-- return;
-- }
-- if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"head")) {
-- return;
-- }
-- }
--
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Implied element body: pushed body\n");
--#endif
-- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-- ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
-- }
--}
--
--/**
-- * htmlCheckParagraph
-- * @ctxt: an HTML parser context
-- *
-- * Check whether a p element need to be implied before inserting
-- * characters in the current element.
-- *
-- * Returns 1 if a paragraph has been inserted, 0 if not and -1
-- * in case of error.
-- */
--
--int
--htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
-- const xmlChar *tag;
-- int i;
--
-- if (ctxt == NULL)
-- return(-1);
-- tag = ctxt->name;
-- if (tag == NULL) {
-- htmlAutoClose(ctxt, BAD_CAST"p");
-- htmlCheckImplied(ctxt, BAD_CAST"p");
-- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-- ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
-- return(1);
-- }
-- if (!htmlOmittedDefaultValue)
-- return(0);
-- for (i = 0; htmlNoContentElements[i] != NULL; i++) {
-- if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Implied element paragraph\n");
--#endif
-- htmlAutoClose(ctxt, BAD_CAST"p");
-- htmlCheckImplied(ctxt, BAD_CAST"p");
-- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-- ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
-- return(1);
-- }
-- }
-- return(0);
--}
--
--/**
-- * htmlIsScriptAttribute:
-- * @name: an attribute name
-- *
-- * Check if an attribute is of content type Script
-- *
-- * Returns 1 is the attribute is a script 0 otherwise
-- */
--int
--htmlIsScriptAttribute(const xmlChar *name) {
-- int i;
--
-- if (name == NULL)
-- return(0);
-- /*
-- * all script attributes start with 'on'
-- */
-- if ((name[0] != 'o') || (name[1] != 'n'))
-- return(0);
-- for (i = 0;
-- i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
-- i++) {
-- if (xmlStrEqual(name, (const xmlChar *) htmlScriptAttributes[i]))
-- return(1);
-- }
-- return(0);
--}
--
--/************************************************************************
-- * *
-- * The list of HTML predefined entities *
-- * *
-- ************************************************************************/
--
--
--htmlEntityDesc html40EntitiesTable[] = {
--/*
-- * the 4 absolute ones, plus apostrophe.
-- */
--{ 34, "quot", "quotation mark = APL quote, U+0022 ISOnum" },
--{ 38, "amp", "ampersand, U+0026 ISOnum" },
--{ 39, "apos", "single quote" },
--{ 60, "lt", "less-than sign, U+003C ISOnum" },
--{ 62, "gt", "greater-than sign, U+003E ISOnum" },
--
--/*
-- * A bunch still in the 128-255 range
-- * Replacing them depend really on the charset used.
-- */
--{ 160, "nbsp", "no-break space = non-breaking space, U+00A0 ISOnum" },
--{ 161, "iexcl","inverted exclamation mark, U+00A1 ISOnum" },
--{ 162, "cent", "cent sign, U+00A2 ISOnum" },
--{ 163, "pound","pound sign, U+00A3 ISOnum" },
--{ 164, "curren","currency sign, U+00A4 ISOnum" },
--{ 165, "yen", "yen sign = yuan sign, U+00A5 ISOnum" },
--{ 166, "brvbar","broken bar = broken vertical bar, U+00A6 ISOnum" },
--{ 167, "sect", "section sign, U+00A7 ISOnum" },
--{ 168, "uml", "diaeresis = spacing diaeresis, U+00A8 ISOdia" },
--{ 169, "copy", "copyright sign, U+00A9 ISOnum" },
--{ 170, "ordf", "feminine ordinal indicator, U+00AA ISOnum" },
--{ 171, "laquo","left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum" },
--{ 172, "not", "not sign, U+00AC ISOnum" },
--{ 173, "shy", "soft hyphen = discretionary hyphen, U+00AD ISOnum" },
--{ 174, "reg", "registered sign = registered trade mark sign, U+00AE ISOnum" },
--{ 175, "macr", "macron = spacing macron = overline = APL overbar, U+00AF ISOdia" },
--{ 176, "deg", "degree sign, U+00B0 ISOnum" },
--{ 177, "plusmn","plus-minus sign = plus-or-minus sign, U+00B1 ISOnum" },
--{ 178, "sup2", "superscript two = superscript digit two = squared, U+00B2 ISOnum" },
--{ 179, "sup3", "superscript three = superscript digit three = cubed, U+00B3 ISOnum" },
--{ 180, "acute","acute accent = spacing acute, U+00B4 ISOdia" },
--{ 181, "micro","micro sign, U+00B5 ISOnum" },
--{ 182, "para", "pilcrow sign = paragraph sign, U+00B6 ISOnum" },
--{ 183, "middot","middle dot = Georgian comma Greek middle dot, U+00B7 ISOnum" },
--{ 184, "cedil","cedilla = spacing cedilla, U+00B8 ISOdia" },
--{ 185, "sup1", "superscript one = superscript digit one, U+00B9 ISOnum" },
--{ 186, "ordm", "masculine ordinal indicator, U+00BA ISOnum" },
--{ 187, "raquo","right-pointing double angle quotation mark right pointing guillemet, U+00BB ISOnum" },
--{ 188, "frac14","vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum" },
--{ 189, "frac12","vulgar fraction one half = fraction one half, U+00BD ISOnum" },
--{ 190, "frac34","vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum" },
--{ 191, "iquest","inverted question mark = turned question mark, U+00BF ISOnum" },
--{ 192, "Agrave","latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1" },
--{ 193, "Aacute","latin capital letter A with acute, U+00C1 ISOlat1" },
--{ 194, "Acirc","latin capital letter A with circumflex, U+00C2 ISOlat1" },
--{ 195, "Atilde","latin capital letter A with tilde, U+00C3 ISOlat1" },
--{ 196, "Auml", "latin capital letter A with diaeresis, U+00C4 ISOlat1" },
--{ 197, "Aring","latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1" },
--{ 198, "AElig","latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1" },
--{ 199, "Ccedil","latin capital letter C with cedilla, U+00C7 ISOlat1" },
--{ 200, "Egrave","latin capital letter E with grave, U+00C8 ISOlat1" },
--{ 201, "Eacute","latin capital letter E with acute, U+00C9 ISOlat1" },
--{ 202, "Ecirc","latin capital letter E with circumflex, U+00CA ISOlat1" },
--{ 203, "Euml", "latin capital letter E with diaeresis, U+00CB ISOlat1" },
--{ 204, "Igrave","latin capital letter I with grave, U+00CC ISOlat1" },
--{ 205, "Iacute","latin capital letter I with acute, U+00CD ISOlat1" },
--{ 206, "Icirc","latin capital letter I with circumflex, U+00CE ISOlat1" },
--{ 207, "Iuml", "latin capital letter I with diaeresis, U+00CF ISOlat1" },
--{ 208, "ETH", "latin capital letter ETH, U+00D0 ISOlat1" },
--{ 209, "Ntilde","latin capital letter N with tilde, U+00D1 ISOlat1" },
--{ 210, "Ograve","latin capital letter O with grave, U+00D2 ISOlat1" },
--{ 211, "Oacute","latin capital letter O with acute, U+00D3 ISOlat1" },
--{ 212, "Ocirc","latin capital letter O with circumflex, U+00D4 ISOlat1" },
--{ 213, "Otilde","latin capital letter O with tilde, U+00D5 ISOlat1" },
--{ 214, "Ouml", "latin capital letter O with diaeresis, U+00D6 ISOlat1" },
--{ 215, "times","multiplication sign, U+00D7 ISOnum" },
--{ 216, "Oslash","latin capital letter O with stroke latin capital letter O slash, U+00D8 ISOlat1" },
--{ 217, "Ugrave","latin capital letter U with grave, U+00D9 ISOlat1" },
--{ 218, "Uacute","latin capital letter U with acute, U+00DA ISOlat1" },
--{ 219, "Ucirc","latin capital letter U with circumflex, U+00DB ISOlat1" },
--{ 220, "Uuml", "latin capital letter U with diaeresis, U+00DC ISOlat1" },
--{ 221, "Yacute","latin capital letter Y with acute, U+00DD ISOlat1" },
--{ 222, "THORN","latin capital letter THORN, U+00DE ISOlat1" },
--{ 223, "szlig","latin small letter sharp s = ess-zed, U+00DF ISOlat1" },
--{ 224, "agrave","latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1" },
--{ 225, "aacute","latin small letter a with acute, U+00E1 ISOlat1" },
--{ 226, "acirc","latin small letter a with circumflex, U+00E2 ISOlat1" },
--{ 227, "atilde","latin small letter a with tilde, U+00E3 ISOlat1" },
--{ 228, "auml", "latin small letter a with diaeresis, U+00E4 ISOlat1" },
--{ 229, "aring","latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1" },
--{ 230, "aelig","latin small letter ae = latin small ligature ae, U+00E6 ISOlat1" },
--{ 231, "ccedil","latin small letter c with cedilla, U+00E7 ISOlat1" },
--{ 232, "egrave","latin small letter e with grave, U+00E8 ISOlat1" },
--{ 233, "eacute","latin small letter e with acute, U+00E9 ISOlat1" },
--{ 234, "ecirc","latin small letter e with circumflex, U+00EA ISOlat1" },
--{ 235, "euml", "latin small letter e with diaeresis, U+00EB ISOlat1" },
--{ 236, "igrave","latin small letter i with grave, U+00EC ISOlat1" },
--{ 237, "iacute","latin small letter i with acute, U+00ED ISOlat1" },
--{ 238, "icirc","latin small letter i with circumflex, U+00EE ISOlat1" },
--{ 239, "iuml", "latin small letter i with diaeresis, U+00EF ISOlat1" },
--{ 240, "eth", "latin small letter eth, U+00F0 ISOlat1" },
--{ 241, "ntilde","latin small letter n with tilde, U+00F1 ISOlat1" },
--{ 242, "ograve","latin small letter o with grave, U+00F2 ISOlat1" },
--{ 243, "oacute","latin small letter o with acute, U+00F3 ISOlat1" },
--{ 244, "ocirc","latin small letter o with circumflex, U+00F4 ISOlat1" },
--{ 245, "otilde","latin small letter o with tilde, U+00F5 ISOlat1" },
--{ 246, "ouml", "latin small letter o with diaeresis, U+00F6 ISOlat1" },
--{ 247, "divide","division sign, U+00F7 ISOnum" },
--{ 248, "oslash","latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1" },
--{ 249, "ugrave","latin small letter u with grave, U+00F9 ISOlat1" },
--{ 250, "uacute","latin small letter u with acute, U+00FA ISOlat1" },
--{ 251, "ucirc","latin small letter u with circumflex, U+00FB ISOlat1" },
--{ 252, "uuml", "latin small letter u with diaeresis, U+00FC ISOlat1" },
--{ 253, "yacute","latin small letter y with acute, U+00FD ISOlat1" },
--{ 254, "thorn","latin small letter thorn with, U+00FE ISOlat1" },
--{ 255, "yuml", "latin small letter y with diaeresis, U+00FF ISOlat1" },
--
--{ 338, "OElig","latin capital ligature OE, U+0152 ISOlat2" },
--{ 339, "oelig","latin small ligature oe, U+0153 ISOlat2" },
--{ 352, "Scaron","latin capital letter S with caron, U+0160 ISOlat2" },
--{ 353, "scaron","latin small letter s with caron, U+0161 ISOlat2" },
--{ 376, "Yuml", "latin capital letter Y with diaeresis, U+0178 ISOlat2" },
--
--/*
-- * Anything below should really be kept as entities references
-- */
--{ 402, "fnof", "latin small f with hook = function = florin, U+0192 ISOtech" },
--
--{ 710, "circ", "modifier letter circumflex accent, U+02C6 ISOpub" },
--{ 732, "tilde","small tilde, U+02DC ISOdia" },
--
--{ 913, "Alpha","greek capital letter alpha, U+0391" },
--{ 914, "Beta", "greek capital letter beta, U+0392" },
--{ 915, "Gamma","greek capital letter gamma, U+0393 ISOgrk3" },
--{ 916, "Delta","greek capital letter delta, U+0394 ISOgrk3" },
--{ 917, "Epsilon","greek capital letter epsilon, U+0395" },
--{ 918, "Zeta", "greek capital letter zeta, U+0396" },
--{ 919, "Eta", "greek capital letter eta, U+0397" },
--{ 920, "Theta","greek capital letter theta, U+0398 ISOgrk3" },
--{ 921, "Iota", "greek capital letter iota, U+0399" },
--{ 922, "Kappa","greek capital letter kappa, U+039A" },
--{ 923, "Lambda""greek capital letter lambda, U+039B ISOgrk3" },
--{ 924, "Mu", "greek capital letter mu, U+039C" },
--{ 925, "Nu", "greek capital letter nu, U+039D" },
--{ 926, "Xi", "greek capital letter xi, U+039E ISOgrk3" },
--{ 927, "Omicron","greek capital letter omicron, U+039F" },
--{ 928, "Pi", "greek capital letter pi, U+03A0 ISOgrk3" },
--{ 929, "Rho", "greek capital letter rho, U+03A1" },
--{ 931, "Sigma","greek capital letter sigma, U+03A3 ISOgrk3" },
--{ 932, "Tau", "greek capital letter tau, U+03A4" },
--{ 933, "Upsilon","greek capital letter upsilon, U+03A5 ISOgrk3" },
--{ 934, "Phi", "greek capital letter phi, U+03A6 ISOgrk3" },
--{ 935, "Chi", "greek capital letter chi, U+03A7" },
--{ 936, "Psi", "greek capital letter psi, U+03A8 ISOgrk3" },
--{ 937, "Omega","greek capital letter omega, U+03A9 ISOgrk3" },
--
--{ 945, "alpha","greek small letter alpha, U+03B1 ISOgrk3" },
--{ 946, "beta", "greek small letter beta, U+03B2 ISOgrk3" },
--{ 947, "gamma","greek small letter gamma, U+03B3 ISOgrk3" },
--{ 948, "delta","greek small letter delta, U+03B4 ISOgrk3" },
--{ 949, "epsilon","greek small letter epsilon, U+03B5 ISOgrk3" },
--{ 950, "zeta", "greek small letter zeta, U+03B6 ISOgrk3" },
--{ 951, "eta", "greek small letter eta, U+03B7 ISOgrk3" },
--{ 952, "theta","greek small letter theta, U+03B8 ISOgrk3" },
--{ 953, "iota", "greek small letter iota, U+03B9 ISOgrk3" },
--{ 954, "kappa","greek small letter kappa, U+03BA ISOgrk3" },
--{ 955, "lambda","greek small letter lambda, U+03BB ISOgrk3" },
--{ 956, "mu", "greek small letter mu, U+03BC ISOgrk3" },
--{ 957, "nu", "greek small letter nu, U+03BD ISOgrk3" },
--{ 958, "xi", "greek small letter xi, U+03BE ISOgrk3" },
--{ 959, "omicron","greek small letter omicron, U+03BF NEW" },
--{ 960, "pi", "greek small letter pi, U+03C0 ISOgrk3" },
--{ 961, "rho", "greek small letter rho, U+03C1 ISOgrk3" },
--{ 962, "sigmaf","greek small letter final sigma, U+03C2 ISOgrk3" },
--{ 963, "sigma","greek small letter sigma, U+03C3 ISOgrk3" },
--{ 964, "tau", "greek small letter tau, U+03C4 ISOgrk3" },
--{ 965, "upsilon","greek small letter upsilon, U+03C5 ISOgrk3" },
--{ 966, "phi", "greek small letter phi, U+03C6 ISOgrk3" },
--{ 967, "chi", "greek small letter chi, U+03C7 ISOgrk3" },
--{ 968, "psi", "greek small letter psi, U+03C8 ISOgrk3" },
--{ 969, "omega","greek small letter omega, U+03C9 ISOgrk3" },
--{ 977, "thetasym","greek small letter theta symbol, U+03D1 NEW" },
--{ 978, "upsih","greek upsilon with hook symbol, U+03D2 NEW" },
--{ 982, "piv", "greek pi symbol, U+03D6 ISOgrk3" },
--
--{ 8194, "ensp", "en space, U+2002 ISOpub" },
--{ 8195, "emsp", "em space, U+2003 ISOpub" },
--{ 8201, "thinsp","thin space, U+2009 ISOpub" },
--{ 8204, "zwnj", "zero width non-joiner, U+200C NEW RFC 2070" },
--{ 8205, "zwj", "zero width joiner, U+200D NEW RFC 2070" },
--{ 8206, "lrm", "left-to-right mark, U+200E NEW RFC 2070" },
--{ 8207, "rlm", "right-to-left mark, U+200F NEW RFC 2070" },
--{ 8211, "ndash","en dash, U+2013 ISOpub" },
--{ 8212, "mdash","em dash, U+2014 ISOpub" },
--{ 8216, "lsquo","left single quotation mark, U+2018 ISOnum" },
--{ 8217, "rsquo","right single quotation mark, U+2019 ISOnum" },
--{ 8218, "sbquo","single low-9 quotation mark, U+201A NEW" },
--{ 8220, "ldquo","left double quotation mark, U+201C ISOnum" },
--{ 8221, "rdquo","right double quotation mark, U+201D ISOnum" },
--{ 8222, "bdquo","double low-9 quotation mark, U+201E NEW" },
--{ 8224, "dagger","dagger, U+2020 ISOpub" },
--{ 8225, "Dagger","double dagger, U+2021 ISOpub" },
--
--{ 8226, "bull", "bullet = black small circle, U+2022 ISOpub" },
--{ 8230, "hellip","horizontal ellipsis = three dot leader, U+2026 ISOpub" },
--
--{ 8240, "permil","per mille sign, U+2030 ISOtech" },
--
--{ 8242, "prime","prime = minutes = feet, U+2032 ISOtech" },
--{ 8243, "Prime","double prime = seconds = inches, U+2033 ISOtech" },
--
--{ 8249, "lsaquo","single left-pointing angle quotation mark, U+2039 ISO proposed" },
--{ 8250, "rsaquo","single right-pointing angle quotation mark, U+203A ISO proposed" },
--
--{ 8254, "oline","overline = spacing overscore, U+203E NEW" },
--{ 8260, "frasl","fraction slash, U+2044 NEW" },
--
--{ 8364, "euro", "euro sign, U+20AC NEW" },
--
--{ 8465, "image","blackletter capital I = imaginary part, U+2111 ISOamso" },
--{ 8472, "weierp","script capital P = power set = Weierstrass p, U+2118 ISOamso" },
--{ 8476, "real", "blackletter capital R = real part symbol, U+211C ISOamso" },
--{ 8482, "trade","trade mark sign, U+2122 ISOnum" },
--{ 8501, "alefsym","alef symbol = first transfinite cardinal, U+2135 NEW" },
--{ 8592, "larr", "leftwards arrow, U+2190 ISOnum" },
--{ 8593, "uarr", "upwards arrow, U+2191 ISOnum" },
--{ 8594, "rarr", "rightwards arrow, U+2192 ISOnum" },
--{ 8595, "darr", "downwards arrow, U+2193 ISOnum" },
--{ 8596, "harr", "left right arrow, U+2194 ISOamsa" },
--{ 8629, "crarr","downwards arrow with corner leftwards = carriage return, U+21B5 NEW" },
--{ 8656, "lArr", "leftwards double arrow, U+21D0 ISOtech" },
--{ 8657, "uArr", "upwards double arrow, U+21D1 ISOamsa" },
--{ 8658, "rArr", "rightwards double arrow, U+21D2 ISOtech" },
--{ 8659, "dArr", "downwards double arrow, U+21D3 ISOamsa" },
--{ 8660, "hArr", "left right double arrow, U+21D4 ISOamsa" },
--
--{ 8704, "forall","for all, U+2200 ISOtech" },
--{ 8706, "part", "partial differential, U+2202 ISOtech" },
--{ 8707, "exist","there exists, U+2203 ISOtech" },
--{ 8709, "empty","empty set = null set = diameter, U+2205 ISOamso" },
--{ 8711, "nabla","nabla = backward difference, U+2207 ISOtech" },
--{ 8712, "isin", "element of, U+2208 ISOtech" },
--{ 8713, "notin","not an element of, U+2209 ISOtech" },
--{ 8715, "ni", "contains as member, U+220B ISOtech" },
--{ 8719, "prod", "n-ary product = product sign, U+220F ISOamsb" },
--{ 8721, "sum", "n-ary sumation, U+2211 ISOamsb" },
--{ 8722, "minus","minus sign, U+2212 ISOtech" },
--{ 8727, "lowast","asterisk operator, U+2217 ISOtech" },
--{ 8730, "radic","square root = radical sign, U+221A ISOtech" },
--{ 8733, "prop", "proportional to, U+221D ISOtech" },
--{ 8734, "infin","infinity, U+221E ISOtech" },
--{ 8736, "ang", "angle, U+2220 ISOamso" },
--{ 8743, "and", "logical and = wedge, U+2227 ISOtech" },
--{ 8744, "or", "logical or = vee, U+2228 ISOtech" },
--{ 8745, "cap", "intersection = cap, U+2229 ISOtech" },
--{ 8746, "cup", "union = cup, U+222A ISOtech" },
--{ 8747, "int", "integral, U+222B ISOtech" },
--{ 8756, "there4","therefore, U+2234 ISOtech" },
--{ 8764, "sim", "tilde operator = varies with = similar to, U+223C ISOtech" },
--{ 8773, "cong", "approximately equal to, U+2245 ISOtech" },
--{ 8776, "asymp","almost equal to = asymptotic to, U+2248 ISOamsr" },
--{ 8800, "ne", "not equal to, U+2260 ISOtech" },
--{ 8801, "equiv","identical to, U+2261 ISOtech" },
--{ 8804, "le", "less-than or equal to, U+2264 ISOtech" },
--{ 8805, "ge", "greater-than or equal to, U+2265 ISOtech" },
--{ 8834, "sub", "subset of, U+2282 ISOtech" },
--{ 8835, "sup", "superset of, U+2283 ISOtech" },
--{ 8836, "nsub", "not a subset of, U+2284 ISOamsn" },
--{ 8838, "sube", "subset of or equal to, U+2286 ISOtech" },
--{ 8839, "supe", "superset of or equal to, U+2287 ISOtech" },
--{ 8853, "oplus","circled plus = direct sum, U+2295 ISOamsb" },
--{ 8855, "otimes","circled times = vector product, U+2297 ISOamsb" },
--{ 8869, "perp", "up tack = orthogonal to = perpendicular, U+22A5 ISOtech" },
--{ 8901, "sdot", "dot operator, U+22C5 ISOamsb" },
--{ 8968, "lceil","left ceiling = apl upstile, U+2308 ISOamsc" },
--{ 8969, "rceil","right ceiling, U+2309 ISOamsc" },
--{ 8970, "lfloor","left floor = apl downstile, U+230A ISOamsc" },
--{ 8971, "rfloor","right floor, U+230B ISOamsc" },
--{ 9001, "lang", "left-pointing angle bracket = bra, U+2329 ISOtech" },
--{ 9002, "rang", "right-pointing angle bracket = ket, U+232A ISOtech" },
--{ 9674, "loz", "lozenge, U+25CA ISOpub" },
--
--{ 9824, "spades","black spade suit, U+2660 ISOpub" },
--{ 9827, "clubs","black club suit = shamrock, U+2663 ISOpub" },
--{ 9829, "hearts","black heart suit = valentine, U+2665 ISOpub" },
--{ 9830, "diams","black diamond suit, U+2666 ISOpub" },
--
--};
--
--/************************************************************************
-- * *
-- * Commodity functions to handle entities *
-- * *
-- ************************************************************************/
--
--/*
-- * Macro used to grow the current buffer.
-- */
--#define growBuffer(buffer) { \
-- buffer##_size *= 2; \
-- buffer = (xmlChar *) xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
-- if (buffer == NULL) { \
-- perror("realloc failed"); \
-- return(NULL); \
-- } \
--}
--
--/**
-- * htmlEntityLookup:
-- * @name: the entity name
-- *
-- * Lookup the given entity in EntitiesTable
-- *
-- * TODO: the linear scan is really ugly, an hash table is really needed.
-- *
-- * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
-- */
--htmlEntityDescPtr
--htmlEntityLookup(const xmlChar *name) {
-- int i;
--
-- for (i = 0;i < (sizeof(html40EntitiesTable)/
-- sizeof(html40EntitiesTable[0]));i++) {
-- if (xmlStrEqual(name, BAD_CAST html40EntitiesTable[i].name)) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", name);
--#endif
-- return(&html40EntitiesTable[i]);
-- }
-- }
-- return(NULL);
--}
--
--/**
-- * htmlEntityValueLookup:
-- * @value: the entity's unicode value
-- *
-- * Lookup the given entity in EntitiesTable
-- *
-- * TODO: the linear scan is really ugly, an hash table is really needed.
-- *
-- * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
-- */
--htmlEntityDescPtr
--htmlEntityValueLookup(int value) {
-- int i;
--#ifdef DEBUG
-- int lv = 0;
--#endif
--
-- for (i = 0;i < (sizeof(html40EntitiesTable)/
-- sizeof(html40EntitiesTable[0]));i++) {
-- if ((unsigned int) html40EntitiesTable[i].value >= value) {
-- if ((unsigned int) html40EntitiesTable[i].value > value)
-- break;
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", html40EntitiesTable[i].name);
--#endif
-- return(&html40EntitiesTable[i]);
-- }
--#ifdef DEBUG
-- if (lv > html40EntitiesTable[i].value) {
-- xmlGenericError(xmlGenericErrorContext,
-- "html40EntitiesTable[] is not sorted (%d > %d)!\n",
-- lv, html40EntitiesTable[i].value);
-- }
-- lv = html40EntitiesTable[i].value;
--#endif
-- }
-- return(NULL);
--}
--
--/**
-- * UTF8ToHtml:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of UTF-8 chars
-- * @inlen: the length of @in
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an ASCII
-- * plus HTML entities block of chars out.
-- *
-- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of octets consumed.
-- */
--int
--UTF8ToHtml(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen) {
-- const unsigned char* processed = in;
-- const unsigned char* outend;
-- const unsigned char* outstart = out;
-- const unsigned char* instart = in;
-- const unsigned char* inend;
-- unsigned int c, d;
-- int trailing;
--
-- if (in == NULL) {
-- /*
-- * initialization nothing to do
-- */
-- *outlen = 0;
-- *inlen = 0;
-- return(0);
-- }
-- inend = in + (*inlen);
-- outend = out + (*outlen);
-- while (in < inend) {
-- d = *in++;
-- if (d < 0x80) { c= d; trailing= 0; }
-- else if (d < 0xC0) {
-- /* trailing byte in leading position */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-- else {
-- /* no chance for this in Ascii */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
--
-- if (inend - in < trailing) {
-- break;
-- }
--
-- for ( ; trailing; trailing--) {
-- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
-- break;
-- c <<= 6;
-- c |= d & 0x3F;
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (c < 0x80) {
-- if (out + 1 >= outend)
-- break;
-- *out++ = c;
-- } else {
-- int len;
-- htmlEntityDescPtr ent;
--
-- /*
-- * Try to lookup a predefined HTML entity for it
-- */
--
-- ent = htmlEntityValueLookup(c);
-- if (ent == NULL) {
-- /* no chance for this in Ascii */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
-- len = strlen(ent->name);
-- if (out + 2 + len >= outend)
-- break;
-- *out++ = '&';
-- memcpy(out, ent->name, len);
-- out += len;
-- *out++ = ';';
-- }
-- processed = in;
-- }
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(0);
--}
--
--/**
-- * htmlEncodeEntities:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of UTF-8 chars
-- * @inlen: the length of @in
-- * @quoteChar: the quote character to escape (' or ") or zero.
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an ASCII
-- * plus HTML entities block of chars out.
-- *
-- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of octets consumed.
-- */
--int
--htmlEncodeEntities(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen, int quoteChar) {
-- const unsigned char* processed = in;
-- const unsigned char* outend = out + (*outlen);
-- const unsigned char* outstart = out;
-- const unsigned char* instart = in;
-- const unsigned char* inend = in + (*inlen);
-- unsigned int c, d;
-- int trailing;
--
-- while (in < inend) {
-- d = *in++;
-- if (d < 0x80) { c= d; trailing= 0; }
-- else if (d < 0xC0) {
-- /* trailing byte in leading position */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-- else {
-- /* no chance for this in Ascii */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
--
-- if (inend - in < trailing)
-- break;
--
-- while (trailing--) {
-- if (((d= *in++) & 0xC0) != 0x80) {
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
-- c <<= 6;
-- c |= d & 0x3F;
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (c < 0x80 && c != quoteChar && c != '&' && c != '<' && c != '>') {
-- if (out >= outend)
-- break;
-- *out++ = c;
-- } else {
-- htmlEntityDescPtr ent;
-- const char *cp;
-- char nbuf[16];
-- int len;
--
-- /*
-- * Try to lookup a predefined HTML entity for it
-- */
-- ent = htmlEntityValueLookup(c);
-- if (ent == NULL) {
-- sprintf(nbuf, "#%u", c);
-- cp = nbuf;
-- }
-- else
-- cp = ent->name;
-- len = strlen(cp);
-- if (out + 2 + len > outend)
-- break;
-- *out++ = '&';
-- memcpy(out, cp, len);
-- out += len;
-- *out++ = ';';
-- }
-- processed = in;
-- }
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(0);
--}
--
--/**
-- * htmlDecodeEntities:
-- * @ctxt: the parser context
-- * @len: the len to decode (in bytes !), -1 for no size limit
-- * @end: an end marker xmlChar, 0 if none
-- * @end2: an end marker xmlChar, 0 if none
-- * @end3: an end marker xmlChar, 0 if none
-- *
-- * Subtitute the HTML entities by their value
-- *
-- * DEPRECATED !!!!
-- *
-- * Returns A newly allocated string with the substitution done. The caller
-- * must deallocate it !
-- */
--xmlChar *
--htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len,
-- xmlChar end, xmlChar end2, xmlChar end3) {
-- xmlChar *name = NULL;
-- xmlChar *buffer = NULL;
-- unsigned int buffer_size = 0;
-- unsigned int nbchars = 0;
-- htmlEntityDescPtr ent;
-- unsigned int max = (unsigned int) len;
-- int c,l;
--
-- if (ctxt->depth > 40) {
-- ctxt->errNo = XML_ERR_ENTITY_LOOP;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Detected entity reference loop\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- /*
-- * allocate a translation buffer.
-- */
-- buffer_size = HTML_PARSER_BIG_BUFFER_SIZE;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("xmlDecodeEntities: malloc failed");
-- return(NULL);
-- }
--
-- /*
-- * Ok loop until we reach one of the ending char or a size limit.
-- */
-- c = CUR_CHAR(l);
-- while ((nbchars < max) && (c != end) &&
-- (c != end2) && (c != end3)) {
--
-- if (c == 0) break;
-- if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
-- int val = htmlParseCharRef(ctxt);
-- COPY_BUF(0,buffer,nbchars,val);
-- NEXTL(l);
-- } else if ((c == '&') && (ctxt->token != '&')) {
-- ent = htmlParseEntityRef(ctxt, &name);
-- if (name != NULL) {
-- if (ent != NULL) {
-- int val = ent->value;
-- COPY_BUF(0,buffer,nbchars,val);
-- NEXTL(l);
-- } else {
-- const xmlChar *cur = name;
--
-- buffer[nbchars++] = '&';
-- if (nbchars > buffer_size - HTML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- while (*cur != 0) {
-- buffer[nbchars++] = *cur++;
-- }
-- buffer[nbchars++] = ';';
-- }
-- }
-- } else {
-- COPY_BUF(l,buffer,nbchars,c);
-- NEXTL(l);
-- if (nbchars > buffer_size - HTML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- }
-- c = CUR_CHAR(l);
-- }
-- buffer[nbchars++] = 0;
-- return(buffer);
--}
--
--/************************************************************************
-- * *
-- * Commodity functions to handle streams *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlFreeInputStream:
-- * @input: an htmlParserInputPtr
-- *
-- * Free up an input stream.
-- */
--void
--htmlFreeInputStream(htmlParserInputPtr input) {
-- if (input == NULL) return;
--
-- if (input->filename != NULL) xmlFree((char *) input->filename);
-- if (input->directory != NULL) xmlFree((char *) input->directory);
-- if ((input->free != NULL) && (input->base != NULL))
-- input->free((xmlChar *) input->base);
-- if (input->buf != NULL)
-- xmlFreeParserInputBuffer(input->buf);
-- memset(input, -1, sizeof(htmlParserInput));
-- xmlFree(input);
--}
--
--/**
-- * htmlNewInputStream:
-- * @ctxt: an HTML parser context
-- *
-- * Create a new input stream structure
-- * Returns the new input stream or NULL
-- */
--htmlParserInputPtr
--htmlNewInputStream(htmlParserCtxtPtr ctxt) {
-- htmlParserInputPtr input;
--
-- input = (xmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
-- if (input == NULL) {
-- ctxt->errNo = XML_ERR_NO_MEMORY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "malloc: couldn't allocate a new input stream\n");
-- return(NULL);
-- }
-- memset(input, 0, sizeof(htmlParserInput));
-- input->filename = NULL;
-- input->directory = NULL;
-- input->base = NULL;
-- input->cur = NULL;
-- input->buf = NULL;
-- input->line = 1;
-- input->col = 1;
-- input->buf = NULL;
-- input->free = NULL;
-- input->version = NULL;
-- input->consumed = 0;
-- input->length = 0;
-- return(input);
--}
--
--
--/************************************************************************
-- * *
-- * Commodity functions, cleanup needed ? *
-- * *
-- ************************************************************************/
--
--/**
-- * areBlanks:
-- * @ctxt: an HTML parser context
-- * @str: a xmlChar *
-- * @len: the size of @str
-- *
-- * Is this a sequence of blank chars that one can ignore ?
-- *
-- * Returns 1 if ignorable 0 otherwise.
-- */
--
--static int areBlanks(htmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
-- int i;
-- xmlNodePtr lastChild;
--
-- for (i = 0;i < len;i++)
-- if (!(IS_BLANK(str[i]))) return(0);
--
-- if (CUR == 0) return(1);
-- if (CUR != '<') return(0);
-- if (ctxt->name == NULL)
-- return(1);
-- if (xmlStrEqual(ctxt->name, BAD_CAST"html"))
-- return(1);
-- if (xmlStrEqual(ctxt->name, BAD_CAST"head"))
-- return(1);
-- if (xmlStrEqual(ctxt->name, BAD_CAST"body"))
-- return(1);
-- if (ctxt->node == NULL) return(0);
-- lastChild = xmlGetLastChild(ctxt->node);
-- if (lastChild == NULL) {
-- if (ctxt->node->content != NULL) return(0);
-- } else if (xmlNodeIsText(lastChild)) {
-- return(0);
-- } else if (xmlStrEqual(lastChild->name, BAD_CAST"b")) {
-- return(0);
-- } else if (xmlStrEqual(lastChild->name, BAD_CAST"bold")) {
-- return(0);
-- } else if (xmlStrEqual(lastChild->name, BAD_CAST"em")) {
-- return(0);
-- }
-- return(1);
--}
--
--/**
-- * htmlHandleEntity:
-- * @ctxt: an HTML parser context
-- * @entity: an XML entity pointer.
-- *
-- * Default handling of an HTML entity, call the parser with the
-- * substitution string
-- */
--
--void
--htmlHandleEntity(htmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-- int len;
--
-- if (entity->content == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "htmlHandleEntity %s: content == NULL\n",
-- entity->name);
-- ctxt->wellFormed = 0;
-- return;
-- }
-- len = xmlStrlen(entity->content);
--
-- /*
-- * Just handle the content as a set of chars.
-- */
-- htmlCheckParagraph(ctxt);
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, entity->content, len);
--
--}
--
--/**
-- * htmlNewDocNoDtD:
-- * @URI: URI for the dtd, or NULL
-- * @ExternalID: the external ID of the DTD, or NULL
-- *
-- * Returns a new document, do not intialize the DTD if not provided
-- */
--htmlDocPtr
--htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
-- xmlDocPtr cur;
--
-- /*
-- * Allocate a new document and fill the fields.
-- */
-- cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewDoc : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlDoc));
--
-- cur->type = XML_HTML_DOCUMENT_NODE;
-- cur->version = NULL;
-- cur->intSubset = NULL;
-- if ((ExternalID != NULL) ||
-- (URI != NULL))
-- xmlCreateIntSubset(cur, BAD_CAST "HTML", ExternalID, URI);
-- cur->doc = cur;
-- cur->name = NULL;
-- cur->children = NULL;
-- cur->extSubset = NULL;
-- cur->oldNs = NULL;
-- cur->encoding = NULL;
-- cur->standalone = 1;
-- cur->compression = 0;
-- cur->ids = NULL;
-- cur->refs = NULL;
--#ifndef XML_WITHOUT_CORBA
-- cur->_private = NULL;
--#endif
-- return(cur);
--}
--
--/**
-- * htmlNewDoc:
-- * @URI: URI for the dtd, or NULL
-- * @ExternalID: the external ID of the DTD, or NULL
-- *
-- * Returns a new document
-- */
--htmlDocPtr
--htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID) {
-- if ((URI == NULL) && (ExternalID == NULL))
-- return(htmlNewDocNoDtD(
-- BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
-- BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd"));
--
-- return(htmlNewDocNoDtD(URI, ExternalID));
--}
--
--
--/************************************************************************
-- * *
-- * The parser itself *
-- * Relates to http://www.w3.org/TR/html40 *
-- * *
-- ************************************************************************/
--
--/************************************************************************
-- * *
-- * The parser itself *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlParseHTMLName:
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML tag or attribute name, note that we convert it to lowercase
-- * since HTML names are not case-sensitive.
-- *
-- * Returns the Tag Name parsed or NULL
-- */
--
--xmlChar *
--htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
-- xmlChar *ret = NULL;
-- int i = 0;
-- xmlChar loc[HTML_PARSER_BUFFER_SIZE];
--
-- if (!IS_LETTER(CUR) && (CUR != '_') &&
-- (CUR != ':')) return(NULL);
--
-- while ((i < HTML_PARSER_BUFFER_SIZE) &&
-- ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == ':') || (CUR == '-') || (CUR == '_'))) {
-- if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
-- else loc[i] = CUR;
-- i++;
--
-- NEXT;
-- }
--
-- ret = xmlStrndup(loc, i);
--
-- return(ret);
--}
--
--/**
-- * htmlParseName:
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML name, this routine is case sensistive.
-- *
-- * Returns the Name parsed or NULL
-- */
--
--xmlChar *
--htmlParseName(htmlParserCtxtPtr ctxt) {
-- xmlChar buf[HTML_MAX_NAMELEN];
-- int len = 0;
--
-- GROW;
-- if (!IS_LETTER(CUR) && (CUR != '_')) {
-- return(NULL);
-- }
--
-- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == '.') || (CUR == '-') ||
-- (CUR == '_') || (CUR == ':') ||
-- (IS_COMBINING(CUR)) ||
-- (IS_EXTENDER(CUR))) {
-- buf[len++] = CUR;
-- NEXT;
-- if (len >= HTML_MAX_NAMELEN) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlParseName: reached HTML_MAX_NAMELEN limit\n");
-- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == '.') || (CUR == '-') ||
-- (CUR == '_') || (CUR == ':') ||
-- (IS_COMBINING(CUR)) ||
-- (IS_EXTENDER(CUR)))
-- NEXT;
-- break;
-- }
-- }
-- return(xmlStrndup(buf, len));
--}
--
--/**
-- * htmlParseHTMLAttribute:
-- * @ctxt: an HTML parser context
-- * @stop: a char stop value
-- *
-- * parse an HTML attribute value till the stop (quote), if
-- * stop is 0 then it stops at the first space
-- *
-- * Returns the attribute parsed or NULL
-- */
--
--xmlChar *
--htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
-- xmlChar *buffer = NULL;
-- int buffer_size = 0;
-- xmlChar *out = NULL;
-- xmlChar *name = NULL;
--
-- xmlChar *cur = NULL;
-- htmlEntityDescPtr ent;
--
-- /*
-- * allocate a translation buffer.
-- */
-- buffer_size = HTML_PARSER_BUFFER_SIZE;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("htmlParseHTMLAttribute: malloc failed");
-- return(NULL);
-- }
-- out = buffer;
--
-- /*
-- * Ok loop until we reach one of the ending chars
-- */
-- while ((CUR != 0) && (CUR != stop) && (CUR != '>')) {
-- if ((stop == 0) && (IS_BLANK(CUR))) break;
-- if (CUR == '&') {
-- if (NXT(1) == '#') {
-- unsigned int c;
-- int bits;
--
-- c = htmlParseCharRef(ctxt);
-- if (c < 0x80)
-- { *out++ = c; bits= -6; }
-- else if (c < 0x800)
-- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000)
-- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else
-- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- *out++ = ((c >> bits) & 0x3F) | 0x80;
-- }
-- } else {
-- ent = htmlParseEntityRef(ctxt, &name);
-- if (name == NULL) {
-- *out++ = '&';
-- if (out - buffer > buffer_size - 100) {
-- int index = out - buffer;
--
-- growBuffer(buffer);
-- out = &buffer[index];
-- }
-- } else if (ent == NULL) {
-- *out++ = '&';
-- cur = name;
-- while (*cur != 0) {
-- if (out - buffer > buffer_size - 100) {
-- int index = out - buffer;
--
-- growBuffer(buffer);
-- out = &buffer[index];
-- }
-- *out++ = *cur++;
-- }
-- xmlFree(name);
-- } else {
-- unsigned int c;
-- int bits;
--
-- if (out - buffer > buffer_size - 100) {
-- int index = out - buffer;
--
-- growBuffer(buffer);
-- out = &buffer[index];
-- }
-- c = (xmlChar)ent->value;
-- if (c < 0x80)
-- { *out++ = c; bits= -6; }
-- else if (c < 0x800)
-- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000)
-- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else
-- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- *out++ = ((c >> bits) & 0x3F) | 0x80;
-- }
-- xmlFree(name);
-- }
-- }
-- } else {
-- unsigned int c;
-- int bits, l;
--
-- if (out - buffer > buffer_size - 100) {
-- int index = out - buffer;
--
-- growBuffer(buffer);
-- out = &buffer[index];
-- }
-- c = CUR_CHAR(l);
-- if (c < 0x80)
-- { *out++ = c; bits= -6; }
-- else if (c < 0x800)
-- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000)
-- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else
-- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- *out++ = ((c >> bits) & 0x3F) | 0x80;
-- }
-- NEXT;
-- }
-- }
-- *out++ = 0;
-- return(buffer);
--}
--
--/**
-- * htmlParseNmtoken:
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML Nmtoken.
-- *
-- * Returns the Nmtoken parsed or NULL
-- */
--
--xmlChar *
--htmlParseNmtoken(htmlParserCtxtPtr ctxt) {
-- xmlChar buf[HTML_MAX_NAMELEN];
-- int len = 0;
--
-- GROW;
-- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == '.') || (CUR == '-') ||
-- (CUR == '_') || (CUR == ':') ||
-- (IS_COMBINING(CUR)) ||
-- (IS_EXTENDER(CUR))) {
-- buf[len++] = CUR;
-- NEXT;
-- if (len >= HTML_MAX_NAMELEN) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlParseNmtoken: reached HTML_MAX_NAMELEN limit\n");
-- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == '.') || (CUR == '-') ||
-- (CUR == '_') || (CUR == ':') ||
-- (IS_COMBINING(CUR)) ||
-- (IS_EXTENDER(CUR)))
-- NEXT;
-- break;
-- }
-- }
-- return(xmlStrndup(buf, len));
--}
--
--/**
-- * htmlParseEntityRef:
-- * @ctxt: an HTML parser context
-- * @str: location to store the entity name
-- *
-- * parse an HTML ENTITY references
-- *
-- * [68] EntityRef ::= '&' Name ';'
-- *
-- * Returns the associated htmlEntityDescPtr if found, or NULL otherwise,
-- * if non-NULL *str will have to be freed by the caller.
-- */
--htmlEntityDescPtr
--htmlParseEntityRef(htmlParserCtxtPtr ctxt, xmlChar **str) {
-- xmlChar *name;
-- htmlEntityDescPtr ent = NULL;
-- *str = NULL;
--
-- if (CUR == '&') {
-- NEXT;
-- name = htmlParseName(ctxt);
-- if (name == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "htmlParseEntityRef: no name\n");
-- ctxt->wellFormed = 0;
-- } else {
-- GROW;
-- if (CUR == ';') {
-- *str = name;
--
-- /*
-- * Lookup the entity in the table.
-- */
-- ent = htmlEntityLookup(name);
-- if (ent != NULL) /* OK that's ugly !!! */
-- NEXT;
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseEntityRef: expecting ';'\n");
-- *str = name;
-- }
-- }
-- }
-- return(ent);
--}
--
--/**
-- * htmlParseAttValue:
-- * @ctxt: an HTML parser context
-- *
-- * parse a value for an attribute
-- * Note: the parser won't do substitution of entities here, this
-- * will be handled later in xmlStringGetNodeList, unless it was
-- * asked for ctxt->replaceEntities != 0
-- *
-- * Returns the AttValue parsed or NULL.
-- */
--
--xmlChar *
--htmlParseAttValue(htmlParserCtxtPtr ctxt) {
-- xmlChar *ret = NULL;
--
-- if (CUR == '"') {
-- NEXT;
-- ret = htmlParseHTMLAttribute(ctxt, '"');
-- if (CUR != '"') {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
-- ctxt->wellFormed = 0;
-- } else
-- NEXT;
-- } else if (CUR == '\'') {
-- NEXT;
-- ret = htmlParseHTMLAttribute(ctxt, '\'');
-- if (CUR != '\'') {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
-- ctxt->wellFormed = 0;
-- } else
-- NEXT;
-- } else {
-- /*
-- * That's an HTMLism, the attribute value may not be quoted
-- */
-- ret = htmlParseHTMLAttribute(ctxt, 0);
-- if (ret == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "AttValue: no value found\n");
-- ctxt->wellFormed = 0;
-- }
-- }
-- return(ret);
--}
--
--/**
-- * htmlParseSystemLiteral:
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML Literal
-- *
-- * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
-- *
-- * Returns the SystemLiteral parsed or NULL
-- */
--
--xmlChar *
--htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
-- const xmlChar *q;
-- xmlChar *ret = NULL;
--
-- if (CUR == '"') {
-- NEXT;
-- q = CUR_PTR;
-- while ((IS_CHAR(CUR)) && (CUR != '"'))
-- NEXT;
-- if (!IS_CHAR(CUR)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
-- ctxt->wellFormed = 0;
-- } else {
-- ret = xmlStrndup(q, CUR_PTR - q);
-- NEXT;
-- }
-- } else if (CUR == '\'') {
-- NEXT;
-- q = CUR_PTR;
-- while ((IS_CHAR(CUR)) && (CUR != '\''))
-- NEXT;
-- if (!IS_CHAR(CUR)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
-- ctxt->wellFormed = 0;
-- } else {
-- ret = xmlStrndup(q, CUR_PTR - q);
-- NEXT;
-- }
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "SystemLiteral \" or ' expected\n");
-- ctxt->wellFormed = 0;
-- }
--
-- return(ret);
--}
--
--/**
-- * htmlParsePubidLiteral:
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML public literal
-- *
-- * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
-- *
-- * Returns the PubidLiteral parsed or NULL.
-- */
--
--xmlChar *
--htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
-- const xmlChar *q;
-- xmlChar *ret = NULL;
-- /*
-- * Name ::= (Letter | '_') (NameChar)*
-- */
-- if (CUR == '"') {
-- NEXT;
-- q = CUR_PTR;
-- while (IS_PUBIDCHAR(CUR)) NEXT;
-- if (CUR != '"') {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
-- ctxt->wellFormed = 0;
-- } else {
-- ret = xmlStrndup(q, CUR_PTR - q);
-- NEXT;
-- }
-- } else if (CUR == '\'') {
-- NEXT;
-- q = CUR_PTR;
-- while ((IS_LETTER(CUR)) && (CUR != '\''))
-- NEXT;
-- if (!IS_LETTER(CUR)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
-- ctxt->wellFormed = 0;
-- } else {
-- ret = xmlStrndup(q, CUR_PTR - q);
-- NEXT;
-- }
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "SystemLiteral \" or ' expected\n");
-- ctxt->wellFormed = 0;
-- }
--
-- return(ret);
--}
--
--/**
-- * htmlParseScript:
-- * @ctxt: an HTML parser context
-- *
-- * parse the content of an HTML SCRIPT or STYLE element
-- * http://www.w3.org/TR/html4/sgml/dtd.html#Script
-- * http://www.w3.org/TR/html4/sgml/dtd.html#StyleSheet
-- * http://www.w3.org/TR/html4/types.html#type-script
-- * http://www.w3.org/TR/html4/types.html#h-6.15
-- * http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2.1
-- *
-- * Script data ( %Script; in the DTD) can be the content of the SCRIPT
-- * element and the value of intrinsic event attributes. User agents must
-- * not evaluate script data as HTML markup but instead must pass it on as
-- * data to a script engine.
-- * NOTES:
-- * - The content is passed like CDATA
-- * - the attributes for style and scripting "onXXX" are also described
-- * as CDATA but SGML allows entities references in attributes so their
-- * processing is identical as other attributes
-- */
--void
--htmlParseScript(htmlParserCtxtPtr ctxt) {
-- xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 1];
-- int nbchar = 0;
-- xmlChar cur;
--
-- SHRINK;
-- cur = CUR;
-- while (IS_CHAR(cur)) {
-- if ((cur == '<') && (NXT(1) == '/')) {
-- /*
-- * One should break here, the specification is clear:
-- * Authors should therefore escape "</" within the content.
-- * Escape mechanisms are specific to each scripting or
-- * style sheet language.
-- */
-- if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
-- ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
-- break; /* while */
-- }
-- buf[nbchar++] = cur;
-- if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
-- if (ctxt->sax->cdataBlock!= NULL) {
-- /*
-- * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
-- */
-- ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
-- }
-- nbchar = 0;
-- }
-- NEXT;
-- cur = CUR;
-- }
-- if (!(IS_CHAR(cur))) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Invalid char in CDATA 0x%X\n", cur);
-- ctxt->wellFormed = 0;
-- NEXT;
-- }
--
-- if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (ctxt->sax->cdataBlock!= NULL) {
-- /*
-- * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
-- */
-- ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
-- }
-- }
--}
--
--
--/**
-- * htmlParseCharData:
-- * @ctxt: an HTML parser context
-- * @cdata: int indicating whether we are within a CDATA section
-- *
-- * parse a CharData section.
-- * if we are within a CDATA section ']]>' marks an end of section.
-- *
-- * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-- */
--
--void
--htmlParseCharData(htmlParserCtxtPtr ctxt, int cdata) {
-- xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
-- int nbchar = 0;
-- int cur, l;
--
-- SHRINK;
-- cur = CUR_CHAR(l);
-- while (((cur != '<') || (ctxt->token == '<')) &&
-- ((cur != '&') || (ctxt->token == '&')) &&
-- (IS_CHAR(cur))) {
-- COPY_BUF(l,buf,nbchar,cur);
-- if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
-- /*
-- * Ok the segment is to be consumed as chars.
-- */
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (areBlanks(ctxt, buf, nbchar)) {
-- if (ctxt->sax->ignorableWhitespace != NULL)
-- ctxt->sax->ignorableWhitespace(ctxt->userData,
-- buf, nbchar);
-- } else {
-- htmlCheckParagraph(ctxt);
-- if (ctxt->sax->characters != NULL)
-- ctxt->sax->characters(ctxt->userData, buf, nbchar);
-- }
-- }
-- nbchar = 0;
-- }
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- }
-- if (nbchar != 0) {
-- /*
-- * Ok the segment is to be consumed as chars.
-- */
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (areBlanks(ctxt, buf, nbchar)) {
-- if (ctxt->sax->ignorableWhitespace != NULL)
-- ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
-- } else {
-- htmlCheckParagraph(ctxt);
-- if (ctxt->sax->characters != NULL)
-- ctxt->sax->characters(ctxt->userData, buf, nbchar);
-- }
-- }
-- }
--}
--
--/**
-- * htmlParseExternalID:
-- * @ctxt: an HTML parser context
-- * @publicID: a xmlChar** receiving PubidLiteral
-- * @strict: indicate whether we should restrict parsing to only
-- * production [75], see NOTE below
-- *
-- * Parse an External ID or a Public ID
-- *
-- * NOTE: Productions [75] and [83] interract badly since [75] can generate
-- * 'PUBLIC' S PubidLiteral S SystemLiteral
-- *
-- * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-- * | 'PUBLIC' S PubidLiteral S SystemLiteral
-- *
-- * [83] PublicID ::= 'PUBLIC' S PubidLiteral
-- *
-- * Returns the function returns SystemLiteral and in the second
-- * case publicID receives PubidLiteral, is strict is off
-- * it is possible to return NULL and have publicID set.
-- */
--
--xmlChar *
--htmlParseExternalID(htmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
-- xmlChar *URI = NULL;
--
-- if ((UPPER == 'S') && (UPP(1) == 'Y') &&
-- (UPP(2) == 'S') && (UPP(3) == 'T') &&
-- (UPP(4) == 'E') && (UPP(5) == 'M')) {
-- SKIP(6);
-- if (!IS_BLANK(CUR)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'SYSTEM'\n");
-- ctxt->wellFormed = 0;
-- }
-- SKIP_BLANKS;
-- URI = htmlParseSystemLiteral(ctxt);
-- if (URI == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseExternalID: SYSTEM, no URI\n");
-- ctxt->wellFormed = 0;
-- }
-- } else if ((UPPER == 'P') && (UPP(1) == 'U') &&
-- (UPP(2) == 'B') && (UPP(3) == 'L') &&
-- (UPP(4) == 'I') && (UPP(5) == 'C')) {
-- SKIP(6);
-- if (!IS_BLANK(CUR)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'PUBLIC'\n");
-- ctxt->wellFormed = 0;
-- }
-- SKIP_BLANKS;
-- *publicID = htmlParsePubidLiteral(ctxt);
-- if (*publicID == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseExternalID: PUBLIC, no Public Identifier\n");
-- ctxt->wellFormed = 0;
-- }
-- SKIP_BLANKS;
-- if ((CUR == '"') || (CUR == '\'')) {
-- URI = htmlParseSystemLiteral(ctxt);
-- }
-- }
-- return(URI);
--}
--
--/**
-- * htmlParseComment:
-- * @ctxt: an HTML parser context
-- *
-- * Parse an XML (SGML) comment <!-- .... -->
-- *
-- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-- */
--void
--htmlParseComment(htmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len;
-- int size = HTML_PARSER_BUFFER_SIZE;
-- int q, ql;
-- int r, rl;
-- int cur, l;
-- xmlParserInputState state;
--
-- /*
-- * Check that there is a comment right here.
-- */
-- if ((RAW != '<') || (NXT(1) != '!') ||
-- (NXT(2) != '-') || (NXT(3) != '-')) return;
--
-- state = ctxt->instate;
-- ctxt->instate = XML_PARSER_COMMENT;
-- SHRINK;
-- SKIP(4);
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- ctxt->instate = state;
-- return;
-- }
-- q = CUR_CHAR(ql);
-- NEXTL(ql);
-- r = CUR_CHAR(rl);
-- NEXTL(rl);
-- cur = CUR_CHAR(l);
-- len = 0;
-- while (IS_CHAR(cur) &&
-- ((cur != '>') ||
-- (r != '-') || (q != '-'))) {
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- ctxt->instate = state;
-- return;
-- }
-- }
-- COPY_BUF(ql,buf,len,q);
-- q = r;
-- ql = rl;
-- r = cur;
-- rl = l;
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- if (cur == 0) {
-- SHRINK;
-- GROW;
-- cur = CUR_CHAR(l);
-- }
-- }
-- buf[len] = 0;
-- if (!IS_CHAR(cur)) {
-- ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Comment not terminated \n<!--%.50s\n", buf);
-- ctxt->wellFormed = 0;
-- xmlFree(buf);
-- } else {
-- NEXT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->comment(ctxt->userData, buf);
-- xmlFree(buf);
-- }
-- ctxt->instate = state;
--}
--
--/**
-- * htmlParseCharRef:
-- * @ctxt: an HTML parser context
-- *
-- * parse Reference declarations
-- *
-- * [66] CharRef ::= '&#' [0-9]+ ';' |
-- * '&#x' [0-9a-fA-F]+ ';'
-- *
-- * Returns the value parsed (as an int)
-- */
--int
--htmlParseCharRef(htmlParserCtxtPtr ctxt) {
-- int val = 0;
--
-- if ((CUR == '&') && (NXT(1) == '#') &&
-- (NXT(2) == 'x')) {
-- SKIP(3);
-- while (CUR != ';') {
-- if ((CUR >= '0') && (CUR <= '9'))
-- val = val * 16 + (CUR - '0');
-- else if ((CUR >= 'a') && (CUR <= 'f'))
-- val = val * 16 + (CUR - 'a') + 10;
-- else if ((CUR >= 'A') && (CUR <= 'F'))
-- val = val * 16 + (CUR - 'A') + 10;
-- else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseCharRef: invalid hexadecimal value\n");
-- ctxt->wellFormed = 0;
-- return(0);
-- }
-- NEXT;
-- }
-- if (CUR == ';')
-- NEXT;
-- } else if ((CUR == '&') && (NXT(1) == '#')) {
-- SKIP(2);
-- while (CUR != ';') {
-- if ((CUR >= '0') && (CUR <= '9'))
-- val = val * 10 + (CUR - '0');
-- else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseCharRef: invalid decimal value\n");
-- ctxt->wellFormed = 0;
-- return(0);
-- }
-- NEXT;
-- }
-- if (CUR == ';')
-- NEXT;
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "htmlParseCharRef: invalid value\n");
-- ctxt->wellFormed = 0;
-- }
-- /*
-- * Check the value IS_CHAR ...
-- */
-- if (IS_CHAR(val)) {
-- return(val);
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "htmlParseCharRef: invalid xmlChar value %d\n",
-- val);
-- ctxt->wellFormed = 0;
-- }
-- return(0);
--}
--
--
--/**
-- * htmlParseDocTypeDecl :
-- * @ctxt: an HTML parser context
-- *
-- * parse a DOCTYPE declaration
-- *
-- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-- * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-- */
--
--void
--htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *ExternalID = NULL;
-- xmlChar *URI = NULL;
--
-- /*
-- * We know that '<!DOCTYPE' has been detected.
-- */
-- SKIP(9);
--
-- SKIP_BLANKS;
--
-- /*
-- * Parse the DOCTYPE name.
-- */
-- name = htmlParseName(ctxt);
-- if (name == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "htmlParseDocTypeDecl : no DOCTYPE name !\n");
-- ctxt->wellFormed = 0;
-- }
-- /*
-- * Check that upper(name) == "HTML" !!!!!!!!!!!!!
-- */
--
-- SKIP_BLANKS;
--
-- /*
-- * Check for SystemID and ExternalID
-- */
-- URI = htmlParseExternalID(ctxt, &ExternalID, 0);
-- SKIP_BLANKS;
--
-- /*
-- * We should be at the end of the DOCTYPE declaration.
-- */
-- if (CUR != '>') {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
-- ctxt->wellFormed = 0;
-- /* We shouldn't try to resynchronize ... */
-- }
-- NEXT;
--
-- /*
-- * Create or update the document accordingly to the DOCTYPE
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
--
-- /*
-- * Cleanup, since we don't use all those identifiers
-- */
-- if (URI != NULL) xmlFree(URI);
-- if (ExternalID != NULL) xmlFree(ExternalID);
-- if (name != NULL) xmlFree(name);
--}
--
--/**
-- * htmlParseAttribute:
-- * @ctxt: an HTML parser context
-- * @value: a xmlChar ** used to store the value of the attribute
-- *
-- * parse an attribute
-- *
-- * [41] Attribute ::= Name Eq AttValue
-- *
-- * [25] Eq ::= S? '=' S?
-- *
-- * With namespace:
-- *
-- * [NS 11] Attribute ::= QName Eq AttValue
-- *
-- * Also the case QName == xmlns:??? is handled independently as a namespace
-- * definition.
-- *
-- * Returns the attribute name, and the value in *value.
-- */
--
--xmlChar *
--htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
-- xmlChar *name, *val = NULL;
--
-- *value = NULL;
-- name = htmlParseHTMLName(ctxt);
-- if (name == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
-- ctxt->wellFormed = 0;
-- return(NULL);
-- }
--
-- /*
-- * read the value
-- */
-- SKIP_BLANKS;
-- if (CUR == '=') {
-- NEXT;
-- SKIP_BLANKS;
-- val = htmlParseAttValue(ctxt);
-- /******
-- } else {
-- * TODO : some attribute must have values, some may not
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "No value for attribute %s\n", name); */
-- }
--
-- *value = val;
-- return(name);
--}
--
--/**
-- * htmlCheckEncoding:
-- * @ctxt: an HTML parser context
-- * @attvalue: the attribute value
-- *
-- * Checks an http-equiv attribute from a Meta tag to detect
-- * the encoding
-- * If a new encoding is detected the parser is switched to decode
-- * it and pass UTF8
-- */
--void
--htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
-- const xmlChar *encoding;
--
-- if ((ctxt == NULL) || (attvalue == NULL))
-- return;
--
-- /* do not change encoding */
-- if (ctxt->input->encoding != NULL)
-- return;
--
-- encoding = xmlStrcasestr(attvalue, BAD_CAST"charset=");
-- if (encoding != NULL) {
-- encoding += 8;
-- } else {
-- encoding = xmlStrcasestr(attvalue, BAD_CAST"charset =");
-- if (encoding != NULL)
-- encoding += 9;
-- }
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
-- xmlCharEncodingHandlerPtr handler;
--
-- while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
--
-- if (ctxt->input->encoding != NULL)
-- xmlFree((xmlChar *) ctxt->input->encoding);
-- ctxt->input->encoding = xmlStrdup(encoding);
--
-- enc = xmlParseCharEncoding((const char *) encoding);
-- /*
-- * registered set of known encodings
-- */
-- if (enc != XML_CHAR_ENCODING_ERROR) {
-- xmlSwitchEncoding(ctxt, enc);
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- } else {
-- /*
-- * fallback for unknown encodings
-- */
-- handler = xmlFindCharEncodingHandler((const char *) encoding);
-- if (handler != NULL) {
-- xmlSwitchToEncoding(ctxt, handler);
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- } else {
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- }
-- }
--
-- if ((ctxt->input->buf != NULL) &&
-- (ctxt->input->buf->encoder != NULL) &&
-- (ctxt->input->buf->raw != NULL) &&
-- (ctxt->input->buf->buffer != NULL)) {
-- int nbchars;
-- int processed;
--
-- /*
-- * convert as much as possible to the parser reading buffer.
-- */
-- processed = ctxt->input->cur - ctxt->input->base;
-- xmlBufferShrink(ctxt->input->buf->buffer, processed);
-- nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-- ctxt->input->buf->buffer,
-- ctxt->input->buf->raw);
-- if (nbchars < 0) {
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlCheckEncoding: encoder error\n");
-- }
-- ctxt->input->base =
-- ctxt->input->cur = ctxt->input->buf->buffer->content;
-- }
-- }
--}
--
--/**
-- * htmlCheckMeta:
-- * @ctxt: an HTML parser context
-- * @atts: the attributes values
-- *
-- * Checks an attributes from a Meta tag
-- */
--void
--htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
-- int i;
-- const xmlChar *att, *value;
-- int http = 0;
-- const xmlChar *content = NULL;
--
-- if ((ctxt == NULL) || (atts == NULL))
-- return;
--
-- i = 0;
-- att = atts[i++];
-- while (att != NULL) {
-- value = atts[i++];
-- if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"http-equiv"))
-- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
-- http = 1;
-- else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"content")))
-- content = value;
-- att = atts[i++];
-- }
-- if ((http) && (content != NULL))
-- htmlCheckEncoding(ctxt, content);
--
--}
--
--/**
-- * htmlParseStartTag:
-- * @ctxt: an HTML parser context
-- *
-- * parse a start of tag either for rule element or
-- * EmptyElement. In both case we don't parse the tag closing chars.
-- *
-- * [40] STag ::= '<' Name (S Attribute)* S? '>'
-- *
-- * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
-- *
-- * With namespace:
-- *
-- * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
-- *
-- * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
-- *
-- */
--
--void
--htmlParseStartTag(htmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *attname;
-- xmlChar *attvalue;
-- const xmlChar **atts = NULL;
-- int nbatts = 0;
-- int maxatts = 0;
-- int meta = 0;
-- int i;
--
-- if (CUR != '<') return;
-- NEXT;
--
-- GROW;
-- name = htmlParseHTMLName(ctxt);
-- if (name == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseStartTag: invalid element name\n");
-- ctxt->wellFormed = 0;
-- /* Dump the bogus tag like browsers do */
-- while ((IS_CHAR(CUR)) && (CUR != '>'))
-- NEXT;
-- return;
-- }
-- if (xmlStrEqual(name, BAD_CAST"meta"))
-- meta = 1;
--
-- /*
-- * Check for auto-closure of HTML elements.
-- */
-- htmlAutoClose(ctxt, name);
--
-- /*
-- * Check for implied HTML elements.
-- */
-- htmlCheckImplied(ctxt, name);
--
-- /*
-- * Avoid html at any level > 0, head at any level != 1
-- * or any attempt to recurse body
-- */
-- if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseStartTag: misplaced <html> tag\n");
-- ctxt->wellFormed = 0;
-- xmlFree(name);
-- return;
-- }
-- if ((ctxt->nameNr != 1) &&
-- (xmlStrEqual(name, BAD_CAST"head"))) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseStartTag: misplaced <head> tag\n");
-- ctxt->wellFormed = 0;
-- xmlFree(name);
-- return;
-- }
-- if (xmlStrEqual(name, BAD_CAST"body")) {
-- int i;
-- for (i = 0;i < ctxt->nameNr;i++) {
-- if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseStartTag: misplaced <body> tag\n");
-- ctxt->wellFormed = 0;
-- xmlFree(name);
-- return;
-- }
-- }
-- }
--
-- /*
-- * Now parse the attributes, it ends up with the ending
-- *
-- * (S Attribute)* S?
-- */
-- SKIP_BLANKS;
-- while ((IS_CHAR(CUR)) &&
-- (CUR != '>') &&
-- ((CUR != '/') || (NXT(1) != '>'))) {
-- long cons = ctxt->nbChars;
--
-- GROW;
-- attname = htmlParseAttribute(ctxt, &attvalue);
-- if (attname != NULL) {
--
-- /*
-- * Well formedness requires at most one declaration of an attribute
-- */
-- for (i = 0; i < nbatts;i += 2) {
-- if (xmlStrEqual(atts[i], attname)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attribute %s redefined\n",
-- attname);
-- ctxt->wellFormed = 0;
-- xmlFree(attname);
-- if (attvalue != NULL)
-- xmlFree(attvalue);
-- goto failed;
-- }
-- }
--
-- /*
-- * Add the pair to atts
-- */
-- if (atts == NULL) {
-- maxatts = 10;
-- atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
-- if (atts == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %ld byte failed\n",
-- maxatts * (long)sizeof(xmlChar *));
-- if (name != NULL) xmlFree(name);
-- return;
-- }
-- } else if (nbatts + 4 > maxatts) {
-- maxatts *= 2;
-- atts = (const xmlChar **) xmlRealloc((void *) atts,
-- maxatts * sizeof(xmlChar *));
-- if (atts == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %ld byte failed\n",
-- maxatts * (long)sizeof(xmlChar *));
-- if (name != NULL) xmlFree(name);
-- return;
-- }
-- }
-- atts[nbatts++] = attname;
-- atts[nbatts++] = attvalue;
-- atts[nbatts] = NULL;
-- atts[nbatts + 1] = NULL;
-- }
-- else {
-- /* Dump the bogus attribute string up to the next blank or
-- * the end of the tag. */
-- while ((IS_CHAR(CUR)) && !(IS_BLANK(CUR)) && (CUR != '>')
-- && ((CUR != '/') || (NXT(1) != '>')))
-- NEXT;
-- }
--
--failed:
-- SKIP_BLANKS;
-- if (cons == ctxt->nbChars) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "htmlParseStartTag: problem parsing attributes\n");
-- ctxt->wellFormed = 0;
-- break;
-- }
-- }
--
-- /*
-- * Handle specific association to the META tag
-- */
-- if (meta)
-- htmlCheckMeta(ctxt, atts);
--
-- /*
-- * SAX: Start of Element !
-- */
-- htmlnamePush(ctxt, xmlStrdup(name));
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Start of element %s: pushed %s\n", name, ctxt->name);
--#endif
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-- ctxt->sax->startElement(ctxt->userData, name, atts);
--
-- if (atts != NULL) {
-- for (i = 0;i < nbatts;i++) {
-- if (atts[i] != NULL)
-- xmlFree((xmlChar *) atts[i]);
-- }
-- xmlFree((void *) atts);
-- }
-- if (name != NULL) xmlFree(name);
--}
--
--/**
-- * htmlParseEndTag:
-- * @ctxt: an HTML parser context
-- *
-- * parse an end of tag
-- *
-- * [42] ETag ::= '</' Name S? '>'
-- *
-- * With namespace
-- *
-- * [NS 9] ETag ::= '</' QName S? '>'
-- */
--
--void
--htmlParseEndTag(htmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *oldname;
-- int i;
--
-- if ((CUR != '<') || (NXT(1) != '/')) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "htmlParseEndTag: '</' not found\n");
-- ctxt->wellFormed = 0;
-- return;
-- }
-- SKIP(2);
--
-- name = htmlParseHTMLName(ctxt);
-- if (name == NULL) return;
--
-- /*
-- * We should definitely be at the ending "S? '>'" part
-- */
-- SKIP_BLANKS;
-- if ((!IS_CHAR(CUR)) || (CUR != '>')) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
-- ctxt->wellFormed = 0;
-- } else
-- NEXT;
--
-- /*
-- * If the name read is not one of the element in the parsing stack
-- * then return, it's just an error.
-- */
-- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
-- if (xmlStrEqual(name, ctxt->nameTab[i])) break;
-- }
-- if (i < 0) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Unexpected end tag : %s\n", name);
-- xmlFree(name);
-- ctxt->wellFormed = 0;
-- return;
-- }
--
--
-- /*
-- * Check for auto-closure of HTML elements.
-- */
--
-- htmlAutoCloseOnClose(ctxt, name);
--
-- /*
-- * Well formedness constraints, opening and closing must match.
-- * With the exception that the autoclose may have popped stuff out
-- * of the stack.
-- */
-- if (!xmlStrEqual(name, ctxt->name)) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", name, ctxt->name);
--#endif
-- if ((ctxt->name != NULL) &&
-- (!xmlStrEqual(ctxt->name, name))) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Opening and ending tag mismatch: %s and %s\n",
-- name, ctxt->name);
-- ctxt->wellFormed = 0;
-- }
-- }
--
-- /*
-- * SAX: End of Tag
-- */
-- oldname = ctxt->name;
-- if ((oldname != NULL) && (xmlStrEqual(oldname, name))) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, name);
-- oldname = htmlnamePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of tag %s: popping out %s\n", name, oldname);
--#endif
-- xmlFree(oldname);
--#ifdef DEBUG
-- } else {
-- xmlGenericError(xmlGenericErrorContext,"End of tag %s: stack empty !!!\n", name);
--#endif
-- }
-- }
--
-- if (name != NULL)
-- xmlFree(name);
--
-- return;
--}
--
--
--/**
-- * htmlParseReference:
-- * @ctxt: an HTML parser context
-- *
-- * parse and handle entity references in content,
-- * this will end-up in a call to character() since this is either a
-- * CharRef, or a predefined entity.
-- */
--void
--htmlParseReference(htmlParserCtxtPtr ctxt) {
-- htmlEntityDescPtr ent;
-- xmlChar out[6];
-- xmlChar *name;
-- if (CUR != '&') return;
--
-- if (NXT(1) == '#') {
-- unsigned int c;
-- int bits, i = 0;
--
-- c = htmlParseCharRef(ctxt);
-- if (c == 0)
-- return;
--
-- if (c < 0x80) { out[i++]= c; bits= -6; }
-- else if (c < 0x800) { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- out[i++]= ((c >> bits) & 0x3F) | 0x80;
-- }
-- out[i] = 0;
--
-- htmlCheckParagraph(ctxt);
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, out, i);
-- } else {
-- ent = htmlParseEntityRef(ctxt, &name);
-- if (name == NULL) {
-- htmlCheckParagraph(ctxt);
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
-- return;
-- }
-- if ((ent == NULL) || (ent->value <= 0)) {
-- htmlCheckParagraph(ctxt);
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) {
-- ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
-- ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name));
-- /* ctxt->sax->characters(ctxt->userData, BAD_CAST ";", 1); */
-- }
-- } else {
-- unsigned int c;
-- int bits, i = 0;
--
-- c = ent->value;
-- if (c < 0x80)
-- { out[i++]= c; bits= -6; }
-- else if (c < 0x800)
-- { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000)
-- { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else
-- { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- out[i++]= ((c >> bits) & 0x3F) | 0x80;
-- }
-- out[i] = 0;
--
-- htmlCheckParagraph(ctxt);
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, out, i);
-- }
-- xmlFree(name);
-- }
--}
--
--/**
-- * htmlParseContent:
-- * @ctxt: an HTML parser context
-- * @name: the node name
-- *
-- * Parse a content: comment, sub-element, reference or text.
-- *
-- */
--
--void
--htmlParseContent(htmlParserCtxtPtr ctxt) {
-- xmlChar *currentNode;
-- int depth;
--
-- currentNode = xmlStrdup(ctxt->name);
-- depth = ctxt->nameNr;
-- while (1) {
-- long cons = ctxt->nbChars;
--
-- GROW;
-- /*
-- * Our tag or one of it's parent or children is ending.
-- */
-- if ((CUR == '<') && (NXT(1) == '/')) {
-- htmlParseEndTag(ctxt);
-- if (currentNode != NULL) xmlFree(currentNode);
-- return;
-- }
--
-- /*
-- * Has this node been popped out during parsing of
-- * the next element
-- */
-- if ((!xmlStrEqual(currentNode, ctxt->name)) &&
-- (depth >= ctxt->nameNr)) {
-- if (currentNode != NULL) xmlFree(currentNode);
-- return;
-- }
--
-- if ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
-- (xmlStrEqual(currentNode, BAD_CAST"style"))) {
-- /*
-- * Handle SCRIPT/STYLE separately
-- */
-- htmlParseScript(ctxt);
-- } else {
-- /*
-- * Sometimes DOCTYPE arrives in the middle of the document
-- */
-- if ((CUR == '<') && (NXT(1) == '!') &&
-- (UPP(2) == 'D') && (UPP(3) == 'O') &&
-- (UPP(4) == 'C') && (UPP(5) == 'T') &&
-- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-- (UPP(8) == 'E')) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Misplaced DOCTYPE declaration\n");
-- ctxt->wellFormed = 0;
-- htmlParseDocTypeDecl(ctxt);
-- }
--
-- /*
-- * First case : a comment
-- */
-- if ((CUR == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '-') && (NXT(3) == '-')) {
-- htmlParseComment(ctxt);
-- }
--
-- /*
-- * Second case : a sub-element.
-- */
-- else if (CUR == '<') {
-- htmlParseElement(ctxt);
-- }
--
-- /*
-- * Third case : a reference. If if has not been resolved,
-- * parsing returns it's Name, create the node
-- */
-- else if (CUR == '&') {
-- htmlParseReference(ctxt);
-- }
--
-- /*
-- * Fourth : end of the resource
-- */
-- else if (CUR == 0) {
-- htmlAutoClose(ctxt, NULL);
-- }
--
-- /*
-- * Last case, text. Note that References are handled directly.
-- */
-- else {
-- htmlParseCharData(ctxt, 0);
-- }
--
-- if (cons == ctxt->nbChars) {
-- if (ctxt->node != NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "detected an error in element content\n");
-- ctxt->wellFormed = 0;
-- }
-- break;
-- }
-- }
-- GROW;
-- }
-- if (currentNode != NULL) xmlFree(currentNode);
--}
--
--/**
-- * htmlParseElement:
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML element, this is highly recursive
-- *
-- * [39] element ::= EmptyElemTag | STag content ETag
-- *
-- * [41] Attribute ::= Name Eq AttValue
-- */
--
--void
--htmlParseElement(htmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *currentNode = NULL;
-- htmlElemDescPtr info;
-- htmlParserNodeInfo node_info;
-- xmlChar *oldname;
-- int depth = ctxt->nameNr;
--
-- /* Capture start position */
-- if (ctxt->record_info) {
-- node_info.begin_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.begin_line = ctxt->input->line;
-- }
--
-- oldname = xmlStrdup(ctxt->name);
-- htmlParseStartTag(ctxt);
-- name = ctxt->name;
--#ifdef DEBUG
-- if (oldname == NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "Start of element %s\n", name);
-- else if (name == NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "Start of element failed, was %s\n", oldname);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "Start of element %s, was %s\n", name, oldname);
--#endif
-- if (((depth == ctxt->nameNr) && (xmlStrEqual(oldname, ctxt->name))) ||
-- (name == NULL)) {
-- if (CUR == '>')
-- NEXT;
-- if (oldname != NULL)
-- xmlFree(oldname);
-- return;
-- }
-- if (oldname != NULL)
-- xmlFree(oldname);
--
-- /*
-- * Lookup the info for that element.
-- */
-- info = htmlTagLookup(name);
-- if (info == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
-- name);
-- ctxt->wellFormed = 0;
-- } else if (info->depr) {
--/***************************
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData, "Tag %s is deprecated\n",
-- name);
-- ***************************/
-- }
--
-- /*
-- * Check for an Empty Element labelled the XML/SGML way
-- */
-- if ((CUR == '/') && (NXT(1) == '>')) {
-- SKIP(2);
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, name);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n", oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- return;
-- }
--
-- if (CUR == '>') {
-- NEXT;
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Couldn't find end of Start Tag %s\n",
-- name);
-- ctxt->wellFormed = 0;
--
-- /*
-- * end of parsing of this node.
-- */
-- if (xmlStrEqual(name, ctxt->name)) {
-- nodePop(ctxt);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of start tag problem: popping out %s\n", oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- }
--
-- /*
-- * Capture end position and add node
-- */
-- if ( currentNode != NULL && ctxt->record_info ) {
-- node_info.end_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.end_line = ctxt->input->line;
-- node_info.node = ctxt->node;
-- xmlParserAddNodeInfo(ctxt, &node_info);
-- }
-- return;
-- }
--
-- /*
-- * Check for an Empty Element from DTD definition
-- */
-- if ((info != NULL) && (info->empty)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, name);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- return;
-- }
--
-- /*
-- * Parse the content of the element:
-- */
-- currentNode = xmlStrdup(ctxt->name);
-- depth = ctxt->nameNr;
-- while (IS_CHAR(CUR)) {
-- htmlParseContent(ctxt);
-- if (ctxt->nameNr < depth) break;
-- }
--
-- if (!IS_CHAR(CUR)) {
-- /************
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Premature end of data in tag %s\n", currentNode);
-- ctxt->wellFormed = 0;
-- *************/
--
-- /*
-- * end of parsing of this node.
-- */
-- nodePop(ctxt);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"Premature end of tag %s : popping out %s\n", name, oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- if (currentNode != NULL)
-- xmlFree(currentNode);
-- return;
-- }
--
-- /*
-- * Capture end position and add node
-- */
-- if ( currentNode != NULL && ctxt->record_info ) {
-- node_info.end_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.end_line = ctxt->input->line;
-- node_info.node = ctxt->node;
-- xmlParserAddNodeInfo(ctxt, &node_info);
-- }
-- if (currentNode != NULL)
-- xmlFree(currentNode);
--}
--
--/**
-- * htmlParseDocument :
-- * @ctxt: an HTML parser context
-- *
-- * parse an HTML document (and build a tree if using the standard SAX
-- * interface).
-- *
-- * Returns 0, -1 in case of error. the parser context is augmented
-- * as a result of the parsing.
-- */
--
--int
--htmlParseDocument(htmlParserCtxtPtr ctxt) {
-- xmlDtdPtr dtd;
--
-- htmlDefaultSAXHandlerInit();
-- ctxt->html = 1;
--
-- GROW;
-- /*
-- * SAX: beginning of the document processing.
-- */
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
--
-- /*
-- * Wipe out everything which is before the first '<'
-- */
-- SKIP_BLANKS;
-- if (CUR == 0) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Document is empty\n");
-- ctxt->wellFormed = 0;
-- }
--
-- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
--
--
-- /*
-- * Parse possible comments before any content
-- */
-- while ((CUR == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '-') && (NXT(3) == '-')) {
-- htmlParseComment(ctxt);
-- SKIP_BLANKS;
-- }
--
--
-- /*
-- * Then possibly doc type declaration(s) and more Misc
-- * (doctypedecl Misc*)?
-- */
-- if ((CUR == '<') && (NXT(1) == '!') &&
-- (UPP(2) == 'D') && (UPP(3) == 'O') &&
-- (UPP(4) == 'C') && (UPP(5) == 'T') &&
-- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-- (UPP(8) == 'E')) {
-- htmlParseDocTypeDecl(ctxt);
-- }
-- SKIP_BLANKS;
--
-- /*
-- * Parse possible comments before any content
-- */
-- while ((CUR == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '-') && (NXT(3) == '-')) {
-- htmlParseComment(ctxt);
-- SKIP_BLANKS;
-- }
--
-- /*
-- * Time to start parsing the tree itself
-- */
-- htmlParseContent(ctxt);
--
-- /*
-- * autoclose
-- */
-- if (CUR == 0)
-- htmlAutoClose(ctxt, NULL);
--
--
-- /*
-- * SAX: end of the document processing.
-- */
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-- ctxt->sax->endDocument(ctxt->userData);
--
-- if (ctxt->myDoc != NULL) {
-- dtd = xmlGetIntSubset(ctxt->myDoc);
-- if (dtd == NULL)
-- ctxt->myDoc->intSubset =
-- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "HTML",
-- BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
-- BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
-- }
-- if (! ctxt->wellFormed) return(-1);
-- return(0);
--}
--
--
--/************************************************************************
-- * *
-- * Parser contexts handling *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlInitParserCtxt:
-- * @ctxt: an HTML parser context
-- *
-- * Initialize a parser context
-- */
--
--void
--htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
--{
-- htmlSAXHandler *sax;
--
-- if (ctxt == NULL) return;
-- memset(ctxt, 0, sizeof(htmlParserCtxt));
--
-- sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
-- if (sax == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlInitParserCtxt: out of memory\n");
-- }
-- else
-- memset(sax, 0, sizeof(htmlSAXHandler));
--
-- /* Allocate the Input stack */
-- ctxt->inputTab = (htmlParserInputPtr *)
-- xmlMalloc(5 * sizeof(htmlParserInputPtr));
-- if (ctxt->inputTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlInitParserCtxt: out of memory\n");
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- return;
-- }
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 5;
-- ctxt->input = NULL;
-- ctxt->version = NULL;
-- ctxt->encoding = NULL;
-- ctxt->standalone = -1;
-- ctxt->instate = XML_PARSER_START;
--
-- /* Allocate the Node stack */
-- ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
-- if (ctxt->nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlInitParserCtxt: out of memory\n");
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 0;
-- ctxt->node = NULL;
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- return;
-- }
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 10;
-- ctxt->node = NULL;
--
-- /* Allocate the Name stack */
-- ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
-- if (ctxt->nameTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlInitParserCtxt: out of memory\n");
-- ctxt->nameNr = 0;
-- ctxt->nameMax = 10;
-- ctxt->name = NULL;
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 0;
-- ctxt->node = NULL;
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- return;
-- }
-- ctxt->nameNr = 0;
-- ctxt->nameMax = 10;
-- ctxt->name = NULL;
--
-- if (sax == NULL) ctxt->sax = &htmlDefaultSAXHandler;
-- else {
-- ctxt->sax = sax;
-- memcpy(sax, &htmlDefaultSAXHandler, sizeof(htmlSAXHandler));
-- }
-- ctxt->userData = ctxt;
-- ctxt->myDoc = NULL;
-- ctxt->wellFormed = 1;
-- ctxt->replaceEntities = 0;
-- ctxt->html = 1;
-- ctxt->record_info = 0;
-- ctxt->validate = 0;
-- ctxt->nbChars = 0;
-- ctxt->checkIndex = 0;
-- xmlInitNodeInfoSeq(&ctxt->node_seq);
--}
--
--/**
-- * htmlFreeParserCtxt:
-- * @ctxt: an HTML parser context
-- *
-- * Free all the memory used by a parser context. However the parsed
-- * document in ctxt->myDoc is not freed.
-- */
--
--void
--htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)
--{
-- xmlFreeParserCtxt(ctxt);
--}
--
--/**
-- * htmlCreateDocParserCtxt :
-- * @cur: a pointer to an array of xmlChar
-- * @encoding: a free form C string describing the HTML document encoding, or NULL
-- *
-- * Create a parser context for an HTML document.
-- *
-- * Returns the new parser context or NULL
-- */
--htmlParserCtxtPtr
--htmlCreateDocParserCtxt(xmlChar *cur, const char *encoding) {
-- htmlParserCtxtPtr ctxt;
-- htmlParserInputPtr input;
-- /* htmlCharEncoding enc; */
--
-- ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
-- if (ctxt == NULL) {
-- perror("malloc");
-- return(NULL);
-- }
-- htmlInitParserCtxt(ctxt);
-- input = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
-- if (input == NULL) {
-- perror("malloc");
-- xmlFree(ctxt);
-- return(NULL);
-- }
-- memset(input, 0, sizeof(htmlParserInput));
--
-- input->line = 1;
-- input->col = 1;
-- input->base = cur;
-- input->cur = cur;
--
-- inputPush(ctxt, input);
-- return(ctxt);
--}
--
--/************************************************************************
-- * *
-- * Progressive parsing interfaces *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlParseLookupSequence:
-- * @ctxt: an HTML parser context
-- * @first: the first char to lookup
-- * @next: the next char to lookup or zero
-- * @third: the next char to lookup or zero
-- *
-- * Try to find if a sequence (first, next, third) or just (first next) or
-- * (first) is available in the input stream.
-- * This function has a side effect of (possibly) incrementing ctxt->checkIndex
-- * to avoid rescanning sequences of bytes, it DOES change the state of the
-- * parser, do not use liberally.
-- * This is basically similar to xmlParseLookupSequence()
-- *
-- * Returns the index to the current parsing point if the full sequence
-- * is available, -1 otherwise.
-- */
--int
--htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
-- xmlChar next, xmlChar third) {
-- int base, len;
-- htmlParserInputPtr in;
-- const xmlChar *buf;
--
-- in = ctxt->input;
-- if (in == NULL) return(-1);
-- base = in->cur - in->base;
-- if (base < 0) return(-1);
-- if (ctxt->checkIndex > base)
-- base = ctxt->checkIndex;
-- if (in->buf == NULL) {
-- buf = in->base;
-- len = in->length;
-- } else {
-- buf = in->buf->buffer->content;
-- len = in->buf->buffer->use;
-- }
-- /* take into account the sequence length */
-- if (third) len -= 2;
-- else if (next) len --;
-- for (;base < len;base++) {
-- if (buf[base] == first) {
-- if (third != 0) {
-- if ((buf[base + 1] != next) ||
-- (buf[base + 2] != third)) continue;
-- } else if (next != 0) {
-- if (buf[base + 1] != next) continue;
-- }
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- if (next == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: lookup '%c' found at %d\n",
-- first, base);
-- else if (third == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: lookup '%c%c' found at %d\n",
-- first, next, base);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: lookup '%c%c%c' found at %d\n",
-- first, next, third, base);
--#endif
-- return(base - (in->cur - in->base));
-- }
-- }
-- ctxt->checkIndex = base;
--#ifdef DEBUG_PUSH
-- if (next == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: lookup '%c' failed\n", first);
-- else if (third == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: lookup '%c%c' failed\n", first, next);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: lookup '%c%c%c' failed\n", first, next, third);
--#endif
-- return(-1);
--}
--
--/**
-- * htmlParseTryOrFinish:
-- * @ctxt: an HTML parser context
-- * @terminate: last chunk indicator
-- *
-- * Try to progress on parsing
-- *
-- * Returns zero if no parsing was possible
-- */
--int
--htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
-- int ret = 0;
-- htmlParserInputPtr in;
-- int avail = 0;
-- xmlChar cur, next;
--
--#ifdef DEBUG_PUSH
-- switch (ctxt->instate) {
-- case XML_PARSER_EOF:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try EOF\n"); break;
-- case XML_PARSER_START:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try START\n"); break;
-- case XML_PARSER_MISC:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try MISC\n");break;
-- case XML_PARSER_COMMENT:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try COMMENT\n");break;
-- case XML_PARSER_PROLOG:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try PROLOG\n");break;
-- case XML_PARSER_START_TAG:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try START_TAG\n");break;
-- case XML_PARSER_CONTENT:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try CONTENT\n");break;
-- case XML_PARSER_CDATA_SECTION:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try CDATA_SECTION\n");break;
-- case XML_PARSER_END_TAG:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try END_TAG\n");break;
-- case XML_PARSER_ENTITY_DECL:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try ENTITY_DECL\n");break;
-- case XML_PARSER_ENTITY_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try ENTITY_VALUE\n");break;
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try ATTRIBUTE_VALUE\n");break;
-- case XML_PARSER_DTD:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try DTD\n");break;
-- case XML_PARSER_EPILOG:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try EPILOG\n");break;
-- case XML_PARSER_PI:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try PI\n");break;
-- case XML_PARSER_SYSTEM_LITERAL:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: try SYSTEM_LITERAL\n");break;
-- }
--#endif
--
-- while (1) {
--
-- in = ctxt->input;
-- if (in == NULL) break;
-- if (in->buf == NULL)
-- avail = in->length - (in->cur - in->base);
-- else
-- avail = in->buf->buffer->use - (in->cur - in->base);
-- if ((avail == 0) && (terminate)) {
-- htmlAutoClose(ctxt, NULL);
-- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
-- /*
-- * SAX: end of the document processing.
-- */
-- ctxt->instate = XML_PARSER_EOF;
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-- ctxt->sax->endDocument(ctxt->userData);
-- }
-- }
-- if (avail < 1)
-- goto done;
-- switch (ctxt->instate) {
-- case XML_PARSER_EOF:
-- /*
-- * Document parsing is done !
-- */
-- goto done;
-- case XML_PARSER_START:
-- /*
-- * Very first chars read from the document flow.
-- */
-- cur = in->cur[0];
-- if (IS_BLANK(cur)) {
-- SKIP_BLANKS;
-- if (in->buf == NULL)
-- avail = in->length - (in->cur - in->base);
-- else
-- avail = in->buf->buffer->use - (in->cur - in->base);
-- }
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData,
-- &xmlDefaultSAXLocator);
-- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
--
-- cur = in->cur[0];
-- next = in->cur[1];
-- if ((cur == '<') && (next == '!') &&
-- (UPP(2) == 'D') && (UPP(3) == 'O') &&
-- (UPP(4) == 'C') && (UPP(5) == 'T') &&
-- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-- (UPP(8) == 'E')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing internal subset\n");
--#endif
-- htmlParseDocTypeDecl(ctxt);
-- ctxt->instate = XML_PARSER_PROLOG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering PROLOG\n");
--#endif
-- } else {
-- ctxt->instate = XML_PARSER_MISC;
-- }
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering MISC\n");
--#endif
-- break;
-- case XML_PARSER_MISC:
-- SKIP_BLANKS;
-- if (in->buf == NULL)
-- avail = in->length - (in->cur - in->base);
-- else
-- avail = in->buf->buffer->use - (in->cur - in->base);
-- if (avail < 2)
-- goto done;
-- cur = in->cur[0];
-- next = in->cur[1];
-- if ((cur == '<') && (next == '!') &&
-- (in->cur[2] == '-') && (in->cur[3] == '-')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing Comment\n");
--#endif
-- htmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_MISC;
-- } else if ((cur == '<') && (next == '!') &&
-- (UPP(2) == 'D') && (UPP(3) == 'O') &&
-- (UPP(4) == 'C') && (UPP(5) == 'T') &&
-- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-- (UPP(8) == 'E')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing internal subset\n");
--#endif
-- htmlParseDocTypeDecl(ctxt);
-- ctxt->instate = XML_PARSER_PROLOG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering PROLOG\n");
--#endif
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 9)) {
-- goto done;
-- } else {
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering START_TAG\n");
--#endif
-- }
-- break;
-- case XML_PARSER_PROLOG:
-- SKIP_BLANKS;
-- if (in->buf == NULL)
-- avail = in->length - (in->cur - in->base);
-- else
-- avail = in->buf->buffer->use - (in->cur - in->base);
-- if (avail < 2)
-- goto done;
-- cur = in->cur[0];
-- next = in->cur[1];
-- if ((cur == '<') && (next == '!') &&
-- (in->cur[2] == '-') && (in->cur[3] == '-')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing Comment\n");
--#endif
-- htmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_PROLOG;
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 4)) {
-- goto done;
-- } else {
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering START_TAG\n");
--#endif
-- }
-- break;
-- case XML_PARSER_EPILOG:
-- if (in->buf == NULL)
-- avail = in->length - (in->cur - in->base);
-- else
-- avail = in->buf->buffer->use - (in->cur - in->base);
-- if (avail < 1)
-- goto done;
-- cur = in->cur[0];
-- if (IS_BLANK(cur)) {
-- htmlParseCharData(ctxt, 0);
-- goto done;
-- }
-- if (avail < 2)
-- goto done;
-- next = in->cur[1];
-- if ((cur == '<') && (next == '!') &&
-- (in->cur[2] == '-') && (in->cur[3] == '-')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing Comment\n");
--#endif
-- htmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_EPILOG;
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 4)) {
-- goto done;
-- } else {
-- ctxt->errNo = XML_ERR_DOCUMENT_END;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra content at the end of the document\n");
-- ctxt->wellFormed = 0;
-- ctxt->instate = XML_PARSER_EOF;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering EOF\n");
--#endif
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-- ctxt->sax->endDocument(ctxt->userData);
-- goto done;
-- }
-- break;
-- case XML_PARSER_START_TAG: {
-- xmlChar *name, *oldname;
-- int depth = ctxt->nameNr;
-- htmlElemDescPtr info;
--
-- if (avail < 2)
-- goto done;
-- cur = in->cur[0];
-- if (cur != '<') {
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- }
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
--
-- oldname = xmlStrdup(ctxt->name);
-- htmlParseStartTag(ctxt);
-- name = ctxt->name;
--#ifdef DEBUG
-- if (oldname == NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "Start of element %s\n", name);
-- else if (name == NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "Start of element failed, was %s\n",
-- oldname);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "Start of element %s, was %s\n",
-- name, oldname);
--#endif
-- if (((depth == ctxt->nameNr) &&
-- (xmlStrEqual(oldname, ctxt->name))) ||
-- (name == NULL)) {
-- if (CUR == '>')
-- NEXT;
-- if (oldname != NULL)
-- xmlFree(oldname);
-- break;
-- }
-- if (oldname != NULL)
-- xmlFree(oldname);
--
-- /*
-- * Lookup the info for that element.
-- */
-- info = htmlTagLookup(name);
-- if (info == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
-- name);
-- ctxt->wellFormed = 0;
-- } else if (info->depr) {
-- /***************************
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Tag %s is deprecated\n",
-- name);
-- ***************************/
-- }
--
-- /*
-- * Check for an Empty Element labelled the XML/SGML way
-- */
-- if ((CUR == '/') && (NXT(1) == '>')) {
-- SKIP(2);
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, name);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n",
-- oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- }
--
-- if (CUR == '>') {
-- NEXT;
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Couldn't find end of Start Tag %s\n",
-- name);
-- ctxt->wellFormed = 0;
--
-- /*
-- * end of parsing of this node.
-- */
-- if (xmlStrEqual(name, ctxt->name)) {
-- nodePop(ctxt);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,
-- "End of start tag problem: popping out %s\n", oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- }
--
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- }
--
-- /*
-- * Check for an Empty Element from DTD definition
-- */
-- if ((info != NULL) && (info->empty)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-- ctxt->sax->endElement(ctxt->userData, name);
-- oldname = htmlnamePop(ctxt);
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
--#endif
-- if (oldname != NULL)
-- xmlFree(oldname);
-- }
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- }
-- case XML_PARSER_CONTENT: {
-- long cons;
-- /*
-- * Handle preparsed entities and charRef
-- */
-- if (ctxt->token != 0) {
-- xmlChar chr[2] = { 0 , 0 } ;
--
-- chr[0] = (xmlChar) ctxt->token;
-- htmlCheckParagraph(ctxt);
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, chr, 1);
-- ctxt->token = 0;
-- ctxt->checkIndex = 0;
-- }
-- if ((avail == 1) && (terminate)) {
-- cur = in->cur[0];
-- if ((cur != '<') && (cur != '&')) {
-- if (ctxt->sax != NULL) {
-- if (IS_BLANK(cur)) {
-- if (ctxt->sax->ignorableWhitespace != NULL)
-- ctxt->sax->ignorableWhitespace(
-- ctxt->userData, &cur, 1);
-- } else {
-- htmlCheckParagraph(ctxt);
-- if (ctxt->sax->characters != NULL)
-- ctxt->sax->characters(
-- ctxt->userData, &cur, 1);
-- }
-- }
-- ctxt->token = 0;
-- ctxt->checkIndex = 0;
-- NEXT;
-- }
-- break;
-- }
-- if (avail < 2)
-- goto done;
-- cur = in->cur[0];
-- next = in->cur[1];
-- cons = ctxt->nbChars;
-- if ((xmlStrEqual(ctxt->name, BAD_CAST"script")) ||
-- (xmlStrEqual(ctxt->name, BAD_CAST"style"))) {
-- /*
-- * Handle SCRIPT/STYLE separately
-- */
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '<', '/', 0) < 0))
-- goto done;
-- htmlParseScript(ctxt);
-- if ((cur == '<') && (next == '/')) {
-- ctxt->instate = XML_PARSER_END_TAG;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering END_TAG\n");
--#endif
-- break;
-- }
-- } else {
-- /*
-- * Sometimes DOCTYPE arrives in the middle of the document
-- */
-- if ((cur == '<') && (next == '!') &&
-- (UPP(2) == 'D') && (UPP(3) == 'O') &&
-- (UPP(4) == 'C') && (UPP(5) == 'T') &&
-- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-- (UPP(8) == 'E')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Misplaced DOCTYPE declaration\n");
-- ctxt->wellFormed = 0;
-- htmlParseDocTypeDecl(ctxt);
-- } else if ((cur == '<') && (next == '!') &&
-- (in->cur[2] == '-') && (in->cur[3] == '-')) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing Comment\n");
--#endif
-- htmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_CONTENT;
-- } else if ((cur == '<') && (next == '!') && (avail < 4)) {
-- goto done;
-- } else if ((cur == '<') && (next == '/')) {
-- ctxt->instate = XML_PARSER_END_TAG;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering END_TAG\n");
--#endif
-- break;
-- } else if (cur == '<') {
-- ctxt->instate = XML_PARSER_START_TAG;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering START_TAG\n");
--#endif
-- break;
-- } else if (cur == '&') {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing Reference\n");
--#endif
-- /* TODO: check generation of subtrees if noent !!! */
-- htmlParseReference(ctxt);
-- } else {
-- /* TODO Avoid the extra copy, handle directly !!!!!! */
-- /*
-- * Goal of the following test is :
-- * - minimize calls to the SAX 'character' callback
-- * when they are mergeable
-- */
-- if ((ctxt->inputNr == 1) &&
-- (avail < HTML_PARSER_BIG_BUFFER_SIZE)) {
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
-- goto done;
-- }
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: Parsing char data\n");
--#endif
-- htmlParseCharData(ctxt, 0);
-- }
-- }
-- if (cons == ctxt->nbChars) {
-- if (ctxt->node != NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "detected an error in element content\n");
-- ctxt->wellFormed = 0;
-- }
-- NEXT;
-- break;
-- }
--
-- break;
-- }
-- case XML_PARSER_END_TAG:
-- if (avail < 2)
-- goto done;
-- if ((!terminate) &&
-- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
-- htmlParseEndTag(ctxt);
-- if (ctxt->nameNr == 0) {
-- ctxt->instate = XML_PARSER_EPILOG;
-- } else {
-- ctxt->instate = XML_PARSER_CONTENT;
-- }
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_CDATA_SECTION:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == CDATA\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_DTD:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == DTD\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_COMMENT:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == COMMENT\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_PI:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == PI\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_ENTITY_DECL:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == ENTITY_DECL\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_ENTITY_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == ENTITY_VALUE\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering DTD\n");
--#endif
-- break;
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == ATTRIBUTE_VALUE\n");
-- ctxt->instate = XML_PARSER_START_TAG;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering START_TAG\n");
--#endif
-- break;
-- case XML_PARSER_SYSTEM_LITERAL:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == XML_PARSER_SYSTEM_LITERAL\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_IGNORE:
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: internal error, state == XML_PARSER_IGNORE\n");
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "HPP: entering CONTENT\n");
--#endif
-- break;
-- }
-- }
--done:
-- if ((avail == 0) && (terminate)) {
-- htmlAutoClose(ctxt, NULL);
-- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
-- /*
-- * SAX: end of the document processing.
-- */
-- ctxt->instate = XML_PARSER_EOF;
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-- ctxt->sax->endDocument(ctxt->userData);
-- }
-- }
-- if ((ctxt->myDoc != NULL) &&
-- ((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
-- (ctxt->instate == XML_PARSER_EPILOG))) {
-- xmlDtdPtr dtd;
-- dtd = xmlGetIntSubset(ctxt->myDoc);
-- if (dtd == NULL)
-- ctxt->myDoc->intSubset =
-- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "HTML",
-- BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
-- BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
-- }
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext, "HPP: done %d\n", ret);
--#endif
-- return(ret);
--}
--
--/**
-- * htmlParseTry:
-- * @ctxt: an HTML parser context
-- *
-- * Try to progress on parsing
-- *
-- * Returns zero if no parsing was possible
-- */
--int
--htmlParseTry(htmlParserCtxtPtr ctxt) {
-- return(htmlParseTryOrFinish(ctxt, 0));
--}
--
--/**
-- * htmlParseChunk:
-- * @ctxt: an XML parser context
-- * @chunk: an char array
-- * @size: the size in byte of the chunk
-- * @terminate: last chunk indicator
-- *
-- * Parse a Chunk of memory
-- *
-- * Returns zero if no error, the xmlParserErrors otherwise.
-- */
--int
--htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
-- int terminate) {
-- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
-- int base = ctxt->input->base - ctxt->input->buf->buffer->content;
-- int cur = ctxt->input->cur - ctxt->input->base;
--
-- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-- ctxt->input->base = ctxt->input->buf->buffer->content + base;
-- ctxt->input->cur = ctxt->input->base + cur;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
--#endif
--
-- if ((terminate) || (ctxt->input->buf->buffer->use > 80))
-- htmlParseTryOrFinish(ctxt, terminate);
-- } else if (ctxt->instate != XML_PARSER_EOF) {
-- xmlParserInputBufferPush(ctxt->input->buf, 0, "");
-- htmlParseTryOrFinish(ctxt, terminate);
-- }
-- if (terminate) {
-- if ((ctxt->instate != XML_PARSER_EOF) &&
-- (ctxt->instate != XML_PARSER_EPILOG) &&
-- (ctxt->instate != XML_PARSER_MISC)) {
-- ctxt->errNo = XML_ERR_DOCUMENT_END;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra content at the end of the document\n");
-- ctxt->wellFormed = 0;
-- }
-- if (ctxt->instate != XML_PARSER_EOF) {
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-- ctxt->sax->endDocument(ctxt->userData);
-- }
-- ctxt->instate = XML_PARSER_EOF;
-- }
-- return((xmlParserErrors) ctxt->errNo);
--}
--
--/************************************************************************
-- * *
-- * User entry points *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlCreatePushParserCtxt :
-- * @sax: a SAX handler
-- * @user_data: The user data returned on SAX callbacks
-- * @chunk: a pointer to an array of chars
-- * @size: number of chars in the array
-- * @filename: an optional file name or URI
-- * @enc: an optional encoding
-- *
-- * Create a parser context for using the HTML parser in push mode
-- * To allow content encoding detection, @size should be >= 4
-- * The value of @filename is used for fetching external entities
-- * and error/warning reports.
-- *
-- * Returns the new parser context or NULL
-- */
--htmlParserCtxtPtr
--htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
-- const char *chunk, int size, const char *filename,
-- xmlCharEncoding enc) {
-- htmlParserCtxtPtr ctxt;
-- htmlParserInputPtr inputStream;
-- xmlParserInputBufferPtr buf;
--
-- buf = xmlAllocParserInputBuffer(enc);
-- if (buf == NULL) return(NULL);
--
-- ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
-- if (ctxt == NULL) {
-- xmlFree(buf);
-- return(NULL);
-- }
-- memset(ctxt, 0, sizeof(htmlParserCtxt));
-- htmlInitParserCtxt(ctxt);
-- if (sax != NULL) {
-- if (ctxt->sax != &htmlDefaultSAXHandler)
-- xmlFree(ctxt->sax);
-- ctxt->sax = (htmlSAXHandlerPtr) xmlMalloc(sizeof(htmlSAXHandler));
-- if (ctxt->sax == NULL) {
-- xmlFree(buf);
-- xmlFree(ctxt);
-- return(NULL);
-- }
-- memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
-- if (user_data != NULL)
-- ctxt->userData = user_data;
-- }
-- if (filename == NULL) {
-- ctxt->directory = NULL;
-- } else {
-- ctxt->directory = xmlParserGetDirectory(filename);
-- }
--
-- inputStream = htmlNewInputStream(ctxt);
-- if (inputStream == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- if (filename == NULL)
-- inputStream->filename = NULL;
-- else
-- inputStream->filename = xmlMemStrdup(filename);
-- inputStream->buf = buf;
-- inputStream->base = inputStream->buf->buffer->content;
-- inputStream->cur = inputStream->buf->buffer->content;
--
-- inputPush(ctxt, inputStream);
--
-- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-- (ctxt->input->buf != NULL)) {
-- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
--#endif
-- }
--
-- return(ctxt);
--}
--
--/**
-- * htmlSAXParseDoc :
-- * @cur: a pointer to an array of xmlChar
-- * @encoding: a free form C string describing the HTML document encoding, or NULL
-- * @sax: the SAX handler block
-- * @userData: if using SAX, this pointer will be provided on callbacks.
-- *
-- * parse an HTML in-memory document and build a tree.
-- * It use the given SAX function block to handle the parsing callback.
-- * If sax is NULL, fallback to the default DOM tree building routines.
-- *
-- * Returns the resulting document tree
-- */
--
--htmlDocPtr
--htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData) {
-- htmlDocPtr ret;
-- htmlParserCtxtPtr ctxt;
--
-- if (cur == NULL) return(NULL);
--
--
-- ctxt = htmlCreateDocParserCtxt(cur, encoding);
-- if (ctxt == NULL) return(NULL);
-- if (sax != NULL) {
-- ctxt->sax = sax;
-- ctxt->userData = userData;
-- }
--
-- htmlParseDocument(ctxt);
-- ret = ctxt->myDoc;
-- if (sax != NULL) {
-- ctxt->sax = NULL;
-- ctxt->userData = NULL;
-- }
-- htmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * htmlParseDoc :
-- * @cur: a pointer to an array of xmlChar
-- * @encoding: a free form C string describing the HTML document encoding, or NULL
-- *
-- * parse an HTML in-memory document and build a tree.
-- *
-- * Returns the resulting document tree
-- */
--
--htmlDocPtr
--htmlParseDoc(xmlChar *cur, const char *encoding) {
-- return(htmlSAXParseDoc(cur, encoding, NULL, NULL));
--}
--
--
--/**
-- * htmlCreateFileParserCtxt :
-- * @filename: the filename
-- * @encoding: a free form C string describing the HTML document encoding, or NULL
-- *
-- * Create a parser context for a file content.
-- * Automatic support for ZLIB/Compress compressed document is provided
-- * by default if found at compile-time.
-- *
-- * Returns the new parser context or NULL
-- */
--htmlParserCtxtPtr
--htmlCreateFileParserCtxt(const char *filename, const char *encoding)
--{
-- htmlParserCtxtPtr ctxt;
-- htmlParserInputPtr inputStream;
-- xmlParserInputBufferPtr buf;
-- /* htmlCharEncoding enc; */
-- xmlChar *content, *content_line = (xmlChar *) "charset=";
--
-- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-- if (buf == NULL) return(NULL);
--
-- ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
-- if (ctxt == NULL) {
-- perror("malloc");
-- return(NULL);
-- }
-- memset(ctxt, 0, sizeof(htmlParserCtxt));
-- htmlInitParserCtxt(ctxt);
-- inputStream = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
-- if (inputStream == NULL) {
-- perror("malloc");
-- xmlFree(ctxt);
-- return(NULL);
-- }
-- memset(inputStream, 0, sizeof(htmlParserInput));
--
-- inputStream->filename = xmlMemStrdup(filename);
-- inputStream->line = 1;
-- inputStream->col = 1;
-- inputStream->buf = buf;
-- inputStream->directory = NULL;
--
-- inputStream->base = inputStream->buf->buffer->content;
-- inputStream->cur = inputStream->buf->buffer->content;
-- inputStream->free = NULL;
--
-- inputPush(ctxt, inputStream);
--
-- /* set encoding */
-- if (encoding) {
-- content = xmlMalloc (xmlStrlen(content_line) + strlen(encoding) + 1);
-- if (content) {
-- strcpy ((char *)content, (char *)content_line);
-- strcat ((char *)content, (char *)encoding);
-- htmlCheckEncoding (ctxt, content);
-- xmlFree (content);
-- }
-- }
--
-- return(ctxt);
--}
--
--/**
-- * htmlSAXParseFile :
-- * @filename: the filename
-- * @encoding: a free form C string describing the HTML document encoding, or NULL
-- * @sax: the SAX handler block
-- * @userData: if using SAX, this pointer will be provided on callbacks.
-- *
-- * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
-- * compressed document is provided by default if found at compile-time.
-- * It use the given SAX function block to handle the parsing callback.
-- * If sax is NULL, fallback to the default DOM tree building routines.
-- *
-- * Returns the resulting document tree
-- */
--
--htmlDocPtr
--htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
-- void *userData) {
-- htmlDocPtr ret;
-- htmlParserCtxtPtr ctxt;
-- htmlSAXHandlerPtr oldsax = NULL;
--
-- ctxt = htmlCreateFileParserCtxt(filename, encoding);
-- if (ctxt == NULL) return(NULL);
-- if (sax != NULL) {
-- oldsax = ctxt->sax;
-- ctxt->sax = sax;
-- ctxt->userData = userData;
-- }
--
-- htmlParseDocument(ctxt);
--
-- ret = ctxt->myDoc;
-- if (sax != NULL) {
-- ctxt->sax = oldsax;
-- ctxt->userData = NULL;
-- }
-- htmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * htmlParseFile :
-- * @filename: the filename
-- * @encoding: a free form C string describing the HTML document encoding, or NULL
-- *
-- * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
-- * compressed document is provided by default if found at compile-time.
-- *
-- * Returns the resulting document tree
-- */
--
--htmlDocPtr
--htmlParseFile(const char *filename, const char *encoding) {
-- return(htmlSAXParseFile(filename, encoding, NULL, NULL));
--}
--
--/**
-- * htmlHandleOmittedElem:
-- * @val: int 0 or 1
-- *
-- * Set and return the previous value for handling HTML omitted tags.
-- *
-- * Returns the last value for 0 for no handling, 1 for auto insertion.
-- */
--
--int
--htmlHandleOmittedElem(int val) {
-- int old = htmlOmittedDefaultValue;
--
-- htmlOmittedDefaultValue = val;
-- return(old);
--}
--
--#endif /* LIBXML_HTML_ENABLED */
-diff -Nru libxml2-2.3.0/HTMLtree.c libxml2-2.3.0.new/HTMLtree.c
---- libxml2-2.3.0/HTMLtree.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/HTMLtree.c Thu Jan 1 01:00:00 1970
-@@ -1,1132 +0,0 @@
--/*
-- * HTMLtree.c : implemetation of access function for an HTML tree.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_HTML_ENABLED
--
--#include <stdio.h>
--#include <string.h> /* for memset() only ! */
--
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/HTMLparser.h>
--#include <libxml/HTMLtree.h>
--#include <libxml/entities.h>
--#include <libxml/valid.h>
--#include <libxml/xmlerror.h>
--#include <libxml/parserInternals.h>
--
--/************************************************************************
-- * *
-- * Getting/Setting encoding meta tags *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlGetMetaEncoding:
-- * @doc: the document
-- *
-- * Encoding definition lookup in the Meta tags
-- *
-- * Returns the current encoding as flagged in the HTML source
-- */
--const xmlChar *
--htmlGetMetaEncoding(htmlDocPtr doc) {
-- htmlNodePtr cur;
-- const xmlChar *content;
-- const xmlChar *encoding;
--
-- if (doc == NULL)
-- return(NULL);
-- cur = doc->children;
--
-- /*
-- * Search the html
-- */
-- while (cur != NULL) {
-- if (cur->name != NULL) {
-- if (xmlStrEqual(cur->name, BAD_CAST"html"))
-- break;
-- if (xmlStrEqual(cur->name, BAD_CAST"head"))
-- goto found_head;
-- if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-- goto found_meta;
-- }
-- cur = cur->next;
-- }
-- if (cur == NULL)
-- return(NULL);
-- cur = cur->children;
--
-- /*
-- * Search the head
-- */
-- while (cur != NULL) {
-- if (cur->name != NULL) {
-- if (xmlStrEqual(cur->name, BAD_CAST"head"))
-- break;
-- if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-- goto found_meta;
-- }
-- cur = cur->next;
-- }
-- if (cur == NULL)
-- return(NULL);
--found_head:
-- cur = cur->children;
--
-- /*
-- * Search the meta elements
-- */
--found_meta:
-- while (cur != NULL) {
-- if (cur->name != NULL) {
-- if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
-- xmlAttrPtr attr = cur->properties;
-- int http;
-- const xmlChar *value;
--
-- content = NULL;
-- http = 0;
-- while (attr != NULL) {
-- if ((attr->children != NULL) &&
-- (attr->children->type == XML_TEXT_NODE) &&
-- (attr->children->next == NULL)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- value = attr->children->content;
--#else
-- value = xmlBufferContent(attr->children->content);
--#endif
-- if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
-- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
-- http = 1;
-- else if ((value != NULL)
-- && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
-- content = value;
-- if ((http != 0) && (content != NULL))
-- goto found_content;
-- }
-- attr = attr->next;
-- }
-- }
-- }
-- cur = cur->next;
-- }
-- return(NULL);
--
--found_content:
-- encoding = xmlStrstr(content, BAD_CAST"charset=");
-- if (encoding == NULL)
-- encoding = xmlStrstr(content, BAD_CAST"Charset=");
-- if (encoding == NULL)
-- encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
-- if (encoding != NULL) {
-- encoding += 8;
-- } else {
-- encoding = xmlStrstr(content, BAD_CAST"charset =");
-- if (encoding == NULL)
-- encoding = xmlStrstr(content, BAD_CAST"Charset =");
-- if (encoding == NULL)
-- encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
-- if (encoding != NULL)
-- encoding += 9;
-- }
-- if (encoding != NULL) {
-- while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
-- }
-- return(encoding);
--}
--
--/**
-- * htmlSetMetaEncoding:
-- * @doc: the document
-- * @encoding: the encoding string
-- *
-- * Sets the current encoding in the Meta tags
-- * NOTE: this will not change the document content encoding, just
-- * the META flag associated.
-- *
-- * Returns 0 in case of success and -1 in case of error
-- */
--int
--htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
-- htmlNodePtr cur, meta;
-- const xmlChar *content;
-- char newcontent[100];
--
--
-- if (doc == NULL)
-- return(-1);
--
-- if (encoding != NULL) {
--#ifdef HAVE_SNPRINTF
-- snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
-- encoding);
--#else
-- sprintf(newcontent, "text/html; charset=%s", encoding);
--#endif
-- newcontent[sizeof(newcontent) - 1] = 0;
-- }
--
-- cur = doc->children;
--
-- /*
-- * Search the html
-- */
-- while (cur != NULL) {
-- if (cur->name != NULL) {
-- if (xmlStrEqual(cur->name, BAD_CAST"html"))
-- break;
-- if (xmlStrEqual(cur->name, BAD_CAST"body")) {
-- if (encoding == NULL)
-- return(0);
-- meta = xmlNewDocNode(doc, NULL, BAD_CAST"head", NULL);
-- xmlAddPrevSibling(cur, meta);
-- cur = meta;
-- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-- xmlAddChild(cur, meta);
-- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-- return(0);
-- }
-- if (xmlStrEqual(cur->name, BAD_CAST"head"))
-- goto found_head;
-- if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-- goto found_meta;
-- }
-- cur = cur->next;
-- }
-- if (cur == NULL)
-- return(-1);
-- cur = cur->children;
--
-- /*
-- * Search the head
-- */
-- while (cur != NULL) {
-- if (cur->name != NULL) {
-- if (xmlStrEqual(cur->name, BAD_CAST"head"))
-- break;
-- if (xmlStrEqual(cur->name, BAD_CAST"body")) {
-- if (encoding == NULL)
-- return(0);
-- meta = xmlNewDocNode(doc, NULL, BAD_CAST"head", NULL);
-- xmlAddPrevSibling(cur, meta);
-- cur = meta;
-- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-- xmlAddChild(cur, meta);
-- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-- return(0);
-- }
-- if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-- goto found_meta;
-- }
-- cur = cur->next;
-- }
-- if (cur == NULL)
-- return(-1);
--found_head:
-- if (cur->children == NULL) {
-- if (encoding == NULL)
-- return(0);
-- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-- xmlAddChild(cur, meta);
-- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-- return(0);
-- }
-- cur = cur->children;
--
--found_meta:
-- if (encoding != NULL) {
-- /*
-- * Create a new Meta element with the right aatributes
-- */
--
-- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-- xmlAddPrevSibling(cur, meta);
-- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-- }
--
-- /*
-- * Search and destroy all the remaining the meta elements carrying
-- * encoding informations
-- */
-- while (cur != NULL) {
-- if (cur->name != NULL) {
-- if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
-- xmlAttrPtr attr = cur->properties;
-- int http;
-- const xmlChar *value;
--
-- content = NULL;
-- http = 0;
-- while (attr != NULL) {
-- if ((attr->children != NULL) &&
-- (attr->children->type == XML_TEXT_NODE) &&
-- (attr->children->next == NULL)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- value = attr->children->content;
--#else
-- value = xmlBufferContent(attr->children->content);
--#endif
-- if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
-- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
-- http = 1;
-- else if ((value != NULL)
-- && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
-- content = value;
-- if ((http != 0) && (content != NULL))
-- break;
-- }
-- attr = attr->next;
-- }
-- if ((http != 0) && (content != NULL)) {
-- meta = cur;
-- cur = cur->next;
-- xmlUnlinkNode(meta);
-- xmlFreeNode(meta);
-- continue;
-- }
--
-- }
-- }
-- cur = cur->next;
-- }
-- return(0);
--}
--
--/************************************************************************
-- * *
-- * Dumping HTML tree content to a simple buffer *
-- * *
-- ************************************************************************/
--
--static void
--htmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur);
--
--/**
-- * htmlDtdDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- *
-- * Dump the HTML document DTD, if any.
-- */
--static void
--htmlDtdDump(xmlBufferPtr buf, xmlDocPtr doc) {
-- xmlDtdPtr cur = doc->intSubset;
--
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlDtdDump : no internal subset\n");
-- return;
-- }
-- xmlBufferWriteChar(buf, "<!DOCTYPE ");
-- xmlBufferWriteCHAR(buf, cur->name);
-- if (cur->ExternalID != NULL) {
-- xmlBufferWriteChar(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf, cur->ExternalID);
-- if (cur->SystemID != NULL) {
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteQuotedString(buf, cur->SystemID);
-- }
-- } else if (cur->SystemID != NULL) {
-- xmlBufferWriteChar(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf, cur->SystemID);
-- }
-- xmlBufferWriteChar(buf, ">\n");
--}
--
--/**
-- * htmlAttrDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the attribute pointer
-- *
-- * Dump an HTML attribute
-- */
--static void
--htmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-- xmlChar *value;
--
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlAttrDump : property == NULL\n");
-- return;
-- }
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteCHAR(buf, cur->name);
-- if (cur->children != NULL) {
-- value = xmlNodeListGetString(doc, cur->children, 0);
-- if (value) {
-- xmlBufferWriteChar(buf, "=");
-- xmlBufferWriteQuotedString(buf, value);
-- xmlFree(value);
-- } else {
-- xmlBufferWriteChar(buf, "=\"\"");
-- }
-- }
--}
--
--/**
-- * htmlAttrListDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the first attribute pointer
-- *
-- * Dump a list of HTML attributes
-- */
--static void
--htmlAttrListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlAttrListDump : property == NULL\n");
-- return;
-- }
-- while (cur != NULL) {
-- htmlAttrDump(buf, doc, cur);
-- cur = cur->next;
-- }
--}
--
--
--void
--htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur);
--/**
-- * htmlNodeListDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the first node
-- *
-- * Dump an HTML node list, recursive behaviour,children are printed too.
-- */
--static void
--htmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlNodeListDump : node == NULL\n");
-- return;
-- }
-- while (cur != NULL) {
-- htmlNodeDump(buf, doc, cur);
-- cur = cur->next;
-- }
--}
--
--/**
-- * htmlNodeDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the current node
-- *
-- * Dump an HTML node, recursive behaviour,children are printed too.
-- */
--void
--htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
-- htmlElemDescPtr info;
--
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlNodeDump : node == NULL\n");
-- return;
-- }
-- /*
-- * Special cases.
-- */
-- if (cur->type == XML_DTD_NODE)
-- return;
-- if (cur->type == XML_HTML_DOCUMENT_NODE) {
-- htmlDocContentDump(buf, (xmlDocPtr) cur);
-- return;
-- }
-- if (cur->type == HTML_TEXT_NODE) {
-- if (cur->content != NULL) {
-- if ((cur->name == xmlStringText) ||
-- (cur->name != xmlStringTextNoenc)) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
--#else
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlBufferWriteCHAR(buf, buffer);
-- xmlFree(buffer);
-- }
-- } else {
-- xmlBufferWriteCHAR(buf, cur->content);
-- }
-- }
-- return;
-- }
-- if (cur->type == HTML_COMMENT_NODE) {
-- if (cur->content != NULL) {
-- xmlBufferWriteChar(buf, "<!--");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlBufferWriteCHAR(buf, cur->content);
--#else
-- xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
--#endif
-- xmlBufferWriteChar(buf, "-->");
-- }
-- return;
-- }
-- if (cur->type == HTML_ENTITY_REF_NODE) {
-- xmlBufferWriteChar(buf, "&");
-- xmlBufferWriteCHAR(buf, cur->name);
-- xmlBufferWriteChar(buf, ";");
-- return;
-- }
--
-- /*
-- * Get specific HTmL info for taht node.
-- */
-- info = htmlTagLookup(cur->name);
--
-- xmlBufferWriteChar(buf, "<");
-- xmlBufferWriteCHAR(buf, cur->name);
-- if (cur->properties != NULL)
-- htmlAttrListDump(buf, doc, cur->properties);
--
-- if ((info != NULL) && (info->empty)) {
-- xmlBufferWriteChar(buf, ">");
-- if (cur->next != NULL) {
-- if ((cur->next->type != HTML_TEXT_NODE) &&
-- (cur->next->type != HTML_ENTITY_REF_NODE))
-- xmlBufferWriteChar(buf, "\n");
-- }
-- return;
-- }
-- if ((cur->content == NULL) && (cur->children == NULL)) {
-- if ((info != NULL) && (info->endTag != 0))
-- xmlBufferWriteChar(buf, ">");
-- else {
-- xmlBufferWriteChar(buf, "></");
-- xmlBufferWriteCHAR(buf, cur->name);
-- xmlBufferWriteChar(buf, ">");
-- }
-- if (cur->next != NULL) {
-- if ((cur->next->type != HTML_TEXT_NODE) &&
-- (cur->next->type != HTML_ENTITY_REF_NODE))
-- xmlBufferWriteChar(buf, "\n");
-- }
-- return;
-- }
-- xmlBufferWriteChar(buf, ">");
-- if (cur->content != NULL) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
--#else
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlBufferWriteCHAR(buf, buffer);
-- xmlFree(buffer);
-- }
-- }
-- if (cur->children != NULL) {
-- if ((cur->children->type != HTML_TEXT_NODE) &&
-- (cur->children->type != HTML_ENTITY_REF_NODE) &&
-- (cur->children != cur->last))
-- xmlBufferWriteChar(buf, "\n");
-- htmlNodeListDump(buf, doc, cur->children);
-- if ((cur->last->type != HTML_TEXT_NODE) &&
-- (cur->last->type != HTML_ENTITY_REF_NODE) &&
-- (cur->children != cur->last))
-- xmlBufferWriteChar(buf, "\n");
-- }
-- if (!htmlIsAutoClosed(doc, cur)) {
-- xmlBufferWriteChar(buf, "</");
-- xmlBufferWriteCHAR(buf, cur->name);
-- xmlBufferWriteChar(buf, ">");
-- }
-- if (cur->next != NULL) {
-- if ((cur->next->type != HTML_TEXT_NODE) &&
-- (cur->next->type != HTML_ENTITY_REF_NODE))
-- xmlBufferWriteChar(buf, "\n");
-- }
--}
--
--/**
-- * htmlNodeDumpFile:
-- * @out: the FILE pointer
-- * @doc: the document
-- * @cur: the current node
-- *
-- * Dump an HTML node, recursive behaviour,children are printed too.
-- */
--void
--htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
-- xmlBufferPtr buf;
--
-- buf = xmlBufferCreate();
-- if (buf == NULL) return;
-- htmlNodeDump(buf, doc, cur);
-- xmlBufferDump(out, buf);
-- xmlBufferFree(buf);
--}
--
--/**
-- * htmlDocContentDump:
-- * @buf: the HTML buffer output
-- * @cur: the document
-- *
-- * Dump an HTML document.
-- */
--static void
--htmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur) {
-- int type;
--
-- /*
-- * force to output the stuff as HTML, especially for entities
-- */
-- type = cur->type;
-- cur->type = XML_HTML_DOCUMENT_NODE;
-- if (cur->intSubset != NULL)
-- htmlDtdDump(buf, cur);
-- else {
-- /* Default to HTML-4.0 transitionnal @@@@ */
-- xmlBufferWriteChar(buf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">");
--
-- }
-- if (cur->children != NULL) {
-- htmlNodeListDump(buf, cur, cur->children);
-- }
-- xmlBufferWriteChar(buf, "\n");
-- cur->type = (xmlElementType) type;
--}
--
--/**
-- * htmlDocDumpMemory:
-- * @cur: the document
-- * @mem: OUT: the memory pointer
-- * @size: OUT: the memory lenght
-- *
-- * Dump an HTML document in memory and return the xmlChar * and it's size.
-- * It's up to the caller to free the memory.
-- */
--void
--htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
-- xmlBufferPtr buf;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlxmlDocDumpMemory : document == NULL\n");
--#endif
-- *mem = NULL;
-- *size = 0;
-- return;
-- }
-- buf = xmlBufferCreate();
-- if (buf == NULL) {
-- *mem = NULL;
-- *size = 0;
-- return;
-- }
-- htmlDocContentDump(buf, cur);
-- *mem = buf->content;
-- *size = buf->use;
-- memset(buf, -1, sizeof(xmlBuffer));
-- xmlFree(buf);
--}
--
--
--/************************************************************************
-- * *
-- * Dumping HTML tree content to an I/O output buffer *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlDtdDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- *
-- * Dump the HTML document DTD, if any.
-- */
--static void
--htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, const char *encoding) {
-- xmlDtdPtr cur = doc->intSubset;
--
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlDtdDump : no internal subset\n");
-- return;
-- }
-- xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- if (cur->ExternalID != NULL) {
-- xmlOutputBufferWriteString(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID);
-- if (cur->SystemID != NULL) {
-- xmlOutputBufferWriteString(buf, " ");
-- xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
-- }
-- } else if (cur->SystemID != NULL) {
-- xmlOutputBufferWriteString(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
-- }
-- xmlOutputBufferWriteString(buf, ">\n");
--}
--
--/**
-- * htmlAttrDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the attribute pointer
-- *
-- * Dump an HTML attribute
-- */
--static void
--htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
-- xmlChar *value;
--
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlAttrDump : property == NULL\n");
-- return;
-- }
-- xmlOutputBufferWriteString(buf, " ");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- if (cur->children != NULL) {
-- value = xmlNodeListGetString(doc, cur->children, 0);
-- if (value) {
-- xmlOutputBufferWriteString(buf, "=");
-- xmlBufferWriteQuotedString(buf->buffer, value);
-- xmlFree(value);
-- } else {
-- xmlOutputBufferWriteString(buf, "=\"\"");
-- }
-- }
--}
--
--/**
-- * htmlAttrListDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the first attribute pointer
-- *
-- * Dump a list of HTML attributes
-- */
--static void
--htmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlAttrListDump : property == NULL\n");
-- return;
-- }
-- while (cur != NULL) {
-- htmlAttrDumpOutput(buf, doc, cur, encoding);
-- cur = cur->next;
-- }
--}
--
--
--void htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
-- xmlNodePtr cur, const char *encoding);
--
--/**
-- * htmlNodeListDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the first node
-- *
-- * Dump an HTML node list, recursive behaviour,children are printed too.
-- */
--static void
--htmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const char *encoding) {
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlNodeListDump : node == NULL\n");
-- return;
-- }
-- while (cur != NULL) {
-- htmlNodeDumpOutput(buf, doc, cur, encoding);
-- cur = cur->next;
-- }
--}
--
--/**
-- * htmlNodeDump:
-- * @buf: the HTML buffer output
-- * @doc: the document
-- * @cur: the current node
-- *
-- * Dump an HTML node, recursive behaviour,children are printed too.
-- */
--void
--htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const char *encoding) {
-- htmlElemDescPtr info;
--
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlNodeDump : node == NULL\n");
-- return;
-- }
-- /*
-- * Special cases.
-- */
-- if (cur->type == XML_DTD_NODE)
-- return;
-- if (cur->type == XML_HTML_DOCUMENT_NODE) {
-- htmlDocContentDumpOutput(buf, (xmlDocPtr) cur, encoding);
-- return;
-- }
-- if (cur->type == HTML_TEXT_NODE) {
-- if (cur->content != NULL) {
-- if ((cur->name == xmlStringText) ||
-- (cur->name != xmlStringTextNoenc)) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
--#else
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlOutputBufferWriteString(buf, (const char *)buffer);
-- xmlFree(buffer);
-- }
-- } else {
-- xmlOutputBufferWriteString(buf, (const char *)cur->content);
-- }
-- }
-- return;
-- }
-- if (cur->type == HTML_COMMENT_NODE) {
-- if (cur->content != NULL) {
-- xmlOutputBufferWriteString(buf, "<!--");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *)cur->content);
--#else
-- xmlOutputBufferWriteString(buf, (const char *)
-- xmlBufferContent(cur->content));
--#endif
-- xmlOutputBufferWriteString(buf, "-->");
-- }
-- return;
-- }
-- if (cur->type == HTML_ENTITY_REF_NODE) {
-- xmlOutputBufferWriteString(buf, "&");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- xmlOutputBufferWriteString(buf, ";");
-- return;
-- }
-- if (cur->type == HTML_PRESERVE_NODE) {
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *)cur->content);
--#else
-- xmlOutputBufferWriteString(buf, (const char *)
-- xmlBufferContent(cur->content));
--#endif
-- }
-- return;
-- }
--
-- /*
-- * Get specific HTmL info for taht node.
-- */
-- info = htmlTagLookup(cur->name);
--
-- xmlOutputBufferWriteString(buf, "<");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- if (cur->properties != NULL)
-- htmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
--
-- if ((info != NULL) && (info->empty)) {
-- xmlOutputBufferWriteString(buf, ">");
-- if (cur->next != NULL) {
-- if ((cur->next->type != HTML_TEXT_NODE) &&
-- (cur->next->type != HTML_ENTITY_REF_NODE))
-- xmlOutputBufferWriteString(buf, "\n");
-- }
-- return;
-- }
-- if ((cur->content == NULL) && (cur->children == NULL)) {
-- if ((info != NULL) && (info->endTag != 0) &&
-- (strcmp(info->name, "html")) && (strcmp(info->name, "body"))) {
-- xmlOutputBufferWriteString(buf, ">");
-- } else {
-- xmlOutputBufferWriteString(buf, "></");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- xmlOutputBufferWriteString(buf, ">");
-- }
-- if (cur->next != NULL) {
-- if ((cur->next->type != HTML_TEXT_NODE) &&
-- (cur->next->type != HTML_ENTITY_REF_NODE))
-- xmlOutputBufferWriteString(buf, "\n");
-- }
-- return;
-- }
-- xmlOutputBufferWriteString(buf, ">");
-- if (cur->content != NULL) {
-- /*
-- * Uses the OutputBuffer property to automatically convert
-- * invalids to charrefs
-- */
--
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *) cur->content);
--#else
-- xmlOutputBufferWriteString(buf,
-- (const char *) xmlBufferContent(cur->content));
--#endif
-- }
-- if (cur->children != NULL) {
-- if ((cur->children->type != HTML_TEXT_NODE) &&
-- (cur->children->type != HTML_ENTITY_REF_NODE) &&
-- (cur->children != cur->last))
-- xmlOutputBufferWriteString(buf, "\n");
-- htmlNodeListDumpOutput(buf, doc, cur->children, encoding);
-- if ((cur->last->type != HTML_TEXT_NODE) &&
-- (cur->last->type != HTML_ENTITY_REF_NODE) &&
-- (cur->children != cur->last))
-- xmlOutputBufferWriteString(buf, "\n");
-- }
-- if (!htmlIsAutoClosed(doc, cur)) {
-- xmlOutputBufferWriteString(buf, "</");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- xmlOutputBufferWriteString(buf, ">");
-- }
-- if (cur->next != NULL) {
-- if ((cur->next->type != HTML_TEXT_NODE) &&
-- (cur->next->type != HTML_ENTITY_REF_NODE))
-- xmlOutputBufferWriteString(buf, "\n");
-- }
--}
--
--/**
-- * htmlDocContentDump:
-- * @buf: the HTML buffer output
-- * @cur: the document
-- *
-- * Dump an HTML document.
-- */
--void
--htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
-- int type;
--
-- /*
-- * force to output the stuff as HTML, especially for entities
-- */
-- type = cur->type;
-- cur->type = XML_HTML_DOCUMENT_NODE;
-- if (cur->intSubset != NULL)
-- htmlDtdDumpOutput(buf, cur, NULL);
-- else {
-- /* Default to HTML-4.0 transitionnal @@@@ */
-- xmlOutputBufferWriteString(buf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
--
-- }
-- if (cur->children != NULL) {
-- htmlNodeListDumpOutput(buf, cur, cur->children, encoding);
-- }
-- xmlOutputBufferWriteString(buf, "\n");
-- cur->type = (xmlElementType) type;
--}
--
--
--/************************************************************************
-- * *
-- * Saving functions front-ends *
-- * *
-- ************************************************************************/
--
--/**
-- * htmlDocDump:
-- * @f: the FILE*
-- * @cur: the document
-- *
-- * Dump an HTML document to an open FILE.
-- *
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--htmlDocDump(FILE *f, xmlDocPtr cur) {
-- xmlOutputBufferPtr buf;
-- xmlCharEncodingHandlerPtr handler = NULL;
-- const char *encoding;
-- int ret;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "htmlDocDump : document == NULL\n");
--#endif
-- return(-1);
-- }
--
-- encoding = (const char *) htmlGetMetaEncoding(cur);
--
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
--
-- enc = xmlParseCharEncoding(encoding);
-- if (enc != cur->charset) {
-- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-- /*
-- * Not supported yet
-- */
-- return(-1);
-- }
--
-- handler = xmlFindCharEncodingHandler(encoding);
-- if (handler == NULL)
-- return(-1);
-- }
-- }
--
-- /*
-- * Fallback to HTML or ASCII when the encoding is unspecified
-- */
-- if (handler == NULL)
-- handler = xmlFindCharEncodingHandler("HTML");
-- if (handler == NULL)
-- handler = xmlFindCharEncodingHandler("ascii");
--
-- buf = xmlOutputBufferCreateFile(f, handler);
-- if (buf == NULL) return(-1);
-- htmlDocContentDumpOutput(buf, cur, NULL);
--
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--
--/**
-- * htmlSaveFile:
-- * @filename: the filename (or URL)
-- * @cur: the document
-- *
-- * Dump an HTML document to a file. If @filename is "-" the stdout file is
-- * used.
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--htmlSaveFile(const char *filename, xmlDocPtr cur) {
-- xmlOutputBufferPtr buf;
-- xmlCharEncodingHandlerPtr handler = NULL;
-- const char *encoding;
-- int ret;
--
-- encoding = (const char *) htmlGetMetaEncoding(cur);
--
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
--
-- enc = xmlParseCharEncoding(encoding);
-- if (enc != cur->charset) {
-- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-- /*
-- * Not supported yet
-- */
-- return(-1);
-- }
--
-- handler = xmlFindCharEncodingHandler(encoding);
-- if (handler == NULL)
-- return(-1);
-- }
-- }
--
-- /*
-- * Fallback to HTML or ASCII when the encoding is unspecified
-- */
-- if (handler == NULL)
-- handler = xmlFindCharEncodingHandler("HTML");
-- if (handler == NULL)
-- handler = xmlFindCharEncodingHandler("ascii");
--
-- /*
-- * save the content to a temp buffer.
-- */
-- buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
-- if (buf == NULL) return(0);
--
-- htmlDocContentDumpOutput(buf, cur, NULL);
--
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--
--/**
-- * htmlSaveFileEnc:
-- * @filename: the filename
-- * @cur: the document
-- *
-- * Dump an HTML document to a file using a given encoding.
-- *
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
-- xmlOutputBufferPtr buf;
-- xmlCharEncodingHandlerPtr handler = NULL;
-- int ret;
--
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
--
-- enc = xmlParseCharEncoding(encoding);
-- if (enc != cur->charset) {
-- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-- /*
-- * Not supported yet
-- */
-- return(-1);
-- }
--
-- handler = xmlFindCharEncodingHandler(encoding);
-- if (handler == NULL)
-- return(-1);
-- htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
-- }
-- }
--
-- /*
-- * Fallback to HTML or ASCII when the encoding is unspecified
-- */
-- if (handler == NULL)
-- handler = xmlFindCharEncodingHandler("HTML");
-- if (handler == NULL)
-- handler = xmlFindCharEncodingHandler("ascii");
--
-- /*
-- * save the content to a temp buffer.
-- */
-- buf = xmlOutputBufferCreateFilename(filename, handler, 0);
-- if (buf == NULL) return(0);
--
-- htmlDocContentDumpOutput(buf, cur, encoding);
--
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--#endif /* LIBXML_HTML_ENABLED */
-diff -Nru libxml2-2.3.0/Makefile.am libxml2-2.3.0.new/Makefile.am
---- libxml2-2.3.0/Makefile.am Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/Makefile.am Mon Feb 12 04:07:26 2001
-@@ -1,50 +1,17 @@
- ## Process this file with automake to produce Makefile.in
-
--SUBDIRS = . include doc example
-+SUBDIRS = libxml doc example
-
--INCLUDES = -I@srcdir@/include -I./include @Z_CFLAGS@ @CORBA_CFLAGS@
-+INCLUDES = $(CORBA_CFLAGS)
-
- noinst_PROGRAMS=testSAX testHTML testXPath testURI
-
- bin_PROGRAMS = xmllint
-
--bin_SCRIPTS=xml2-config
-+DEPS = ./libxml/libxml.la
-+LDADDS = ./libxml/libxml.la
-
--lib_LTLIBRARIES = libxml2.la
--libxml2_la_LIBADD = @Z_LIBS@
--
--libxml2_la_LDFLAGS = -version-info @LIBXML_VERSION_INFO@
--
--libxml2_la_SOURCES = \
-- SAX.c \
-- entities.c \
-- encoding.c \
-- error.c \
-- parserInternals.c \
-- parser.c \
-- tree.c \
-- hash.c \
-- xmlIO.c \
-- xmlmemory.c \
-- uri.c \
-- valid.c \
-- xlink.c \
-- HTMLparser.c \
-- HTMLtree.c \
-- debugXML.c \
-- xpath.c \
-- xpointer.c \
-- xinclude.c \
-- nanohttp.c \
-- nanoftp.c
--
--DEPS = $(top_builddir)/libxml2.la
--LDADDS = $(top_builddir)/libxml2.la @Z_LIBS@ @M_LIBS@
--
--man_MANS = xmllint.1 xml2-config.1 libxml.4
--
--m4datadir = $(datadir)/aclocal
--m4data_DATA = libxml.m4
-+man_MANS = xmllint.1
-
- xmllint_SOURCES=xmllint.c
- xmllint_LDFLAGS =
-@@ -73,14 +40,6 @@
-
- check-local: tests
-
--$(srcdir)/libxml:
-- -$(RM) $(srcdir)/libxml
-- ln -s $(srcdir)/. $(srcdir)/libxml
--
--install-data: $(srcdir)/libxml
--
--$(libxml2_la_SOURCES): $(srcdir)/libxml
--
- testall : tests SVGtests SAXtests
-
- tests: XMLtests XMLenttests HTMLtests Validtests URItests XPathtests XPtrtests XIncludetests
-@@ -410,28 +369,7 @@
- ## the value NONE in configure if the user doesn't specify them (this
- ## is an autoconf feature, not a bug).
-
--confexecdir=$(libdir)
--confexec_DATA = xml2Conf.sh
--
--CLEANFILES=xml2Conf.sh
--
--confexecdir=$(libdir)
--confexec_DATA = xml2Conf.sh
--EXTRA_DIST = xml2Conf.sh.in libxml.spec.in libxml.spec libxml.m4 \
-- example/Makefile.am example/gjobread.c example/gjobs.xml \
-- $(man_MANS) libxml-2.0.pc.in xmlversion.h.in \
-- win32/README.MSDev win32/Makefile.mingw \
-+EXTRA_DIST = libxml.spec.in \
-+ $(man_MANS) win32/README.MSDev win32/Makefile.mingw \
- win32/libxml2/libxml2.dsp win32/libxml2/libxml2_so.dsp \
- win32/libxml2/libxml2_a.dsp vms/build_libxml.com vms/config.vms
--
--pkgconfigdir = $(libdir)/pkgconfig
--pkgconfig_DATA = libxml-2.0.pc
--
--#xml2Conf.sh: xml2Conf.sh.in Makefile
--### Use sed and then mv to avoid problems if the user interrupts.
--# sed -e 's?\@XML_LIBDIR\@?$(XML_LIBDIR)?g' \
--# -e 's?\@XML_INCLUDEDIR\@?$(XML_INCLUDEDIR)?g' \
--# -e 's?\@XML_LIBS\@?$(XML_LIBS)?g' \
--# -e 's?\@VERSION\@?$(VERSION)?g' \
--# < $(srcdir)/xml2Conf.sh.in > xml2Conf.tmp \
--# && mv xml2Conf.tmp xml2Conf.sh
-diff -Nru libxml2-2.3.0/SAX.c libxml2-2.3.0.new/SAX.c
---- libxml2-2.3.0/SAX.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/SAX.c Thu Jan 1 01:00:00 1970
-@@ -1,1749 +0,0 @@
--/*
-- * SAX.c : Default SAX handler to build a tree.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel Veillard <Daniel.Veillard@w3.org>
-- */
--
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--#include <stdio.h>
--#include <stdlib.h>
--#include <string.h>
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/parserInternals.h>
--#include <libxml/valid.h>
--#include <libxml/entities.h>
--#include <libxml/xmlerror.h>
--#include <libxml/debugXML.h>
--#include <libxml/xmlIO.h>
--#include <libxml/SAX.h>
--#include <libxml/uri.h>
--#include <libxml/HTMLtree.h>
--
--/* #define DEBUG_SAX */
--/* #define DEBUG_SAX_TREE */
--
--/**
-- * getPublicId:
-- * @ctx: the user data (XML parser context)
-- *
-- * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
-- *
-- * Returns a xmlChar *
-- */
--const xmlChar *
--getPublicId(void *ctx)
--{
-- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-- return(NULL);
--}
--
--/**
-- * getSystemId:
-- * @ctx: the user data (XML parser context)
-- *
-- * Return the system ID, basically URL or filename e.g.
-- * http://www.sgmlsource.com/dtds/memo.dtd
-- *
-- * Returns a xmlChar *
-- */
--const xmlChar *
--getSystemId(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- return(BAD_CAST ctxt->input->filename);
--}
--
--/**
-- * getLineNumber:
-- * @ctx: the user data (XML parser context)
-- *
-- * Return the line number of the current parsing point.
-- *
-- * Returns an int
-- */
--int
--getLineNumber(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- return(ctxt->input->line);
--}
--
--/**
-- * getColumnNumber:
-- * @ctx: the user data (XML parser context)
-- *
-- * Return the column number of the current parsing point.
-- *
-- * Returns an int
-- */
--int
--getColumnNumber(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- return(ctxt->input->col);
--}
--
--/*
-- * The default SAX Locator.
-- */
--
--xmlSAXLocator xmlDefaultSAXLocator = {
-- getPublicId, getSystemId, getLineNumber, getColumnNumber
--};
--
--/**
-- * isStandalone:
-- * @ctx: the user data (XML parser context)
-- *
-- * Is this document tagged standalone ?
-- *
-- * Returns 1 if true
-- */
--int
--isStandalone(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- return(ctxt->myDoc->standalone == 1);
--}
--
--/**
-- * hasInternalSubset:
-- * @ctx: the user data (XML parser context)
-- *
-- * Does this document has an internal subset
-- *
-- * Returns 1 if true
-- */
--int
--hasInternalSubset(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- return(ctxt->myDoc->intSubset != NULL);
--}
--
--/**
-- * hasExternalSubset:
-- * @ctx: the user data (XML parser context)
-- *
-- * Does this document has an external subset
-- *
-- * Returns 1 if true
-- */
--int
--hasExternalSubset(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- return(ctxt->myDoc->extSubset != NULL);
--}
--
--/**
-- * internalSubset:
-- * @ctx: the user data (XML parser context)
-- * @name: the root element name
-- * @ExternalID: the external ID
-- * @SystemID: the SYSTEM ID (e.g. filename or URL)
-- *
-- * Callback on internal subset declaration.
-- */
--void
--internalSubset(void *ctx, const xmlChar *name,
-- const xmlChar *ExternalID, const xmlChar *SystemID)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlDtdPtr dtd;
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.internalSubset(%s, %s, %s)\n",
-- name, ExternalID, SystemID);
--#endif
--
-- if (ctxt->myDoc == NULL)
-- return;
-- dtd = xmlGetIntSubset(ctxt->myDoc);
-- if (dtd != NULL) {
-- if (ctxt->html)
-- return;
-- xmlUnlinkNode((xmlNodePtr) dtd);
-- xmlFreeDtd(dtd);
-- ctxt->myDoc->intSubset = NULL;
-- }
-- ctxt->myDoc->intSubset =
-- xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
--}
--
--/**
-- * externalSubset:
-- * @ctx: the user data (XML parser context)
-- * @name: the root element name
-- * @ExternalID: the external ID
-- * @SystemID: the SYSTEM ID (e.g. filename or URL)
-- *
-- * Callback on external subset declaration.
-- */
--void
--externalSubset(void *ctx, const xmlChar *name,
-- const xmlChar *ExternalID, const xmlChar *SystemID)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.externalSubset(%s, %s, %s)\n",
-- name, ExternalID, SystemID);
--#endif
-- if (((ExternalID != NULL) || (SystemID != NULL)) &&
-- (((ctxt->validate) || (ctxt->loadsubset)) &&
-- (ctxt->wellFormed && ctxt->myDoc))) {
-- /*
-- * Try to fetch and parse the external subset.
-- */
-- xmlParserInputPtr oldinput;
-- int oldinputNr;
-- int oldinputMax;
-- xmlParserInputPtr *oldinputTab;
-- int oldwellFormed;
-- xmlParserInputPtr input = NULL;
-- xmlCharEncoding enc;
-- int oldcharset;
--
-- /*
-- * Ask the Entity resolver to load the damn thing
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
-- input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
-- SystemID);
-- if (input == NULL) {
-- return;
-- }
--
-- xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
--
-- /*
-- * make sure we won't destroy the main document context
-- */
-- oldinput = ctxt->input;
-- oldinputNr = ctxt->inputNr;
-- oldinputMax = ctxt->inputMax;
-- oldinputTab = ctxt->inputTab;
-- oldwellFormed = ctxt->wellFormed;
-- oldcharset = ctxt->charset;
--
-- ctxt->inputTab = (xmlParserInputPtr *)
-- xmlMalloc(5 * sizeof(xmlParserInputPtr));
-- if (ctxt->inputTab == NULL) {
-- ctxt->errNo = XML_ERR_NO_MEMORY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "externalSubset: out of memory\n");
-- ctxt->errNo = XML_ERR_NO_MEMORY;
-- ctxt->input = oldinput;
-- ctxt->inputNr = oldinputNr;
-- ctxt->inputMax = oldinputMax;
-- ctxt->inputTab = oldinputTab;
-- ctxt->charset = oldcharset;
-- return;
-- }
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 5;
-- ctxt->input = NULL;
-- xmlPushInput(ctxt, input);
--
-- /*
-- * On the fly encoding conversion if needed
-- */
-- enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
-- xmlSwitchEncoding(ctxt, enc);
--
-- if (input->filename == NULL)
-- input->filename = (char *) xmlStrdup(SystemID);
-- input->line = 1;
-- input->col = 1;
-- input->base = ctxt->input->cur;
-- input->cur = ctxt->input->cur;
-- input->free = NULL;
--
-- /*
-- * let's parse that entity knowing it's an external subset.
-- */
-- xmlParseExternalSubset(ctxt, ExternalID, SystemID);
--
-- /*
-- * Free up the external entities
-- */
--
-- while (ctxt->inputNr > 1)
-- xmlPopInput(ctxt);
-- xmlFreeInputStream(ctxt->input);
-- xmlFree(ctxt->inputTab);
--
-- /*
-- * Restore the parsing context of the main entity
-- */
-- ctxt->input = oldinput;
-- ctxt->inputNr = oldinputNr;
-- ctxt->inputMax = oldinputMax;
-- ctxt->inputTab = oldinputTab;
-- ctxt->charset = oldcharset;
-- /* ctxt->wellFormed = oldwellFormed; */
-- }
--}
--
--/**
-- * resolveEntity:
-- * @ctx: the user data (XML parser context)
-- * @publicId: The public ID of the entity
-- * @systemId: The system ID of the entity
-- *
-- * The entity loader, to control the loading of external entities,
-- * the application can either:
-- * - override this resolveEntity() callback in the SAX block
-- * - or better use the xmlSetExternalEntityLoader() function to
-- * set up it's own entity resolution routine
-- *
-- * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
-- */
--xmlParserInputPtr
--resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlParserInputPtr ret;
-- xmlChar *URI;
-- const char *base = NULL;
--
-- if (ctxt->input != NULL)
-- base = ctxt->input->filename;
-- if (base == NULL)
-- base = ctxt->directory;
--
-- URI = xmlBuildURI(systemId, (const xmlChar *) base);
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
--#endif
--
-- ret = xmlLoadExternalEntity((const char *) URI,
-- (const char *) publicId, ctxt);
-- if (URI != NULL)
-- xmlFree(URI);
-- return(ret);
--}
--
--/**
-- * getEntity:
-- * @ctx: the user data (XML parser context)
-- * @name: The entity name
-- *
-- * Get an entity by name
-- *
-- * Returns the xmlEntityPtr if found.
-- */
--xmlEntityPtr
--getEntity(void *ctx, const xmlChar *name)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlEntityPtr ret;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.getEntity(%s)\n", name);
--#endif
--
-- ret = xmlGetDocEntity(ctxt->myDoc, name);
-- if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
-- (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-- /*
-- * for validation purposes we really need to fetch and
-- * parse the external entity
-- */
-- int parse;
-- xmlNodePtr children;
--
-- parse = xmlParseCtxtExternalEntity(ctxt,
-- ret->SystemID, ret->ExternalID, &children);
-- xmlAddChildList((xmlNodePtr) ret, children);
-- }
-- return(ret);
--}
--
--/**
-- * getParameterEntity:
-- * @ctx: the user data (XML parser context)
-- * @name: The entity name
-- *
-- * Get a parameter entity by name
-- *
-- * Returns the xmlEntityPtr if found.
-- */
--xmlEntityPtr
--getParameterEntity(void *ctx, const xmlChar *name)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlEntityPtr ret;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.getParameterEntity(%s)\n", name);
--#endif
--
-- ret = xmlGetParameterEntity(ctxt->myDoc, name);
-- return(ret);
--}
--
--
--/**
-- * entityDecl:
-- * @ctx: the user data (XML parser context)
-- * @name: the entity name
-- * @type: the entity type
-- * @publicId: The public ID of the entity
-- * @systemId: The system ID of the entity
-- * @content: the entity value (without processing).
-- *
-- * An entity definition has been parsed
-- */
--void
--entityDecl(void *ctx, const xmlChar *name, int type,
-- const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
--{
-- xmlEntityPtr ent;
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
-- name, type, publicId, systemId, content);
--#endif
-- if (ctxt->inSubset == 1) {
-- ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
-- systemId, content);
-- if ((ent == NULL) && (ctxt->pedantic) &&
-- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt,
-- "Entity(%s) already defined in the internal subset\n", name);
-- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
-- xmlChar *URI;
-- const char *base = NULL;
--
-- if (ctxt->input != NULL)
-- base = ctxt->input->filename;
-- if (base == NULL)
-- base = ctxt->directory;
--
-- URI = xmlBuildURI(systemId, (const xmlChar *) base);
-- ent->URI = URI;
-- }
-- } else if (ctxt->inSubset == 2) {
-- ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
-- systemId, content);
-- if ((ent == NULL) && (ctxt->pedantic) &&
-- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt,
-- "Entity(%s) already defined in the external subset\n", name);
-- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
-- xmlChar *URI;
-- const char *base = NULL;
--
-- if (ctxt->input != NULL)
-- base = ctxt->input->filename;
-- if (base == NULL)
-- base = ctxt->directory;
--
-- URI = xmlBuildURI(systemId, (const xmlChar *) base);
-- ent->URI = URI;
-- }
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "SAX.entityDecl(%s) called while not in subset\n", name);
-- }
--}
--
--/**
-- * attributeDecl:
-- * @ctx: the user data (XML parser context)
-- * @elem: the name of the element
-- * @fullname: the attribute name
-- * @type: the attribute type
-- * @def: the type of default value
-- * @defaultValue: the attribute default value
-- * @tree: the tree of enumerated value set
-- *
-- * An attribute definition has been parsed
-- */
--void
--attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
-- int type, int def, const xmlChar *defaultValue,
-- xmlEnumerationPtr tree)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlAttributePtr attr;
-- xmlChar *name = NULL, *prefix = NULL;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
-- elem, fullname, type, def, defaultValue);
--#endif
-- name = xmlSplitQName(ctxt, fullname, &prefix);
-- if (ctxt->inSubset == 1)
-- attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
-- name, prefix, (xmlAttributeType) type,
-- (xmlAttributeDefault) def, defaultValue, tree);
-- else if (ctxt->inSubset == 2)
-- attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
-- name, prefix, (xmlAttributeType) type,
-- (xmlAttributeDefault) def, defaultValue, tree);
-- else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "SAX.attributeDecl(%s) called while not in subset\n", name);
-- return;
-- }
-- if (attr == 0) ctxt->valid = 0;
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
-- attr);
-- if (prefix != NULL)
-- xmlFree(prefix);
-- if (name != NULL)
-- xmlFree(name);
--}
--
--/**
-- * elementDecl:
-- * @ctx: the user data (XML parser context)
-- * @name: the element name
-- * @type: the element type
-- * @content: the element value tree
-- *
-- * An element definition has been parsed
-- */
--void
--elementDecl(void *ctx, const xmlChar *name, int type,
-- xmlElementContentPtr content)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlElementPtr elem = NULL;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.elementDecl(%s, %d, ...)\n",
-- fullname, type);
--#endif
--
-- if (ctxt->inSubset == 1)
-- elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
-- name, (xmlElementTypeVal) type, content);
-- else if (ctxt->inSubset == 2)
-- elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
-- name, (xmlElementTypeVal) type, content);
-- else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "SAX.elementDecl(%s) called while not in subset\n", name);
-- return;
-- }
-- if (elem == NULL) ctxt->valid = 0;
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
--}
--
--/**
-- * notationDecl:
-- * @ctx: the user data (XML parser context)
-- * @name: The name of the notation
-- * @publicId: The public ID of the entity
-- * @systemId: The system ID of the entity
-- *
-- * What to do when a notation declaration has been parsed.
-- */
--void
--notationDecl(void *ctx, const xmlChar *name,
-- const xmlChar *publicId, const xmlChar *systemId)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNotationPtr nota = NULL;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
--#endif
--
-- if (ctxt->inSubset == 1)
-- nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
-- publicId, systemId);
-- else if (ctxt->inSubset == 2)
-- nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
-- publicId, systemId);
-- else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "SAX.notationDecl(%s) called while not in subset\n", name);
-- return;
-- }
-- if (nota == NULL) ctxt->valid = 0;
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
-- nota);
--}
--
--/**
-- * unparsedEntityDecl:
-- * @ctx: the user data (XML parser context)
-- * @name: The name of the entity
-- * @publicId: The public ID of the entity
-- * @systemId: The system ID of the entity
-- * @notationName: the name of the notation
-- *
-- * What to do when an unparsed entity declaration is parsed
-- */
--void
--unparsedEntityDecl(void *ctx, const xmlChar *name,
-- const xmlChar *publicId, const xmlChar *systemId,
-- const xmlChar *notationName)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
-- name, publicId, systemId, notationName);
--#endif
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
-- notationName);
-- xmlAddDocEntity(ctxt->myDoc, name,
-- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
-- publicId, systemId, notationName);
--}
--
--/**
-- * setDocumentLocator:
-- * @ctx: the user data (XML parser context)
-- * @loc: A SAX Locator
-- *
-- * Receive the document locator at startup, actually xmlDefaultSAXLocator
-- * Everything is available on the context, so this is useless in our case.
-- */
--void
--setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
--{
-- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.setDocumentLocator()\n");
--#endif
--}
--
--/**
-- * startDocument:
-- * @ctx: the user data (XML parser context)
-- *
-- * called when the document start being processed.
-- */
--void
--startDocument(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlDocPtr doc;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.startDocument()\n");
--#endif
-- if (ctxt->html) {
-- if (ctxt->myDoc == NULL)
--#ifdef LIBXML_HTML_ENABLED
-- ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
--#else
-- xmlGenericError(xmlGenericErrorContext,
-- "libxml2 built without HTML support\n");
--#endif
-- } else {
-- doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
-- if (doc != NULL) {
-- if (ctxt->encoding != NULL)
-- doc->encoding = xmlStrdup(ctxt->encoding);
-- else
-- doc->encoding = NULL;
-- doc->standalone = ctxt->standalone;
-- }
-- }
-- if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
-- (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
-- ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
-- }
--}
--
--/**
-- * endDocument:
-- * @ctx: the user data (XML parser context)
-- *
-- * called when the document end has been detected.
-- */
--void
--endDocument(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.endDocument()\n");
--#endif
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
--
-- /*
-- * Grab the encoding if it was added on-the-fly
-- */
-- if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
-- (ctxt->myDoc->encoding == NULL)) {
-- ctxt->myDoc->encoding = ctxt->encoding;
-- ctxt->encoding = NULL;
-- }
-- if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
-- (ctxt->myDoc->encoding == NULL)) {
-- ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
-- }
-- if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
-- (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
-- ctxt->myDoc->charset = ctxt->charset;
-- }
--}
--
--/**
-- * attribute:
-- * @ctx: the user data (XML parser context)
-- * @fullname: The attribute name, including namespace prefix
-- * @value: The attribute value
-- *
-- * Handle an attribute that has been read by the parser.
-- * The default handling is to convert the attribute into an
-- * DOM subtree and past it in a new xmlAttr element added to
-- * the element.
-- */
--void
--attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlAttrPtr ret;
-- xmlChar *name;
-- xmlChar *ns;
-- xmlChar *nval;
-- xmlNsPtr namespace;
--
--/****************
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.attribute(%s, %s)\n", fullname, value);
--#endif
-- ****************/
-- /*
-- * Split the full name into a namespace prefix and the tag name
-- */
-- name = xmlSplitQName(ctxt, fullname, &ns);
--
-- /*
-- * Do the last stage of the attribute normalization
-- * Needed for HTML too:
-- * http://www.w3.org/TR/html4/types.html#h-6.2
-- */
-- nval = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node,
-- fullname, value);
-- if (nval != NULL)
-- value = nval;
--
-- /*
-- * Check whether it's a namespace definition
-- */
-- if ((!ctxt->html) && (ns == NULL) &&
-- (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
-- (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
-- xmlURIPtr uri;
--
-- uri = xmlParseURI((const char *)value);
-- if (uri == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "nmlns: %s not a valid URI\n", value);
-- } else {
-- if (uri->scheme == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "nmlns: URI %s is not absolute\n", value);
-- }
-- xmlFreeURI(uri);
-- }
--
-- /* a default namespace definition */
-- xmlNewNs(ctxt->node, value, NULL);
-- if (name != NULL)
-- xmlFree(name);
-- if (nval != NULL)
-- xmlFree(nval);
-- return;
-- }
-- if ((!ctxt->html) &&
-- (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
-- (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
-- /*
-- * Validate also for namespace decls, they are attributes from
-- * an XML-1.0 perspective
-- TODO ... doesn't map well with current API
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
-- ctxt->node, ret, value);
-- */
-- /* a standard namespace definition */
-- xmlNewNs(ctxt->node, value, name);
-- xmlFree(ns);
-- if (name != NULL)
-- xmlFree(name);
-- if (nval != NULL)
-- xmlFree(nval);
-- return;
-- }
--
-- if (ns != NULL)
-- namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
-- else {
-- namespace = NULL;
-- }
--
-- /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
-- ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
--
-- if (ret != NULL) {
-- if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
-- xmlNodePtr tmp;
--
-- ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
-- tmp = ret->children;
-- while (tmp != NULL) {
-- tmp->parent = (xmlNodePtr) ret;
-- if (tmp->next == NULL)
-- ret->last = tmp;
-- tmp = tmp->next;
-- }
-- } else if (value != NULL) {
-- ret->children = xmlNewDocText(ctxt->myDoc, value);
-- ret->last = ret->children;
-- if (ret->children != NULL)
-- ret->children->parent = (xmlNodePtr) ret;
-- }
-- }
--
-- if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset) {
--
-- /*
-- * If we don't substitute entities, the validation should be
-- * done on a value with replaced entities anyway.
-- */
-- if (!ctxt->replaceEntities) {
-- xmlChar *val;
--
-- ctxt->depth++;
-- val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
-- 0,0,0);
-- ctxt->depth--;
-- if (val == NULL)
-- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
-- ctxt->myDoc, ctxt->node, ret, value);
-- else {
-- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
-- ctxt->myDoc, ctxt->node, ret, val);
-- xmlFree(val);
-- }
-- } else {
-- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
-- ctxt->node, ret, value);
-- }
-- } else {
-- /*
-- * when validating, the ID registration is done at the attribute
-- * validation level. Otherwise we have to do specific handling here.
-- */
-- if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
-- xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
-- else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
-- xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
-- }
--
-- if (nval != NULL)
-- xmlFree(nval);
-- if (name != NULL)
-- xmlFree(name);
-- if (ns != NULL)
-- xmlFree(ns);
--}
--
--/**
-- * startElement:
-- * @ctx: the user data (XML parser context)
-- * @fullname: The element name, including namespace prefix
-- * @atts: An array of name/value attributes pairs, NULL terminated
-- *
-- * called when an opening tag has been processed.
-- */
--void
--startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr ret;
-- xmlNodePtr parent = ctxt->node;
-- xmlNsPtr ns;
-- xmlChar *name;
-- xmlChar *prefix;
-- const xmlChar *att;
-- const xmlChar *value;
-- int i;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.startElement(%s)\n", fullname);
--#endif
--
-- /*
-- * First check on validity:
-- */
-- if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
-- ((ctxt->myDoc->intSubset == NULL) ||
-- ((ctxt->myDoc->intSubset->notations == NULL) &&
-- (ctxt->myDoc->intSubset->elements == NULL) &&
-- (ctxt->myDoc->intSubset->attributes == NULL) &&
-- (ctxt->myDoc->intSubset->entities == NULL)))) {
-- if (ctxt->vctxt.error != NULL) {
-- ctxt->vctxt.error(ctxt->vctxt.userData,
-- "Validation failed: no DTD found !\n");
-- }
-- ctxt->validate = 0;
-- }
--
--
-- /*
-- * Split the full name into a namespace prefix and the tag name
-- */
-- name = xmlSplitQName(ctxt, fullname, &prefix);
--
--
-- /*
-- * Note : the namespace resolution is deferred until the end of the
-- * attributes parsing, since local namespace can be defined as
-- * an attribute at this level.
-- */
-- ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
-- if (ret == NULL) return;
-- if (ctxt->myDoc->children == NULL) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
--#endif
-- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-- } else if (parent == NULL) {
-- parent = ctxt->myDoc->children;
-- }
-- ctxt->nodemem = -1;
--
-- /*
-- * We are parsing a new node.
-- */
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
--#endif
-- nodePush(ctxt, ret);
--
-- /*
-- * Link the child element
-- */
-- if (parent != NULL) {
-- if (parent->type == XML_ELEMENT_NODE) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "adding child %s to %s\n", name, parent->name);
--#endif
-- xmlAddChild(parent, ret);
-- } else {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "adding sibling %s to ", name);
-- xmlDebugDumpOneNode(stderr, parent, 0);
--#endif
-- xmlAddSibling(parent, ret);
-- }
-- }
--
-- /*
-- * process all the attributes whose name start with "xml"
-- */
-- if (atts != NULL) {
-- i = 0;
-- att = atts[i++];
-- value = atts[i++];
-- if (!ctxt->html) {
-- while ((att != NULL) && (value != NULL)) {
-- if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
-- attribute(ctxt, att, value);
--
-- att = atts[i++];
-- value = atts[i++];
-- }
-- }
-- }
--
-- /*
-- * Search the namespace, note that since the attributes have been
-- * processed, the local namespaces are available.
-- */
-- ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
-- if ((ns == NULL) && (parent != NULL))
-- ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
-- if ((prefix != NULL) && (ns == NULL)) {
-- ns = xmlNewNs(ret, NULL, prefix);
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Namespace prefix %s is not defined\n", prefix);
-- }
-- xmlSetNs(ret, ns);
--
-- /*
-- * process all the other attributes
-- */
-- if (atts != NULL) {
-- i = 0;
-- att = atts[i++];
-- value = atts[i++];
-- if (ctxt->html) {
-- while (att != NULL) {
-- attribute(ctxt, att, value);
-- att = atts[i++];
-- value = atts[i++];
-- }
-- } else {
-- while ((att != NULL) && (value != NULL)) {
-- if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
-- attribute(ctxt, att, value);
--
-- /*
-- * Next ones
-- */
-- att = atts[i++];
-- value = atts[i++];
-- }
-- }
-- }
--
-- /*
-- * If it's the Document root, finish the Dtd validation and
-- * check the document root element for validity
-- */
-- if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
-- ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
-- ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-- ctxt->vctxt.finishDtd = 1;
-- }
--
-- if (prefix != NULL)
-- xmlFree(prefix);
-- if (name != NULL)
-- xmlFree(name);
--
--}
--
--/**
-- * endElement:
-- * @ctx: the user data (XML parser context)
-- * @name: The element name
-- *
-- * called when the end of an element has been detected.
-- */
--void
--endElement(void *ctx, const xmlChar *name)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlParserNodeInfo node_info;
-- xmlNodePtr cur = ctxt->node;
--
--#ifdef DEBUG_SAX
-- if (name == NULL)
-- xmlGenericError(xmlGenericErrorContext, "SAX.endElement(NULL)\n");
-- else
-- xmlGenericError(xmlGenericErrorContext, "SAX.endElement(%s)\n", name);
--#endif
--
-- /* Capture end position and add node */
-- if (cur != NULL && ctxt->record_info) {
-- node_info.end_pos = ctxt->input->cur - ctxt->input->base;
-- node_info.end_line = ctxt->input->line;
-- node_info.node = cur;
-- xmlParserAddNodeInfo(ctxt, &node_info);
-- }
-- ctxt->nodemem = -1;
--
-- if (ctxt->validate && ctxt->wellFormed &&
-- ctxt->myDoc && ctxt->myDoc->intSubset)
-- ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
-- cur);
--
--
-- /*
-- * end of parsing of this node.
-- */
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
--#endif
-- nodePop(ctxt);
--}
--
--/**
-- * reference:
-- * @ctx: the user data (XML parser context)
-- * @name: The entity name
-- *
-- * called when an entity reference is detected.
-- */
--void
--reference(void *ctx, const xmlChar *name)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr ret;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.reference(%s)\n", name);
--#endif
-- if (name[0] == '#')
-- ret = xmlNewCharRef(ctxt->myDoc, name);
-- else
-- ret = xmlNewReference(ctxt->myDoc, name);
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "add reference %s to %s \n", name, ctxt->node->name);
--#endif
-- xmlAddChild(ctxt->node, ret);
--}
--
--/**
-- * characters:
-- * @ctx: the user data (XML parser context)
-- * @ch: a xmlChar string
-- * @len: the number of xmlChar
-- *
-- * receiving some chars from the parser.
-- * Question: how much at a time ???
-- */
--void
--characters(void *ctx, const xmlChar *ch, int len)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr lastChild;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.characters(%.30s, %d)\n", ch, len);
--#endif
-- /*
-- * Handle the data if any. If there is no child
-- * add it as content, otherwise if the last child is text,
-- * concatenate it, else create a new node of type text.
-- */
--
-- if (ctxt->node == NULL) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "add chars: ctxt->node == NULL !\n");
--#endif
-- return;
-- }
-- lastChild = xmlGetLastChild(ctxt->node);
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "add chars to %s \n", ctxt->node->name);
--#endif
--
-- /*
-- * Here we needed an accelerator mechanism in case of very large
-- * elements. Use an attribute in the structure !!!
-- */
-- if (lastChild == NULL) {
-- /* first node, first time */
-- xmlNodeAddContentLen(ctxt->node, ch, len);
--#ifndef XML_USE_BUFFER_CONTENT
-- if (ctxt->node->children != NULL) {
-- ctxt->nodelen = len;
-- ctxt->nodemem = len + 1;
-- }
--#endif
-- } else {
-- if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- /*
-- * The whole point of maintaining nodelen and nodemem,
-- * xmlTextConcat is too costly, i.e. compute lenght,
-- * reallocate a new buffer, move data, append ch. Here
-- * We try to minimaze realloc() uses and avoid copying
-- * and recomputing lenght over and over.
-- */
-- if (ctxt->nodelen + len >= ctxt->nodemem) {
-- xmlChar *newbuf;
-- int size;
--
-- size = ctxt->nodemem + len;
-- size *= 2;
-- newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
-- if (newbuf == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "SAX.characters(): out of memory\n");
-- return;
-- }
-- ctxt->nodemem = size;
-- lastChild->content = newbuf;
-- }
-- memcpy(&lastChild->content[ctxt->nodelen], ch, len);
-- ctxt->nodelen += len;
-- lastChild->content[ctxt->nodelen] = 0;
--#else
-- xmlTextConcat(lastChild, ch, len);
--#endif
-- } else {
-- /* Mixed content, first time */
-- lastChild = xmlNewTextLen(ch, len);
-- xmlAddChild(ctxt->node, lastChild);
--#ifndef XML_USE_BUFFER_CONTENT
-- if (ctxt->node->children != NULL) {
-- ctxt->nodelen = len;
-- ctxt->nodemem = len + 1;
-- }
--#endif
-- }
-- }
--}
--
--/**
-- * ignorableWhitespace:
-- * @ctx: the user data (XML parser context)
-- * @ch: a xmlChar string
-- * @len: the number of xmlChar
-- *
-- * receiving some ignorable whitespaces from the parser.
-- * Question: how much at a time ???
-- */
--void
--ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
--{
-- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
--#endif
--}
--
--/**
-- * processingInstruction:
-- * @ctx: the user data (XML parser context)
-- * @target: the target name
-- * @data: the PI data's
-- *
-- * A processing instruction has been parsed.
-- */
--void
--processingInstruction(void *ctx, const xmlChar *target,
-- const xmlChar *data)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr ret;
-- xmlNodePtr parent = ctxt->node;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.processingInstruction(%s, %s)\n", target, data);
--#endif
--
-- ret = xmlNewPI(target, data);
-- if (ret == NULL) return;
-- parent = ctxt->node;
--
-- if (ctxt->inSubset == 1) {
-- xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
-- return;
-- } else if (ctxt->inSubset == 2) {
-- xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
-- return;
-- }
-- if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "Setting PI %s as root\n", target);
--#endif
-- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-- return;
-- }
-- if (parent->type == XML_ELEMENT_NODE) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "adding PI %s child to %s\n", target, parent->name);
--#endif
-- xmlAddChild(parent, ret);
-- } else {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "adding PI %s sibling to ", target);
-- xmlDebugDumpOneNode(stderr, parent, 0);
--#endif
-- xmlAddSibling(parent, ret);
-- }
--}
--
--/**
-- * globalNamespace:
-- * @ctx: the user data (XML parser context)
-- * @href: the namespace associated URN
-- * @prefix: the namespace prefix
-- *
-- * An old global namespace has been parsed.
-- */
--void
--globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.globalNamespace(%s, %s)\n", href, prefix);
--#endif
-- xmlNewGlobalNs(ctxt->myDoc, href, prefix);
--}
--
--/**
-- * setNamespace:
-- * @ctx: the user data (XML parser context)
-- * @name: the namespace prefix
-- *
-- * Set the current element namespace.
-- */
--
--void
--setNamespace(void *ctx, const xmlChar *name)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNsPtr ns;
-- xmlNodePtr parent;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext, "SAX.setNamespace(%s)\n", name);
--#endif
-- ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
-- if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
-- if (ctxt->nodeNr >= 2) {
-- parent = ctxt->nodeTab[ctxt->nodeNr - 2];
-- if (parent != NULL)
-- ns = xmlSearchNs(ctxt->myDoc, parent, name);
-- }
-- }
-- xmlSetNs(ctxt->node, ns);
--}
--
--/**
-- * getNamespace:
-- * @ctx: the user data (XML parser context)
-- *
-- * Get the current element namespace.
-- *
-- * Returns the xmlNsPtr or NULL if none
-- */
--
--xmlNsPtr
--getNamespace(void *ctx)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNsPtr ret;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext, "SAX.getNamespace()\n");
--#endif
-- ret = ctxt->node->ns;
-- return(ret);
--}
--
--/**
-- * checkNamespace:
-- * @ctx: the user data (XML parser context)
-- * @namespace: the namespace to check against
-- *
-- * Check that the current element namespace is the same as the
-- * one read upon parsing.
-- *
-- * Returns 1 if true 0 otherwise
-- */
--
--int
--checkNamespace(void *ctx, xmlChar *namespace)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr cur = ctxt->node;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.checkNamespace(%s)\n", namespace);
--#endif
--
-- /*
-- * Check that the Name in the ETag is the same as in the STag.
-- */
-- if (namespace == NULL) {
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "End tags for %s don't hold the namespace %s\n",
-- cur->name, cur->ns->prefix);
-- ctxt->wellFormed = 0;
-- }
-- } else {
-- if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "End tags %s holds a prefix %s not used by the open tag\n",
-- cur->name, namespace);
-- ctxt->wellFormed = 0;
-- } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt,
-- "Start and End tags for %s don't use the same namespaces: %s and %s\n",
-- cur->name, cur->ns->prefix, namespace);
-- ctxt->wellFormed = 0;
-- } else
-- return(1);
-- }
-- return(0);
--}
--
--/**
-- * namespaceDecl:
-- * @ctx: the user data (XML parser context)
-- * @href: the namespace associated URN
-- * @prefix: the namespace prefix
-- *
-- * A namespace has been parsed.
-- */
--void
--namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
--#ifdef DEBUG_SAX
-- if (prefix == NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.namespaceDecl(%s, NULL)\n", href);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.namespaceDecl(%s, %s)\n", href, prefix);
--#endif
-- xmlNewNs(ctxt->node, href, prefix);
--}
--
--/**
-- * comment:
-- * @ctx: the user data (XML parser context)
-- * @value: the comment content
-- *
-- * A comment has been parsed.
-- */
--void
--comment(void *ctx, const xmlChar *value)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr ret;
-- xmlNodePtr parent = ctxt->node;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext, "SAX.comment(%s)\n", value);
--#endif
-- ret = xmlNewDocComment(ctxt->myDoc, value);
-- if (ret == NULL) return;
--
-- if (ctxt->inSubset == 1) {
-- xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
-- return;
-- } else if (ctxt->inSubset == 2) {
-- xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
-- return;
-- }
-- if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "Setting comment as root\n");
--#endif
-- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-- return;
-- }
-- if (parent->type == XML_ELEMENT_NODE) {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "adding comment child to %s\n", parent->name);
--#endif
-- xmlAddChild(parent, ret);
-- } else {
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "adding comment sibling to ");
-- xmlDebugDumpOneNode(stderr, parent, 0);
--#endif
-- xmlAddSibling(parent, ret);
-- }
--}
--
--/**
-- * cdataBlock:
-- * @ctx: the user data (XML parser context)
-- * @value: The pcdata content
-- * @len: the block length
-- *
-- * called when a pcdata block has been parsed
-- */
--void
--cdataBlock(void *ctx, const xmlChar *value, int len)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlNodePtr ret, lastChild;
--
--#ifdef DEBUG_SAX
-- xmlGenericError(xmlGenericErrorContext,
-- "SAX.pcdata(%.10s, %d)\n", value, len);
--#endif
-- lastChild = xmlGetLastChild(ctxt->node);
--#ifdef DEBUG_SAX_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "add chars to %s \n", ctxt->node->name);
--#endif
-- if ((lastChild != NULL) &&
-- (lastChild->type == XML_CDATA_SECTION_NODE)) {
-- xmlTextConcat(lastChild, value, len);
-- } else {
-- ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
-- xmlAddChild(ctxt->node, ret);
-- }
--}
--
--/*
-- * Default handler for XML, builds the DOM tree
-- */
--xmlSAXHandler xmlDefaultSAXHandler = {
-- internalSubset,
-- isStandalone,
-- hasInternalSubset,
-- hasExternalSubset,
-- resolveEntity,
-- getEntity,
-- entityDecl,
-- notationDecl,
-- attributeDecl,
-- elementDecl,
-- unparsedEntityDecl,
-- setDocumentLocator,
-- startDocument,
-- endDocument,
-- startElement,
-- endElement,
-- reference,
-- characters,
-- ignorableWhitespace,
-- processingInstruction,
-- comment,
-- xmlParserWarning,
-- xmlParserError,
-- xmlParserError,
-- getParameterEntity,
-- cdataBlock,
-- externalSubset,
--};
--
--/**
-- * xmlDefaultSAXHandlerInit:
-- *
-- * Initialize the default SAX handler
-- */
--void
--xmlDefaultSAXHandlerInit(void)
--{
-- xmlDefaultSAXHandler.internalSubset = internalSubset;
-- xmlDefaultSAXHandler.externalSubset = externalSubset;
-- xmlDefaultSAXHandler.isStandalone = isStandalone;
-- xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
-- xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
-- xmlDefaultSAXHandler.resolveEntity = resolveEntity;
-- xmlDefaultSAXHandler.getEntity = getEntity;
-- xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
-- xmlDefaultSAXHandler.entityDecl = entityDecl;
-- xmlDefaultSAXHandler.attributeDecl = attributeDecl;
-- xmlDefaultSAXHandler.elementDecl = elementDecl;
-- xmlDefaultSAXHandler.notationDecl = notationDecl;
-- xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
-- xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
-- xmlDefaultSAXHandler.startDocument = startDocument;
-- xmlDefaultSAXHandler.endDocument = endDocument;
-- xmlDefaultSAXHandler.startElement = startElement;
-- xmlDefaultSAXHandler.endElement = endElement;
-- xmlDefaultSAXHandler.reference = reference;
-- xmlDefaultSAXHandler.characters = characters;
-- xmlDefaultSAXHandler.cdataBlock = cdataBlock;
-- xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
-- xmlDefaultSAXHandler.processingInstruction = processingInstruction;
-- xmlDefaultSAXHandler.comment = comment;
-- if (xmlGetWarningsDefaultValue == 0)
-- xmlDefaultSAXHandler.warning = NULL;
-- else
-- xmlDefaultSAXHandler.warning = xmlParserWarning;
-- xmlDefaultSAXHandler.error = xmlParserError;
-- xmlDefaultSAXHandler.fatalError = xmlParserError;
--}
--
--/*
-- * Default handler for HTML, builds the DOM tree
-- */
--xmlSAXHandler htmlDefaultSAXHandler = {
-- internalSubset,
-- NULL,
-- NULL,
-- NULL,
-- NULL,
-- getEntity,
-- NULL,
-- NULL,
-- NULL,
-- NULL,
-- NULL,
-- setDocumentLocator,
-- startDocument,
-- endDocument,
-- startElement,
-- endElement,
-- NULL,
-- characters,
-- ignorableWhitespace,
-- NULL,
-- comment,
-- xmlParserWarning,
-- xmlParserError,
-- xmlParserError,
-- getParameterEntity,
-- cdataBlock,
-- NULL,
--};
--
--/**
-- * htmlDefaultSAXHandlerInit:
-- *
-- * Initialize the default SAX handler
-- */
--void
--htmlDefaultSAXHandlerInit(void)
--{
-- htmlDefaultSAXHandler.internalSubset = internalSubset;
-- htmlDefaultSAXHandler.externalSubset = NULL;
-- htmlDefaultSAXHandler.isStandalone = NULL;
-- htmlDefaultSAXHandler.hasInternalSubset = NULL;
-- htmlDefaultSAXHandler.hasExternalSubset = NULL;
-- htmlDefaultSAXHandler.resolveEntity = NULL;
-- htmlDefaultSAXHandler.getEntity = getEntity;
-- htmlDefaultSAXHandler.getParameterEntity = NULL;
-- htmlDefaultSAXHandler.entityDecl = NULL;
-- htmlDefaultSAXHandler.attributeDecl = NULL;
-- htmlDefaultSAXHandler.elementDecl = NULL;
-- htmlDefaultSAXHandler.notationDecl = NULL;
-- htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
-- htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
-- htmlDefaultSAXHandler.startDocument = startDocument;
-- htmlDefaultSAXHandler.endDocument = endDocument;
-- htmlDefaultSAXHandler.startElement = startElement;
-- htmlDefaultSAXHandler.endElement = endElement;
-- htmlDefaultSAXHandler.reference = NULL;
-- htmlDefaultSAXHandler.characters = characters;
-- htmlDefaultSAXHandler.cdataBlock = cdataBlock;
-- htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
-- htmlDefaultSAXHandler.processingInstruction = NULL;
-- htmlDefaultSAXHandler.comment = comment;
-- htmlDefaultSAXHandler.warning = xmlParserWarning;
-- htmlDefaultSAXHandler.error = xmlParserError;
-- htmlDefaultSAXHandler.fatalError = xmlParserError;
--}
--
--/*
-- * Default handler for HTML, builds the DOM tree
-- */
--xmlSAXHandler sgmlDefaultSAXHandler = {
-- internalSubset,
-- NULL,
-- NULL,
-- NULL,
-- NULL,
-- getEntity,
-- NULL,
-- NULL,
-- NULL,
-- NULL,
-- NULL,
-- setDocumentLocator,
-- startDocument,
-- endDocument,
-- startElement,
-- endElement,
-- NULL,
-- characters,
-- ignorableWhitespace,
-- NULL,
-- comment,
-- xmlParserWarning,
-- xmlParserError,
-- xmlParserError,
-- getParameterEntity,
-- NULL,
-- NULL,
--};
--
--/**
-- * sgmlDefaultSAXHandlerInit:
-- *
-- * Initialize the default SAX handler
-- */
--void
--sgmlDefaultSAXHandlerInit(void)
--{
-- sgmlDefaultSAXHandler.internalSubset = internalSubset;
-- sgmlDefaultSAXHandler.externalSubset = NULL;
-- sgmlDefaultSAXHandler.isStandalone = NULL;
-- sgmlDefaultSAXHandler.hasInternalSubset = NULL;
-- sgmlDefaultSAXHandler.hasExternalSubset = NULL;
-- sgmlDefaultSAXHandler.resolveEntity = NULL;
-- sgmlDefaultSAXHandler.getEntity = getEntity;
-- sgmlDefaultSAXHandler.getParameterEntity = NULL;
-- sgmlDefaultSAXHandler.entityDecl = NULL;
-- sgmlDefaultSAXHandler.attributeDecl = NULL;
-- sgmlDefaultSAXHandler.elementDecl = NULL;
-- sgmlDefaultSAXHandler.notationDecl = NULL;
-- sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
-- sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
-- sgmlDefaultSAXHandler.startDocument = startDocument;
-- sgmlDefaultSAXHandler.endDocument = endDocument;
-- sgmlDefaultSAXHandler.startElement = startElement;
-- sgmlDefaultSAXHandler.endElement = endElement;
-- sgmlDefaultSAXHandler.reference = NULL;
-- sgmlDefaultSAXHandler.characters = characters;
-- sgmlDefaultSAXHandler.cdataBlock = NULL;
-- sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
-- sgmlDefaultSAXHandler.processingInstruction = NULL;
-- sgmlDefaultSAXHandler.comment = comment;
-- sgmlDefaultSAXHandler.warning = xmlParserWarning;
-- sgmlDefaultSAXHandler.error = xmlParserError;
-- sgmlDefaultSAXHandler.fatalError = xmlParserError;
--}
-diff -Nru libxml2-2.3.0/configure.in libxml2-2.3.0.new/configure.in
---- libxml2-2.3.0/configure.in Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/configure.in Mon Feb 12 04:07:26 2001
-@@ -1,6 +1,6 @@
- dnl Process this file with autoconf to produce a configure script.
- AC_PREREQ(2.2)
--AC_INIT(entities.c)
-+AC_INIT(libxml/entities.c)
- AM_CONFIG_HEADER(config.h)
- AC_CANONICAL_HOST
-
-@@ -19,9 +19,7 @@
- AC_SUBST(LIBXML_VERSION_INFO)
- AC_SUBST(LIBXML_VERSION_NUMBER)
-
--VERSION=${LIBXML_VERSION}
--
--AM_INIT_AUTOMAKE(libxml2, $VERSION)
-+AM_INIT_AUTOMAKE(libxml, $LIBXML_VERSION)
-
- AC_ARG_WITH(html-dir, [ --with-html-dir=PATH path to installed docs ])
-
-@@ -29,9 +27,6 @@
- AC_PROG_CC
- AC_PROG_INSTALL
- AC_PROG_CPP
--AC_PATH_PROG(RM, rm, /bin/rm)
--AC_PATH_PROG(MV, mv, /bin/mv)
--AC_PATH_PROG(TAR, tar, /bin/tar)
-
- dnl Make sure we have an ANSI compiler
- AM_C_PROTOTYPES
-@@ -41,33 +36,9 @@
-
- AM_MAINTAINER_MODE
-
--dnl Checks for zlib library.
--_cppflags="${CPPFLAGS}"
--_ldflags="${LDFLAGS}"
--
--AC_ARG_WITH(zlib,
--[ --with-zlib[=DIR] use libz in DIR],[
-- if test "$withval" != "no" -a "$withval" != "yes"; then
-- Z_DIR=$withval
-- CPPFLAGS="${CPPFLAGS} -I$withval/include"
-- LDFLAGS="${LDFLAGS} -L$withval/lib"
-- fi
--])
--
- AC_CHECK_HEADERS(zlib.h,
-- AC_CHECK_LIB(z, gzread,[
-- AC_DEFINE(HAVE_LIBZ)
-- if test "x${Z_DIR}" != "x"; then
-- Z_CFLAGS="-I${Z_DIR}/include"
-- Z_LIBS="-L${Z_DIR}/lib -lz"
-- else
-- Z_LIBS="-lz"
-- fi]))
--AC_SUBST(Z_CFLAGS)
--AC_SUBST(Z_LIBS)
--
--CPPFLAGS=${_cppflags}
--LDFLAGS=${_ldflags}
-+ AC_CHECK_LIB(z, gzread, [AC_DEFINE(HAVE_LIBZ) LIBS="$LIBS -lz"])
-+)
-
- dnl Checks for header files.
- AC_HEADER_DIRENT
-@@ -145,7 +116,7 @@
-
- XML_LIBDIR='-L${libdir}'
- XML_INCLUDEDIR='-I${includedir}/libxml -I${includedir}'
--XML_LIBS="-lxml2 $Z_LIBS $M_LIBS $LIBS"
-+XML_LIBS="-lxml $Z_LIBS $M_LIBS $LIBS"
-
- dnl
- dnl Extra flags
-@@ -170,7 +141,6 @@
- esac
-
-
--
- dnl
- dnl Use buffers for content
- dnl
-@@ -351,7 +321,6 @@
- fi
- AC_SUBST(WITH_MEM_DEBUG)
-
--AC_SUBST(CFLAGS)
- AC_SUBST(XML_CFLAGS)
-
- AC_SUBST(XML_LIBDIR)
-@@ -364,37 +333,14 @@
- AC_SUBST(M_LIBS)
- AC_SUBST(RDL_LIBS)
-
--dnl
--dnl create the libxml and include links needed to get dependencies right
--dnl
--if test ! -d $srcdir/include/libxml
--then
-- if test ! -d $srcdir/include
-- then
-- rm -f $srcdir/include
-- mkdir $srcdir/include
-- fi
-- rm -f $srcdir/libxml
-- (cd $srcdir/include ; ln -s .. libxml)
--fi
--if test ! -r $srcdir/libxml
--then
-- (cd $srcdir ; ln -s include/libxml libxml)
--fi
--if test ! -r include/libxml
--then
-- if test ! -d include
-- then
-- rm -f include
-- mkdir include
-- fi
-- (cd include ; ln -s ../libxml libxml)
--fi
--if test ! -r libxml
--then
-- rm -rf libxml
-- ln -s $srcdir/include/libxml libxml
--fi
--
--AC_OUTPUT(libxml.spec Makefile include/Makefile doc/Makefile example/Makefile libxml/xmlversion.h xml2-config libxml-2.0.pc xml2Conf.sh)
--
-+AC_OUTPUT([
-+ Makefile
-+ libxml/Makefile
-+ libxml/xmlversion.h
-+ libxml/xml-config
-+ libxml/libxml.pc
-+ libxml/xmlConf.sh
-+ doc/Makefile
-+ example/Makefile
-+ libxml.spec
-+ ])
-diff -Nru libxml2-2.3.0/debugXML.c libxml2-2.3.0.new/debugXML.c
---- libxml2-2.3.0/debugXML.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/debugXML.c Thu Jan 1 01:00:00 1970
-@@ -1,1888 +0,0 @@
--/*
-- * debugXML.c : This is a set of routines used for debugging the tree
-- * produced by the XML parser.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel Veillard <Daniel.Veillard@w3.org>
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_DEBUG_ENABLED
--
--#include <stdio.h>
--#include <string.h>
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_STRING_H
--#include <string.h>
--#endif
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/valid.h>
--#include <libxml/debugXML.h>
--#include <libxml/HTMLtree.h>
--#include <libxml/HTMLparser.h>
--#include <libxml/xmlerror.h>
--
--#define IS_BLANK(c) \
-- (((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
--
--void xmlDebugDumpString(FILE *output, const xmlChar *str) {
-- int i;
-- if (str == NULL) {
-- fprintf(output, "(NULL)");
-- return;
-- }
-- for (i = 0;i < 40;i++)
-- if (str[i] == 0) return;
-- else if (IS_BLANK(str[i])) fputc(' ', output);
-- else if (str[i] >= 0x80)
-- fprintf(output, "#%X", str[i]);
-- else fputc(str[i], output);
-- fprintf(output, "...");
--}
--
--void xmlDebugDumpDtd(FILE *output, xmlDtdPtr dtd, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
--
-- if (dtd->type != XML_DTD_NODE) {
-- fprintf(output, "PBM: not a DTD\n");
-- return;
-- }
-- if (dtd->name != NULL)
-- fprintf(output, "DTD(%s)", dtd->name);
-- else
-- fprintf(output, "DTD");
-- if (dtd->ExternalID != NULL)
-- fprintf(output, ", PUBLIC %s", dtd->ExternalID);
-- if (dtd->SystemID != NULL)
-- fprintf(output, ", SYSTEM %s", dtd->SystemID);
-- fprintf(output, "\n");
-- /*
-- * Do a bit of checking
-- */
-- if (dtd->parent == NULL)
-- fprintf(output, "PBM: Dtd has no parent\n");
-- if (dtd->doc == NULL)
-- fprintf(output, "PBM: Dtd has no doc\n");
-- if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
-- fprintf(output, "PBM: Dtd doc differs from parent's one\n");
-- if (dtd->prev == NULL) {
-- if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
-- fprintf(output, "PBM: Dtd has no prev and not first of list\n");
-- } else {
-- if (dtd->prev->next != (xmlNodePtr) dtd)
-- fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
-- }
-- if (dtd->next == NULL) {
-- if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
-- fprintf(output, "PBM: Dtd has no next and not last of list\n");
-- } else {
-- if (dtd->next->prev != (xmlNodePtr) dtd)
-- fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
-- }
--}
--
--void xmlDebugDumpAttrDecl(FILE *output, xmlAttributePtr attr, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
--
-- if (attr->type != XML_ATTRIBUTE_DECL) {
-- fprintf(output, "PBM: not a Attr\n");
-- return;
-- }
-- if (attr->name != NULL)
-- fprintf(output, "ATTRDECL(%s)", attr->name);
-- else
-- fprintf(output, "PBM ATTRDECL noname!!!");
-- if (attr->elem != NULL)
-- fprintf(output, " for %s", attr->elem);
-- else
-- fprintf(output, " PBM noelem!!!");
-- switch (attr->atype) {
-- case XML_ATTRIBUTE_CDATA:
-- fprintf(output, " CDATA");
-- break;
-- case XML_ATTRIBUTE_ID:
-- fprintf(output, " ID");
-- break;
-- case XML_ATTRIBUTE_IDREF:
-- fprintf(output, " IDREF");
-- break;
-- case XML_ATTRIBUTE_IDREFS:
-- fprintf(output, " IDREFS");
-- break;
-- case XML_ATTRIBUTE_ENTITY:
-- fprintf(output, " ENTITY");
-- break;
-- case XML_ATTRIBUTE_ENTITIES:
-- fprintf(output, " ENTITIES");
-- break;
-- case XML_ATTRIBUTE_NMTOKEN:
-- fprintf(output, " NMTOKEN");
-- break;
-- case XML_ATTRIBUTE_NMTOKENS:
-- fprintf(output, " NMTOKENS");
-- break;
-- case XML_ATTRIBUTE_ENUMERATION:
-- fprintf(output, " ENUMERATION");
-- break;
-- case XML_ATTRIBUTE_NOTATION:
-- fprintf(output, " NOTATION ");
-- break;
-- }
-- if (attr->tree != NULL) {
-- int i;
-- xmlEnumerationPtr cur = attr->tree;
--
-- for (i = 0;i < 5; i++) {
-- if (i != 0)
-- fprintf(output, "|%s", cur->name);
-- else
-- fprintf(output, " (%s", cur->name);
-- cur = cur->next;
-- if (cur == NULL) break;
-- }
-- if (cur == NULL)
-- fprintf(output, ")");
-- else
-- fprintf(output, "...)");
-- }
-- switch (attr->def) {
-- case XML_ATTRIBUTE_NONE:
-- break;
-- case XML_ATTRIBUTE_REQUIRED:
-- fprintf(output, " REQUIRED");
-- break;
-- case XML_ATTRIBUTE_IMPLIED:
-- fprintf(output, " IMPLIED");
-- break;
-- case XML_ATTRIBUTE_FIXED:
-- fprintf(output, " FIXED");
-- break;
-- }
-- if (attr->defaultValue != NULL) {
-- fprintf(output, "\"");
-- xmlDebugDumpString(output, attr->defaultValue);
-- fprintf(output, "\"");
-- }
-- printf("\n");
--
-- /*
-- * Do a bit of checking
-- */
-- if (attr->parent == NULL)
-- fprintf(output, "PBM: Attr has no parent\n");
-- if (attr->doc == NULL)
-- fprintf(output, "PBM: Attr has no doc\n");
-- if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
-- fprintf(output, "PBM: Attr doc differs from parent's one\n");
-- if (attr->prev == NULL) {
-- if ((attr->parent != NULL) && (attr->parent->children != (xmlNodePtr)attr))
-- fprintf(output, "PBM: Attr has no prev and not first of list\n");
-- } else {
-- if (attr->prev->next != (xmlNodePtr) attr)
-- fprintf(output, "PBM: Attr prev->next : back link wrong\n");
-- }
-- if (attr->next == NULL) {
-- if ((attr->parent != NULL) && (attr->parent->last != (xmlNodePtr) attr))
-- fprintf(output, "PBM: Attr has no next and not last of list\n");
-- } else {
-- if (attr->next->prev != (xmlNodePtr) attr)
-- fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
-- }
--}
--
--void xmlDebugDumpElemDecl(FILE *output, xmlElementPtr elem, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
--
-- if (elem->type != XML_ELEMENT_DECL) {
-- fprintf(output, "PBM: not a Elem\n");
-- return;
-- }
-- if (elem->name != NULL) {
-- fprintf(output, "ELEMDECL(");
-- xmlDebugDumpString(output, elem->name);
-- fprintf(output, ")");
-- } else
-- fprintf(output, "PBM ELEMDECL noname!!!");
-- switch (elem->etype) {
-- case XML_ELEMENT_TYPE_EMPTY:
-- fprintf(output, ", EMPTY");
-- break;
-- case XML_ELEMENT_TYPE_ANY:
-- fprintf(output, ", ANY");
-- break;
-- case XML_ELEMENT_TYPE_MIXED:
-- fprintf(output, ", MIXED ");
-- break;
-- case XML_ELEMENT_TYPE_ELEMENT:
-- fprintf(output, ", MIXED ");
-- break;
-- }
-- if (elem->content != NULL) {
-- char buf[5001];
--
-- buf[0] = 0;
-- xmlSprintfElementContent(buf, elem->content, 1);
-- buf[5000] = 0;
-- fprintf(output, "%s", buf);
-- }
-- printf("\n");
--
-- /*
-- * Do a bit of checking
-- */
-- if (elem->parent == NULL)
-- fprintf(output, "PBM: Elem has no parent\n");
-- if (elem->doc == NULL)
-- fprintf(output, "PBM: Elem has no doc\n");
-- if ((elem->parent != NULL) && (elem->doc != elem->parent->doc))
-- fprintf(output, "PBM: Elem doc differs from parent's one\n");
-- if (elem->prev == NULL) {
-- if ((elem->parent != NULL) && (elem->parent->children != (xmlNodePtr)elem))
-- fprintf(output, "PBM: Elem has no prev and not first of list\n");
-- } else {
-- if (elem->prev->next != (xmlNodePtr) elem)
-- fprintf(output, "PBM: Elem prev->next : back link wrong\n");
-- }
-- if (elem->next == NULL) {
-- if ((elem->parent != NULL) && (elem->parent->last != (xmlNodePtr) elem))
-- fprintf(output, "PBM: Elem has no next and not last of list\n");
-- } else {
-- if (elem->next->prev != (xmlNodePtr) elem)
-- fprintf(output, "PBM: Elem next->prev : forward link wrong\n");
-- }
--}
--
--void xmlDebugDumpEntityDecl(FILE *output, xmlEntityPtr ent, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
--
-- if (ent->type != XML_ENTITY_DECL) {
-- fprintf(output, "PBM: not a Entity decl\n");
-- return;
-- }
-- if (ent->name != NULL) {
-- fprintf(output, "ENTITYDECL(");
-- xmlDebugDumpString(output, ent->name);
-- fprintf(output, ")");
-- } else
-- fprintf(output, "PBM ENTITYDECL noname!!!");
-- switch (ent->etype) {
-- case XML_INTERNAL_GENERAL_ENTITY:
-- fprintf(output, ", internal\n");
-- break;
-- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-- fprintf(output, ", external parsed\n");
-- break;
-- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-- fprintf(output, ", unparsed\n");
-- break;
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- fprintf(output, ", parameter\n");
-- break;
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- fprintf(output, ", external parameter\n");
-- break;
-- case XML_INTERNAL_PREDEFINED_ENTITY:
-- fprintf(output, ", predefined\n");
-- break;
-- }
-- if (ent->ExternalID) {
-- fprintf(output, shift);
-- fprintf(output, " ExternalID=%s\n", ent->ExternalID);
-- }
-- if (ent->SystemID) {
-- fprintf(output, shift);
-- fprintf(output, " SystemID=%s\n", ent->SystemID);
-- }
-- if (ent->URI != NULL) {
-- fprintf(output, shift);
-- fprintf(output, " URI=%s\n", ent->URI);
-- }
-- if (ent->content) {
-- fprintf(output, shift);
-- fprintf(output, " content=");
-- xmlDebugDumpString(output, ent->content);
-- fprintf(output, "\n");
-- }
--
-- /*
-- * Do a bit of checking
-- */
-- if (ent->parent == NULL)
-- fprintf(output, "PBM: Ent has no parent\n");
-- if (ent->doc == NULL)
-- fprintf(output, "PBM: Ent has no doc\n");
-- if ((ent->parent != NULL) && (ent->doc != ent->parent->doc))
-- fprintf(output, "PBM: Ent doc differs from parent's one\n");
-- if (ent->prev == NULL) {
-- if ((ent->parent != NULL) && (ent->parent->children != (xmlNodePtr)ent))
-- fprintf(output, "PBM: Ent has no prev and not first of list\n");
-- } else {
-- if (ent->prev->next != (xmlNodePtr) ent)
-- fprintf(output, "PBM: Ent prev->next : back link wrong\n");
-- }
-- if (ent->next == NULL) {
-- if ((ent->parent != NULL) && (ent->parent->last != (xmlNodePtr) ent))
-- fprintf(output, "PBM: Ent has no next and not last of list\n");
-- } else {
-- if (ent->next->prev != (xmlNodePtr) ent)
-- fprintf(output, "PBM: Ent next->prev : forward link wrong\n");
-- }
--}
--
--void xmlDebugDumpNamespace(FILE *output, xmlNsPtr ns, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
-- if (ns->type != XML_NAMESPACE_DECL) {
-- fprintf(output, "invalid namespace node %d\n", ns->type);
-- return;
-- }
-- if (ns->href == NULL) {
-- if (ns->prefix != NULL)
-- fprintf(output, "incomplete namespace %s href=NULL\n", ns->prefix);
-- else
-- fprintf(output, "incomplete default namespace href=NULL\n");
-- } else {
-- if (ns->prefix != NULL)
-- fprintf(output, "namespace %s href=", ns->prefix);
-- else
-- fprintf(output, "default namespace href=");
--
-- xmlDebugDumpString(output, ns->href);
-- fprintf(output, "\n");
-- }
--}
--
--void xmlDebugDumpNamespaceList(FILE *output, xmlNsPtr ns, int depth) {
-- while (ns != NULL) {
-- xmlDebugDumpNamespace(output, ns, depth);
-- ns = ns->next;
-- }
--}
--
--void xmlDebugDumpEntity(FILE *output, xmlEntityPtr ent, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
-- switch (ent->etype) {
-- case XML_INTERNAL_GENERAL_ENTITY:
-- fprintf(output, "INTERNAL_GENERAL_ENTITY ");
-- break;
-- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-- fprintf(output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
-- break;
-- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-- fprintf(output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
-- break;
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- fprintf(output, "INTERNAL_PARAMETER_ENTITY ");
-- break;
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- fprintf(output, "EXTERNAL_PARAMETER_ENTITY ");
-- break;
-- default:
-- fprintf(output, "ENTITY_%d ! ", ent->etype);
-- }
-- fprintf(output, "%s\n", ent->name);
-- if (ent->ExternalID) {
-- fprintf(output, shift);
-- fprintf(output, "ExternalID=%s\n", ent->ExternalID);
-- }
-- if (ent->SystemID) {
-- fprintf(output, shift);
-- fprintf(output, "SystemID=%s\n", ent->SystemID);
-- }
-- if (ent->URI) {
-- fprintf(output, shift);
-- fprintf(output, "URI=%s\n", ent->URI);
-- }
-- if (ent->content) {
-- fprintf(output, shift);
-- fprintf(output, "content=");
-- xmlDebugDumpString(output, ent->content);
-- fprintf(output, "\n");
-- }
--}
--
--void xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
--
-- fprintf(output, "ATTRIBUTE ");
-- xmlDebugDumpString(output, attr->name);
-- fprintf(output, "\n");
-- if (attr->children != NULL)
-- xmlDebugDumpNodeList(output, attr->children, depth + 1);
--
-- /*
-- * Do a bit of checking
-- */
-- if (attr->parent == NULL)
-- fprintf(output, "PBM: Attr has no parent\n");
-- if (attr->doc == NULL)
-- fprintf(output, "PBM: Attr has no doc\n");
-- if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
-- fprintf(output, "PBM: Attr doc differs from parent's one\n");
-- if (attr->prev == NULL) {
-- if ((attr->parent != NULL) && (attr->parent->properties != attr))
-- fprintf(output, "PBM: Attr has no prev and not first of list\n");
-- } else {
-- if (attr->prev->next != attr)
-- fprintf(output, "PBM: Attr prev->next : back link wrong\n");
-- }
-- if (attr->next != NULL) {
-- if (attr->next->prev != attr)
-- fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
-- }
--}
--
--void xmlDebugDumpAttrList(FILE *output, xmlAttrPtr attr, int depth) {
-- while (attr != NULL) {
-- xmlDebugDumpAttr(output, attr, depth);
-- attr = attr->next;
-- }
--}
--
--void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- switch (node->type) {
-- case XML_ELEMENT_NODE:
-- fprintf(output, shift);
-- fprintf(output, "ELEMENT ");
-- if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
-- xmlDebugDumpString(output, node->ns->prefix);
-- fprintf(output, ":");
-- }
-- xmlDebugDumpString(output, node->name);
-- fprintf(output, "\n");
-- break;
-- case XML_ATTRIBUTE_NODE:
-- fprintf(output, shift);
-- fprintf(output, "Error, ATTRIBUTE found here\n");
-- break;
-- case XML_TEXT_NODE:
-- fprintf(output, shift);
-- fprintf(output, "TEXT\n");
-- break;
-- case XML_CDATA_SECTION_NODE:
-- fprintf(output, shift);
-- fprintf(output, "CDATA_SECTION\n");
-- break;
-- case XML_ENTITY_REF_NODE:
-- fprintf(output, shift);
-- fprintf(output, "ENTITY_REF(%s)\n", node->name);
-- break;
-- case XML_ENTITY_NODE:
-- fprintf(output, shift);
-- fprintf(output, "ENTITY\n");
-- break;
-- case XML_PI_NODE:
-- fprintf(output, shift);
-- fprintf(output, "PI %s\n", node->name);
-- break;
-- case XML_COMMENT_NODE:
-- fprintf(output, shift);
-- fprintf(output, "COMMENT\n");
-- break;
-- case XML_DOCUMENT_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- fprintf(output, shift);
-- fprintf(output, "Error, DOCUMENT found here\n");
-- break;
-- case XML_DOCUMENT_TYPE_NODE:
-- fprintf(output, shift);
-- fprintf(output, "DOCUMENT_TYPE\n");
-- break;
-- case XML_DOCUMENT_FRAG_NODE:
-- fprintf(output, shift);
-- fprintf(output, "DOCUMENT_FRAG\n");
-- break;
-- case XML_NOTATION_NODE:
-- fprintf(output, shift);
-- fprintf(output, "NOTATION\n");
-- break;
-- case XML_DTD_NODE:
-- xmlDebugDumpDtd(output, (xmlDtdPtr) node, depth);
-- return;
-- case XML_ELEMENT_DECL:
-- xmlDebugDumpElemDecl(output, (xmlElementPtr) node, depth);
-- return;
-- case XML_ATTRIBUTE_DECL:
-- xmlDebugDumpAttrDecl(output, (xmlAttributePtr) node, depth);
-- return;
-- case XML_ENTITY_DECL:
-- xmlDebugDumpEntityDecl(output, (xmlEntityPtr) node, depth);
-- return;
-- case XML_NAMESPACE_DECL:
-- xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
-- return;
-- case XML_XINCLUDE_START:
-- fprintf(output, shift);
-- fprintf(output, "INCLUDE START\n");
-- return;
-- case XML_XINCLUDE_END:
-- fprintf(output, shift);
-- fprintf(output, "INCLUDE END\n");
-- return;
-- default:
-- fprintf(output, shift);
-- fprintf(output, "NODE_%d !!!\n", node->type);
-- return;
-- }
-- if (node->doc == NULL) {
-- fprintf(output, shift);
-- fprintf(output, "doc == NULL !!!\n");
-- }
-- if (node->nsDef != NULL)
-- xmlDebugDumpNamespaceList(output, node->nsDef, depth + 1);
-- if (node->properties != NULL)
-- xmlDebugDumpAttrList(output, node->properties, depth + 1);
-- if (node->type != XML_ENTITY_REF_NODE) {
-- if (node->content != NULL) {
-- shift[2 * i] = shift[2 * i + 1] = ' ' ;
-- shift[2 * i + 2] = shift[2 * i + 3] = 0 ;
-- fprintf(output, shift);
-- fprintf(output, "content=");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlDebugDumpString(output, node->content);
--#else
-- xmlDebugDumpString(output, xmlBufferContent(node->content));
--#endif
-- fprintf(output, "\n");
-- }
-- } else {
-- xmlEntityPtr ent;
-- ent = xmlGetDocEntity(node->doc, node->name);
-- if (ent != NULL)
-- xmlDebugDumpEntity(output, ent, depth + 1);
-- }
-- /*
-- * Do a bit of checking
-- */
-- if (node->parent == NULL)
-- fprintf(output, "PBM: Node has no parent\n");
-- if (node->doc == NULL)
-- fprintf(output, "PBM: Node has no doc\n");
-- if ((node->parent != NULL) && (node->doc != node->parent->doc))
-- fprintf(output, "PBM: Node doc differs from parent's one\n");
-- if (node->prev == NULL) {
-- if ((node->parent != NULL) && (node->parent->children != node))
-- fprintf(output, "PBM: Node has no prev and not first of list\n");
-- } else {
-- if (node->prev->next != node)
-- fprintf(output, "PBM: Node prev->next : back link wrong\n");
-- }
-- if (node->next == NULL) {
-- if ((node->parent != NULL) && (node->parent->last != node))
-- fprintf(output, "PBM: Node has no next and not last of list\n");
-- } else {
-- if (node->next->prev != node)
-- fprintf(output, "PBM: Node next->prev : forward link wrong\n");
-- }
--}
--
--void xmlDebugDumpNode(FILE *output, xmlNodePtr node, int depth) {
-- xmlDebugDumpOneNode(output, node, depth);
-- if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
-- xmlDebugDumpNodeList(output, node->children, depth + 1);
--}
--
--void xmlDebugDumpNodeList(FILE *output, xmlNodePtr node, int depth) {
-- while (node != NULL) {
-- xmlDebugDumpNode(output, node, depth);
-- node = node->next;
-- }
--}
--
--
--void xmlDebugDumpDocumentHead(FILE *output, xmlDocPtr doc) {
-- if (output == NULL) output = stdout;
-- if (doc == NULL) {
-- fprintf(output, "DOCUMENT == NULL !\n");
-- return;
-- }
--
-- switch (doc->type) {
-- case XML_ELEMENT_NODE:
-- fprintf(output, "Error, ELEMENT found here ");
-- break;
-- case XML_ATTRIBUTE_NODE:
-- fprintf(output, "Error, ATTRIBUTE found here\n");
-- break;
-- case XML_TEXT_NODE:
-- fprintf(output, "Error, TEXT\n");
-- break;
-- case XML_CDATA_SECTION_NODE:
-- fprintf(output, "Error, CDATA_SECTION\n");
-- break;
-- case XML_ENTITY_REF_NODE:
-- fprintf(output, "Error, ENTITY_REF\n");
-- break;
-- case XML_ENTITY_NODE:
-- fprintf(output, "Error, ENTITY\n");
-- break;
-- case XML_PI_NODE:
-- fprintf(output, "Error, PI\n");
-- break;
-- case XML_COMMENT_NODE:
-- fprintf(output, "Error, COMMENT\n");
-- break;
-- case XML_DOCUMENT_NODE:
-- fprintf(output, "DOCUMENT\n");
-- break;
-- case XML_HTML_DOCUMENT_NODE:
-- fprintf(output, "HTML DOCUMENT\n");
-- break;
-- case XML_DOCUMENT_TYPE_NODE:
-- fprintf(output, "Error, DOCUMENT_TYPE\n");
-- break;
-- case XML_DOCUMENT_FRAG_NODE:
-- fprintf(output, "Error, DOCUMENT_FRAG\n");
-- break;
-- case XML_NOTATION_NODE:
-- fprintf(output, "Error, NOTATION\n");
-- break;
-- default:
-- fprintf(output, "NODE_%d\n", doc->type);
-- }
-- if (doc->name != NULL) {
-- fprintf(output, "name=");
-- xmlDebugDumpString(output, BAD_CAST doc->name);
-- fprintf(output, "\n");
-- }
-- if (doc->version != NULL) {
-- fprintf(output, "version=");
-- xmlDebugDumpString(output, doc->version);
-- fprintf(output, "\n");
-- }
-- if (doc->encoding != NULL) {
-- fprintf(output, "encoding=");
-- xmlDebugDumpString(output, doc->encoding);
-- fprintf(output, "\n");
-- }
-- if (doc->URL != NULL) {
-- fprintf(output, "URL=");
-- xmlDebugDumpString(output, doc->URL);
-- fprintf(output, "\n");
-- }
-- if (doc->standalone)
-- fprintf(output, "standalone=true\n");
-- if (doc->oldNs != NULL)
-- xmlDebugDumpNamespaceList(output, doc->oldNs, 0);
--}
--
--void xmlDebugDumpDocument(FILE *output, xmlDocPtr doc) {
-- if (output == NULL) output = stdout;
-- if (doc == NULL) {
-- fprintf(output, "DOCUMENT == NULL !\n");
-- return;
-- }
-- xmlDebugDumpDocumentHead(output, doc);
-- if (((doc->type == XML_DOCUMENT_NODE) ||
-- (doc->type == XML_HTML_DOCUMENT_NODE)) &&
-- (doc->children != NULL))
-- xmlDebugDumpNodeList(output, doc->children, 1);
--}
--
--void xmlDebugDumpDTD(FILE *output, xmlDtdPtr dtd) {
-- if (dtd == NULL)
-- return;
-- if (dtd->type != XML_DTD_NODE) {
-- fprintf(output, "PBM: not a DTD\n");
-- return;
-- }
-- if (dtd->name != NULL)
-- fprintf(output, "DTD(%s)", dtd->name);
-- else
-- fprintf(output, "DTD");
-- if (dtd->ExternalID != NULL)
-- fprintf(output, ", PUBLIC %s", dtd->ExternalID);
-- if (dtd->SystemID != NULL)
-- fprintf(output, ", SYSTEM %s", dtd->SystemID);
-- fprintf(output, "\n");
-- /*
-- * Do a bit of checking
-- */
-- if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
-- fprintf(output, "PBM: Dtd doc differs from parent's one\n");
-- if (dtd->prev == NULL) {
-- if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
-- fprintf(output, "PBM: Dtd has no prev and not first of list\n");
-- } else {
-- if (dtd->prev->next != (xmlNodePtr) dtd)
-- fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
-- }
-- if (dtd->next == NULL) {
-- if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
-- fprintf(output, "PBM: Dtd has no next and not last of list\n");
-- } else {
-- if (dtd->next->prev != (xmlNodePtr) dtd)
-- fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
-- }
-- if (dtd->children == NULL)
-- fprintf(output, " DTD is empty\n");
-- else
-- xmlDebugDumpNodeList(output, dtd->children, 1);
--}
--
--void xmlDebugDumpEntityCallback(xmlEntityPtr cur, FILE *output,
-- const xmlChar *name) {
-- fprintf(output, "%s : ", cur->name);
-- switch (cur->etype) {
-- case XML_INTERNAL_GENERAL_ENTITY:
-- fprintf(output, "INTERNAL GENERAL, ");
-- break;
-- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-- fprintf(output, "EXTERNAL PARSED, ");
-- break;
-- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-- fprintf(output, "EXTERNAL UNPARSED, ");
-- break;
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- fprintf(output, "INTERNAL PARAMETER, ");
-- break;
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- fprintf(output, "EXTERNAL PARAMETER, ");
-- break;
-- default:
-- fprintf(output, "UNKNOWN TYPE %d",
-- cur->etype);
-- }
-- if (cur->ExternalID != NULL)
-- fprintf(output, "ID \"%s\"", cur->ExternalID);
-- if (cur->SystemID != NULL)
-- fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
-- if (cur->orig != NULL)
-- fprintf(output, "\n orig \"%s\"", cur->orig);
-- if (cur->content != NULL)
-- fprintf(output, "\n content \"%s\"", cur->content);
-- fprintf(output, "\n");
--}
--
--void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
-- if (output == NULL) output = stdout;
-- if (doc == NULL) {
-- fprintf(output, "DOCUMENT == NULL !\n");
-- return;
-- }
--
-- switch (doc->type) {
-- case XML_ELEMENT_NODE:
-- fprintf(output, "Error, ELEMENT found here ");
-- break;
-- case XML_ATTRIBUTE_NODE:
-- fprintf(output, "Error, ATTRIBUTE found here\n");
-- break;
-- case XML_TEXT_NODE:
-- fprintf(output, "Error, TEXT\n");
-- break;
-- case XML_CDATA_SECTION_NODE:
-- fprintf(output, "Error, CDATA_SECTION\n");
-- break;
-- case XML_ENTITY_REF_NODE:
-- fprintf(output, "Error, ENTITY_REF\n");
-- break;
-- case XML_ENTITY_NODE:
-- fprintf(output, "Error, ENTITY\n");
-- break;
-- case XML_PI_NODE:
-- fprintf(output, "Error, PI\n");
-- break;
-- case XML_COMMENT_NODE:
-- fprintf(output, "Error, COMMENT\n");
-- break;
-- case XML_DOCUMENT_NODE:
-- fprintf(output, "DOCUMENT\n");
-- break;
-- case XML_HTML_DOCUMENT_NODE:
-- fprintf(output, "HTML DOCUMENT\n");
-- break;
-- case XML_DOCUMENT_TYPE_NODE:
-- fprintf(output, "Error, DOCUMENT_TYPE\n");
-- break;
-- case XML_DOCUMENT_FRAG_NODE:
-- fprintf(output, "Error, DOCUMENT_FRAG\n");
-- break;
-- case XML_NOTATION_NODE:
-- fprintf(output, "Error, NOTATION\n");
-- break;
-- default:
-- fprintf(output, "NODE_%d\n", doc->type);
-- }
-- if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
-- xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
-- doc->intSubset->entities;
-- fprintf(output, "Entities in internal subset\n");
-- xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
-- } else
-- fprintf(output, "No entities in internal subset\n");
-- if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-- xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
-- doc->extSubset->entities;
-- fprintf(output, "Entities in external subset\n");
-- xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
-- } else
-- fprintf(output, "No entities in external subset\n");
--}
--
--static int xmlLsCountNode(xmlNodePtr node) {
-- int ret = 0;
-- xmlNodePtr list = NULL;
--
-- switch (node->type) {
-- case XML_ELEMENT_NODE:
-- list = node->children;
-- break;
-- case XML_DOCUMENT_NODE:
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- list = ((xmlDocPtr) node)->children;
-- break;
-- case XML_ATTRIBUTE_NODE:
-- list = ((xmlAttrPtr) node)->children;
-- break;
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- if (node->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- ret = xmlStrlen(node->content);
--#else
-- ret = xmlBufferLength(node->content);
--#endif
-- }
-- break;
-- case XML_ENTITY_REF_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_ENTITY_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_NOTATION_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- ret = 1;
-- break;
-- }
-- for (;list != NULL;ret++)
-- list = list->next;
-- return(ret);
--}
--
--void xmlLsOneNode(FILE *output, xmlNodePtr node) {
-- switch (node->type) {
-- case XML_ELEMENT_NODE:
-- fprintf(output, "-");
-- break;
-- case XML_ATTRIBUTE_NODE:
-- fprintf(output, "a");
-- break;
-- case XML_TEXT_NODE:
-- fprintf(output, "t");
-- break;
-- case XML_CDATA_SECTION_NODE:
-- fprintf(output, "c");
-- break;
-- case XML_ENTITY_REF_NODE:
-- fprintf(output, "e");
-- break;
-- case XML_ENTITY_NODE:
-- fprintf(output, "E");
-- break;
-- case XML_PI_NODE:
-- fprintf(output, "p");
-- break;
-- case XML_COMMENT_NODE:
-- fprintf(output, "c");
-- break;
-- case XML_DOCUMENT_NODE:
-- fprintf(output, "d");
-- break;
-- case XML_HTML_DOCUMENT_NODE:
-- fprintf(output, "h");
-- break;
-- case XML_DOCUMENT_TYPE_NODE:
-- fprintf(output, "T");
-- break;
-- case XML_DOCUMENT_FRAG_NODE:
-- fprintf(output, "F");
-- break;
-- case XML_NOTATION_NODE:
-- fprintf(output, "N");
-- break;
-- default:
-- fprintf(output, "?");
-- }
-- if (node->properties != NULL)
-- fprintf(output, "a");
-- else
-- fprintf(output, "-");
-- if (node->nsDef != NULL)
-- fprintf(output, "n");
-- else
-- fprintf(output, "-");
--
-- fprintf(output, " %8d ", xmlLsCountNode(node));
--
-- switch (node->type) {
-- case XML_ELEMENT_NODE:
-- if (node->name != NULL)
-- fprintf(output, "%s", node->name);
-- break;
-- case XML_ATTRIBUTE_NODE:
-- if (node->name != NULL)
-- fprintf(output, "%s", node->name);
-- break;
-- case XML_TEXT_NODE:
-- if (node->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlDebugDumpString(output, node->content);
--#else
-- xmlDebugDumpString(output, xmlBufferContent(node->content));
--#endif
-- }
-- break;
-- case XML_CDATA_SECTION_NODE:
-- break;
-- case XML_ENTITY_REF_NODE:
-- if (node->name != NULL)
-- fprintf(output, "%s", node->name);
-- break;
-- case XML_ENTITY_NODE:
-- if (node->name != NULL)
-- fprintf(output, "%s", node->name);
-- break;
-- case XML_PI_NODE:
-- if (node->name != NULL)
-- fprintf(output, "%s", node->name);
-- break;
-- case XML_COMMENT_NODE:
-- break;
-- case XML_DOCUMENT_NODE:
-- break;
-- case XML_HTML_DOCUMENT_NODE:
-- break;
-- case XML_DOCUMENT_TYPE_NODE:
-- break;
-- case XML_DOCUMENT_FRAG_NODE:
-- break;
-- case XML_NOTATION_NODE:
-- break;
-- default:
-- if (node->name != NULL)
-- fprintf(output, "%s", node->name);
-- }
-- fprintf(output, "\n");
--}
--
--/****************************************************************
-- * *
-- * The XML shell related functions *
-- * *
-- ****************************************************************/
--
--/*
-- * TODO: Improvement/cleanups for the XML shell
-- * - allow to shell out an editor on a subpart
-- * - cleanup function registrations (with help) and calling
-- * - provide registration routines
-- */
--
--/**
-- * xmlShellList:
-- * @ctxt: the shell context
-- * @arg: unused
-- * @node: a node
-- * @node2: unused
-- *
-- * Implements the XML shell function "ls"
-- * Does an Unix like listing of the given node (like a directory)
-- *
-- * Returns 0
-- */
--int
--xmlShellList(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
-- xmlNodePtr node2) {
-- xmlNodePtr cur;
--
-- if ((node->type == XML_DOCUMENT_NODE) ||
-- (node->type == XML_HTML_DOCUMENT_NODE)) {
-- cur = ((xmlDocPtr) node)->children;
-- } else if (node->children != NULL) {
-- cur = node->children;
-- } else {
-- xmlLsOneNode(stdout, node);
-- return(0);
-- }
-- while (cur != NULL) {
-- xmlLsOneNode(stdout, cur);
-- cur = cur->next;
-- }
-- return(0);
--}
--
--/**
-- * xmlShellDir:
-- * @ctxt: the shell context
-- * @arg: unused
-- * @node: a node
-- * @node2: unused
-- *
-- * Implements the XML shell function "dir"
-- * dumps informations about the node (namespace, attributes, content).
-- *
-- * Returns 0
-- */
--int
--xmlShellDir(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
-- xmlNodePtr node2) {
-- if ((node->type == XML_DOCUMENT_NODE) ||
-- (node->type == XML_HTML_DOCUMENT_NODE)) {
-- xmlDebugDumpDocumentHead(stdout, (xmlDocPtr) node);
-- } else if (node->type == XML_ATTRIBUTE_NODE) {
-- xmlDebugDumpAttr(stdout, (xmlAttrPtr) node, 0);
-- } else {
-- xmlDebugDumpOneNode(stdout, node, 0);
-- }
-- return(0);
--}
--
--/**
-- * xmlShellCat:
-- * @ctxt: the shell context
-- * @arg: unused
-- * @node: a node
-- * @node2: unused
-- *
-- * Implements the XML shell function "cat"
-- * dumps the serialization node content (XML or HTML).
-- *
-- * Returns 0
-- */
--int
--xmlShellCat(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
-- xmlNodePtr node2) {
-- if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
--#ifdef LIBXML_HTML_ENABLED
-- if (node->type == XML_HTML_DOCUMENT_NODE)
-- htmlDocDump(stdout, (htmlDocPtr) node);
-- else
-- htmlNodeDumpFile(stdout, ctxt->doc, node);
--#else
-- if (node->type == XML_DOCUMENT_NODE)
-- xmlDocDump(stdout, (xmlDocPtr) node);
-- else
-- xmlElemDump(stdout, ctxt->doc, node);
--#endif /* LIBXML_HTML_ENABLED */
-- } else {
-- if (node->type == XML_DOCUMENT_NODE)
-- xmlDocDump(stdout, (xmlDocPtr) node);
-- else
-- xmlElemDump(stdout, ctxt->doc, node);
-- }
-- printf("\n");
-- return(0);
--}
--
--/**
-- * xmlShellLoad:
-- * @ctxt: the shell context
-- * @filename: the file name
-- * @node: unused
-- * @node2: unused
-- *
-- * Implements the XML shell function "load"
-- * loads a new document specified by the filename
-- *
-- * Returns 0 or -1 if loading failed
-- */
--int
--xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-- xmlNodePtr node2) {
-- xmlDocPtr doc;
-- int html = 0;
--
-- if (ctxt->doc != NULL)
-- html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
--
-- if (html) {
--#ifdef LIBXML_HTML_ENABLED
-- doc = htmlParseFile(filename, NULL);
--#else
-- printf("HTML support not compiled in\n");
-- doc = NULL;
--#endif /* LIBXML_HTML_ENABLED */
-- } else {
-- doc = xmlParseFile(filename);
-- }
-- if (doc != NULL) {
-- if (ctxt->loaded == 1) {
-- xmlFreeDoc(ctxt->doc);
-- }
-- ctxt->loaded = 1;
--#ifdef LIBXML_XPATH_ENABLED
-- xmlXPathFreeContext(ctxt->pctxt);
--#endif /* LIBXML_XPATH_ENABLED */
-- xmlFree(ctxt->filename);
-- ctxt->doc = doc;
-- ctxt->node = (xmlNodePtr) doc;
--#ifdef LIBXML_XPATH_ENABLED
-- ctxt->pctxt = xmlXPathNewContext(doc);
--#endif /* LIBXML_XPATH_ENABLED */
-- ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
-- } else
-- return(-1);
-- return(0);
--}
--
--/**
-- * xmlShellWrite:
-- * @ctxt: the shell context
-- * @filename: the file name
-- * @node: a node in the tree
-- * @node2: unused
-- *
-- * Implements the XML shell function "write"
-- * Write the current node to the filename, it saves the serailization
-- * of the subtree under the @node specified
-- *
-- * Returns 0 or -1 in case of error
-- */
--int
--xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-- xmlNodePtr node2) {
-- if (node == NULL)
-- return(-1);
-- if ((filename == NULL) || (filename[0] == 0)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Write command requires a filename argument\n");
-- return(-1);
-- }
--#ifdef W_OK
-- if (access((char *) filename, W_OK)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Cannot write to %s\n", filename);
-- return(-1);
-- }
--#endif
-- switch(node->type) {
-- case XML_DOCUMENT_NODE:
-- if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to write to %s\n", filename);
-- return(-1);
-- }
-- break;
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_HTML_ENABLED
-- if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to write to %s\n", filename);
-- return(-1);
-- }
--#else
-- if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to write to %s\n", filename);
-- return(-1);
-- }
--#endif /* LIBXML_HTML_ENABLED */
-- break;
-- default: {
-- FILE *f;
--
-- f = fopen((char *) filename, "w");
-- if (f == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to write to %s\n", filename);
-- return(-1);
-- }
-- xmlElemDump(f, ctxt->doc, node);
-- fclose(f);
-- }
-- }
-- return(0);
--}
--
--/**
-- * xmlShellSave:
-- * @ctxt: the shell context
-- * @filename: the file name (optionnal)
-- * @node: unused
-- * @node2: unused
-- *
-- * Implements the XML shell function "save"
-- * Write the current document to the filename, or it's original name
-- *
-- * Returns 0 or -1 in case of error
-- */
--int
--xmlShellSave(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-- xmlNodePtr node2) {
-- if (ctxt->doc == NULL)
-- return(-1);
-- if ((filename == NULL) || (filename[0] == 0))
-- filename = ctxt->filename;
--#ifdef W_OK
-- if (access((char *) filename, W_OK)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Cannot save to %s\n", filename);
-- return(-1);
-- }
--#endif
-- switch(ctxt->doc->type) {
-- case XML_DOCUMENT_NODE:
-- if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to save to %s\n", filename);
-- }
-- break;
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_HTML_ENABLED
-- if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to save to %s\n", filename);
-- }
--#else
-- if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to save to %s\n", filename);
-- }
--#endif /* LIBXML_HTML_ENABLED */
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "To save to subparts of a document use the 'write' command\n");
-- return(-1);
--
-- }
-- return(0);
--}
--
--/**
-- * xmlShellValidate:
-- * @ctxt: the shell context
-- * @dtd: the DTD URI (optionnal)
-- * @node: unused
-- * @node2: unused
-- *
-- * Implements the XML shell function "validate"
-- * Validate the document, if a DTD path is provided, then the validation
-- * is done against the given DTD.
-- *
-- * Returns 0 or -1 in case of error
-- */
--int
--xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd, xmlNodePtr node,
-- xmlNodePtr node2) {
-- xmlValidCtxt vctxt;
-- int res = -1;
--
-- vctxt.userData = stderr;
-- vctxt.error = (xmlValidityErrorFunc) fprintf;
-- vctxt.warning = (xmlValidityWarningFunc) fprintf;
--
-- if ((dtd == NULL) || (dtd[0] == 0)) {
-- res = xmlValidateDocument(&vctxt, ctxt->doc);
-- } else {
-- xmlDtdPtr subset;
--
-- subset = xmlParseDTD(NULL, (xmlChar *) dtd);
-- if (subset != NULL) {
-- res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
--
-- xmlFreeDtd(subset);
-- }
-- }
-- return(res);
--}
--
--/**
-- * xmlShellDu:
-- * @ctxt: the shell context
-- * @arg: unused
-- * @tree: a node defining a subtree
-- * @node2: unused
-- *
-- * Implements the XML shell function "du"
-- * show the structure of the subtree under node @tree
-- * If @tree is null, the command works on the current node.
-- *
-- * Returns 0 or -1 in case of error
-- */
--int
--xmlShellDu(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr tree,
-- xmlNodePtr node2) {
-- xmlNodePtr node;
-- int indent = 0,i;
--
-- if (tree == NULL) return(-1);
-- node = tree;
-- while (node != NULL) {
-- if ((node->type == XML_DOCUMENT_NODE) ||
-- (node->type == XML_HTML_DOCUMENT_NODE)) {
-- printf("/\n");
-- } else if (node->type == XML_ELEMENT_NODE) {
-- for (i = 0;i < indent;i++)
-- printf(" ");
-- printf("%s\n", node->name);
-- } else {
-- }
--
-- /*
-- * Browse the full subtree, deep first
-- */
--
-- if ((node->type == XML_DOCUMENT_NODE) ||
-- (node->type == XML_HTML_DOCUMENT_NODE)) {
-- node = ((xmlDocPtr) node)->children;
-- } else if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
-- /* deep first */
-- node = node->children;
-- indent++;
-- } else if ((node != tree) && (node->next != NULL)) {
-- /* then siblings */
-- node = node->next;
-- } else if (node != tree) {
-- /* go up to parents->next if needed */
-- while (node != tree) {
-- if (node->parent != NULL) {
-- node = node->parent;
-- indent--;
-- }
-- if ((node != tree) && (node->next != NULL)) {
-- node = node->next;
-- break;
-- }
-- if (node->parent == NULL) {
-- node = NULL;
-- break;
-- }
-- if (node == tree) {
-- node = NULL;
-- break;
-- }
-- }
-- /* exit condition */
-- if (node == tree)
-- node = NULL;
-- } else
-- node = NULL;
-- }
-- return(0);
--}
--
--/**
-- * xmlShellPwd:
-- * @ctxt: the shell context
-- * @buffer: the output buffer
-- * @tree: a node
-- * @node2: unused
-- *
-- * Implements the XML shell function "pwd"
-- * Show the full path from the root to the node, if needed building
-- * thumblers when similar elements exists at a given ancestor level.
-- * The output is compatible with XPath commands.
-- *
-- * Returns 0 or -1 in case of error
-- */
--int
--xmlShellPwd(xmlShellCtxtPtr ctxt, char *buffer, xmlNodePtr node,
-- xmlNodePtr node2) {
-- xmlNodePtr cur, tmp, next;
-- char buf[500];
-- char sep;
-- const char *name;
-- int occur = 0;
--
-- buffer[0] = 0;
-- if (node == NULL) return(-1);
-- cur = node;
-- do {
-- name = "";
-- sep= '?';
-- occur = 0;
-- if ((cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- sep = '/';
-- next = NULL;
-- } else if (cur->type == XML_ELEMENT_NODE) {
-- sep = '/';
-- name = (const char *)cur->name;
-- next = cur->parent;
--
-- /*
-- * Thumbler index computation
-- */
-- tmp = cur->prev;
-- while (tmp != NULL) {
-- if (xmlStrEqual(cur->name, tmp->name))
-- occur++;
-- tmp = tmp->prev;
-- }
-- if (occur == 0) {
-- tmp = cur->next;
-- while (tmp != NULL) {
-- if (xmlStrEqual(cur->name, tmp->name))
-- occur++;
-- tmp = tmp->next;
-- }
-- if (occur != 0) occur = 1;
-- } else
-- occur++;
-- } else if (cur->type == XML_ATTRIBUTE_NODE) {
-- sep = '@';
-- name = (const char *) (((xmlAttrPtr) cur)->name);
-- next = ((xmlAttrPtr) cur)->parent;
-- } else {
-- next = cur->parent;
-- }
-- if (occur == 0)
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
--#else
-- sprintf(buf, "%c%s%s", sep, name, buffer);
--#endif
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "%c%s[%d]%s",
-- sep, name, occur, buffer);
--#else
-- sprintf(buf, "%c%s[%d]%s", sep, name, occur, buffer);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- /*
-- * This test prevents buffer overflow, because this routine
-- * is only called by xmlShell, in which the second argument is
-- * 500 chars long.
-- * It is a dirty hack before a cleaner solution is found.
-- * Documentation should mention that the second argument must
-- * be at least 500 chars long, and could be stripped if too long.
-- */
-- if (strlen(buffer) + strlen(buf) > 499)
-- break;
-- strcpy(buffer, buf);
-- cur = next;
-- } while (cur != NULL);
-- return(0);
--}
--
--/**
-- * xmlShell
-- * @doc: the initial document
-- * @filename: the output buffer
-- * @input: the line reading function
-- * @output: the output FILE*
-- *
-- * Implements the XML shell
-- * This allow to load, validate, view, modify and save a document
-- * using a environment similar to a UNIX commandline.
-- */
--void
--xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
-- FILE *output) {
-- char prompt[500] = "/ > ";
-- char *cmdline = NULL, *cur;
-- int nbargs;
-- char command[100];
-- char arg[400];
-- int i;
-- xmlShellCtxtPtr ctxt;
-- xmlXPathObjectPtr list;
--
-- if (doc == NULL)
-- return;
-- if (filename == NULL)
-- return;
-- if (input == NULL)
-- return;
-- if (output == NULL)
-- return;
-- ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
-- if (ctxt == NULL)
-- return;
-- ctxt->loaded = 0;
-- ctxt->doc = doc;
-- ctxt->input = input;
-- ctxt->output = output;
-- ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
-- ctxt->node = (xmlNodePtr) ctxt->doc;
--
--#ifdef LIBXML_XPATH_ENABLED
-- ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
-- if (ctxt->pctxt == NULL) {
-- xmlFree(ctxt);
-- return;
-- }
--#endif /* LIBXML_XPATH_ENABLED */
-- while (1) {
-- if (ctxt->node == (xmlNodePtr) ctxt->doc)
-- sprintf(prompt, "%s > ", "/");
-- else if (ctxt->node->name)
--#ifdef HAVE_SNPRINTF
-- snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
--#else
-- sprintf(prompt, "%s > ", ctxt->node->name);
--#endif
-- else
-- sprintf(prompt, "? > ");
-- prompt[sizeof(prompt) - 1] = 0;
--
-- /*
-- * Get a new command line
-- */
-- cmdline = ctxt->input(prompt);
-- if (cmdline == NULL) break;
--
-- /*
-- * Parse the command itself
-- */
-- cur = cmdline;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- i = 0;
-- while ((*cur != ' ') && (*cur != '\t') &&
-- (*cur != '\n') && (*cur != '\r')) {
-- if (*cur == 0)
-- break;
-- command[i++] = *cur++;
-- }
-- command[i] = 0;
-- if (i == 0) continue;
-- nbargs++;
--
-- /*
-- * Parse the argument
-- */
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- i = 0;
-- while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
-- if (*cur == 0)
-- break;
-- arg[i++] = *cur++;
-- }
-- arg[i] = 0;
-- if (i != 0)
-- nbargs++;
--
-- /*
-- * start interpreting the command
-- */
-- if (!strcmp(command, "exit"))
-- break;
-- if (!strcmp(command, "quit"))
-- break;
-- if (!strcmp(command, "bye"))
-- break;
-- if (!strcmp(command, "validate")) {
-- xmlShellValidate(ctxt, arg, NULL, NULL);
-- } else if (!strcmp(command, "load")) {
-- xmlShellLoad(ctxt, arg, NULL, NULL);
-- } else if (!strcmp(command, "save")) {
-- xmlShellSave(ctxt, arg, NULL, NULL);
-- } else if (!strcmp(command, "write")) {
-- xmlShellWrite(ctxt, arg, NULL, NULL);
-- } else if (!strcmp(command, "free")) {
-- if (arg[0] == 0) {
-- xmlMemShow(stdout, 0);
-- } else {
-- int len = 0;
-- sscanf(arg, "%d", &len);
-- xmlMemShow(stdout, len);
-- }
-- } else if (!strcmp(command, "pwd")) {
-- char dir[500];
-- if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
-- printf("%s\n", dir);
-- } else if (!strcmp(command, "du")) {
-- xmlShellDu(ctxt, NULL, ctxt->node, NULL);
-- } else if ((!strcmp(command, "ls")) ||
-- (!strcmp(command, "dir"))) {
-- int dir = (!strcmp(command, "dir"));
-- if (arg[0] == 0) {
-- if (dir)
-- xmlShellDir(ctxt, NULL, ctxt->node, NULL);
-- else
-- xmlShellList(ctxt, NULL, ctxt->node, NULL);
-- } else {
-- ctxt->pctxt->node = ctxt->node;
--#ifdef LIBXML_XPATH_ENABLED
-- ctxt->pctxt->node = ctxt->node;
-- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
--#else
-- list = NULL;
--#endif /* LIBXML_XPATH_ENABLED */
-- if (list != NULL) {
-- switch (list->type) {
-- case XPATH_UNDEFINED:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: no such node\n", arg);
-- break;
-- case XPATH_NODESET: {
-- int i;
--
-- for (i = 0;i < list->nodesetval->nodeNr;i++) {
-- if (dir)
-- xmlShellDir(ctxt, NULL,
-- list->nodesetval->nodeTab[i], NULL);
-- else
-- xmlShellList(ctxt, NULL,
-- list->nodesetval->nodeTab[i], NULL);
-- }
-- break;
-- }
-- case XPATH_BOOLEAN:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a Boolean\n", arg);
-- break;
-- case XPATH_NUMBER:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a number\n", arg);
-- break;
-- case XPATH_STRING:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a string\n", arg);
-- break;
-- case XPATH_POINT:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a point\n", arg);
-- break;
-- case XPATH_RANGE:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a range\n", arg);
-- break;
-- case XPATH_LOCATIONSET:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a range\n", arg);
-- break;
-- case XPATH_USERS:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is user-defined\n", arg);
-- break;
-- case XPATH_XSLT_TREE:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is an XSLT value tree\n", arg);
-- break;
-- }
-- xmlXPathFreeNodeSetList(list);
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: no such node\n", arg);
-- }
-- ctxt->pctxt->node = NULL;
-- }
-- } else if (!strcmp(command, "cd")) {
-- if (arg[0] == 0) {
-- ctxt->node = (xmlNodePtr) ctxt->doc;
-- } else {
--#ifdef LIBXML_XPATH_ENABLED
-- ctxt->pctxt->node = ctxt->node;
-- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
--#else
-- list = NULL;
--#endif /* LIBXML_XPATH_ENABLED */
-- if (list != NULL) {
-- switch (list->type) {
-- case XPATH_UNDEFINED:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: no such node\n", arg);
-- break;
-- case XPATH_NODESET:
-- if (list->nodesetval->nodeNr == 1) {
-- ctxt->node = list->nodesetval->nodeTab[0];
-- } else
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a %d Node Set\n",
-- arg, list->nodesetval->nodeNr);
-- break;
-- case XPATH_BOOLEAN:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a Boolean\n", arg);
-- break;
-- case XPATH_NUMBER:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a number\n", arg);
-- break;
-- case XPATH_STRING:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a string\n", arg);
-- break;
-- case XPATH_POINT:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a point\n", arg);
-- break;
-- case XPATH_RANGE:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a range\n", arg);
-- break;
-- case XPATH_LOCATIONSET:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a range\n", arg);
-- break;
-- case XPATH_USERS:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is user-defined\n", arg);
-- break;
-- case XPATH_XSLT_TREE:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is an XSLT value tree\n", arg);
-- break;
-- }
-- xmlXPathFreeNodeSetList(list);
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: no such node\n", arg);
-- }
-- ctxt->pctxt->node = NULL;
-- }
-- } else if (!strcmp(command, "cat")) {
-- if (arg[0] == 0) {
-- xmlShellCat(ctxt, NULL, ctxt->node, NULL);
-- } else {
-- ctxt->pctxt->node = ctxt->node;
--#ifdef LIBXML_XPATH_ENABLED
-- ctxt->pctxt->node = ctxt->node;
-- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
--#else
-- list = NULL;
--#endif /* LIBXML_XPATH_ENABLED */
-- if (list != NULL) {
-- switch (list->type) {
-- case XPATH_UNDEFINED:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: no such node\n", arg);
-- break;
-- case XPATH_NODESET: {
-- int i;
--
-- for (i = 0;i < list->nodesetval->nodeNr;i++) {
-- if (i > 0) printf(" -------\n");
-- xmlShellCat(ctxt, NULL,
-- list->nodesetval->nodeTab[i], NULL);
-- }
-- break;
-- }
-- case XPATH_BOOLEAN:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a Boolean\n", arg);
-- break;
-- case XPATH_NUMBER:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a number\n", arg);
-- break;
-- case XPATH_STRING:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a string\n", arg);
-- break;
-- case XPATH_POINT:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a point\n", arg);
-- break;
-- case XPATH_RANGE:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a range\n", arg);
-- break;
-- case XPATH_LOCATIONSET:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is a range\n", arg);
-- break;
-- case XPATH_USERS:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is user-defined\n", arg);
-- break;
-- case XPATH_XSLT_TREE:
-- xmlGenericError(xmlGenericErrorContext,
-- "%s is an XSLT value tree\n", arg);
-- break;
-- }
-- xmlXPathFreeNodeSetList(list);
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: no such node\n", arg);
-- }
-- ctxt->pctxt->node = NULL;
-- }
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "Unknown command %s\n", command);
-- }
-- free(cmdline); /* not xmlFree here ! */
-- }
--#ifdef LIBXML_XPATH_ENABLED
-- xmlXPathFreeContext(ctxt->pctxt);
--#endif /* LIBXML_XPATH_ENABLED */
-- if (ctxt->loaded) {
-- xmlFreeDoc(ctxt->doc);
-- }
-- xmlFree(ctxt);
-- if (cmdline != NULL)
-- free(cmdline); /* not xmlFree here ! */
--}
--
--#endif /* LIBXML_DEBUG_ENABLED */
-diff -Nru libxml2-2.3.0/encoding.c libxml2-2.3.0.new/encoding.c
---- libxml2-2.3.0/encoding.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/encoding.c Thu Jan 1 01:00:00 1970
-@@ -1,2078 +0,0 @@
--/*
-- * encoding.c : implements the encoding conversion functions needed for XML
-- *
-- * Related specs:
-- * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
-- * rfc2781 UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau
-- * [ISO-10646] UTF-8 and UTF-16 in Annexes
-- * [ISO-8859-1] ISO Latin-1 characters codes.
-- * [UNICODE] The Unicode Consortium, "The Unicode Standard --
-- * Worldwide Character Encoding -- Version 1.0", Addison-
-- * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
-- * described in Unicode Technical Report #4.
-- * [US-ASCII] Coded Character Set--7-bit American Standard Code for
-- * Information Interchange, ANSI X3.4-1986.
-- *
-- * Original code for IsoLatin1 and UTF-16 by "Martin J. Duerst" <duerst@w3.org>
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_ICONV_ENABLED
--#ifdef HAVE_ERRNO_H
--#include <errno.h>
--#endif
--#endif
--#include <libxml/encoding.h>
--#include <libxml/xmlmemory.h>
--#ifdef LIBXML_HTML_ENABLED
--#include <libxml/HTMLparser.h>
--#endif
--#include <libxml/xmlerror.h>
--
--xmlCharEncodingHandlerPtr xmlUTF16LEHandler = NULL;
--xmlCharEncodingHandlerPtr xmlUTF16BEHandler = NULL;
--
--typedef struct _xmlCharEncodingAlias xmlCharEncodingAlias;
--typedef xmlCharEncodingAlias *xmlCharEncodingAliasPtr;
--struct _xmlCharEncodingAlias {
-- const char *name;
-- const char *alias;
--};
--
--static xmlCharEncodingAliasPtr xmlCharEncodingAliases = NULL;
--static int xmlCharEncodingAliasesNb = 0;
--static int xmlCharEncodingAliasesMax = 0;
--
--#ifdef LIBXML_ICONV_ENABLED
--#if 0
--#define DEBUG_ENCODING /* Define this to get encoding traces */
--#endif
--#endif
--
--static int xmlLittleEndian = 1;
--
--/*
-- * From rfc2044: encoding of the Unicode values on UTF-8:
-- *
-- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-- * 0000 0000-0000 007F 0xxxxxxx
-- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- *
-- * I hope we won't use values > 0xFFFF anytime soon !
-- */
--
--/**
-- * xmlGetUTF8Char:
-- * @utf: a sequence of UTF-8 encoded bytes
-- * @len: a pointer to @bytes len
-- *
-- * Read one UTF8 Char from @utf
-- *
-- * Returns the char value or -1 in case of error and update @len with the
-- * number of bytes used
-- */
--int
--xmlGetUTF8Char(const unsigned char *utf, int *len) {
-- unsigned int c;
--
-- if (utf == NULL)
-- goto error;
-- if (len == NULL)
-- goto error;
-- if (*len < 1)
-- goto error;
--
-- c = utf[0];
-- if (c & 0x80) {
-- if (*len < 2)
-- goto error;
-- if ((utf[1] & 0xc0) != 0x80)
-- goto error;
-- if ((c & 0xe0) == 0xe0) {
-- if (*len < 3)
-- goto error;
-- if ((utf[2] & 0xc0) != 0x80)
-- goto error;
-- if ((c & 0xf0) == 0xf0) {
-- if (*len < 4)
-- goto error;
-- if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
-- goto error;
-- *len = 4;
-- /* 4-byte code */
-- c = (utf[0] & 0x7) << 18;
-- c |= (utf[1] & 0x3f) << 12;
-- c |= (utf[2] & 0x3f) << 6;
-- c |= utf[3] & 0x3f;
-- } else {
-- /* 3-byte code */
-- *len = 3;
-- c = (utf[0] & 0xf) << 12;
-- c |= (utf[1] & 0x3f) << 6;
-- c |= utf[2] & 0x3f;
-- }
-- } else {
-- /* 2-byte code */
-- *len = 2;
-- c = (utf[0] & 0x1f) << 6;
-- c |= utf[1] & 0x3f;
-- }
-- } else {
-- /* 1-byte code */
-- *len = 1;
-- }
-- return(c);
--
--error:
-- *len = 0;
-- return(-1);
--}
--
--/**
-- * xmlCheckUTF8: Check utf-8 string for legality.
-- * @utf: Pointer to putative utf-8 encoded string.
-- *
-- * Checks @utf for being valid utf-8. @utf is assumed to be
-- * null-terminated. This function is not super-strict, as it will
-- * allow longer utf-8 sequences than necessary. Note that Java is
-- * capable of producing these sequences if provoked. Also note, this
-- * routine checks for the 4-byte maxiumum size, but does not check for
-- * 0x10ffff maximum value.
-- *
-- * Return value: true if @utf is valid.
-- **/
--int
--xmlCheckUTF8(const unsigned char *utf)
--{
-- int ix;
-- unsigned char c;
--
-- for (ix = 0; (c = utf[ix]);) {
-- if (c & 0x80) {
-- if ((utf[ix + 1] & 0xc0) != 0x80)
-- return(0);
-- if ((c & 0xe0) == 0xe0) {
-- if ((utf[ix + 2] & 0xc0) != 0x80)
-- return(0);
-- if ((c & 0xf0) == 0xf0) {
-- if ((c & 0xf8) != 0xf0 || (utf[ix + 3] & 0xc0) != 0x80)
-- return(0);
-- ix += 4;
-- /* 4-byte code */
-- } else
-- /* 3-byte code */
-- ix += 3;
-- } else
-- /* 2-byte code */
-- ix += 2;
-- } else
-- /* 1-byte code */
-- ix++;
-- }
-- return(1);
--}
--
--/**
-- * asciiToUTF8:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of ASCII chars
-- * @inlen: the length of @in
-- *
-- * Take a block of ASCII chars in and try to convert it to an UTF-8
-- * block of chars out.
-- * Returns 0 if success, or -1 otherwise
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--int
--asciiToUTF8(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen) {
-- unsigned char* outstart = out;
-- const unsigned char* base = in;
-- const unsigned char* processed = in;
-- unsigned char* outend = out + *outlen;
-- const unsigned char* inend;
-- unsigned int c;
-- int bits;
--
-- inend = in + (*inlen);
-- while ((in < inend) && (out - outstart + 5 < *outlen)) {
-- c= *in++;
--
-- /* assertion: c is a single UTF-4 value */
-- if (out >= outend)
-- break;
-- if (c < 0x80) { *out++= c; bits= -6; }
-- else {
-- *outlen = out - outstart;
-- *inlen = processed - base;
-- return(-1);
-- }
--
-- for ( ; bits >= 0; bits-= 6) {
-- if (out >= outend)
-- break;
-- *out++= ((c >> bits) & 0x3F) | 0x80;
-- }
-- processed = (const unsigned char*) in;
-- }
-- *outlen = out - outstart;
-- *inlen = processed - base;
-- return(0);
--}
--
--/**
-- * UTF8Toascii:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of UTF-8 chars
-- * @inlen: the length of @in
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an ASCII
-- * block of chars out.
-- *
-- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--int
--UTF8Toascii(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen) {
-- const unsigned char* processed = in;
-- const unsigned char* outend;
-- const unsigned char* outstart = out;
-- const unsigned char* instart = in;
-- const unsigned char* inend;
-- unsigned int c, d;
-- int trailing;
--
-- if (in == NULL) {
-- /*
-- * initialization nothing to do
-- */
-- *outlen = 0;
-- *inlen = 0;
-- return(0);
-- }
-- inend = in + (*inlen);
-- outend = out + (*outlen);
-- while (in < inend) {
-- d = *in++;
-- if (d < 0x80) { c= d; trailing= 0; }
-- else if (d < 0xC0) {
-- /* trailing byte in leading position */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-- else {
-- /* no chance for this in Ascii */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
--
-- if (inend - in < trailing) {
-- break;
-- }
--
-- for ( ; trailing; trailing--) {
-- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
-- break;
-- c <<= 6;
-- c |= d & 0x3F;
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (c < 0x80) {
-- if (out >= outend)
-- break;
-- *out++ = c;
-- } else {
-- /* no chance for this in Ascii */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
-- processed = in;
-- }
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(0);
--}
--
--/**
-- * isolat1ToUTF8:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of ISO Latin 1 chars
-- * @inlen: the length of @in
-- *
-- * Take a block of ISO Latin 1 chars in and try to convert it to an UTF-8
-- * block of chars out.
-- * Returns 0 if success, or -1 otherwise
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--int
--isolat1ToUTF8(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen) {
-- unsigned char* outstart = out;
-- const unsigned char* base = in;
-- const unsigned char* processed = in;
-- unsigned char* outend = out + *outlen;
-- const unsigned char* inend;
-- unsigned int c;
-- int bits;
--
-- inend = in + (*inlen);
-- while ((in < inend) && (out - outstart + 5 < *outlen)) {
-- c= *in++;
--
-- /* assertion: c is a single UTF-4 value */
-- if (out >= outend)
-- break;
-- if (c < 0x80) { *out++= c; bits= -6; }
-- else { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- if (out >= outend)
-- break;
-- *out++= ((c >> bits) & 0x3F) | 0x80;
-- }
-- processed = (const unsigned char*) in;
-- }
-- *outlen = out - outstart;
-- *inlen = processed - base;
-- return(0);
--}
--
--/**
-- * UTF8Toisolat1:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of UTF-8 chars
-- * @inlen: the length of @in
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an ISO Latin 1
-- * block of chars out.
-- *
-- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--int
--UTF8Toisolat1(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen) {
-- const unsigned char* processed = in;
-- const unsigned char* outend;
-- const unsigned char* outstart = out;
-- const unsigned char* instart = in;
-- const unsigned char* inend;
-- unsigned int c, d;
-- int trailing;
--
-- if (in == NULL) {
-- /*
-- * initialization nothing to do
-- */
-- *outlen = 0;
-- *inlen = 0;
-- return(0);
-- }
-- inend = in + (*inlen);
-- outend = out + (*outlen);
-- while (in < inend) {
-- d = *in++;
-- if (d < 0x80) { c= d; trailing= 0; }
-- else if (d < 0xC0) {
-- /* trailing byte in leading position */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-- else {
-- /* no chance for this in IsoLat1 */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
--
-- if (inend - in < trailing) {
-- break;
-- }
--
-- for ( ; trailing; trailing--) {
-- if (in >= inend)
-- break;
-- if (((d= *in++) & 0xC0) != 0x80) {
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
-- c <<= 6;
-- c |= d & 0x3F;
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (c <= 0xFF) {
-- if (out >= outend)
-- break;
-- *out++ = c;
-- } else {
-- /* no chance for this in IsoLat1 */
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(-2);
-- }
-- processed = in;
-- }
-- *outlen = out - outstart;
-- *inlen = processed - instart;
-- return(0);
--}
--
--/**
-- * UTF16LEToUTF8:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @inb: a pointer to an array of UTF-16LE passwd as a byte array
-- * @inlenb: the length of @in in UTF-16LE chars
-- *
-- * Take a block of UTF-16LE ushorts in and try to convert it to an UTF-8
-- * block of chars out. This function assume the endian properity
-- * is the same between the native type of this machine and the
-- * inputed one.
-- *
-- * Returns the number of byte written, or -1 by lack of space, or -2
-- * if the transcoding fails (for *in is not valid utf16 string)
-- * The value of *inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- */
--int
--UTF16LEToUTF8(unsigned char* out, int *outlen,
-- const unsigned char* inb, int *inlenb)
--{
-- unsigned char* outstart = out;
-- const unsigned char* processed = inb;
-- unsigned char* outend = out + *outlen;
-- unsigned short* in = (unsigned short*) inb;
-- unsigned short* inend;
-- unsigned int c, d, inlen;
-- unsigned char *tmp;
-- int bits;
--
-- if ((*inlenb % 2) == 1)
-- (*inlenb)--;
-- inlen = *inlenb / 2;
-- inend = in + inlen;
-- while ((in < inend) && (out - outstart + 5 < *outlen)) {
-- if (xmlLittleEndian) {
-- c= *in++;
-- } else {
-- tmp = (unsigned char *) in;
-- c = *tmp++;
-- c = c | (((unsigned int)*tmp) << 8);
-- in++;
-- }
-- if ((c & 0xFC00) == 0xD800) { /* surrogates */
-- if (in >= inend) { /* (in > inend) shouldn't happens */
-- break;
-- }
-- if (xmlLittleEndian) {
-- d = *in++;
-- } else {
-- tmp = (unsigned char *) in;
-- d = *tmp++;
-- d = d | (((unsigned int)*tmp) << 8);
-- in++;
-- }
-- if ((d & 0xFC00) == 0xDC00) {
-- c &= 0x03FF;
-- c <<= 10;
-- c |= d & 0x03FF;
-- c += 0x10000;
-- }
-- else {
-- *outlen = out - outstart;
-- *inlenb = processed - inb;
-- return(-2);
-- }
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (out >= outend)
-- break;
-- if (c < 0x80) { *out++= c; bits= -6; }
-- else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- if (out >= outend)
-- break;
-- *out++= ((c >> bits) & 0x3F) | 0x80;
-- }
-- processed = (const unsigned char*) in;
-- }
-- *outlen = out - outstart;
-- *inlenb = processed - inb;
-- return(0);
--}
--
--/**
-- * UTF8ToUTF16LE:
-- * @outb: a pointer to an array of bytes to store the result
-- * @outlen: the length of @outb
-- * @in: a pointer to an array of UTF-8 chars
-- * @inlen: the length of @in
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an UTF-16LE
-- * block of chars out.
-- *
-- * Returns the number of byte written, or -1 by lack of space, or -2
-- * if the transcoding failed.
-- */
--int
--UTF8ToUTF16LE(unsigned char* outb, int *outlen,
-- const unsigned char* in, int *inlen)
--{
-- unsigned short* out = (unsigned short*) outb;
-- const unsigned char* processed = in;
-- unsigned short* outstart= out;
-- unsigned short* outend;
-- const unsigned char* inend= in+*inlen;
-- unsigned int c, d;
-- int trailing;
-- unsigned char *tmp;
-- unsigned short tmp1, tmp2;
--
-- if (in == NULL) {
-- /*
-- * initialization, add the Byte Order Mark
-- */
-- if (*outlen >= 2) {
-- outb[0] = 0xFF;
-- outb[1] = 0xFE;
-- *outlen = 2;
-- *inlen = 0;
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "Added FFFE Byte Order Mark\n");
--#endif
-- return(2);
-- }
-- *outlen = 0;
-- *inlen = 0;
-- return(0);
-- }
-- outend = out + (*outlen / 2);
-- while (in < inend) {
-- d= *in++;
-- if (d < 0x80) { c= d; trailing= 0; }
-- else if (d < 0xC0) {
-- /* trailing byte in leading position */
-- *outlen = (out - outstart) * 2;
-- *inlen = processed - in;
-- return(-2);
-- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-- else {
-- /* no chance for this in UTF-16 */
-- *outlen = (out - outstart) * 2;
-- *inlen = processed - in;
-- return(-2);
-- }
--
-- if (inend - in < trailing) {
-- break;
-- }
--
-- for ( ; trailing; trailing--) {
-- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
-- break;
-- c <<= 6;
-- c |= d & 0x3F;
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (c < 0x10000) {
-- if (out >= outend)
-- break;
-- if (xmlLittleEndian) {
-- *out++ = c;
-- } else {
-- tmp = (unsigned char *) out;
-- *tmp = c ;
-- *(tmp + 1) = c >> 8 ;
-- out++;
-- }
-- }
-- else if (c < 0x110000) {
-- if (out+1 >= outend)
-- break;
-- c -= 0x10000;
-- if (xmlLittleEndian) {
-- *out++ = 0xD800 | (c >> 10);
-- *out++ = 0xDC00 | (c & 0x03FF);
-- } else {
-- tmp1 = 0xD800 | (c >> 10);
-- tmp = (unsigned char *) out;
-- *tmp = (unsigned char) tmp1;
-- *(tmp + 1) = tmp1 >> 8;
-- out++;
--
-- tmp2 = 0xDC00 | (c & 0x03FF);
-- tmp = (unsigned char *) out;
-- *tmp = (unsigned char) tmp2;
-- *(tmp + 1) = tmp2 >> 8;
-- out++;
-- }
-- }
-- else
-- break;
-- processed = in;
-- }
-- *outlen = (out - outstart) * 2;
-- *inlen = processed - in;
-- return(0);
--}
--
--/**
-- * UTF16BEToUTF8:
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @inb: a pointer to an array of UTF-16 passwd as a byte array
-- * @inlenb: the length of @in in UTF-16 chars
-- *
-- * Take a block of UTF-16 ushorts in and try to convert it to an UTF-8
-- * block of chars out. This function assume the endian properity
-- * is the same between the native type of this machine and the
-- * inputed one.
-- *
-- * Returns the number of byte written, or -1 by lack of space, or -2
-- * if the transcoding fails (for *in is not valid utf16 string)
-- * The value of *inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- */
--int
--UTF16BEToUTF8(unsigned char* out, int *outlen,
-- const unsigned char* inb, int *inlenb)
--{
-- unsigned char* outstart = out;
-- const unsigned char* processed = inb;
-- unsigned char* outend = out + *outlen;
-- unsigned short* in = (unsigned short*) inb;
-- unsigned short* inend;
-- unsigned int c, d, inlen;
-- unsigned char *tmp;
-- int bits;
--
-- if ((*inlenb % 2) == 1)
-- (*inlenb)--;
-- inlen = *inlenb / 2;
-- inend= in + inlen;
-- while (in < inend) {
-- if (xmlLittleEndian) {
-- tmp = (unsigned char *) in;
-- c = *tmp++;
-- c = c << 8;
-- c = c | (unsigned int) *tmp;
-- in++;
-- } else {
-- c= *in++;
-- }
-- if ((c & 0xFC00) == 0xD800) { /* surrogates */
-- if (in >= inend) { /* (in > inend) shouldn't happens */
-- *outlen = out - outstart;
-- *inlenb = processed - inb;
-- return(-2);
-- }
-- if (xmlLittleEndian) {
-- tmp = (unsigned char *) in;
-- d = *tmp++;
-- d = d << 8;
-- d = d | (unsigned int) *tmp;
-- in++;
-- } else {
-- d= *in++;
-- }
-- if ((d & 0xFC00) == 0xDC00) {
-- c &= 0x03FF;
-- c <<= 10;
-- c |= d & 0x03FF;
-- c += 0x10000;
-- }
-- else {
-- *outlen = out - outstart;
-- *inlenb = processed - inb;
-- return(-2);
-- }
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (out >= outend)
-- break;
-- if (c < 0x80) { *out++= c; bits= -6; }
-- else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-- else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-- else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6) {
-- if (out >= outend)
-- break;
-- *out++= ((c >> bits) & 0x3F) | 0x80;
-- }
-- processed = (const unsigned char*) in;
-- }
-- *outlen = out - outstart;
-- *inlenb = processed - inb;
-- return(0);
--}
--
--/**
-- * UTF8ToUTF16BE:
-- * @outb: a pointer to an array of bytes to store the result
-- * @outlen: the length of @outb
-- * @in: a pointer to an array of UTF-8 chars
-- * @inlen: the length of @in
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an UTF-16BE
-- * block of chars out.
-- *
-- * Returns the number of byte written, or -1 by lack of space, or -2
-- * if the transcoding failed.
-- */
--int
--UTF8ToUTF16BE(unsigned char* outb, int *outlen,
-- const unsigned char* in, int *inlen)
--{
-- unsigned short* out = (unsigned short*) outb;
-- const unsigned char* processed = in;
-- unsigned short* outstart= out;
-- unsigned short* outend;
-- const unsigned char* inend= in+*inlen;
-- unsigned int c, d;
-- int trailing;
-- unsigned char *tmp;
-- unsigned short tmp1, tmp2;
--
-- if (in == NULL) {
-- /*
-- * initialization, add the Byte Order Mark
-- */
-- if (*outlen >= 2) {
-- outb[0] = 0xFE;
-- outb[1] = 0xFF;
-- *outlen = 2;
-- *inlen = 0;
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "Added FEFF Byte Order Mark\n");
--#endif
-- return(2);
-- }
-- *outlen = 0;
-- *inlen = 0;
-- return(0);
-- }
-- outend = out + (*outlen / 2);
-- while (in < inend) {
-- d= *in++;
-- if (d < 0x80) { c= d; trailing= 0; }
-- else if (d < 0xC0) {
-- /* trailing byte in leading position */
-- *outlen = out - outstart;
-- *inlen = processed - in;
-- return(-2);
-- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-- else {
-- /* no chance for this in UTF-16 */
-- *outlen = out - outstart;
-- *inlen = processed - in;
-- return(-2);
-- }
--
-- if (inend - in < trailing) {
-- break;
-- }
--
-- for ( ; trailing; trailing--) {
-- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80)) break;
-- c <<= 6;
-- c |= d & 0x3F;
-- }
--
-- /* assertion: c is a single UTF-4 value */
-- if (c < 0x10000) {
-- if (out >= outend) break;
-- if (xmlLittleEndian) {
-- tmp = (unsigned char *) out;
-- *tmp = c >> 8;
-- *(tmp + 1) = c;
-- out++;
-- } else {
-- *out++ = c;
-- }
-- }
-- else if (c < 0x110000) {
-- if (out+1 >= outend) break;
-- c -= 0x10000;
-- if (xmlLittleEndian) {
-- tmp1 = 0xD800 | (c >> 10);
-- tmp = (unsigned char *) out;
-- *tmp = tmp1 >> 8;
-- *(tmp + 1) = (unsigned char) tmp1;
-- out++;
--
-- tmp2 = 0xDC00 | (c & 0x03FF);
-- tmp = (unsigned char *) out;
-- *tmp = tmp2 >> 8;
-- *(tmp + 1) = (unsigned char) tmp2;
-- out++;
-- } else {
-- *out++ = 0xD800 | (c >> 10);
-- *out++ = 0xDC00 | (c & 0x03FF);
-- }
-- }
-- else
-- break;
-- processed = in;
-- }
-- *outlen = (out - outstart) * 2;
-- *inlen = processed - in;
-- return(0);
--}
--
--/**
-- * xmlDetectCharEncoding:
-- * @in: a pointer to the first bytes of the XML entity, must be at least
-- * 4 bytes long.
-- * @len: pointer to the length of the buffer
-- *
-- * Guess the encoding of the entity using the first bytes of the entity content
-- * accordingly of the non-normative appendix F of the XML-1.0 recommendation.
-- *
-- * Returns one of the XML_CHAR_ENCODING_... values.
-- */
--xmlCharEncoding
--xmlDetectCharEncoding(const unsigned char* in, int len)
--{
-- if (len >= 4) {
-- if ((in[0] == 0x00) && (in[1] == 0x00) &&
-- (in[2] == 0x00) && (in[3] == 0x3C))
-- return(XML_CHAR_ENCODING_UCS4BE);
-- if ((in[0] == 0x3C) && (in[1] == 0x00) &&
-- (in[2] == 0x00) && (in[3] == 0x00))
-- return(XML_CHAR_ENCODING_UCS4LE);
-- if ((in[0] == 0x00) && (in[1] == 0x00) &&
-- (in[2] == 0x3C) && (in[3] == 0x00))
-- return(XML_CHAR_ENCODING_UCS4_2143);
-- if ((in[0] == 0x00) && (in[1] == 0x3C) &&
-- (in[2] == 0x00) && (in[3] == 0x00))
-- return(XML_CHAR_ENCODING_UCS4_3412);
-- if ((in[0] == 0x4C) && (in[1] == 0x6F) &&
-- (in[2] == 0xA7) && (in[3] == 0x94))
-- return(XML_CHAR_ENCODING_EBCDIC);
-- if ((in[0] == 0x3C) && (in[1] == 0x3F) &&
-- (in[2] == 0x78) && (in[3] == 0x6D))
-- return(XML_CHAR_ENCODING_UTF8);
-- }
-- if (len >= 2) {
-- if ((in[0] == 0xFE) && (in[1] == 0xFF))
-- return(XML_CHAR_ENCODING_UTF16BE);
-- if ((in[0] == 0xFF) && (in[1] == 0xFE))
-- return(XML_CHAR_ENCODING_UTF16LE);
-- }
-- return(XML_CHAR_ENCODING_NONE);
--}
--
--/**
-- * xmlCleanupEncodingAliases:
-- *
-- * Unregisters all aliases
-- */
--void
--xmlCleanupEncodingAliases(void) {
-- int i;
--
-- if (xmlCharEncodingAliases == NULL)
-- return;
--
-- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-- if (xmlCharEncodingAliases[i].name != NULL)
-- xmlFree((char *) xmlCharEncodingAliases[i].name);
-- if (xmlCharEncodingAliases[i].alias != NULL)
-- xmlFree((char *) xmlCharEncodingAliases[i].alias);
-- }
-- xmlCharEncodingAliasesNb = 0;
-- xmlCharEncodingAliasesMax = 0;
-- xmlFree(xmlCharEncodingAliases);
--}
--
--/**
-- * xmlGetEncodingAlias:
-- * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
-- *
-- * Lookup an encoding name for the given alias.
-- *
-- * Returns NULL if not found the original name otherwise
-- */
--const char *
--xmlGetEncodingAlias(const char *alias) {
-- int i;
-- char upper[100];
--
-- if (alias == NULL)
-- return(NULL);
--
-- if (xmlCharEncodingAliases == NULL)
-- return(NULL);
--
-- for (i = 0;i < 99;i++) {
-- upper[i] = toupper(alias[i]);
-- if (upper[i] == 0) break;
-- }
-- upper[i] = 0;
--
-- /*
-- * Walk down the list looking for a definition of the alias
-- */
-- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-- if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
-- return(xmlCharEncodingAliases[i].name);
-- }
-- }
-- return(NULL);
--}
--
--/**
-- * xmlAddEncodingAlias:
-- * @name: the encoding name as parsed, in UTF-8 format (ASCII actually)
-- * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
-- *
-- * Registers and alias @alias for an encoding named @name. Existing alias
-- * will be overwritten.
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlAddEncodingAlias(const char *name, const char *alias) {
-- int i;
-- char upper[100];
--
-- if ((name == NULL) || (alias == NULL))
-- return(-1);
--
-- for (i = 0;i < 99;i++) {
-- upper[i] = toupper(alias[i]);
-- if (upper[i] == 0) break;
-- }
-- upper[i] = 0;
--
-- if (xmlCharEncodingAliases == NULL) {
-- xmlCharEncodingAliasesNb = 0;
-- xmlCharEncodingAliasesMax = 20;
-- xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
-- xmlMalloc(xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
-- if (xmlCharEncodingAliases == NULL)
-- return(-1);
-- } else if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
-- xmlCharEncodingAliasesMax *= 2;
-- xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
-- xmlRealloc(xmlCharEncodingAliases,
-- xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
-- }
-- /*
-- * Walk down the list looking for a definition of the alias
-- */
-- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-- if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
-- /*
-- * Replace the definition.
-- */
-- xmlFree((char *) xmlCharEncodingAliases[i].name);
-- xmlCharEncodingAliases[i].name = xmlMemStrdup(name);
-- return(0);
-- }
-- }
-- /*
-- * Add the definition
-- */
-- xmlCharEncodingAliases[xmlCharEncodingAliasesNb].name = xmlMemStrdup(name);
-- xmlCharEncodingAliases[xmlCharEncodingAliasesNb].alias = xmlMemStrdup(upper);
-- xmlCharEncodingAliasesNb++;
-- return(0);
--}
--
--/**
-- * xmlDelEncodingAlias:
-- * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
-- *
-- * Unregisters an encoding alias @alias
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlDelEncodingAlias(const char *alias) {
-- int i;
--
-- if (alias == NULL)
-- return(-1);
--
-- if (xmlCharEncodingAliases == NULL)
-- return(-1);
-- /*
-- * Walk down the list looking for a definition of the alias
-- */
-- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-- if (!strcmp(xmlCharEncodingAliases[i].alias, alias)) {
-- xmlFree((char *) xmlCharEncodingAliases[i].name);
-- xmlFree((char *) xmlCharEncodingAliases[i].alias);
-- xmlCharEncodingAliasesNb--;
-- memmove(&xmlCharEncodingAliases[i], &xmlCharEncodingAliases[i + 1],
-- sizeof(xmlCharEncodingAlias) * (xmlCharEncodingAliasesNb - i));
-- return(0);
-- }
-- }
-- return(-1);
--}
--
--/**
-- * xmlParseCharEncoding:
-- * @name: the encoding name as parsed, in UTF-8 format (ASCII actually)
-- *
-- * Conpare the string to the known encoding schemes already known. Note
-- * that the comparison is case insensitive accordingly to the section
-- * [XML] 4.3.3 Character Encoding in Entities.
-- *
-- * Returns one of the XML_CHAR_ENCODING_... values or XML_CHAR_ENCODING_NONE
-- * if not recognized.
-- */
--xmlCharEncoding
--xmlParseCharEncoding(const char* name)
--{
-- const char *alias;
-- char upper[500];
-- int i;
--
-- if (name == NULL)
-- return(XML_CHAR_ENCODING_NONE);
--
-- /*
-- * Do the alias resolution
-- */
-- alias = xmlGetEncodingAlias(name);
-- if (alias != NULL)
-- name = alias;
--
-- for (i = 0;i < 499;i++) {
-- upper[i] = toupper(name[i]);
-- if (upper[i] == 0) break;
-- }
-- upper[i] = 0;
--
-- if (!strcmp(upper, "")) return(XML_CHAR_ENCODING_NONE);
-- if (!strcmp(upper, "UTF-8")) return(XML_CHAR_ENCODING_UTF8);
-- if (!strcmp(upper, "UTF8")) return(XML_CHAR_ENCODING_UTF8);
--
-- /*
-- * NOTE: if we were able to parse this, the endianness of UTF16 is
-- * already found and in use
-- */
-- if (!strcmp(upper, "UTF-16")) return(XML_CHAR_ENCODING_UTF16LE);
-- if (!strcmp(upper, "UTF16")) return(XML_CHAR_ENCODING_UTF16LE);
--
-- if (!strcmp(upper, "ISO-10646-UCS-2")) return(XML_CHAR_ENCODING_UCS2);
-- if (!strcmp(upper, "UCS-2")) return(XML_CHAR_ENCODING_UCS2);
-- if (!strcmp(upper, "UCS2")) return(XML_CHAR_ENCODING_UCS2);
--
-- /*
-- * NOTE: if we were able to parse this, the endianness of UCS4 is
-- * already found and in use
-- */
-- if (!strcmp(upper, "ISO-10646-UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
-- if (!strcmp(upper, "UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
-- if (!strcmp(upper, "UCS4")) return(XML_CHAR_ENCODING_UCS4LE);
--
--
-- if (!strcmp(upper, "ISO-8859-1")) return(XML_CHAR_ENCODING_8859_1);
-- if (!strcmp(upper, "ISO-LATIN-1")) return(XML_CHAR_ENCODING_8859_1);
-- if (!strcmp(upper, "ISO LATIN 1")) return(XML_CHAR_ENCODING_8859_1);
--
-- if (!strcmp(upper, "ISO-8859-2")) return(XML_CHAR_ENCODING_8859_2);
-- if (!strcmp(upper, "ISO-LATIN-2")) return(XML_CHAR_ENCODING_8859_2);
-- if (!strcmp(upper, "ISO LATIN 2")) return(XML_CHAR_ENCODING_8859_2);
--
-- if (!strcmp(upper, "ISO-8859-3")) return(XML_CHAR_ENCODING_8859_3);
-- if (!strcmp(upper, "ISO-8859-4")) return(XML_CHAR_ENCODING_8859_4);
-- if (!strcmp(upper, "ISO-8859-5")) return(XML_CHAR_ENCODING_8859_5);
-- if (!strcmp(upper, "ISO-8859-6")) return(XML_CHAR_ENCODING_8859_6);
-- if (!strcmp(upper, "ISO-8859-7")) return(XML_CHAR_ENCODING_8859_7);
-- if (!strcmp(upper, "ISO-8859-8")) return(XML_CHAR_ENCODING_8859_8);
-- if (!strcmp(upper, "ISO-8859-9")) return(XML_CHAR_ENCODING_8859_9);
--
-- if (!strcmp(upper, "ISO-2022-JP")) return(XML_CHAR_ENCODING_2022_JP);
-- if (!strcmp(upper, "SHIFT_JIS")) return(XML_CHAR_ENCODING_SHIFT_JIS);
-- if (!strcmp(upper, "EUC-JP")) return(XML_CHAR_ENCODING_EUC_JP);
--
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext, "Unknown encoding %s\n", name);
--#endif
-- return(XML_CHAR_ENCODING_ERROR);
--}
--
--/**
-- * xmlGetCharEncodingName:
-- * @enc: the encoding
-- *
-- * The "canonical" name for XML encoding.
-- * C.f. http://www.w3.org/TR/REC-xml#charencoding
-- * Section 4.3.3 Character Encoding in Entities
-- *
-- * Returns the canonical name for the given encoding
-- */
--
--const char*
--xmlGetCharEncodingName(xmlCharEncoding enc) {
-- switch (enc) {
-- case XML_CHAR_ENCODING_ERROR:
-- return(NULL);
-- case XML_CHAR_ENCODING_NONE:
-- return(NULL);
-- case XML_CHAR_ENCODING_UTF8:
-- return("UTF-8");
-- case XML_CHAR_ENCODING_UTF16LE:
-- return("UTF-16");
-- case XML_CHAR_ENCODING_UTF16BE:
-- return("UTF-16");
-- case XML_CHAR_ENCODING_EBCDIC:
-- return("EBCDIC");
-- case XML_CHAR_ENCODING_UCS4LE:
-- return("ISO-10646-UCS-4");
-- case XML_CHAR_ENCODING_UCS4BE:
-- return("ISO-10646-UCS-4");
-- case XML_CHAR_ENCODING_UCS4_2143:
-- return("ISO-10646-UCS-4");
-- case XML_CHAR_ENCODING_UCS4_3412:
-- return("ISO-10646-UCS-4");
-- case XML_CHAR_ENCODING_UCS2:
-- return("ISO-10646-UCS-2");
-- case XML_CHAR_ENCODING_8859_1:
-- return("ISO-8859-1");
-- case XML_CHAR_ENCODING_8859_2:
-- return("ISO-8859-2");
-- case XML_CHAR_ENCODING_8859_3:
-- return("ISO-8859-3");
-- case XML_CHAR_ENCODING_8859_4:
-- return("ISO-8859-4");
-- case XML_CHAR_ENCODING_8859_5:
-- return("ISO-8859-5");
-- case XML_CHAR_ENCODING_8859_6:
-- return("ISO-8859-6");
-- case XML_CHAR_ENCODING_8859_7:
-- return("ISO-8859-7");
-- case XML_CHAR_ENCODING_8859_8:
-- return("ISO-8859-8");
-- case XML_CHAR_ENCODING_8859_9:
-- return("ISO-8859-9");
-- case XML_CHAR_ENCODING_2022_JP:
-- return("ISO-2022-JP");
-- case XML_CHAR_ENCODING_SHIFT_JIS:
-- return("Shift-JIS");
-- case XML_CHAR_ENCODING_EUC_JP:
-- return("EUC-JP");
-- case XML_CHAR_ENCODING_ASCII:
-- return(NULL);
-- }
-- return(NULL);
--}
--
--/****************************************************************
-- * *
-- * Char encoding handlers *
-- * *
-- ****************************************************************/
--
--/* the size should be growable, but it's not a big deal ... */
--#define MAX_ENCODING_HANDLERS 50
--static xmlCharEncodingHandlerPtr *handlers = NULL;
--static int nbCharEncodingHandler = 0;
--
--/*
-- * The default is UTF-8 for XML, that's also the default used for the
-- * parser internals, so the default encoding handler is NULL
-- */
--
--static xmlCharEncodingHandlerPtr xmlDefaultCharEncodingHandler = NULL;
--
--/**
-- * xmlNewCharEncodingHandler:
-- * @name: the encoding name, in UTF-8 format (ASCII actually)
-- * @input: the xmlCharEncodingInputFunc to read that encoding
-- * @output: the xmlCharEncodingOutputFunc to write that encoding
-- *
-- * Create and registers an xmlCharEncodingHandler.
-- * Returns the xmlCharEncodingHandlerPtr created (or NULL in case of error).
-- */
--xmlCharEncodingHandlerPtr
--xmlNewCharEncodingHandler(const char *name,
-- xmlCharEncodingInputFunc input,
-- xmlCharEncodingOutputFunc output) {
-- xmlCharEncodingHandlerPtr handler;
-- const char *alias;
-- char upper[500];
-- int i;
-- char *up = 0;
--
-- /*
-- * Do the alias resolution
-- */
-- alias = xmlGetEncodingAlias(name);
-- if (alias != NULL)
-- name = alias;
--
-- /*
-- * Keep only the uppercase version of the encoding.
-- */
-- if (name == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewCharEncodingHandler : no name !\n");
-- return(NULL);
-- }
-- for (i = 0;i < 499;i++) {
-- upper[i] = toupper(name[i]);
-- if (upper[i] == 0) break;
-- }
-- upper[i] = 0;
-- up = xmlMemStrdup(upper);
-- if (up == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewCharEncodingHandler : out of memory !\n");
-- return(NULL);
-- }
--
-- /*
-- * allocate and fill-up an handler block.
-- */
-- handler = (xmlCharEncodingHandlerPtr)
-- xmlMalloc(sizeof(xmlCharEncodingHandler));
-- if (handler == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewCharEncodingHandler : out of memory !\n");
-- return(NULL);
-- }
-- handler->input = input;
-- handler->output = output;
-- handler->name = up;
--
--#ifdef LIBXML_ICONV_ENABLED
-- handler->iconv_in = NULL;
-- handler->iconv_out = NULL;
--#endif /* LIBXML_ICONV_ENABLED */
--
-- /*
-- * registers and returns the handler.
-- */
-- xmlRegisterCharEncodingHandler(handler);
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "Registered encoding handler for %s\n", name);
--#endif
-- return(handler);
--}
--
--/**
-- * xmlInitCharEncodingHandlers:
-- *
-- * Initialize the char encoding support, it registers the default
-- * encoding supported.
-- * NOTE: while public, this function usually doesn't need to be called
-- * in normal processing.
-- */
--void
--xmlInitCharEncodingHandlers(void) {
-- unsigned short int tst = 0x1234;
-- unsigned char *ptr = (unsigned char *) &tst;
--
-- if (handlers != NULL) return;
--
-- handlers = (xmlCharEncodingHandlerPtr *)
-- xmlMalloc(MAX_ENCODING_HANDLERS * sizeof(xmlCharEncodingHandlerPtr));
--
-- if (*ptr == 0x12) xmlLittleEndian = 0;
-- else if (*ptr == 0x34) xmlLittleEndian = 1;
-- else xmlGenericError(xmlGenericErrorContext,
-- "Odd problem at endianness detection\n");
--
-- if (handlers == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitCharEncodingHandlers : out of memory !\n");
-- return;
-- }
-- xmlNewCharEncodingHandler("UTF-8", NULL, NULL);
-- xmlUTF16LEHandler =
-- xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, UTF8ToUTF16LE);
-- xmlUTF16BEHandler =
-- xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, UTF8ToUTF16BE);
-- xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, UTF8Toisolat1);
-- xmlNewCharEncodingHandler("ASCII", asciiToUTF8, UTF8Toascii);
--#ifdef LIBXML_HTML_ENABLED
-- xmlNewCharEncodingHandler("HTML", NULL, UTF8ToHtml);
--#endif
--}
--
--/**
-- * xmlCleanupCharEncodingHandlers:
-- *
-- * Cleanup the memory allocated for the char encoding support, it
-- * unregisters all the encoding handlers and the aliases.
-- */
--void
--xmlCleanupCharEncodingHandlers(void) {
-- xmlCleanupEncodingAliases();
--
-- if (handlers == NULL) return;
--
-- for (;nbCharEncodingHandler > 0;) {
-- nbCharEncodingHandler--;
-- if (handlers[nbCharEncodingHandler] != NULL) {
-- if (handlers[nbCharEncodingHandler]->name != NULL)
-- xmlFree(handlers[nbCharEncodingHandler]->name);
-- xmlFree(handlers[nbCharEncodingHandler]);
-- }
-- }
-- xmlFree(handlers);
-- handlers = NULL;
-- nbCharEncodingHandler = 0;
-- xmlDefaultCharEncodingHandler = NULL;
--}
--
--/**
-- * xmlRegisterCharEncodingHandler:
-- * @handler: the xmlCharEncodingHandlerPtr handler block
-- *
-- * Register the char encoding handler, surprizing, isn't it ?
-- */
--void
--xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
-- if (handlers == NULL) xmlInitCharEncodingHandlers();
-- if (handler == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlRegisterCharEncodingHandler: NULL handler !\n");
-- return;
-- }
--
-- if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlRegisterCharEncodingHandler: Too many handler registered\n");
-- xmlGenericError(xmlGenericErrorContext,
-- "\tincrease MAX_ENCODING_HANDLERS : %s\n", __FILE__);
-- return;
-- }
-- handlers[nbCharEncodingHandler++] = handler;
--}
--
--/**
-- * xmlGetCharEncodingHandler:
-- * @enc: an xmlCharEncoding value.
-- *
-- * Search in the registrered set the handler able to read/write that encoding.
-- *
-- * Returns the handler or NULL if not found
-- */
--xmlCharEncodingHandlerPtr
--xmlGetCharEncodingHandler(xmlCharEncoding enc) {
-- xmlCharEncodingHandlerPtr handler;
--
-- if (handlers == NULL) xmlInitCharEncodingHandlers();
-- switch (enc) {
-- case XML_CHAR_ENCODING_ERROR:
-- return(NULL);
-- case XML_CHAR_ENCODING_NONE:
-- return(NULL);
-- case XML_CHAR_ENCODING_UTF8:
-- return(NULL);
-- case XML_CHAR_ENCODING_UTF16LE:
-- return(xmlUTF16LEHandler);
-- case XML_CHAR_ENCODING_UTF16BE:
-- return(xmlUTF16BEHandler);
-- case XML_CHAR_ENCODING_EBCDIC:
-- handler = xmlFindCharEncodingHandler("EBCDIC");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("ebcdic");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_UCS4BE:
-- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("UCS-4");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("UCS4");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_UCS4LE:
-- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("UCS-4");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("UCS4");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_UCS4_2143:
-- break;
-- case XML_CHAR_ENCODING_UCS4_3412:
-- break;
-- case XML_CHAR_ENCODING_UCS2:
-- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-2");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("UCS-2");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("UCS2");
-- if (handler != NULL) return(handler);
-- break;
--
-- /*
-- * We used to keep ISO Latin encodings native in the
-- * generated data. This led to so many problems that
-- * this has been removed. One can still change this
-- * back by registering no-ops encoders for those
-- */
-- case XML_CHAR_ENCODING_8859_1:
-- handler = xmlFindCharEncodingHandler("ISO-8859-1");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_2:
-- handler = xmlFindCharEncodingHandler("ISO-8859-2");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_3:
-- handler = xmlFindCharEncodingHandler("ISO-8859-3");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_4:
-- handler = xmlFindCharEncodingHandler("ISO-8859-4");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_5:
-- handler = xmlFindCharEncodingHandler("ISO-8859-5");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_6:
-- handler = xmlFindCharEncodingHandler("ISO-8859-6");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_7:
-- handler = xmlFindCharEncodingHandler("ISO-8859-7");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_8:
-- handler = xmlFindCharEncodingHandler("ISO-8859-8");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_8859_9:
-- handler = xmlFindCharEncodingHandler("ISO-8859-9");
-- if (handler != NULL) return(handler);
-- break;
--
--
-- case XML_CHAR_ENCODING_2022_JP:
-- handler = xmlFindCharEncodingHandler("ISO-2022-JP");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_SHIFT_JIS:
-- handler = xmlFindCharEncodingHandler("SHIFT-JIS");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("SHIFT_JIS");
-- if (handler != NULL) return(handler);
-- handler = xmlFindCharEncodingHandler("Shift_JIS");
-- if (handler != NULL) return(handler);
-- break;
-- case XML_CHAR_ENCODING_EUC_JP:
-- handler = xmlFindCharEncodingHandler("EUC-JP");
-- if (handler != NULL) return(handler);
-- break;
-- default:
-- break;
-- }
--
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "No handler found for encoding %d\n", enc);
--#endif
-- return(NULL);
--}
--
--/**
-- * xmlGetCharEncodingHandler:
-- * @enc: a string describing the char encoding.
-- *
-- * Search in the registrered set the handler able to read/write that encoding.
-- *
-- * Returns the handler or NULL if not found
-- */
--xmlCharEncodingHandlerPtr
--xmlFindCharEncodingHandler(const char *name) {
-- const char *nalias;
-- const char *norig;
-- xmlCharEncoding alias;
--#ifdef LIBXML_ICONV_ENABLED
-- xmlCharEncodingHandlerPtr enc;
-- iconv_t icv_in, icv_out;
--#endif /* LIBXML_ICONV_ENABLED */
-- char upper[100];
-- int i;
--
-- if (handlers == NULL) xmlInitCharEncodingHandlers();
-- if (name == NULL) return(xmlDefaultCharEncodingHandler);
-- if (name[0] == 0) return(xmlDefaultCharEncodingHandler);
--
-- /*
-- * Do the alias resolution
-- */
-- norig = name;
-- nalias = xmlGetEncodingAlias(name);
-- if (nalias != NULL)
-- name = nalias;
--
-- /*
-- * Check first for directly registered encoding names
-- */
-- for (i = 0;i < 99;i++) {
-- upper[i] = toupper(name[i]);
-- if (upper[i] == 0) break;
-- }
-- upper[i] = 0;
--
-- for (i = 0;i < nbCharEncodingHandler; i++)
-- if (!strcmp(upper, handlers[i]->name)) {
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "Found registered handler for encoding %s\n", name);
--#endif
-- return(handlers[i]);
-- }
--
--#ifdef LIBXML_ICONV_ENABLED
-- /* check whether iconv can handle this */
-- icv_in = iconv_open("UTF-8", name);
-- icv_out = iconv_open(name, "UTF-8");
-- if ((icv_in != (iconv_t) -1) && (icv_out != (iconv_t) -1)) {
-- enc = (xmlCharEncodingHandlerPtr)
-- xmlMalloc(sizeof(xmlCharEncodingHandler));
-- if (enc == NULL) {
-- iconv_close(icv_in);
-- iconv_close(icv_out);
-- return(NULL);
-- }
-- enc->name = xmlMemStrdup(name);
-- enc->input = NULL;
-- enc->output = NULL;
-- enc->iconv_in = icv_in;
-- enc->iconv_out = icv_out;
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "Found iconv handler for encoding %s\n", name);
--#endif
-- return enc;
-- } else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
-- xmlGenericError(xmlGenericErrorContext,
-- "iconv : problems with filters for '%s'\n", name);
-- }
--#endif /* LIBXML_ICONV_ENABLED */
--
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "No handler found for encoding %s\n", name);
--#endif
--
-- /*
-- * Fallback using the canonical names
-- */
-- alias = xmlParseCharEncoding(norig);
-- if (alias != XML_CHAR_ENCODING_ERROR) {
-- const char* canon;
-- canon = xmlGetCharEncodingName(alias);
-- if ((canon != NULL) && (strcmp(name, canon))) {
-- return(xmlFindCharEncodingHandler(canon));
-- }
-- }
--
-- return(NULL);
--}
--
--#ifdef LIBXML_ICONV_ENABLED
--/**
-- * xmlIconvWrapper:
-- * @cd: iconv converter data structure
-- * @out: a pointer to an array of bytes to store the result
-- * @outlen: the length of @out
-- * @in: a pointer to an array of ISO Latin 1 chars
-- * @inlen: the length of @in
-- *
-- * Returns 0 if success, or
-- * -1 by lack of space, or
-- * -2 if the transcoding fails (for *in is not valid utf8 string or
-- * the result of transformation can't fit into the encoding we want), or
-- * -3 if there the last byte can't form a single output char.
-- *
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--static int
--xmlIconvWrapper(iconv_t cd,
-- unsigned char *out, int *outlen,
-- const unsigned char *in, int *inlen) {
--
-- size_t icv_inlen = *inlen, icv_outlen = *outlen;
-- const char *icv_in = (const char *) in;
-- char *icv_out = (char *) out;
-- int ret;
--
-- ret = iconv(cd,
-- &icv_in, &icv_inlen,
-- &icv_out, &icv_outlen);
-- if (in != NULL) {
-- *inlen -= icv_inlen;
-- *outlen -= icv_outlen;
-- } else {
-- *inlen = 0;
-- *outlen = 0;
-- }
-- if (icv_inlen != 0 || ret == (size_t) -1) {
--#ifdef EILSEQ
-- if (errno == EILSEQ) {
-- return -2;
-- } else
--#endif
--#ifdef E2BIG
-- if (errno == E2BIG) {
-- return -1;
-- } else
--#endif
--#ifdef EINVAL
-- if (errno == EINVAL) {
-- return -3;
-- } else
--#endif
-- {
-- return -3;
-- }
-- }
-- return 0;
--}
--#endif /* LIBXML_ICONV_ENABLED */
--
--/**
-- * xmlCharEncFirstLine:
-- * @handler: char enconding transformation data structure
-- * @out: an xmlBuffer for the output.
-- * @in: an xmlBuffer for the input
-- *
-- * Front-end for the encoding handler input function, but handle only
-- * the very first line, i.e. limit itself to 45 chars.
-- *
-- * Returns the number of byte written if success, or
-- * -1 general error
-- * -2 if the transcoding fails (for *in is not valid utf8 string or
-- * the result of transformation can't fit into the encoding we want), or
-- */
--int
--xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
-- xmlBufferPtr in) {
-- int ret = -2;
-- int written;
-- int toconv;
--
-- if (handler == NULL) return(-1);
-- if (out == NULL) return(-1);
-- if (in == NULL) return(-1);
--
-- written = out->size - out->use;
-- toconv = in->use;
-- if (toconv * 2 >= written) {
-- xmlBufferGrow(out, toconv);
-- written = out->size - out->use - 1;
-- }
--
-- /*
-- * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
-- * 45 chars should be sufficient to reach the end of the encoding
-- * decalration without going too far inside the document content.
-- */
-- written = 45;
--
-- if (handler->input != NULL) {
-- ret = handler->input(&out->content[out->use], &written,
-- in->content, &toconv);
-- xmlBufferShrink(in, toconv);
-- out->use += written;
-- out->content[out->use] = 0;
-- }
--#ifdef LIBXML_ICONV_ENABLED
-- else if (handler->iconv_in != NULL) {
-- ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
-- &written, in->content, &toconv);
-- xmlBufferShrink(in, toconv);
-- out->use += written;
-- out->content[out->use] = 0;
-- if (ret == -1) ret = -3;
-- }
--#endif /* LIBXML_ICONV_ENABLED */
--#ifdef DEBUG_ENCODING
-- switch (ret) {
-- case 0:
-- xmlGenericError(xmlGenericErrorContext,
-- "converted %d bytes to %d bytes of input\n",
-- toconv, written);
-- break;
-- case -1:
-- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-- toconv, written, in->use);
-- break;
-- case -2:
-- xmlGenericError(xmlGenericErrorContext,
-- "input conversion failed due to input error\n");
-- break;
-- case -3:
-- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-- toconv, written, in->use);
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,"Unknown input conversion failed %d\n", ret);
-- }
--#endif
-- /*
-- * Ignore when input buffer is not on a boundary
-- */
-- if (ret == -3) ret = 0;
-- if (ret == -1) ret = 0;
-- return(ret);
--}
--
--/**
-- * xmlCharEncInFunc:
-- * @handler: char enconding transformation data structure
-- * @out: an xmlBuffer for the output.
-- * @in: an xmlBuffer for the input
-- *
-- * Generic front-end for the encoding handler input function
-- *
-- * Returns the number of byte written if success, or
-- * -1 general error
-- * -2 if the transcoding fails (for *in is not valid utf8 string or
-- * the result of transformation can't fit into the encoding we want), or
-- */
--int
--xmlCharEncInFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
-- xmlBufferPtr in) {
-- int ret = -2;
-- int written;
-- int toconv;
--
-- if (handler == NULL) return(-1);
-- if (out == NULL) return(-1);
-- if (in == NULL) return(-1);
--
-- toconv = in->use;
-- if (toconv == 0)
-- return(0);
-- written = out->size - out->use;
-- if (toconv * 2 >= written) {
-- xmlBufferGrow(out, out->size + toconv * 2);
-- written = out->size - out->use - 1;
-- }
-- if (handler->input != NULL) {
-- ret = handler->input(&out->content[out->use], &written,
-- in->content, &toconv);
-- xmlBufferShrink(in, toconv);
-- out->use += written;
-- out->content[out->use] = 0;
-- }
--#ifdef LIBXML_ICONV_ENABLED
-- else if (handler->iconv_in != NULL) {
-- ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
-- &written, in->content, &toconv);
-- xmlBufferShrink(in, toconv);
-- out->use += written;
-- out->content[out->use] = 0;
-- if (ret == -1) ret = -3;
-- }
--#endif /* LIBXML_ICONV_ENABLED */
-- switch (ret) {
--#ifdef DEBUG_ENCODING
-- case 0:
-- xmlGenericError(xmlGenericErrorContext,
-- "converted %d bytes to %d bytes of input\n",
-- toconv, written);
-- break;
-- case -1:
-- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-- toconv, written, in->use);
-- break;
-- case -3:
-- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-- toconv, written, in->use);
-- break;
--#endif
-- case -2:
-- xmlGenericError(xmlGenericErrorContext,
-- "input conversion failed due to input error\n");
-- xmlGenericError(xmlGenericErrorContext,
-- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- in->content[0], in->content[1],
-- in->content[2], in->content[3]);
-- }
-- /*
-- * Ignore when input buffer is not on a boundary
-- */
-- if (ret == -3) ret = 0;
-- return(ret);
--}
--
--/**
-- * xmlCharEncOutFunc:
-- * @handler: char enconding transformation data structure
-- * @out: an xmlBuffer for the output.
-- * @in: an xmlBuffer for the input
-- *
-- * Generic front-end for the encoding handler output function
-- * a first call with @in == NULL has to be made firs to initiate the
-- * output in case of non-stateless encoding needing to initiate their
-- * state or the output (like the BOM in UTF16).
-- * In case of UTF8 sequence conversion errors for the given encoder,
-- * the content will be automatically remapped to a CharRef sequence.
-- *
-- * Returns the number of byte written if success, or
-- * -1 general error
-- * -2 if the transcoding fails (for *in is not valid utf8 string or
-- * the result of transformation can't fit into the encoding we want), or
-- */
--int
--xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
-- xmlBufferPtr in) {
-- int ret = -2;
-- int written;
-- int writtentot = 0;
-- int toconv;
-- int output = 0;
--
-- if (handler == NULL) return(-1);
-- if (out == NULL) return(-1);
--
--retry:
--
-- written = out->size - out->use;
--
-- /*
-- * First specific handling of in = NULL, i.e. the initialization call
-- */
-- if (in == NULL) {
-- toconv = 0;
-- if (handler->output != NULL) {
-- ret = handler->output(&out->content[out->use], &written,
-- NULL, &toconv);
-- out->use += written;
-- out->content[out->use] = 0;
-- }
--#ifdef LIBXML_ICONV_ENABLED
-- else if (handler->iconv_out != NULL) {
-- ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
-- &written, NULL, &toconv);
-- out->use += written;
-- out->content[out->use] = 0;
-- }
--#endif /* LIBXML_ICONV_ENABLED */
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "initialized encoder\n");
--#endif
-- return(0);
-- }
--
-- /*
-- * Convertion itself.
-- */
-- toconv = in->use;
-- if (toconv == 0)
-- return(0);
-- if (toconv * 2 >= written) {
-- xmlBufferGrow(out, toconv * 2);
-- written = out->size - out->use - 1;
-- }
-- if (handler->output != NULL) {
-- ret = handler->output(&out->content[out->use], &written,
-- in->content, &toconv);
-- xmlBufferShrink(in, toconv);
-- out->use += written;
-- writtentot += written;
-- out->content[out->use] = 0;
-- }
--#ifdef LIBXML_ICONV_ENABLED
-- else if (handler->iconv_out != NULL) {
-- ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
-- &written, in->content, &toconv);
-- xmlBufferShrink(in, toconv);
-- out->use += written;
-- writtentot += written;
-- out->content[out->use] = 0;
-- if (ret == -1) {
-- if (written > 0) {
-- /*
-- * Can be a limitation of iconv
-- */
-- goto retry;
-- }
-- ret = -3;
-- }
-- }
--#endif /* LIBXML_ICONV_ENABLED */
-- else {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCharEncOutFunc: no output function !\n");
-- return(-1);
-- }
--
-- if (ret >= 0) output += ret;
--
-- /*
-- * Attempt to handle error cases
-- */
-- switch (ret) {
--#ifdef DEBUG_ENCODING
-- case 0:
-- xmlGenericError(xmlGenericErrorContext,
-- "converted %d bytes to %d bytes of output\n",
-- toconv, written);
-- break;
-- case -1:
-- xmlGenericError(xmlGenericErrorContext,
-- "output conversion failed by lack of space\n");
-- break;
--#endif
-- case -3:
-- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n",
-- toconv, written, in->use);
-- break;
-- case -2: {
-- int len = in->use;
-- const xmlChar *utf = (const xmlChar *) in->content;
-- int cur;
--
-- cur = xmlGetUTF8Char(utf, &len);
-- if (cur > 0) {
-- xmlChar charref[20];
--
--#ifdef DEBUG_ENCODING
-- xmlGenericError(xmlGenericErrorContext,
-- "handling output conversion error\n");
-- xmlGenericError(xmlGenericErrorContext,
-- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- in->content[0], in->content[1],
-- in->content[2], in->content[3]);
--#endif
-- /*
-- * Removes the UTF8 sequence, and replace it by a charref
-- * and continue the transcoding phase, hoping the error
-- * did not mangle the encoder state.
-- */
-- sprintf((char *) charref, "&#x%X;", cur);
-- xmlBufferShrink(in, len);
-- xmlBufferAddHead(in, charref, -1);
--
-- goto retry;
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "output conversion failed due to conv error\n");
-- xmlGenericError(xmlGenericErrorContext,
-- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- in->content[0], in->content[1],
-- in->content[2], in->content[3]);
-- in->content[0] = ' ';
-- }
-- break;
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlCharEncCloseFunc:
-- * @handler: char enconding transformation data structure
-- *
-- * Generic front-end for hencoding handler close function
-- *
-- * Returns 0 if success, or -1 in case of error
-- */
--int
--xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
-- int ret = 0;
-- if (handler == NULL) return(-1);
-- if (handler->name == NULL) return(-1);
--#ifdef LIBXML_ICONV_ENABLED
-- /*
-- * Iconv handlers can be oused only once, free the whole block.
-- * and the associated icon resources.
-- */
-- if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
-- if (handler->name != NULL)
-- xmlFree(handler->name);
-- handler->name = NULL;
-- if (handler->iconv_out != NULL) {
-- if (iconv_close(handler->iconv_out))
-- ret = -1;
-- handler->iconv_out = NULL;
-- }
-- if (handler->iconv_in != NULL) {
-- if (iconv_close(handler->iconv_in))
-- ret = -1;
-- handler->iconv_in = NULL;
-- }
-- xmlFree(handler);
-- }
--#endif /* LIBXML_ICONV_ENABLED */
--#ifdef DEBUG_ENCODING
-- if (ret)
-- xmlGenericError(xmlGenericErrorContext,
-- "failed to close the encoding handler\n");
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "closed the encoding handler\n");
--
--#endif
-- return(ret);
--}
--
-diff -Nru libxml2-2.3.0/entities.c libxml2-2.3.0.new/entities.c
---- libxml2-2.3.0/entities.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/entities.c Thu Jan 1 01:00:00 1970
-@@ -1,1034 +0,0 @@
--/*
-- * entities.c : implementation for the XML entities handking
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#include <libxml/xmlmemory.h>
--#include <libxml/hash.h>
--#include <libxml/entities.h>
--#include <libxml/parser.h>
--#include <libxml/xmlerror.h>
--
--#define DEBUG_ENT_REF /* debugging of cross entities dependancies */
--#define ENTITY_HASH_SIZE 256 /* modify xmlEntityComputeHash accordingly */
--
--/*
-- * xmlEntityComputeHash:
-- *
-- * Computes the hash value for this given entity
-- */
--int
--xmlEntityComputeHash(const xmlChar *name) {
-- register const unsigned char *cur = (const unsigned char *) name;
-- register unsigned char val = 0;
--
-- if (name == NULL)
-- return(val);
-- while (*cur) val += *cur++;
-- return(val);
--}
--
--/*
-- * The XML predefined entities.
-- */
--
--struct xmlPredefinedEntityValue {
-- const char *name;
-- const char *value;
--};
--struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
-- { "lt", "<" },
-- { "gt", ">" },
-- { "apos", "'" },
-- { "quot", "\"" },
-- { "amp", "&" }
--};
--
--/*
-- * TODO: !!!!!!! This is GROSS, allocation of a 256 entry hash for
-- * a fixed number of 4 elements !
-- */
--xmlHashTablePtr xmlPredefinedEntities = NULL;
--
--/*
-- * xmlFreeEntity : clean-up an entity record.
-- */
--void xmlFreeEntity(xmlEntityPtr entity) {
-- if (entity == NULL) return;
--
-- if (entity->children)
-- xmlFreeNodeList(entity->children);
-- if (entity->name != NULL)
-- xmlFree((char *) entity->name);
-- if (entity->ExternalID != NULL)
-- xmlFree((char *) entity->ExternalID);
-- if (entity->SystemID != NULL)
-- xmlFree((char *) entity->SystemID);
-- if (entity->URI != NULL)
-- xmlFree((char *) entity->URI);
-- if (entity->content != NULL)
-- xmlFree((char *) entity->content);
-- if (entity->orig != NULL)
-- xmlFree((char *) entity->orig);
-- memset(entity, -1, sizeof(xmlEntity));
-- xmlFree(entity);
--}
--
--/*
-- * xmlAddEntity : register a new entity for an entities table.
-- */
--static xmlEntityPtr
--xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
-- const xmlChar *ExternalID, const xmlChar *SystemID,
-- const xmlChar *content) {
-- xmlEntitiesTablePtr table = NULL;
-- xmlEntityPtr ret;
--
-- if (name == NULL)
-- return(NULL);
-- switch (type) {
-- case XML_INTERNAL_GENERAL_ENTITY:
-- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-- if (dtd->entities == NULL)
-- dtd->entities = xmlHashCreate(0);
-- table = dtd->entities;
-- break;
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- if (dtd->pentities == NULL)
-- dtd->pentities = xmlHashCreate(0);
-- table = dtd->pentities;
-- break;
-- case XML_INTERNAL_PREDEFINED_ENTITY:
-- if (xmlPredefinedEntities == NULL)
-- xmlPredefinedEntities = xmlHashCreate(8);
-- table = xmlPredefinedEntities;
-- }
-- if (table == NULL)
-- return(NULL);
-- ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddEntity: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlEntity));
-- ret->type = XML_ENTITY_DECL;
--
-- /*
-- * fill the structure.
-- */
-- ret->name = xmlStrdup(name);
-- ret->etype = (xmlEntityType) type;
-- if (ExternalID != NULL)
-- ret->ExternalID = xmlStrdup(ExternalID);
-- if (SystemID != NULL)
-- ret->SystemID = xmlStrdup(SystemID);
-- if (content != NULL) {
-- ret->length = xmlStrlen(content);
-- ret->content = xmlStrndup(content, ret->length);
-- } else {
-- ret->length = 0;
-- ret->content = NULL;
-- }
-- ret->URI = NULL; /* to be computed by the layer knowing
-- the defining entity */
-- ret->orig = NULL;
--
-- if (xmlHashAddEntry(table, name, ret)) {
-- /*
-- * entity was already defined at another level.
-- */
-- xmlFreeEntity(ret);
-- return(NULL);
-- }
-- return(ret);
--}
--
--/**
-- * xmlInitializePredefinedEntities:
-- *
-- * Set up the predefined entities.
-- */
--void xmlInitializePredefinedEntities(void) {
-- int i;
-- xmlChar name[50];
-- xmlChar value[50];
-- const char *in;
-- xmlChar *out;
--
-- if (xmlPredefinedEntities != NULL) return;
--
-- xmlPredefinedEntities = xmlCreateEntitiesTable();
-- for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
-- sizeof(xmlPredefinedEntityValues[0]);i++) {
-- in = xmlPredefinedEntityValues[i].name;
-- out = &name[0];
-- for (;(*out++ = (xmlChar) *in);)in++;
-- in = xmlPredefinedEntityValues[i].value;
-- out = &value[0];
-- for (;(*out++ = (xmlChar) *in);)in++;
--
-- xmlAddEntity(NULL, (const xmlChar *) &name[0],
-- XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
-- &value[0]);
-- }
--}
--
--/**
-- * xmlCleanupPredefinedEntities:
-- *
-- * Cleanup up the predefined entities table.
-- */
--void xmlCleanupPredefinedEntities(void) {
-- if (xmlPredefinedEntities == NULL) return;
--
-- xmlFreeEntitiesTable(xmlPredefinedEntities);
-- xmlPredefinedEntities = NULL;
--}
--
--/**
-- * xmlGetPredefinedEntity:
-- * @name: the entity name
-- *
-- * Check whether this name is an predefined entity.
-- *
-- * Returns NULL if not, othervise the entity
-- */
--xmlEntityPtr
--xmlGetPredefinedEntity(const xmlChar *name) {
-- if (xmlPredefinedEntities == NULL)
-- xmlInitializePredefinedEntities();
-- return((xmlEntityPtr) xmlHashLookup(xmlPredefinedEntities, name));
--}
--
--/**
-- * xmlAddDtdEntity:
-- * @doc: the document
-- * @name: the entity name
-- * @type: the entity type XML_xxx_yyy_ENTITY
-- * @ExternalID: the entity external ID if available
-- * @SystemID: the entity system ID if available
-- * @content: the entity content
-- *
-- * Register a new entity for this document DTD external subset.
-- *
-- * Returns a pointer to the entity or NULL in case of error
-- */
--xmlEntityPtr
--xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
-- const xmlChar *ExternalID, const xmlChar *SystemID,
-- const xmlChar *content) {
-- xmlEntityPtr ret;
-- xmlDtdPtr dtd;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddDtdEntity: doc == NULL !\n");
-- return(NULL);
-- }
-- if (doc->extSubset == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddDtdEntity: document without external subset !\n");
-- return(NULL);
-- }
-- dtd = doc->extSubset;
-- ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
-- if (ret == NULL) return(NULL);
--
-- /*
-- * Link it to the Dtd
-- */
-- ret->parent = dtd;
-- ret->doc = dtd->doc;
-- if (dtd->last == NULL) {
-- dtd->children = dtd->last = (xmlNodePtr) ret;
-- } else {
-- dtd->last->next = (xmlNodePtr) ret;
-- ret->prev = dtd->last;
-- dtd->last = (xmlNodePtr) ret;
-- }
-- return(ret);
--}
--
--/**
-- * xmlAddDocEntity:
-- * @doc: the document
-- * @name: the entity name
-- * @type: the entity type XML_xxx_yyy_ENTITY
-- * @ExternalID: the entity external ID if available
-- * @SystemID: the entity system ID if available
-- * @content: the entity content
-- *
-- * Register a new entity for this document.
-- *
-- * Returns a pointer to the entity or NULL in case of error
-- */
--xmlEntityPtr
--xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
-- const xmlChar *ExternalID, const xmlChar *SystemID,
-- const xmlChar *content) {
-- xmlEntityPtr ret;
-- xmlDtdPtr dtd;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddDocEntity: document is NULL !\n");
-- return(NULL);
-- }
-- if (doc->intSubset == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddDtdEntity: document without internal subset !\n");
-- return(NULL);
-- }
-- dtd = doc->intSubset;
-- ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
-- if (ret == NULL) return(NULL);
--
-- /*
-- * Link it to the Dtd
-- */
-- ret->parent = dtd;
-- ret->doc = dtd->doc;
-- if (dtd->last == NULL) {
-- dtd->children = dtd->last = (xmlNodePtr) ret;
-- } else {
-- dtd->last->next = (xmlNodePtr) ret;
-- ret->prev = dtd->last;
-- dtd->last = (xmlNodePtr) ret;
-- }
-- return(ret);
--}
--
--/**
-- * xmlGetEntityFromTable:
-- * @table: an entity table
-- * @name: the entity name
-- * @parameter: look for parameter entities
-- *
-- * Do an entity lookup in the table.
-- * returns the corresponding parameter entity, if found.
-- *
-- * Returns A pointer to the entity structure or NULL if not found.
-- */
--xmlEntityPtr
--xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) {
-- return((xmlEntityPtr) xmlHashLookup(table, name));
--}
--
--/**
-- * xmlGetParameterEntity:
-- * @doc: the document referencing the entity
-- * @name: the entity name
-- *
-- * Do an entity lookup in the internal and external subsets and
-- * returns the corresponding parameter entity, if found.
-- *
-- * Returns A pointer to the entity structure or NULL if not found.
-- */
--xmlEntityPtr
--xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
-- xmlEntitiesTablePtr table;
-- xmlEntityPtr ret;
--
-- if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) {
-- table = (xmlEntitiesTablePtr) doc->intSubset->pentities;
-- ret = xmlGetEntityFromTable(table, name);
-- if (ret != NULL)
-- return(ret);
-- }
-- if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) {
-- table = (xmlEntitiesTablePtr) doc->extSubset->pentities;
-- return(xmlGetEntityFromTable(table, name));
-- }
-- return(NULL);
--}
--
--/**
-- * xmlGetDtdEntity:
-- * @doc: the document referencing the entity
-- * @name: the entity name
-- *
-- * Do an entity lookup in the Dtd entity hash table and
-- * returns the corresponding entity, if found.
-- *
-- * Returns A pointer to the entity structure or NULL if not found.
-- */
--xmlEntityPtr
--xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
-- xmlEntitiesTablePtr table;
--
-- if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-- table = (xmlEntitiesTablePtr) doc->extSubset->entities;
-- return(xmlGetEntityFromTable(table, name));
-- }
-- return(NULL);
--}
--
--/**
-- * xmlGetDocEntity:
-- * @doc: the document referencing the entity
-- * @name: the entity name
-- *
-- * Do an entity lookup in the document entity hash table and
-- * returns the corrsponding entity, otherwise a lookup is done
-- * in the predefined entities too.
-- *
-- * Returns A pointer to the entity structure or NULL if not found.
-- */
--xmlEntityPtr
--xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
-- xmlEntityPtr cur;
-- xmlEntitiesTablePtr table;
--
-- if (doc != NULL) {
-- if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
-- table = (xmlEntitiesTablePtr) doc->intSubset->entities;
-- cur = xmlGetEntityFromTable(table, name);
-- if (cur != NULL)
-- return(cur);
-- }
-- if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-- table = (xmlEntitiesTablePtr) doc->extSubset->entities;
-- cur = xmlGetEntityFromTable(table, name);
-- if (cur != NULL)
-- return(cur);
-- }
-- }
-- if (xmlPredefinedEntities == NULL)
-- xmlInitializePredefinedEntities();
-- table = xmlPredefinedEntities;
-- return(xmlGetEntityFromTable(table, name));
--}
--
--/*
-- * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-- * | [#x10000-#x10FFFF]
-- * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
-- */
--#define IS_CHAR(c) \
-- (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
-- (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
--
--/*
-- * A buffer used for converting entities to their equivalent and back.
-- */
--static int buffer_size = 0;
--static xmlChar *buffer = NULL;
--
--int growBuffer(void) {
-- buffer_size *= 2;
-- buffer = (xmlChar *) xmlRealloc(buffer, buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("realloc failed");
-- return(-1);
-- }
-- return(0);
--}
--
--
--/**
-- * xmlEncodeEntities:
-- * @doc: the document containing the string
-- * @input: A string to convert to XML.
-- *
-- * Do a global encoding of a string, replacing the predefined entities
-- * and non ASCII values with their entities and CharRef counterparts.
-- *
-- * TODO: remove xmlEncodeEntities, once we are not afraid of breaking binary
-- * compatibility
-- *
-- * People must migrate their code to xmlEncodeEntitiesReentrant !
-- * This routine will issue a warning when encountered.
-- *
-- * Returns A newly allocated string with the substitution done.
-- */
--const xmlChar *
--xmlEncodeEntities(xmlDocPtr doc, const xmlChar *input) {
-- const xmlChar *cur = input;
-- xmlChar *out = buffer;
-- static int warning = 1;
-- int html = 0;
--
--
-- if (warning) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Deprecated API xmlEncodeEntities() used\n");
-- xmlGenericError(xmlGenericErrorContext,
-- " change code to use xmlEncodeEntitiesReentrant()\n");
-- warning = 0;
-- }
--
-- if (input == NULL) return(NULL);
-- if (doc != NULL)
-- html = (doc->type == XML_HTML_DOCUMENT_NODE);
--
-- if (buffer == NULL) {
-- buffer_size = 1000;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("malloc failed");
-- return(NULL);
-- }
-- out = buffer;
-- }
-- while (*cur != '\0') {
-- if (out - buffer > buffer_size - 100) {
-- int index = out - buffer;
--
-- growBuffer();
-- out = &buffer[index];
-- }
--
-- /*
-- * By default one have to encode at least '<', '>', '"' and '&' !
-- */
-- if (*cur == '<') {
-- *out++ = '&';
-- *out++ = 'l';
-- *out++ = 't';
-- *out++ = ';';
-- } else if (*cur == '>') {
-- *out++ = '&';
-- *out++ = 'g';
-- *out++ = 't';
-- *out++ = ';';
-- } else if (*cur == '&') {
-- *out++ = '&';
-- *out++ = 'a';
-- *out++ = 'm';
-- *out++ = 'p';
-- *out++ = ';';
-- } else if (*cur == '"') {
-- *out++ = '&';
-- *out++ = 'q';
-- *out++ = 'u';
-- *out++ = 'o';
-- *out++ = 't';
-- *out++ = ';';
-- } else if ((*cur == '\'') && (!html)) {
-- *out++ = '&';
-- *out++ = 'a';
-- *out++ = 'p';
-- *out++ = 'o';
-- *out++ = 's';
-- *out++ = ';';
-- } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
-- (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
-- /*
-- * default case, just copy !
-- */
-- *out++ = *cur;
--#ifndef USE_UTF_8
-- } else if ((sizeof(xmlChar) == 1) && (*cur >= 0x80)) {
-- char buf[10], *ptr;
--
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "&#%d;", *cur);
--#else
-- sprintf(buf, "&#%d;", *cur);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- ptr = buf;
-- while (*ptr != 0) *out++ = *ptr++;
--#endif
-- } else if (IS_CHAR(*cur)) {
-- char buf[10], *ptr;
--
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "&#%d;", *cur);
--#else
-- sprintf(buf, "&#%d;", *cur);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- ptr = buf;
-- while (*ptr != 0) *out++ = *ptr++;
-- }
--#if 0
-- else {
-- /*
-- * default case, this is not a valid char !
-- * Skip it...
-- */
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlEncodeEntities: invalid char %d\n", (int) *cur);
-- }
--#endif
-- cur++;
-- }
-- *out++ = 0;
-- return(buffer);
--}
--
--/*
-- * Macro used to grow the current buffer.
-- */
--#define growBufferReentrant() { \
-- buffer_size *= 2; \
-- buffer = (xmlChar *) \
-- xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
-- if (buffer == NULL) { \
-- perror("realloc failed"); \
-- return(NULL); \
-- } \
--}
--
--
--/**
-- * xmlEncodeEntitiesReentrant:
-- * @doc: the document containing the string
-- * @input: A string to convert to XML.
-- *
-- * Do a global encoding of a string, replacing the predefined entities
-- * and non ASCII values with their entities and CharRef counterparts.
-- * Contrary to xmlEncodeEntities, this routine is reentrant, and result
-- * must be deallocated.
-- *
-- * Returns A newly allocated string with the substitution done.
-- */
--xmlChar *
--xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
-- const xmlChar *cur = input;
-- xmlChar *buffer = NULL;
-- xmlChar *out = NULL;
-- int buffer_size = 0;
-- int html = 0;
--
-- if (input == NULL) return(NULL);
-- if (doc != NULL)
-- html = (doc->type == XML_HTML_DOCUMENT_NODE);
--
-- /*
-- * allocate an translation buffer.
-- */
-- buffer_size = 1000;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("malloc failed");
-- return(NULL);
-- }
-- out = buffer;
--
-- while (*cur != '\0') {
-- if (out - buffer > buffer_size - 100) {
-- int index = out - buffer;
--
-- growBufferReentrant();
-- out = &buffer[index];
-- }
--
-- /*
-- * By default one have to encode at least '<', '>', '"' and '&' !
-- */
-- if (*cur == '<') {
-- *out++ = '&';
-- *out++ = 'l';
-- *out++ = 't';
-- *out++ = ';';
-- } else if (*cur == '>') {
-- *out++ = '&';
-- *out++ = 'g';
-- *out++ = 't';
-- *out++ = ';';
-- } else if (*cur == '&') {
-- *out++ = '&';
-- *out++ = 'a';
-- *out++ = 'm';
-- *out++ = 'p';
-- *out++ = ';';
-- } else if (*cur == '"') {
-- *out++ = '&';
-- *out++ = 'q';
-- *out++ = 'u';
-- *out++ = 'o';
-- *out++ = 't';
-- *out++ = ';';
--#if 0
-- } else if ((*cur == '\'') && (!html)) {
-- *out++ = '&';
-- *out++ = 'a';
-- *out++ = 'p';
-- *out++ = 'o';
-- *out++ = 's';
-- *out++ = ';';
--#endif
-- } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
-- (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
-- /*
-- * default case, just copy !
-- */
-- *out++ = *cur;
-- } else if (*cur >= 0x80) {
-- if ((doc->encoding != NULL) || (html)) {
-- /*
-- * Bjørn Reese <br@sseusa.com> provided the patch
-- xmlChar xc;
-- xc = (*cur & 0x3F) << 6;
-- if (cur[1] != 0) {
-- xc += *(++cur) & 0x3F;
-- *out++ = xc;
-- } else
-- */
-- *out++ = *cur;
-- } else {
-- /*
-- * We assume we have UTF-8 input.
-- */
-- char buf[10], *ptr;
-- int val = 0, l = 1;
--
-- if (*cur < 0xC0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlEncodeEntitiesReentrant : input not UTF-8\n");
-- doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "&#%d;", *cur);
--#else
-- sprintf(buf, "&#%d;", *cur);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- ptr = buf;
-- while (*ptr != 0) *out++ = *ptr++;
-- continue;
-- } else if (*cur < 0xE0) {
-- val = (cur[0]) & 0x1F;
-- val <<= 6;
-- val |= (cur[1]) & 0x3F;
-- l = 2;
-- } else if (*cur < 0xF0) {
-- val = (cur[0]) & 0x0F;
-- val <<= 6;
-- val |= (cur[1]) & 0x3F;
-- val <<= 6;
-- val |= (cur[2]) & 0x3F;
-- l = 3;
-- } else if (*cur < 0xF8) {
-- val = (cur[0]) & 0x07;
-- val <<= 6;
-- val |= (cur[1]) & 0x3F;
-- val <<= 6;
-- val |= (cur[2]) & 0x3F;
-- val <<= 6;
-- val |= (cur[3]) & 0x3F;
-- l = 4;
-- }
-- if ((l == 1) || (!IS_CHAR(val))) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlEncodeEntitiesReentrant : char out of range\n");
-- doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "&#%d;", *cur);
--#else
-- sprintf(buf, "&#%d;", *cur);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- ptr = buf;
-- while (*ptr != 0) *out++ = *ptr++;
-- cur++;
-- continue;
-- }
-- /*
-- * We could do multiple things here. Just save as a char ref
-- */
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "&#x%X;", val);
--#else
-- sprintf(buf, "&#x%X;", val);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- ptr = buf;
-- while (*ptr != 0) *out++ = *ptr++;
-- cur += l;
-- continue;
-- }
-- } else if (IS_CHAR(*cur)) {
-- char buf[10], *ptr;
--
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "&#%d;", *cur);
--#else
-- sprintf(buf, "&#%d;", *cur);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- ptr = buf;
-- while (*ptr != 0) *out++ = *ptr++;
-- }
--#if 0
-- else {
-- /*
-- * default case, this is not a valid char !
-- * Skip it...
-- */
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlEncodeEntities: invalid char %d\n", (int) *cur);
-- }
--#endif
-- cur++;
-- }
-- *out++ = 0;
-- return(buffer);
--}
--
--/**
-- * xmlEncodeSpecialChars:
-- * @doc: the document containing the string
-- * @input: A string to convert to XML.
-- *
-- * Do a global encoding of a string, replacing the predefined entities
-- * this routine is reentrant, and result must be deallocated.
-- *
-- * Returns A newly allocated string with the substitution done.
-- */
--xmlChar *
--xmlEncodeSpecialChars(xmlDocPtr doc, const xmlChar *input) {
-- const xmlChar *cur = input;
-- xmlChar *buffer = NULL;
-- xmlChar *out = NULL;
-- int buffer_size = 0;
-- int html = 0;
--
-- if (input == NULL) return(NULL);
-- if (doc != NULL)
-- html = (doc->type == XML_HTML_DOCUMENT_NODE);
--
-- /*
-- * allocate an translation buffer.
-- */
-- buffer_size = 1000;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("malloc failed");
-- return(NULL);
-- }
-- out = buffer;
--
-- while (*cur != '\0') {
-- if (out - buffer > buffer_size - 10) {
-- int index = out - buffer;
--
-- growBufferReentrant();
-- out = &buffer[index];
-- }
--
-- /*
-- * By default one have to encode at least '<', '>', '"' and '&' !
-- */
-- if (*cur == '<') {
-- *out++ = '&';
-- *out++ = 'l';
-- *out++ = 't';
-- *out++ = ';';
-- } else if (*cur == '>') {
-- *out++ = '&';
-- *out++ = 'g';
-- *out++ = 't';
-- *out++ = ';';
-- } else if (*cur == '&') {
-- *out++ = '&';
-- *out++ = 'a';
-- *out++ = 'm';
-- *out++ = 'p';
-- *out++ = ';';
-- } else if (*cur == '"') {
-- *out++ = '&';
-- *out++ = 'q';
-- *out++ = 'u';
-- *out++ = 'o';
-- *out++ = 't';
-- *out++ = ';';
-- } else {
-- /*
-- * Works because on UTF-8, all extended sequences cannot
-- * result in bytes in the ASCII range.
-- */
-- *out++ = *cur;
-- }
-- cur++;
-- }
-- *out++ = 0;
-- return(buffer);
--}
--
--/**
-- * xmlCreateEntitiesTable:
-- *
-- * create and initialize an empty entities hash table.
-- *
-- * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
-- */
--xmlEntitiesTablePtr
--xmlCreateEntitiesTable(void) {
-- return((xmlEntitiesTablePtr) xmlHashCreate(0));
--}
--
--/**
-- * xmlFreeEntitiesTable:
-- * @table: An entity table
-- *
-- * Deallocate the memory used by an entities hash table.
-- */
--void
--xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
-- xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntity);
--}
--
--/**
-- * xmlCopyEntity:
-- * @ent: An entity
-- *
-- * Build a copy of an entity
-- *
-- * Returns the new xmlEntitiesPtr or NULL in case of error.
-- */
--xmlEntityPtr
--xmlCopyEntity(xmlEntityPtr ent) {
-- xmlEntityPtr cur;
--
-- cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCopyEntity: out of memory !\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlEntity));
-- cur->type = XML_ELEMENT_DECL;
--
-- cur->etype = ent->etype;
-- if (ent->name != NULL)
-- cur->name = xmlStrdup(ent->name);
-- if (ent->ExternalID != NULL)
-- cur->ExternalID = xmlStrdup(ent->ExternalID);
-- if (ent->SystemID != NULL)
-- cur->SystemID = xmlStrdup(ent->SystemID);
-- if (ent->content != NULL)
-- cur->content = xmlStrdup(ent->content);
-- if (ent->orig != NULL)
-- cur->orig = xmlStrdup(ent->orig);
-- return(cur);
--}
--
--/**
-- * xmlCopyEntitiesTable:
-- * @table: An entity table
-- *
-- * Build a copy of an entity table.
-- *
-- * Returns the new xmlEntitiesTablePtr or NULL in case of error.
-- */
--xmlEntitiesTablePtr
--xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
-- return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity));
--}
--
--/**
-- * xmlDumpEntityDecl:
-- * @buf: An XML buffer.
-- * @ent: An entity table
-- *
-- * This will dump the content of the entity table as an XML DTD definition
-- */
--void
--xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
-- switch (ent->etype) {
-- case XML_INTERNAL_GENERAL_ENTITY:
-- xmlBufferWriteChar(buf, "<!ENTITY ");
-- xmlBufferWriteCHAR(buf, ent->name);
-- xmlBufferWriteChar(buf, " ");
-- if (ent->orig != NULL)
-- xmlBufferWriteQuotedString(buf, ent->orig);
-- else
-- xmlBufferWriteQuotedString(buf, ent->content);
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-- xmlBufferWriteChar(buf, "<!ENTITY ");
-- xmlBufferWriteCHAR(buf, ent->name);
-- if (ent->ExternalID != NULL) {
-- xmlBufferWriteChar(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf, ent->ExternalID);
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteQuotedString(buf, ent->SystemID);
-- } else {
-- xmlBufferWriteChar(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf, ent->SystemID);
-- }
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-- xmlBufferWriteChar(buf, "<!ENTITY ");
-- xmlBufferWriteCHAR(buf, ent->name);
-- if (ent->ExternalID != NULL) {
-- xmlBufferWriteChar(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf, ent->ExternalID);
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteQuotedString(buf, ent->SystemID);
-- } else {
-- xmlBufferWriteChar(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf, ent->SystemID);
-- }
-- if (ent->content != NULL) { /* Should be true ! */
-- xmlBufferWriteChar(buf, " NDATA ");
-- if (ent->orig != NULL)
-- xmlBufferWriteCHAR(buf, ent->orig);
-- else
-- xmlBufferWriteCHAR(buf, ent->content);
-- }
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- xmlBufferWriteChar(buf, "<!ENTITY % ");
-- xmlBufferWriteCHAR(buf, ent->name);
-- xmlBufferWriteChar(buf, " ");
-- if (ent->orig == NULL)
-- xmlBufferWriteQuotedString(buf, ent->content);
-- else
-- xmlBufferWriteQuotedString(buf, ent->orig);
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- xmlBufferWriteChar(buf, "<!ENTITY % ");
-- xmlBufferWriteCHAR(buf, ent->name);
-- if (ent->ExternalID != NULL) {
-- xmlBufferWriteChar(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf, ent->ExternalID);
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteQuotedString(buf, ent->SystemID);
-- } else {
-- xmlBufferWriteChar(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf, ent->SystemID);
-- }
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDumpEntitiesTable: internal: unknown type %d\n",
-- ent->etype);
-- }
--}
--
--/**
-- * xmlDumpEntitiesTable:
-- * @buf: An XML buffer.
-- * @table: An entity table
-- *
-- * This will dump the content of the entity table as an XML DTD definition
-- */
--void
--xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
-- xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDecl, buf);
--}
-diff -Nru libxml2-2.3.0/error.c libxml2-2.3.0.new/error.c
---- libxml2-2.3.0/error.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/error.c Thu Jan 1 01:00:00 1970
-@@ -1,298 +0,0 @@
--/*
-- * error.c: module displaying/handling XML parser errors
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel Veillard <Daniel.Veillard@w3.org>
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <stdarg.h>
--#include <libxml/parser.h>
--#include <libxml/xmlerror.h>
--
--/************************************************************************
-- * *
-- * Handling of out of context errors *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlGenericErrorDefaultFunc:
-- * @ctx: an error context
-- * @msg: the message to display/transmit
-- * @...: extra parameters for the message display
-- *
-- * Default handler for out of context error messages.
-- */
--void
--xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...) {
-- va_list args;
--
-- if (xmlGenericErrorContext == NULL)
-- xmlGenericErrorContext = (void *) stderr;
--
-- va_start(args, msg);
-- vfprintf((FILE *)xmlGenericErrorContext, msg, args);
-- va_end(args);
--}
--
--xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
--void *xmlGenericErrorContext = NULL;
--
--
--/**
-- * xmlSetGenericErrorFunc:
-- * @ctx: the new error handling context
-- * @handler: the new handler function
-- *
-- * Function to reset the handler and the error context for out of
-- * context error messages.
-- * This simply means that @handler will be called for subsequent
-- * error messages while not parsing nor validating. And @ctx will
-- * be passed as first argument to @handler
-- * One can simply force messages to be emitted to another FILE * than
-- * stderr by setting @ctx to this file handle and @handler to NULL.
-- */
--void
--xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
-- xmlGenericErrorContext = ctx;
-- if (handler != NULL)
-- xmlGenericError = handler;
-- else
-- xmlGenericError = xmlGenericErrorDefaultFunc;
--}
--
--/************************************************************************
-- * *
-- * Handling of parsing errors *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlParserPrintFileInfo:
-- * @input: an xmlParserInputPtr input
-- *
-- * Displays the associated file and line informations for the current input
-- */
--
--void
--xmlParserPrintFileInfo(xmlParserInputPtr input) {
-- if (input != NULL) {
-- if (input->filename)
-- xmlGenericError(xmlGenericErrorContext,
-- "%s:%d: ", input->filename,
-- input->line);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "Entity: line %d: ", input->line);
-- }
--}
--
--/**
-- * xmlParserPrintFileContext:
-- * @input: an xmlParserInputPtr input
-- *
-- * Displays current context within the input content for error tracking
-- */
--
--void
--xmlParserPrintFileContext(xmlParserInputPtr input) {
-- const xmlChar *cur, *base;
-- int n;
--
-- if (input == NULL) return;
-- cur = input->cur;
-- base = input->base;
-- while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
-- cur--;
-- }
-- n = 0;
-- while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
-- cur--;
-- if ((*cur == '\n') || (*cur == '\r')) cur++;
-- base = cur;
-- n = 0;
-- while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "%c", (unsigned char) *cur++);
-- n++;
-- }
-- xmlGenericError(xmlGenericErrorContext, "\n");
-- cur = input->cur;
-- while ((*cur == '\n') || (*cur == '\r'))
-- cur--;
-- n = 0;
-- while ((cur != base) && (n++ < 80)) {
-- xmlGenericError(xmlGenericErrorContext, " ");
-- base++;
-- }
-- xmlGenericError(xmlGenericErrorContext,"^\n");
--}
--
--/**
-- * xmlParserError:
-- * @ctx: an XML parser context
-- * @msg: the message to display/transmit
-- * @...: extra parameters for the message display
-- *
-- * Display and format an error messages, gives file, line, position and
-- * extra parameters.
-- */
--void
--xmlParserError(void *ctx, const char *msg, ...)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlParserInputPtr input = NULL;
-- xmlParserInputPtr cur = NULL;
-- va_list args;
--
-- if (ctxt != NULL) {
-- input = ctxt->input;
-- if ((input != NULL) && (input->filename == NULL) &&
-- (ctxt->inputNr > 1)) {
-- cur = input;
-- input = ctxt->inputTab[ctxt->inputNr - 2];
-- }
-- xmlParserPrintFileInfo(input);
-- }
--
-- xmlGenericError(xmlGenericErrorContext, "error: ");
-- va_start(args, msg);
-- vfprintf(xmlGenericErrorContext, msg, args);
-- va_end(args);
--
-- if (ctxt != NULL) {
-- xmlParserPrintFileContext(input);
-- if (cur != NULL) {
-- xmlParserPrintFileInfo(cur);
-- xmlGenericError(xmlGenericErrorContext, "\n");
-- xmlParserPrintFileContext(cur);
-- }
-- }
--}
--
--/**
-- * xmlParserWarning:
-- * @ctx: an XML parser context
-- * @msg: the message to display/transmit
-- * @...: extra parameters for the message display
-- *
-- * Display and format a warning messages, gives file, line, position and
-- * extra parameters.
-- */
--void
--xmlParserWarning(void *ctx, const char *msg, ...)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlParserInputPtr input = NULL;
-- xmlParserInputPtr cur = NULL;
-- va_list args;
--
-- if (ctxt != NULL) {
-- input = ctxt->input;
-- if ((input != NULL) && (input->filename == NULL) &&
-- (ctxt->inputNr > 1)) {
-- cur = input;
-- input = ctxt->inputTab[ctxt->inputNr - 2];
-- }
-- xmlParserPrintFileInfo(input);
-- }
--
-- xmlGenericError(xmlGenericErrorContext, "warning: ");
-- va_start(args, msg);
-- vfprintf(xmlGenericErrorContext, msg, args);
-- va_end(args);
--
--
-- if (ctxt != NULL) {
-- xmlParserPrintFileContext(input);
-- if (cur != NULL) {
-- xmlParserPrintFileInfo(cur);
-- xmlGenericError(xmlGenericErrorContext, "\n");
-- xmlParserPrintFileContext(cur);
-- }
-- }
--}
--
--/************************************************************************
-- * *
-- * Handling of validation errors *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlParserValidityError:
-- * @ctx: an XML parser context
-- * @msg: the message to display/transmit
-- * @...: extra parameters for the message display
-- *
-- * Display and format an validity error messages, gives file,
-- * line, position and extra parameters.
-- */
--void
--xmlParserValidityError(void *ctx, const char *msg, ...)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlParserInputPtr input = NULL;
-- va_list args;
--
-- if (ctxt != NULL) {
-- input = ctxt->input;
-- if ((input->filename == NULL) && (ctxt->inputNr > 1))
-- input = ctxt->inputTab[ctxt->inputNr - 2];
--
-- xmlParserPrintFileInfo(input);
-- }
--
-- xmlGenericError(xmlGenericErrorContext, "validity error: ");
-- va_start(args, msg);
-- vfprintf(xmlGenericErrorContext, msg, args);
-- va_end(args);
--
-- if (ctxt != NULL) {
-- xmlParserPrintFileContext(input);
-- }
--}
--
--/**
-- * xmlParserValidityWarning:
-- * @ctx: an XML parser context
-- * @msg: the message to display/transmit
-- * @...: extra parameters for the message display
-- *
-- * Display and format a validity warning messages, gives file, line,
-- * position and extra parameters.
-- */
--void
--xmlParserValidityWarning(void *ctx, const char *msg, ...)
--{
-- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-- xmlParserInputPtr input = NULL;
-- va_list args;
--
-- if (ctxt != NULL) {
-- input = ctxt->input;
-- if ((input->filename == NULL) && (ctxt->inputNr > 1))
-- input = ctxt->inputTab[ctxt->inputNr - 2];
--
-- xmlParserPrintFileInfo(input);
-- }
--
-- xmlGenericError(xmlGenericErrorContext, "validity warning: ");
-- va_start(args, msg);
-- vfprintf(xmlGenericErrorContext, msg, args);
-- va_end(args);
--
-- if (ctxt != NULL) {
-- xmlParserPrintFileContext(input);
-- }
--}
--
--
-diff -Nru libxml2-2.3.0/example/Makefile.am libxml2-2.3.0.new/example/Makefile.am
---- libxml2-2.3.0/example/Makefile.am Sat Jan 27 20:37:13 2001
-+++ libxml2-2.3.0.new/example/Makefile.am Mon Feb 12 04:15:20 2001
-@@ -1,8 +1,4 @@
- noinst_PROGRAMS = gjobread
-
--INCLUDES = \
-- -I$(top_builddir) -I$(top_srcdir) \
-- -I@srcdir@
--
--LDADD = $(top_builddir)/libxml2.la @Z_LIBS@
-+LDADD = ../libxml/libxml.la
-
-diff -Nru libxml2-2.3.0/hash.c libxml2-2.3.0.new/hash.c
---- libxml2-2.3.0/hash.c Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/hash.c Thu Jan 1 01:00:00 1970
-@@ -1,533 +0,0 @@
--/*
-- * hash.c: chained hash tables
-- *
-- * Reference: Your favorite introductory book on algorithms
-- *
-- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-- *
-- * Author: bjorn.reese@systematic.dk
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <string.h>
--#include <libxml/hash.h>
--#include <libxml/xmlmemory.h>
--#include <libxml/parser.h>
--
--/*
-- * A single entry in the hash table
-- */
--typedef struct _xmlHashEntry xmlHashEntry;
--typedef xmlHashEntry *xmlHashEntryPtr;
--struct _xmlHashEntry {
-- struct _xmlHashEntry *next;
-- xmlChar *name;
-- xmlChar *name2;
-- xmlChar *name3;
-- void *payload;
--};
--
--/*
-- * The entire hash table
-- */
--struct _xmlHashTable {
-- struct _xmlHashEntry **table;
-- int size;
-- int nbElems;
--};
--
--/*
-- * xmlHashComputeKey:
-- * Calculate the hash key
-- */
--static unsigned long
--xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *string) {
-- unsigned long value = 0L;
-- char ch;
--
-- while ((ch = *string++) != 0) {
-- /* value *= 31; */
-- value += (unsigned long)ch;
-- }
-- return (value % table->size);
--}
--
--/**
-- * xmlHashCreate:
-- * @size: the size of the hash table
-- *
-- * Create a new xmlHashTablePtr.
-- *
-- * Returns the newly created object, or NULL if an error occured.
-- */
--xmlHashTablePtr
--xmlHashCreate(int size) {
-- xmlHashTablePtr table;
--
-- if (size <= 0)
-- size = 256;
--
-- table = xmlMalloc(sizeof(xmlHashTable));
-- if (table) {
-- table->size = size;
-- table->nbElems = 0;
-- table->table = xmlMalloc(size * sizeof(xmlHashEntry));
-- if (table->table) {
-- memset(table->table, 0, size * sizeof(xmlHashEntry));
-- return(table);
-- }
-- xmlFree(table);
-- }
-- return(NULL);
--}
--
--/**
-- * xmlHashFree:
-- * @table: the hash table
-- * @f: the deallocator function for items in the hash
-- *
-- * Free the hash table and its contents. The userdata is
-- * deallocated with f if provided.
-- */
--void
--xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
-- int i;
-- xmlHashEntryPtr iter;
-- xmlHashEntryPtr next;
--
-- if (table == NULL)
-- return;
-- if (table->table) {
-- for(i = 0; i < table->size; i++) {
-- iter = table->table[i];
-- while (iter) {
-- next = iter->next;
-- if (iter->name)
-- xmlFree(iter->name);
-- if (iter->name2)
-- xmlFree(iter->name2);
-- if (iter->name3)
-- xmlFree(iter->name3);
-- if (f)
-- f(iter->payload, iter->name);
-- iter->payload = NULL;
-- xmlFree(iter);
-- iter = next;
-- }
-- table->table[i] = NULL;
-- }
-- xmlFree(table->table);
-- }
-- xmlFree(table);
--}
--
--/**
-- * xmlHashAddEntry:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @userdata: a pointer to the userdata
-- *
-- * Add the userdata to the hash table. This can later be retrieved
-- * by using the name. Duplicate names generate errors.
-- *
-- * Returns 0 the addition succeeded and -1 in case of error.
-- */
--int
--xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
-- return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
--}
--
--/**
-- * xmlHashAddEntry2:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @name2: a second name of the userdata
-- * @userdata: a pointer to the userdata
-- *
-- * Add the userdata to the hash table. This can later be retrieved
-- * by using the (name, name2) tuple. Duplicate tuples generate errors.
-- *
-- * Returns 0 the addition succeeded and -1 in case of error.
-- */
--int
--xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2, void *userdata) {
-- return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
--}
--
--/**
-- * xmlHashUpdateEntry:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @userdata: a pointer to the userdata
-- * @f: the deallocator function for replaced item (if any)
-- *
-- * Add the userdata to the hash table. This can later be retrieved
-- * by using the name. Existing entry for this name will be removed
-- * and freed with @f if found.
-- *
-- * Returns 0 the addition succeeded and -1 in case of error.
-- */
--int
--xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
-- void *userdata, xmlHashDeallocator f) {
-- return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
--}
--
--/**
-- * xmlHashUpdateEntry2:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @name2: a second name of the userdata
-- * @userdata: a pointer to the userdata
-- * @f: the deallocator function for replaced item (if any)
-- *
-- * Add the userdata to the hash table. This can later be retrieved
-- * by using the (name, name2) tuple. Existing entry for this tuple will
-- * be removed and freed with @f if found.
-- *
-- * Returns 0 the addition succeeded and -1 in case of error.
-- */
--int
--xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2, void *userdata,
-- xmlHashDeallocator f) {
-- return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
--}
--
--/**
-- * xmlHashLookup:
-- * @table: the hash table
-- * @name: the name of the userdata
-- *
-- * Find the userdata specified by the name.
-- *
-- * Returns the a pointer to the userdata
-- */
--void *
--xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
-- return(xmlHashLookup3(table, name, NULL, NULL));
--}
--
--/**
-- * xmlHashLookup2:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @name2: a second name of the userdata
-- *
-- * Find the userdata specified by the (name, name2) tuple.
-- *
-- * Returns the a pointer to the userdata
-- */
--void *
--xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2) {
-- return(xmlHashLookup3(table, name, name2, NULL));
--}
--
--/**
-- * xmlHashAddEntry3:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @name2: a second name of the userdata
-- * @name3: a third name of the userdata
-- * @userdata: a pointer to the userdata
-- *
-- * Add the userdata to the hash table. This can later be retrieved
-- * by using the tuple (name, name2, name3). Duplicate entries generate
-- * errors.
-- *
-- * Returns 0 the addition succeeded and -1 in case of error.
-- */
--int
--xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2, const xmlChar *name3,
-- void *userdata) {
-- unsigned long key;
-- xmlHashEntryPtr entry;
-- xmlHashEntryPtr insert;
--
-- if ((table == NULL) || name == NULL)
-- return(-1);
--
-- /*
-- * Check for duplicate and insertion location.
-- */
-- key = xmlHashComputeKey(table, name);
-- if (table->table[key] == NULL) {
-- insert = NULL;
-- } else {
-- for (insert = table->table[key]; insert->next != NULL;
-- insert = insert->next) {
-- if ((xmlStrEqual(insert->name, name)) &&
-- (xmlStrEqual(insert->name2, name2)) &&
-- (xmlStrEqual(insert->name3, name3)))
-- return(-1);
-- }
-- if ((xmlStrEqual(insert->name, name)) &&
-- (xmlStrEqual(insert->name2, name2)) &&
-- (xmlStrEqual(insert->name3, name3)))
-- return(-1);
-- }
--
-- entry = xmlMalloc(sizeof(xmlHashEntry));
-- if (entry == NULL)
-- return(-1);
-- entry->name = xmlStrdup(name);
-- entry->name2 = xmlStrdup(name2);
-- entry->name3 = xmlStrdup(name3);
-- entry->payload = userdata;
-- entry->next = NULL;
--
--
-- if (insert == NULL) {
-- table->table[key] = entry;
-- } else {
-- insert->next = entry;
-- }
-- table->nbElems++;
-- return(0);
--}
--
--/**
-- * xmlHashUpdateEntry3:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @name2: a second name of the userdata
-- * @name3: a third name of the userdata
-- * @userdata: a pointer to the userdata
-- * @f: the deallocator function for replaced item (if any)
-- *
-- * Add the userdata to the hash table. This can later be retrieved
-- * by using the tuple (name, name2, name3). Existing entry for this tuple
-- * will be removed and freed with @f if found.
-- *
-- * Returns 0 the addition succeeded and -1 in case of error.
-- */
--int
--xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2, const xmlChar *name3,
-- void *userdata, xmlHashDeallocator f) {
-- unsigned long key;
-- xmlHashEntryPtr entry;
-- xmlHashEntryPtr insert;
--
-- if ((table == NULL) || name == NULL)
-- return(-1);
--
-- /*
-- * Check for duplicate and insertion location.
-- */
-- key = xmlHashComputeKey(table, name);
-- if (table->table[key] == NULL) {
-- insert = NULL;
-- } else {
-- for (insert = table->table[key]; insert->next != NULL;
-- insert = insert->next) {
-- if ((xmlStrEqual(insert->name, name)) &&
-- (xmlStrEqual(insert->name2, name2)) &&
-- (xmlStrEqual(insert->name3, name3))) {
-- if (f)
-- f(insert->payload, insert->name);
-- insert->payload = userdata;
-- return(0);
-- }
-- }
-- if ((xmlStrEqual(insert->name, name)) &&
-- (xmlStrEqual(insert->name2, name2)) &&
-- (xmlStrEqual(insert->name3, name3))) {
-- if (f)
-- f(insert->payload, insert->name);
-- insert->payload = userdata;
-- return(0);
-- }
-- }
--
-- entry = xmlMalloc(sizeof(xmlHashEntry));
-- if (entry == NULL)
-- return(-1);
-- entry->name = xmlStrdup(name);
-- entry->name2 = xmlStrdup(name2);
-- entry->name3 = xmlStrdup(name3);
-- entry->payload = userdata;
-- entry->next = NULL;
-- table->nbElems++;
--
--
-- if (insert == NULL) {
-- table->table[key] = entry;
-- } else {
-- insert->next = entry;
-- }
-- return(0);
--}
--
--/**
-- * xmlHashLookup:
-- * @table: the hash table
-- * @name: the name of the userdata
-- * @name2: a second name of the userdata
-- * @name3: a third name of the userdata
-- *
-- * Find the userdata specified by the (name, name2, name3) tuple.
-- *
-- * Returns the a pointer to the userdata
-- */
--void *
--xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2, const xmlChar *name3) {
-- unsigned long key;
-- xmlHashEntryPtr entry;
--
-- if (table == NULL)
-- return(NULL);
-- if (name == NULL)
-- return(NULL);
-- key = xmlHashComputeKey(table, name);
-- for (entry = table->table[key]; entry != NULL; entry = entry->next) {
-- if ((xmlStrEqual(entry->name, name)) &&
-- (xmlStrEqual(entry->name2, name2)) &&
-- (xmlStrEqual(entry->name3, name3)))
-- return(entry->payload);
-- }
-- return(NULL);
--}
--
--/**
-- * xmlHashScan:
-- * @table: the hash table
-- * @f: the scanner function for items in the hash
-- * @data: extra data passed to f
-- *
-- * Scan the hash table and applied f to each value.
-- */
--void
--xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
-- int i;
-- xmlHashEntryPtr iter;
-- xmlHashEntryPtr next;
--
-- if (table == NULL)
-- return;
-- if (f == NULL)
-- return;
--
-- if (table->table) {
-- for(i = 0; i < table->size; i++) {
-- iter = table->table[i];
-- while (iter) {
-- next = iter->next;
-- if (f)
-- f(iter->payload, data, iter->name);
-- iter = next;
-- }
-- }
-- }
--}
--
--/**
-- * xmlHashScan3:
-- * @table: the hash table
-- * @name: the name of the userdata or NULL
-- * @name2: a second name of the userdata or NULL
-- * @name3: a third name of the userdata or NULL
-- * @f: the scanner function for items in the hash
-- * @data: extra data passed to f
-- *
-- * Scan the hash table and applied f to each value matching
-- * (name, name2, name3) tuple. If one of the names is null,
-- * the comparison is considered to match.
-- */
--void
--xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
-- const xmlChar *name2, const xmlChar *name3,
-- xmlHashScanner f, void *data) {
-- int i;
-- xmlHashEntryPtr iter;
-- xmlHashEntryPtr next;
--
-- if (table == NULL)
-- return;
-- if (f == NULL)
-- return;
--
-- if (table->table) {
-- for(i = 0; i < table->size; i++) {
-- iter = table->table[i];
-- while (iter) {
-- next = iter->next;
-- if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
-- ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
-- ((name3 == NULL) || (xmlStrEqual(name3, iter->name3)))) {
-- f(iter->payload, data, iter->name);
-- }
-- iter = next;
-- }
-- }
-- }
--}
--
--/**
-- * xmlHashCopy:
-- * @table: the hash table
-- * @f: the copier function for items in the hash
-- *
-- * Scan the hash table and applied f to each value.
-- *
-- * Returns the new table or NULL in case of error.
-- */
--xmlHashTablePtr
--xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
-- int i;
-- xmlHashEntryPtr iter;
-- xmlHashEntryPtr next;
-- xmlHashTablePtr ret;
--
-- if (table == NULL)
-- return(NULL);
-- if (f == NULL)
-- return(NULL);
--
-- ret = xmlHashCreate(table->size);
-- if (table->table) {
-- for(i = 0; i < table->size; i++) {
-- iter = table->table[i];
-- while (iter) {
-- next = iter->next;
-- xmlHashAddEntry3(ret, iter->name, iter->name2,
-- iter->name3, f(iter->payload, iter->name));
-- iter = next;
-- }
-- }
-- }
-- ret->nbElems = table->nbElems;
-- return(ret);
--}
--
--/**
-- * xmlHashSize:
-- * @table: the hash table
-- *
-- * Returns the number of elements in the hash table or
-- * -1 in case of error
-- */
--int
--xmlHashSize(xmlHashTablePtr table) {
-- if (table == NULL)
-- return(-1);
-- return(table->nbElems);
--}
-diff -Nru libxml2-2.3.0/include/Makefile.am libxml2-2.3.0.new/include/Makefile.am
---- libxml2-2.3.0/include/Makefile.am Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/include/Makefile.am Thu Jan 1 01:00:00 1970
-@@ -1,33 +0,0 @@
--## Process this file with automake to produce Makefile.in
--
--xmlincdir = $(includedir)
--
--xmlinc_HEADERS = \
-- libxml/SAX.h \
-- libxml/entities.h \
-- libxml/encoding.h \
-- libxml/parser.h \
-- libxml/parserInternals.h \
-- libxml/xmlerror.h \
-- libxml/HTMLparser.h \
-- libxml/HTMLtree.h \
-- libxml/debugXML.h \
-- libxml/tree.h \
-- libxml/hash.h \
-- libxml/xpath.h \
-- libxml/xpathInternals.h \
-- libxml/xpointer.h \
-- libxml/xinclude.h \
-- libxml/xmlIO.h \
-- libxml/xmlmemory.h \
-- libxml/nanohttp.h \
-- libxml/nanoftp.h \
-- libxml/uri.h \
-- libxml/valid.h \
-- libxml/xlink.h \
-- libxml/xmlversion.h
--
--install-exec-hook:
-- $(mkinstalldirs) $(DESTDIR)$(xmlincdir) $(DESTDIR)$(xmlincdir)/libxml
--
--EXTRA_DIST = win32config.h libxml/xmlversion.h.in
-diff -Nru libxml2-2.3.0/include/Makefile.in libxml2-2.3.0.new/include/Makefile.in
---- libxml2-2.3.0/include/Makefile.in Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/include/Makefile.in Thu Jan 1 01:00:00 1970
-@@ -1,273 +0,0 @@
--# Makefile.in generated automatically by automake 1.4 from Makefile.am
--
--# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
--# This Makefile.in is free software; the Free Software Foundation
--# gives unlimited permission to copy and/or distribute it,
--# with or without modifications, as long as this notice is preserved.
--
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
--# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
--# PARTICULAR PURPOSE.
--
--
--SHELL = @SHELL@
--
--srcdir = @srcdir@
--top_srcdir = @top_srcdir@
--VPATH = @srcdir@
--prefix = @prefix@
--exec_prefix = @exec_prefix@
--
--bindir = @bindir@
--sbindir = @sbindir@
--libexecdir = @libexecdir@
--datadir = @datadir@
--sysconfdir = @sysconfdir@
--sharedstatedir = @sharedstatedir@
--localstatedir = @localstatedir@
--libdir = @libdir@
--infodir = @infodir@
--mandir = @mandir@
--includedir = @includedir@
--oldincludedir = /usr/include
--
--DESTDIR =
--
--pkgdatadir = $(datadir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--
--top_builddir = ..
--
--ACLOCAL = @ACLOCAL@
--AUTOCONF = @AUTOCONF@
--AUTOMAKE = @AUTOMAKE@
--AUTOHEADER = @AUTOHEADER@
--
--INSTALL = @INSTALL@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--transform = @program_transform_name@
--
--NORMAL_INSTALL = :
--PRE_INSTALL = :
--POST_INSTALL = :
--NORMAL_UNINSTALL = :
--PRE_UNINSTALL = :
--POST_UNINSTALL = :
--host_alias = @host_alias@
--host_triplet = @host@
--AS = @AS@
--CC = @CC@
--CFLAGS = @CFLAGS@
--CORBA_CFLAGS = @CORBA_CFLAGS@
--CPP = @CPP@
--DEBUG_OBJ = @DEBUG_OBJ@
--DLLTOOL = @DLLTOOL@
--FTP_OBJ = @FTP_OBJ@
--HAVE_ISINF = @HAVE_ISINF@
--HAVE_ISNAN = @HAVE_ISNAN@
--HTML_DIR = @HTML_DIR@
--HTML_OBJ = @HTML_OBJ@
--HTTP_OBJ = @HTTP_OBJ@
--LIBTOOL = @LIBTOOL@
--LIBXML_MAJOR_VERSION = @LIBXML_MAJOR_VERSION@
--LIBXML_MICRO_VERSION = @LIBXML_MICRO_VERSION@
--LIBXML_MINOR_VERSION = @LIBXML_MINOR_VERSION@
--LIBXML_VERSION = @LIBXML_VERSION@
--LIBXML_VERSION_INFO = @LIBXML_VERSION_INFO@
--LIBXML_VERSION_NUMBER = @LIBXML_VERSION_NUMBER@
--LN_S = @LN_S@
--MAINT = @MAINT@
--MAKEINFO = @MAKEINFO@
--MV = @MV@
--M_LIBS = @M_LIBS@
--OBJDUMP = @OBJDUMP@
--PACKAGE = @PACKAGE@
--RANLIB = @RANLIB@
--RDL_LIBS = @RDL_LIBS@
--RM = @RM@
--TAR = @TAR@
--U = @U@
--VERSION = @VERSION@
--WITH_DEBUG = @WITH_DEBUG@
--WITH_FTP = @WITH_FTP@
--WITH_HTML = @WITH_HTML@
--WITH_HTTP = @WITH_HTTP@
--WITH_ICONV = @WITH_ICONV@
--WITH_MEM_DEBUG = @WITH_MEM_DEBUG@
--WITH_XINCLUDE = @WITH_XINCLUDE@
--WITH_XPATH = @WITH_XPATH@
--WITH_XPTR = @WITH_XPTR@
--XINCLUDE_OBJ = @XINCLUDE_OBJ@
--XML_CFLAGS = @XML_CFLAGS@
--XML_INCLUDEDIR = @XML_INCLUDEDIR@
--XML_LIBDIR = @XML_LIBDIR@
--XML_LIBS = @XML_LIBS@
--XPATH_OBJ = @XPATH_OBJ@
--XPTR_OBJ = @XPTR_OBJ@
--Z_CFLAGS = @Z_CFLAGS@
--Z_LIBS = @Z_LIBS@
--
--xmlincdir = $(includedir)
--
--xmlinc_HEADERS = libxml/SAX.h libxml/entities.h libxml/encoding.h libxml/parser.h libxml/parserInternals.h libxml/xmlerror.h libxml/HTMLparser.h libxml/HTMLtree.h libxml/debugXML.h libxml/tree.h libxml/hash.h libxml/xpath.h libxml/xpathInternals.h libxml/xpointer.h libxml/xinclude.h libxml/xmlIO.h libxml/xmlmemory.h libxml/nanohttp.h libxml/nanoftp.h libxml/uri.h libxml/valid.h libxml/xlink.h libxml/xmlversion.h
--
--
--EXTRA_DIST = win32config.h libxml/xmlversion.h.in
--mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
--CONFIG_HEADER = ../config.h
--CONFIG_CLEAN_FILES =
--HEADERS = $(xmlinc_HEADERS)
--
--DIST_COMMON = Makefile.am Makefile.in
--
--
--DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
--
--GZIP_ENV = --best
--all: all-redirect
--.SUFFIXES:
--$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
-- cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps include/Makefile
--
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-- cd $(top_builddir) \
-- && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
--
--
--install-xmlincHEADERS: $(xmlinc_HEADERS)
-- @$(NORMAL_INSTALL)
-- $(mkinstalldirs) $(DESTDIR)$(xmlincdir)
-- @list='$(xmlinc_HEADERS)'; for p in $$list; do \
-- if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
-- echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(xmlincdir)/$$p"; \
-- $(INSTALL_DATA) $$d$$p $(DESTDIR)$(xmlincdir)/$$p; \
-- done
--
--uninstall-xmlincHEADERS:
-- @$(NORMAL_UNINSTALL)
-- list='$(xmlinc_HEADERS)'; for p in $$list; do \
-- rm -f $(DESTDIR)$(xmlincdir)/$$p; \
-- done
--
--tags: TAGS
--
--ID: $(HEADERS) $(SOURCES) $(LISP)
-- list='$(SOURCES) $(HEADERS)'; \
-- unique=`for i in $$list; do echo $$i; done | \
-- awk ' { files[$$0] = 1; } \
-- END { for (i in files) print i; }'`; \
-- here=`pwd` && cd $(srcdir) \
-- && mkid -f$$here/ID $$unique $(LISP)
--
--TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
-- tags=; \
-- here=`pwd`; \
-- list='$(SOURCES) $(HEADERS)'; \
-- unique=`for i in $$list; do echo $$i; done | \
-- awk ' { files[$$0] = 1; } \
-- END { for (i in files) print i; }'`; \
-- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
-- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
--
--mostlyclean-tags:
--
--clean-tags:
--
--distclean-tags:
-- -rm -f TAGS ID
--
--maintainer-clean-tags:
--
--distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
--
--subdir = include
--
--distdir: $(DISTFILES)
-- $(mkinstalldirs) $(distdir)/libxml
-- @for file in $(DISTFILES); do \
-- d=$(srcdir); \
-- if test -d $$d/$$file; then \
-- cp -pr $$d/$$file $(distdir)/$$file; \
-- else \
-- test -f $(distdir)/$$file \
-- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-- || cp -p $$d/$$file $(distdir)/$$file || :; \
-- fi; \
-- done
--info-am:
--info: info-am
--dvi-am:
--dvi: dvi-am
--check-am: all-am
--check: check-am
--installcheck-am:
--installcheck: installcheck-am
--install-exec-am:
-- @$(NORMAL_INSTALL)
-- $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
--install-exec: install-exec-am
--
--install-data-am: install-xmlincHEADERS
--install-data: install-data-am
--
--install-am: all-am
-- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
--install: install-am
--uninstall-am: uninstall-xmlincHEADERS
--uninstall: uninstall-am
--all-am: Makefile $(HEADERS)
--all-redirect: all-am
--install-strip:
-- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
--installdirs:
-- $(mkinstalldirs) $(DESTDIR)$(xmlincdir)
--
--
--mostlyclean-generic:
--
--clean-generic:
--
--distclean-generic:
-- -rm -f Makefile $(CONFIG_CLEAN_FILES)
-- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
--
--maintainer-clean-generic:
--mostlyclean-am: mostlyclean-tags mostlyclean-generic
--
--mostlyclean: mostlyclean-am
--
--clean-am: clean-tags clean-generic mostlyclean-am
--
--clean: clean-am
--
--distclean-am: distclean-tags distclean-generic clean-am
-- -rm -f libtool
--
--distclean: distclean-am
--
--maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
-- distclean-am
-- @echo "This command is intended for maintainers to use;"
-- @echo "it deletes files that may require special tools to rebuild."
--
--maintainer-clean: maintainer-clean-am
--
--.PHONY: uninstall-xmlincHEADERS install-xmlincHEADERS tags \
--mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
--distdir info-am info dvi-am dvi check check-am installcheck-am \
--installcheck install-exec-am install-exec install-data-am install-data \
--install-am install uninstall-am uninstall all-redirect all-am all \
--installdirs mostlyclean-generic distclean-generic clean-generic \
--maintainer-clean-generic clean mostlyclean distclean maintainer-clean
--
--
--install-exec-hook:
-- $(mkinstalldirs) $(DESTDIR)$(xmlincdir) $(DESTDIR)$(xmlincdir)/libxml
--
--# Tell versions [3.59,3.63) of GNU make to not export all variables.
--# Otherwise a system limit (for SysV at least) may be exceeded.
--.NOEXPORT:
-diff -Nru libxml2-2.3.0/include/libxml/HTMLparser.h libxml2-2.3.0.new/include/libxml/HTMLparser.h
---- libxml2-2.3.0/include/libxml/HTMLparser.h Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/include/libxml/HTMLparser.h Thu Jan 1 01:00:00 1970
-@@ -1,114 +0,0 @@
--/*
-- * HTMLparser.h : inf=terface for an HTML 4.0 non-verifying parser
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __HTML_PARSER_H__
--#define __HTML_PARSER_H__
--#include <libxml/parser.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * Most of the back-end structures from XML and HTML are shared
-- */
--typedef xmlParserCtxt htmlParserCtxt;
--typedef xmlParserCtxtPtr htmlParserCtxtPtr;
--typedef xmlParserNodeInfo htmlParserNodeInfo;
--typedef xmlSAXHandler htmlSAXHandler;
--typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
--typedef xmlParserInput htmlParserInput;
--typedef xmlParserInputPtr htmlParserInputPtr;
--typedef xmlDocPtr htmlDocPtr;
--typedef xmlNodePtr htmlNodePtr;
--
--/*
-- * Internal description of an HTML element
-- */
--typedef struct _htmlElemDesc htmlElemDesc;
--typedef htmlElemDesc *htmlElemDescPtr;
--struct _htmlElemDesc {
-- const char *name; /* The tag name */
-- int startTag; /* Whether the start tag can be implied */
-- int endTag; /* Whether the end tag can be implied */
-- int empty; /* Is this an empty element ? */
-- int depr; /* Is this a deprecated element ? */
-- int dtd; /* 1: only in Loose DTD, 2: only Frameset one */
-- const char *desc; /* the description */
--};
--
--/*
-- * Internal description of an HTML entity
-- */
--typedef struct _htmlEntityDesc htmlEntityDesc;
--typedef htmlEntityDesc *htmlEntityDescPtr;
--struct _htmlEntityDesc {
-- int value; /* the UNICODE value for the character */
-- const char *name; /* The entity name */
-- const char *desc; /* the description */
--};
--
--/*
-- * There is only few public functions.
-- */
--htmlElemDescPtr htmlTagLookup (const xmlChar *tag);
--htmlEntityDescPtr htmlEntityLookup(const xmlChar *name);
--htmlEntityDescPtr htmlEntityValueLookup(int value);
--
--int htmlIsAutoClosed(htmlDocPtr doc,
-- htmlNodePtr elem);
--int htmlAutoCloseTag(htmlDocPtr doc,
-- const xmlChar *name,
-- htmlNodePtr elem);
--htmlEntityDescPtr htmlParseEntityRef(htmlParserCtxtPtr ctxt,
-- xmlChar **str);
--int htmlParseCharRef(htmlParserCtxtPtr ctxt);
--void htmlParseElement(htmlParserCtxtPtr ctxt);
--
--htmlDocPtr htmlSAXParseDoc (xmlChar *cur,
-- const char *encoding,
-- htmlSAXHandlerPtr sax,
-- void *userData);
--htmlDocPtr htmlParseDoc (xmlChar *cur,
-- const char *encoding);
--htmlDocPtr htmlSAXParseFile(const char *filename,
-- const char *encoding,
-- htmlSAXHandlerPtr sax,
-- void *userData);
--htmlDocPtr htmlParseFile (const char *filename,
-- const char *encoding);
--int UTF8ToHtml (unsigned char* out,
-- int *outlen,
-- const unsigned char* in,
-- int *inlen);
--int htmlEncodeEntities(unsigned char* out,
-- int *outlen,
-- const unsigned char* in,
-- int *inlen, int quoteChar);
--int htmlIsScriptAttribute(const xmlChar *name);
--int htmlHandleOmittedElem(int val);
--
--/**
-- * Interfaces for the Push mode
-- */
--void htmlFreeParserCtxt (htmlParserCtxtPtr ctxt);
--htmlParserCtxtPtr htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax,
-- void *user_data,
-- const char *chunk,
-- int size,
-- const char *filename,
-- xmlCharEncoding enc);
--int htmlParseChunk (htmlParserCtxtPtr ctxt,
-- const char *chunk,
-- int size,
-- int terminate);
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* __HTML_PARSER_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/HTMLtree.h libxml2-2.3.0.new/include/libxml/HTMLtree.h
---- libxml2-2.3.0/include/libxml/HTMLtree.h Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/include/libxml/HTMLtree.h Thu Jan 1 01:00:00 1970
-@@ -1,61 +0,0 @@
--/*
-- * tree.h : describes the structures found in an tree resulting
-- * from an XML parsing.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __HTML_TREE_H__
--#define __HTML_TREE_H__
--
--#include <stdio.h>
--#include <libxml/tree.h>
--#include <libxml/HTMLparser.h>
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--#define HTML_TEXT_NODE XML_TEXT_NODE
--#define HTML_ENTITY_REF_NODE XML_ENTITY_REF_NODE
--#define HTML_COMMENT_NODE XML_COMMENT_NODE
--#define HTML_PRESERVE_NODE XML_CDATA_SECTION_NODE
--
--htmlDocPtr htmlNewDoc (const xmlChar *URI,
-- const xmlChar *ExternalID);
--htmlDocPtr htmlNewDocNoDtD (const xmlChar *URI,
-- const xmlChar *ExternalID);
--const xmlChar * htmlGetMetaEncoding (htmlDocPtr doc);
--int htmlSetMetaEncoding (htmlDocPtr doc,
-- const xmlChar *encoding);
--void htmlDocDumpMemory (xmlDocPtr cur,
-- xmlChar**mem,
-- int *size);
--int htmlDocDump (FILE *f,
-- xmlDocPtr cur);
--int htmlSaveFile (const char *filename,
-- xmlDocPtr cur);
--void htmlNodeDump (xmlBufferPtr buf,
-- xmlDocPtr doc,
-- xmlNodePtr cur);
--void htmlNodeDumpFile (FILE *out,
-- xmlDocPtr doc,
-- xmlNodePtr cur);
--int htmlSaveFileEnc (const char *filename,
-- xmlDocPtr cur,
-- const char *encoding);
--
--/* This one is imported from xmlIO.h
--void htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
-- xmlDocPtr cur,
-- const char *encoding);
-- */
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* __HTML_TREE_H__ */
--
-diff -Nru libxml2-2.3.0/include/libxml/SAX.h libxml2-2.3.0.new/include/libxml/SAX.h
---- libxml2-2.3.0/include/libxml/SAX.h Mon Feb 12 04:11:17 2001
-+++ libxml2-2.3.0.new/include/libxml/SAX.h Thu Jan 1 01:00:00 1970
-@@ -1,120 +0,0 @@
--/*
-- * SAX.h : Default SAX handler interfaces.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel Veillard <Daniel.Veillard@w3.org>
-- */
--
--
--#ifndef __XML_SAX_H__
--#define __XML_SAX_H__
--
--#include <stdio.h>
--#include <stdlib.h>
--#include <libxml/parser.h>
--#include <libxml/xlink.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--const xmlChar * getPublicId (void *ctx);
--const xmlChar * getSystemId (void *ctx);
--void setDocumentLocator (void *ctx,
-- xmlSAXLocatorPtr loc);
--
--int getLineNumber (void *ctx);
--int getColumnNumber (void *ctx);
--
--int isStandalone (void *ctx);
--int hasInternalSubset (void *ctx);
--int hasExternalSubset (void *ctx);
--
--void internalSubset (void *ctx,
-- const xmlChar *name,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--void externalSubset (void *ctx,
-- const xmlChar *name,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--xmlEntityPtr getEntity (void *ctx,
-- const xmlChar *name);
--xmlEntityPtr getParameterEntity (void *ctx,
-- const xmlChar *name);
--xmlParserInputPtr resolveEntity (void *ctx,
-- const xmlChar *publicId,
-- const xmlChar *systemId);
--
--void entityDecl (void *ctx,
-- const xmlChar *name,
-- int type,
-- const xmlChar *publicId,
-- const xmlChar *systemId,
-- xmlChar *content);
--void attributeDecl (void *ctx,
-- const xmlChar *elem,
-- const xmlChar *name,
-- int type,
-- int def,
-- const xmlChar *defaultValue,
-- xmlEnumerationPtr tree);
--void elementDecl (void *ctx,
-- const xmlChar *name,
-- int type,
-- xmlElementContentPtr content);
--void notationDecl (void *ctx,
-- const xmlChar *name,
-- const xmlChar *publicId,
-- const xmlChar *systemId);
--void unparsedEntityDecl (void *ctx,
-- const xmlChar *name,
-- const xmlChar *publicId,
-- const xmlChar *systemId,
-- const xmlChar *notationName);
--
--void startDocument (void *ctx);
--void endDocument (void *ctx);
--void attribute (void *ctx,
-- const xmlChar *fullname,
-- const xmlChar *value);
--void startElement (void *ctx,
-- const xmlChar *fullname,
-- const xmlChar **atts);
--void endElement (void *ctx,
-- const xmlChar *name);
--void reference (void *ctx,
-- const xmlChar *name);
--void characters (void *ctx,
-- const xmlChar *ch,
-- int len);
--void ignorableWhitespace (void *ctx,
-- const xmlChar *ch,
-- int len);
--void processingInstruction (void *ctx,
-- const xmlChar *target,
-- const xmlChar *data);
--void globalNamespace (void *ctx,
-- const xmlChar *href,
-- const xmlChar *prefix);
--void setNamespace (void *ctx,
-- const xmlChar *name);
--xmlNsPtr getNamespace (void *ctx);
--int checkNamespace (void *ctx,
-- xmlChar *nameSpace);
--void namespaceDecl (void *ctx,
-- const xmlChar *href,
-- const xmlChar *prefix);
--void comment (void *ctx,
-- const xmlChar *value);
--void cdataBlock (void *ctx,
-- const xmlChar *value,
-- int len);
--
--void xmlDefaultSAXHandlerInit (void);
--void htmlDefaultSAXHandlerInit (void);
--void sgmlDefaultSAXHandlerInit (void);
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_SAX_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/debugXML.h libxml2-2.3.0.new/include/libxml/debugXML.h
---- libxml2-2.3.0/include/libxml/debugXML.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/debugXML.h Thu Jan 1 01:00:00 1970
-@@ -1,113 +0,0 @@
--/*
-- * debugXML.h : Interfaces to a set of routines used for debugging the tree
-- * produced by the XML parser.
-- *
-- * Daniel Veillard <Daniel.Veillard@w3.org>
-- */
--
--#ifndef __DEBUG_XML__
--#define __DEBUG_XML__
--#include <stdio.h>
--#include <libxml/tree.h>
--
--#ifdef LIBXML_DEBUG_ENABLED
--
--#include <libxml/xpath.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * The standard Dump routines
-- */
--void xmlDebugDumpString (FILE *output,
-- const xmlChar *str);
--void xmlDebugDumpAttr (FILE *output,
-- xmlAttrPtr attr,
-- int depth);
--void xmlDebugDumpAttrList (FILE *output,
-- xmlAttrPtr attr,
-- int depth);
--void xmlDebugDumpOneNode (FILE *output,
-- xmlNodePtr node,
-- int depth);
--void xmlDebugDumpNode (FILE *output,
-- xmlNodePtr node,
-- int depth);
--void xmlDebugDumpNodeList (FILE *output,
-- xmlNodePtr node,
-- int depth);
--void xmlDebugDumpDocumentHead(FILE *output,
-- xmlDocPtr doc);
--void xmlDebugDumpDocument (FILE *output,
-- xmlDocPtr doc);
--void xmlDebugDumpDTD (FILE *output,
-- xmlDtdPtr doc);
--void xmlDebugDumpEntities (FILE *output,
-- xmlDocPtr doc);
--void xmlLsOneNode (FILE *output,
-- xmlNodePtr node);
--
--/****************************************************************
-- * *
-- * The XML shell related structures and functions *
-- * *
-- ****************************************************************/
--
--/**
-- * xmlShellReadlineFunc:
-- * @prompt: a string prompt
-- *
-- * This is a generic signature for the XML shell input function
-- *
-- * Returns a string which will be freed by the Shell
-- */
--typedef char * (* xmlShellReadlineFunc)(char *prompt);
--
--/*
-- * The shell context itself
-- * TODO: add the defined function tables.
-- */
--typedef struct _xmlShellCtxt xmlShellCtxt;
--typedef xmlShellCtxt *xmlShellCtxtPtr;
--struct _xmlShellCtxt {
-- char *filename;
-- xmlDocPtr doc;
-- xmlNodePtr node;
-- xmlXPathContextPtr pctxt;
-- int loaded;
-- FILE *output;
-- xmlShellReadlineFunc input;
--};
--
--/**
-- * xmlShellCmd:
-- * @ctxt: a shell context
-- * @arg: a string argument
-- * @node: a first node
-- * @node2: a second node
-- *
-- * This is a generic signature for the XML shell functions
-- *
-- * Returns an int, negative returns indicating errors
-- */
--typedef int (* xmlShellCmd) (xmlShellCtxtPtr ctxt,
-- char *arg,
-- xmlNodePtr node,
-- xmlNodePtr node2);
--
--/*
-- * The Shell interface.
-- */
--void xmlShell (xmlDocPtr doc,
-- char *filename,
-- xmlShellReadlineFunc input,
-- FILE *output);
--
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* LIBXML_DEBUG_ENABLED */
--#endif /* __DEBUG_XML__ */
-diff -Nru libxml2-2.3.0/include/libxml/encoding.h libxml2-2.3.0.new/include/libxml/encoding.h
---- libxml2-2.3.0/include/libxml/encoding.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/encoding.h Thu Jan 1 01:00:00 1970
-@@ -1,187 +0,0 @@
--/*
-- * encoding.h : interface for the encoding conversion functions needed for
-- * XML
-- *
-- * Related specs:
-- * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
-- * [ISO-10646] UTF-8 and UTF-16 in Annexes
-- * [ISO-8859-1] ISO Latin-1 characters codes.
-- * [UNICODE] The Unicode Consortium, "The Unicode Standard --
-- * Worldwide Character Encoding -- Version 1.0", Addison-
-- * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
-- * described in Unicode Technical Report #4.
-- * [US-ASCII] Coded Character Set--7-bit American Standard Code for
-- * Information Interchange, ANSI X3.4-1986.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_CHAR_ENCODING_H__
--#define __XML_CHAR_ENCODING_H__
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_ICONV_ENABLED
--#include <iconv.h>
--#endif
--#include <libxml/tree.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/**
-- * Predefined values for some standard encodings
-- * Libxml don't do beforehand translation on UTF8, ISOLatinX
-- * It also support UTF16 (LE and BE) by default.
-- *
-- * Anything else would have to be translated to UTF8 before being
-- * given to the parser itself. The BOM for UTF16 and the encoding
-- * declaration are looked at and a converter is looked for at that
-- * point. If not found the parser stops here as asked by the XML REC
-- * Converter can be registered by the user using xmlRegisterCharEncodingHandler
-- * but the currentl form doesn't allow stateful transcoding (a serious
-- * problem agreed !). If iconv has been found it will be used
-- * automatically and allow stateful transcoding, the simplest is then
-- * to be sure to enable icon and to provide iconv libs for the encoding
-- * support needed.
-- */
--typedef enum {
-- XML_CHAR_ENCODING_ERROR= -1, /* No char encoding detected */
-- XML_CHAR_ENCODING_NONE= 0, /* No char encoding detected */
-- XML_CHAR_ENCODING_UTF8= 1, /* UTF-8 */
-- XML_CHAR_ENCODING_UTF16LE= 2, /* UTF-16 little endian */
-- XML_CHAR_ENCODING_UTF16BE= 3, /* UTF-16 big endian */
-- XML_CHAR_ENCODING_UCS4LE= 4, /* UCS-4 little endian */
-- XML_CHAR_ENCODING_UCS4BE= 5, /* UCS-4 big endian */
-- XML_CHAR_ENCODING_EBCDIC= 6, /* EBCDIC uh! */
-- XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */
-- XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */
-- XML_CHAR_ENCODING_UCS2= 9, /* UCS-2 */
-- XML_CHAR_ENCODING_8859_1= 10,/* ISO-8859-1 ISO Latin 1 */
-- XML_CHAR_ENCODING_8859_2= 11,/* ISO-8859-2 ISO Latin 2 */
-- XML_CHAR_ENCODING_8859_3= 12,/* ISO-8859-3 */
-- XML_CHAR_ENCODING_8859_4= 13,/* ISO-8859-4 */
-- XML_CHAR_ENCODING_8859_5= 14,/* ISO-8859-5 */
-- XML_CHAR_ENCODING_8859_6= 15,/* ISO-8859-6 */
-- XML_CHAR_ENCODING_8859_7= 16,/* ISO-8859-7 */
-- XML_CHAR_ENCODING_8859_8= 17,/* ISO-8859-8 */
-- XML_CHAR_ENCODING_8859_9= 18,/* ISO-8859-9 */
-- XML_CHAR_ENCODING_2022_JP= 19,/* ISO-2022-JP */
-- XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */
-- XML_CHAR_ENCODING_EUC_JP= 21,/* EUC-JP */
-- XML_CHAR_ENCODING_ASCII= 22 /* pure ASCII */
--} xmlCharEncoding;
--
--/**
-- * xmlCharEncodingInputFunc:
-- * @out: a pointer ot an array of bytes to store the UTF-8 result
-- * @outlen: the lenght of @out
-- * @in: a pointer ot an array of chars in the original encoding
-- * @inlen: the lenght of @in
-- *
-- * Take a block of chars in the original encoding and try to convert
-- * it to an UTF-8 block of chars out.
-- *
-- * Returns the number of byte written, or -1 by lack of space, or -2
-- * if the transcoding failed.
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--typedef int (* xmlCharEncodingInputFunc)(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen);
--
--
--/**
-- * xmlCharEncodingOutputFunc:
-- * @out: a pointer ot an array of bytes to store the result
-- * @outlen: the lenght of @out
-- * @in: a pointer ot an array of UTF-8 chars
-- * @inlen: the lenght of @in
-- *
-- * Take a block of UTF-8 chars in and try to convert it to an other
-- * encoding.
-- * Note: a first call designed to produce heading info is called with
-- * in = NULL. If stateful this should also initialize the encoder state
-- *
-- * Returns the number of byte written, or -1 by lack of space, or -2
-- * if the transcoding failed.
-- * The value of @inlen after return is the number of octets consumed
-- * as the return value is positive, else unpredictiable.
-- * The value of @outlen after return is the number of ocetes consumed.
-- */
--typedef int (* xmlCharEncodingOutputFunc)(unsigned char* out, int *outlen,
-- const unsigned char* in, int *inlen);
--
--
--/*
-- * Block defining the handlers for non UTF-8 encodings.
-- * If iconv is supported, there is two extra fields
-- */
--
--typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
--typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
--struct _xmlCharEncodingHandler {
-- char *name;
-- xmlCharEncodingInputFunc input;
-- xmlCharEncodingOutputFunc output;
--#ifdef LIBXML_ICONV_ENABLED
-- iconv_t iconv_in;
-- iconv_t iconv_out;
--#endif /* LIBXML_ICONV_ENABLED */
--};
--
--/*
-- * Interfaces for encoding handlers
-- */
--void xmlInitCharEncodingHandlers (void);
--void xmlCleanupCharEncodingHandlers (void);
--void xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler);
--xmlCharEncodingHandlerPtr
-- xmlGetCharEncodingHandler (xmlCharEncoding enc);
--xmlCharEncodingHandlerPtr
-- xmlFindCharEncodingHandler (const char *name);
--
--
--/*
-- * Interfaces for encoding names and aliases
-- */
--int xmlAddEncodingAlias (const char *name,
-- const char *alias);
--int xmlDelEncodingAlias (const char *alias);
--const char *
-- xmlGetEncodingAlias (const char *alias);
--void xmlCleanupEncodingAliases (void);
--xmlCharEncoding
-- xmlParseCharEncoding (const char* name);
--const char*
-- xmlGetCharEncodingName (xmlCharEncoding enc);
--
--/*
-- * Interfaces directly used by the parsers.
-- */
--xmlCharEncoding
-- xmlDetectCharEncoding (const unsigned char* in,
-- int len);
--
--int xmlCheckUTF8 (const unsigned char *utf);
--
--int xmlCharEncOutFunc (xmlCharEncodingHandler *handler,
-- xmlBufferPtr out,
-- xmlBufferPtr in);
--
--int xmlCharEncInFunc (xmlCharEncodingHandler *handler,
-- xmlBufferPtr out,
-- xmlBufferPtr in);
--int xmlCharEncFirstLine (xmlCharEncodingHandler *handler,
-- xmlBufferPtr out,
-- xmlBufferPtr in);
--int xmlCharEncCloseFunc (xmlCharEncodingHandler *handler);
--
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* __XML_CHAR_ENCODING_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/entities.h libxml2-2.3.0.new/include/libxml/entities.h
---- libxml2-2.3.0/include/libxml/entities.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/entities.h Thu Jan 1 01:00:00 1970
-@@ -1,114 +0,0 @@
--/*
-- * entities.h : interface for the XML entities handking
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_ENTITIES_H__
--#define __XML_ENTITIES_H__
--
--#include <libxml/tree.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * The different valid entity types
-- */
--typedef enum {
-- XML_INTERNAL_GENERAL_ENTITY = 1,
-- XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
-- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
-- XML_INTERNAL_PARAMETER_ENTITY = 4,
-- XML_EXTERNAL_PARAMETER_ENTITY = 5,
-- XML_INTERNAL_PREDEFINED_ENTITY = 6
--} xmlEntityType;
--
--/*
-- * An unit of storage for an entity, contains the string, the value
-- * and the linkind data needed for the linking in the hash table.
-- */
--
--typedef struct _xmlEntity xmlEntity;
--typedef xmlEntity *xmlEntityPtr;
--struct _xmlEntity {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* XML_ENTITY_DECL, must be second ! */
-- const xmlChar *name; /* Attribute name */
-- struct _xmlNode *children; /* NULL */
-- struct _xmlNode *last; /* NULL */
-- struct _xmlDtd *parent; /* -> DTD */
-- struct _xmlNode *next; /* next sibling link */
-- struct _xmlNode *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* the containing document */
--
-- xmlChar *orig; /* content without ref substitution */
-- xmlChar *content; /* content or ndata if unparsed */
-- int length; /* the content length */
-- xmlEntityType etype; /* The entity type */
-- const xmlChar *ExternalID; /* External identifier for PUBLIC */
-- const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */
--
-- struct _xmlEntity *nexte; /* unused */
-- const xmlChar *URI; /* the full URI as computed */
--};
--
--/*
-- * ALl entities are stored in an hash table
-- * there is 2 separate hash tables for global and parmeter entities
-- */
--
--typedef struct _xmlHashTable xmlEntitiesTable;
--typedef xmlEntitiesTable *xmlEntitiesTablePtr;
--
--/*
-- * External functions :
-- */
--
--void xmlInitializePredefinedEntities (void);
--xmlEntityPtr xmlAddDocEntity (xmlDocPtr doc,
-- const xmlChar *name,
-- int type,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID,
-- const xmlChar *content);
--xmlEntityPtr xmlAddDtdEntity (xmlDocPtr doc,
-- const xmlChar *name,
-- int type,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID,
-- const xmlChar *content);
--xmlEntityPtr xmlGetPredefinedEntity (const xmlChar *name);
--xmlEntityPtr xmlGetDocEntity (xmlDocPtr doc,
-- const xmlChar *name);
--xmlEntityPtr xmlGetDtdEntity (xmlDocPtr doc,
-- const xmlChar *name);
--xmlEntityPtr xmlGetParameterEntity (xmlDocPtr doc,
-- const xmlChar *name);
--const xmlChar * xmlEncodeEntities (xmlDocPtr doc,
-- const xmlChar *input);
--xmlChar * xmlEncodeEntitiesReentrant(xmlDocPtr doc,
-- const xmlChar *input);
--xmlChar * xmlEncodeSpecialChars (xmlDocPtr doc,
-- const xmlChar *input);
--xmlEntitiesTablePtr xmlCreateEntitiesTable (void);
--xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table);
--void xmlFreeEntitiesTable (xmlEntitiesTablePtr table);
--void xmlDumpEntitiesTable (xmlBufferPtr buf,
-- xmlEntitiesTablePtr table);
--void xmlDumpEntityDecl (xmlBufferPtr buf,
-- xmlEntityPtr ent);
--xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table);
--void xmlCleanupPredefinedEntities(void);
--
--
--#ifdef __cplusplus
--}
--#endif
--
--# endif /* __XML_ENTITIES_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/hash.h libxml2-2.3.0.new/include/libxml/hash.h
---- libxml2-2.3.0/include/libxml/hash.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/hash.h Thu Jan 1 01:00:00 1970
-@@ -1,117 +0,0 @@
--/*
-- * hash.c: chained hash tables
-- *
-- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-- *
-- * Author: bjorn.reese@systematic.dk
-- */
--
--#ifndef __XML_HASH_H__
--#define __XML_HASH_H__
--
--#include <libxml/parser.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * The hash table
-- */
--typedef struct _xmlHashTable xmlHashTable;
--typedef xmlHashTable *xmlHashTablePtr;
--
--/*
-- * function types:
-- */
--typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
--typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
--typedef void *(*xmlHashScanner)(void *payload, void *data, xmlChar *name);
--
--/*
-- * Constructor and destructor
-- */
--xmlHashTablePtr xmlHashCreate (int size);
--void xmlHashFree (xmlHashTablePtr table,
-- xmlHashDeallocator f);
--
--/*
-- * Add a new entry to the hash table
-- */
--int xmlHashAddEntry (xmlHashTablePtr table,
-- const xmlChar *name,
-- void *userdata);
--int xmlHashUpdateEntry(xmlHashTablePtr table,
-- const xmlChar *name,
-- void *userdata,
-- xmlHashDeallocator f);
--int xmlHashAddEntry2(xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- void *userdata);
--int xmlHashUpdateEntry2(xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- void *userdata,
-- xmlHashDeallocator f);
--int xmlHashAddEntry3(xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- const xmlChar *name3,
-- void *userdata);
--int xmlHashUpdateEntry3(xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- const xmlChar *name3,
-- void *userdata,
-- xmlHashDeallocator f);
--/*
-- * Retrieve the userdata
-- */
--void * xmlHashLookup (xmlHashTablePtr table,
-- const xmlChar *name);
--void * xmlHashLookup2 (xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2);
--void * xmlHashLookup3 (xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- const xmlChar *name3);
--
--/*
-- * Helpers
-- */
--xmlHashTablePtr xmlHashCopy (xmlHashTablePtr table,
-- xmlHashCopier f);
--int xmlHashSize (xmlHashTablePtr);
--void xmlHashScan (xmlHashTablePtr table,
-- xmlHashScanner f,
-- void *data);
--void xmlHashScan1 (xmlHashTablePtr table,
-- const xmlChar *name,
-- xmlHashScanner f,
-- void *data);
--void xmlHashScan2 (xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- xmlHashScanner f,
-- void *data);
--void xmlHashScan3 (xmlHashTablePtr table,
-- const xmlChar *name,
-- const xmlChar *name2,
-- const xmlChar *name3,
-- xmlHashScanner f,
-- void *data);
--#ifdef __cplusplus
--}
--#endif
--#endif /* ! __XML_HASH_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/nanoftp.h libxml2-2.3.0.new/include/libxml/nanoftp.h
---- libxml2-2.3.0/include/libxml/nanoftp.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/nanoftp.h Thu Jan 1 01:00:00 1970
-@@ -1,110 +0,0 @@
--/*
-- * nanohttp.c: minimalist FTP implementation to fetch external subsets.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __NANO_FTP_H__
--#define __NANO_FTP_H__
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_FTP_ENABLED
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/**
-- * ftpListCallback:
-- * @userData: user provided data for the callback
-- * @filename: the file name (including "->" when links are shown)
-- * @attrib: the attribute string
-- * @owner: the owner string
-- * @group: the group string
-- * @size: the file size
-- * @links: the link count
-- * @year: the year
-- * @month: the month
-- * @day: the day
-- * @hour: the hour
-- * @minute: the minute
-- *
-- * A callback for the xmlNanoFTPList command
-- * Note that only one of year and day:minute are specified
-- */
--typedef void (*ftpListCallback) (void *userData,
-- const char *filename, const char* attrib,
-- const char *owner, const char *group,
-- unsigned long size, int links, int year,
-- const char *month, int day, int hour,
-- int minute);
--/**
-- * ftpDataCallback:
-- * A callback for the xmlNanoFTPGet command
-- */
--typedef void (*ftpDataCallback) (void *userData, const char *data, int len);
--
--/*
-- * Init
-- */
--void xmlNanoFTPInit (void);
--void xmlNanoFTPCleanup (void);
--
--/*
-- * Creating/freeing contexts
-- */
--void * xmlNanoFTPNewCtxt (const char *URL);
--void xmlNanoFTPFreeCtxt (void * ctx);
--void * xmlNanoFTPConnectTo (const char *server,
-- int port);
--/*
-- * Opening/closing session connections
-- */
--void * xmlNanoFTPOpen (const char *URL);
--int xmlNanoFTPConnect (void *ctx);
--int xmlNanoFTPClose (void *ctx);
--int xmlNanoFTPQuit (void *ctx);
--void xmlNanoFTPScanProxy (const char *URL);
--void xmlNanoFTPProxy (const char *host,
-- int port,
-- const char *user,
-- const char *passwd,
-- int type);
--int xmlNanoFTPUpdateURL (void *ctx,
-- const char *URL);
--
--/*
-- * Rathern internal commands
-- */
--int xmlNanoFTPGetResponse (void *ctx);
--int xmlNanoFTPCheckResponse (void *ctx);
--
--/*
-- * CD/DIR/GET handlers
-- */
--int xmlNanoFTPCwd (void *ctx,
-- char *directory);
--
--int xmlNanoFTPGetConnection (void *ctx);
--int xmlNanoFTPCloseConnection(void *ctx);
--int xmlNanoFTPList (void *ctx,
-- ftpListCallback callback,
-- void *userData,
-- char *filename);
--int xmlNanoFTPGetSocket (void *ctx,
-- const char *filename);
--int xmlNanoFTPGet (void *ctx,
-- ftpDataCallback callback,
-- void *userData,
-- const char *filename);
--int xmlNanoFTPRead (void *ctx,
-- void *dest,
-- int len);
--
--#ifdef __cplusplus
--}
--#endif /* LIBXML_FTP_ENABLED */
--#endif
--#endif /* __NANO_FTP_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/nanohttp.h libxml2-2.3.0.new/include/libxml/nanohttp.h
---- libxml2-2.3.0/include/libxml/nanohttp.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/nanohttp.h Thu Jan 1 01:00:00 1970
-@@ -1,44 +0,0 @@
--/*
-- * nanohttp.c: minimalist HTTP implementation to fetch external subsets.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __NANO_HTTP_H__
--#define __NANO_HTTP_H__
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_HTTP_ENABLED
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--void xmlNanoHTTPInit (void);
--void xmlNanoHTTPCleanup (void);
--void xmlNanoHTTPScanProxy (const char *URL);
--int xmlNanoHTTPFetch (const char *URL,
-- const char *filename,
-- char **contentType);
--void * xmlNanoHTTPMethod (const char *URL,
-- const char *method,
-- const char *input,
-- char **contentType,
-- const char *headers);
--void * xmlNanoHTTPOpen (const char *URL,
-- char **contentType);
--int xmlNanoHTTPReturnCode (void *ctx);
--const char * xmlNanoHTTPAuthHeader(void *ctx);
--int xmlNanoHTTPRead (void *ctx,
-- void *dest,
-- int len);
--int xmlNanoHTTPSave (void *ctxt,
-- const char *filename);
--void xmlNanoHTTPClose (void *ctx);
--#ifdef __cplusplus
--}
--
--#endif /* LIBXML_HTTP_ENABLED */
--#endif
--#endif /* __NANO_HTTP_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/parser.h libxml2-2.3.0.new/include/libxml/parser.h
---- libxml2-2.3.0/include/libxml/parser.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/parser.h Thu Jan 1 01:00:00 1970
-@@ -1,527 +0,0 @@
--/*
-- * parser.h : Interfaces, constants and types related to the XML parser.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_PARSER_H__
--#define __XML_PARSER_H__
--
--#include <libxml/tree.h>
--#include <libxml/valid.h>
--#include <libxml/xmlIO.h>
--#include <libxml/entities.h>
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * Constants.
-- */
--#define XML_DEFAULT_VERSION "1.0"
--
--/**
-- * an xmlParserInput is an input flow for the XML processor.
-- * Each entity parsed is associated an xmlParserInput (except the
-- * few predefined ones). This is the case both for internal entities
-- * - in which case the flow is already completely in memory - or
-- * external entities - in which case we use the buf structure for
-- * progressive reading and I18N conversions to the internal UTF-8 format.
-- */
--
--typedef void (* xmlParserInputDeallocate)(xmlChar *);
--typedef struct _xmlParserInput xmlParserInput;
--typedef xmlParserInput *xmlParserInputPtr;
--struct _xmlParserInput {
-- /* Input buffer */
-- xmlParserInputBufferPtr buf; /* UTF-8 encoded buffer */
--
-- const char *filename; /* The file analyzed, if any */
-- const char *directory; /* the directory/base of teh file */
-- const xmlChar *base; /* Base of the array to parse */
-- const xmlChar *cur; /* Current char being parsed */
-- int length; /* length if known */
-- int line; /* Current line */
-- int col; /* Current column */
-- int consumed; /* How many xmlChars already consumed */
-- xmlParserInputDeallocate free; /* function to deallocate the base */
-- const xmlChar *encoding; /* the encoding string for entity */
-- const xmlChar *version; /* the version string for entity */
-- int standalone; /* Was that entity marked standalone */
--};
--
--/**
-- * the parser can be asked to collect Node informations, i.e. at what
-- * place in the file they were detected.
-- * NOTE: This is off by default and not very well tested.
-- */
--typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
--typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;
--
--struct _xmlParserNodeInfo {
-- const struct _xmlNode* node;
-- /* Position & line # that text that created the node begins & ends on */
-- unsigned long begin_pos;
-- unsigned long begin_line;
-- unsigned long end_pos;
-- unsigned long end_line;
--};
--
--typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
--typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
--struct _xmlParserNodeInfoSeq {
-- unsigned long maximum;
-- unsigned long length;
-- xmlParserNodeInfo* buffer;
--};
--
--/**
-- * The parser is now working also as a state based parser
-- * The recursive one use the stagte info for entities processing
-- */
--typedef enum {
-- XML_PARSER_EOF = -1, /* nothing is to be parsed */
-- XML_PARSER_START = 0, /* nothing has been parsed */
-- XML_PARSER_MISC, /* Misc* before int subset */
-- XML_PARSER_PI, /* Whithin a processing instruction */
-- XML_PARSER_DTD, /* within some DTD content */
-- XML_PARSER_PROLOG, /* Misc* after internal subset */
-- XML_PARSER_COMMENT, /* within a comment */
-- XML_PARSER_START_TAG, /* within a start tag */
-- XML_PARSER_CONTENT, /* within the content */
-- XML_PARSER_CDATA_SECTION, /* within a CDATA section */
-- XML_PARSER_END_TAG, /* within a closing tag */
-- XML_PARSER_ENTITY_DECL, /* within an entity declaration */
-- XML_PARSER_ENTITY_VALUE, /* within an entity value in a decl */
-- XML_PARSER_ATTRIBUTE_VALUE, /* within an attribute value */
-- XML_PARSER_SYSTEM_LITERAL, /* within a SYSTEM value */
-- XML_PARSER_EPILOG, /* the Misc* after the last end tag */
-- XML_PARSER_IGNORE /* within an IGNORED section */
--} xmlParserInputState;
--
--/**
-- * The parser context.
-- * NOTE This doesn't completely defines the parser state, the (current ?)
-- * design of the parser uses recursive function calls since this allow
-- * and easy mapping from the production rules of the specification
-- * to the actual code. The drawback is that the actual function call
-- * also reflect the parser state. However most of the parsing routines
-- * takes as the only argument the parser context pointer, so migrating
-- * to a state based parser for progressive parsing shouldn't be too hard.
-- */
--typedef struct _xmlParserCtxt xmlParserCtxt;
--typedef xmlParserCtxt *xmlParserCtxtPtr;
--struct _xmlParserCtxt {
-- struct _xmlSAXHandler *sax; /* The SAX handler */
-- void *userData; /* For SAX interface only, used by DOM build */
-- xmlDocPtr myDoc; /* the document being built */
-- int wellFormed; /* is the document well formed */
-- int replaceEntities; /* shall we replace entities ? */
-- const xmlChar *version; /* the XML version string */
-- const xmlChar *encoding; /* the declared encoding, if any */
-- int standalone; /* standalone document */
-- int html; /* an HTML(1)/Docbook(2) document */
--
-- /* Input stream stack */
-- xmlParserInputPtr input; /* Current input stream */
-- int inputNr; /* Number of current input streams */
-- int inputMax; /* Max number of input streams */
-- xmlParserInputPtr *inputTab; /* stack of inputs */
--
-- /* Node analysis stack only used for DOM building */
-- xmlNodePtr node; /* Current parsed Node */
-- int nodeNr; /* Depth of the parsing stack */
-- int nodeMax; /* Max depth of the parsing stack */
-- xmlNodePtr *nodeTab; /* array of nodes */
--
-- int record_info; /* Whether node info should be kept */
-- xmlParserNodeInfoSeq node_seq; /* info about each node parsed */
--
-- int errNo; /* error code */
--
-- int hasExternalSubset; /* reference and external subset */
-- int hasPErefs; /* the internal subset has PE refs */
-- int external; /* are we parsing an external entity */
--
-- int valid; /* is the document valid */
-- int validate; /* shall we try to validate ? */
-- xmlValidCtxt vctxt; /* The validity context */
--
-- xmlParserInputState instate; /* current type of input */
-- int token; /* next char look-ahead */
--
-- char *directory; /* the data directory */
--
-- /* Node name stack */
-- xmlChar *name; /* Current parsed Node */
-- int nameNr; /* Depth of the parsing stack */
-- int nameMax; /* Max depth of the parsing stack */
-- xmlChar * *nameTab; /* array of nodes */
--
-- long nbChars; /* number of xmlChar processed */
-- long checkIndex; /* used by progressive parsing lookup */
-- int keepBlanks; /* ugly but ... */
-- int disableSAX; /* SAX callbacks are disabled */
-- int inSubset; /* Parsing is in int 1/ext 2 subset */
-- xmlChar * intSubName; /* name of subset */
-- xmlChar * extSubURI; /* URI of external subset */
-- xmlChar * extSubSystem; /* SYSTEM ID of external subset */
--
-- /* xml:space values */
-- int * space; /* Should the parser preserve spaces */
-- int spaceNr; /* Depth of the parsing stack */
-- int spaceMax; /* Max depth of the parsing stack */
-- int * spaceTab; /* array of space infos */
--
-- int depth; /* to prevent entity substitution loops */
-- xmlParserInputPtr entity; /* used to check entities boundaries */
-- int charset; /* encoding of the in-memory content
-- actually an xmlCharEncoding */
-- int nodelen; /* Those two fields are there to */
-- int nodemem; /* Speed up large node parsing */
-- int pedantic; /* signal pedantic warnings */
-- void *_private; /* For user data, libxml won't touch it */
--
-- int loadsubset; /* should the external subset be loaded */
--};
--
--/**
-- * a SAX Locator.
-- */
--typedef struct _xmlSAXLocator xmlSAXLocator;
--typedef xmlSAXLocator *xmlSAXLocatorPtr;
--struct _xmlSAXLocator {
-- const xmlChar *(*getPublicId)(void *ctx);
-- const xmlChar *(*getSystemId)(void *ctx);
-- int (*getLineNumber)(void *ctx);
-- int (*getColumnNumber)(void *ctx);
--};
--
--/**
-- * a SAX handler is bunch of callbacks called by the parser when processing
-- * of the input generate data or structure informations.
-- */
--
--typedef xmlParserInputPtr (*resolveEntitySAXFunc) (void *ctx,
-- const xmlChar *publicId, const xmlChar *systemId);
--typedef void (*internalSubsetSAXFunc) (void *ctx, const xmlChar *name,
-- const xmlChar *ExternalID, const xmlChar *SystemID);
--typedef void (*externalSubsetSAXFunc) (void *ctx, const xmlChar *name,
-- const xmlChar *ExternalID, const xmlChar *SystemID);
--typedef xmlEntityPtr (*getEntitySAXFunc) (void *ctx,
-- const xmlChar *name);
--typedef xmlEntityPtr (*getParameterEntitySAXFunc) (void *ctx,
-- const xmlChar *name);
--typedef void (*entityDeclSAXFunc) (void *ctx,
-- const xmlChar *name, int type, const xmlChar *publicId,
-- const xmlChar *systemId, xmlChar *content);
--typedef void (*notationDeclSAXFunc)(void *ctx, const xmlChar *name,
-- const xmlChar *publicId, const xmlChar *systemId);
--typedef void (*attributeDeclSAXFunc)(void *ctx, const xmlChar *elem,
-- const xmlChar *name, int type, int def,
-- const xmlChar *defaultValue, xmlEnumerationPtr tree);
--typedef void (*elementDeclSAXFunc)(void *ctx, const xmlChar *name,
-- int type, xmlElementContentPtr content);
--typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
-- const xmlChar *name, const xmlChar *publicId,
-- const xmlChar *systemId, const xmlChar *notationName);
--typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
-- xmlSAXLocatorPtr loc);
--typedef void (*startDocumentSAXFunc) (void *ctx);
--typedef void (*endDocumentSAXFunc) (void *ctx);
--typedef void (*startElementSAXFunc) (void *ctx, const xmlChar *name,
-- const xmlChar **atts);
--typedef void (*endElementSAXFunc) (void *ctx, const xmlChar *name);
--typedef void (*attributeSAXFunc) (void *ctx, const xmlChar *name,
-- const xmlChar *value);
--typedef void (*referenceSAXFunc) (void *ctx, const xmlChar *name);
--typedef void (*charactersSAXFunc) (void *ctx, const xmlChar *ch,
-- int len);
--typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
-- const xmlChar *ch, int len);
--typedef void (*processingInstructionSAXFunc) (void *ctx,
-- const xmlChar *target, const xmlChar *data);
--typedef void (*commentSAXFunc) (void *ctx, const xmlChar *value);
--typedef void (*cdataBlockSAXFunc) (void *ctx, const xmlChar *value, int len);
--typedef void (*warningSAXFunc) (void *ctx, const char *msg, ...);
--typedef void (*errorSAXFunc) (void *ctx, const char *msg, ...);
--typedef void (*fatalErrorSAXFunc) (void *ctx, const char *msg, ...);
--typedef int (*isStandaloneSAXFunc) (void *ctx);
--typedef int (*hasInternalSubsetSAXFunc) (void *ctx);
--typedef int (*hasExternalSubsetSAXFunc) (void *ctx);
--
--typedef struct _xmlSAXHandler xmlSAXHandler;
--typedef xmlSAXHandler *xmlSAXHandlerPtr;
--struct _xmlSAXHandler {
-- internalSubsetSAXFunc internalSubset;
-- isStandaloneSAXFunc isStandalone;
-- hasInternalSubsetSAXFunc hasInternalSubset;
-- hasExternalSubsetSAXFunc hasExternalSubset;
-- resolveEntitySAXFunc resolveEntity;
-- getEntitySAXFunc getEntity;
-- entityDeclSAXFunc entityDecl;
-- notationDeclSAXFunc notationDecl;
-- attributeDeclSAXFunc attributeDecl;
-- elementDeclSAXFunc elementDecl;
-- unparsedEntityDeclSAXFunc unparsedEntityDecl;
-- setDocumentLocatorSAXFunc setDocumentLocator;
-- startDocumentSAXFunc startDocument;
-- endDocumentSAXFunc endDocument;
-- startElementSAXFunc startElement;
-- endElementSAXFunc endElement;
-- referenceSAXFunc reference;
-- charactersSAXFunc characters;
-- ignorableWhitespaceSAXFunc ignorableWhitespace;
-- processingInstructionSAXFunc processingInstruction;
-- commentSAXFunc comment;
-- warningSAXFunc warning;
-- errorSAXFunc error;
-- fatalErrorSAXFunc fatalError;
-- getParameterEntitySAXFunc getParameterEntity;
-- cdataBlockSAXFunc cdataBlock;
-- externalSubsetSAXFunc externalSubset;
--};
--
--/**
-- * External entity loaders types
-- */
--typedef xmlParserInputPtr (*xmlExternalEntityLoader)(const char *URL,
-- const char *ID,
-- xmlParserCtxtPtr context);
--
--/**
-- * Global variables: just the default SAX interface tables and XML
-- * version infos.
-- */
--LIBXML_DLL_IMPORT extern const char *xmlParserVersion;
--
--LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator;
--LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler;
--LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler;
--LIBXML_DLL_IMPORT extern xmlSAXHandler sgmlDefaultSAXHandler;
--
--/**
-- * entity substitution default behaviour.
-- */
--
--#ifdef VMS
--LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultVal;
--#define xmlSubstituteEntitiesDefaultValue xmlSubstituteEntitiesDefaultVal
--#else
--LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
--#endif
--LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
--
--
--/**
-- * Init/Cleanup
-- */
--void xmlInitParser (void);
--void xmlCleanupParser (void);
--
--/**
-- * Input functions
-- */
--int xmlParserInputRead (xmlParserInputPtr in,
-- int len);
--int xmlParserInputGrow (xmlParserInputPtr in,
-- int len);
--
--/**
-- * xmlChar handling
-- */
--xmlChar * xmlStrdup (const xmlChar *cur);
--xmlChar * xmlStrndup (const xmlChar *cur,
-- int len);
--xmlChar * xmlStrsub (const xmlChar *str,
-- int start,
-- int len);
--const xmlChar * xmlStrchr (const xmlChar *str,
-- xmlChar val);
--const xmlChar * xmlStrstr (const xmlChar *str,
-- xmlChar *val);
--const xmlChar * xmlStrcasestr (const xmlChar *str,
-- xmlChar *val);
--int xmlStrcmp (const xmlChar *str1,
-- const xmlChar *str2);
--int xmlStrncmp (const xmlChar *str1,
-- const xmlChar *str2,
-- int len);
--int xmlStrcasecmp (const xmlChar *str1,
-- const xmlChar *str2);
--int xmlStrncasecmp (const xmlChar *str1,
-- const xmlChar *str2,
-- int len);
--int xmlStrEqual (const xmlChar *str1,
-- const xmlChar *str2);
--int xmlStrlen (const xmlChar *str);
--xmlChar * xmlStrcat (xmlChar *cur,
-- const xmlChar *add);
--xmlChar * xmlStrncat (xmlChar *cur,
-- const xmlChar *add,
-- int len);
--
--/**
-- * Basic parsing Interfaces
-- */
--xmlDocPtr xmlParseDoc (xmlChar *cur);
--xmlDocPtr xmlParseMemory (char *buffer,
-- int size);
--xmlDocPtr xmlParseFile (const char *filename);
--int xmlSubstituteEntitiesDefault(int val);
--int xmlKeepBlanksDefault (int val);
--void xmlStopParser (xmlParserCtxtPtr ctxt);
--int xmlPedanticParserDefault(int val);
--
--/**
-- * Recovery mode
-- */
--xmlDocPtr xmlRecoverDoc (xmlChar *cur);
--xmlDocPtr xmlRecoverMemory (char *buffer,
-- int size);
--xmlDocPtr xmlRecoverFile (const char *filename);
--
--/**
-- * Less common routines and SAX interfaces
-- */
--int xmlParseDocument (xmlParserCtxtPtr ctxt);
--int xmlParseExtParsedEnt (xmlParserCtxtPtr ctxt);
--xmlDocPtr xmlSAXParseDoc (xmlSAXHandlerPtr sax,
-- xmlChar *cur,
-- int recovery);
--int xmlSAXUserParseFile (xmlSAXHandlerPtr sax,
-- void *user_data,
-- const char *filename);
--int xmlSAXUserParseMemory (xmlSAXHandlerPtr sax,
-- void *user_data,
-- char *buffer,
-- int size);
--xmlDocPtr xmlSAXParseMemory (xmlSAXHandlerPtr sax,
-- char *buffer,
-- int size,
-- int recovery);
--xmlDocPtr xmlSAXParseFile (xmlSAXHandlerPtr sax,
-- const char *filename,
-- int recovery);
--xmlDocPtr xmlSAXParseEntity (xmlSAXHandlerPtr sax,
-- const char *filename);
--xmlDocPtr xmlParseEntity (const char *filename);
--xmlDtdPtr xmlParseDTD (const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--xmlDtdPtr xmlSAXParseDTD (xmlSAXHandlerPtr sax,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--xmlDtdPtr xmlIOParseDTD (xmlSAXHandlerPtr sax,
-- xmlParserInputBufferPtr input,
-- xmlCharEncoding enc);
--int xmlParseBalancedChunkMemory(xmlDocPtr doc,
-- xmlSAXHandlerPtr sax,
-- void *user_data,
-- int depth,
-- const xmlChar *string,
-- xmlNodePtr *list);
--int xmlParseExternalEntity (xmlDocPtr doc,
-- xmlSAXHandlerPtr sax,
-- void *user_data,
-- int depth,
-- const xmlChar *URL,
-- const xmlChar *ID,
-- xmlNodePtr *list);
--int xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx,
-- const xmlChar *URL,
-- const xmlChar *ID,
-- xmlNodePtr *list);
--
--/**
-- * SAX initialization routines
-- */
--void xmlDefaultSAXHandlerInit(void);
--void htmlDefaultSAXHandlerInit(void);
--
--/**
-- * Parser contexts handling.
-- */
--void xmlInitParserCtxt (xmlParserCtxtPtr ctxt);
--void xmlClearParserCtxt (xmlParserCtxtPtr ctxt);
--void xmlFreeParserCtxt (xmlParserCtxtPtr ctxt);
--void xmlSetupParserForBuffer (xmlParserCtxtPtr ctxt,
-- const xmlChar* buffer,
-- const char* filename);
--xmlParserCtxtPtr xmlCreateDocParserCtxt (xmlChar *cur);
--
--/**
-- * Reading/setting optional parsing features.
-- */
--
--int xmlGetFeaturesList (int *len,
-- const char **result);
--int xmlGetFeature (xmlParserCtxtPtr ctxt,
-- const char *name,
-- void *result);
--int xmlSetFeature (xmlParserCtxtPtr ctxt,
-- const char *name,
-- void *value);
--
--/**
-- * Interfaces for the Push mode
-- */
--xmlParserCtxtPtr xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax,
-- void *user_data,
-- const char *chunk,
-- int size,
-- const char *filename);
--int xmlParseChunk (xmlParserCtxtPtr ctxt,
-- const char *chunk,
-- int size,
-- int terminate);
--
--/**
-- * Special I/O mode
-- */
--
--xmlParserCtxtPtr xmlCreateIOParserCtxt (xmlSAXHandlerPtr sax,
-- void *user_data,
-- xmlInputReadCallback ioread,
-- xmlInputCloseCallback ioclose,
-- void *ioctx,
-- xmlCharEncoding enc);
--
--xmlParserInputPtr xmlNewIOInputStream (xmlParserCtxtPtr ctxt,
-- xmlParserInputBufferPtr input,
-- xmlCharEncoding enc);
--
--/**
-- * Node infos
-- */
--const xmlParserNodeInfo*
-- xmlParserFindNodeInfo (const xmlParserCtxt* ctxt,
-- const xmlNode* node);
--void xmlInitNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
--void xmlClearNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
--unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
-- const xmlNode* node);
--void xmlParserAddNodeInfo (xmlParserCtxtPtr ctxt,
-- const xmlParserNodeInfo* info);
--
--/*
-- * External entities handling actually implemented in xmlIO
-- */
--
--void xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
--xmlExternalEntityLoader
-- xmlGetExternalEntityLoader(void);
--xmlParserInputPtr
-- xmlLoadExternalEntity (const char *URL,
-- const char *ID,
-- xmlParserCtxtPtr context);
--
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* __XML_PARSER_H__ */
--
-diff -Nru libxml2-2.3.0/include/libxml/parserInternals.h libxml2-2.3.0.new/include/libxml/parserInternals.h
---- libxml2-2.3.0/include/libxml/parserInternals.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/parserInternals.h Thu Jan 1 01:00:00 1970
-@@ -1,314 +0,0 @@
--/*
-- * parserInternals.h : internals routines exported by the parser.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- *
-- * 14 Nov 2000 ht - truncated declaration of xmlParseElementChildrenContentDecl
-- * for VMS
-- *
-- */
--
--#ifndef __XML_PARSER_INTERNALS_H__
--#define __XML_PARSER_INTERNALS_H__
--
--#include <libxml/parser.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
-- /*
-- * Identifiers can be longer, but this will be more costly
-- * at runtime.
-- */
--#define XML_MAX_NAMELEN 100
--
--/*
-- * The parser tries to always have that amount of input ready
-- * one of the point is providing context when reporting errors
-- */
--#define INPUT_CHUNK 250
--
--/************************************************************************
-- * *
-- * UNICODE version of the macros. *
-- * *
-- ************************************************************************/
--/*
-- * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-- * | [#x10000-#x10FFFF]
-- * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
-- */
--#define IS_CHAR(c) \
-- (((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) || \
-- (((c) >= 0x20) && ((c) <= 0xD7FF)) || \
-- (((c) >= 0xE000) && ((c) <= 0xFFFD)) || \
-- (((c) >= 0x10000) && ((c) <= 0x10FFFF)))
--
--/*
-- * [3] S ::= (#x20 | #x9 | #xD | #xA)+
-- */
--#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
-- ((c) == 0x0D))
--
--/*
-- * [85] BaseChar ::= ... long list see REC ...
-- */
--#define IS_BASECHAR(c) xmlIsBaseChar(c)
--
--/*
-- * [88] Digit ::= ... long list see REC ...
-- */
--#define IS_DIGIT(c) xmlIsDigit(c)
--
--/*
-- * [87] CombiningChar ::= ... long list see REC ...
-- */
--#define IS_COMBINING(c) xmlIsCombining(c)
--
--/*
-- * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
-- * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
-- * [#x309D-#x309E] | [#x30FC-#x30FE]
-- */
--#define IS_EXTENDER(c) xmlIsExtender(c)
--
--/*
-- * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
-- */
--#define IS_IDEOGRAPHIC(c) xmlIsIdeographic(c)
--
--/*
-- * [84] Letter ::= BaseChar | Ideographic
-- */
--#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
--
--
--/*
-- * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-- */
--#define IS_PUBIDCHAR(c) xmlIsPubidChar(c)
--
--#define SKIP_EOL(p) \
-- if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; } \
-- if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
--
--#define MOVETO_ENDTAG(p) \
-- while ((*p) && (*(p) != '>')) (p)++
--
--#define MOVETO_STARTTAG(p) \
-- while ((*p) && (*(p) != '<')) (p)++
--
--/**
-- * Global vaiables affecting the default parser behaviour.
-- */
--
--LIBXML_DLL_IMPORT extern int xmlParserDebugEntities;
--LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
--LIBXML_DLL_IMPORT extern int xmlParserDebugEntities;
--LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
--LIBXML_DLL_IMPORT extern int xmlDoValidityCheckingDefaultValue;
--LIBXML_DLL_IMPORT extern int xmlLoadExtDtdDefaultValue;
--LIBXML_DLL_IMPORT extern int xmlPedanticParserDefaultValue;
--LIBXML_DLL_IMPORT extern int xmlKeepBlanksDefaultValue;
--LIBXML_DLL_IMPORT extern xmlChar xmlStringText[];
--LIBXML_DLL_IMPORT extern xmlChar xmlStringTextNoenc[];
--LIBXML_DLL_IMPORT extern xmlChar xmlStringComment[];
--
--/*
-- * Function to finish teh work of the macros where needed
-- */
--int xmlIsBaseChar (int c);
--int xmlIsBlank (int c);
--int xmlIsPubidChar (int c);
--int xmlIsLetter (int c);
--int xmlIsDigit (int c);
--int xmlIsIdeographic(int c);
--int xmlIsCombining (int c);
--int xmlIsExtender (int c);
--int xmlIsCombining (int c);
--int xmlIsChar (int c);
--
--/**
-- * Parser context
-- */
--xmlParserCtxtPtr xmlCreateDocParserCtxt (xmlChar *cur);
--xmlParserCtxtPtr xmlCreateFileParserCtxt (const char *filename);
--xmlParserCtxtPtr xmlCreateMemoryParserCtxt(char *buffer,
-- int size);
--xmlParserCtxtPtr xmlNewParserCtxt (void);
--xmlParserCtxtPtr xmlCreateEntityParserCtxt(const xmlChar *URL,
-- const xmlChar *ID,
-- const xmlChar *base);
--int xmlSwitchEncoding (xmlParserCtxtPtr ctxt,
-- xmlCharEncoding enc);
--int xmlSwitchToEncoding (xmlParserCtxtPtr ctxt,
-- xmlCharEncodingHandlerPtr handler);
--void xmlFreeParserCtxt (xmlParserCtxtPtr ctxt);
--
--/**
-- * Entities
-- */
--void xmlHandleEntity (xmlParserCtxtPtr ctxt,
-- xmlEntityPtr entity);
--
--/**
-- * Input Streams
-- */
--xmlParserInputPtr xmlNewEntityInputStream (xmlParserCtxtPtr ctxt,
-- xmlEntityPtr entity);
--void xmlPushInput (xmlParserCtxtPtr ctxt,
-- xmlParserInputPtr input);
--xmlChar xmlPopInput (xmlParserCtxtPtr ctxt);
--void xmlFreeInputStream (xmlParserInputPtr input);
--xmlParserInputPtr xmlNewInputFromFile (xmlParserCtxtPtr ctxt,
-- const char *filename);
--xmlParserInputPtr xmlNewInputStream (xmlParserCtxtPtr ctxt);
--
--/**
-- * Namespaces.
-- */
--xmlChar * xmlSplitQName (xmlParserCtxtPtr ctxt,
-- const xmlChar *name,
-- xmlChar **prefix);
--xmlChar * xmlNamespaceParseNCName (xmlParserCtxtPtr ctxt);
--xmlChar * xmlNamespaceParseQName (xmlParserCtxtPtr ctxt,
-- xmlChar **prefix);
--xmlChar * xmlNamespaceParseNSDef (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseQuotedString (xmlParserCtxtPtr ctxt);
--void xmlParseNamespace (xmlParserCtxtPtr ctxt);
--
--/**
-- * Generic production rules
-- */
--xmlChar * xmlScanName (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseName (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseNmtoken (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseEntityValue (xmlParserCtxtPtr ctxt,
-- xmlChar **orig);
--xmlChar * xmlParseAttValue (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseSystemLiteral (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParsePubidLiteral (xmlParserCtxtPtr ctxt);
--void xmlParseCharData (xmlParserCtxtPtr ctxt,
-- int cdata);
--xmlChar * xmlParseExternalID (xmlParserCtxtPtr ctxt,
-- xmlChar **publicID,
-- int strict);
--void xmlParseComment (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParsePITarget (xmlParserCtxtPtr ctxt);
--void xmlParsePI (xmlParserCtxtPtr ctxt);
--void xmlParseNotationDecl (xmlParserCtxtPtr ctxt);
--void xmlParseEntityDecl (xmlParserCtxtPtr ctxt);
--int xmlParseDefaultDecl (xmlParserCtxtPtr ctxt,
-- xmlChar **value);
--xmlEnumerationPtr xmlParseNotationType (xmlParserCtxtPtr ctxt);
--xmlEnumerationPtr xmlParseEnumerationType (xmlParserCtxtPtr ctxt);
--int xmlParseEnumeratedType (xmlParserCtxtPtr ctxt,
-- xmlEnumerationPtr *tree);
--int xmlParseAttributeType (xmlParserCtxtPtr ctxt,
-- xmlEnumerationPtr *tree);
--void xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt);
--xmlElementContentPtr xmlParseElementMixedContentDecl
-- (xmlParserCtxtPtr ctxt);
--#ifdef VMS
--xmlElementContentPtr xmlParseElementChildrenContentD
-- (xmlParserCtxtPtr ctxt);
--#define xmlParseElementChildrenContentDecl xmlParseElementChildrenContentD
--#else
--xmlElementContentPtr xmlParseElementChildrenContentDecl
-- (xmlParserCtxtPtr ctxt);
--#endif
--int xmlParseElementContentDecl(xmlParserCtxtPtr ctxt,
-- xmlChar *name,
-- xmlElementContentPtr *result);
--int xmlParseElementDecl (xmlParserCtxtPtr ctxt);
--void xmlParseMarkupDecl (xmlParserCtxtPtr ctxt);
--int xmlParseCharRef (xmlParserCtxtPtr ctxt);
--xmlEntityPtr xmlParseEntityRef (xmlParserCtxtPtr ctxt);
--void xmlParseReference (xmlParserCtxtPtr ctxt);
--void xmlParsePEReference (xmlParserCtxtPtr ctxt);
--void xmlParseDocTypeDecl (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseAttribute (xmlParserCtxtPtr ctxt,
-- xmlChar **value);
--xmlChar * xmlParseStartTag (xmlParserCtxtPtr ctxt);
--void xmlParseEndTag (xmlParserCtxtPtr ctxt);
--void xmlParseCDSect (xmlParserCtxtPtr ctxt);
--void xmlParseContent (xmlParserCtxtPtr ctxt);
--void xmlParseElement (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseVersionNum (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseVersionInfo (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseEncName (xmlParserCtxtPtr ctxt);
--xmlChar * xmlParseEncodingDecl (xmlParserCtxtPtr ctxt);
--int xmlParseSDDecl (xmlParserCtxtPtr ctxt);
--void xmlParseXMLDecl (xmlParserCtxtPtr ctxt);
--void xmlParseTextDecl (xmlParserCtxtPtr ctxt);
--void xmlParseMisc (xmlParserCtxtPtr ctxt);
--void xmlParseExternalSubset (xmlParserCtxtPtr ctxt,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--/*
-- * Entities substitution
-- */
--#define XML_SUBSTITUTE_NONE 0
--#define XML_SUBSTITUTE_REF 1
--#define XML_SUBSTITUTE_PEREF 2
--#define XML_SUBSTITUTE_BOTH 3
--
--xmlChar * xmlDecodeEntities (xmlParserCtxtPtr ctxt,
-- int len,
-- int what,
-- xmlChar end,
-- xmlChar end2,
-- xmlChar end3);
--xmlChar * xmlStringDecodeEntities (xmlParserCtxtPtr ctxt,
-- const xmlChar *str,
-- int what,
-- xmlChar end,
-- xmlChar end2,
-- xmlChar end3);
--
--/*
-- * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP
-- */
--int nodePush (xmlParserCtxtPtr ctxt,
-- xmlNodePtr value);
--xmlNodePtr nodePop (xmlParserCtxtPtr ctxt);
--int inputPush (xmlParserCtxtPtr ctxt,
-- xmlParserInputPtr value);
--xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
--
--/*
-- * other comodities shared between parser.c and parserInternals
-- */
--int xmlSkipBlankChars (xmlParserCtxtPtr ctxt);
--int xmlStringCurrentChar (xmlParserCtxtPtr ctxt,
-- const xmlChar *cur,
-- int *len);
--void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
--void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
--xmlChar *namePop (xmlParserCtxtPtr ctxt);
--int xmlCheckLanguageID (const xmlChar *lang);
--
--/*
-- * Really core function shared with HTML parser
-- */
--int xmlCurrentChar (xmlParserCtxtPtr ctxt,
-- int *len);
--int xmlCopyChar (int len,
-- xmlChar *out,
-- int val);
--void xmlNextChar (xmlParserCtxtPtr ctxt);
--void xmlParserInputShrink (xmlParserInputPtr in);
--
--#ifdef LIBXML_HTML_ENABLED
--/*
-- * Actually comes from the HTML parser but launched from the init stuff
-- */
--void htmlInitAutoClose (void);
--#endif
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_PARSER_INTERNALS_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/tree.h libxml2-2.3.0.new/include/libxml/tree.h
---- libxml2-2.3.0/include/libxml/tree.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/tree.h Thu Jan 1 01:00:00 1970
-@@ -1,698 +0,0 @@
--/*
-- * tree.h : describes the structures found in an tree resulting
-- * from an XML parsing.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- *
-- * 14 Nov 2000 ht - added redefinition of xmlBufferWriteChar for VMS
-- *
-- */
--
--#ifndef __XML_TREE_H__
--#define __XML_TREE_H__
--
--#include <stdio.h>
--#include <libxml/xmlversion.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * The different element types carried by an XML tree
-- *
-- * NOTE: This is synchronized with DOM Level1 values
-- * See http://www.w3.org/TR/REC-DOM-Level-1/
-- *
-- * Actually this had diverged a bit, and now XML_DOCUMENT_TYPE_NODE should
-- * be deprecated to use an XML_DTD_NODE.
-- */
--typedef enum {
-- XML_ELEMENT_NODE= 1,
-- XML_ATTRIBUTE_NODE= 2,
-- XML_TEXT_NODE= 3,
-- XML_CDATA_SECTION_NODE= 4,
-- XML_ENTITY_REF_NODE= 5,
-- XML_ENTITY_NODE= 6,
-- XML_PI_NODE= 7,
-- XML_COMMENT_NODE= 8,
-- XML_DOCUMENT_NODE= 9,
-- XML_DOCUMENT_TYPE_NODE= 10,
-- XML_DOCUMENT_FRAG_NODE= 11,
-- XML_NOTATION_NODE= 12,
-- XML_HTML_DOCUMENT_NODE= 13,
-- XML_DTD_NODE= 14,
-- XML_ELEMENT_DECL= 15,
-- XML_ATTRIBUTE_DECL= 16,
-- XML_ENTITY_DECL= 17,
-- XML_NAMESPACE_DECL= 18,
-- XML_XINCLUDE_START= 19,
-- XML_XINCLUDE_END= 20
--#ifdef LIBXML_SGML_ENABLED
-- ,XML_SGML_DOCUMENT_NODE= 21
--#endif
--} xmlElementType;
--
--/*
-- * Size of an internal character representation.
-- *
-- * We use 8bit chars internal representation for memory efficiency,
-- * Note that with 8 bits wide xmlChars one can still use UTF-8 to handle
-- * correctly non ISO-Latin input.
-- */
--
--typedef unsigned char xmlChar;
--
--#ifndef WIN32
--#ifndef CHAR
--#define CHAR xmlChar
--#endif
--#endif
--
--#define BAD_CAST (xmlChar *)
--
--/*
-- * a DTD Notation definition
-- */
--
--typedef struct _xmlNotation xmlNotation;
--typedef xmlNotation *xmlNotationPtr;
--struct _xmlNotation {
-- const xmlChar *name; /* Notation name */
-- const xmlChar *PublicID; /* Public identifier, if any */
-- const xmlChar *SystemID; /* System identifier, if any */
--};
--
--/*
-- * a DTD Attribute definition
-- */
--
--typedef enum {
-- XML_ATTRIBUTE_CDATA = 1,
-- XML_ATTRIBUTE_ID,
-- XML_ATTRIBUTE_IDREF ,
-- XML_ATTRIBUTE_IDREFS,
-- XML_ATTRIBUTE_ENTITY,
-- XML_ATTRIBUTE_ENTITIES,
-- XML_ATTRIBUTE_NMTOKEN,
-- XML_ATTRIBUTE_NMTOKENS,
-- XML_ATTRIBUTE_ENUMERATION,
-- XML_ATTRIBUTE_NOTATION
--} xmlAttributeType;
--
--typedef enum {
-- XML_ATTRIBUTE_NONE = 1,
-- XML_ATTRIBUTE_REQUIRED,
-- XML_ATTRIBUTE_IMPLIED,
-- XML_ATTRIBUTE_FIXED
--} xmlAttributeDefault;
--
--typedef struct _xmlEnumeration xmlEnumeration;
--typedef xmlEnumeration *xmlEnumerationPtr;
--struct _xmlEnumeration {
-- struct _xmlEnumeration *next; /* next one */
-- const xmlChar *name; /* Enumeration name */
--};
--
--typedef struct _xmlAttribute xmlAttribute;
--typedef xmlAttribute *xmlAttributePtr;
--struct _xmlAttribute {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* XML_ATTRIBUTE_DECL, must be second ! */
-- const xmlChar *name; /* Attribute name */
-- struct _xmlNode *children; /* NULL */
-- struct _xmlNode *last; /* NULL */
-- struct _xmlDtd *parent; /* -> DTD */
-- struct _xmlNode *next; /* next sibling link */
-- struct _xmlNode *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* the containing document */
--
-- struct _xmlAttribute *nexth; /* next in hash table */
-- xmlAttributeType atype; /* The attribute type */
-- xmlAttributeDefault def; /* the default */
-- const xmlChar *defaultValue; /* or the default value */
-- xmlEnumerationPtr tree; /* or the enumeration tree if any */
-- const xmlChar *prefix; /* the namespace prefix if any */
-- const xmlChar *elem; /* Element holding the attribute */
--};
--
--/*
-- * a DTD Element definition.
-- */
--typedef enum {
-- XML_ELEMENT_CONTENT_PCDATA = 1,
-- XML_ELEMENT_CONTENT_ELEMENT,
-- XML_ELEMENT_CONTENT_SEQ,
-- XML_ELEMENT_CONTENT_OR
--} xmlElementContentType;
--
--typedef enum {
-- XML_ELEMENT_CONTENT_ONCE = 1,
-- XML_ELEMENT_CONTENT_OPT,
-- XML_ELEMENT_CONTENT_MULT,
-- XML_ELEMENT_CONTENT_PLUS
--} xmlElementContentOccur;
--
--typedef struct _xmlElementContent xmlElementContent;
--typedef xmlElementContent *xmlElementContentPtr;
--struct _xmlElementContent {
-- xmlElementContentType type; /* PCDATA, ELEMENT, SEQ or OR */
-- xmlElementContentOccur ocur; /* ONCE, OPT, MULT or PLUS */
-- const xmlChar *name; /* Element name */
-- struct _xmlElementContent *c1; /* first child */
-- struct _xmlElementContent *c2; /* second child */
--};
--
--typedef enum {
-- XML_ELEMENT_TYPE_EMPTY = 1,
-- XML_ELEMENT_TYPE_ANY,
-- XML_ELEMENT_TYPE_MIXED,
-- XML_ELEMENT_TYPE_ELEMENT
--} xmlElementTypeVal;
--
--typedef struct _xmlElement xmlElement;
--typedef xmlElement *xmlElementPtr;
--struct _xmlElement {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* XML_ELEMENT_DECL, must be second ! */
-- const xmlChar *name; /* Element name */
-- struct _xmlNode *children; /* NULL */
-- struct _xmlNode *last; /* NULL */
-- struct _xmlDtd *parent; /* -> DTD */
-- struct _xmlNode *next; /* next sibling link */
-- struct _xmlNode *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* the containing document */
--
-- xmlElementTypeVal etype; /* The type */
-- xmlElementContentPtr content; /* the allowed element content */
-- xmlAttributePtr attributes; /* List of the declared attributes */
-- const xmlChar *prefix; /* the namespace prefix if any */
--};
--
--/*
-- * An XML namespace.
-- * Note that prefix == NULL is valid, it defines the default namespace
-- * within the subtree (until overriden).
-- *
-- * XML_GLOBAL_NAMESPACE is now deprecated for good
-- * xmlNsType is unified with xmlElementType
-- */
--
--#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
--typedef xmlElementType xmlNsType;
--
--typedef struct _xmlNs xmlNs;
--typedef xmlNs *xmlNsPtr;
--struct _xmlNs {
-- struct _xmlNs *next; /* next Ns link for this node */
-- xmlNsType type; /* global or local */
-- const xmlChar *href; /* URL for the namespace */
-- const xmlChar *prefix; /* prefix for the namespace */
--};
--
--/*
-- * An XML DtD, as defined by <!DOCTYPE.
-- */
--typedef struct _xmlDtd xmlDtd;
--typedef xmlDtd *xmlDtdPtr;
--struct _xmlDtd {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* XML_DTD_NODE, must be second ! */
-- const xmlChar *name; /* Name of the DTD */
-- struct _xmlNode *children; /* the value of the property link */
-- struct _xmlNode *last; /* last child link */
-- struct _xmlDoc *parent; /* child->parent link */
-- struct _xmlNode *next; /* next sibling link */
-- struct _xmlNode *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* the containing document */
--
-- /* End of common part */
-- void *notations; /* Hash table for notations if any */
-- void *elements; /* Hash table for elements if any */
-- void *attributes; /* Hash table for attributes if any */
-- void *entities; /* Hash table for entities if any */
-- const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */
-- const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */
-- void *pentities; /* Hash table for param entities if any */
--};
--
--/*
-- * A attribute of an XML node.
-- */
--typedef struct _xmlAttr xmlAttr;
--typedef xmlAttr *xmlAttrPtr;
--struct _xmlAttr {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */
-- const xmlChar *name; /* the name of the property */
-- struct _xmlNode *children; /* the value of the property */
-- struct _xmlNode *last; /* NULL */
-- struct _xmlNode *parent; /* child->parent link */
-- struct _xmlAttr *next; /* next sibling link */
-- struct _xmlAttr *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* the containing document */
-- xmlNs *ns; /* pointer to the associated namespace */
-- xmlAttributeType atype; /* the attribute type if validating */
--};
--
--/*
-- * An XML ID instance.
-- */
--
--typedef struct _xmlID xmlID;
--typedef xmlID *xmlIDPtr;
--struct _xmlID {
-- struct _xmlID *next; /* next ID */
-- const xmlChar *value; /* The ID name */
-- xmlAttrPtr attr; /* The attribut holding it */
--};
--
--/*
-- * An XML IDREF instance.
-- */
--
--typedef struct _xmlRef xmlRef;
--typedef xmlRef *xmlRefPtr;
--struct _xmlRef {
-- struct _xmlRef *next; /* next Ref */
-- const xmlChar *value; /* The Ref name */
-- xmlAttrPtr attr; /* The attribut holding it */
--};
--
--/*
-- * A buffer structure
-- */
--
--typedef enum {
-- XML_BUFFER_ALLOC_DOUBLEIT,
-- XML_BUFFER_ALLOC_EXACT
--} xmlBufferAllocationScheme;
--
--typedef struct _xmlBuffer xmlBuffer;
--typedef xmlBuffer *xmlBufferPtr;
--struct _xmlBuffer {
-- xmlChar *content; /* The buffer content UTF8 */
-- unsigned int use; /* The buffer size used */
-- unsigned int size; /* The buffer size */
-- xmlBufferAllocationScheme alloc; /* The realloc method */
--};
--
--/*
-- * A node in an XML tree.
-- */
--typedef struct _xmlNode xmlNode;
--typedef xmlNode *xmlNodePtr;
--struct _xmlNode {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* type number, must be second ! */
-- const xmlChar *name; /* the name of the node, or the entity */
-- struct _xmlNode *children; /* parent->childs link */
-- struct _xmlNode *last; /* last child link */
-- struct _xmlNode *parent; /* child->parent link */
-- struct _xmlNode *next; /* next sibling link */
-- struct _xmlNode *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* the containing document */
-- xmlNs *ns; /* pointer to the associated namespace */
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlChar *content; /* the content */
--#else
-- xmlBufferPtr content; /* the content in a buffer */
--#endif
--
-- /* End of common part */
-- struct _xmlAttr *properties;/* properties list */
-- xmlNs *nsDef; /* namespace definitions on this node */
--};
--
--/*
-- * An XML document.
-- */
--typedef struct _xmlDoc xmlDoc;
--typedef xmlDoc *xmlDocPtr;
--struct _xmlDoc {
--#ifndef XML_WITHOUT_CORBA
-- void *_private; /* for Corba, must be first ! */
--#endif
-- xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */
-- char *name; /* name/filename/URI of the document */
-- struct _xmlNode *children; /* the document tree */
-- struct _xmlNode *last; /* last child link */
-- struct _xmlNode *parent; /* child->parent link */
-- struct _xmlNode *next; /* next sibling link */
-- struct _xmlNode *prev; /* previous sibling link */
-- struct _xmlDoc *doc; /* autoreference to itself */
--
-- /* End of common part */
-- int compression;/* level of zlib compression */
-- int standalone; /* standalone document (no external refs) */
-- struct _xmlDtd *intSubset; /* the document internal subset */
-- struct _xmlDtd *extSubset; /* the document external subset */
-- struct _xmlNs *oldNs; /* Global namespace, the old way */
-- const xmlChar *version; /* the XML version string */
-- const xmlChar *encoding; /* external initial encoding, if any */
-- void *ids; /* Hash table for ID attributes if any */
-- void *refs; /* Hash table for IDREFs attributes if any */
-- const xmlChar *URL; /* The URI for that document */
-- int charset; /* encoding of the in-memory content
-- actually an xmlCharEncoding */
--};
--
--/*
-- * Compatibility naming layer with libxml1
-- */
--#ifndef xmlChildrenNode
--#define xmlChildrenNode children
--#define xmlRootNode children
--#endif
--
--/*
-- * Variables.
-- */
--LIBXML_DLL_IMPORT extern xmlNsPtr baseDTD;
--LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
--LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
--LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
--LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as <empty></empty> */
--
--/*
-- * Handling Buffers.
-- */
--
--xmlBufferPtr xmlBufferCreate (void);
--xmlBufferPtr xmlBufferCreateSize (size_t size);
--void xmlBufferFree (xmlBufferPtr buf);
--int xmlBufferDump (FILE *file,
-- xmlBufferPtr buf);
--void xmlBufferAdd (xmlBufferPtr buf,
-- const xmlChar *str,
-- int len);
--void xmlBufferAddHead (xmlBufferPtr buf,
-- const xmlChar *str,
-- int len);
--void xmlBufferCat (xmlBufferPtr buf,
-- const xmlChar *str);
--void xmlBufferCCat (xmlBufferPtr buf,
-- const char *str);
--int xmlBufferShrink (xmlBufferPtr buf,
-- unsigned int len);
--int xmlBufferGrow (xmlBufferPtr buf,
-- unsigned int len);
--void xmlBufferEmpty (xmlBufferPtr buf);
--const xmlChar* xmlBufferContent (const xmlBufferPtr buf);
--int xmlBufferUse (const xmlBufferPtr buf);
--void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
-- xmlBufferAllocationScheme scheme);
--int xmlBufferLength (const xmlBufferPtr buf);
--
--/*
-- * Creating/freeing new structures
-- */
--xmlDtdPtr xmlCreateIntSubset (xmlDocPtr doc,
-- const xmlChar *name,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--xmlDtdPtr xmlNewDtd (xmlDocPtr doc,
-- const xmlChar *name,
-- const xmlChar *ExternalID,
-- const xmlChar *SystemID);
--xmlDtdPtr xmlGetIntSubset (xmlDocPtr doc);
--void xmlFreeDtd (xmlDtdPtr cur);
--xmlNsPtr xmlNewGlobalNs (xmlDocPtr doc,
-- const xmlChar *href,
-- const xmlChar *prefix);
--xmlNsPtr xmlNewNs (xmlNodePtr node,
-- const xmlChar *href,
-- const xmlChar *prefix);
--void xmlFreeNs (xmlNsPtr cur);
--xmlDocPtr xmlNewDoc (const xmlChar *version);
--void xmlFreeDoc (xmlDocPtr cur);
--xmlAttrPtr xmlNewDocProp (xmlDocPtr doc,
-- const xmlChar *name,
-- const xmlChar *value);
--xmlAttrPtr xmlNewProp (xmlNodePtr node,
-- const xmlChar *name,
-- const xmlChar *value);
--xmlAttrPtr xmlNewNsProp (xmlNodePtr node,
-- xmlNsPtr ns,
-- const xmlChar *name,
-- const xmlChar *value);
--void xmlFreePropList (xmlAttrPtr cur);
--void xmlFreeProp (xmlAttrPtr cur);
--xmlAttrPtr xmlCopyProp (xmlNodePtr target,
-- xmlAttrPtr cur);
--xmlAttrPtr xmlCopyPropList (xmlNodePtr target,
-- xmlAttrPtr cur);
--xmlDtdPtr xmlCopyDtd (xmlDtdPtr dtd);
--xmlDocPtr xmlCopyDoc (xmlDocPtr doc,
-- int recursive);
--
--/*
-- * Creating new nodes
-- */
--xmlNodePtr xmlNewDocNode (xmlDocPtr doc,
-- xmlNsPtr ns,
-- const xmlChar *name,
-- const xmlChar *content);
--xmlNodePtr xmlNewDocRawNode (xmlDocPtr doc,
-- xmlNsPtr ns,
-- const xmlChar *name,
-- const xmlChar *content);
--xmlNodePtr xmlNewNode (xmlNsPtr ns,
-- const xmlChar *name);
--xmlNodePtr xmlNewChild (xmlNodePtr parent,
-- xmlNsPtr ns,
-- const xmlChar *name,
-- const xmlChar *content);
--xmlNodePtr xmlNewTextChild (xmlNodePtr parent,
-- xmlNsPtr ns,
-- const xmlChar *name,
-- const xmlChar *content);
--xmlNodePtr xmlNewDocText (xmlDocPtr doc,
-- const xmlChar *content);
--xmlNodePtr xmlNewText (const xmlChar *content);
--xmlNodePtr xmlNewPI (const xmlChar *name,
-- const xmlChar *content);
--xmlNodePtr xmlNewDocTextLen (xmlDocPtr doc,
-- const xmlChar *content,
-- int len);
--xmlNodePtr xmlNewTextLen (const xmlChar *content,
-- int len);
--xmlNodePtr xmlNewDocComment (xmlDocPtr doc,
-- const xmlChar *content);
--xmlNodePtr xmlNewComment (const xmlChar *content);
--xmlNodePtr xmlNewCDataBlock (xmlDocPtr doc,
-- const xmlChar *content,
-- int len);
--xmlNodePtr xmlNewCharRef (xmlDocPtr doc,
-- const xmlChar *name);
--xmlNodePtr xmlNewReference (xmlDocPtr doc,
-- const xmlChar *name);
--xmlNodePtr xmlCopyNode (xmlNodePtr node,
-- int recursive);
--xmlNodePtr xmlCopyNodeList (xmlNodePtr node);
--xmlNodePtr xmlNewDocFragment (xmlDocPtr doc);
--
--/*
-- * Navigating
-- */
--xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc);
--xmlNodePtr xmlGetLastChild (xmlNodePtr parent);
--int xmlNodeIsText (xmlNodePtr node);
--int xmlIsBlankNode (xmlNodePtr node);
--
--/*
-- * Changing the structure
-- */
--xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc,
-- xmlNodePtr root);
--void xmlNodeSetName (xmlNodePtr cur,
-- const xmlChar *name);
--xmlNodePtr xmlAddChild (xmlNodePtr parent,
-- xmlNodePtr cur);
--xmlNodePtr xmlAddChildList (xmlNodePtr parent,
-- xmlNodePtr cur);
--xmlNodePtr xmlReplaceNode (xmlNodePtr old,
-- xmlNodePtr cur);
--xmlNodePtr xmlAddSibling (xmlNodePtr cur,
-- xmlNodePtr elem);
--xmlNodePtr xmlAddPrevSibling (xmlNodePtr cur,
-- xmlNodePtr elem);
--xmlNodePtr xmlAddNextSibling (xmlNodePtr cur,
-- xmlNodePtr elem);
--void xmlUnlinkNode (xmlNodePtr cur);
--xmlNodePtr xmlTextMerge (xmlNodePtr first,
-- xmlNodePtr second);
--void xmlTextConcat (xmlNodePtr node,
-- const xmlChar *content,
-- int len);
--void xmlFreeNodeList (xmlNodePtr cur);
--void xmlFreeNode (xmlNodePtr cur);
--void xmlSetTreeDoc (xmlNodePtr tree,
-- xmlDocPtr doc);
--void xmlSetListDoc (xmlNodePtr list,
-- xmlDocPtr doc);
--
--/*
-- * Namespaces
-- */
--xmlNsPtr xmlSearchNs (xmlDocPtr doc,
-- xmlNodePtr node,
-- const xmlChar *nameSpace);
--xmlNsPtr xmlSearchNsByHref (xmlDocPtr doc,
-- xmlNodePtr node,
-- const xmlChar *href);
--xmlNsPtr * xmlGetNsList (xmlDocPtr doc,
-- xmlNodePtr node);
--void xmlSetNs (xmlNodePtr node,
-- xmlNsPtr ns);
--xmlNsPtr xmlCopyNamespace (xmlNsPtr cur);
--xmlNsPtr xmlCopyNamespaceList (xmlNsPtr cur);
--
--/*
-- * Changing the content.
-- */
--xmlAttrPtr xmlSetProp (xmlNodePtr node,
-- const xmlChar *name,
-- const xmlChar *value);
--xmlChar * xmlGetProp (xmlNodePtr node,
-- const xmlChar *name);
--xmlAttrPtr xmlHasProp (xmlNodePtr node,
-- const xmlChar *name);
--xmlAttrPtr xmlSetNsProp (xmlNodePtr node,
-- xmlNsPtr ns,
-- const xmlChar *name,
-- const xmlChar *value);
--xmlChar * xmlGetNsProp (xmlNodePtr node,
-- const xmlChar *name,
-- const xmlChar *nameSpace);
--xmlNodePtr xmlStringGetNodeList (xmlDocPtr doc,
-- const xmlChar *value);
--xmlNodePtr xmlStringLenGetNodeList (xmlDocPtr doc,
-- const xmlChar *value,
-- int len);
--xmlChar * xmlNodeListGetString (xmlDocPtr doc,
-- xmlNodePtr list,
-- int inLine);
--xmlChar * xmlNodeListGetRawString (xmlDocPtr doc,
-- xmlNodePtr list,
-- int inLine);
--void xmlNodeSetContent (xmlNodePtr cur,
-- const xmlChar *content);
--void xmlNodeSetContentLen (xmlNodePtr cur,
-- const xmlChar *content,
-- int len);
--void xmlNodeAddContent (xmlNodePtr cur,
-- const xmlChar *content);
--void xmlNodeAddContentLen (xmlNodePtr cur,
-- const xmlChar *content,
-- int len);
--xmlChar * xmlNodeGetContent (xmlNodePtr cur);
--xmlChar * xmlNodeGetLang (xmlNodePtr cur);
--void xmlNodeSetLang (xmlNodePtr cur,
-- const xmlChar *lang);
--int xmlNodeGetSpacePreserve (xmlNodePtr cur);
--void xmlNodeSetSpacePreserve (xmlNodePtr cur, int
-- val);
--xmlChar * xmlNodeGetBase (xmlDocPtr doc,
-- xmlNodePtr cur);
--void xmlNodeSetBase (xmlNodePtr cur,
-- xmlChar *uri);
--
--/*
-- * Removing content.
-- */
--int xmlRemoveProp (xmlAttrPtr attr);
--int xmlRemoveNode (xmlNodePtr node); /* TODO */
--
--/*
-- * Internal, don't use
-- */
--#ifdef VMS
--void xmlBufferWriteXmlCHAR (xmlBufferPtr buf,
-- const xmlChar *string);
--#define xmlBufferWriteCHAR xmlBufferWriteXmlCHAR
--#else
--void xmlBufferWriteCHAR (xmlBufferPtr buf,
-- const xmlChar *string);
--#endif
--void xmlBufferWriteChar (xmlBufferPtr buf,
-- const char *string);
--void xmlBufferWriteQuotedString(xmlBufferPtr buf,
-- const xmlChar *string);
--
--/*
-- * Namespace handling
-- */
--int xmlReconciliateNs (xmlDocPtr doc,
-- xmlNodePtr tree);
--
--/*
-- * Saving
-- */
--void xmlDocDumpFormatMemory (xmlDocPtr cur,
-- xmlChar**mem,
-- int *size,
-- int format);
--void xmlDocDumpMemory (xmlDocPtr cur,
-- xmlChar**mem,
-- int *size);
--void xmlDocDumpMemoryEnc (xmlDocPtr out_doc,
-- xmlChar **doc_txt_ptr,
-- int * doc_txt_len,
-- const char *txt_encoding);
--void xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
-- xmlChar **doc_txt_ptr,
-- int * doc_txt_len,
-- const char *txt_encoding,
-- int format);
--int xmlDocDump (FILE *f,
-- xmlDocPtr cur);
--void xmlElemDump (FILE *f,
-- xmlDocPtr doc,
-- xmlNodePtr cur);
--int xmlSaveFile (const char *filename,
-- xmlDocPtr cur);
--void xmlNodeDump (xmlBufferPtr buf,
-- xmlDocPtr doc,
-- xmlNodePtr cur,
-- int level,
-- int format);
--
--/* This one is exported from xmlIO.h
--
--int xmlSaveFileTo (xmlOutputBuffer *buf,
-- xmlDocPtr cur,
-- const char *encoding);
-- */
--
--int xmlSaveFileEnc (const char *filename,
-- xmlDocPtr cur,
-- const char *encoding);
--
--/*
-- * Compression
-- */
--int xmlGetDocCompressMode (xmlDocPtr doc);
--void xmlSetDocCompressMode (xmlDocPtr doc,
-- int mode);
--int xmlGetCompressMode (void);
--void xmlSetCompressMode (int mode);
--
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* __XML_TREE_H__ */
--
-diff -Nru libxml2-2.3.0/include/libxml/uri.h libxml2-2.3.0.new/include/libxml/uri.h
---- libxml2-2.3.0/include/libxml/uri.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/uri.h Thu Jan 1 01:00:00 1970
-@@ -1,61 +0,0 @@
--/**
-- * uri.c: library of generic URI related routines
-- *
-- * Reference: RFC 2396
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_URI_H__
--#define __XML_URI_H__
--
--#include <libxml/tree.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/**
-- *
-- */
--typedef struct _xmlURI xmlURI;
--typedef xmlURI *xmlURIPtr;
--struct _xmlURI {
-- char *scheme;
-- char *opaque;
-- char *authority;
-- char *server;
-- char *user;
-- int port;
-- char *path;
-- char *query;
-- char *fragment;
--};
--
--/*
-- * This function is in tree.h:
-- * xmlChar * xmlNodeGetBase (xmlDocPtr doc,
-- * xmlNodePtr cur);
-- */
--xmlURIPtr xmlCreateURI (void);
--xmlChar * xmlBuildURI (const xmlChar *URI,
-- const xmlChar *base);
--xmlURIPtr xmlParseURI (const char *URI);
--int xmlParseURIReference (xmlURIPtr uri,
-- const char *str);
--xmlChar * xmlSaveUri (xmlURIPtr uri);
--void xmlPrintURI (FILE *stream,
-- xmlURIPtr uri);
--char * xmlURIUnescapeString (const char *str,
-- int len,
-- char *target);
--int xmlNormalizeURIPath (char *path);
--xmlChar * xmlURIEscape (const xmlChar *str);
--void xmlFreeURI (xmlURIPtr uri);
--
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_URI_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/valid.h libxml2-2.3.0.new/include/libxml/valid.h
---- libxml2-2.3.0/include/libxml/valid.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/valid.h Thu Jan 1 01:00:00 1970
-@@ -1,236 +0,0 @@
--/*
-- * valid.h : interface to the DTD handling and the validity checking
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--
--#ifndef __XML_VALID_H__
--#define __XML_VALID_H__
--
--#include <libxml/tree.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/**
-- * an xmlValidCtxt is used for error reporting when validating
-- */
--
--typedef void (*xmlValidityErrorFunc) (void *ctx, const char *msg, ...);
--typedef void (*xmlValidityWarningFunc) (void *ctx, const char *msg, ...);
--
--typedef struct _xmlValidCtxt xmlValidCtxt;
--typedef xmlValidCtxt *xmlValidCtxtPtr;
--struct _xmlValidCtxt {
-- void *userData; /* user specific data block */
-- xmlValidityErrorFunc error; /* the callback in case of errors */
-- xmlValidityWarningFunc warning; /* the callback in case of warning */
--
-- /* Node analysis stack used when validating within entities */
-- xmlNodePtr node; /* Current parsed Node */
-- int nodeNr; /* Depth of the parsing stack */
-- int nodeMax; /* Max depth of the parsing stack */
-- xmlNodePtr *nodeTab; /* array of nodes */
--
-- int finishDtd; /* finished validating the Dtd ? */
-- xmlDocPtr doc; /* the document */
-- int valid; /* temporary validity check result */
--};
--
--/*
-- * ALl notation declarations are stored in a table
-- * there is one table per DTD
-- */
--
--typedef struct _xmlHashTable xmlNotationTable;
--typedef xmlNotationTable *xmlNotationTablePtr;
--
--/*
-- * ALl element declarations are stored in a table
-- * there is one table per DTD
-- */
--
--typedef struct _xmlHashTable xmlElementTable;
--typedef xmlElementTable *xmlElementTablePtr;
--
--/*
-- * ALl attribute declarations are stored in a table
-- * there is one table per DTD
-- */
--
--typedef struct _xmlHashTable xmlAttributeTable;
--typedef xmlAttributeTable *xmlAttributeTablePtr;
--
--/*
-- * ALl IDs attributes are stored in a table
-- * there is one table per document
-- */
--
--typedef struct _xmlHashTable xmlIDTable;
--typedef xmlIDTable *xmlIDTablePtr;
--
--/*
-- * ALl Refs attributes are stored in a table
-- * there is one table per document
-- */
--
--typedef struct _xmlHashTable xmlRefTable;
--typedef xmlRefTable *xmlRefTablePtr;
--
--/* helper */
--xmlChar * xmlSplitQName2 (const xmlChar *name,
-- xmlChar **prefix);
--
--/* Notation */
--xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
-- xmlDtdPtr dtd,
-- const xmlChar *name,
-- const xmlChar *PublicID,
-- const xmlChar *SystemID);
--xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table);
--void xmlFreeNotationTable(xmlNotationTablePtr table);
--void xmlDumpNotationDecl (xmlBufferPtr buf,
-- xmlNotationPtr nota);
--void xmlDumpNotationTable(xmlBufferPtr buf,
-- xmlNotationTablePtr table);
--
--/* Element Content */
--xmlElementContentPtr xmlNewElementContent (xmlChar *name,
-- xmlElementContentType type);
--xmlElementContentPtr xmlCopyElementContent(xmlElementContentPtr content);
--void xmlFreeElementContent(xmlElementContentPtr cur);
--void xmlSprintfElementContent(char *buf,
-- xmlElementContentPtr content,
-- int glob);
--
--/* Element */
--xmlElementPtr xmlAddElementDecl (xmlValidCtxtPtr ctxt,
-- xmlDtdPtr dtd,
-- const xmlChar *name,
-- xmlElementTypeVal type,
-- xmlElementContentPtr content);
--xmlElementTablePtr xmlCopyElementTable (xmlElementTablePtr table);
--void xmlFreeElementTable (xmlElementTablePtr table);
--void xmlDumpElementTable (xmlBufferPtr buf,
-- xmlElementTablePtr table);
--void xmlDumpElementDecl (xmlBufferPtr buf,
-- xmlElementPtr elem);
--
--/* Enumeration */
--xmlEnumerationPtr xmlCreateEnumeration (xmlChar *name);
--void xmlFreeEnumeration (xmlEnumerationPtr cur);
--xmlEnumerationPtr xmlCopyEnumeration (xmlEnumerationPtr cur);
--
--/* Attribute */
--xmlAttributePtr xmlAddAttributeDecl (xmlValidCtxtPtr ctxt,
-- xmlDtdPtr dtd,
-- const xmlChar *elem,
-- const xmlChar *name,
-- const xmlChar *ns,
-- xmlAttributeType type,
-- xmlAttributeDefault def,
-- const xmlChar *defaultValue,
-- xmlEnumerationPtr tree);
--xmlAttributeTablePtr xmlCopyAttributeTable (xmlAttributeTablePtr table);
--void xmlFreeAttributeTable (xmlAttributeTablePtr table);
--void xmlDumpAttributeTable (xmlBufferPtr buf,
-- xmlAttributeTablePtr table);
--void xmlDumpAttributeDecl (xmlBufferPtr buf,
-- xmlAttributePtr attr);
--
--/* IDs */
--xmlIDPtr xmlAddID (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- const xmlChar *value,
-- xmlAttrPtr attr);
--xmlIDTablePtr xmlCopyIDTable (xmlIDTablePtr table);
--void xmlFreeIDTable (xmlIDTablePtr table);
--xmlAttrPtr xmlGetID (xmlDocPtr doc,
-- const xmlChar *ID);
--int xmlIsID (xmlDocPtr doc,
-- xmlNodePtr elem,
-- xmlAttrPtr attr);
--int xmlRemoveID (xmlDocPtr doc, xmlAttrPtr attr);
--
--/* IDREFs */
--xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- const xmlChar *value,
-- xmlAttrPtr attr);
--xmlRefTablePtr xmlCopyRefTable (xmlRefTablePtr table);
--void xmlFreeRefTable (xmlRefTablePtr table);
--int xmlIsRef (xmlDocPtr doc,
-- xmlNodePtr elem,
-- xmlAttrPtr attr);
--int xmlRemoveRef (xmlDocPtr doc, xmlAttrPtr attr);
--
--/**
-- * The public function calls related to validity checking
-- */
--
--int xmlValidateRoot (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc);
--int xmlValidateElementDecl (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlElementPtr elem);
--xmlChar * xmlValidNormalizeAttributeValue(xmlDocPtr doc,
-- xmlNodePtr elem,
-- const xmlChar *name,
-- const xmlChar *value);
--int xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlAttributePtr attr);
--int xmlValidateAttributeValue(xmlAttributeType type,
-- const xmlChar *value);
--int xmlValidateNotationDecl (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlNotationPtr nota);
--int xmlValidateDtd (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlDtdPtr dtd);
--int xmlValidateDtdFinal (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc);
--int xmlValidateDocument (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc);
--int xmlValidateElement (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlNodePtr elem);
--int xmlValidateOneElement (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlNodePtr elem);
--int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- xmlNodePtr elem,
-- xmlAttrPtr attr,
-- const xmlChar *value);
--int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc);
--int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
-- xmlDocPtr doc,
-- const xmlChar *notationName);
--int xmlIsMixedElement (xmlDocPtr doc,
-- const xmlChar *name);
--xmlAttributePtr xmlGetDtdAttrDesc (xmlDtdPtr dtd,
-- const xmlChar *elem,
-- const xmlChar *name);
--xmlNotationPtr xmlGetDtdNotationDesc (xmlDtdPtr dtd,
-- const xmlChar *name);
--xmlElementPtr xmlGetDtdElementDesc (xmlDtdPtr dtd,
-- const xmlChar *name);
--
--int xmlValidGetValidElements(xmlNode *prev,
-- xmlNode *next,
-- const xmlChar **list,
-- int max);
--int xmlValidGetPotentialChildren(xmlElementContent *ctree,
-- const xmlChar **list,
-- int *len,
-- int max);
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_VALID_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xinclude.h libxml2-2.3.0.new/include/libxml/xinclude.h
---- libxml2-2.3.0/include/libxml/xinclude.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xinclude.h Thu Jan 1 01:00:00 1970
-@@ -1,26 +0,0 @@
--/*
-- * xinclude.c : API to handle XInclude processing
-- *
-- * World Wide Web Consortium Working Draft 26 October 2000
-- * http://www.w3.org/TR/2000/WD-xinclude-20001026
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_XINCLUDE_H__
--#define __XML_XINCLUDE_H__
--
--#include <libxml/tree.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--int xmlXIncludeProcess (xmlDocPtr doc);
--
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_XINCLUDE_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xlink.h libxml2-2.3.0.new/include/libxml/xlink.h
---- libxml2-2.3.0/include/libxml/xlink.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xlink.h Thu Jan 1 01:00:00 1970
-@@ -1,182 +0,0 @@
--/*
-- * xlink.h : interfaces to the hyperlinks detection module
-- *
-- * See Copyright for the status of this software.
-- *
-- * Related specification: http://www.w3.org/TR/xlink
-- * http://www.w3.org/HTML/
-- * and XBase
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_XLINK_H__
--#define __XML_XLINK_H__
--
--#include <libxml/tree.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--/**
-- * Various defines for the various Link properties.
-- *
-- * NOTE: the link detection layer will try to resolve QName expansion
-- * of namespaces, if "foo" is the prefix for "http://foo.com/"
-- * then the link detection layer will expand role="foo:myrole"
-- * to "http://foo.com/:myrole"
-- * NOTE: the link detection layer will expand URI-Refences found on
-- * href attributes by using the base mechanism if found.
-- */
--typedef xmlChar *xlinkHRef;
--typedef xmlChar *xlinkRole;
--typedef xmlChar *xlinkTitle;
--
--typedef enum {
-- XLINK_TYPE_NONE = 0,
-- XLINK_TYPE_SIMPLE,
-- XLINK_TYPE_EXTENDED,
-- XLINK_TYPE_EXTENDED_SET
--} xlinkType;
--
--typedef enum {
-- XLINK_SHOW_NONE = 0,
-- XLINK_SHOW_NEW,
-- XLINK_SHOW_EMBED,
-- XLINK_SHOW_REPLACE
--} xlinkShow;
--
--typedef enum {
-- XLINK_ACTUATE_NONE = 0,
-- XLINK_ACTUATE_AUTO,
-- XLINK_ACTUATE_ONREQUEST
--} xlinkActuate;
--
--/**
-- * xlinkNodeDetectFunc:
-- * @ctx: user data pointer
-- * @node: the node to check
-- *
-- * This is the prototype for the link detection routine
-- * It calls the default link detection callbacks upon link detection.
-- */
--typedef void
--(*xlinkNodeDetectFunc) (void *ctx,
-- xmlNodePtr node);
--
--/**
-- * The link detection module interract with the upper layers using
-- * a set of callback registered at parsing time.
-- */
--
--/**
-- * xlinkSimpleLinkFunk:
-- * @ctx: user data pointer
-- * @node: the node carrying the link
-- * @href: the target of the link
-- * @role: the role string
-- * @title: the link title
-- *
-- * This is the prototype for a simple link detection callback.
-- */
--typedef void
--(*xlinkSimpleLinkFunk) (void *ctx,
-- xmlNodePtr node,
-- const xlinkHRef href,
-- const xlinkRole role,
-- const xlinkTitle title);
--
--/**
-- * xlinkExtendedLinkFunk:
-- * @ctx: user data pointer
-- * @node: the node carrying the link
-- * @nbLocators: the number of locators detected on the link
-- * @hrefs: pointer to the array of locator hrefs
-- * @roles: pointer to the array of locator roles
-- * @nbArcs: the number of arcs detected on the link
-- * @from: pointer to the array of source roles found on the arcs
-- * @to: pointer to the array of target roles found on the arcs
-- * @show: array of values for the show attributes found on the arcs
-- * @actuate: array of values for the actuate attributes found on the arcs
-- * @nbTitles: the number of titles detected on the link
-- * @title: array of titles detected on the link
-- * @langs: array of xml:lang values for the titles
-- *
-- * This is the prototype for a extended link detection callback.
-- */
--typedef void
--(*xlinkExtendedLinkFunk)(void *ctx,
-- xmlNodePtr node,
-- int nbLocators,
-- const xlinkHRef *hrefs,
-- const xlinkRole *roles,
-- int nbArcs,
-- const xlinkRole *from,
-- const xlinkRole *to,
-- xlinkShow *show,
-- xlinkActuate *actuate,
-- int nbTitles,
-- const xlinkTitle *titles,
-- const xmlChar **langs);
--
--/**
-- * xlinkExtendedLinkSetFunk:
-- * @ctx: user data pointer
-- * @node: the node carrying the link
-- * @nbLocators: the number of locators detected on the link
-- * @hrefs: pointer to the array of locator hrefs
-- * @roles: pointer to the array of locator roles
-- * @nbTitles: the number of titles detected on the link
-- * @title: array of titles detected on the link
-- * @langs: array of xml:lang values for the titles
-- *
-- * This is the prototype for a extended link set detection callback.
-- */
--typedef void
--(*xlinkExtendedLinkSetFunk) (void *ctx,
-- xmlNodePtr node,
-- int nbLocators,
-- const xlinkHRef *hrefs,
-- const xlinkRole *roles,
-- int nbTitles,
-- const xlinkTitle *titles,
-- const xmlChar **langs);
--
--/**
-- * This is the structure containing a set of Links detection callbacks
-- *
-- * There is no default xlink callbacks, if one want to get link
-- * recognition activated, those call backs must be provided before parsing.
-- */
--typedef struct _xlinkHandler xlinkHandler;
--typedef xlinkHandler *xlinkHandlerPtr;
--struct _xlinkHandler {
-- xlinkSimpleLinkFunk simple;
-- xlinkExtendedLinkFunk extended;
-- xlinkExtendedLinkSetFunk set;
--};
--
--/**
-- * the default detection routine, can be overriden, they call the default
-- * detection callbacks.
-- */
--
--xlinkNodeDetectFunc xlinkGetDefaultDetect (void);
--void xlinkSetDefaultDetect (xlinkNodeDetectFunc func);
--
--/**
-- * Routines to set/get the default handlers.
-- */
--xlinkHandlerPtr xlinkGetDefaultHandler (void);
--void xlinkSetDefaultHandler (xlinkHandlerPtr handler);
--
--/*
-- * Link detection module itself.
-- */
--xlinkType xlinkIsLink (xmlDocPtr doc,
-- xmlNodePtr node);
--
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_XLINK_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xmlIO.h libxml2-2.3.0.new/include/libxml/xmlIO.h
---- libxml2-2.3.0/include/libxml/xmlIO.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xmlIO.h Thu Jan 1 01:00:00 1970
-@@ -1,178 +0,0 @@
--/*
-- * xmlIO.h : interface for the I/O interfaces used by the parser
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- *
-- * 15 Nov 2000 ht - modified for VMS
-- */
--
--#ifndef __XML_IO_H__
--#define __XML_IO_H__
--
--#include <stdio.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/encoding.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * Those are the functions and datatypes for the parser input
-- * I/O structures.
-- */
--
--typedef int (*xmlInputMatchCallback) (char const *filename);
--typedef void * (*xmlInputOpenCallback) (char const *filename);
--typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
--typedef void (*xmlInputCloseCallback) (void * context);
--
--typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
--typedef xmlParserInputBuffer *xmlParserInputBufferPtr;
--struct _xmlParserInputBuffer {
-- void* context;
-- xmlInputReadCallback readcallback;
-- xmlInputCloseCallback closecallback;
--
-- xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
--
-- xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 */
-- xmlBufferPtr raw; /* if encoder != NULL buffer for raw input */
--};
--
--
--/*
-- * Those are the functions and datatypes for the library output
-- * I/O structures.
-- */
--
--typedef int (*xmlOutputMatchCallback) (char const *filename);
--typedef void * (*xmlOutputOpenCallback) (char const *filename);
--typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
-- int len);
--typedef void (*xmlOutputCloseCallback) (void * context);
--
--typedef struct _xmlOutputBuffer xmlOutputBuffer;
--typedef xmlOutputBuffer *xmlOutputBufferPtr;
--struct _xmlOutputBuffer {
-- void* context;
-- xmlOutputWriteCallback writecallback;
-- xmlOutputCloseCallback closecallback;
--
-- xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
--
-- xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 or ISOLatin */
-- xmlBufferPtr conv; /* if encoder != NULL buffer for output */
-- int written; /* total number of byte written */
--};
--
--/*
-- * Interfaces for input
-- */
--
--void xmlRegisterDefaultInputCallbacks (void);
--xmlParserInputBufferPtr
-- xmlAllocParserInputBuffer (xmlCharEncoding enc);
--
--#ifdef VMS
--xmlParserInputBufferPtr
-- xmlParserInputBufferCreateFname (const char *URI,
-- xmlCharEncoding enc);
--#define xmlParserInputBufferCreateFilename xmlParserInputBufferCreateFname
--#else
--xmlParserInputBufferPtr
-- xmlParserInputBufferCreateFilename (const char *URI,
-- xmlCharEncoding enc);
--#endif
--
--xmlParserInputBufferPtr
-- xmlParserInputBufferCreateFile (FILE *file,
-- xmlCharEncoding enc);
--xmlParserInputBufferPtr
-- xmlParserInputBufferCreateFd (int fd,
-- xmlCharEncoding enc);
--xmlParserInputBufferPtr
-- xmlParserInputBufferCreateMem (const char *mem, int size,
-- xmlCharEncoding enc);
--xmlParserInputBufferPtr
-- xmlParserInputBufferCreateIO (xmlInputReadCallback ioread,
-- xmlInputCloseCallback ioclose,
-- void *ioctx,
-- xmlCharEncoding enc);
--int xmlParserInputBufferRead (xmlParserInputBufferPtr in,
-- int len);
--int xmlParserInputBufferGrow (xmlParserInputBufferPtr in,
-- int len);
--int xmlParserInputBufferPush (xmlParserInputBufferPtr in,
-- int len,
-- const char *buf);
--void xmlFreeParserInputBuffer (xmlParserInputBufferPtr in);
--char * xmlParserGetDirectory (const char *filename);
--
--int xmlRegisterInputCallbacks (xmlInputMatchCallback match,
-- xmlInputOpenCallback open,
-- xmlInputReadCallback read,
-- xmlInputCloseCallback close);
--/*
-- * Interfaces for output
-- */
--void xmlRegisterDefaultOutputCallbacks(void);
--xmlOutputBufferPtr
-- xmlAllocOutputBuffer (xmlCharEncodingHandlerPtr encoder);
--
--xmlOutputBufferPtr
-- xmlOutputBufferCreateFilename (const char *URI,
-- xmlCharEncodingHandlerPtr encoder,
-- int compression);
--
--xmlOutputBufferPtr
-- xmlOutputBufferCreateFile (FILE *file,
-- xmlCharEncodingHandlerPtr encoder);
--
--xmlOutputBufferPtr
-- xmlOutputBufferCreateFd (int fd,
-- xmlCharEncodingHandlerPtr encoder);
--
--xmlOutputBufferPtr
-- xmlOutputBufferCreateIO (xmlOutputWriteCallback iowrite,
-- xmlOutputCloseCallback ioclose,
-- void *ioctx,
-- xmlCharEncodingHandlerPtr encoder);
--
--int xmlOutputBufferWrite (xmlOutputBufferPtr out,
-- int len,
-- const char *buf);
--int xmlOutputBufferWriteString (xmlOutputBufferPtr out,
-- const char *str);
--
--int xmlOutputBufferFlush (xmlOutputBufferPtr out);
--int xmlOutputBufferClose (xmlOutputBufferPtr out);
--
--int xmlRegisterOutputCallbacks (xmlOutputMatchCallback match,
-- xmlOutputOpenCallback open,
-- xmlOutputWriteCallback write,
-- xmlOutputCloseCallback close);
--
--/*
-- * This save function are part of tree.h and HTMLtree.h actually
-- */
--int xmlSaveFileTo (xmlOutputBuffer *buf,
-- xmlDocPtr cur,
-- const char *encoding);
--void xmlNodeDumpOutput (xmlOutputBufferPtr buf,
-- xmlDocPtr doc,
-- xmlNodePtr cur,
-- int level,
-- int format,
-- const char *encoding);
--void htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
-- xmlDocPtr cur,
-- const char *encoding);
--#ifdef __cplusplus
--}
--#endif
--
--#endif /* __XML_IO_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xmlerror.h libxml2-2.3.0.new/include/libxml/xmlerror.h
---- libxml2-2.3.0/include/libxml/xmlerror.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xmlerror.h Thu Jan 1 01:00:00 1970
-@@ -1,180 +0,0 @@
--#ifndef __XML_ERROR_H__
--#define __XML_ERROR_H__
--
--#include <libxml/parser.h>
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--typedef enum {
-- XML_ERR_OK = 0,
-- XML_ERR_INTERNAL_ERROR,
-- XML_ERR_NO_MEMORY,
--
-- XML_ERR_DOCUMENT_START, /* 3 */
-- XML_ERR_DOCUMENT_EMPTY,
-- XML_ERR_DOCUMENT_END,
--
-- XML_ERR_INVALID_HEX_CHARREF, /* 6 */
-- XML_ERR_INVALID_DEC_CHARREF,
-- XML_ERR_INVALID_CHARREF,
-- XML_ERR_INVALID_CHAR,
--
-- XML_ERR_CHARREF_AT_EOF, /* 10 */
-- XML_ERR_CHARREF_IN_PROLOG,
-- XML_ERR_CHARREF_IN_EPILOG,
-- XML_ERR_CHARREF_IN_DTD,
-- XML_ERR_ENTITYREF_AT_EOF,
-- XML_ERR_ENTITYREF_IN_PROLOG,
-- XML_ERR_ENTITYREF_IN_EPILOG,
-- XML_ERR_ENTITYREF_IN_DTD,
-- XML_ERR_PEREF_AT_EOF,
-- XML_ERR_PEREF_IN_PROLOG,
-- XML_ERR_PEREF_IN_EPILOG,
-- XML_ERR_PEREF_IN_INT_SUBSET,
--
-- XML_ERR_ENTITYREF_NO_NAME, /* 22 */
-- XML_ERR_ENTITYREF_SEMICOL_MISSING,
--
-- XML_ERR_PEREF_NO_NAME, /* 24 */
-- XML_ERR_PEREF_SEMICOL_MISSING,
--
-- XML_ERR_UNDECLARED_ENTITY, /* 26 */
-- XML_WAR_UNDECLARED_ENTITY,
-- XML_ERR_UNPARSED_ENTITY,
-- XML_ERR_ENTITY_IS_EXTERNAL,
-- XML_ERR_ENTITY_IS_PARAMETER,
--
-- XML_ERR_UNKNOWN_ENCODING, /* 31 */
-- XML_ERR_UNSUPPORTED_ENCODING,
--
-- XML_ERR_STRING_NOT_STARTED, /* 33 */
-- XML_ERR_STRING_NOT_CLOSED,
-- XML_ERR_NS_DECL_ERROR,
--
-- XML_ERR_ENTITY_NOT_STARTED, /* 36 */
-- XML_ERR_ENTITY_NOT_FINISHED,
--
-- XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
-- XML_ERR_ATTRIBUTE_NOT_STARTED,
-- XML_ERR_ATTRIBUTE_NOT_FINISHED,
-- XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
-- XML_ERR_ATTRIBUTE_REDEFINED,
--
-- XML_ERR_LITERAL_NOT_STARTED, /* 43 */
-- XML_ERR_LITERAL_NOT_FINISHED,
--
-- XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
--
-- XML_ERR_PI_NOT_STARTED, /* 47 */
-- XML_ERR_PI_NOT_FINISHED,
--
-- XML_ERR_NOTATION_NOT_STARTED, /* 49 */
-- XML_ERR_NOTATION_NOT_FINISHED,
--
-- XML_ERR_ATTLIST_NOT_STARTED, /* 51 */
-- XML_ERR_ATTLIST_NOT_FINISHED,
--
-- XML_ERR_MIXED_NOT_STARTED, /* 53 */
-- XML_ERR_MIXED_NOT_FINISHED,
--
-- XML_ERR_ELEMCONTENT_NOT_STARTED, /* 55 */
-- XML_ERR_ELEMCONTENT_NOT_FINISHED,
--
-- XML_ERR_XMLDECL_NOT_STARTED, /* 57 */
-- XML_ERR_XMLDECL_NOT_FINISHED,
--
-- XML_ERR_CONDSEC_NOT_STARTED, /* 59 */
-- XML_ERR_CONDSEC_NOT_FINISHED,
--
-- XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 61 */
--
-- XML_ERR_DOCTYPE_NOT_FINISHED, /* 62 */
--
-- XML_ERR_MISPLACED_CDATA_END, /* 63 */
-- XML_ERR_CDATA_NOT_FINISHED,
--
-- XML_ERR_RESERVED_XML_NAME, /* 65 */
--
-- XML_ERR_SPACE_REQUIRED, /* 66 */
-- XML_ERR_SEPARATOR_REQUIRED,
-- XML_ERR_NMTOKEN_REQUIRED,
-- XML_ERR_NAME_REQUIRED,
-- XML_ERR_PCDATA_REQUIRED,
-- XML_ERR_URI_REQUIRED,
-- XML_ERR_PUBID_REQUIRED,
-- XML_ERR_LT_REQUIRED,
-- XML_ERR_GT_REQUIRED,
-- XML_ERR_LTSLASH_REQUIRED,
-- XML_ERR_EQUAL_REQUIRED,
--
-- XML_ERR_TAG_NAME_MISMATCH, /* 77 */
-- XML_ERR_TAG_NOT_FINISED,
--
-- XML_ERR_STANDALONE_VALUE, /* 79 */
--
-- XML_ERR_ENCODING_NAME, /* 80 */
--
-- XML_ERR_HYPHEN_IN_COMMENT, /* 81 */
--
-- XML_ERR_INVALID_ENCODING, /* 82 */
--
-- XML_ERR_EXT_ENTITY_STANDALONE, /* 83 */
--
-- XML_ERR_CONDSEC_INVALID, /* 84 */
--
-- XML_ERR_VALUE_REQUIRED, /* 85 */
--
-- XML_ERR_NOT_WELL_BALANCED, /* 86 */
-- XML_ERR_EXTRA_CONTENT, /* 87 */
-- XML_ERR_ENTITY_CHAR_ERROR, /* 88 */
-- XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
-- XML_ERR_ENTITY_LOOP, /* 89 */
-- XML_ERR_ENTITY_BOUNDARY, /* 90 */
-- XML_ERR_INVALID_URI, /* 91 */
-- XML_ERR_URI_FRAGMENT /* 92 */
--}xmlParserErrors;
--
--/*
-- * Signature of the function to use when there is an error and
-- * no parsing or validity context available
-- */
--typedef void (*xmlGenericErrorFunc) (void *ctx, const char *msg, ...);
--
--/*
-- * Those are the default error function and associated context to use
-- * when when there is an error and no parsing or validity context available
-- */
--
--LIBXML_DLL_IMPORT extern xmlGenericErrorFunc xmlGenericError;
--LIBXML_DLL_IMPORT extern void *xmlGenericErrorContext;
--
--/*
-- * Use the following function to reset the two previous global variables.
-- */
--void xmlSetGenericErrorFunc (void *ctx,
-- xmlGenericErrorFunc handler);
--
--/*
-- * Default message routines used by SAX and Valid context for error
-- * and warning reporting
-- */
--void xmlParserError (void *ctx,
-- const char *msg,
-- ...);
--void xmlParserWarning (void *ctx,
-- const char *msg,
-- ...);
--void xmlParserValidityError (void *ctx,
-- const char *msg,
-- ...);
--void xmlParserValidityWarning(void *ctx,
-- const char *msg,
-- ...);
--void xmlParserPrintFileInfo (xmlParserInputPtr input);
--void xmlParserPrintFileContext(xmlParserInputPtr input);
--
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_ERROR_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xmlmemory.h libxml2-2.3.0.new/include/libxml/xmlmemory.h
---- libxml2-2.3.0/include/libxml/xmlmemory.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xmlmemory.h Thu Jan 1 01:00:00 1970
-@@ -1,91 +0,0 @@
--/*
-- * xmlmemory.h: interface for the memory allocation debug.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--
--#ifndef _DEBUG_MEMORY_ALLOC_
--#define _DEBUG_MEMORY_ALLOC_
--
--#include <stdio.h>
--#include <libxml/xmlversion.h>
--
--/*
-- * DEBUG_MEMORY_LOCATION should be activated only done when debugging
-- * libxml.
-- */
--/* #define DEBUG_MEMORY_LOCATION */
--
--#ifdef DEBUG
--#ifndef DEBUG_MEMORY
--#define DEBUG_MEMORY
--#endif
--#endif
--
--#ifdef DEBUG_MEMORY_LOCATION
--#define MEM_LIST /* keep a list of all the allocated memory blocks */
--#endif
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * The XML memory wrapper support 4 basic overloadable functions
-- */
--typedef void (*xmlFreeFunc)(void *);
--typedef void *(*xmlMallocFunc)(int);
--typedef void *(*xmlReallocFunc)(void *, int);
--typedef char *(*xmlStrdupFunc)(const char *);
--
--/*
-- * The 4 interfaces used for all memory handling within libxml
-- */
--LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
--LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
--LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
--LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
--
--/*
-- * The way to overload the existing functions
-- */
--int xmlMemSetup (xmlFreeFunc freeFunc,
-- xmlMallocFunc mallocFunc,
-- xmlReallocFunc reallocFunc,
-- xmlStrdupFunc strdupFunc);
--int xmlMemGet (xmlFreeFunc *freeFunc,
-- xmlMallocFunc *mallocFunc,
-- xmlReallocFunc *reallocFunc,
-- xmlStrdupFunc *strdupFunc);
--
--/*
-- * Initialization of the memory layer
-- */
--int xmlInitMemory (void);
--
--/*
-- * Those are specific to the XML debug memory wrapper
-- */
--int xmlMemUsed (void);
--void xmlMemDisplay (FILE *fp);
--void xmlMemShow (FILE *fp, int nr);
--void xmlMemoryDump (void);
--int xmlInitMemory (void);
--
--#ifdef DEBUG_MEMORY_LOCATION
--#define xmlMalloc(x) xmlMallocLoc((x), __FILE__, __LINE__)
--#define xmlRealloc(p, x) xmlReallocLoc((p), (x), __FILE__, __LINE__)
--#define xmlMemStrdup(x) xmlMemStrdupLoc((x), __FILE__, __LINE__)
--
--void * xmlMallocLoc(int size, const char *file, int line);
--void * xmlReallocLoc(void *ptr,int size, const char *file, int line);
--char * xmlMemStrdupLoc(const char *str, const char *file, int line);
--#endif /* DEBUG_MEMORY_LOCATION */
--
--#ifdef __cplusplus
--}
--#endif /* __cplusplus */
--
--#endif /* _DEBUG_MEMORY_ALLOC_ */
--
-diff -Nru libxml2-2.3.0/include/libxml/xmlversion.h libxml2-2.3.0.new/include/libxml/xmlversion.h
---- libxml2-2.3.0/include/libxml/xmlversion.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xmlversion.h Thu Jan 1 01:00:00 1970
-@@ -1,129 +0,0 @@
--/*
-- * xmlversion.h : compile-time version informations for the XML parser.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_VERSION_H__
--#define __XML_VERSION_H__
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * use those to be sure nothing nasty will happen if
-- * your library and includes mismatch
-- */
--extern void xmlCheckVersion(int version);
--#define LIBXML_DOTTED_VERSION "2.3.0"
--#define LIBXML_VERSION 20300
--#define LIBXML_VERSION_STRING "20300"
--#define LIBXML_TEST_VERSION xmlCheckVersion(20300);
--
--/*
-- * Whether the FTP support is configured in
-- */
--#if 1
--#define LIBXML_FTP_ENABLED
--#else
--#define LIBXML_FTP_DISABLED
--#endif
--
--/*
-- * Whether the HTTP support is configured in
-- */
--#if 1
--#define LIBXML_HTTP_ENABLED
--#else
--#define LIBXML_HTTP_DISABLED
--#endif
--
--/*
-- * Whether the HTML support is configured in
-- */
--#if 1
--#define LIBXML_HTML_ENABLED
--#else
--#define LIBXML_HTML_DISABLED
--#endif
--
--/*
-- * Whether the Docbook support is configured in
--#if @WITH_SGML@
--#define LIBXML_SGML_ENABLED
--#else
--#define LIBXML_SGML_DISABLED
--#endif
-- */
--
--/*
-- * Whether XPath is configured in
-- */
--#if 1
--#define LIBXML_XPATH_ENABLED
--#else
--#define LIBXML_XPATH_DISABLED
--#endif
--
--/*
-- * Whether XPointer is configured in
-- */
--#if 1
--#define LIBXML_XPTR_ENABLED
--#else
--#define LIBXML_XPTR_DISABLED
--#endif
--
--/*
-- * Whether XInclude is configured in
-- */
--#if 1
--#define LIBXML_XINCLUDE_ENABLED
--#else
--#define LIBXML_XINCLUDE_DISABLED
--#endif
--
--/*
-- * Whether iconv support is available
-- */
--#ifndef WIN32
--#if 1
--#define LIBXML_ICONV_ENABLED
--#else
--#define LIBXML_ICONV_DISABLED
--#endif
--#endif
--
--/*
-- * Whether Debugging module is configured in
-- */
--#if 1
--#define LIBXML_DEBUG_ENABLED
--#else
--#define LIBXML_DEBUG_DISABLED
--#endif
--
--/*
-- * Whether the memory debugging is configured in
-- */
--#if 0
--#define DEBUG_MEMORY_LOCATION
--#endif
--
--#ifndef LIBXML_DLL_IMPORT
--#if defined(WIN32) && !defined(STATIC)
--#define LIBXML_DLL_IMPORT __declspec(dllimport)
--#else
--#define LIBXML_DLL_IMPORT
--#endif
--#endif
--
--#ifdef __cplusplus
--}
--#endif /* __cplusplus */
--#endif
--
--
-diff -Nru libxml2-2.3.0/include/libxml/xmlversion.h.in libxml2-2.3.0.new/include/libxml/xmlversion.h.in
---- libxml2-2.3.0/include/libxml/xmlversion.h.in Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xmlversion.h.in Thu Jan 1 01:00:00 1970
-@@ -1,129 +0,0 @@
--/*
-- * xmlversion.h : compile-time version informations for the XML parser.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_VERSION_H__
--#define __XML_VERSION_H__
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * use those to be sure nothing nasty will happen if
-- * your library and includes mismatch
-- */
--extern void xmlCheckVersion(int version);
--#define LIBXML_DOTTED_VERSION "@VERSION@"
--#define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
--#define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
--#define LIBXML_TEST_VERSION xmlCheckVersion(@LIBXML_VERSION_NUMBER@);
--
--/*
-- * Whether the FTP support is configured in
-- */
--#if @WITH_FTP@
--#define LIBXML_FTP_ENABLED
--#else
--#define LIBXML_FTP_DISABLED
--#endif
--
--/*
-- * Whether the HTTP support is configured in
-- */
--#if @WITH_HTTP@
--#define LIBXML_HTTP_ENABLED
--#else
--#define LIBXML_HTTP_DISABLED
--#endif
--
--/*
-- * Whether the HTML support is configured in
-- */
--#if @WITH_HTML@
--#define LIBXML_HTML_ENABLED
--#else
--#define LIBXML_HTML_DISABLED
--#endif
--
--/*
-- * Whether the Docbook support is configured in
--#if @WITH_SGML@
--#define LIBXML_SGML_ENABLED
--#else
--#define LIBXML_SGML_DISABLED
--#endif
-- */
--
--/*
-- * Whether XPath is configured in
-- */
--#if @WITH_XPATH@
--#define LIBXML_XPATH_ENABLED
--#else
--#define LIBXML_XPATH_DISABLED
--#endif
--
--/*
-- * Whether XPointer is configured in
-- */
--#if @WITH_XPTR@
--#define LIBXML_XPTR_ENABLED
--#else
--#define LIBXML_XPTR_DISABLED
--#endif
--
--/*
-- * Whether XInclude is configured in
-- */
--#if @WITH_XINCLUDE@
--#define LIBXML_XINCLUDE_ENABLED
--#else
--#define LIBXML_XINCLUDE_DISABLED
--#endif
--
--/*
-- * Whether iconv support is available
-- */
--#ifndef WIN32
--#if @WITH_ICONV@
--#define LIBXML_ICONV_ENABLED
--#else
--#define LIBXML_ICONV_DISABLED
--#endif
--#endif
--
--/*
-- * Whether Debugging module is configured in
-- */
--#if @WITH_DEBUG@
--#define LIBXML_DEBUG_ENABLED
--#else
--#define LIBXML_DEBUG_DISABLED
--#endif
--
--/*
-- * Whether the memory debugging is configured in
-- */
--#if @WITH_MEM_DEBUG@
--#define DEBUG_MEMORY_LOCATION
--#endif
--
--#ifndef LIBXML_DLL_IMPORT
--#if defined(WIN32) && !defined(STATIC)
--#define LIBXML_DLL_IMPORT __declspec(dllimport)
--#else
--#define LIBXML_DLL_IMPORT
--#endif
--#endif
--
--#ifdef __cplusplus
--}
--#endif /* __cplusplus */
--#endif
--
--
-diff -Nru libxml2-2.3.0/include/libxml/xpath.h libxml2-2.3.0.new/include/libxml/xpath.h
---- libxml2-2.3.0/include/libxml/xpath.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xpath.h Thu Jan 1 01:00:00 1970
-@@ -1,278 +0,0 @@
--/*
-- * xpath.c: interface for XML Path Language implementation
-- *
-- * Reference: W3C Working Draft 5 July 1999
-- * http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
-- *
-- * See COPYRIGHT for the status of this software
-- *
-- * Author: Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_XPATH_H__
--#define __XML_XPATH_H__
--
--#include <libxml/tree.h>
--#include <libxml/hash.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--typedef struct _xmlXPathContext xmlXPathContext;
--typedef xmlXPathContext *xmlXPathContextPtr;
--typedef struct _xmlXPathParserContext xmlXPathParserContext;
--typedef xmlXPathParserContext *xmlXPathParserContextPtr;
--
--/**
-- * The set of XPath error codes
-- */
--
--typedef enum {
-- XPATH_EXPRESSION_OK = 0,
-- XPATH_NUMBER_ERROR,
-- XPATH_UNFINISHED_LITERAL_ERROR,
-- XPATH_START_LITERAL_ERROR,
-- XPATH_VARIABLE_REF_ERROR,
-- XPATH_UNDEF_VARIABLE_ERROR,
-- XPATH_INVALID_PREDICATE_ERROR,
-- XPATH_EXPR_ERROR,
-- XPATH_UNCLOSED_ERROR,
-- XPATH_UNKNOWN_FUNC_ERROR,
-- XPATH_INVALID_OPERAND,
-- XPATH_INVALID_TYPE,
-- XPATH_INVALID_ARITY,
-- XPATH_INVALID_CTXT_SIZE,
-- XPATH_INVALID_CTXT_POSITION,
-- XPATH_MEMORY_ERROR,
-- XPTR_SYNTAX_ERROR,
-- XPTR_RESOURCE_ERROR,
-- XPTR_SUB_RESOURCE_ERROR,
-- XPATH_UNDEF_PREFIX_ERROR
--} xmlXPathError;
--
--/*
-- * A node-set (an unordered collection of nodes without duplicates)
-- */
--typedef struct _xmlNodeSet xmlNodeSet;
--typedef xmlNodeSet *xmlNodeSetPtr;
--struct _xmlNodeSet {
-- int nodeNr; /* number of nodes in the set */
-- int nodeMax; /* size of the array as allocated */
-- xmlNodePtr *nodeTab; /* array of nodes in no particular order */
--};
--
--/*
-- * An expression is evaluated to yield an object, which
-- * has one of the following four basic types:
-- * - node-set
-- * - boolean
-- * - number
-- * - string
-- *
-- * @@ XPointer will add more types !
-- */
--
--typedef enum {
-- XPATH_UNDEFINED = 0,
-- XPATH_NODESET = 1,
-- XPATH_BOOLEAN = 2,
-- XPATH_NUMBER = 3,
-- XPATH_STRING = 4,
-- XPATH_POINT = 5,
-- XPATH_RANGE = 6,
-- XPATH_LOCATIONSET = 7,
-- XPATH_USERS = 8,
-- XPATH_XSLT_TREE = 9 /* An XSLT value tree, non modifiable */
--} xmlXPathObjectType;
--
--typedef struct _xmlXPathObject xmlXPathObject;
--typedef xmlXPathObject *xmlXPathObjectPtr;
--struct _xmlXPathObject {
-- xmlXPathObjectType type;
-- xmlNodeSetPtr nodesetval;
-- int boolval;
-- double floatval;
-- xmlChar *stringval;
-- void *user;
-- int index;
-- void *user2;
-- int index2;
--};
--
--/*
-- * A conversion function is associated to a type and used to cast
-- * the new type to primitive values.
-- */
--typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
--
--/*
-- * Extra type: a name and a conversion function.
-- */
--
--typedef struct _xmlXPathType xmlXPathType;
--typedef xmlXPathType *xmlXPathTypePtr;
--struct _xmlXPathType {
-- const xmlChar *name; /* the type name */
-- xmlXPathConvertFunc func; /* the conversion function */
--};
--
--/*
-- * Extra variable: a name and a value.
-- */
--
--typedef struct _xmlXPathVariable xmlXPathVariable;
--typedef xmlXPathVariable *xmlXPathVariablePtr;
--struct _xmlXPathVariable {
-- const xmlChar *name; /* the variable name */
-- xmlXPathObjectPtr value; /* the value */
--};
--
--/*
-- * an evaluation function, the parameters are on the context stack
-- */
--
--typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, int nargs);
--
--/*
-- * Extra function: a name and a evaluation function.
-- */
--
--typedef struct _xmlXPathFunct xmlXPathFunct;
--typedef xmlXPathFunct *xmlXPathFuncPtr;
--struct _xmlXPathFunct {
-- const xmlChar *name; /* the function name */
-- xmlXPathEvalFunc func; /* the evaluation function */
--};
--
--/*
-- * An axis traversal function. To traverse an axis, the engine calls
-- * the first time with cur == NULL and repeat until the function returns
-- * NULL indicating the end of the axis traversal.
-- */
--
--typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
-- xmlXPathObjectPtr cur);
--
--/*
-- * Extra axis: a name and an axis function.
-- */
--
--typedef struct _xmlXPathAxis xmlXPathAxis;
--typedef xmlXPathAxis *xmlXPathAxisPtr;
--struct _xmlXPathAxis {
-- const xmlChar *name; /* the axis name */
-- xmlXPathAxisFunc func; /* the search function */
--};
--
--/*
-- * Expression evaluation occurs with respect to a context.
-- * he context consists of:
-- * - a node (the context node)
-- * - a node list (the context node list)
-- * - a set of variable bindings
-- * - a function library
-- * - the set of namespace declarations in scope for the expression
-- * Following the switch to hash tables, this need to be trimmed up at
-- * the next binary incompatible release.
-- */
--
--struct _xmlXPathContext {
-- xmlDocPtr doc; /* The current document */
-- xmlNodePtr node; /* The current node */
--
-- int nb_variables_unused; /* unused (hash table) */
-- int max_variables_unused; /* unused (hash table) */
-- xmlHashTablePtr varHash; /* Hash table of defined variables */
--
-- int nb_types; /* number of defined types */
-- int max_types; /* max number of types */
-- xmlXPathTypePtr types; /* Array of defined types */
--
-- int nb_funcs_unused; /* unused (hash table) */
-- int max_funcs_unused; /* unused (hash table) */
-- xmlHashTablePtr funcHash; /* Hash table of defined funcs */
--
-- int nb_axis; /* number of defined axis */
-- int max_axis; /* max number of axis */
-- xmlXPathAxisPtr axis; /* Array of defined axis */
--
-- /* the namespace nodes of the context node */
-- xmlNsPtr *namespaces; /* Array of namespaces */
-- int nsNr; /* number of namespace in scope */
-- void *user; /* function to free */
--
-- /* extra variables */
-- int contextSize; /* the context size */
-- int proximityPosition; /* the proximity position */
--
-- /* extra stuff for XPointer */
-- int xptr; /* it this an XPointer context */
-- xmlNodePtr here; /* for here() */
-- xmlNodePtr origin; /* for origin() */
--
-- /* the set of namespace declarations in scope for the expression */
-- xmlHashTablePtr nsHash; /* The namespaces hash table */
-- void *varLookupFunc; /* variable lookup func */
-- void *varLookupData; /* variable lookup data */
--
-- /* Possibility to link in an extra item */
-- void *extra; /* needed for XSLT */
--};
--
--/*
-- * An XPath parser context, it contains pure parsing informations,
-- * an xmlXPathContext, and the stack of objects.
-- */
--struct _xmlXPathParserContext {
-- const xmlChar *cur; /* the current char being parsed */
-- const xmlChar *base; /* the full expression */
--
-- int error; /* error code */
--
-- xmlXPathContextPtr context; /* the evaluation context */
-- xmlXPathObjectPtr value; /* the current value */
-- int valueNr; /* number of values stacked */
-- int valueMax; /* max number of values stacked */
-- xmlXPathObjectPtr *valueTab; /* stack of values */
--};
--
--/*
-- * An XPath function
-- * The arguments (if any) are popped out of the context stack
-- * and the result is pushed on the stack.
-- */
--
--typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
--
--/************************************************************************
-- * *
-- * Public API *
-- * *
-- ************************************************************************/
--
--/**
-- * Evaluation functions.
-- */
--void xmlXPathInit (void);
--xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
--void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
--xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
-- xmlXPathContextPtr ctxt);
--xmlXPathObjectPtr xmlXPathEvalXPtrExpr (const xmlChar *str,
-- xmlXPathContextPtr ctxt);
--void xmlXPathFreeObject (xmlXPathObjectPtr obj);
--xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
-- xmlXPathContextPtr ctxt);
--xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
--void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
--void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
--xmlXPathObjectPtr xmlXPathObjectCopy (xmlXPathObjectPtr val);
--int xmlXPathCmpNodes (xmlNodePtr node1,
-- xmlNodePtr node2);
--
--
--#ifdef __cplusplus
--}
--#endif
--#endif /* ! __XML_XPATH_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xpathInternals.h libxml2-2.3.0.new/include/libxml/xpathInternals.h
---- libxml2-2.3.0/include/libxml/xpathInternals.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xpathInternals.h Thu Jan 1 01:00:00 1970
-@@ -1,229 +0,0 @@
--/*
-- * xpath.c: internal interfaces for XML Path Language implementation
-- * used to build new modules on top of XPath
-- *
-- * See COPYRIGHT for the status of this software
-- *
-- * Author: Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_XPATH_INTERNALS_H__
--#define __XML_XPATH_INTERNALS_H__
--
--#include <libxml/xpath.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/************************************************************************
-- * *
-- * Helpers *
-- * *
-- ************************************************************************/
--
--#define CHECK_ERROR \
-- if (ctxt->error != XPATH_EXPRESSION_OK) return
--
--#define CHECK_ERROR0 \
-- if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
--
--#define XP_ERROR(X) \
-- { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
-- ctxt->error = (X); return; }
--
--#define XP_ERROR0(X) \
-- { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
-- ctxt->error = (X); return(0); }
--
--#define CHECK_TYPE(typeval) \
-- if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
-- XP_ERROR(XPATH_INVALID_TYPE)
--
--#define CHECK_ARITY(x) \
-- if (nargs != (x)) \
-- XP_ERROR(XPATH_INVALID_ARITY);
--
--#define CAST_TO_STRING \
-- if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING)) \
-- xmlXPathStringFunction(ctxt, 1);
--
--#define CAST_TO_NUMBER \
-- if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER)) \
-- xmlXPathNumberFunction(ctxt, 1);
--
--#define CAST_TO_BOOLEAN \
-- if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN)) \
-- xmlXPathBooleanFunction(ctxt, 1);
--
--/*
-- * Varibale Lookup forwarding
-- */
--typedef xmlXPathObjectPtr
-- (*xmlXPathVariableLookupFunc) (void *ctxt,
-- const xmlChar *name,
-- const xmlChar *ns_uri);
--
--void xmlXPathRegisterVariableLookup (xmlXPathContextPtr ctxt,
-- xmlXPathVariableLookupFunc f,
-- void *varCtxt);
--
--/*
-- * Error reporting
-- */
--void xmlXPatherror (xmlXPathParserContextPtr ctxt,
-- const char *file,
-- int line,
-- int no);
--
--void xmlXPathDebugDumpObject (FILE *output,
-- xmlXPathObjectPtr cur,
-- int depth);
--
--/**
-- * Extending a context
-- */
--
--int xmlXPathRegisterNs (xmlXPathContextPtr ctxt,
-- const xmlChar *prefix,
-- const xmlChar *ns_uri);
--const xmlChar * xmlXPathNsLookup (xmlXPathContextPtr ctxt,
-- const xmlChar *ns_uri);
--void xmlXPathRegisteredNsCleanup (xmlXPathContextPtr ctxt);
--
--int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
-- const xmlChar *name,
-- xmlXPathFunction f);
--int xmlXPathRegisterFuncNS (xmlXPathContextPtr ctxt,
-- const xmlChar *name,
-- const xmlChar *ns_uri,
-- xmlXPathFunction f);
--int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
-- const xmlChar *name,
-- xmlXPathObjectPtr value);
--int xmlXPathRegisterVariableNS (xmlXPathContextPtr ctxt,
-- const xmlChar *name,
-- const xmlChar *ns_uri,
-- xmlXPathObjectPtr value);
--xmlXPathFunction xmlXPathFunctionLookup (xmlXPathContextPtr ctxt,
-- const xmlChar *name);
--xmlXPathFunction xmlXPathFunctionLookupNS (xmlXPathContextPtr ctxt,
-- const xmlChar *name,
-- const xmlChar *ns_uri);
--void xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt);
--xmlXPathObjectPtr xmlXPathVariableLookup (xmlXPathContextPtr ctxt,
-- const xmlChar *name);
--xmlXPathObjectPtr xmlXPathVariableLookupNS (xmlXPathContextPtr ctxt,
-- const xmlChar *name,
-- const xmlChar *ns_uri);
--void xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt);
--
--/**
-- * Utilities to extend XPath
-- */
--xmlXPathParserContextPtr
-- xmlXPathNewParserContext (const xmlChar *str,
-- xmlXPathContextPtr ctxt);
--void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
--
--/* TODO: remap to xmlXPathValuePop and Push */
--xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
--int valuePush (xmlXPathParserContextPtr ctxt,
-- xmlXPathObjectPtr value);
--
--xmlXPathObjectPtr xmlXPathNewString (const xmlChar *val);
--xmlXPathObjectPtr xmlXPathNewCString (const char *val);
--xmlXPathObjectPtr xmlXPathNewFloat (double val);
--xmlXPathObjectPtr xmlXPathNewBoolean (int val);
--xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
--xmlXPathObjectPtr xmlXPathNewValueTree (xmlNodePtr val);
--void xmlXPathNodeSetAdd (xmlNodeSetPtr cur,
-- xmlNodePtr val);
--
--
--void xmlXPathIdFunction (xmlXPathParserContextPtr ctxt,
-- int nargs);
--void xmlXPathRoot (xmlXPathParserContextPtr ctxt);
--void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt);
--xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt);
--xmlChar * xmlXPathParseNCName (xmlXPathParserContextPtr ctxt);
--
--/*
-- * Debug
-- */
--#ifdef LIBXML_DEBUG_ENABLED
--double xmlXPathStringEvalNumber(const xmlChar *str);
--void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
--#endif
--/*
-- * Existing functions
-- */
--
--int xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
-- xmlXPathObjectPtr res);
--void xmlXPathInit(void);
--void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt);
--xmlNodeSetPtr xmlXPathNodeSetCreate(xmlNodePtr val);
--void xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val);
--xmlNodeSetPtr xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2);
--void xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val);
--void xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val);
--void xmlXPathFreeNodeSet(xmlNodeSetPtr obj);
--xmlXPathObjectPtr xmlXPathNewNodeSet(xmlNodePtr val);
--xmlXPathObjectPtr xmlXPathNewNodeSetList(xmlNodeSetPtr val);
--xmlXPathObjectPtr xmlXPathWrapNodeSet(xmlNodeSetPtr val);
--void xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj);
--
--
--xmlXPathObjectPtr xmlXPathNewFloat(double val);
--xmlXPathObjectPtr xmlXPathNewBoolean(int val);
--xmlXPathObjectPtr xmlXPathNewString(const xmlChar *val);
--xmlXPathObjectPtr xmlXPathNewCString(const char *val);
--void xmlXPathFreeObject(xmlXPathObjectPtr obj);
--xmlXPathContextPtr xmlXPathNewContext(xmlDocPtr doc);
--void xmlXPathFreeContext(xmlXPathContextPtr ctxt);
--
--int xmlXPathEqualValues(xmlXPathParserContextPtr ctxt);
--int xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict);
--void xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt);
--void xmlXPathAddValues(xmlXPathParserContextPtr ctxt);
--void xmlXPathSubValues(xmlXPathParserContextPtr ctxt);
--void xmlXPathMultValues(xmlXPathParserContextPtr ctxt);
--void xmlXPathDivValues(xmlXPathParserContextPtr ctxt);
--void xmlXPathModValues(xmlXPathParserContextPtr ctxt);
--
--/*
-- * The official core of XPath functions
-- */
--void xmlXPathRoot(xmlXPathParserContextPtr ctxt);
--void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
--#ifdef __cplusplus
--}
--#endif
--#endif /* ! __XML_XPATH_INTERNALS_H__ */
-diff -Nru libxml2-2.3.0/include/libxml/xpointer.h libxml2-2.3.0.new/include/libxml/xpointer.h
---- libxml2-2.3.0/include/libxml/xpointer.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/libxml/xpointer.h Thu Jan 1 01:00:00 1970
-@@ -1,57 +0,0 @@
--/*
-- * xpointer.h : API to handle XML Pointers
-- *
-- * World Wide Web Consortium Working Draft 03-March-1998
-- * http://www.w3.org/TR/1998/WD-xptr-19980303
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_XPTR_H__
--#define __XML_XPTR_H__
--
--#include <libxml/tree.h>
--#include <libxml/xpath.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * A Location Set
-- */
--typedef struct _xmlLocationSet xmlLocationSet;
--typedef xmlLocationSet *xmlLocationSetPtr;
--struct _xmlLocationSet {
-- int locNr; /* number of locations in the set */
-- int locMax; /* size of the array as allocated */
-- xmlXPathObjectPtr *locTab;/* array of locations */
--};
--
--/*
-- * Handling of location sets
-- */
--
--void xmlXPtrFreeLocationSet (xmlLocationSetPtr obj);
--xmlLocationSetPtr xmlXPtrLocationSetMerge (xmlLocationSetPtr val1,
-- xmlLocationSetPtr val2);
--
--/*
-- * Functions
-- */
--xmlXPathContextPtr xmlXPtrNewContext (xmlDocPtr doc,
-- xmlNodePtr here,
-- xmlNodePtr origin);
--xmlXPathObjectPtr xmlXPtrEval (const xmlChar *str,
-- xmlXPathContextPtr ctx);
--void xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt,
-- int nargs);
--xmlNodePtr xmlXPtrBuildNodeList (xmlXPathObjectPtr obj);
--void xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt);
--
--#ifdef __cplusplus
--}
--#endif
--#endif /* __XML_XPTR_H__ */
-diff -Nru libxml2-2.3.0/include/win32config.h libxml2-2.3.0.new/include/win32config.h
---- libxml2-2.3.0/include/win32config.h Mon Feb 12 04:11:18 2001
-+++ libxml2-2.3.0.new/include/win32config.h Thu Jan 1 01:00:00 1970
-@@ -1,92 +0,0 @@
--#define HAVE_CTYPE_H
--#define HAVE_STDLIB_H
--#define HAVE_MALLOC_H
--#define HAVE_TIME_H
--#define HAVE_FCNTL_H
--
--#include <io.h>
--
--#define LIBXML_DLL_IMPORT
--#define SOCKLEN_T int
--
--#ifdef INCLUDE_WINSOCK
--#include <winsock2.h>
--
--#define EWOULDBLOCK WSAEWOULDBLOCK
--#define EINPROGRESS WSAEINPROGRESS
--#define EALREADY WSAEALREADY
--#define ENOTSOCK WSAENOTSOCK
--#define EDESTADDRREQ WSAEDESTADDRREQ
--#define EMSGSIZE WSAEMSGSIZE
--#define EPROTOTYPE WSAEPROTOTYPE
--#define ENOPROTOOPT WSAENOPROTOOPT
--#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
--#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
--#define EOPNOTSUPP WSAEOPNOTSUPP
--#define EPFNOSUPPORT WSAEPFNOSUPPORT
--#define EAFNOSUPPORT WSAEAFNOSUPPORT
--#define EADDRINUSE WSAEADDRINUSE
--#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
--#define ENETDOWN WSAENETDOWN
--#define ENETUNREACH WSAENETUNREACH
--#define ENETRESET WSAENETRESET
--#define ECONNABORTED WSAECONNABORTED
--#define ECONNRESET WSAECONNRESET
--#define ENOBUFS WSAENOBUFS
--#define EISCONN WSAEISCONN
--#define ENOTCONN WSAENOTCONN
--#define ESHUTDOWN WSAESHUTDOWN
--#define ETOOMANYREFS WSAETOOMANYREFS
--#define ETIMEDOUT WSAETIMEDOUT
--#define ECONNREFUSED WSAECONNREFUSED
--#define ELOOP WSAELOOP
--#define ENAMETOOLONG WSAENAMETOOLONG
--#define EHOSTDOWN WSAEHOSTDOWN
--#define EHOSTUNREACH WSAEHOSTUNREACH
--#define ENOTEMPTY WSAENOTEMPTY
--#define EPROCLIM WSAEPROCLIM
--#define EUSERS WSAEUSERS
--#define EDQUOT WSAEDQUOT
--#define ESTALE WSAESTALE
--#define EREMOTE WSAEREMOTE
--#endif /* INCLUDE_WINSOCK */
--
--#define HAVE_ISINF
--#define HAVE_ISNAN
--
--#include <math.h>
--static int isinf (double d) {
-- int expon = 0;
-- double val = frexp (d, &expon);
-- if (expon == 1025) {
-- if (val == 0.5) {
-- return 1;
-- } else if (val == -0.5) {
-- return -1;
-- } else {
-- return 0;
-- }
-- } else {
-- return 0;
-- }
--}
--static int isnan (double d) {
-- int expon = 0;
-- double val = frexp (d, &expon);
-- if (expon == 1025) {
-- if (val == 0.5) {
-- return 0;
-- } else if (val == -0.5) {
-- return 0;
-- } else {
-- return 1;
-- }
-- } else {
-- return 0;
-- }
--}
--
--#include <direct.h>
--
--#define HAVE_SYS_STAT_H #define HAVE__STAT
--
-diff -Nru libxml2-2.3.0/libxml/HTMLparser.c libxml2-2.3.0.new/libxml/HTMLparser.c
---- libxml2-2.3.0/libxml/HTMLparser.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/HTMLparser.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,4966 @@
-+/*
-+ * HTMLparser.c : an HTML 4.0 non-verifying parser
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_HTML_ENABLED
-+#include <stdio.h>
-+#include <string.h>
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_ZLIB_H
-+#include <zlib.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/xmlerror.h>
-+#include <libxml/HTMLparser.h>
-+#include <libxml/entities.h>
-+#include <libxml/encoding.h>
-+#include <libxml/valid.h>
-+#include <libxml/xmlIO.h>
-+
-+#define HTML_MAX_NAMELEN 1000
-+#define HTML_PARSER_BIG_BUFFER_SIZE 1000
-+#define HTML_PARSER_BUFFER_SIZE 100
-+
-+/* #define DEBUG */
-+/* #define DEBUG_PUSH */
-+
-+int htmlOmittedDefaultValue = 1;
-+
-+/************************************************************************
-+ * *
-+ * Parser stacks related functions and macros *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * Generic function for accessing stacks in the Parser Context
-+ */
-+
-+#define PUSH_AND_POP(scope, type, name) \
-+scope int html##name##Push(htmlParserCtxtPtr ctxt, type value) { \
-+ if (ctxt->name##Nr >= ctxt->name##Max) { \
-+ ctxt->name##Max *= 2; \
-+ ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-+ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-+ if (ctxt->name##Tab == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "realloc failed !\n"); \
-+ return(0); \
-+ } \
-+ } \
-+ ctxt->name##Tab[ctxt->name##Nr] = value; \
-+ ctxt->name = value; \
-+ return(ctxt->name##Nr++); \
-+} \
-+scope type html##name##Pop(htmlParserCtxtPtr ctxt) { \
-+ type ret; \
-+ if (ctxt->name##Nr < 0) return(0); \
-+ ctxt->name##Nr--; \
-+ if (ctxt->name##Nr < 0) return(0); \
-+ if (ctxt->name##Nr > 0) \
-+ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-+ else \
-+ ctxt->name = NULL; \
-+ ret = ctxt->name##Tab[ctxt->name##Nr]; \
-+ ctxt->name##Tab[ctxt->name##Nr] = 0; \
-+ return(ret); \
-+} \
-+
-+PUSH_AND_POP(extern, xmlNodePtr, node)
-+PUSH_AND_POP(extern, xmlChar*, name)
-+
-+/*
-+ * Macros for accessing the content. Those should be used only by the parser,
-+ * and not exported.
-+ *
-+ * Dirty macros, i.e. one need to make assumption on the context to use them
-+ *
-+ * CUR_PTR return the current pointer to the xmlChar to be parsed.
-+ * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
-+ * in ISO-Latin or UTF-8, and the current 16 bit value if compiled
-+ * in UNICODE mode. This should be used internally by the parser
-+ * only to compare to ASCII values otherwise it would break when
-+ * running with UTF-8 encoding.
-+ * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-+ * to compare on ASCII based substring.
-+ * UPP(n) returns the n'th next xmlChar converted to uppercase. Same as CUR
-+ * it should be used only to compare on ASCII based substring.
-+ * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-+ * strings within the parser.
-+ *
-+ * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
-+ *
-+ * CURRENT Returns the current char value, with the full decoding of
-+ * UTF-8 if we are using this mode. It returns an int.
-+ * NEXT Skip to the next character, this does the proper decoding
-+ * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-+ * COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
-+ */
-+
-+#define UPPER (toupper(*ctxt->input->cur))
-+
-+#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val)
-+
-+#define NXT(val) ctxt->input->cur[(val)]
-+
-+#define UPP(val) (toupper(ctxt->input->cur[(val)]))
-+
-+#define CUR_PTR ctxt->input->cur
-+
-+#define SHRINK xmlParserInputShrink(ctxt->input)
-+
-+#define GROW xmlParserInputGrow(ctxt->input, INPUT_CHUNK)
-+
-+#define CURRENT ((int) (*ctxt->input->cur))
-+
-+#define SKIP_BLANKS htmlSkipBlankChars(ctxt)
-+
-+/* Inported from XML */
-+
-+/* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
-+#define CUR ((int) (*ctxt->input->cur))
-+#define NEXT xmlNextChar(ctxt),ctxt->nbChars++
-+
-+#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-+#define NXT(val) ctxt->input->cur[(val)]
-+#define CUR_PTR ctxt->input->cur
-+
-+
-+#define NEXTL(l) do { \
-+ if (*(ctxt->input->cur) == '\n') { \
-+ ctxt->input->line++; ctxt->input->col = 1; \
-+ } else ctxt->input->col++; \
-+ ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \
-+ } while (0)
-+
-+/************
-+ \
-+ if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
-+ if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
-+ ************/
-+
-+#define CUR_CHAR(l) htmlCurrentChar(ctxt, &l)
-+#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
-+
-+#define COPY_BUF(l,b,i,v) \
-+ if (l == 1) b[i++] = (xmlChar) v; \
-+ else i += xmlCopyChar(l,&b[i],v)
-+
-+/**
-+ * htmlCurrentChar:
-+ * @ctxt: the HTML parser context
-+ * @len: pointer to the length of the char read
-+ *
-+ * The current char value, if using UTF-8 this may actaully span multiple
-+ * bytes in the input buffer. Implement the end of line normalization:
-+ * 2.11 End-of-Line Handling
-+ * If the encoding is unspecified, in the case we find an ISO-Latin-1
-+ * char, then the encoding converter is plugged in automatically.
-+ *
-+ * Returns the current char value and its lenght
-+ */
-+
-+int
-+htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
-+ if (ctxt->instate == XML_PARSER_EOF)
-+ return(0);
-+
-+ if (ctxt->token != 0) {
-+ *len = 0;
-+ return(ctxt->token);
-+ }
-+ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * We are supposed to handle UTF8, check it's valid
-+ * From rfc2044: encoding of the Unicode values on UTF-8:
-+ *
-+ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-+ * 0000 0000-0000 007F 0xxxxxxx
-+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-+ *
-+ * Check for the 0x110000 limit too
-+ */
-+ const unsigned char *cur = ctxt->input->cur;
-+ unsigned char c;
-+ unsigned int val;
-+
-+ c = *cur;
-+ if (c & 0x80) {
-+ if (cur[1] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if ((cur[1] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xe0) == 0xe0) {
-+
-+ if (cur[2] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if ((cur[2] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xf0) == 0xf0) {
-+ if (cur[3] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if (((c & 0xf8) != 0xf0) ||
-+ ((cur[3] & 0xc0) != 0x80))
-+ goto encoding_error;
-+ /* 4-byte code */
-+ *len = 4;
-+ val = (cur[0] & 0x7) << 18;
-+ val |= (cur[1] & 0x3f) << 12;
-+ val |= (cur[2] & 0x3f) << 6;
-+ val |= cur[3] & 0x3f;
-+ } else {
-+ /* 3-byte code */
-+ *len = 3;
-+ val = (cur[0] & 0xf) << 12;
-+ val |= (cur[1] & 0x3f) << 6;
-+ val |= cur[2] & 0x3f;
-+ }
-+ } else {
-+ /* 2-byte code */
-+ *len = 2;
-+ val = (cur[0] & 0x1f) << 6;
-+ val |= cur[1] & 0x3f;
-+ }
-+ if (!IS_CHAR(val)) {
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Char 0x%X out of allowed range\n", val);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(val);
-+ } else {
-+ /* 1-byte code */
-+ *len = 1;
-+ return((int) *ctxt->input->cur);
-+ }
-+ }
-+ /*
-+ * Assume it's a fixed lenght encoding (1) with
-+ * a compatibke encoding for the ASCII set, since
-+ * XML constructs only use < 128 chars
-+ */
-+ *len = 1;
-+ if ((int) *ctxt->input->cur < 0x80)
-+ return((int) *ctxt->input->cur);
-+
-+ /*
-+ * Humm this is bad, do an automatic flow conversion
-+ */
-+ xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ return(xmlCurrentChar(ctxt, len));
-+
-+encoding_error:
-+ /*
-+ * If we detect an UTF8 error that probably mean that the
-+ * input encoding didn't get properly advertized in the
-+ * declaration header. Report the error and switch the encoding
-+ * to ISO-Latin-1 (if you don't like this policy, just declare the
-+ * encoding !)
-+ */
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-+ ctxt->sax->error(ctxt->userData,
-+ "Input is not proper UTF-8, indicate encoding !\n");
-+ ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ ctxt->input->cur[0], ctxt->input->cur[1],
-+ ctxt->input->cur[2], ctxt->input->cur[3]);
-+ }
-+
-+ ctxt->charset = XML_CHAR_ENCODING_8859_1;
-+ *len = 1;
-+ return((int) *ctxt->input->cur);
-+}
-+
-+/**
-+ * htmlNextChar:
-+ * @ctxt: the HTML parser context
-+ *
-+ * Skip to the next char input char.
-+ */
-+
-+void
-+htmlNextChar(htmlParserCtxtPtr ctxt) {
-+ if (ctxt->instate == XML_PARSER_EOF)
-+ return;
-+ if ((*ctxt->input->cur == 0) &&
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
-+ xmlPopInput(ctxt);
-+ } else {
-+ if (*(ctxt->input->cur) == '\n') {
-+ ctxt->input->line++; ctxt->input->col = 1;
-+ } else ctxt->input->col++;
-+ ctxt->input->cur++;
-+ ctxt->nbChars++;
-+ if (*ctxt->input->cur == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ }
-+}
-+
-+/**
-+ * htmlSkipBlankChars:
-+ * @ctxt: the HTML parser context
-+ *
-+ * skip all blanks character found at that point in the input streams.
-+ *
-+ * Returns the number of space chars skipped
-+ */
-+
-+int
-+htmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
-+ int res = 0;
-+
-+ while (IS_BLANK(*(ctxt->input->cur))) {
-+ if ((*ctxt->input->cur == 0) &&
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
-+ xmlPopInput(ctxt);
-+ } else {
-+ if (*(ctxt->input->cur) == '\n') {
-+ ctxt->input->line++; ctxt->input->col = 1;
-+ } else ctxt->input->col++;
-+ ctxt->input->cur++;
-+ ctxt->nbChars++;
-+ if (*ctxt->input->cur == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ }
-+ res++;
-+ }
-+ return(res);
-+}
-+
-+
-+
-+/************************************************************************
-+ * *
-+ * The list of HTML elements and their properties *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * Start Tag: 1 means the start tag can be ommited
-+ * End Tag: 1 means the end tag can be ommited
-+ * 2 means it's forbidden (empty elements)
-+ * Depr: this element is deprecated
-+ * DTD: 1 means that this element is valid only in the Loose DTD
-+ * 2 means that this element is valid only in the Frameset DTD
-+ *
-+ * Name,Start Tag,End Tag, Empty, Depr., DTD, Description
-+ */
-+htmlElemDesc html40ElementTable[] = {
-+{ "a", 0, 0, 0, 0, 0, "anchor " },
-+{ "abbr", 0, 0, 0, 0, 0, "abbreviated form" },
-+{ "acronym", 0, 0, 0, 0, 0, "" },
-+{ "address", 0, 0, 0, 0, 0, "information on author " },
-+{ "applet", 0, 0, 0, 1, 1, "java applet " },
-+{ "area", 0, 2, 1, 0, 0, "client-side image map area " },
-+{ "b", 0, 0, 0, 0, 0, "bold text style" },
-+{ "base", 0, 2, 1, 0, 0, "document base uri " },
-+{ "basefont", 0, 2, 1, 1, 1, "base font size " },
-+{ "bdo", 0, 0, 0, 0, 0, "i18n bidi over-ride " },
-+{ "big", 0, 0, 0, 0, 0, "large text style" },
-+{ "blockquote", 0, 0, 0, 0, 0, "long quotation " },
-+{ "body", 1, 1, 0, 0, 0, "document body " },
-+{ "br", 0, 2, 1, 0, 0, "forced line break " },
-+{ "button", 0, 0, 0, 0, 0, "push button " },
-+{ "caption", 0, 0, 0, 0, 0, "table caption " },
-+{ "center", 0, 0, 0, 1, 1, "shorthand for div align=center " },
-+{ "cite", 0, 0, 0, 0, 0, "citation" },
-+{ "code", 0, 0, 0, 0, 0, "computer code fragment" },
-+{ "col", 0, 2, 1, 0, 0, "table column " },
-+{ "colgroup", 0, 1, 0, 0, 0, "table column group " },
-+{ "dd", 0, 1, 0, 0, 0, "definition description " },
-+{ "del", 0, 0, 0, 0, 0, "deleted text " },
-+{ "dfn", 0, 0, 0, 0, 0, "instance definition" },
-+{ "dir", 0, 0, 0, 1, 1, "directory list" },
-+{ "div", 0, 0, 0, 0, 0, "generic language/style container"},
-+{ "dl", 0, 0, 0, 0, 0, "definition list " },
-+{ "dt", 0, 1, 0, 0, 0, "definition term " },
-+{ "em", 0, 0, 0, 0, 0, "emphasis" },
-+{ "fieldset", 0, 0, 0, 0, 0, "form control group " },
-+{ "font", 0, 0, 0, 1, 1, "local change to font " },
-+{ "form", 0, 0, 0, 0, 0, "interactive form " },
-+{ "frame", 0, 2, 1, 0, 2, "subwindow " },
-+{ "frameset", 0, 0, 0, 0, 2, "window subdivision" },
-+{ "h1", 0, 0, 0, 0, 0, "heading " },
-+{ "h2", 0, 0, 0, 0, 0, "heading " },
-+{ "h3", 0, 0, 0, 0, 0, "heading " },
-+{ "h4", 0, 0, 0, 0, 0, "heading " },
-+{ "h5", 0, 0, 0, 0, 0, "heading " },
-+{ "h6", 0, 0, 0, 0, 0, "heading " },
-+{ "head", 1, 1, 0, 0, 0, "document head " },
-+{ "hr", 0, 2, 1, 0, 0, "horizontal rule " },
-+{ "html", 1, 1, 0, 0, 0, "document root element " },
-+{ "i", 0, 0, 0, 0, 0, "italic text style" },
-+{ "iframe", 0, 0, 0, 0, 1, "inline subwindow " },
-+{ "img", 0, 2, 1, 0, 0, "embedded image " },
-+{ "input", 0, 2, 1, 0, 0, "form control " },
-+{ "ins", 0, 0, 0, 0, 0, "inserted text" },
-+{ "isindex", 0, 2, 1, 1, 1, "single line prompt " },
-+{ "kbd", 0, 0, 0, 0, 0, "text to be entered by the user" },
-+{ "label", 0, 0, 0, 0, 0, "form field label text " },
-+{ "legend", 0, 0, 0, 0, 0, "fieldset legend " },
-+{ "li", 0, 1, 0, 0, 0, "list item " },
-+{ "link", 0, 2, 1, 0, 0, "a media-independent link " },
-+{ "map", 0, 0, 0, 0, 0, "client-side image map " },
-+{ "menu", 0, 0, 0, 1, 1, "menu list " },
-+{ "meta", 0, 2, 1, 0, 0, "generic metainformation " },
-+{ "noframes", 0, 0, 0, 0, 2, "alternate content container for non frame-based rendering " },
-+{ "noscript", 0, 0, 0, 0, 0, "alternate content container for non script-based rendering " },
-+{ "object", 0, 0, 0, 0, 0, "generic embedded object " },
-+{ "ol", 0, 0, 0, 0, 0, "ordered list " },
-+{ "optgroup", 0, 0, 0, 0, 0, "option group " },
-+{ "option", 0, 1, 0, 0, 0, "selectable choice " },
-+{ "p", 0, 1, 0, 0, 0, "paragraph " },
-+{ "param", 0, 2, 1, 0, 0, "named property value " },
-+{ "pre", 0, 0, 0, 0, 0, "preformatted text " },
-+{ "q", 0, 0, 0, 0, 0, "short inline quotation " },
-+{ "s", 0, 0, 0, 1, 1, "strike-through text style" },
-+{ "samp", 0, 0, 0, 0, 0, "sample program output, scripts, etc." },
-+{ "script", 0, 0, 0, 0, 0, "script statements " },
-+{ "select", 0, 0, 0, 0, 0, "option selector " },
-+{ "small", 0, 0, 0, 0, 0, "small text style" },
-+{ "span", 0, 0, 0, 0, 0, "generic language/style container " },
-+{ "strike", 0, 0, 0, 1, 1, "strike-through text" },
-+{ "strong", 0, 0, 0, 0, 0, "strong emphasis" },
-+{ "style", 0, 0, 0, 0, 0, "style info " },
-+{ "sub", 0, 0, 0, 0, 0, "subscript" },
-+{ "sup", 0, 0, 0, 0, 0, "superscript " },
-+{ "table", 0, 0, 0, 0, 0, " " },
-+{ "tbody", 1, 1, 0, 0, 0, "table body " },
-+{ "td", 0, 1, 0, 0, 0, "table data cell" },
-+{ "textarea", 0, 0, 0, 0, 0, "multi-line text field " },
-+{ "tfoot", 0, 1, 0, 0, 0, "table footer " },
-+{ "th", 0, 1, 0, 0, 0, "table header cell" },
-+{ "thead", 0, 1, 0, 0, 0, "table header " },
-+{ "title", 0, 0, 0, 0, 0, "document title " },
-+{ "tr", 0, 1, 0, 0, 0, "table row " },
-+{ "tt", 0, 0, 0, 0, 0, "teletype or monospaced text style" },
-+{ "u", 0, 0, 0, 1, 1, "underlined text style" },
-+{ "ul", 0, 0, 0, 0, 0, "unordered list " },
-+{ "var", 0, 0, 0, 0, 0, "instance of a variable or program argument" },
-+};
-+
-+/*
-+ * start tags that imply the end of a current element
-+ * any tag of each line implies the end of the current element if the type of
-+ * that element is in the same line
-+ */
-+char *htmlEquEnd[] = {
-+"dt", "dd", "li", "option", NULL,
-+"h1", "h2", "h3", "h4", "h5", "h6", NULL,
-+"ol", "menu", "dir", "address", "pre", "listing", "xmp", NULL,
-+NULL
-+};
-+/*
-+ * acording the HTML DTD, HR should be added to the 2nd line above, as it
-+ * is not allowed within a H1, H2, H3, etc. But we should tolerate that case
-+ * because many documents contain rules in headings...
-+ */
-+
-+/*
-+ * start tags that imply the end of current element
-+ */
-+char *htmlStartClose[] = {
-+"form", "form", "p", "hr", "h1", "h2", "h3", "h4", "h5", "h6",
-+ "dl", "ul", "ol", "menu", "dir", "address", "pre",
-+ "listing", "xmp", "head", NULL,
-+"head", "p", NULL,
-+"title", "p", NULL,
-+"body", "head", "style", "link", "title", "p", NULL,
-+"li", "p", "h1", "h2", "h3", "h4", "h5", "h6", "dl", "address",
-+ "pre", "listing", "xmp", "head", "li", NULL,
-+"hr", "p", "head", NULL,
-+"h1", "p", "head", NULL,
-+"h2", "p", "head", NULL,
-+"h3", "p", "head", NULL,
-+"h4", "p", "head", NULL,
-+"h5", "p", "head", NULL,
-+"h6", "p", "head", NULL,
-+"dir", "p", "head", NULL,
-+"address", "p", "head", "ul", NULL,
-+"pre", "p", "head", "ul", NULL,
-+"listing", "p", "head", NULL,
-+"xmp", "p", "head", NULL,
-+"blockquote", "p", "head", NULL,
-+"dl", "p", "dt", "menu", "dir", "address", "pre", "listing",
-+ "xmp", "head", NULL,
-+"dt", "p", "menu", "dir", "address", "pre", "listing", "xmp",
-+ "head", "dd", NULL,
-+"dd", "p", "menu", "dir", "address", "pre", "listing", "xmp",
-+ "head", "dt", NULL,
-+"ul", "p", "head", "ol", "menu", "dir", "address", "pre",
-+ "listing", "xmp", NULL,
-+"ol", "p", "head", "ul", NULL,
-+"menu", "p", "head", "ul", NULL,
-+"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", NULL,
-+"div", "p", "head", NULL,
-+"noscript", "p", "head", NULL,
-+"center", "font", "b", "i", "p", "head", NULL,
-+"a", "a", NULL,
-+"caption", "p", NULL,
-+"colgroup", "caption", "colgroup", "col", "p", NULL,
-+"col", "caption", "col", "p", NULL,
-+"table", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", "pre",
-+ "listing", "xmp", "a", NULL,
-+"th", "th", "td", NULL,
-+"td", "th", "td", "p", NULL,
-+"tr", "th", "td", "tr", "caption", "col", "colgroup", "p", NULL,
-+"thead", "caption", "col", "colgroup", NULL,
-+"tfoot", "th", "td", "tr", "caption", "col", "colgroup", "thead",
-+ "tbody", "p", NULL,
-+"tbody", "th", "td", "tr", "caption", "col", "colgroup", "thead",
-+ "tfoot", "tbody", "p", NULL,
-+"optgroup", "option", NULL,
-+"option", "option", NULL,
-+"fieldset", "legend", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6",
-+ "pre", "listing", "xmp", "a", NULL,
-+NULL
-+};
-+
-+/*
-+ * The list of HTML elements which are supposed not to have
-+ * CDATA content and where a p element will be implied
-+ *
-+ * TODO: extend that list by reading the HTML SGML DtD on
-+ * implied paragraph
-+ */
-+static char *htmlNoContentElements[] = {
-+ "html",
-+ "head",
-+ "body",
-+ NULL
-+};
-+
-+/*
-+ * The list of HTML attributes which are of content %Script;
-+ * NOTE: when adding ones, check htmlIsScriptAttribute() since
-+ * it assumes the name starts with 'on'
-+ */
-+static char *htmlScriptAttributes[] = {
-+ "onclick",
-+ "ondblclick",
-+ "onmousedown",
-+ "onmouseup",
-+ "onmouseover",
-+ "onmousemove",
-+ "onmouseout",
-+ "onkeypress",
-+ "onkeydown",
-+ "onkeyup",
-+ "onload",
-+ "onunload",
-+ "onfocus",
-+ "onblur",
-+ "onsubmit",
-+ "onrest",
-+ "onchange",
-+ "onselect"
-+};
-+
-+
-+static char** htmlStartCloseIndex[100];
-+static int htmlStartCloseIndexinitialized = 0;
-+
-+/************************************************************************
-+ * *
-+ * functions to handle HTML specific data *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlInitAutoClose:
-+ *
-+ * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
-+ * This is not reentrant. Call xmlInitParser() once before processing in
-+ * case of use in multithreaded programs.
-+ */
-+void
-+htmlInitAutoClose(void) {
-+ int index, i = 0;
-+
-+ if (htmlStartCloseIndexinitialized) return;
-+
-+ for (index = 0;index < 100;index ++) htmlStartCloseIndex[index] = NULL;
-+ index = 0;
-+ while ((htmlStartClose[i] != NULL) && (index < 100 - 1)) {
-+ htmlStartCloseIndex[index++] = &htmlStartClose[i];
-+ while (htmlStartClose[i] != NULL) i++;
-+ i++;
-+ }
-+ htmlStartCloseIndexinitialized = 1;
-+}
-+
-+/**
-+ * htmlTagLookup:
-+ * @tag: The tag name in lowercase
-+ *
-+ * Lookup the HTML tag in the ElementTable
-+ *
-+ * Returns the related htmlElemDescPtr or NULL if not found.
-+ */
-+htmlElemDescPtr
-+htmlTagLookup(const xmlChar *tag) {
-+ int i;
-+
-+ for (i = 0; i < (sizeof(html40ElementTable) /
-+ sizeof(html40ElementTable[0]));i++) {
-+ if (xmlStrEqual(tag, BAD_CAST html40ElementTable[i].name))
-+ return(&html40ElementTable[i]);
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * htmlCheckAutoClose:
-+ * @newtag: The new tag name
-+ * @oldtag: The old tag name
-+ *
-+ * Checks wether the new tag is one of the registered valid tags for closing old.
-+ * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
-+ *
-+ * Returns 0 if no, 1 if yes.
-+ */
-+int
-+htmlCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
-+ int i, index;
-+ char **close = NULL;
-+
-+ if (htmlStartCloseIndexinitialized == 0) htmlInitAutoClose();
-+
-+ /* inefficient, but not a big deal */
-+ for (index = 0; index < 100;index++) {
-+ close = htmlStartCloseIndex[index];
-+ if (close == NULL) return(0);
-+ if (xmlStrEqual(BAD_CAST *close, newtag)) break;
-+ }
-+
-+ i = close - htmlStartClose;
-+ i++;
-+ while (htmlStartClose[i] != NULL) {
-+ if (xmlStrEqual(BAD_CAST htmlStartClose[i], oldtag)) {
-+ return(1);
-+ }
-+ i++;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * htmlAutoCloseOnClose:
-+ * @ctxt: an HTML parser context
-+ * @newtag: The new tag name
-+ *
-+ * The HTmL DtD allows an ending tag to implicitely close other tags.
-+ */
-+void
-+htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
-+ htmlElemDescPtr info;
-+ xmlChar *oldname;
-+ int i;
-+
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Close of %s stack: %d elements\n", newtag, ctxt->nameNr);
-+ for (i = 0;i < ctxt->nameNr;i++)
-+ xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
-+#endif
-+
-+ for (i = (ctxt->nameNr - 1);i >= 0;i--) {
-+ if (xmlStrEqual(newtag, ctxt->nameTab[i])) break;
-+ }
-+ if (i < 0) return;
-+
-+ while (!xmlStrEqual(newtag, ctxt->name)) {
-+ info = htmlTagLookup(ctxt->name);
-+ if ((info == NULL) || (info->endTag == 1)) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: %s closes %s\n", newtag, ctxt->name);
-+#endif
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Opening and ending tag mismatch: %s and %s\n",
-+ newtag, ctxt->name);
-+ ctxt->wellFormed = 0;
-+ }
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, ctxt->name);
-+ oldname = htmlnamePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ }
-+}
-+
-+/**
-+ * htmlAutoClose:
-+ * @ctxt: an HTML parser context
-+ * @newtag: The new tag name or NULL
-+ *
-+ * The HTmL DtD allows a tag to implicitely close other tags.
-+ * The list is kept in htmlStartClose array. This function is
-+ * called when a new tag has been detected and generates the
-+ * appropriates closes if possible/needed.
-+ * If newtag is NULL this mean we are at the end of the resource
-+ * and we should check
-+ */
-+void
-+htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
-+ xmlChar *oldname;
-+ while ((newtag != NULL) && (ctxt->name != NULL) &&
-+ (htmlCheckAutoClose(newtag, ctxt->name))) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: %s closes %s\n", newtag, ctxt->name);
-+#endif
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, ctxt->name);
-+ oldname = htmlnamePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ }
-+ if (newtag == NULL) {
-+ htmlAutoCloseOnClose(ctxt, BAD_CAST"head");
-+ htmlAutoCloseOnClose(ctxt, BAD_CAST"body");
-+ htmlAutoCloseOnClose(ctxt, BAD_CAST"html");
-+ }
-+ while ((newtag == NULL) && (ctxt->name != NULL) &&
-+ ((xmlStrEqual(ctxt->name, BAD_CAST"head")) ||
-+ (xmlStrEqual(ctxt->name, BAD_CAST"body")) ||
-+ (xmlStrEqual(ctxt->name, BAD_CAST"html")))) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: EOF closes %s\n", ctxt->name);
-+#endif
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, ctxt->name);
-+ oldname = htmlnamePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ }
-+
-+}
-+
-+/**
-+ * htmlAutoCloseTag:
-+ * @doc: the HTML document
-+ * @name: The tag name
-+ * @elem: the HTML element
-+ *
-+ * The HTmL DtD allows a tag to implicitely close other tags.
-+ * The list is kept in htmlStartClose array. This function checks
-+ * if the element or one of it's children would autoclose the
-+ * given tag.
-+ *
-+ * Returns 1 if autoclose, 0 otherwise
-+ */
-+int
-+htmlAutoCloseTag(htmlDocPtr doc, const xmlChar *name, htmlNodePtr elem) {
-+ htmlNodePtr child;
-+
-+ if (elem == NULL) return(1);
-+ if (xmlStrEqual(name, elem->name)) return(0);
-+ if (htmlCheckAutoClose(elem->name, name)) return(1);
-+ child = elem->children;
-+ while (child != NULL) {
-+ if (htmlAutoCloseTag(doc, name, child)) return(1);
-+ child = child->next;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * htmlIsAutoClosed:
-+ * @doc: the HTML document
-+ * @elem: the HTML element
-+ *
-+ * The HTmL DtD allows a tag to implicitely close other tags.
-+ * The list is kept in htmlStartClose array. This function checks
-+ * if a tag is autoclosed by one of it's child
-+ *
-+ * Returns 1 if autoclosed, 0 otherwise
-+ */
-+int
-+htmlIsAutoClosed(htmlDocPtr doc, htmlNodePtr elem) {
-+ htmlNodePtr child;
-+
-+ if (elem == NULL) return(1);
-+ child = elem->children;
-+ while (child != NULL) {
-+ if (htmlAutoCloseTag(doc, elem->name, child)) return(1);
-+ child = child->next;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * htmlCheckImplied:
-+ * @ctxt: an HTML parser context
-+ * @newtag: The new tag name
-+ *
-+ * The HTML DtD allows a tag to exists only implicitely
-+ * called when a new tag has been detected and generates the
-+ * appropriates implicit tags if missing
-+ */
-+void
-+htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
-+ if (!htmlOmittedDefaultValue)
-+ return;
-+ if (xmlStrEqual(newtag, BAD_CAST"html"))
-+ return;
-+ if (ctxt->nameNr <= 0) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Implied element html: pushed html\n");
-+#endif
-+ htmlnamePush(ctxt, xmlStrdup(BAD_CAST"html"));
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-+ ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
-+ }
-+ if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
-+ return;
-+ if ((ctxt->nameNr <= 1) &&
-+ ((xmlStrEqual(newtag, BAD_CAST"script")) ||
-+ (xmlStrEqual(newtag, BAD_CAST"style")) ||
-+ (xmlStrEqual(newtag, BAD_CAST"meta")) ||
-+ (xmlStrEqual(newtag, BAD_CAST"link")) ||
-+ (xmlStrEqual(newtag, BAD_CAST"title")) ||
-+ (xmlStrEqual(newtag, BAD_CAST"base")))) {
-+ /*
-+ * dropped OBJECT ... i you put it first BODY will be
-+ * assumed !
-+ */
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Implied element head: pushed head\n");
-+#endif
-+ htmlnamePush(ctxt, xmlStrdup(BAD_CAST"head"));
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-+ ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
-+ } else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
-+ (!xmlStrEqual(newtag, BAD_CAST"frame")) &&
-+ (!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
-+ int i;
-+ for (i = 0;i < ctxt->nameNr;i++) {
-+ if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
-+ return;
-+ }
-+ if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"head")) {
-+ return;
-+ }
-+ }
-+
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Implied element body: pushed body\n");
-+#endif
-+ htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-+ ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
-+ }
-+}
-+
-+/**
-+ * htmlCheckParagraph
-+ * @ctxt: an HTML parser context
-+ *
-+ * Check whether a p element need to be implied before inserting
-+ * characters in the current element.
-+ *
-+ * Returns 1 if a paragraph has been inserted, 0 if not and -1
-+ * in case of error.
-+ */
-+
-+int
-+htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
-+ const xmlChar *tag;
-+ int i;
-+
-+ if (ctxt == NULL)
-+ return(-1);
-+ tag = ctxt->name;
-+ if (tag == NULL) {
-+ htmlAutoClose(ctxt, BAD_CAST"p");
-+ htmlCheckImplied(ctxt, BAD_CAST"p");
-+ htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-+ ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
-+ return(1);
-+ }
-+ if (!htmlOmittedDefaultValue)
-+ return(0);
-+ for (i = 0; htmlNoContentElements[i] != NULL; i++) {
-+ if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Implied element paragraph\n");
-+#endif
-+ htmlAutoClose(ctxt, BAD_CAST"p");
-+ htmlCheckImplied(ctxt, BAD_CAST"p");
-+ htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-+ ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
-+ return(1);
-+ }
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * htmlIsScriptAttribute:
-+ * @name: an attribute name
-+ *
-+ * Check if an attribute is of content type Script
-+ *
-+ * Returns 1 is the attribute is a script 0 otherwise
-+ */
-+int
-+htmlIsScriptAttribute(const xmlChar *name) {
-+ int i;
-+
-+ if (name == NULL)
-+ return(0);
-+ /*
-+ * all script attributes start with 'on'
-+ */
-+ if ((name[0] != 'o') || (name[1] != 'n'))
-+ return(0);
-+ for (i = 0;
-+ i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
-+ i++) {
-+ if (xmlStrEqual(name, (const xmlChar *) htmlScriptAttributes[i]))
-+ return(1);
-+ }
-+ return(0);
-+}
-+
-+/************************************************************************
-+ * *
-+ * The list of HTML predefined entities *
-+ * *
-+ ************************************************************************/
-+
-+
-+htmlEntityDesc html40EntitiesTable[] = {
-+/*
-+ * the 4 absolute ones, plus apostrophe.
-+ */
-+{ 34, "quot", "quotation mark = APL quote, U+0022 ISOnum" },
-+{ 38, "amp", "ampersand, U+0026 ISOnum" },
-+{ 39, "apos", "single quote" },
-+{ 60, "lt", "less-than sign, U+003C ISOnum" },
-+{ 62, "gt", "greater-than sign, U+003E ISOnum" },
-+
-+/*
-+ * A bunch still in the 128-255 range
-+ * Replacing them depend really on the charset used.
-+ */
-+{ 160, "nbsp", "no-break space = non-breaking space, U+00A0 ISOnum" },
-+{ 161, "iexcl","inverted exclamation mark, U+00A1 ISOnum" },
-+{ 162, "cent", "cent sign, U+00A2 ISOnum" },
-+{ 163, "pound","pound sign, U+00A3 ISOnum" },
-+{ 164, "curren","currency sign, U+00A4 ISOnum" },
-+{ 165, "yen", "yen sign = yuan sign, U+00A5 ISOnum" },
-+{ 166, "brvbar","broken bar = broken vertical bar, U+00A6 ISOnum" },
-+{ 167, "sect", "section sign, U+00A7 ISOnum" },
-+{ 168, "uml", "diaeresis = spacing diaeresis, U+00A8 ISOdia" },
-+{ 169, "copy", "copyright sign, U+00A9 ISOnum" },
-+{ 170, "ordf", "feminine ordinal indicator, U+00AA ISOnum" },
-+{ 171, "laquo","left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum" },
-+{ 172, "not", "not sign, U+00AC ISOnum" },
-+{ 173, "shy", "soft hyphen = discretionary hyphen, U+00AD ISOnum" },
-+{ 174, "reg", "registered sign = registered trade mark sign, U+00AE ISOnum" },
-+{ 175, "macr", "macron = spacing macron = overline = APL overbar, U+00AF ISOdia" },
-+{ 176, "deg", "degree sign, U+00B0 ISOnum" },
-+{ 177, "plusmn","plus-minus sign = plus-or-minus sign, U+00B1 ISOnum" },
-+{ 178, "sup2", "superscript two = superscript digit two = squared, U+00B2 ISOnum" },
-+{ 179, "sup3", "superscript three = superscript digit three = cubed, U+00B3 ISOnum" },
-+{ 180, "acute","acute accent = spacing acute, U+00B4 ISOdia" },
-+{ 181, "micro","micro sign, U+00B5 ISOnum" },
-+{ 182, "para", "pilcrow sign = paragraph sign, U+00B6 ISOnum" },
-+{ 183, "middot","middle dot = Georgian comma Greek middle dot, U+00B7 ISOnum" },
-+{ 184, "cedil","cedilla = spacing cedilla, U+00B8 ISOdia" },
-+{ 185, "sup1", "superscript one = superscript digit one, U+00B9 ISOnum" },
-+{ 186, "ordm", "masculine ordinal indicator, U+00BA ISOnum" },
-+{ 187, "raquo","right-pointing double angle quotation mark right pointing guillemet, U+00BB ISOnum" },
-+{ 188, "frac14","vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum" },
-+{ 189, "frac12","vulgar fraction one half = fraction one half, U+00BD ISOnum" },
-+{ 190, "frac34","vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum" },
-+{ 191, "iquest","inverted question mark = turned question mark, U+00BF ISOnum" },
-+{ 192, "Agrave","latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1" },
-+{ 193, "Aacute","latin capital letter A with acute, U+00C1 ISOlat1" },
-+{ 194, "Acirc","latin capital letter A with circumflex, U+00C2 ISOlat1" },
-+{ 195, "Atilde","latin capital letter A with tilde, U+00C3 ISOlat1" },
-+{ 196, "Auml", "latin capital letter A with diaeresis, U+00C4 ISOlat1" },
-+{ 197, "Aring","latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1" },
-+{ 198, "AElig","latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1" },
-+{ 199, "Ccedil","latin capital letter C with cedilla, U+00C7 ISOlat1" },
-+{ 200, "Egrave","latin capital letter E with grave, U+00C8 ISOlat1" },
-+{ 201, "Eacute","latin capital letter E with acute, U+00C9 ISOlat1" },
-+{ 202, "Ecirc","latin capital letter E with circumflex, U+00CA ISOlat1" },
-+{ 203, "Euml", "latin capital letter E with diaeresis, U+00CB ISOlat1" },
-+{ 204, "Igrave","latin capital letter I with grave, U+00CC ISOlat1" },
-+{ 205, "Iacute","latin capital letter I with acute, U+00CD ISOlat1" },
-+{ 206, "Icirc","latin capital letter I with circumflex, U+00CE ISOlat1" },
-+{ 207, "Iuml", "latin capital letter I with diaeresis, U+00CF ISOlat1" },
-+{ 208, "ETH", "latin capital letter ETH, U+00D0 ISOlat1" },
-+{ 209, "Ntilde","latin capital letter N with tilde, U+00D1 ISOlat1" },
-+{ 210, "Ograve","latin capital letter O with grave, U+00D2 ISOlat1" },
-+{ 211, "Oacute","latin capital letter O with acute, U+00D3 ISOlat1" },
-+{ 212, "Ocirc","latin capital letter O with circumflex, U+00D4 ISOlat1" },
-+{ 213, "Otilde","latin capital letter O with tilde, U+00D5 ISOlat1" },
-+{ 214, "Ouml", "latin capital letter O with diaeresis, U+00D6 ISOlat1" },
-+{ 215, "times","multiplication sign, U+00D7 ISOnum" },
-+{ 216, "Oslash","latin capital letter O with stroke latin capital letter O slash, U+00D8 ISOlat1" },
-+{ 217, "Ugrave","latin capital letter U with grave, U+00D9 ISOlat1" },
-+{ 218, "Uacute","latin capital letter U with acute, U+00DA ISOlat1" },
-+{ 219, "Ucirc","latin capital letter U with circumflex, U+00DB ISOlat1" },
-+{ 220, "Uuml", "latin capital letter U with diaeresis, U+00DC ISOlat1" },
-+{ 221, "Yacute","latin capital letter Y with acute, U+00DD ISOlat1" },
-+{ 222, "THORN","latin capital letter THORN, U+00DE ISOlat1" },
-+{ 223, "szlig","latin small letter sharp s = ess-zed, U+00DF ISOlat1" },
-+{ 224, "agrave","latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1" },
-+{ 225, "aacute","latin small letter a with acute, U+00E1 ISOlat1" },
-+{ 226, "acirc","latin small letter a with circumflex, U+00E2 ISOlat1" },
-+{ 227, "atilde","latin small letter a with tilde, U+00E3 ISOlat1" },
-+{ 228, "auml", "latin small letter a with diaeresis, U+00E4 ISOlat1" },
-+{ 229, "aring","latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1" },
-+{ 230, "aelig","latin small letter ae = latin small ligature ae, U+00E6 ISOlat1" },
-+{ 231, "ccedil","latin small letter c with cedilla, U+00E7 ISOlat1" },
-+{ 232, "egrave","latin small letter e with grave, U+00E8 ISOlat1" },
-+{ 233, "eacute","latin small letter e with acute, U+00E9 ISOlat1" },
-+{ 234, "ecirc","latin small letter e with circumflex, U+00EA ISOlat1" },
-+{ 235, "euml", "latin small letter e with diaeresis, U+00EB ISOlat1" },
-+{ 236, "igrave","latin small letter i with grave, U+00EC ISOlat1" },
-+{ 237, "iacute","latin small letter i with acute, U+00ED ISOlat1" },
-+{ 238, "icirc","latin small letter i with circumflex, U+00EE ISOlat1" },
-+{ 239, "iuml", "latin small letter i with diaeresis, U+00EF ISOlat1" },
-+{ 240, "eth", "latin small letter eth, U+00F0 ISOlat1" },
-+{ 241, "ntilde","latin small letter n with tilde, U+00F1 ISOlat1" },
-+{ 242, "ograve","latin small letter o with grave, U+00F2 ISOlat1" },
-+{ 243, "oacute","latin small letter o with acute, U+00F3 ISOlat1" },
-+{ 244, "ocirc","latin small letter o with circumflex, U+00F4 ISOlat1" },
-+{ 245, "otilde","latin small letter o with tilde, U+00F5 ISOlat1" },
-+{ 246, "ouml", "latin small letter o with diaeresis, U+00F6 ISOlat1" },
-+{ 247, "divide","division sign, U+00F7 ISOnum" },
-+{ 248, "oslash","latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1" },
-+{ 249, "ugrave","latin small letter u with grave, U+00F9 ISOlat1" },
-+{ 250, "uacute","latin small letter u with acute, U+00FA ISOlat1" },
-+{ 251, "ucirc","latin small letter u with circumflex, U+00FB ISOlat1" },
-+{ 252, "uuml", "latin small letter u with diaeresis, U+00FC ISOlat1" },
-+{ 253, "yacute","latin small letter y with acute, U+00FD ISOlat1" },
-+{ 254, "thorn","latin small letter thorn with, U+00FE ISOlat1" },
-+{ 255, "yuml", "latin small letter y with diaeresis, U+00FF ISOlat1" },
-+
-+{ 338, "OElig","latin capital ligature OE, U+0152 ISOlat2" },
-+{ 339, "oelig","latin small ligature oe, U+0153 ISOlat2" },
-+{ 352, "Scaron","latin capital letter S with caron, U+0160 ISOlat2" },
-+{ 353, "scaron","latin small letter s with caron, U+0161 ISOlat2" },
-+{ 376, "Yuml", "latin capital letter Y with diaeresis, U+0178 ISOlat2" },
-+
-+/*
-+ * Anything below should really be kept as entities references
-+ */
-+{ 402, "fnof", "latin small f with hook = function = florin, U+0192 ISOtech" },
-+
-+{ 710, "circ", "modifier letter circumflex accent, U+02C6 ISOpub" },
-+{ 732, "tilde","small tilde, U+02DC ISOdia" },
-+
-+{ 913, "Alpha","greek capital letter alpha, U+0391" },
-+{ 914, "Beta", "greek capital letter beta, U+0392" },
-+{ 915, "Gamma","greek capital letter gamma, U+0393 ISOgrk3" },
-+{ 916, "Delta","greek capital letter delta, U+0394 ISOgrk3" },
-+{ 917, "Epsilon","greek capital letter epsilon, U+0395" },
-+{ 918, "Zeta", "greek capital letter zeta, U+0396" },
-+{ 919, "Eta", "greek capital letter eta, U+0397" },
-+{ 920, "Theta","greek capital letter theta, U+0398 ISOgrk3" },
-+{ 921, "Iota", "greek capital letter iota, U+0399" },
-+{ 922, "Kappa","greek capital letter kappa, U+039A" },
-+{ 923, "Lambda""greek capital letter lambda, U+039B ISOgrk3" },
-+{ 924, "Mu", "greek capital letter mu, U+039C" },
-+{ 925, "Nu", "greek capital letter nu, U+039D" },
-+{ 926, "Xi", "greek capital letter xi, U+039E ISOgrk3" },
-+{ 927, "Omicron","greek capital letter omicron, U+039F" },
-+{ 928, "Pi", "greek capital letter pi, U+03A0 ISOgrk3" },
-+{ 929, "Rho", "greek capital letter rho, U+03A1" },
-+{ 931, "Sigma","greek capital letter sigma, U+03A3 ISOgrk3" },
-+{ 932, "Tau", "greek capital letter tau, U+03A4" },
-+{ 933, "Upsilon","greek capital letter upsilon, U+03A5 ISOgrk3" },
-+{ 934, "Phi", "greek capital letter phi, U+03A6 ISOgrk3" },
-+{ 935, "Chi", "greek capital letter chi, U+03A7" },
-+{ 936, "Psi", "greek capital letter psi, U+03A8 ISOgrk3" },
-+{ 937, "Omega","greek capital letter omega, U+03A9 ISOgrk3" },
-+
-+{ 945, "alpha","greek small letter alpha, U+03B1 ISOgrk3" },
-+{ 946, "beta", "greek small letter beta, U+03B2 ISOgrk3" },
-+{ 947, "gamma","greek small letter gamma, U+03B3 ISOgrk3" },
-+{ 948, "delta","greek small letter delta, U+03B4 ISOgrk3" },
-+{ 949, "epsilon","greek small letter epsilon, U+03B5 ISOgrk3" },
-+{ 950, "zeta", "greek small letter zeta, U+03B6 ISOgrk3" },
-+{ 951, "eta", "greek small letter eta, U+03B7 ISOgrk3" },
-+{ 952, "theta","greek small letter theta, U+03B8 ISOgrk3" },
-+{ 953, "iota", "greek small letter iota, U+03B9 ISOgrk3" },
-+{ 954, "kappa","greek small letter kappa, U+03BA ISOgrk3" },
-+{ 955, "lambda","greek small letter lambda, U+03BB ISOgrk3" },
-+{ 956, "mu", "greek small letter mu, U+03BC ISOgrk3" },
-+{ 957, "nu", "greek small letter nu, U+03BD ISOgrk3" },
-+{ 958, "xi", "greek small letter xi, U+03BE ISOgrk3" },
-+{ 959, "omicron","greek small letter omicron, U+03BF NEW" },
-+{ 960, "pi", "greek small letter pi, U+03C0 ISOgrk3" },
-+{ 961, "rho", "greek small letter rho, U+03C1 ISOgrk3" },
-+{ 962, "sigmaf","greek small letter final sigma, U+03C2 ISOgrk3" },
-+{ 963, "sigma","greek small letter sigma, U+03C3 ISOgrk3" },
-+{ 964, "tau", "greek small letter tau, U+03C4 ISOgrk3" },
-+{ 965, "upsilon","greek small letter upsilon, U+03C5 ISOgrk3" },
-+{ 966, "phi", "greek small letter phi, U+03C6 ISOgrk3" },
-+{ 967, "chi", "greek small letter chi, U+03C7 ISOgrk3" },
-+{ 968, "psi", "greek small letter psi, U+03C8 ISOgrk3" },
-+{ 969, "omega","greek small letter omega, U+03C9 ISOgrk3" },
-+{ 977, "thetasym","greek small letter theta symbol, U+03D1 NEW" },
-+{ 978, "upsih","greek upsilon with hook symbol, U+03D2 NEW" },
-+{ 982, "piv", "greek pi symbol, U+03D6 ISOgrk3" },
-+
-+{ 8194, "ensp", "en space, U+2002 ISOpub" },
-+{ 8195, "emsp", "em space, U+2003 ISOpub" },
-+{ 8201, "thinsp","thin space, U+2009 ISOpub" },
-+{ 8204, "zwnj", "zero width non-joiner, U+200C NEW RFC 2070" },
-+{ 8205, "zwj", "zero width joiner, U+200D NEW RFC 2070" },
-+{ 8206, "lrm", "left-to-right mark, U+200E NEW RFC 2070" },
-+{ 8207, "rlm", "right-to-left mark, U+200F NEW RFC 2070" },
-+{ 8211, "ndash","en dash, U+2013 ISOpub" },
-+{ 8212, "mdash","em dash, U+2014 ISOpub" },
-+{ 8216, "lsquo","left single quotation mark, U+2018 ISOnum" },
-+{ 8217, "rsquo","right single quotation mark, U+2019 ISOnum" },
-+{ 8218, "sbquo","single low-9 quotation mark, U+201A NEW" },
-+{ 8220, "ldquo","left double quotation mark, U+201C ISOnum" },
-+{ 8221, "rdquo","right double quotation mark, U+201D ISOnum" },
-+{ 8222, "bdquo","double low-9 quotation mark, U+201E NEW" },
-+{ 8224, "dagger","dagger, U+2020 ISOpub" },
-+{ 8225, "Dagger","double dagger, U+2021 ISOpub" },
-+
-+{ 8226, "bull", "bullet = black small circle, U+2022 ISOpub" },
-+{ 8230, "hellip","horizontal ellipsis = three dot leader, U+2026 ISOpub" },
-+
-+{ 8240, "permil","per mille sign, U+2030 ISOtech" },
-+
-+{ 8242, "prime","prime = minutes = feet, U+2032 ISOtech" },
-+{ 8243, "Prime","double prime = seconds = inches, U+2033 ISOtech" },
-+
-+{ 8249, "lsaquo","single left-pointing angle quotation mark, U+2039 ISO proposed" },
-+{ 8250, "rsaquo","single right-pointing angle quotation mark, U+203A ISO proposed" },
-+
-+{ 8254, "oline","overline = spacing overscore, U+203E NEW" },
-+{ 8260, "frasl","fraction slash, U+2044 NEW" },
-+
-+{ 8364, "euro", "euro sign, U+20AC NEW" },
-+
-+{ 8465, "image","blackletter capital I = imaginary part, U+2111 ISOamso" },
-+{ 8472, "weierp","script capital P = power set = Weierstrass p, U+2118 ISOamso" },
-+{ 8476, "real", "blackletter capital R = real part symbol, U+211C ISOamso" },
-+{ 8482, "trade","trade mark sign, U+2122 ISOnum" },
-+{ 8501, "alefsym","alef symbol = first transfinite cardinal, U+2135 NEW" },
-+{ 8592, "larr", "leftwards arrow, U+2190 ISOnum" },
-+{ 8593, "uarr", "upwards arrow, U+2191 ISOnum" },
-+{ 8594, "rarr", "rightwards arrow, U+2192 ISOnum" },
-+{ 8595, "darr", "downwards arrow, U+2193 ISOnum" },
-+{ 8596, "harr", "left right arrow, U+2194 ISOamsa" },
-+{ 8629, "crarr","downwards arrow with corner leftwards = carriage return, U+21B5 NEW" },
-+{ 8656, "lArr", "leftwards double arrow, U+21D0 ISOtech" },
-+{ 8657, "uArr", "upwards double arrow, U+21D1 ISOamsa" },
-+{ 8658, "rArr", "rightwards double arrow, U+21D2 ISOtech" },
-+{ 8659, "dArr", "downwards double arrow, U+21D3 ISOamsa" },
-+{ 8660, "hArr", "left right double arrow, U+21D4 ISOamsa" },
-+
-+{ 8704, "forall","for all, U+2200 ISOtech" },
-+{ 8706, "part", "partial differential, U+2202 ISOtech" },
-+{ 8707, "exist","there exists, U+2203 ISOtech" },
-+{ 8709, "empty","empty set = null set = diameter, U+2205 ISOamso" },
-+{ 8711, "nabla","nabla = backward difference, U+2207 ISOtech" },
-+{ 8712, "isin", "element of, U+2208 ISOtech" },
-+{ 8713, "notin","not an element of, U+2209 ISOtech" },
-+{ 8715, "ni", "contains as member, U+220B ISOtech" },
-+{ 8719, "prod", "n-ary product = product sign, U+220F ISOamsb" },
-+{ 8721, "sum", "n-ary sumation, U+2211 ISOamsb" },
-+{ 8722, "minus","minus sign, U+2212 ISOtech" },
-+{ 8727, "lowast","asterisk operator, U+2217 ISOtech" },
-+{ 8730, "radic","square root = radical sign, U+221A ISOtech" },
-+{ 8733, "prop", "proportional to, U+221D ISOtech" },
-+{ 8734, "infin","infinity, U+221E ISOtech" },
-+{ 8736, "ang", "angle, U+2220 ISOamso" },
-+{ 8743, "and", "logical and = wedge, U+2227 ISOtech" },
-+{ 8744, "or", "logical or = vee, U+2228 ISOtech" },
-+{ 8745, "cap", "intersection = cap, U+2229 ISOtech" },
-+{ 8746, "cup", "union = cup, U+222A ISOtech" },
-+{ 8747, "int", "integral, U+222B ISOtech" },
-+{ 8756, "there4","therefore, U+2234 ISOtech" },
-+{ 8764, "sim", "tilde operator = varies with = similar to, U+223C ISOtech" },
-+{ 8773, "cong", "approximately equal to, U+2245 ISOtech" },
-+{ 8776, "asymp","almost equal to = asymptotic to, U+2248 ISOamsr" },
-+{ 8800, "ne", "not equal to, U+2260 ISOtech" },
-+{ 8801, "equiv","identical to, U+2261 ISOtech" },
-+{ 8804, "le", "less-than or equal to, U+2264 ISOtech" },
-+{ 8805, "ge", "greater-than or equal to, U+2265 ISOtech" },
-+{ 8834, "sub", "subset of, U+2282 ISOtech" },
-+{ 8835, "sup", "superset of, U+2283 ISOtech" },
-+{ 8836, "nsub", "not a subset of, U+2284 ISOamsn" },
-+{ 8838, "sube", "subset of or equal to, U+2286 ISOtech" },
-+{ 8839, "supe", "superset of or equal to, U+2287 ISOtech" },
-+{ 8853, "oplus","circled plus = direct sum, U+2295 ISOamsb" },
-+{ 8855, "otimes","circled times = vector product, U+2297 ISOamsb" },
-+{ 8869, "perp", "up tack = orthogonal to = perpendicular, U+22A5 ISOtech" },
-+{ 8901, "sdot", "dot operator, U+22C5 ISOamsb" },
-+{ 8968, "lceil","left ceiling = apl upstile, U+2308 ISOamsc" },
-+{ 8969, "rceil","right ceiling, U+2309 ISOamsc" },
-+{ 8970, "lfloor","left floor = apl downstile, U+230A ISOamsc" },
-+{ 8971, "rfloor","right floor, U+230B ISOamsc" },
-+{ 9001, "lang", "left-pointing angle bracket = bra, U+2329 ISOtech" },
-+{ 9002, "rang", "right-pointing angle bracket = ket, U+232A ISOtech" },
-+{ 9674, "loz", "lozenge, U+25CA ISOpub" },
-+
-+{ 9824, "spades","black spade suit, U+2660 ISOpub" },
-+{ 9827, "clubs","black club suit = shamrock, U+2663 ISOpub" },
-+{ 9829, "hearts","black heart suit = valentine, U+2665 ISOpub" },
-+{ 9830, "diams","black diamond suit, U+2666 ISOpub" },
-+
-+};
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to handle entities *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * Macro used to grow the current buffer.
-+ */
-+#define growBuffer(buffer) { \
-+ buffer##_size *= 2; \
-+ buffer = (xmlChar *) xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
-+ if (buffer == NULL) { \
-+ perror("realloc failed"); \
-+ return(NULL); \
-+ } \
-+}
-+
-+/**
-+ * htmlEntityLookup:
-+ * @name: the entity name
-+ *
-+ * Lookup the given entity in EntitiesTable
-+ *
-+ * TODO: the linear scan is really ugly, an hash table is really needed.
-+ *
-+ * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
-+ */
-+htmlEntityDescPtr
-+htmlEntityLookup(const xmlChar *name) {
-+ int i;
-+
-+ for (i = 0;i < (sizeof(html40EntitiesTable)/
-+ sizeof(html40EntitiesTable[0]));i++) {
-+ if (xmlStrEqual(name, BAD_CAST html40EntitiesTable[i].name)) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", name);
-+#endif
-+ return(&html40EntitiesTable[i]);
-+ }
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * htmlEntityValueLookup:
-+ * @value: the entity's unicode value
-+ *
-+ * Lookup the given entity in EntitiesTable
-+ *
-+ * TODO: the linear scan is really ugly, an hash table is really needed.
-+ *
-+ * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
-+ */
-+htmlEntityDescPtr
-+htmlEntityValueLookup(int value) {
-+ int i;
-+#ifdef DEBUG
-+ int lv = 0;
-+#endif
-+
-+ for (i = 0;i < (sizeof(html40EntitiesTable)/
-+ sizeof(html40EntitiesTable[0]));i++) {
-+ if ((unsigned int) html40EntitiesTable[i].value >= value) {
-+ if ((unsigned int) html40EntitiesTable[i].value > value)
-+ break;
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", html40EntitiesTable[i].name);
-+#endif
-+ return(&html40EntitiesTable[i]);
-+ }
-+#ifdef DEBUG
-+ if (lv > html40EntitiesTable[i].value) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "html40EntitiesTable[] is not sorted (%d > %d)!\n",
-+ lv, html40EntitiesTable[i].value);
-+ }
-+ lv = html40EntitiesTable[i].value;
-+#endif
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * UTF8ToHtml:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of UTF-8 chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
-+ * plus HTML entities block of chars out.
-+ *
-+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of octets consumed.
-+ */
-+int
-+UTF8ToHtml(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen) {
-+ const unsigned char* processed = in;
-+ const unsigned char* outend;
-+ const unsigned char* outstart = out;
-+ const unsigned char* instart = in;
-+ const unsigned char* inend;
-+ unsigned int c, d;
-+ int trailing;
-+
-+ if (in == NULL) {
-+ /*
-+ * initialization nothing to do
-+ */
-+ *outlen = 0;
-+ *inlen = 0;
-+ return(0);
-+ }
-+ inend = in + (*inlen);
-+ outend = out + (*outlen);
-+ while (in < inend) {
-+ d = *in++;
-+ if (d < 0x80) { c= d; trailing= 0; }
-+ else if (d < 0xC0) {
-+ /* trailing byte in leading position */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-+ else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-+ else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-+ else {
-+ /* no chance for this in Ascii */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+
-+ if (inend - in < trailing) {
-+ break;
-+ }
-+
-+ for ( ; trailing; trailing--) {
-+ if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
-+ break;
-+ c <<= 6;
-+ c |= d & 0x3F;
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (c < 0x80) {
-+ if (out + 1 >= outend)
-+ break;
-+ *out++ = c;
-+ } else {
-+ int len;
-+ htmlEntityDescPtr ent;
-+
-+ /*
-+ * Try to lookup a predefined HTML entity for it
-+ */
-+
-+ ent = htmlEntityValueLookup(c);
-+ if (ent == NULL) {
-+ /* no chance for this in Ascii */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+ len = strlen(ent->name);
-+ if (out + 2 + len >= outend)
-+ break;
-+ *out++ = '&';
-+ memcpy(out, ent->name, len);
-+ out += len;
-+ *out++ = ';';
-+ }
-+ processed = in;
-+ }
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(0);
-+}
-+
-+/**
-+ * htmlEncodeEntities:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of UTF-8 chars
-+ * @inlen: the length of @in
-+ * @quoteChar: the quote character to escape (' or ") or zero.
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
-+ * plus HTML entities block of chars out.
-+ *
-+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of octets consumed.
-+ */
-+int
-+htmlEncodeEntities(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen, int quoteChar) {
-+ const unsigned char* processed = in;
-+ const unsigned char* outend = out + (*outlen);
-+ const unsigned char* outstart = out;
-+ const unsigned char* instart = in;
-+ const unsigned char* inend = in + (*inlen);
-+ unsigned int c, d;
-+ int trailing;
-+
-+ while (in < inend) {
-+ d = *in++;
-+ if (d < 0x80) { c= d; trailing= 0; }
-+ else if (d < 0xC0) {
-+ /* trailing byte in leading position */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-+ else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-+ else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-+ else {
-+ /* no chance for this in Ascii */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+
-+ if (inend - in < trailing)
-+ break;
-+
-+ while (trailing--) {
-+ if (((d= *in++) & 0xC0) != 0x80) {
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+ c <<= 6;
-+ c |= d & 0x3F;
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (c < 0x80 && c != quoteChar && c != '&' && c != '<' && c != '>') {
-+ if (out >= outend)
-+ break;
-+ *out++ = c;
-+ } else {
-+ htmlEntityDescPtr ent;
-+ const char *cp;
-+ char nbuf[16];
-+ int len;
-+
-+ /*
-+ * Try to lookup a predefined HTML entity for it
-+ */
-+ ent = htmlEntityValueLookup(c);
-+ if (ent == NULL) {
-+ sprintf(nbuf, "#%u", c);
-+ cp = nbuf;
-+ }
-+ else
-+ cp = ent->name;
-+ len = strlen(cp);
-+ if (out + 2 + len > outend)
-+ break;
-+ *out++ = '&';
-+ memcpy(out, cp, len);
-+ out += len;
-+ *out++ = ';';
-+ }
-+ processed = in;
-+ }
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(0);
-+}
-+
-+/**
-+ * htmlDecodeEntities:
-+ * @ctxt: the parser context
-+ * @len: the len to decode (in bytes !), -1 for no size limit
-+ * @end: an end marker xmlChar, 0 if none
-+ * @end2: an end marker xmlChar, 0 if none
-+ * @end3: an end marker xmlChar, 0 if none
-+ *
-+ * Subtitute the HTML entities by their value
-+ *
-+ * DEPRECATED !!!!
-+ *
-+ * Returns A newly allocated string with the substitution done. The caller
-+ * must deallocate it !
-+ */
-+xmlChar *
-+htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len,
-+ xmlChar end, xmlChar end2, xmlChar end3) {
-+ xmlChar *name = NULL;
-+ xmlChar *buffer = NULL;
-+ unsigned int buffer_size = 0;
-+ unsigned int nbchars = 0;
-+ htmlEntityDescPtr ent;
-+ unsigned int max = (unsigned int) len;
-+ int c,l;
-+
-+ if (ctxt->depth > 40) {
-+ ctxt->errNo = XML_ERR_ENTITY_LOOP;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Detected entity reference loop\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * allocate a translation buffer.
-+ */
-+ buffer_size = HTML_PARSER_BIG_BUFFER_SIZE;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("xmlDecodeEntities: malloc failed");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Ok loop until we reach one of the ending char or a size limit.
-+ */
-+ c = CUR_CHAR(l);
-+ while ((nbchars < max) && (c != end) &&
-+ (c != end2) && (c != end3)) {
-+
-+ if (c == 0) break;
-+ if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
-+ int val = htmlParseCharRef(ctxt);
-+ COPY_BUF(0,buffer,nbchars,val);
-+ NEXTL(l);
-+ } else if ((c == '&') && (ctxt->token != '&')) {
-+ ent = htmlParseEntityRef(ctxt, &name);
-+ if (name != NULL) {
-+ if (ent != NULL) {
-+ int val = ent->value;
-+ COPY_BUF(0,buffer,nbchars,val);
-+ NEXTL(l);
-+ } else {
-+ const xmlChar *cur = name;
-+
-+ buffer[nbchars++] = '&';
-+ if (nbchars > buffer_size - HTML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ while (*cur != 0) {
-+ buffer[nbchars++] = *cur++;
-+ }
-+ buffer[nbchars++] = ';';
-+ }
-+ }
-+ } else {
-+ COPY_BUF(l,buffer,nbchars,c);
-+ NEXTL(l);
-+ if (nbchars > buffer_size - HTML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ }
-+ c = CUR_CHAR(l);
-+ }
-+ buffer[nbchars++] = 0;
-+ return(buffer);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to handle streams *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlFreeInputStream:
-+ * @input: an htmlParserInputPtr
-+ *
-+ * Free up an input stream.
-+ */
-+void
-+htmlFreeInputStream(htmlParserInputPtr input) {
-+ if (input == NULL) return;
-+
-+ if (input->filename != NULL) xmlFree((char *) input->filename);
-+ if (input->directory != NULL) xmlFree((char *) input->directory);
-+ if ((input->free != NULL) && (input->base != NULL))
-+ input->free((xmlChar *) input->base);
-+ if (input->buf != NULL)
-+ xmlFreeParserInputBuffer(input->buf);
-+ memset(input, -1, sizeof(htmlParserInput));
-+ xmlFree(input);
-+}
-+
-+/**
-+ * htmlNewInputStream:
-+ * @ctxt: an HTML parser context
-+ *
-+ * Create a new input stream structure
-+ * Returns the new input stream or NULL
-+ */
-+htmlParserInputPtr
-+htmlNewInputStream(htmlParserCtxtPtr ctxt) {
-+ htmlParserInputPtr input;
-+
-+ input = (xmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
-+ if (input == NULL) {
-+ ctxt->errNo = XML_ERR_NO_MEMORY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "malloc: couldn't allocate a new input stream\n");
-+ return(NULL);
-+ }
-+ memset(input, 0, sizeof(htmlParserInput));
-+ input->filename = NULL;
-+ input->directory = NULL;
-+ input->base = NULL;
-+ input->cur = NULL;
-+ input->buf = NULL;
-+ input->line = 1;
-+ input->col = 1;
-+ input->buf = NULL;
-+ input->free = NULL;
-+ input->version = NULL;
-+ input->consumed = 0;
-+ input->length = 0;
-+ return(input);
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions, cleanup needed ? *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * areBlanks:
-+ * @ctxt: an HTML parser context
-+ * @str: a xmlChar *
-+ * @len: the size of @str
-+ *
-+ * Is this a sequence of blank chars that one can ignore ?
-+ *
-+ * Returns 1 if ignorable 0 otherwise.
-+ */
-+
-+static int areBlanks(htmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
-+ int i;
-+ xmlNodePtr lastChild;
-+
-+ for (i = 0;i < len;i++)
-+ if (!(IS_BLANK(str[i]))) return(0);
-+
-+ if (CUR == 0) return(1);
-+ if (CUR != '<') return(0);
-+ if (ctxt->name == NULL)
-+ return(1);
-+ if (xmlStrEqual(ctxt->name, BAD_CAST"html"))
-+ return(1);
-+ if (xmlStrEqual(ctxt->name, BAD_CAST"head"))
-+ return(1);
-+ if (xmlStrEqual(ctxt->name, BAD_CAST"body"))
-+ return(1);
-+ if (ctxt->node == NULL) return(0);
-+ lastChild = xmlGetLastChild(ctxt->node);
-+ if (lastChild == NULL) {
-+ if (ctxt->node->content != NULL) return(0);
-+ } else if (xmlNodeIsText(lastChild)) {
-+ return(0);
-+ } else if (xmlStrEqual(lastChild->name, BAD_CAST"b")) {
-+ return(0);
-+ } else if (xmlStrEqual(lastChild->name, BAD_CAST"bold")) {
-+ return(0);
-+ } else if (xmlStrEqual(lastChild->name, BAD_CAST"em")) {
-+ return(0);
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * htmlHandleEntity:
-+ * @ctxt: an HTML parser context
-+ * @entity: an XML entity pointer.
-+ *
-+ * Default handling of an HTML entity, call the parser with the
-+ * substitution string
-+ */
-+
-+void
-+htmlHandleEntity(htmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-+ int len;
-+
-+ if (entity->content == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "htmlHandleEntity %s: content == NULL\n",
-+ entity->name);
-+ ctxt->wellFormed = 0;
-+ return;
-+ }
-+ len = xmlStrlen(entity->content);
-+
-+ /*
-+ * Just handle the content as a set of chars.
-+ */
-+ htmlCheckParagraph(ctxt);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, entity->content, len);
-+
-+}
-+
-+/**
-+ * htmlNewDocNoDtD:
-+ * @URI: URI for the dtd, or NULL
-+ * @ExternalID: the external ID of the DTD, or NULL
-+ *
-+ * Returns a new document, do not intialize the DTD if not provided
-+ */
-+htmlDocPtr
-+htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
-+ xmlDocPtr cur;
-+
-+ /*
-+ * Allocate a new document and fill the fields.
-+ */
-+ cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewDoc : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlDoc));
-+
-+ cur->type = XML_HTML_DOCUMENT_NODE;
-+ cur->version = NULL;
-+ cur->intSubset = NULL;
-+ if ((ExternalID != NULL) ||
-+ (URI != NULL))
-+ xmlCreateIntSubset(cur, BAD_CAST "HTML", ExternalID, URI);
-+ cur->doc = cur;
-+ cur->name = NULL;
-+ cur->children = NULL;
-+ cur->extSubset = NULL;
-+ cur->oldNs = NULL;
-+ cur->encoding = NULL;
-+ cur->standalone = 1;
-+ cur->compression = 0;
-+ cur->ids = NULL;
-+ cur->refs = NULL;
-+#ifndef XML_WITHOUT_CORBA
-+ cur->_private = NULL;
-+#endif
-+ return(cur);
-+}
-+
-+/**
-+ * htmlNewDoc:
-+ * @URI: URI for the dtd, or NULL
-+ * @ExternalID: the external ID of the DTD, or NULL
-+ *
-+ * Returns a new document
-+ */
-+htmlDocPtr
-+htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID) {
-+ if ((URI == NULL) && (ExternalID == NULL))
-+ return(htmlNewDocNoDtD(
-+ BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
-+ BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd"));
-+
-+ return(htmlNewDocNoDtD(URI, ExternalID));
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * The parser itself *
-+ * Relates to http://www.w3.org/TR/html40 *
-+ * *
-+ ************************************************************************/
-+
-+/************************************************************************
-+ * *
-+ * The parser itself *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlParseHTMLName:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML tag or attribute name, note that we convert it to lowercase
-+ * since HTML names are not case-sensitive.
-+ *
-+ * Returns the Tag Name parsed or NULL
-+ */
-+
-+xmlChar *
-+htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
-+ xmlChar *ret = NULL;
-+ int i = 0;
-+ xmlChar loc[HTML_PARSER_BUFFER_SIZE];
-+
-+ if (!IS_LETTER(CUR) && (CUR != '_') &&
-+ (CUR != ':')) return(NULL);
-+
-+ while ((i < HTML_PARSER_BUFFER_SIZE) &&
-+ ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == ':') || (CUR == '-') || (CUR == '_'))) {
-+ if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
-+ else loc[i] = CUR;
-+ i++;
-+
-+ NEXT;
-+ }
-+
-+ ret = xmlStrndup(loc, i);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParseName:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML name, this routine is case sensistive.
-+ *
-+ * Returns the Name parsed or NULL
-+ */
-+
-+xmlChar *
-+htmlParseName(htmlParserCtxtPtr ctxt) {
-+ xmlChar buf[HTML_MAX_NAMELEN];
-+ int len = 0;
-+
-+ GROW;
-+ if (!IS_LETTER(CUR) && (CUR != '_')) {
-+ return(NULL);
-+ }
-+
-+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == '.') || (CUR == '-') ||
-+ (CUR == '_') || (CUR == ':') ||
-+ (IS_COMBINING(CUR)) ||
-+ (IS_EXTENDER(CUR))) {
-+ buf[len++] = CUR;
-+ NEXT;
-+ if (len >= HTML_MAX_NAMELEN) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlParseName: reached HTML_MAX_NAMELEN limit\n");
-+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == '.') || (CUR == '-') ||
-+ (CUR == '_') || (CUR == ':') ||
-+ (IS_COMBINING(CUR)) ||
-+ (IS_EXTENDER(CUR)))
-+ NEXT;
-+ break;
-+ }
-+ }
-+ return(xmlStrndup(buf, len));
-+}
-+
-+/**
-+ * htmlParseHTMLAttribute:
-+ * @ctxt: an HTML parser context
-+ * @stop: a char stop value
-+ *
-+ * parse an HTML attribute value till the stop (quote), if
-+ * stop is 0 then it stops at the first space
-+ *
-+ * Returns the attribute parsed or NULL
-+ */
-+
-+xmlChar *
-+htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
-+ xmlChar *buffer = NULL;
-+ int buffer_size = 0;
-+ xmlChar *out = NULL;
-+ xmlChar *name = NULL;
-+
-+ xmlChar *cur = NULL;
-+ htmlEntityDescPtr ent;
-+
-+ /*
-+ * allocate a translation buffer.
-+ */
-+ buffer_size = HTML_PARSER_BUFFER_SIZE;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("htmlParseHTMLAttribute: malloc failed");
-+ return(NULL);
-+ }
-+ out = buffer;
-+
-+ /*
-+ * Ok loop until we reach one of the ending chars
-+ */
-+ while ((CUR != 0) && (CUR != stop) && (CUR != '>')) {
-+ if ((stop == 0) && (IS_BLANK(CUR))) break;
-+ if (CUR == '&') {
-+ if (NXT(1) == '#') {
-+ unsigned int c;
-+ int bits;
-+
-+ c = htmlParseCharRef(ctxt);
-+ if (c < 0x80)
-+ { *out++ = c; bits= -6; }
-+ else if (c < 0x800)
-+ { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000)
-+ { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else
-+ { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ *out++ = ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ } else {
-+ ent = htmlParseEntityRef(ctxt, &name);
-+ if (name == NULL) {
-+ *out++ = '&';
-+ if (out - buffer > buffer_size - 100) {
-+ int index = out - buffer;
-+
-+ growBuffer(buffer);
-+ out = &buffer[index];
-+ }
-+ } else if (ent == NULL) {
-+ *out++ = '&';
-+ cur = name;
-+ while (*cur != 0) {
-+ if (out - buffer > buffer_size - 100) {
-+ int index = out - buffer;
-+
-+ growBuffer(buffer);
-+ out = &buffer[index];
-+ }
-+ *out++ = *cur++;
-+ }
-+ xmlFree(name);
-+ } else {
-+ unsigned int c;
-+ int bits;
-+
-+ if (out - buffer > buffer_size - 100) {
-+ int index = out - buffer;
-+
-+ growBuffer(buffer);
-+ out = &buffer[index];
-+ }
-+ c = (xmlChar)ent->value;
-+ if (c < 0x80)
-+ { *out++ = c; bits= -6; }
-+ else if (c < 0x800)
-+ { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000)
-+ { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else
-+ { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ *out++ = ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ xmlFree(name);
-+ }
-+ }
-+ } else {
-+ unsigned int c;
-+ int bits, l;
-+
-+ if (out - buffer > buffer_size - 100) {
-+ int index = out - buffer;
-+
-+ growBuffer(buffer);
-+ out = &buffer[index];
-+ }
-+ c = CUR_CHAR(l);
-+ if (c < 0x80)
-+ { *out++ = c; bits= -6; }
-+ else if (c < 0x800)
-+ { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000)
-+ { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else
-+ { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ *out++ = ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ NEXT;
-+ }
-+ }
-+ *out++ = 0;
-+ return(buffer);
-+}
-+
-+/**
-+ * htmlParseNmtoken:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML Nmtoken.
-+ *
-+ * Returns the Nmtoken parsed or NULL
-+ */
-+
-+xmlChar *
-+htmlParseNmtoken(htmlParserCtxtPtr ctxt) {
-+ xmlChar buf[HTML_MAX_NAMELEN];
-+ int len = 0;
-+
-+ GROW;
-+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == '.') || (CUR == '-') ||
-+ (CUR == '_') || (CUR == ':') ||
-+ (IS_COMBINING(CUR)) ||
-+ (IS_EXTENDER(CUR))) {
-+ buf[len++] = CUR;
-+ NEXT;
-+ if (len >= HTML_MAX_NAMELEN) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlParseNmtoken: reached HTML_MAX_NAMELEN limit\n");
-+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == '.') || (CUR == '-') ||
-+ (CUR == '_') || (CUR == ':') ||
-+ (IS_COMBINING(CUR)) ||
-+ (IS_EXTENDER(CUR)))
-+ NEXT;
-+ break;
-+ }
-+ }
-+ return(xmlStrndup(buf, len));
-+}
-+
-+/**
-+ * htmlParseEntityRef:
-+ * @ctxt: an HTML parser context
-+ * @str: location to store the entity name
-+ *
-+ * parse an HTML ENTITY references
-+ *
-+ * [68] EntityRef ::= '&' Name ';'
-+ *
-+ * Returns the associated htmlEntityDescPtr if found, or NULL otherwise,
-+ * if non-NULL *str will have to be freed by the caller.
-+ */
-+htmlEntityDescPtr
-+htmlParseEntityRef(htmlParserCtxtPtr ctxt, xmlChar **str) {
-+ xmlChar *name;
-+ htmlEntityDescPtr ent = NULL;
-+ *str = NULL;
-+
-+ if (CUR == '&') {
-+ NEXT;
-+ name = htmlParseName(ctxt);
-+ if (name == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "htmlParseEntityRef: no name\n");
-+ ctxt->wellFormed = 0;
-+ } else {
-+ GROW;
-+ if (CUR == ';') {
-+ *str = name;
-+
-+ /*
-+ * Lookup the entity in the table.
-+ */
-+ ent = htmlEntityLookup(name);
-+ if (ent != NULL) /* OK that's ugly !!! */
-+ NEXT;
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseEntityRef: expecting ';'\n");
-+ *str = name;
-+ }
-+ }
-+ }
-+ return(ent);
-+}
-+
-+/**
-+ * htmlParseAttValue:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse a value for an attribute
-+ * Note: the parser won't do substitution of entities here, this
-+ * will be handled later in xmlStringGetNodeList, unless it was
-+ * asked for ctxt->replaceEntities != 0
-+ *
-+ * Returns the AttValue parsed or NULL.
-+ */
-+
-+xmlChar *
-+htmlParseAttValue(htmlParserCtxtPtr ctxt) {
-+ xmlChar *ret = NULL;
-+
-+ if (CUR == '"') {
-+ NEXT;
-+ ret = htmlParseHTMLAttribute(ctxt, '"');
-+ if (CUR != '"') {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
-+ ctxt->wellFormed = 0;
-+ } else
-+ NEXT;
-+ } else if (CUR == '\'') {
-+ NEXT;
-+ ret = htmlParseHTMLAttribute(ctxt, '\'');
-+ if (CUR != '\'') {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
-+ ctxt->wellFormed = 0;
-+ } else
-+ NEXT;
-+ } else {
-+ /*
-+ * That's an HTMLism, the attribute value may not be quoted
-+ */
-+ ret = htmlParseHTMLAttribute(ctxt, 0);
-+ if (ret == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "AttValue: no value found\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParseSystemLiteral:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML Literal
-+ *
-+ * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
-+ *
-+ * Returns the SystemLiteral parsed or NULL
-+ */
-+
-+xmlChar *
-+htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
-+ const xmlChar *q;
-+ xmlChar *ret = NULL;
-+
-+ if (CUR == '"') {
-+ NEXT;
-+ q = CUR_PTR;
-+ while ((IS_CHAR(CUR)) && (CUR != '"'))
-+ NEXT;
-+ if (!IS_CHAR(CUR)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
-+ ctxt->wellFormed = 0;
-+ } else {
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+ NEXT;
-+ }
-+ } else if (CUR == '\'') {
-+ NEXT;
-+ q = CUR_PTR;
-+ while ((IS_CHAR(CUR)) && (CUR != '\''))
-+ NEXT;
-+ if (!IS_CHAR(CUR)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
-+ ctxt->wellFormed = 0;
-+ } else {
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+ NEXT;
-+ }
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "SystemLiteral \" or ' expected\n");
-+ ctxt->wellFormed = 0;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParsePubidLiteral:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML public literal
-+ *
-+ * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
-+ *
-+ * Returns the PubidLiteral parsed or NULL.
-+ */
-+
-+xmlChar *
-+htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
-+ const xmlChar *q;
-+ xmlChar *ret = NULL;
-+ /*
-+ * Name ::= (Letter | '_') (NameChar)*
-+ */
-+ if (CUR == '"') {
-+ NEXT;
-+ q = CUR_PTR;
-+ while (IS_PUBIDCHAR(CUR)) NEXT;
-+ if (CUR != '"') {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
-+ ctxt->wellFormed = 0;
-+ } else {
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+ NEXT;
-+ }
-+ } else if (CUR == '\'') {
-+ NEXT;
-+ q = CUR_PTR;
-+ while ((IS_LETTER(CUR)) && (CUR != '\''))
-+ NEXT;
-+ if (!IS_LETTER(CUR)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
-+ ctxt->wellFormed = 0;
-+ } else {
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+ NEXT;
-+ }
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "SystemLiteral \" or ' expected\n");
-+ ctxt->wellFormed = 0;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParseScript:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse the content of an HTML SCRIPT or STYLE element
-+ * http://www.w3.org/TR/html4/sgml/dtd.html#Script
-+ * http://www.w3.org/TR/html4/sgml/dtd.html#StyleSheet
-+ * http://www.w3.org/TR/html4/types.html#type-script
-+ * http://www.w3.org/TR/html4/types.html#h-6.15
-+ * http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2.1
-+ *
-+ * Script data ( %Script; in the DTD) can be the content of the SCRIPT
-+ * element and the value of intrinsic event attributes. User agents must
-+ * not evaluate script data as HTML markup but instead must pass it on as
-+ * data to a script engine.
-+ * NOTES:
-+ * - The content is passed like CDATA
-+ * - the attributes for style and scripting "onXXX" are also described
-+ * as CDATA but SGML allows entities references in attributes so their
-+ * processing is identical as other attributes
-+ */
-+void
-+htmlParseScript(htmlParserCtxtPtr ctxt) {
-+ xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 1];
-+ int nbchar = 0;
-+ xmlChar cur;
-+
-+ SHRINK;
-+ cur = CUR;
-+ while (IS_CHAR(cur)) {
-+ if ((cur == '<') && (NXT(1) == '/')) {
-+ /*
-+ * One should break here, the specification is clear:
-+ * Authors should therefore escape "</" within the content.
-+ * Escape mechanisms are specific to each scripting or
-+ * style sheet language.
-+ */
-+ if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
-+ ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
-+ break; /* while */
-+ }
-+ buf[nbchar++] = cur;
-+ if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
-+ if (ctxt->sax->cdataBlock!= NULL) {
-+ /*
-+ * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
-+ */
-+ ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
-+ }
-+ nbchar = 0;
-+ }
-+ NEXT;
-+ cur = CUR;
-+ }
-+ if (!(IS_CHAR(cur))) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Invalid char in CDATA 0x%X\n", cur);
-+ ctxt->wellFormed = 0;
-+ NEXT;
-+ }
-+
-+ if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (ctxt->sax->cdataBlock!= NULL) {
-+ /*
-+ * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
-+ */
-+ ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
-+ }
-+ }
-+}
-+
-+
-+/**
-+ * htmlParseCharData:
-+ * @ctxt: an HTML parser context
-+ * @cdata: int indicating whether we are within a CDATA section
-+ *
-+ * parse a CharData section.
-+ * if we are within a CDATA section ']]>' marks an end of section.
-+ *
-+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-+ */
-+
-+void
-+htmlParseCharData(htmlParserCtxtPtr ctxt, int cdata) {
-+ xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
-+ int nbchar = 0;
-+ int cur, l;
-+
-+ SHRINK;
-+ cur = CUR_CHAR(l);
-+ while (((cur != '<') || (ctxt->token == '<')) &&
-+ ((cur != '&') || (ctxt->token == '&')) &&
-+ (IS_CHAR(cur))) {
-+ COPY_BUF(l,buf,nbchar,cur);
-+ if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
-+ /*
-+ * Ok the segment is to be consumed as chars.
-+ */
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (areBlanks(ctxt, buf, nbchar)) {
-+ if (ctxt->sax->ignorableWhitespace != NULL)
-+ ctxt->sax->ignorableWhitespace(ctxt->userData,
-+ buf, nbchar);
-+ } else {
-+ htmlCheckParagraph(ctxt);
-+ if (ctxt->sax->characters != NULL)
-+ ctxt->sax->characters(ctxt->userData, buf, nbchar);
-+ }
-+ }
-+ nbchar = 0;
-+ }
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ }
-+ if (nbchar != 0) {
-+ /*
-+ * Ok the segment is to be consumed as chars.
-+ */
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (areBlanks(ctxt, buf, nbchar)) {
-+ if (ctxt->sax->ignorableWhitespace != NULL)
-+ ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
-+ } else {
-+ htmlCheckParagraph(ctxt);
-+ if (ctxt->sax->characters != NULL)
-+ ctxt->sax->characters(ctxt->userData, buf, nbchar);
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * htmlParseExternalID:
-+ * @ctxt: an HTML parser context
-+ * @publicID: a xmlChar** receiving PubidLiteral
-+ * @strict: indicate whether we should restrict parsing to only
-+ * production [75], see NOTE below
-+ *
-+ * Parse an External ID or a Public ID
-+ *
-+ * NOTE: Productions [75] and [83] interract badly since [75] can generate
-+ * 'PUBLIC' S PubidLiteral S SystemLiteral
-+ *
-+ * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-+ * | 'PUBLIC' S PubidLiteral S SystemLiteral
-+ *
-+ * [83] PublicID ::= 'PUBLIC' S PubidLiteral
-+ *
-+ * Returns the function returns SystemLiteral and in the second
-+ * case publicID receives PubidLiteral, is strict is off
-+ * it is possible to return NULL and have publicID set.
-+ */
-+
-+xmlChar *
-+htmlParseExternalID(htmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
-+ xmlChar *URI = NULL;
-+
-+ if ((UPPER == 'S') && (UPP(1) == 'Y') &&
-+ (UPP(2) == 'S') && (UPP(3) == 'T') &&
-+ (UPP(4) == 'E') && (UPP(5) == 'M')) {
-+ SKIP(6);
-+ if (!IS_BLANK(CUR)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'SYSTEM'\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ SKIP_BLANKS;
-+ URI = htmlParseSystemLiteral(ctxt);
-+ if (URI == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseExternalID: SYSTEM, no URI\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ } else if ((UPPER == 'P') && (UPP(1) == 'U') &&
-+ (UPP(2) == 'B') && (UPP(3) == 'L') &&
-+ (UPP(4) == 'I') && (UPP(5) == 'C')) {
-+ SKIP(6);
-+ if (!IS_BLANK(CUR)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'PUBLIC'\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ SKIP_BLANKS;
-+ *publicID = htmlParsePubidLiteral(ctxt);
-+ if (*publicID == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseExternalID: PUBLIC, no Public Identifier\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ SKIP_BLANKS;
-+ if ((CUR == '"') || (CUR == '\'')) {
-+ URI = htmlParseSystemLiteral(ctxt);
-+ }
-+ }
-+ return(URI);
-+}
-+
-+/**
-+ * htmlParseComment:
-+ * @ctxt: an HTML parser context
-+ *
-+ * Parse an XML (SGML) comment <!-- .... -->
-+ *
-+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-+ */
-+void
-+htmlParseComment(htmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len;
-+ int size = HTML_PARSER_BUFFER_SIZE;
-+ int q, ql;
-+ int r, rl;
-+ int cur, l;
-+ xmlParserInputState state;
-+
-+ /*
-+ * Check that there is a comment right here.
-+ */
-+ if ((RAW != '<') || (NXT(1) != '!') ||
-+ (NXT(2) != '-') || (NXT(3) != '-')) return;
-+
-+ state = ctxt->instate;
-+ ctxt->instate = XML_PARSER_COMMENT;
-+ SHRINK;
-+ SKIP(4);
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ ctxt->instate = state;
-+ return;
-+ }
-+ q = CUR_CHAR(ql);
-+ NEXTL(ql);
-+ r = CUR_CHAR(rl);
-+ NEXTL(rl);
-+ cur = CUR_CHAR(l);
-+ len = 0;
-+ while (IS_CHAR(cur) &&
-+ ((cur != '>') ||
-+ (r != '-') || (q != '-'))) {
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ ctxt->instate = state;
-+ return;
-+ }
-+ }
-+ COPY_BUF(ql,buf,len,q);
-+ q = r;
-+ ql = rl;
-+ r = cur;
-+ rl = l;
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ if (cur == 0) {
-+ SHRINK;
-+ GROW;
-+ cur = CUR_CHAR(l);
-+ }
-+ }
-+ buf[len] = 0;
-+ if (!IS_CHAR(cur)) {
-+ ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Comment not terminated \n<!--%.50s\n", buf);
-+ ctxt->wellFormed = 0;
-+ xmlFree(buf);
-+ } else {
-+ NEXT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->comment(ctxt->userData, buf);
-+ xmlFree(buf);
-+ }
-+ ctxt->instate = state;
-+}
-+
-+/**
-+ * htmlParseCharRef:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse Reference declarations
-+ *
-+ * [66] CharRef ::= '&#' [0-9]+ ';' |
-+ * '&#x' [0-9a-fA-F]+ ';'
-+ *
-+ * Returns the value parsed (as an int)
-+ */
-+int
-+htmlParseCharRef(htmlParserCtxtPtr ctxt) {
-+ int val = 0;
-+
-+ if ((CUR == '&') && (NXT(1) == '#') &&
-+ (NXT(2) == 'x')) {
-+ SKIP(3);
-+ while (CUR != ';') {
-+ if ((CUR >= '0') && (CUR <= '9'))
-+ val = val * 16 + (CUR - '0');
-+ else if ((CUR >= 'a') && (CUR <= 'f'))
-+ val = val * 16 + (CUR - 'a') + 10;
-+ else if ((CUR >= 'A') && (CUR <= 'F'))
-+ val = val * 16 + (CUR - 'A') + 10;
-+ else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseCharRef: invalid hexadecimal value\n");
-+ ctxt->wellFormed = 0;
-+ return(0);
-+ }
-+ NEXT;
-+ }
-+ if (CUR == ';')
-+ NEXT;
-+ } else if ((CUR == '&') && (NXT(1) == '#')) {
-+ SKIP(2);
-+ while (CUR != ';') {
-+ if ((CUR >= '0') && (CUR <= '9'))
-+ val = val * 10 + (CUR - '0');
-+ else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseCharRef: invalid decimal value\n");
-+ ctxt->wellFormed = 0;
-+ return(0);
-+ }
-+ NEXT;
-+ }
-+ if (CUR == ';')
-+ NEXT;
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "htmlParseCharRef: invalid value\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ /*
-+ * Check the value IS_CHAR ...
-+ */
-+ if (IS_CHAR(val)) {
-+ return(val);
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "htmlParseCharRef: invalid xmlChar value %d\n",
-+ val);
-+ ctxt->wellFormed = 0;
-+ }
-+ return(0);
-+}
-+
-+
-+/**
-+ * htmlParseDocTypeDecl :
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse a DOCTYPE declaration
-+ *
-+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-+ * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-+ */
-+
-+void
-+htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *ExternalID = NULL;
-+ xmlChar *URI = NULL;
-+
-+ /*
-+ * We know that '<!DOCTYPE' has been detected.
-+ */
-+ SKIP(9);
-+
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Parse the DOCTYPE name.
-+ */
-+ name = htmlParseName(ctxt);
-+ if (name == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "htmlParseDocTypeDecl : no DOCTYPE name !\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ /*
-+ * Check that upper(name) == "HTML" !!!!!!!!!!!!!
-+ */
-+
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Check for SystemID and ExternalID
-+ */
-+ URI = htmlParseExternalID(ctxt, &ExternalID, 0);
-+ SKIP_BLANKS;
-+
-+ /*
-+ * We should be at the end of the DOCTYPE declaration.
-+ */
-+ if (CUR != '>') {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
-+ ctxt->wellFormed = 0;
-+ /* We shouldn't try to resynchronize ... */
-+ }
-+ NEXT;
-+
-+ /*
-+ * Create or update the document accordingly to the DOCTYPE
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
-+
-+ /*
-+ * Cleanup, since we don't use all those identifiers
-+ */
-+ if (URI != NULL) xmlFree(URI);
-+ if (ExternalID != NULL) xmlFree(ExternalID);
-+ if (name != NULL) xmlFree(name);
-+}
-+
-+/**
-+ * htmlParseAttribute:
-+ * @ctxt: an HTML parser context
-+ * @value: a xmlChar ** used to store the value of the attribute
-+ *
-+ * parse an attribute
-+ *
-+ * [41] Attribute ::= Name Eq AttValue
-+ *
-+ * [25] Eq ::= S? '=' S?
-+ *
-+ * With namespace:
-+ *
-+ * [NS 11] Attribute ::= QName Eq AttValue
-+ *
-+ * Also the case QName == xmlns:??? is handled independently as a namespace
-+ * definition.
-+ *
-+ * Returns the attribute name, and the value in *value.
-+ */
-+
-+xmlChar *
-+htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
-+ xmlChar *name, *val = NULL;
-+
-+ *value = NULL;
-+ name = htmlParseHTMLName(ctxt);
-+ if (name == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
-+ ctxt->wellFormed = 0;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * read the value
-+ */
-+ SKIP_BLANKS;
-+ if (CUR == '=') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ val = htmlParseAttValue(ctxt);
-+ /******
-+ } else {
-+ * TODO : some attribute must have values, some may not
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "No value for attribute %s\n", name); */
-+ }
-+
-+ *value = val;
-+ return(name);
-+}
-+
-+/**
-+ * htmlCheckEncoding:
-+ * @ctxt: an HTML parser context
-+ * @attvalue: the attribute value
-+ *
-+ * Checks an http-equiv attribute from a Meta tag to detect
-+ * the encoding
-+ * If a new encoding is detected the parser is switched to decode
-+ * it and pass UTF8
-+ */
-+void
-+htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
-+ const xmlChar *encoding;
-+
-+ if ((ctxt == NULL) || (attvalue == NULL))
-+ return;
-+
-+ /* do not change encoding */
-+ if (ctxt->input->encoding != NULL)
-+ return;
-+
-+ encoding = xmlStrcasestr(attvalue, BAD_CAST"charset=");
-+ if (encoding != NULL) {
-+ encoding += 8;
-+ } else {
-+ encoding = xmlStrcasestr(attvalue, BAD_CAST"charset =");
-+ if (encoding != NULL)
-+ encoding += 9;
-+ }
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+ xmlCharEncodingHandlerPtr handler;
-+
-+ while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
-+
-+ if (ctxt->input->encoding != NULL)
-+ xmlFree((xmlChar *) ctxt->input->encoding);
-+ ctxt->input->encoding = xmlStrdup(encoding);
-+
-+ enc = xmlParseCharEncoding((const char *) encoding);
-+ /*
-+ * registered set of known encodings
-+ */
-+ if (enc != XML_CHAR_ENCODING_ERROR) {
-+ xmlSwitchEncoding(ctxt, enc);
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ } else {
-+ /*
-+ * fallback for unknown encodings
-+ */
-+ handler = xmlFindCharEncodingHandler((const char *) encoding);
-+ if (handler != NULL) {
-+ xmlSwitchToEncoding(ctxt, handler);
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ } else {
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ }
-+ }
-+
-+ if ((ctxt->input->buf != NULL) &&
-+ (ctxt->input->buf->encoder != NULL) &&
-+ (ctxt->input->buf->raw != NULL) &&
-+ (ctxt->input->buf->buffer != NULL)) {
-+ int nbchars;
-+ int processed;
-+
-+ /*
-+ * convert as much as possible to the parser reading buffer.
-+ */
-+ processed = ctxt->input->cur - ctxt->input->base;
-+ xmlBufferShrink(ctxt->input->buf->buffer, processed);
-+ nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-+ ctxt->input->buf->buffer,
-+ ctxt->input->buf->raw);
-+ if (nbchars < 0) {
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlCheckEncoding: encoder error\n");
-+ }
-+ ctxt->input->base =
-+ ctxt->input->cur = ctxt->input->buf->buffer->content;
-+ }
-+ }
-+}
-+
-+/**
-+ * htmlCheckMeta:
-+ * @ctxt: an HTML parser context
-+ * @atts: the attributes values
-+ *
-+ * Checks an attributes from a Meta tag
-+ */
-+void
-+htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
-+ int i;
-+ const xmlChar *att, *value;
-+ int http = 0;
-+ const xmlChar *content = NULL;
-+
-+ if ((ctxt == NULL) || (atts == NULL))
-+ return;
-+
-+ i = 0;
-+ att = atts[i++];
-+ while (att != NULL) {
-+ value = atts[i++];
-+ if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"http-equiv"))
-+ && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
-+ http = 1;
-+ else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"content")))
-+ content = value;
-+ att = atts[i++];
-+ }
-+ if ((http) && (content != NULL))
-+ htmlCheckEncoding(ctxt, content);
-+
-+}
-+
-+/**
-+ * htmlParseStartTag:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse a start of tag either for rule element or
-+ * EmptyElement. In both case we don't parse the tag closing chars.
-+ *
-+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
-+ *
-+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
-+ *
-+ * With namespace:
-+ *
-+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
-+ *
-+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
-+ *
-+ */
-+
-+void
-+htmlParseStartTag(htmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *attname;
-+ xmlChar *attvalue;
-+ const xmlChar **atts = NULL;
-+ int nbatts = 0;
-+ int maxatts = 0;
-+ int meta = 0;
-+ int i;
-+
-+ if (CUR != '<') return;
-+ NEXT;
-+
-+ GROW;
-+ name = htmlParseHTMLName(ctxt);
-+ if (name == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseStartTag: invalid element name\n");
-+ ctxt->wellFormed = 0;
-+ /* Dump the bogus tag like browsers do */
-+ while ((IS_CHAR(CUR)) && (CUR != '>'))
-+ NEXT;
-+ return;
-+ }
-+ if (xmlStrEqual(name, BAD_CAST"meta"))
-+ meta = 1;
-+
-+ /*
-+ * Check for auto-closure of HTML elements.
-+ */
-+ htmlAutoClose(ctxt, name);
-+
-+ /*
-+ * Check for implied HTML elements.
-+ */
-+ htmlCheckImplied(ctxt, name);
-+
-+ /*
-+ * Avoid html at any level > 0, head at any level != 1
-+ * or any attempt to recurse body
-+ */
-+ if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseStartTag: misplaced <html> tag\n");
-+ ctxt->wellFormed = 0;
-+ xmlFree(name);
-+ return;
-+ }
-+ if ((ctxt->nameNr != 1) &&
-+ (xmlStrEqual(name, BAD_CAST"head"))) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseStartTag: misplaced <head> tag\n");
-+ ctxt->wellFormed = 0;
-+ xmlFree(name);
-+ return;
-+ }
-+ if (xmlStrEqual(name, BAD_CAST"body")) {
-+ int i;
-+ for (i = 0;i < ctxt->nameNr;i++) {
-+ if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseStartTag: misplaced <body> tag\n");
-+ ctxt->wellFormed = 0;
-+ xmlFree(name);
-+ return;
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Now parse the attributes, it ends up with the ending
-+ *
-+ * (S Attribute)* S?
-+ */
-+ SKIP_BLANKS;
-+ while ((IS_CHAR(CUR)) &&
-+ (CUR != '>') &&
-+ ((CUR != '/') || (NXT(1) != '>'))) {
-+ long cons = ctxt->nbChars;
-+
-+ GROW;
-+ attname = htmlParseAttribute(ctxt, &attvalue);
-+ if (attname != NULL) {
-+
-+ /*
-+ * Well formedness requires at most one declaration of an attribute
-+ */
-+ for (i = 0; i < nbatts;i += 2) {
-+ if (xmlStrEqual(atts[i], attname)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attribute %s redefined\n",
-+ attname);
-+ ctxt->wellFormed = 0;
-+ xmlFree(attname);
-+ if (attvalue != NULL)
-+ xmlFree(attvalue);
-+ goto failed;
-+ }
-+ }
-+
-+ /*
-+ * Add the pair to atts
-+ */
-+ if (atts == NULL) {
-+ maxatts = 10;
-+ atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
-+ if (atts == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %ld byte failed\n",
-+ maxatts * (long)sizeof(xmlChar *));
-+ if (name != NULL) xmlFree(name);
-+ return;
-+ }
-+ } else if (nbatts + 4 > maxatts) {
-+ maxatts *= 2;
-+ atts = (const xmlChar **) xmlRealloc((void *) atts,
-+ maxatts * sizeof(xmlChar *));
-+ if (atts == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %ld byte failed\n",
-+ maxatts * (long)sizeof(xmlChar *));
-+ if (name != NULL) xmlFree(name);
-+ return;
-+ }
-+ }
-+ atts[nbatts++] = attname;
-+ atts[nbatts++] = attvalue;
-+ atts[nbatts] = NULL;
-+ atts[nbatts + 1] = NULL;
-+ }
-+ else {
-+ /* Dump the bogus attribute string up to the next blank or
-+ * the end of the tag. */
-+ while ((IS_CHAR(CUR)) && !(IS_BLANK(CUR)) && (CUR != '>')
-+ && ((CUR != '/') || (NXT(1) != '>')))
-+ NEXT;
-+ }
-+
-+failed:
-+ SKIP_BLANKS;
-+ if (cons == ctxt->nbChars) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "htmlParseStartTag: problem parsing attributes\n");
-+ ctxt->wellFormed = 0;
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * Handle specific association to the META tag
-+ */
-+ if (meta)
-+ htmlCheckMeta(ctxt, atts);
-+
-+ /*
-+ * SAX: Start of Element !
-+ */
-+ htmlnamePush(ctxt, xmlStrdup(name));
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Start of element %s: pushed %s\n", name, ctxt->name);
-+#endif
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-+ ctxt->sax->startElement(ctxt->userData, name, atts);
-+
-+ if (atts != NULL) {
-+ for (i = 0;i < nbatts;i++) {
-+ if (atts[i] != NULL)
-+ xmlFree((xmlChar *) atts[i]);
-+ }
-+ xmlFree((void *) atts);
-+ }
-+ if (name != NULL) xmlFree(name);
-+}
-+
-+/**
-+ * htmlParseEndTag:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an end of tag
-+ *
-+ * [42] ETag ::= '</' Name S? '>'
-+ *
-+ * With namespace
-+ *
-+ * [NS 9] ETag ::= '</' QName S? '>'
-+ */
-+
-+void
-+htmlParseEndTag(htmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *oldname;
-+ int i;
-+
-+ if ((CUR != '<') || (NXT(1) != '/')) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "htmlParseEndTag: '</' not found\n");
-+ ctxt->wellFormed = 0;
-+ return;
-+ }
-+ SKIP(2);
-+
-+ name = htmlParseHTMLName(ctxt);
-+ if (name == NULL) return;
-+
-+ /*
-+ * We should definitely be at the ending "S? '>'" part
-+ */
-+ SKIP_BLANKS;
-+ if ((!IS_CHAR(CUR)) || (CUR != '>')) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
-+ ctxt->wellFormed = 0;
-+ } else
-+ NEXT;
-+
-+ /*
-+ * If the name read is not one of the element in the parsing stack
-+ * then return, it's just an error.
-+ */
-+ for (i = (ctxt->nameNr - 1);i >= 0;i--) {
-+ if (xmlStrEqual(name, ctxt->nameTab[i])) break;
-+ }
-+ if (i < 0) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Unexpected end tag : %s\n", name);
-+ xmlFree(name);
-+ ctxt->wellFormed = 0;
-+ return;
-+ }
-+
-+
-+ /*
-+ * Check for auto-closure of HTML elements.
-+ */
-+
-+ htmlAutoCloseOnClose(ctxt, name);
-+
-+ /*
-+ * Well formedness constraints, opening and closing must match.
-+ * With the exception that the autoclose may have popped stuff out
-+ * of the stack.
-+ */
-+ if (!xmlStrEqual(name, ctxt->name)) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", name, ctxt->name);
-+#endif
-+ if ((ctxt->name != NULL) &&
-+ (!xmlStrEqual(ctxt->name, name))) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Opening and ending tag mismatch: %s and %s\n",
-+ name, ctxt->name);
-+ ctxt->wellFormed = 0;
-+ }
-+ }
-+
-+ /*
-+ * SAX: End of Tag
-+ */
-+ oldname = ctxt->name;
-+ if ((oldname != NULL) && (xmlStrEqual(oldname, name))) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ oldname = htmlnamePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of tag %s: popping out %s\n", name, oldname);
-+#endif
-+ xmlFree(oldname);
-+#ifdef DEBUG
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,"End of tag %s: stack empty !!!\n", name);
-+#endif
-+ }
-+ }
-+
-+ if (name != NULL)
-+ xmlFree(name);
-+
-+ return;
-+}
-+
-+
-+/**
-+ * htmlParseReference:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse and handle entity references in content,
-+ * this will end-up in a call to character() since this is either a
-+ * CharRef, or a predefined entity.
-+ */
-+void
-+htmlParseReference(htmlParserCtxtPtr ctxt) {
-+ htmlEntityDescPtr ent;
-+ xmlChar out[6];
-+ xmlChar *name;
-+ if (CUR != '&') return;
-+
-+ if (NXT(1) == '#') {
-+ unsigned int c;
-+ int bits, i = 0;
-+
-+ c = htmlParseCharRef(ctxt);
-+ if (c == 0)
-+ return;
-+
-+ if (c < 0x80) { out[i++]= c; bits= -6; }
-+ else if (c < 0x800) { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ out[i++]= ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ out[i] = 0;
-+
-+ htmlCheckParagraph(ctxt);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, out, i);
-+ } else {
-+ ent = htmlParseEntityRef(ctxt, &name);
-+ if (name == NULL) {
-+ htmlCheckParagraph(ctxt);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
-+ return;
-+ }
-+ if ((ent == NULL) || (ent->value <= 0)) {
-+ htmlCheckParagraph(ctxt);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) {
-+ ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
-+ ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name));
-+ /* ctxt->sax->characters(ctxt->userData, BAD_CAST ";", 1); */
-+ }
-+ } else {
-+ unsigned int c;
-+ int bits, i = 0;
-+
-+ c = ent->value;
-+ if (c < 0x80)
-+ { out[i++]= c; bits= -6; }
-+ else if (c < 0x800)
-+ { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000)
-+ { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else
-+ { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ out[i++]= ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ out[i] = 0;
-+
-+ htmlCheckParagraph(ctxt);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, out, i);
-+ }
-+ xmlFree(name);
-+ }
-+}
-+
-+/**
-+ * htmlParseContent:
-+ * @ctxt: an HTML parser context
-+ * @name: the node name
-+ *
-+ * Parse a content: comment, sub-element, reference or text.
-+ *
-+ */
-+
-+void
-+htmlParseContent(htmlParserCtxtPtr ctxt) {
-+ xmlChar *currentNode;
-+ int depth;
-+
-+ currentNode = xmlStrdup(ctxt->name);
-+ depth = ctxt->nameNr;
-+ while (1) {
-+ long cons = ctxt->nbChars;
-+
-+ GROW;
-+ /*
-+ * Our tag or one of it's parent or children is ending.
-+ */
-+ if ((CUR == '<') && (NXT(1) == '/')) {
-+ htmlParseEndTag(ctxt);
-+ if (currentNode != NULL) xmlFree(currentNode);
-+ return;
-+ }
-+
-+ /*
-+ * Has this node been popped out during parsing of
-+ * the next element
-+ */
-+ if ((!xmlStrEqual(currentNode, ctxt->name)) &&
-+ (depth >= ctxt->nameNr)) {
-+ if (currentNode != NULL) xmlFree(currentNode);
-+ return;
-+ }
-+
-+ if ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
-+ (xmlStrEqual(currentNode, BAD_CAST"style"))) {
-+ /*
-+ * Handle SCRIPT/STYLE separately
-+ */
-+ htmlParseScript(ctxt);
-+ } else {
-+ /*
-+ * Sometimes DOCTYPE arrives in the middle of the document
-+ */
-+ if ((CUR == '<') && (NXT(1) == '!') &&
-+ (UPP(2) == 'D') && (UPP(3) == 'O') &&
-+ (UPP(4) == 'C') && (UPP(5) == 'T') &&
-+ (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-+ (UPP(8) == 'E')) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Misplaced DOCTYPE declaration\n");
-+ ctxt->wellFormed = 0;
-+ htmlParseDocTypeDecl(ctxt);
-+ }
-+
-+ /*
-+ * First case : a comment
-+ */
-+ if ((CUR == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '-') && (NXT(3) == '-')) {
-+ htmlParseComment(ctxt);
-+ }
-+
-+ /*
-+ * Second case : a sub-element.
-+ */
-+ else if (CUR == '<') {
-+ htmlParseElement(ctxt);
-+ }
-+
-+ /*
-+ * Third case : a reference. If if has not been resolved,
-+ * parsing returns it's Name, create the node
-+ */
-+ else if (CUR == '&') {
-+ htmlParseReference(ctxt);
-+ }
-+
-+ /*
-+ * Fourth : end of the resource
-+ */
-+ else if (CUR == 0) {
-+ htmlAutoClose(ctxt, NULL);
-+ }
-+
-+ /*
-+ * Last case, text. Note that References are handled directly.
-+ */
-+ else {
-+ htmlParseCharData(ctxt, 0);
-+ }
-+
-+ if (cons == ctxt->nbChars) {
-+ if (ctxt->node != NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "detected an error in element content\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ break;
-+ }
-+ }
-+ GROW;
-+ }
-+ if (currentNode != NULL) xmlFree(currentNode);
-+}
-+
-+/**
-+ * htmlParseElement:
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML element, this is highly recursive
-+ *
-+ * [39] element ::= EmptyElemTag | STag content ETag
-+ *
-+ * [41] Attribute ::= Name Eq AttValue
-+ */
-+
-+void
-+htmlParseElement(htmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *currentNode = NULL;
-+ htmlElemDescPtr info;
-+ htmlParserNodeInfo node_info;
-+ xmlChar *oldname;
-+ int depth = ctxt->nameNr;
-+
-+ /* Capture start position */
-+ if (ctxt->record_info) {
-+ node_info.begin_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.begin_line = ctxt->input->line;
-+ }
-+
-+ oldname = xmlStrdup(ctxt->name);
-+ htmlParseStartTag(ctxt);
-+ name = ctxt->name;
-+#ifdef DEBUG
-+ if (oldname == NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Start of element %s\n", name);
-+ else if (name == NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Start of element failed, was %s\n", oldname);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Start of element %s, was %s\n", name, oldname);
-+#endif
-+ if (((depth == ctxt->nameNr) && (xmlStrEqual(oldname, ctxt->name))) ||
-+ (name == NULL)) {
-+ if (CUR == '>')
-+ NEXT;
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ return;
-+ }
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+
-+ /*
-+ * Lookup the info for that element.
-+ */
-+ info = htmlTagLookup(name);
-+ if (info == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+ } else if (info->depr) {
-+/***************************
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData, "Tag %s is deprecated\n",
-+ name);
-+ ***************************/
-+ }
-+
-+ /*
-+ * Check for an Empty Element labelled the XML/SGML way
-+ */
-+ if ((CUR == '/') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n", oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ return;
-+ }
-+
-+ if (CUR == '>') {
-+ NEXT;
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Couldn't find end of Start Tag %s\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+ if (xmlStrEqual(name, ctxt->name)) {
-+ nodePop(ctxt);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of start tag problem: popping out %s\n", oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ }
-+
-+ /*
-+ * Capture end position and add node
-+ */
-+ if ( currentNode != NULL && ctxt->record_info ) {
-+ node_info.end_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.end_line = ctxt->input->line;
-+ node_info.node = ctxt->node;
-+ xmlParserAddNodeInfo(ctxt, &node_info);
-+ }
-+ return;
-+ }
-+
-+ /*
-+ * Check for an Empty Element from DTD definition
-+ */
-+ if ((info != NULL) && (info->empty)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ return;
-+ }
-+
-+ /*
-+ * Parse the content of the element:
-+ */
-+ currentNode = xmlStrdup(ctxt->name);
-+ depth = ctxt->nameNr;
-+ while (IS_CHAR(CUR)) {
-+ htmlParseContent(ctxt);
-+ if (ctxt->nameNr < depth) break;
-+ }
-+
-+ if (!IS_CHAR(CUR)) {
-+ /************
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Premature end of data in tag %s\n", currentNode);
-+ ctxt->wellFormed = 0;
-+ *************/
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+ nodePop(ctxt);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"Premature end of tag %s : popping out %s\n", name, oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ if (currentNode != NULL)
-+ xmlFree(currentNode);
-+ return;
-+ }
-+
-+ /*
-+ * Capture end position and add node
-+ */
-+ if ( currentNode != NULL && ctxt->record_info ) {
-+ node_info.end_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.end_line = ctxt->input->line;
-+ node_info.node = ctxt->node;
-+ xmlParserAddNodeInfo(ctxt, &node_info);
-+ }
-+ if (currentNode != NULL)
-+ xmlFree(currentNode);
-+}
-+
-+/**
-+ * htmlParseDocument :
-+ * @ctxt: an HTML parser context
-+ *
-+ * parse an HTML document (and build a tree if using the standard SAX
-+ * interface).
-+ *
-+ * Returns 0, -1 in case of error. the parser context is augmented
-+ * as a result of the parsing.
-+ */
-+
-+int
-+htmlParseDocument(htmlParserCtxtPtr ctxt) {
-+ xmlDtdPtr dtd;
-+
-+ htmlDefaultSAXHandlerInit();
-+ ctxt->html = 1;
-+
-+ GROW;
-+ /*
-+ * SAX: beginning of the document processing.
-+ */
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-+
-+ /*
-+ * Wipe out everything which is before the first '<'
-+ */
-+ SKIP_BLANKS;
-+ if (CUR == 0) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Document is empty\n");
-+ ctxt->wellFormed = 0;
-+ }
-+
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+
-+
-+ /*
-+ * Parse possible comments before any content
-+ */
-+ while ((CUR == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '-') && (NXT(3) == '-')) {
-+ htmlParseComment(ctxt);
-+ SKIP_BLANKS;
-+ }
-+
-+
-+ /*
-+ * Then possibly doc type declaration(s) and more Misc
-+ * (doctypedecl Misc*)?
-+ */
-+ if ((CUR == '<') && (NXT(1) == '!') &&
-+ (UPP(2) == 'D') && (UPP(3) == 'O') &&
-+ (UPP(4) == 'C') && (UPP(5) == 'T') &&
-+ (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-+ (UPP(8) == 'E')) {
-+ htmlParseDocTypeDecl(ctxt);
-+ }
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Parse possible comments before any content
-+ */
-+ while ((CUR == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '-') && (NXT(3) == '-')) {
-+ htmlParseComment(ctxt);
-+ SKIP_BLANKS;
-+ }
-+
-+ /*
-+ * Time to start parsing the tree itself
-+ */
-+ htmlParseContent(ctxt);
-+
-+ /*
-+ * autoclose
-+ */
-+ if (CUR == 0)
-+ htmlAutoClose(ctxt, NULL);
-+
-+
-+ /*
-+ * SAX: end of the document processing.
-+ */
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-+ ctxt->sax->endDocument(ctxt->userData);
-+
-+ if (ctxt->myDoc != NULL) {
-+ dtd = xmlGetIntSubset(ctxt->myDoc);
-+ if (dtd == NULL)
-+ ctxt->myDoc->intSubset =
-+ xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "HTML",
-+ BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
-+ BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
-+ }
-+ if (! ctxt->wellFormed) return(-1);
-+ return(0);
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Parser contexts handling *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlInitParserCtxt:
-+ * @ctxt: an HTML parser context
-+ *
-+ * Initialize a parser context
-+ */
-+
-+void
-+htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
-+{
-+ htmlSAXHandler *sax;
-+
-+ if (ctxt == NULL) return;
-+ memset(ctxt, 0, sizeof(htmlParserCtxt));
-+
-+ sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
-+ if (sax == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlInitParserCtxt: out of memory\n");
-+ }
-+ else
-+ memset(sax, 0, sizeof(htmlSAXHandler));
-+
-+ /* Allocate the Input stack */
-+ ctxt->inputTab = (htmlParserInputPtr *)
-+ xmlMalloc(5 * sizeof(htmlParserInputPtr));
-+ if (ctxt->inputTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlInitParserCtxt: out of memory\n");
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ return;
-+ }
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 5;
-+ ctxt->input = NULL;
-+ ctxt->version = NULL;
-+ ctxt->encoding = NULL;
-+ ctxt->standalone = -1;
-+ ctxt->instate = XML_PARSER_START;
-+
-+ /* Allocate the Node stack */
-+ ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
-+ if (ctxt->nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlInitParserCtxt: out of memory\n");
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 0;
-+ ctxt->node = NULL;
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ return;
-+ }
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 10;
-+ ctxt->node = NULL;
-+
-+ /* Allocate the Name stack */
-+ ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
-+ if (ctxt->nameTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlInitParserCtxt: out of memory\n");
-+ ctxt->nameNr = 0;
-+ ctxt->nameMax = 10;
-+ ctxt->name = NULL;
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 0;
-+ ctxt->node = NULL;
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ return;
-+ }
-+ ctxt->nameNr = 0;
-+ ctxt->nameMax = 10;
-+ ctxt->name = NULL;
-+
-+ if (sax == NULL) ctxt->sax = &htmlDefaultSAXHandler;
-+ else {
-+ ctxt->sax = sax;
-+ memcpy(sax, &htmlDefaultSAXHandler, sizeof(htmlSAXHandler));
-+ }
-+ ctxt->userData = ctxt;
-+ ctxt->myDoc = NULL;
-+ ctxt->wellFormed = 1;
-+ ctxt->replaceEntities = 0;
-+ ctxt->html = 1;
-+ ctxt->record_info = 0;
-+ ctxt->validate = 0;
-+ ctxt->nbChars = 0;
-+ ctxt->checkIndex = 0;
-+ xmlInitNodeInfoSeq(&ctxt->node_seq);
-+}
-+
-+/**
-+ * htmlFreeParserCtxt:
-+ * @ctxt: an HTML parser context
-+ *
-+ * Free all the memory used by a parser context. However the parsed
-+ * document in ctxt->myDoc is not freed.
-+ */
-+
-+void
-+htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)
-+{
-+ xmlFreeParserCtxt(ctxt);
-+}
-+
-+/**
-+ * htmlCreateDocParserCtxt :
-+ * @cur: a pointer to an array of xmlChar
-+ * @encoding: a free form C string describing the HTML document encoding, or NULL
-+ *
-+ * Create a parser context for an HTML document.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+htmlParserCtxtPtr
-+htmlCreateDocParserCtxt(xmlChar *cur, const char *encoding) {
-+ htmlParserCtxtPtr ctxt;
-+ htmlParserInputPtr input;
-+ /* htmlCharEncoding enc; */
-+
-+ ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
-+ if (ctxt == NULL) {
-+ perror("malloc");
-+ return(NULL);
-+ }
-+ htmlInitParserCtxt(ctxt);
-+ input = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
-+ if (input == NULL) {
-+ perror("malloc");
-+ xmlFree(ctxt);
-+ return(NULL);
-+ }
-+ memset(input, 0, sizeof(htmlParserInput));
-+
-+ input->line = 1;
-+ input->col = 1;
-+ input->base = cur;
-+ input->cur = cur;
-+
-+ inputPush(ctxt, input);
-+ return(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Progressive parsing interfaces *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlParseLookupSequence:
-+ * @ctxt: an HTML parser context
-+ * @first: the first char to lookup
-+ * @next: the next char to lookup or zero
-+ * @third: the next char to lookup or zero
-+ *
-+ * Try to find if a sequence (first, next, third) or just (first next) or
-+ * (first) is available in the input stream.
-+ * This function has a side effect of (possibly) incrementing ctxt->checkIndex
-+ * to avoid rescanning sequences of bytes, it DOES change the state of the
-+ * parser, do not use liberally.
-+ * This is basically similar to xmlParseLookupSequence()
-+ *
-+ * Returns the index to the current parsing point if the full sequence
-+ * is available, -1 otherwise.
-+ */
-+int
-+htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
-+ xmlChar next, xmlChar third) {
-+ int base, len;
-+ htmlParserInputPtr in;
-+ const xmlChar *buf;
-+
-+ in = ctxt->input;
-+ if (in == NULL) return(-1);
-+ base = in->cur - in->base;
-+ if (base < 0) return(-1);
-+ if (ctxt->checkIndex > base)
-+ base = ctxt->checkIndex;
-+ if (in->buf == NULL) {
-+ buf = in->base;
-+ len = in->length;
-+ } else {
-+ buf = in->buf->buffer->content;
-+ len = in->buf->buffer->use;
-+ }
-+ /* take into account the sequence length */
-+ if (third) len -= 2;
-+ else if (next) len --;
-+ for (;base < len;base++) {
-+ if (buf[base] == first) {
-+ if (third != 0) {
-+ if ((buf[base + 1] != next) ||
-+ (buf[base + 2] != third)) continue;
-+ } else if (next != 0) {
-+ if (buf[base + 1] != next) continue;
-+ }
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ if (next == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: lookup '%c' found at %d\n",
-+ first, base);
-+ else if (third == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: lookup '%c%c' found at %d\n",
-+ first, next, base);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: lookup '%c%c%c' found at %d\n",
-+ first, next, third, base);
-+#endif
-+ return(base - (in->cur - in->base));
-+ }
-+ }
-+ ctxt->checkIndex = base;
-+#ifdef DEBUG_PUSH
-+ if (next == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: lookup '%c' failed\n", first);
-+ else if (third == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: lookup '%c%c' failed\n", first, next);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: lookup '%c%c%c' failed\n", first, next, third);
-+#endif
-+ return(-1);
-+}
-+
-+/**
-+ * htmlParseTryOrFinish:
-+ * @ctxt: an HTML parser context
-+ * @terminate: last chunk indicator
-+ *
-+ * Try to progress on parsing
-+ *
-+ * Returns zero if no parsing was possible
-+ */
-+int
-+htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
-+ int ret = 0;
-+ htmlParserInputPtr in;
-+ int avail = 0;
-+ xmlChar cur, next;
-+
-+#ifdef DEBUG_PUSH
-+ switch (ctxt->instate) {
-+ case XML_PARSER_EOF:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try EOF\n"); break;
-+ case XML_PARSER_START:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try START\n"); break;
-+ case XML_PARSER_MISC:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try MISC\n");break;
-+ case XML_PARSER_COMMENT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try COMMENT\n");break;
-+ case XML_PARSER_PROLOG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try PROLOG\n");break;
-+ case XML_PARSER_START_TAG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try START_TAG\n");break;
-+ case XML_PARSER_CONTENT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try CONTENT\n");break;
-+ case XML_PARSER_CDATA_SECTION:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try CDATA_SECTION\n");break;
-+ case XML_PARSER_END_TAG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try END_TAG\n");break;
-+ case XML_PARSER_ENTITY_DECL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try ENTITY_DECL\n");break;
-+ case XML_PARSER_ENTITY_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try ENTITY_VALUE\n");break;
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try ATTRIBUTE_VALUE\n");break;
-+ case XML_PARSER_DTD:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try DTD\n");break;
-+ case XML_PARSER_EPILOG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try EPILOG\n");break;
-+ case XML_PARSER_PI:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try PI\n");break;
-+ case XML_PARSER_SYSTEM_LITERAL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: try SYSTEM_LITERAL\n");break;
-+ }
-+#endif
-+
-+ while (1) {
-+
-+ in = ctxt->input;
-+ if (in == NULL) break;
-+ if (in->buf == NULL)
-+ avail = in->length - (in->cur - in->base);
-+ else
-+ avail = in->buf->buffer->use - (in->cur - in->base);
-+ if ((avail == 0) && (terminate)) {
-+ htmlAutoClose(ctxt, NULL);
-+ if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
-+ /*
-+ * SAX: end of the document processing.
-+ */
-+ ctxt->instate = XML_PARSER_EOF;
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ }
-+ }
-+ if (avail < 1)
-+ goto done;
-+ switch (ctxt->instate) {
-+ case XML_PARSER_EOF:
-+ /*
-+ * Document parsing is done !
-+ */
-+ goto done;
-+ case XML_PARSER_START:
-+ /*
-+ * Very first chars read from the document flow.
-+ */
-+ cur = in->cur[0];
-+ if (IS_BLANK(cur)) {
-+ SKIP_BLANKS;
-+ if (in->buf == NULL)
-+ avail = in->length - (in->cur - in->base);
-+ else
-+ avail = in->buf->buffer->use - (in->cur - in->base);
-+ }
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData,
-+ &xmlDefaultSAXLocator);
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+
-+ cur = in->cur[0];
-+ next = in->cur[1];
-+ if ((cur == '<') && (next == '!') &&
-+ (UPP(2) == 'D') && (UPP(3) == 'O') &&
-+ (UPP(4) == 'C') && (UPP(5) == 'T') &&
-+ (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-+ (UPP(8) == 'E')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing internal subset\n");
-+#endif
-+ htmlParseDocTypeDecl(ctxt);
-+ ctxt->instate = XML_PARSER_PROLOG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering PROLOG\n");
-+#endif
-+ } else {
-+ ctxt->instate = XML_PARSER_MISC;
-+ }
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering MISC\n");
-+#endif
-+ break;
-+ case XML_PARSER_MISC:
-+ SKIP_BLANKS;
-+ if (in->buf == NULL)
-+ avail = in->length - (in->cur - in->base);
-+ else
-+ avail = in->buf->buffer->use - (in->cur - in->base);
-+ if (avail < 2)
-+ goto done;
-+ cur = in->cur[0];
-+ next = in->cur[1];
-+ if ((cur == '<') && (next == '!') &&
-+ (in->cur[2] == '-') && (in->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing Comment\n");
-+#endif
-+ htmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_MISC;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (UPP(2) == 'D') && (UPP(3) == 'O') &&
-+ (UPP(4) == 'C') && (UPP(5) == 'T') &&
-+ (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-+ (UPP(8) == 'E')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing internal subset\n");
-+#endif
-+ htmlParseDocTypeDecl(ctxt);
-+ ctxt->instate = XML_PARSER_PROLOG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering PROLOG\n");
-+#endif
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 9)) {
-+ goto done;
-+ } else {
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering START_TAG\n");
-+#endif
-+ }
-+ break;
-+ case XML_PARSER_PROLOG:
-+ SKIP_BLANKS;
-+ if (in->buf == NULL)
-+ avail = in->length - (in->cur - in->base);
-+ else
-+ avail = in->buf->buffer->use - (in->cur - in->base);
-+ if (avail < 2)
-+ goto done;
-+ cur = in->cur[0];
-+ next = in->cur[1];
-+ if ((cur == '<') && (next == '!') &&
-+ (in->cur[2] == '-') && (in->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing Comment\n");
-+#endif
-+ htmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_PROLOG;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 4)) {
-+ goto done;
-+ } else {
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering START_TAG\n");
-+#endif
-+ }
-+ break;
-+ case XML_PARSER_EPILOG:
-+ if (in->buf == NULL)
-+ avail = in->length - (in->cur - in->base);
-+ else
-+ avail = in->buf->buffer->use - (in->cur - in->base);
-+ if (avail < 1)
-+ goto done;
-+ cur = in->cur[0];
-+ if (IS_BLANK(cur)) {
-+ htmlParseCharData(ctxt, 0);
-+ goto done;
-+ }
-+ if (avail < 2)
-+ goto done;
-+ next = in->cur[1];
-+ if ((cur == '<') && (next == '!') &&
-+ (in->cur[2] == '-') && (in->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing Comment\n");
-+#endif
-+ htmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_EPILOG;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 4)) {
-+ goto done;
-+ } else {
-+ ctxt->errNo = XML_ERR_DOCUMENT_END;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra content at the end of the document\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->instate = XML_PARSER_EOF;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering EOF\n");
-+#endif
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ goto done;
-+ }
-+ break;
-+ case XML_PARSER_START_TAG: {
-+ xmlChar *name, *oldname;
-+ int depth = ctxt->nameNr;
-+ htmlElemDescPtr info;
-+
-+ if (avail < 2)
-+ goto done;
-+ cur = in->cur[0];
-+ if (cur != '<') {
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ }
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+
-+ oldname = xmlStrdup(ctxt->name);
-+ htmlParseStartTag(ctxt);
-+ name = ctxt->name;
-+#ifdef DEBUG
-+ if (oldname == NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Start of element %s\n", name);
-+ else if (name == NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Start of element failed, was %s\n",
-+ oldname);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Start of element %s, was %s\n",
-+ name, oldname);
-+#endif
-+ if (((depth == ctxt->nameNr) &&
-+ (xmlStrEqual(oldname, ctxt->name))) ||
-+ (name == NULL)) {
-+ if (CUR == '>')
-+ NEXT;
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ break;
-+ }
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+
-+ /*
-+ * Lookup the info for that element.
-+ */
-+ info = htmlTagLookup(name);
-+ if (info == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+ } else if (info->depr) {
-+ /***************************
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Tag %s is deprecated\n",
-+ name);
-+ ***************************/
-+ }
-+
-+ /*
-+ * Check for an Empty Element labelled the XML/SGML way
-+ */
-+ if ((CUR == '/') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n",
-+ oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ }
-+
-+ if (CUR == '>') {
-+ NEXT;
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Couldn't find end of Start Tag %s\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+ if (xmlStrEqual(name, ctxt->name)) {
-+ nodePop(ctxt);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,
-+ "End of start tag problem: popping out %s\n", oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ }
-+
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ }
-+
-+ /*
-+ * Check for an Empty Element from DTD definition
-+ */
-+ if ((info != NULL) && (info->empty)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ oldname = htmlnamePop(ctxt);
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
-+#endif
-+ if (oldname != NULL)
-+ xmlFree(oldname);
-+ }
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ }
-+ case XML_PARSER_CONTENT: {
-+ long cons;
-+ /*
-+ * Handle preparsed entities and charRef
-+ */
-+ if (ctxt->token != 0) {
-+ xmlChar chr[2] = { 0 , 0 } ;
-+
-+ chr[0] = (xmlChar) ctxt->token;
-+ htmlCheckParagraph(ctxt);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, chr, 1);
-+ ctxt->token = 0;
-+ ctxt->checkIndex = 0;
-+ }
-+ if ((avail == 1) && (terminate)) {
-+ cur = in->cur[0];
-+ if ((cur != '<') && (cur != '&')) {
-+ if (ctxt->sax != NULL) {
-+ if (IS_BLANK(cur)) {
-+ if (ctxt->sax->ignorableWhitespace != NULL)
-+ ctxt->sax->ignorableWhitespace(
-+ ctxt->userData, &cur, 1);
-+ } else {
-+ htmlCheckParagraph(ctxt);
-+ if (ctxt->sax->characters != NULL)
-+ ctxt->sax->characters(
-+ ctxt->userData, &cur, 1);
-+ }
-+ }
-+ ctxt->token = 0;
-+ ctxt->checkIndex = 0;
-+ NEXT;
-+ }
-+ break;
-+ }
-+ if (avail < 2)
-+ goto done;
-+ cur = in->cur[0];
-+ next = in->cur[1];
-+ cons = ctxt->nbChars;
-+ if ((xmlStrEqual(ctxt->name, BAD_CAST"script")) ||
-+ (xmlStrEqual(ctxt->name, BAD_CAST"style"))) {
-+ /*
-+ * Handle SCRIPT/STYLE separately
-+ */
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '<', '/', 0) < 0))
-+ goto done;
-+ htmlParseScript(ctxt);
-+ if ((cur == '<') && (next == '/')) {
-+ ctxt->instate = XML_PARSER_END_TAG;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering END_TAG\n");
-+#endif
-+ break;
-+ }
-+ } else {
-+ /*
-+ * Sometimes DOCTYPE arrives in the middle of the document
-+ */
-+ if ((cur == '<') && (next == '!') &&
-+ (UPP(2) == 'D') && (UPP(3) == 'O') &&
-+ (UPP(4) == 'C') && (UPP(5) == 'T') &&
-+ (UPP(6) == 'Y') && (UPP(7) == 'P') &&
-+ (UPP(8) == 'E')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Misplaced DOCTYPE declaration\n");
-+ ctxt->wellFormed = 0;
-+ htmlParseDocTypeDecl(ctxt);
-+ } else if ((cur == '<') && (next == '!') &&
-+ (in->cur[2] == '-') && (in->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing Comment\n");
-+#endif
-+ htmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ } else if ((cur == '<') && (next == '!') && (avail < 4)) {
-+ goto done;
-+ } else if ((cur == '<') && (next == '/')) {
-+ ctxt->instate = XML_PARSER_END_TAG;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering END_TAG\n");
-+#endif
-+ break;
-+ } else if (cur == '<') {
-+ ctxt->instate = XML_PARSER_START_TAG;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering START_TAG\n");
-+#endif
-+ break;
-+ } else if (cur == '&') {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing Reference\n");
-+#endif
-+ /* TODO: check generation of subtrees if noent !!! */
-+ htmlParseReference(ctxt);
-+ } else {
-+ /* TODO Avoid the extra copy, handle directly !!!!!! */
-+ /*
-+ * Goal of the following test is :
-+ * - minimize calls to the SAX 'character' callback
-+ * when they are mergeable
-+ */
-+ if ((ctxt->inputNr == 1) &&
-+ (avail < HTML_PARSER_BIG_BUFFER_SIZE)) {
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
-+ goto done;
-+ }
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: Parsing char data\n");
-+#endif
-+ htmlParseCharData(ctxt, 0);
-+ }
-+ }
-+ if (cons == ctxt->nbChars) {
-+ if (ctxt->node != NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "detected an error in element content\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ NEXT;
-+ break;
-+ }
-+
-+ break;
-+ }
-+ case XML_PARSER_END_TAG:
-+ if (avail < 2)
-+ goto done;
-+ if ((!terminate) &&
-+ (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+ htmlParseEndTag(ctxt);
-+ if (ctxt->nameNr == 0) {
-+ ctxt->instate = XML_PARSER_EPILOG;
-+ } else {
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ }
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_CDATA_SECTION:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == CDATA\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_DTD:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == DTD\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_COMMENT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == COMMENT\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_PI:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == PI\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_ENTITY_DECL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == ENTITY_DECL\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_ENTITY_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == ENTITY_VALUE\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering DTD\n");
-+#endif
-+ break;
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == ATTRIBUTE_VALUE\n");
-+ ctxt->instate = XML_PARSER_START_TAG;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering START_TAG\n");
-+#endif
-+ break;
-+ case XML_PARSER_SYSTEM_LITERAL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == XML_PARSER_SYSTEM_LITERAL\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_IGNORE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: internal error, state == XML_PARSER_IGNORE\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HPP: entering CONTENT\n");
-+#endif
-+ break;
-+ }
-+ }
-+done:
-+ if ((avail == 0) && (terminate)) {
-+ htmlAutoClose(ctxt, NULL);
-+ if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
-+ /*
-+ * SAX: end of the document processing.
-+ */
-+ ctxt->instate = XML_PARSER_EOF;
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ }
-+ }
-+ if ((ctxt->myDoc != NULL) &&
-+ ((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
-+ (ctxt->instate == XML_PARSER_EPILOG))) {
-+ xmlDtdPtr dtd;
-+ dtd = xmlGetIntSubset(ctxt->myDoc);
-+ if (dtd == NULL)
-+ ctxt->myDoc->intSubset =
-+ xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "HTML",
-+ BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
-+ BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
-+ }
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext, "HPP: done %d\n", ret);
-+#endif
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParseTry:
-+ * @ctxt: an HTML parser context
-+ *
-+ * Try to progress on parsing
-+ *
-+ * Returns zero if no parsing was possible
-+ */
-+int
-+htmlParseTry(htmlParserCtxtPtr ctxt) {
-+ return(htmlParseTryOrFinish(ctxt, 0));
-+}
-+
-+/**
-+ * htmlParseChunk:
-+ * @ctxt: an XML parser context
-+ * @chunk: an char array
-+ * @size: the size in byte of the chunk
-+ * @terminate: last chunk indicator
-+ *
-+ * Parse a Chunk of memory
-+ *
-+ * Returns zero if no error, the xmlParserErrors otherwise.
-+ */
-+int
-+htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
-+ int terminate) {
-+ if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-+ (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
-+ int base = ctxt->input->base - ctxt->input->buf->buffer->content;
-+ int cur = ctxt->input->cur - ctxt->input->base;
-+
-+ xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-+ ctxt->input->base = ctxt->input->buf->buffer->content + base;
-+ ctxt->input->cur = ctxt->input->base + cur;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-+#endif
-+
-+ if ((terminate) || (ctxt->input->buf->buffer->use > 80))
-+ htmlParseTryOrFinish(ctxt, terminate);
-+ } else if (ctxt->instate != XML_PARSER_EOF) {
-+ xmlParserInputBufferPush(ctxt->input->buf, 0, "");
-+ htmlParseTryOrFinish(ctxt, terminate);
-+ }
-+ if (terminate) {
-+ if ((ctxt->instate != XML_PARSER_EOF) &&
-+ (ctxt->instate != XML_PARSER_EPILOG) &&
-+ (ctxt->instate != XML_PARSER_MISC)) {
-+ ctxt->errNo = XML_ERR_DOCUMENT_END;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra content at the end of the document\n");
-+ ctxt->wellFormed = 0;
-+ }
-+ if (ctxt->instate != XML_PARSER_EOF) {
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ }
-+ ctxt->instate = XML_PARSER_EOF;
-+ }
-+ return((xmlParserErrors) ctxt->errNo);
-+}
-+
-+/************************************************************************
-+ * *
-+ * User entry points *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlCreatePushParserCtxt :
-+ * @sax: a SAX handler
-+ * @user_data: The user data returned on SAX callbacks
-+ * @chunk: a pointer to an array of chars
-+ * @size: number of chars in the array
-+ * @filename: an optional file name or URI
-+ * @enc: an optional encoding
-+ *
-+ * Create a parser context for using the HTML parser in push mode
-+ * To allow content encoding detection, @size should be >= 4
-+ * The value of @filename is used for fetching external entities
-+ * and error/warning reports.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+htmlParserCtxtPtr
-+htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
-+ const char *chunk, int size, const char *filename,
-+ xmlCharEncoding enc) {
-+ htmlParserCtxtPtr ctxt;
-+ htmlParserInputPtr inputStream;
-+ xmlParserInputBufferPtr buf;
-+
-+ buf = xmlAllocParserInputBuffer(enc);
-+ if (buf == NULL) return(NULL);
-+
-+ ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
-+ if (ctxt == NULL) {
-+ xmlFree(buf);
-+ return(NULL);
-+ }
-+ memset(ctxt, 0, sizeof(htmlParserCtxt));
-+ htmlInitParserCtxt(ctxt);
-+ if (sax != NULL) {
-+ if (ctxt->sax != &htmlDefaultSAXHandler)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = (htmlSAXHandlerPtr) xmlMalloc(sizeof(htmlSAXHandler));
-+ if (ctxt->sax == NULL) {
-+ xmlFree(buf);
-+ xmlFree(ctxt);
-+ return(NULL);
-+ }
-+ memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
-+ if (user_data != NULL)
-+ ctxt->userData = user_data;
-+ }
-+ if (filename == NULL) {
-+ ctxt->directory = NULL;
-+ } else {
-+ ctxt->directory = xmlParserGetDirectory(filename);
-+ }
-+
-+ inputStream = htmlNewInputStream(ctxt);
-+ if (inputStream == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ if (filename == NULL)
-+ inputStream->filename = NULL;
-+ else
-+ inputStream->filename = xmlMemStrdup(filename);
-+ inputStream->buf = buf;
-+ inputStream->base = inputStream->buf->buffer->content;
-+ inputStream->cur = inputStream->buf->buffer->content;
-+
-+ inputPush(ctxt, inputStream);
-+
-+ if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-+ (ctxt->input->buf != NULL)) {
-+ xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-+#endif
-+ }
-+
-+ return(ctxt);
-+}
-+
-+/**
-+ * htmlSAXParseDoc :
-+ * @cur: a pointer to an array of xmlChar
-+ * @encoding: a free form C string describing the HTML document encoding, or NULL
-+ * @sax: the SAX handler block
-+ * @userData: if using SAX, this pointer will be provided on callbacks.
-+ *
-+ * parse an HTML in-memory document and build a tree.
-+ * It use the given SAX function block to handle the parsing callback.
-+ * If sax is NULL, fallback to the default DOM tree building routines.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+htmlDocPtr
-+htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData) {
-+ htmlDocPtr ret;
-+ htmlParserCtxtPtr ctxt;
-+
-+ if (cur == NULL) return(NULL);
-+
-+
-+ ctxt = htmlCreateDocParserCtxt(cur, encoding);
-+ if (ctxt == NULL) return(NULL);
-+ if (sax != NULL) {
-+ ctxt->sax = sax;
-+ ctxt->userData = userData;
-+ }
-+
-+ htmlParseDocument(ctxt);
-+ ret = ctxt->myDoc;
-+ if (sax != NULL) {
-+ ctxt->sax = NULL;
-+ ctxt->userData = NULL;
-+ }
-+ htmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParseDoc :
-+ * @cur: a pointer to an array of xmlChar
-+ * @encoding: a free form C string describing the HTML document encoding, or NULL
-+ *
-+ * parse an HTML in-memory document and build a tree.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+htmlDocPtr
-+htmlParseDoc(xmlChar *cur, const char *encoding) {
-+ return(htmlSAXParseDoc(cur, encoding, NULL, NULL));
-+}
-+
-+
-+/**
-+ * htmlCreateFileParserCtxt :
-+ * @filename: the filename
-+ * @encoding: a free form C string describing the HTML document encoding, or NULL
-+ *
-+ * Create a parser context for a file content.
-+ * Automatic support for ZLIB/Compress compressed document is provided
-+ * by default if found at compile-time.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+htmlParserCtxtPtr
-+htmlCreateFileParserCtxt(const char *filename, const char *encoding)
-+{
-+ htmlParserCtxtPtr ctxt;
-+ htmlParserInputPtr inputStream;
-+ xmlParserInputBufferPtr buf;
-+ /* htmlCharEncoding enc; */
-+ xmlChar *content, *content_line = (xmlChar *) "charset=";
-+
-+ buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-+ if (buf == NULL) return(NULL);
-+
-+ ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
-+ if (ctxt == NULL) {
-+ perror("malloc");
-+ return(NULL);
-+ }
-+ memset(ctxt, 0, sizeof(htmlParserCtxt));
-+ htmlInitParserCtxt(ctxt);
-+ inputStream = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
-+ if (inputStream == NULL) {
-+ perror("malloc");
-+ xmlFree(ctxt);
-+ return(NULL);
-+ }
-+ memset(inputStream, 0, sizeof(htmlParserInput));
-+
-+ inputStream->filename = xmlMemStrdup(filename);
-+ inputStream->line = 1;
-+ inputStream->col = 1;
-+ inputStream->buf = buf;
-+ inputStream->directory = NULL;
-+
-+ inputStream->base = inputStream->buf->buffer->content;
-+ inputStream->cur = inputStream->buf->buffer->content;
-+ inputStream->free = NULL;
-+
-+ inputPush(ctxt, inputStream);
-+
-+ /* set encoding */
-+ if (encoding) {
-+ content = xmlMalloc (xmlStrlen(content_line) + strlen(encoding) + 1);
-+ if (content) {
-+ strcpy ((char *)content, (char *)content_line);
-+ strcat ((char *)content, (char *)encoding);
-+ htmlCheckEncoding (ctxt, content);
-+ xmlFree (content);
-+ }
-+ }
-+
-+ return(ctxt);
-+}
-+
-+/**
-+ * htmlSAXParseFile :
-+ * @filename: the filename
-+ * @encoding: a free form C string describing the HTML document encoding, or NULL
-+ * @sax: the SAX handler block
-+ * @userData: if using SAX, this pointer will be provided on callbacks.
-+ *
-+ * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
-+ * compressed document is provided by default if found at compile-time.
-+ * It use the given SAX function block to handle the parsing callback.
-+ * If sax is NULL, fallback to the default DOM tree building routines.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+htmlDocPtr
-+htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
-+ void *userData) {
-+ htmlDocPtr ret;
-+ htmlParserCtxtPtr ctxt;
-+ htmlSAXHandlerPtr oldsax = NULL;
-+
-+ ctxt = htmlCreateFileParserCtxt(filename, encoding);
-+ if (ctxt == NULL) return(NULL);
-+ if (sax != NULL) {
-+ oldsax = ctxt->sax;
-+ ctxt->sax = sax;
-+ ctxt->userData = userData;
-+ }
-+
-+ htmlParseDocument(ctxt);
-+
-+ ret = ctxt->myDoc;
-+ if (sax != NULL) {
-+ ctxt->sax = oldsax;
-+ ctxt->userData = NULL;
-+ }
-+ htmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * htmlParseFile :
-+ * @filename: the filename
-+ * @encoding: a free form C string describing the HTML document encoding, or NULL
-+ *
-+ * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
-+ * compressed document is provided by default if found at compile-time.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+htmlDocPtr
-+htmlParseFile(const char *filename, const char *encoding) {
-+ return(htmlSAXParseFile(filename, encoding, NULL, NULL));
-+}
-+
-+/**
-+ * htmlHandleOmittedElem:
-+ * @val: int 0 or 1
-+ *
-+ * Set and return the previous value for handling HTML omitted tags.
-+ *
-+ * Returns the last value for 0 for no handling, 1 for auto insertion.
-+ */
-+
-+int
-+htmlHandleOmittedElem(int val) {
-+ int old = htmlOmittedDefaultValue;
-+
-+ htmlOmittedDefaultValue = val;
-+ return(old);
-+}
-+
-+#endif /* LIBXML_HTML_ENABLED */
-diff -Nru libxml2-2.3.0/libxml/HTMLparser.h libxml2-2.3.0.new/libxml/HTMLparser.h
---- libxml2-2.3.0/libxml/HTMLparser.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/HTMLparser.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,114 @@
-+/*
-+ * HTMLparser.h : inf=terface for an HTML 4.0 non-verifying parser
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __HTML_PARSER_H__
-+#define __HTML_PARSER_H__
-+#include <libxml/parser.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * Most of the back-end structures from XML and HTML are shared
-+ */
-+typedef xmlParserCtxt htmlParserCtxt;
-+typedef xmlParserCtxtPtr htmlParserCtxtPtr;
-+typedef xmlParserNodeInfo htmlParserNodeInfo;
-+typedef xmlSAXHandler htmlSAXHandler;
-+typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
-+typedef xmlParserInput htmlParserInput;
-+typedef xmlParserInputPtr htmlParserInputPtr;
-+typedef xmlDocPtr htmlDocPtr;
-+typedef xmlNodePtr htmlNodePtr;
-+
-+/*
-+ * Internal description of an HTML element
-+ */
-+typedef struct _htmlElemDesc htmlElemDesc;
-+typedef htmlElemDesc *htmlElemDescPtr;
-+struct _htmlElemDesc {
-+ const char *name; /* The tag name */
-+ int startTag; /* Whether the start tag can be implied */
-+ int endTag; /* Whether the end tag can be implied */
-+ int empty; /* Is this an empty element ? */
-+ int depr; /* Is this a deprecated element ? */
-+ int dtd; /* 1: only in Loose DTD, 2: only Frameset one */
-+ const char *desc; /* the description */
-+};
-+
-+/*
-+ * Internal description of an HTML entity
-+ */
-+typedef struct _htmlEntityDesc htmlEntityDesc;
-+typedef htmlEntityDesc *htmlEntityDescPtr;
-+struct _htmlEntityDesc {
-+ int value; /* the UNICODE value for the character */
-+ const char *name; /* The entity name */
-+ const char *desc; /* the description */
-+};
-+
-+/*
-+ * There is only few public functions.
-+ */
-+htmlElemDescPtr htmlTagLookup (const xmlChar *tag);
-+htmlEntityDescPtr htmlEntityLookup(const xmlChar *name);
-+htmlEntityDescPtr htmlEntityValueLookup(int value);
-+
-+int htmlIsAutoClosed(htmlDocPtr doc,
-+ htmlNodePtr elem);
-+int htmlAutoCloseTag(htmlDocPtr doc,
-+ const xmlChar *name,
-+ htmlNodePtr elem);
-+htmlEntityDescPtr htmlParseEntityRef(htmlParserCtxtPtr ctxt,
-+ xmlChar **str);
-+int htmlParseCharRef(htmlParserCtxtPtr ctxt);
-+void htmlParseElement(htmlParserCtxtPtr ctxt);
-+
-+htmlDocPtr htmlSAXParseDoc (xmlChar *cur,
-+ const char *encoding,
-+ htmlSAXHandlerPtr sax,
-+ void *userData);
-+htmlDocPtr htmlParseDoc (xmlChar *cur,
-+ const char *encoding);
-+htmlDocPtr htmlSAXParseFile(const char *filename,
-+ const char *encoding,
-+ htmlSAXHandlerPtr sax,
-+ void *userData);
-+htmlDocPtr htmlParseFile (const char *filename,
-+ const char *encoding);
-+int UTF8ToHtml (unsigned char* out,
-+ int *outlen,
-+ const unsigned char* in,
-+ int *inlen);
-+int htmlEncodeEntities(unsigned char* out,
-+ int *outlen,
-+ const unsigned char* in,
-+ int *inlen, int quoteChar);
-+int htmlIsScriptAttribute(const xmlChar *name);
-+int htmlHandleOmittedElem(int val);
-+
-+/**
-+ * Interfaces for the Push mode
-+ */
-+void htmlFreeParserCtxt (htmlParserCtxtPtr ctxt);
-+htmlParserCtxtPtr htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax,
-+ void *user_data,
-+ const char *chunk,
-+ int size,
-+ const char *filename,
-+ xmlCharEncoding enc);
-+int htmlParseChunk (htmlParserCtxtPtr ctxt,
-+ const char *chunk,
-+ int size,
-+ int terminate);
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __HTML_PARSER_H__ */
-diff -Nru libxml2-2.3.0/libxml/HTMLtree.c libxml2-2.3.0.new/libxml/HTMLtree.c
---- libxml2-2.3.0/libxml/HTMLtree.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/HTMLtree.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,1132 @@
-+/*
-+ * HTMLtree.c : implemetation of access function for an HTML tree.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_HTML_ENABLED
-+
-+#include <stdio.h>
-+#include <string.h> /* for memset() only ! */
-+
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/HTMLparser.h>
-+#include <libxml/HTMLtree.h>
-+#include <libxml/entities.h>
-+#include <libxml/valid.h>
-+#include <libxml/xmlerror.h>
-+#include <libxml/parserInternals.h>
-+
-+/************************************************************************
-+ * *
-+ * Getting/Setting encoding meta tags *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlGetMetaEncoding:
-+ * @doc: the document
-+ *
-+ * Encoding definition lookup in the Meta tags
-+ *
-+ * Returns the current encoding as flagged in the HTML source
-+ */
-+const xmlChar *
-+htmlGetMetaEncoding(htmlDocPtr doc) {
-+ htmlNodePtr cur;
-+ const xmlChar *content;
-+ const xmlChar *encoding;
-+
-+ if (doc == NULL)
-+ return(NULL);
-+ cur = doc->children;
-+
-+ /*
-+ * Search the html
-+ */
-+ while (cur != NULL) {
-+ if (cur->name != NULL) {
-+ if (xmlStrEqual(cur->name, BAD_CAST"html"))
-+ break;
-+ if (xmlStrEqual(cur->name, BAD_CAST"head"))
-+ goto found_head;
-+ if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-+ goto found_meta;
-+ }
-+ cur = cur->next;
-+ }
-+ if (cur == NULL)
-+ return(NULL);
-+ cur = cur->children;
-+
-+ /*
-+ * Search the head
-+ */
-+ while (cur != NULL) {
-+ if (cur->name != NULL) {
-+ if (xmlStrEqual(cur->name, BAD_CAST"head"))
-+ break;
-+ if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-+ goto found_meta;
-+ }
-+ cur = cur->next;
-+ }
-+ if (cur == NULL)
-+ return(NULL);
-+found_head:
-+ cur = cur->children;
-+
-+ /*
-+ * Search the meta elements
-+ */
-+found_meta:
-+ while (cur != NULL) {
-+ if (cur->name != NULL) {
-+ if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
-+ xmlAttrPtr attr = cur->properties;
-+ int http;
-+ const xmlChar *value;
-+
-+ content = NULL;
-+ http = 0;
-+ while (attr != NULL) {
-+ if ((attr->children != NULL) &&
-+ (attr->children->type == XML_TEXT_NODE) &&
-+ (attr->children->next == NULL)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ value = attr->children->content;
-+#else
-+ value = xmlBufferContent(attr->children->content);
-+#endif
-+ if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
-+ && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
-+ http = 1;
-+ else if ((value != NULL)
-+ && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
-+ content = value;
-+ if ((http != 0) && (content != NULL))
-+ goto found_content;
-+ }
-+ attr = attr->next;
-+ }
-+ }
-+ }
-+ cur = cur->next;
-+ }
-+ return(NULL);
-+
-+found_content:
-+ encoding = xmlStrstr(content, BAD_CAST"charset=");
-+ if (encoding == NULL)
-+ encoding = xmlStrstr(content, BAD_CAST"Charset=");
-+ if (encoding == NULL)
-+ encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
-+ if (encoding != NULL) {
-+ encoding += 8;
-+ } else {
-+ encoding = xmlStrstr(content, BAD_CAST"charset =");
-+ if (encoding == NULL)
-+ encoding = xmlStrstr(content, BAD_CAST"Charset =");
-+ if (encoding == NULL)
-+ encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
-+ if (encoding != NULL)
-+ encoding += 9;
-+ }
-+ if (encoding != NULL) {
-+ while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
-+ }
-+ return(encoding);
-+}
-+
-+/**
-+ * htmlSetMetaEncoding:
-+ * @doc: the document
-+ * @encoding: the encoding string
-+ *
-+ * Sets the current encoding in the Meta tags
-+ * NOTE: this will not change the document content encoding, just
-+ * the META flag associated.
-+ *
-+ * Returns 0 in case of success and -1 in case of error
-+ */
-+int
-+htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
-+ htmlNodePtr cur, meta;
-+ const xmlChar *content;
-+ char newcontent[100];
-+
-+
-+ if (doc == NULL)
-+ return(-1);
-+
-+ if (encoding != NULL) {
-+#ifdef HAVE_SNPRINTF
-+ snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
-+ encoding);
-+#else
-+ sprintf(newcontent, "text/html; charset=%s", encoding);
-+#endif
-+ newcontent[sizeof(newcontent) - 1] = 0;
-+ }
-+
-+ cur = doc->children;
-+
-+ /*
-+ * Search the html
-+ */
-+ while (cur != NULL) {
-+ if (cur->name != NULL) {
-+ if (xmlStrEqual(cur->name, BAD_CAST"html"))
-+ break;
-+ if (xmlStrEqual(cur->name, BAD_CAST"body")) {
-+ if (encoding == NULL)
-+ return(0);
-+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"head", NULL);
-+ xmlAddPrevSibling(cur, meta);
-+ cur = meta;
-+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-+ xmlAddChild(cur, meta);
-+ xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-+ xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-+ return(0);
-+ }
-+ if (xmlStrEqual(cur->name, BAD_CAST"head"))
-+ goto found_head;
-+ if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-+ goto found_meta;
-+ }
-+ cur = cur->next;
-+ }
-+ if (cur == NULL)
-+ return(-1);
-+ cur = cur->children;
-+
-+ /*
-+ * Search the head
-+ */
-+ while (cur != NULL) {
-+ if (cur->name != NULL) {
-+ if (xmlStrEqual(cur->name, BAD_CAST"head"))
-+ break;
-+ if (xmlStrEqual(cur->name, BAD_CAST"body")) {
-+ if (encoding == NULL)
-+ return(0);
-+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"head", NULL);
-+ xmlAddPrevSibling(cur, meta);
-+ cur = meta;
-+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-+ xmlAddChild(cur, meta);
-+ xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-+ xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-+ return(0);
-+ }
-+ if (xmlStrEqual(cur->name, BAD_CAST"meta"))
-+ goto found_meta;
-+ }
-+ cur = cur->next;
-+ }
-+ if (cur == NULL)
-+ return(-1);
-+found_head:
-+ if (cur->children == NULL) {
-+ if (encoding == NULL)
-+ return(0);
-+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-+ xmlAddChild(cur, meta);
-+ xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-+ xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-+ return(0);
-+ }
-+ cur = cur->children;
-+
-+found_meta:
-+ if (encoding != NULL) {
-+ /*
-+ * Create a new Meta element with the right aatributes
-+ */
-+
-+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-+ xmlAddPrevSibling(cur, meta);
-+ xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-+ xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-+ }
-+
-+ /*
-+ * Search and destroy all the remaining the meta elements carrying
-+ * encoding informations
-+ */
-+ while (cur != NULL) {
-+ if (cur->name != NULL) {
-+ if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
-+ xmlAttrPtr attr = cur->properties;
-+ int http;
-+ const xmlChar *value;
-+
-+ content = NULL;
-+ http = 0;
-+ while (attr != NULL) {
-+ if ((attr->children != NULL) &&
-+ (attr->children->type == XML_TEXT_NODE) &&
-+ (attr->children->next == NULL)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ value = attr->children->content;
-+#else
-+ value = xmlBufferContent(attr->children->content);
-+#endif
-+ if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
-+ && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
-+ http = 1;
-+ else if ((value != NULL)
-+ && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
-+ content = value;
-+ if ((http != 0) && (content != NULL))
-+ break;
-+ }
-+ attr = attr->next;
-+ }
-+ if ((http != 0) && (content != NULL)) {
-+ meta = cur;
-+ cur = cur->next;
-+ xmlUnlinkNode(meta);
-+ xmlFreeNode(meta);
-+ continue;
-+ }
-+
-+ }
-+ }
-+ cur = cur->next;
-+ }
-+ return(0);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Dumping HTML tree content to a simple buffer *
-+ * *
-+ ************************************************************************/
-+
-+static void
-+htmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur);
-+
-+/**
-+ * htmlDtdDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ *
-+ * Dump the HTML document DTD, if any.
-+ */
-+static void
-+htmlDtdDump(xmlBufferPtr buf, xmlDocPtr doc) {
-+ xmlDtdPtr cur = doc->intSubset;
-+
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlDtdDump : no internal subset\n");
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, "<!DOCTYPE ");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ if (cur->ExternalID != NULL) {
-+ xmlBufferWriteChar(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf, cur->ExternalID);
-+ if (cur->SystemID != NULL) {
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteQuotedString(buf, cur->SystemID);
-+ }
-+ } else if (cur->SystemID != NULL) {
-+ xmlBufferWriteChar(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf, cur->SystemID);
-+ }
-+ xmlBufferWriteChar(buf, ">\n");
-+}
-+
-+/**
-+ * htmlAttrDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the attribute pointer
-+ *
-+ * Dump an HTML attribute
-+ */
-+static void
-+htmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-+ xmlChar *value;
-+
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlAttrDump : property == NULL\n");
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ if (cur->children != NULL) {
-+ value = xmlNodeListGetString(doc, cur->children, 0);
-+ if (value) {
-+ xmlBufferWriteChar(buf, "=");
-+ xmlBufferWriteQuotedString(buf, value);
-+ xmlFree(value);
-+ } else {
-+ xmlBufferWriteChar(buf, "=\"\"");
-+ }
-+ }
-+}
-+
-+/**
-+ * htmlAttrListDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the first attribute pointer
-+ *
-+ * Dump a list of HTML attributes
-+ */
-+static void
-+htmlAttrListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlAttrListDump : property == NULL\n");
-+ return;
-+ }
-+ while (cur != NULL) {
-+ htmlAttrDump(buf, doc, cur);
-+ cur = cur->next;
-+ }
-+}
-+
-+
-+void
-+htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur);
-+/**
-+ * htmlNodeListDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the first node
-+ *
-+ * Dump an HTML node list, recursive behaviour,children are printed too.
-+ */
-+static void
-+htmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlNodeListDump : node == NULL\n");
-+ return;
-+ }
-+ while (cur != NULL) {
-+ htmlNodeDump(buf, doc, cur);
-+ cur = cur->next;
-+ }
-+}
-+
-+/**
-+ * htmlNodeDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the current node
-+ *
-+ * Dump an HTML node, recursive behaviour,children are printed too.
-+ */
-+void
-+htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
-+ htmlElemDescPtr info;
-+
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlNodeDump : node == NULL\n");
-+ return;
-+ }
-+ /*
-+ * Special cases.
-+ */
-+ if (cur->type == XML_DTD_NODE)
-+ return;
-+ if (cur->type == XML_HTML_DOCUMENT_NODE) {
-+ htmlDocContentDump(buf, (xmlDocPtr) cur);
-+ return;
-+ }
-+ if (cur->type == HTML_TEXT_NODE) {
-+ if (cur->content != NULL) {
-+ if ((cur->name == xmlStringText) ||
-+ (cur->name != xmlStringTextNoenc)) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+#else
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlBufferWriteCHAR(buf, buffer);
-+ xmlFree(buffer);
-+ }
-+ } else {
-+ xmlBufferWriteCHAR(buf, cur->content);
-+ }
-+ }
-+ return;
-+ }
-+ if (cur->type == HTML_COMMENT_NODE) {
-+ if (cur->content != NULL) {
-+ xmlBufferWriteChar(buf, "<!--");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlBufferWriteCHAR(buf, cur->content);
-+#else
-+ xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
-+#endif
-+ xmlBufferWriteChar(buf, "-->");
-+ }
-+ return;
-+ }
-+ if (cur->type == HTML_ENTITY_REF_NODE) {
-+ xmlBufferWriteChar(buf, "&");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ xmlBufferWriteChar(buf, ";");
-+ return;
-+ }
-+
-+ /*
-+ * Get specific HTmL info for taht node.
-+ */
-+ info = htmlTagLookup(cur->name);
-+
-+ xmlBufferWriteChar(buf, "<");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ if (cur->properties != NULL)
-+ htmlAttrListDump(buf, doc, cur->properties);
-+
-+ if ((info != NULL) && (info->empty)) {
-+ xmlBufferWriteChar(buf, ">");
-+ if (cur->next != NULL) {
-+ if ((cur->next->type != HTML_TEXT_NODE) &&
-+ (cur->next->type != HTML_ENTITY_REF_NODE))
-+ xmlBufferWriteChar(buf, "\n");
-+ }
-+ return;
-+ }
-+ if ((cur->content == NULL) && (cur->children == NULL)) {
-+ if ((info != NULL) && (info->endTag != 0))
-+ xmlBufferWriteChar(buf, ">");
-+ else {
-+ xmlBufferWriteChar(buf, "></");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ xmlBufferWriteChar(buf, ">");
-+ }
-+ if (cur->next != NULL) {
-+ if ((cur->next->type != HTML_TEXT_NODE) &&
-+ (cur->next->type != HTML_ENTITY_REF_NODE))
-+ xmlBufferWriteChar(buf, "\n");
-+ }
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, ">");
-+ if (cur->content != NULL) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+#else
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlBufferWriteCHAR(buf, buffer);
-+ xmlFree(buffer);
-+ }
-+ }
-+ if (cur->children != NULL) {
-+ if ((cur->children->type != HTML_TEXT_NODE) &&
-+ (cur->children->type != HTML_ENTITY_REF_NODE) &&
-+ (cur->children != cur->last))
-+ xmlBufferWriteChar(buf, "\n");
-+ htmlNodeListDump(buf, doc, cur->children);
-+ if ((cur->last->type != HTML_TEXT_NODE) &&
-+ (cur->last->type != HTML_ENTITY_REF_NODE) &&
-+ (cur->children != cur->last))
-+ xmlBufferWriteChar(buf, "\n");
-+ }
-+ if (!htmlIsAutoClosed(doc, cur)) {
-+ xmlBufferWriteChar(buf, "</");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ xmlBufferWriteChar(buf, ">");
-+ }
-+ if (cur->next != NULL) {
-+ if ((cur->next->type != HTML_TEXT_NODE) &&
-+ (cur->next->type != HTML_ENTITY_REF_NODE))
-+ xmlBufferWriteChar(buf, "\n");
-+ }
-+}
-+
-+/**
-+ * htmlNodeDumpFile:
-+ * @out: the FILE pointer
-+ * @doc: the document
-+ * @cur: the current node
-+ *
-+ * Dump an HTML node, recursive behaviour,children are printed too.
-+ */
-+void
-+htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
-+ xmlBufferPtr buf;
-+
-+ buf = xmlBufferCreate();
-+ if (buf == NULL) return;
-+ htmlNodeDump(buf, doc, cur);
-+ xmlBufferDump(out, buf);
-+ xmlBufferFree(buf);
-+}
-+
-+/**
-+ * htmlDocContentDump:
-+ * @buf: the HTML buffer output
-+ * @cur: the document
-+ *
-+ * Dump an HTML document.
-+ */
-+static void
-+htmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur) {
-+ int type;
-+
-+ /*
-+ * force to output the stuff as HTML, especially for entities
-+ */
-+ type = cur->type;
-+ cur->type = XML_HTML_DOCUMENT_NODE;
-+ if (cur->intSubset != NULL)
-+ htmlDtdDump(buf, cur);
-+ else {
-+ /* Default to HTML-4.0 transitionnal @@@@ */
-+ xmlBufferWriteChar(buf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">");
-+
-+ }
-+ if (cur->children != NULL) {
-+ htmlNodeListDump(buf, cur, cur->children);
-+ }
-+ xmlBufferWriteChar(buf, "\n");
-+ cur->type = (xmlElementType) type;
-+}
-+
-+/**
-+ * htmlDocDumpMemory:
-+ * @cur: the document
-+ * @mem: OUT: the memory pointer
-+ * @size: OUT: the memory lenght
-+ *
-+ * Dump an HTML document in memory and return the xmlChar * and it's size.
-+ * It's up to the caller to free the memory.
-+ */
-+void
-+htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
-+ xmlBufferPtr buf;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlxmlDocDumpMemory : document == NULL\n");
-+#endif
-+ *mem = NULL;
-+ *size = 0;
-+ return;
-+ }
-+ buf = xmlBufferCreate();
-+ if (buf == NULL) {
-+ *mem = NULL;
-+ *size = 0;
-+ return;
-+ }
-+ htmlDocContentDump(buf, cur);
-+ *mem = buf->content;
-+ *size = buf->use;
-+ memset(buf, -1, sizeof(xmlBuffer));
-+ xmlFree(buf);
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Dumping HTML tree content to an I/O output buffer *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlDtdDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ *
-+ * Dump the HTML document DTD, if any.
-+ */
-+static void
-+htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, const char *encoding) {
-+ xmlDtdPtr cur = doc->intSubset;
-+
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlDtdDump : no internal subset\n");
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ if (cur->ExternalID != NULL) {
-+ xmlOutputBufferWriteString(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID);
-+ if (cur->SystemID != NULL) {
-+ xmlOutputBufferWriteString(buf, " ");
-+ xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
-+ }
-+ } else if (cur->SystemID != NULL) {
-+ xmlOutputBufferWriteString(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
-+ }
-+ xmlOutputBufferWriteString(buf, ">\n");
-+}
-+
-+/**
-+ * htmlAttrDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the attribute pointer
-+ *
-+ * Dump an HTML attribute
-+ */
-+static void
-+htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
-+ xmlChar *value;
-+
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlAttrDump : property == NULL\n");
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, " ");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ if (cur->children != NULL) {
-+ value = xmlNodeListGetString(doc, cur->children, 0);
-+ if (value) {
-+ xmlOutputBufferWriteString(buf, "=");
-+ xmlBufferWriteQuotedString(buf->buffer, value);
-+ xmlFree(value);
-+ } else {
-+ xmlOutputBufferWriteString(buf, "=\"\"");
-+ }
-+ }
-+}
-+
-+/**
-+ * htmlAttrListDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the first attribute pointer
-+ *
-+ * Dump a list of HTML attributes
-+ */
-+static void
-+htmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlAttrListDump : property == NULL\n");
-+ return;
-+ }
-+ while (cur != NULL) {
-+ htmlAttrDumpOutput(buf, doc, cur, encoding);
-+ cur = cur->next;
-+ }
-+}
-+
-+
-+void htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
-+ xmlNodePtr cur, const char *encoding);
-+
-+/**
-+ * htmlNodeListDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the first node
-+ *
-+ * Dump an HTML node list, recursive behaviour,children are printed too.
-+ */
-+static void
-+htmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const char *encoding) {
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlNodeListDump : node == NULL\n");
-+ return;
-+ }
-+ while (cur != NULL) {
-+ htmlNodeDumpOutput(buf, doc, cur, encoding);
-+ cur = cur->next;
-+ }
-+}
-+
-+/**
-+ * htmlNodeDump:
-+ * @buf: the HTML buffer output
-+ * @doc: the document
-+ * @cur: the current node
-+ *
-+ * Dump an HTML node, recursive behaviour,children are printed too.
-+ */
-+void
-+htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const char *encoding) {
-+ htmlElemDescPtr info;
-+
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlNodeDump : node == NULL\n");
-+ return;
-+ }
-+ /*
-+ * Special cases.
-+ */
-+ if (cur->type == XML_DTD_NODE)
-+ return;
-+ if (cur->type == XML_HTML_DOCUMENT_NODE) {
-+ htmlDocContentDumpOutput(buf, (xmlDocPtr) cur, encoding);
-+ return;
-+ }
-+ if (cur->type == HTML_TEXT_NODE) {
-+ if (cur->content != NULL) {
-+ if ((cur->name == xmlStringText) ||
-+ (cur->name != xmlStringTextNoenc)) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+#else
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlOutputBufferWriteString(buf, (const char *)buffer);
-+ xmlFree(buffer);
-+ }
-+ } else {
-+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
-+ }
-+ }
-+ return;
-+ }
-+ if (cur->type == HTML_COMMENT_NODE) {
-+ if (cur->content != NULL) {
-+ xmlOutputBufferWriteString(buf, "<!--");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf, (const char *)
-+ xmlBufferContent(cur->content));
-+#endif
-+ xmlOutputBufferWriteString(buf, "-->");
-+ }
-+ return;
-+ }
-+ if (cur->type == HTML_ENTITY_REF_NODE) {
-+ xmlOutputBufferWriteString(buf, "&");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ xmlOutputBufferWriteString(buf, ";");
-+ return;
-+ }
-+ if (cur->type == HTML_PRESERVE_NODE) {
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf, (const char *)
-+ xmlBufferContent(cur->content));
-+#endif
-+ }
-+ return;
-+ }
-+
-+ /*
-+ * Get specific HTmL info for taht node.
-+ */
-+ info = htmlTagLookup(cur->name);
-+
-+ xmlOutputBufferWriteString(buf, "<");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ if (cur->properties != NULL)
-+ htmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
-+
-+ if ((info != NULL) && (info->empty)) {
-+ xmlOutputBufferWriteString(buf, ">");
-+ if (cur->next != NULL) {
-+ if ((cur->next->type != HTML_TEXT_NODE) &&
-+ (cur->next->type != HTML_ENTITY_REF_NODE))
-+ xmlOutputBufferWriteString(buf, "\n");
-+ }
-+ return;
-+ }
-+ if ((cur->content == NULL) && (cur->children == NULL)) {
-+ if ((info != NULL) && (info->endTag != 0) &&
-+ (strcmp(info->name, "html")) && (strcmp(info->name, "body"))) {
-+ xmlOutputBufferWriteString(buf, ">");
-+ } else {
-+ xmlOutputBufferWriteString(buf, "></");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ xmlOutputBufferWriteString(buf, ">");
-+ }
-+ if (cur->next != NULL) {
-+ if ((cur->next->type != HTML_TEXT_NODE) &&
-+ (cur->next->type != HTML_ENTITY_REF_NODE))
-+ xmlOutputBufferWriteString(buf, "\n");
-+ }
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, ">");
-+ if (cur->content != NULL) {
-+ /*
-+ * Uses the OutputBuffer property to automatically convert
-+ * invalids to charrefs
-+ */
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *) cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf,
-+ (const char *) xmlBufferContent(cur->content));
-+#endif
-+ }
-+ if (cur->children != NULL) {
-+ if ((cur->children->type != HTML_TEXT_NODE) &&
-+ (cur->children->type != HTML_ENTITY_REF_NODE) &&
-+ (cur->children != cur->last))
-+ xmlOutputBufferWriteString(buf, "\n");
-+ htmlNodeListDumpOutput(buf, doc, cur->children, encoding);
-+ if ((cur->last->type != HTML_TEXT_NODE) &&
-+ (cur->last->type != HTML_ENTITY_REF_NODE) &&
-+ (cur->children != cur->last))
-+ xmlOutputBufferWriteString(buf, "\n");
-+ }
-+ if (!htmlIsAutoClosed(doc, cur)) {
-+ xmlOutputBufferWriteString(buf, "</");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ xmlOutputBufferWriteString(buf, ">");
-+ }
-+ if (cur->next != NULL) {
-+ if ((cur->next->type != HTML_TEXT_NODE) &&
-+ (cur->next->type != HTML_ENTITY_REF_NODE))
-+ xmlOutputBufferWriteString(buf, "\n");
-+ }
-+}
-+
-+/**
-+ * htmlDocContentDump:
-+ * @buf: the HTML buffer output
-+ * @cur: the document
-+ *
-+ * Dump an HTML document.
-+ */
-+void
-+htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
-+ int type;
-+
-+ /*
-+ * force to output the stuff as HTML, especially for entities
-+ */
-+ type = cur->type;
-+ cur->type = XML_HTML_DOCUMENT_NODE;
-+ if (cur->intSubset != NULL)
-+ htmlDtdDumpOutput(buf, cur, NULL);
-+ else {
-+ /* Default to HTML-4.0 transitionnal @@@@ */
-+ xmlOutputBufferWriteString(buf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
-+
-+ }
-+ if (cur->children != NULL) {
-+ htmlNodeListDumpOutput(buf, cur, cur->children, encoding);
-+ }
-+ xmlOutputBufferWriteString(buf, "\n");
-+ cur->type = (xmlElementType) type;
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Saving functions front-ends *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * htmlDocDump:
-+ * @f: the FILE*
-+ * @cur: the document
-+ *
-+ * Dump an HTML document to an open FILE.
-+ *
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+htmlDocDump(FILE *f, xmlDocPtr cur) {
-+ xmlOutputBufferPtr buf;
-+ xmlCharEncodingHandlerPtr handler = NULL;
-+ const char *encoding;
-+ int ret;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "htmlDocDump : document == NULL\n");
-+#endif
-+ return(-1);
-+ }
-+
-+ encoding = (const char *) htmlGetMetaEncoding(cur);
-+
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+
-+ enc = xmlParseCharEncoding(encoding);
-+ if (enc != cur->charset) {
-+ if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * Not supported yet
-+ */
-+ return(-1);
-+ }
-+
-+ handler = xmlFindCharEncodingHandler(encoding);
-+ if (handler == NULL)
-+ return(-1);
-+ }
-+ }
-+
-+ /*
-+ * Fallback to HTML or ASCII when the encoding is unspecified
-+ */
-+ if (handler == NULL)
-+ handler = xmlFindCharEncodingHandler("HTML");
-+ if (handler == NULL)
-+ handler = xmlFindCharEncodingHandler("ascii");
-+
-+ buf = xmlOutputBufferCreateFile(f, handler);
-+ if (buf == NULL) return(-1);
-+ htmlDocContentDumpOutput(buf, cur, NULL);
-+
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+
-+/**
-+ * htmlSaveFile:
-+ * @filename: the filename (or URL)
-+ * @cur: the document
-+ *
-+ * Dump an HTML document to a file. If @filename is "-" the stdout file is
-+ * used.
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+htmlSaveFile(const char *filename, xmlDocPtr cur) {
-+ xmlOutputBufferPtr buf;
-+ xmlCharEncodingHandlerPtr handler = NULL;
-+ const char *encoding;
-+ int ret;
-+
-+ encoding = (const char *) htmlGetMetaEncoding(cur);
-+
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+
-+ enc = xmlParseCharEncoding(encoding);
-+ if (enc != cur->charset) {
-+ if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * Not supported yet
-+ */
-+ return(-1);
-+ }
-+
-+ handler = xmlFindCharEncodingHandler(encoding);
-+ if (handler == NULL)
-+ return(-1);
-+ }
-+ }
-+
-+ /*
-+ * Fallback to HTML or ASCII when the encoding is unspecified
-+ */
-+ if (handler == NULL)
-+ handler = xmlFindCharEncodingHandler("HTML");
-+ if (handler == NULL)
-+ handler = xmlFindCharEncodingHandler("ascii");
-+
-+ /*
-+ * save the content to a temp buffer.
-+ */
-+ buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
-+ if (buf == NULL) return(0);
-+
-+ htmlDocContentDumpOutput(buf, cur, NULL);
-+
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+
-+/**
-+ * htmlSaveFileEnc:
-+ * @filename: the filename
-+ * @cur: the document
-+ *
-+ * Dump an HTML document to a file using a given encoding.
-+ *
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
-+ xmlOutputBufferPtr buf;
-+ xmlCharEncodingHandlerPtr handler = NULL;
-+ int ret;
-+
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+
-+ enc = xmlParseCharEncoding(encoding);
-+ if (enc != cur->charset) {
-+ if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * Not supported yet
-+ */
-+ return(-1);
-+ }
-+
-+ handler = xmlFindCharEncodingHandler(encoding);
-+ if (handler == NULL)
-+ return(-1);
-+ htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
-+ }
-+ }
-+
-+ /*
-+ * Fallback to HTML or ASCII when the encoding is unspecified
-+ */
-+ if (handler == NULL)
-+ handler = xmlFindCharEncodingHandler("HTML");
-+ if (handler == NULL)
-+ handler = xmlFindCharEncodingHandler("ascii");
-+
-+ /*
-+ * save the content to a temp buffer.
-+ */
-+ buf = xmlOutputBufferCreateFilename(filename, handler, 0);
-+ if (buf == NULL) return(0);
-+
-+ htmlDocContentDumpOutput(buf, cur, encoding);
-+
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+#endif /* LIBXML_HTML_ENABLED */
-diff -Nru libxml2-2.3.0/libxml/HTMLtree.h libxml2-2.3.0.new/libxml/HTMLtree.h
---- libxml2-2.3.0/libxml/HTMLtree.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/HTMLtree.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,61 @@
-+/*
-+ * tree.h : describes the structures found in an tree resulting
-+ * from an XML parsing.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __HTML_TREE_H__
-+#define __HTML_TREE_H__
-+
-+#include <stdio.h>
-+#include <libxml/tree.h>
-+#include <libxml/HTMLparser.h>
-+
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define HTML_TEXT_NODE XML_TEXT_NODE
-+#define HTML_ENTITY_REF_NODE XML_ENTITY_REF_NODE
-+#define HTML_COMMENT_NODE XML_COMMENT_NODE
-+#define HTML_PRESERVE_NODE XML_CDATA_SECTION_NODE
-+
-+htmlDocPtr htmlNewDoc (const xmlChar *URI,
-+ const xmlChar *ExternalID);
-+htmlDocPtr htmlNewDocNoDtD (const xmlChar *URI,
-+ const xmlChar *ExternalID);
-+const xmlChar * htmlGetMetaEncoding (htmlDocPtr doc);
-+int htmlSetMetaEncoding (htmlDocPtr doc,
-+ const xmlChar *encoding);
-+void htmlDocDumpMemory (xmlDocPtr cur,
-+ xmlChar**mem,
-+ int *size);
-+int htmlDocDump (FILE *f,
-+ xmlDocPtr cur);
-+int htmlSaveFile (const char *filename,
-+ xmlDocPtr cur);
-+void htmlNodeDump (xmlBufferPtr buf,
-+ xmlDocPtr doc,
-+ xmlNodePtr cur);
-+void htmlNodeDumpFile (FILE *out,
-+ xmlDocPtr doc,
-+ xmlNodePtr cur);
-+int htmlSaveFileEnc (const char *filename,
-+ xmlDocPtr cur,
-+ const char *encoding);
-+
-+/* This one is imported from xmlIO.h
-+void htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
-+ xmlDocPtr cur,
-+ const char *encoding);
-+ */
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __HTML_TREE_H__ */
-+
-diff -Nru libxml2-2.3.0/libxml/Makefile.am libxml2-2.3.0.new/libxml/Makefile.am
---- libxml2-2.3.0/libxml/Makefile.am Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/Makefile.am Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,72 @@
-+## Process this file with automake to produce Makefile.in
-+
-+lib_LTLIBRARIES = libxml.la
-+
-+libxmlincludedir = $(includedir)/libxml
-+libxmlinclude_HEADERS = \
-+ debugXML.h \
-+ encoding.h \
-+ entities.h \
-+ hash.h \
-+ HTMLparser.h \
-+ HTMLtree.h \
-+ nanoftp.h \
-+ nanohttp.h \
-+ parser.h \
-+ parserInternals.h \
-+ SAX.h \
-+ tree.h \
-+ uri.h \
-+ valid.h \
-+ xinclude.h \
-+ xlink.h \
-+ xmlerror.h \
-+ xmlIO.h \
-+ xmlmemory.h \
-+ xmlversion.h \
-+ xpath.h \
-+ xpathInternals.h \
-+ xpointer.h
-+
-+libxml_la_LDFLAGS = -version-info $(LIBXML_VERSION_INFO)
-+libxml_la_SOURCES = \
-+ debugXML.c \
-+ encoding.c \
-+ entities.c \
-+ error.c \
-+ hash.c \
-+ HTMLparser.c \
-+ HTMLtree.c \
-+ nanoftp.c \
-+ nanohttp.c \
-+ parser.c \
-+ parserInternals.c \
-+ SAX.c \
-+ tree.c \
-+ uri.c \
-+ valid.c \
-+ xinclude.c \
-+ xlink.c \
-+ xmlIO.c \
-+ xmlmemory.c \
-+ xpath.c \
-+ xpointer.c \
-+ $(libxmlinclude_HEADERS)
-+
-+man_MANS = xml-config.1 libxml.4
-+
-+m4datadir = $(datadir)/aclocal
-+m4data_DATA = libxml.m4
-+
-+CLEANFILES=xmlConf.sh
-+
-+confexecdir = $(libdir)/
-+confexec_DATA = xmlConf.sh
-+
-+bin_SCRIPTS = xml-config
-+
-+pkgconfigdir = $(libdir)/pkgconfig
-+pkgconfig_DATA = libxml.pc
-+
-+EXTRA_DIST = $(man_MANS) $(m4datadir) $(confexecdir) xmlConf.sh.in \
-+ $(pkgconfig_DATA) libxml.pc.in xmlversion.h.in win32config.h
-diff -Nru libxml2-2.3.0/libxml/SAX.c libxml2-2.3.0.new/libxml/SAX.c
---- libxml2-2.3.0/libxml/SAX.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/SAX.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,1749 @@
-+/*
-+ * SAX.c : Default SAX handler to build a tree.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel Veillard <Daniel.Veillard@w3.org>
-+ */
-+
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/valid.h>
-+#include <libxml/entities.h>
-+#include <libxml/xmlerror.h>
-+#include <libxml/debugXML.h>
-+#include <libxml/xmlIO.h>
-+#include <libxml/SAX.h>
-+#include <libxml/uri.h>
-+#include <libxml/HTMLtree.h>
-+
-+/* #define DEBUG_SAX */
-+/* #define DEBUG_SAX_TREE */
-+
-+/**
-+ * getPublicId:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
-+ *
-+ * Returns a xmlChar *
-+ */
-+const xmlChar *
-+getPublicId(void *ctx)
-+{
-+ /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-+ return(NULL);
-+}
-+
-+/**
-+ * getSystemId:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Return the system ID, basically URL or filename e.g.
-+ * http://www.sgmlsource.com/dtds/memo.dtd
-+ *
-+ * Returns a xmlChar *
-+ */
-+const xmlChar *
-+getSystemId(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ return(BAD_CAST ctxt->input->filename);
-+}
-+
-+/**
-+ * getLineNumber:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Return the line number of the current parsing point.
-+ *
-+ * Returns an int
-+ */
-+int
-+getLineNumber(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ return(ctxt->input->line);
-+}
-+
-+/**
-+ * getColumnNumber:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Return the column number of the current parsing point.
-+ *
-+ * Returns an int
-+ */
-+int
-+getColumnNumber(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ return(ctxt->input->col);
-+}
-+
-+/*
-+ * The default SAX Locator.
-+ */
-+
-+xmlSAXLocator xmlDefaultSAXLocator = {
-+ getPublicId, getSystemId, getLineNumber, getColumnNumber
-+};
-+
-+/**
-+ * isStandalone:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Is this document tagged standalone ?
-+ *
-+ * Returns 1 if true
-+ */
-+int
-+isStandalone(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ return(ctxt->myDoc->standalone == 1);
-+}
-+
-+/**
-+ * hasInternalSubset:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Does this document has an internal subset
-+ *
-+ * Returns 1 if true
-+ */
-+int
-+hasInternalSubset(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ return(ctxt->myDoc->intSubset != NULL);
-+}
-+
-+/**
-+ * hasExternalSubset:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Does this document has an external subset
-+ *
-+ * Returns 1 if true
-+ */
-+int
-+hasExternalSubset(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ return(ctxt->myDoc->extSubset != NULL);
-+}
-+
-+/**
-+ * internalSubset:
-+ * @ctx: the user data (XML parser context)
-+ * @name: the root element name
-+ * @ExternalID: the external ID
-+ * @SystemID: the SYSTEM ID (e.g. filename or URL)
-+ *
-+ * Callback on internal subset declaration.
-+ */
-+void
-+internalSubset(void *ctx, const xmlChar *name,
-+ const xmlChar *ExternalID, const xmlChar *SystemID)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlDtdPtr dtd;
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.internalSubset(%s, %s, %s)\n",
-+ name, ExternalID, SystemID);
-+#endif
-+
-+ if (ctxt->myDoc == NULL)
-+ return;
-+ dtd = xmlGetIntSubset(ctxt->myDoc);
-+ if (dtd != NULL) {
-+ if (ctxt->html)
-+ return;
-+ xmlUnlinkNode((xmlNodePtr) dtd);
-+ xmlFreeDtd(dtd);
-+ ctxt->myDoc->intSubset = NULL;
-+ }
-+ ctxt->myDoc->intSubset =
-+ xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
-+}
-+
-+/**
-+ * externalSubset:
-+ * @ctx: the user data (XML parser context)
-+ * @name: the root element name
-+ * @ExternalID: the external ID
-+ * @SystemID: the SYSTEM ID (e.g. filename or URL)
-+ *
-+ * Callback on external subset declaration.
-+ */
-+void
-+externalSubset(void *ctx, const xmlChar *name,
-+ const xmlChar *ExternalID, const xmlChar *SystemID)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.externalSubset(%s, %s, %s)\n",
-+ name, ExternalID, SystemID);
-+#endif
-+ if (((ExternalID != NULL) || (SystemID != NULL)) &&
-+ (((ctxt->validate) || (ctxt->loadsubset)) &&
-+ (ctxt->wellFormed && ctxt->myDoc))) {
-+ /*
-+ * Try to fetch and parse the external subset.
-+ */
-+ xmlParserInputPtr oldinput;
-+ int oldinputNr;
-+ int oldinputMax;
-+ xmlParserInputPtr *oldinputTab;
-+ int oldwellFormed;
-+ xmlParserInputPtr input = NULL;
-+ xmlCharEncoding enc;
-+ int oldcharset;
-+
-+ /*
-+ * Ask the Entity resolver to load the damn thing
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
-+ input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
-+ SystemID);
-+ if (input == NULL) {
-+ return;
-+ }
-+
-+ xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
-+
-+ /*
-+ * make sure we won't destroy the main document context
-+ */
-+ oldinput = ctxt->input;
-+ oldinputNr = ctxt->inputNr;
-+ oldinputMax = ctxt->inputMax;
-+ oldinputTab = ctxt->inputTab;
-+ oldwellFormed = ctxt->wellFormed;
-+ oldcharset = ctxt->charset;
-+
-+ ctxt->inputTab = (xmlParserInputPtr *)
-+ xmlMalloc(5 * sizeof(xmlParserInputPtr));
-+ if (ctxt->inputTab == NULL) {
-+ ctxt->errNo = XML_ERR_NO_MEMORY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "externalSubset: out of memory\n");
-+ ctxt->errNo = XML_ERR_NO_MEMORY;
-+ ctxt->input = oldinput;
-+ ctxt->inputNr = oldinputNr;
-+ ctxt->inputMax = oldinputMax;
-+ ctxt->inputTab = oldinputTab;
-+ ctxt->charset = oldcharset;
-+ return;
-+ }
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 5;
-+ ctxt->input = NULL;
-+ xmlPushInput(ctxt, input);
-+
-+ /*
-+ * On the fly encoding conversion if needed
-+ */
-+ enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
-+ xmlSwitchEncoding(ctxt, enc);
-+
-+ if (input->filename == NULL)
-+ input->filename = (char *) xmlStrdup(SystemID);
-+ input->line = 1;
-+ input->col = 1;
-+ input->base = ctxt->input->cur;
-+ input->cur = ctxt->input->cur;
-+ input->free = NULL;
-+
-+ /*
-+ * let's parse that entity knowing it's an external subset.
-+ */
-+ xmlParseExternalSubset(ctxt, ExternalID, SystemID);
-+
-+ /*
-+ * Free up the external entities
-+ */
-+
-+ while (ctxt->inputNr > 1)
-+ xmlPopInput(ctxt);
-+ xmlFreeInputStream(ctxt->input);
-+ xmlFree(ctxt->inputTab);
-+
-+ /*
-+ * Restore the parsing context of the main entity
-+ */
-+ ctxt->input = oldinput;
-+ ctxt->inputNr = oldinputNr;
-+ ctxt->inputMax = oldinputMax;
-+ ctxt->inputTab = oldinputTab;
-+ ctxt->charset = oldcharset;
-+ /* ctxt->wellFormed = oldwellFormed; */
-+ }
-+}
-+
-+/**
-+ * resolveEntity:
-+ * @ctx: the user data (XML parser context)
-+ * @publicId: The public ID of the entity
-+ * @systemId: The system ID of the entity
-+ *
-+ * The entity loader, to control the loading of external entities,
-+ * the application can either:
-+ * - override this resolveEntity() callback in the SAX block
-+ * - or better use the xmlSetExternalEntityLoader() function to
-+ * set up it's own entity resolution routine
-+ *
-+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
-+ */
-+xmlParserInputPtr
-+resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlParserInputPtr ret;
-+ xmlChar *URI;
-+ const char *base = NULL;
-+
-+ if (ctxt->input != NULL)
-+ base = ctxt->input->filename;
-+ if (base == NULL)
-+ base = ctxt->directory;
-+
-+ URI = xmlBuildURI(systemId, (const xmlChar *) base);
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
-+#endif
-+
-+ ret = xmlLoadExternalEntity((const char *) URI,
-+ (const char *) publicId, ctxt);
-+ if (URI != NULL)
-+ xmlFree(URI);
-+ return(ret);
-+}
-+
-+/**
-+ * getEntity:
-+ * @ctx: the user data (XML parser context)
-+ * @name: The entity name
-+ *
-+ * Get an entity by name
-+ *
-+ * Returns the xmlEntityPtr if found.
-+ */
-+xmlEntityPtr
-+getEntity(void *ctx, const xmlChar *name)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlEntityPtr ret;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.getEntity(%s)\n", name);
-+#endif
-+
-+ ret = xmlGetDocEntity(ctxt->myDoc, name);
-+ if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
-+ (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-+ /*
-+ * for validation purposes we really need to fetch and
-+ * parse the external entity
-+ */
-+ int parse;
-+ xmlNodePtr children;
-+
-+ parse = xmlParseCtxtExternalEntity(ctxt,
-+ ret->SystemID, ret->ExternalID, &children);
-+ xmlAddChildList((xmlNodePtr) ret, children);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * getParameterEntity:
-+ * @ctx: the user data (XML parser context)
-+ * @name: The entity name
-+ *
-+ * Get a parameter entity by name
-+ *
-+ * Returns the xmlEntityPtr if found.
-+ */
-+xmlEntityPtr
-+getParameterEntity(void *ctx, const xmlChar *name)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlEntityPtr ret;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.getParameterEntity(%s)\n", name);
-+#endif
-+
-+ ret = xmlGetParameterEntity(ctxt->myDoc, name);
-+ return(ret);
-+}
-+
-+
-+/**
-+ * entityDecl:
-+ * @ctx: the user data (XML parser context)
-+ * @name: the entity name
-+ * @type: the entity type
-+ * @publicId: The public ID of the entity
-+ * @systemId: The system ID of the entity
-+ * @content: the entity value (without processing).
-+ *
-+ * An entity definition has been parsed
-+ */
-+void
-+entityDecl(void *ctx, const xmlChar *name, int type,
-+ const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
-+{
-+ xmlEntityPtr ent;
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
-+ name, type, publicId, systemId, content);
-+#endif
-+ if (ctxt->inSubset == 1) {
-+ ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
-+ systemId, content);
-+ if ((ent == NULL) && (ctxt->pedantic) &&
-+ (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt,
-+ "Entity(%s) already defined in the internal subset\n", name);
-+ if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
-+ xmlChar *URI;
-+ const char *base = NULL;
-+
-+ if (ctxt->input != NULL)
-+ base = ctxt->input->filename;
-+ if (base == NULL)
-+ base = ctxt->directory;
-+
-+ URI = xmlBuildURI(systemId, (const xmlChar *) base);
-+ ent->URI = URI;
-+ }
-+ } else if (ctxt->inSubset == 2) {
-+ ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
-+ systemId, content);
-+ if ((ent == NULL) && (ctxt->pedantic) &&
-+ (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt,
-+ "Entity(%s) already defined in the external subset\n", name);
-+ if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
-+ xmlChar *URI;
-+ const char *base = NULL;
-+
-+ if (ctxt->input != NULL)
-+ base = ctxt->input->filename;
-+ if (base == NULL)
-+ base = ctxt->directory;
-+
-+ URI = xmlBuildURI(systemId, (const xmlChar *) base);
-+ ent->URI = URI;
-+ }
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "SAX.entityDecl(%s) called while not in subset\n", name);
-+ }
-+}
-+
-+/**
-+ * attributeDecl:
-+ * @ctx: the user data (XML parser context)
-+ * @elem: the name of the element
-+ * @fullname: the attribute name
-+ * @type: the attribute type
-+ * @def: the type of default value
-+ * @defaultValue: the attribute default value
-+ * @tree: the tree of enumerated value set
-+ *
-+ * An attribute definition has been parsed
-+ */
-+void
-+attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
-+ int type, int def, const xmlChar *defaultValue,
-+ xmlEnumerationPtr tree)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlAttributePtr attr;
-+ xmlChar *name = NULL, *prefix = NULL;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
-+ elem, fullname, type, def, defaultValue);
-+#endif
-+ name = xmlSplitQName(ctxt, fullname, &prefix);
-+ if (ctxt->inSubset == 1)
-+ attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
-+ name, prefix, (xmlAttributeType) type,
-+ (xmlAttributeDefault) def, defaultValue, tree);
-+ else if (ctxt->inSubset == 2)
-+ attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
-+ name, prefix, (xmlAttributeType) type,
-+ (xmlAttributeDefault) def, defaultValue, tree);
-+ else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "SAX.attributeDecl(%s) called while not in subset\n", name);
-+ return;
-+ }
-+ if (attr == 0) ctxt->valid = 0;
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
-+ attr);
-+ if (prefix != NULL)
-+ xmlFree(prefix);
-+ if (name != NULL)
-+ xmlFree(name);
-+}
-+
-+/**
-+ * elementDecl:
-+ * @ctx: the user data (XML parser context)
-+ * @name: the element name
-+ * @type: the element type
-+ * @content: the element value tree
-+ *
-+ * An element definition has been parsed
-+ */
-+void
-+elementDecl(void *ctx, const xmlChar *name, int type,
-+ xmlElementContentPtr content)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlElementPtr elem = NULL;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.elementDecl(%s, %d, ...)\n",
-+ fullname, type);
-+#endif
-+
-+ if (ctxt->inSubset == 1)
-+ elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
-+ name, (xmlElementTypeVal) type, content);
-+ else if (ctxt->inSubset == 2)
-+ elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
-+ name, (xmlElementTypeVal) type, content);
-+ else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "SAX.elementDecl(%s) called while not in subset\n", name);
-+ return;
-+ }
-+ if (elem == NULL) ctxt->valid = 0;
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
-+}
-+
-+/**
-+ * notationDecl:
-+ * @ctx: the user data (XML parser context)
-+ * @name: The name of the notation
-+ * @publicId: The public ID of the entity
-+ * @systemId: The system ID of the entity
-+ *
-+ * What to do when a notation declaration has been parsed.
-+ */
-+void
-+notationDecl(void *ctx, const xmlChar *name,
-+ const xmlChar *publicId, const xmlChar *systemId)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNotationPtr nota = NULL;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
-+#endif
-+
-+ if (ctxt->inSubset == 1)
-+ nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
-+ publicId, systemId);
-+ else if (ctxt->inSubset == 2)
-+ nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
-+ publicId, systemId);
-+ else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "SAX.notationDecl(%s) called while not in subset\n", name);
-+ return;
-+ }
-+ if (nota == NULL) ctxt->valid = 0;
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
-+ nota);
-+}
-+
-+/**
-+ * unparsedEntityDecl:
-+ * @ctx: the user data (XML parser context)
-+ * @name: The name of the entity
-+ * @publicId: The public ID of the entity
-+ * @systemId: The system ID of the entity
-+ * @notationName: the name of the notation
-+ *
-+ * What to do when an unparsed entity declaration is parsed
-+ */
-+void
-+unparsedEntityDecl(void *ctx, const xmlChar *name,
-+ const xmlChar *publicId, const xmlChar *systemId,
-+ const xmlChar *notationName)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
-+ name, publicId, systemId, notationName);
-+#endif
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
-+ notationName);
-+ xmlAddDocEntity(ctxt->myDoc, name,
-+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
-+ publicId, systemId, notationName);
-+}
-+
-+/**
-+ * setDocumentLocator:
-+ * @ctx: the user data (XML parser context)
-+ * @loc: A SAX Locator
-+ *
-+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
-+ * Everything is available on the context, so this is useless in our case.
-+ */
-+void
-+setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
-+{
-+ /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.setDocumentLocator()\n");
-+#endif
-+}
-+
-+/**
-+ * startDocument:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * called when the document start being processed.
-+ */
-+void
-+startDocument(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlDocPtr doc;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.startDocument()\n");
-+#endif
-+ if (ctxt->html) {
-+ if (ctxt->myDoc == NULL)
-+#ifdef LIBXML_HTML_ENABLED
-+ ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
-+#else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "libxml2 built without HTML support\n");
-+#endif
-+ } else {
-+ doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
-+ if (doc != NULL) {
-+ if (ctxt->encoding != NULL)
-+ doc->encoding = xmlStrdup(ctxt->encoding);
-+ else
-+ doc->encoding = NULL;
-+ doc->standalone = ctxt->standalone;
-+ }
-+ }
-+ if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
-+ (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
-+ ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
-+ }
-+}
-+
-+/**
-+ * endDocument:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * called when the document end has been detected.
-+ */
-+void
-+endDocument(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.endDocument()\n");
-+#endif
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
-+
-+ /*
-+ * Grab the encoding if it was added on-the-fly
-+ */
-+ if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
-+ (ctxt->myDoc->encoding == NULL)) {
-+ ctxt->myDoc->encoding = ctxt->encoding;
-+ ctxt->encoding = NULL;
-+ }
-+ if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
-+ (ctxt->myDoc->encoding == NULL)) {
-+ ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
-+ }
-+ if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
-+ (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
-+ ctxt->myDoc->charset = ctxt->charset;
-+ }
-+}
-+
-+/**
-+ * attribute:
-+ * @ctx: the user data (XML parser context)
-+ * @fullname: The attribute name, including namespace prefix
-+ * @value: The attribute value
-+ *
-+ * Handle an attribute that has been read by the parser.
-+ * The default handling is to convert the attribute into an
-+ * DOM subtree and past it in a new xmlAttr element added to
-+ * the element.
-+ */
-+void
-+attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlAttrPtr ret;
-+ xmlChar *name;
-+ xmlChar *ns;
-+ xmlChar *nval;
-+ xmlNsPtr namespace;
-+
-+/****************
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.attribute(%s, %s)\n", fullname, value);
-+#endif
-+ ****************/
-+ /*
-+ * Split the full name into a namespace prefix and the tag name
-+ */
-+ name = xmlSplitQName(ctxt, fullname, &ns);
-+
-+ /*
-+ * Do the last stage of the attribute normalization
-+ * Needed for HTML too:
-+ * http://www.w3.org/TR/html4/types.html#h-6.2
-+ */
-+ nval = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node,
-+ fullname, value);
-+ if (nval != NULL)
-+ value = nval;
-+
-+ /*
-+ * Check whether it's a namespace definition
-+ */
-+ if ((!ctxt->html) && (ns == NULL) &&
-+ (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
-+ (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
-+ xmlURIPtr uri;
-+
-+ uri = xmlParseURI((const char *)value);
-+ if (uri == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "nmlns: %s not a valid URI\n", value);
-+ } else {
-+ if (uri->scheme == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "nmlns: URI %s is not absolute\n", value);
-+ }
-+ xmlFreeURI(uri);
-+ }
-+
-+ /* a default namespace definition */
-+ xmlNewNs(ctxt->node, value, NULL);
-+ if (name != NULL)
-+ xmlFree(name);
-+ if (nval != NULL)
-+ xmlFree(nval);
-+ return;
-+ }
-+ if ((!ctxt->html) &&
-+ (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
-+ (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
-+ /*
-+ * Validate also for namespace decls, they are attributes from
-+ * an XML-1.0 perspective
-+ TODO ... doesn't map well with current API
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
-+ ctxt->node, ret, value);
-+ */
-+ /* a standard namespace definition */
-+ xmlNewNs(ctxt->node, value, name);
-+ xmlFree(ns);
-+ if (name != NULL)
-+ xmlFree(name);
-+ if (nval != NULL)
-+ xmlFree(nval);
-+ return;
-+ }
-+
-+ if (ns != NULL)
-+ namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
-+ else {
-+ namespace = NULL;
-+ }
-+
-+ /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
-+ ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
-+
-+ if (ret != NULL) {
-+ if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
-+ xmlNodePtr tmp;
-+
-+ ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
-+ tmp = ret->children;
-+ while (tmp != NULL) {
-+ tmp->parent = (xmlNodePtr) ret;
-+ if (tmp->next == NULL)
-+ ret->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ } else if (value != NULL) {
-+ ret->children = xmlNewDocText(ctxt->myDoc, value);
-+ ret->last = ret->children;
-+ if (ret->children != NULL)
-+ ret->children->parent = (xmlNodePtr) ret;
-+ }
-+ }
-+
-+ if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset) {
-+
-+ /*
-+ * If we don't substitute entities, the validation should be
-+ * done on a value with replaced entities anyway.
-+ */
-+ if (!ctxt->replaceEntities) {
-+ xmlChar *val;
-+
-+ ctxt->depth++;
-+ val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
-+ 0,0,0);
-+ ctxt->depth--;
-+ if (val == NULL)
-+ ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
-+ ctxt->myDoc, ctxt->node, ret, value);
-+ else {
-+ ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
-+ ctxt->myDoc, ctxt->node, ret, val);
-+ xmlFree(val);
-+ }
-+ } else {
-+ ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
-+ ctxt->node, ret, value);
-+ }
-+ } else {
-+ /*
-+ * when validating, the ID registration is done at the attribute
-+ * validation level. Otherwise we have to do specific handling here.
-+ */
-+ if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
-+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
-+ else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
-+ xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
-+ }
-+
-+ if (nval != NULL)
-+ xmlFree(nval);
-+ if (name != NULL)
-+ xmlFree(name);
-+ if (ns != NULL)
-+ xmlFree(ns);
-+}
-+
-+/**
-+ * startElement:
-+ * @ctx: the user data (XML parser context)
-+ * @fullname: The element name, including namespace prefix
-+ * @atts: An array of name/value attributes pairs, NULL terminated
-+ *
-+ * called when an opening tag has been processed.
-+ */
-+void
-+startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr ret;
-+ xmlNodePtr parent = ctxt->node;
-+ xmlNsPtr ns;
-+ xmlChar *name;
-+ xmlChar *prefix;
-+ const xmlChar *att;
-+ const xmlChar *value;
-+ int i;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.startElement(%s)\n", fullname);
-+#endif
-+
-+ /*
-+ * First check on validity:
-+ */
-+ if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
-+ ((ctxt->myDoc->intSubset == NULL) ||
-+ ((ctxt->myDoc->intSubset->notations == NULL) &&
-+ (ctxt->myDoc->intSubset->elements == NULL) &&
-+ (ctxt->myDoc->intSubset->attributes == NULL) &&
-+ (ctxt->myDoc->intSubset->entities == NULL)))) {
-+ if (ctxt->vctxt.error != NULL) {
-+ ctxt->vctxt.error(ctxt->vctxt.userData,
-+ "Validation failed: no DTD found !\n");
-+ }
-+ ctxt->validate = 0;
-+ }
-+
-+
-+ /*
-+ * Split the full name into a namespace prefix and the tag name
-+ */
-+ name = xmlSplitQName(ctxt, fullname, &prefix);
-+
-+
-+ /*
-+ * Note : the namespace resolution is deferred until the end of the
-+ * attributes parsing, since local namespace can be defined as
-+ * an attribute at this level.
-+ */
-+ ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
-+ if (ret == NULL) return;
-+ if (ctxt->myDoc->children == NULL) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
-+#endif
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-+ } else if (parent == NULL) {
-+ parent = ctxt->myDoc->children;
-+ }
-+ ctxt->nodemem = -1;
-+
-+ /*
-+ * We are parsing a new node.
-+ */
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
-+#endif
-+ nodePush(ctxt, ret);
-+
-+ /*
-+ * Link the child element
-+ */
-+ if (parent != NULL) {
-+ if (parent->type == XML_ELEMENT_NODE) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "adding child %s to %s\n", name, parent->name);
-+#endif
-+ xmlAddChild(parent, ret);
-+ } else {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "adding sibling %s to ", name);
-+ xmlDebugDumpOneNode(stderr, parent, 0);
-+#endif
-+ xmlAddSibling(parent, ret);
-+ }
-+ }
-+
-+ /*
-+ * process all the attributes whose name start with "xml"
-+ */
-+ if (atts != NULL) {
-+ i = 0;
-+ att = atts[i++];
-+ value = atts[i++];
-+ if (!ctxt->html) {
-+ while ((att != NULL) && (value != NULL)) {
-+ if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
-+ attribute(ctxt, att, value);
-+
-+ att = atts[i++];
-+ value = atts[i++];
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Search the namespace, note that since the attributes have been
-+ * processed, the local namespaces are available.
-+ */
-+ ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
-+ if ((ns == NULL) && (parent != NULL))
-+ ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
-+ if ((prefix != NULL) && (ns == NULL)) {
-+ ns = xmlNewNs(ret, NULL, prefix);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Namespace prefix %s is not defined\n", prefix);
-+ }
-+ xmlSetNs(ret, ns);
-+
-+ /*
-+ * process all the other attributes
-+ */
-+ if (atts != NULL) {
-+ i = 0;
-+ att = atts[i++];
-+ value = atts[i++];
-+ if (ctxt->html) {
-+ while (att != NULL) {
-+ attribute(ctxt, att, value);
-+ att = atts[i++];
-+ value = atts[i++];
-+ }
-+ } else {
-+ while ((att != NULL) && (value != NULL)) {
-+ if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
-+ attribute(ctxt, att, value);
-+
-+ /*
-+ * Next ones
-+ */
-+ att = atts[i++];
-+ value = atts[i++];
-+ }
-+ }
-+ }
-+
-+ /*
-+ * If it's the Document root, finish the Dtd validation and
-+ * check the document root element for validity
-+ */
-+ if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
-+ ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
-+ ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-+ ctxt->vctxt.finishDtd = 1;
-+ }
-+
-+ if (prefix != NULL)
-+ xmlFree(prefix);
-+ if (name != NULL)
-+ xmlFree(name);
-+
-+}
-+
-+/**
-+ * endElement:
-+ * @ctx: the user data (XML parser context)
-+ * @name: The element name
-+ *
-+ * called when the end of an element has been detected.
-+ */
-+void
-+endElement(void *ctx, const xmlChar *name)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlParserNodeInfo node_info;
-+ xmlNodePtr cur = ctxt->node;
-+
-+#ifdef DEBUG_SAX
-+ if (name == NULL)
-+ xmlGenericError(xmlGenericErrorContext, "SAX.endElement(NULL)\n");
-+ else
-+ xmlGenericError(xmlGenericErrorContext, "SAX.endElement(%s)\n", name);
-+#endif
-+
-+ /* Capture end position and add node */
-+ if (cur != NULL && ctxt->record_info) {
-+ node_info.end_pos = ctxt->input->cur - ctxt->input->base;
-+ node_info.end_line = ctxt->input->line;
-+ node_info.node = cur;
-+ xmlParserAddNodeInfo(ctxt, &node_info);
-+ }
-+ ctxt->nodemem = -1;
-+
-+ if (ctxt->validate && ctxt->wellFormed &&
-+ ctxt->myDoc && ctxt->myDoc->intSubset)
-+ ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
-+ cur);
-+
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
-+#endif
-+ nodePop(ctxt);
-+}
-+
-+/**
-+ * reference:
-+ * @ctx: the user data (XML parser context)
-+ * @name: The entity name
-+ *
-+ * called when an entity reference is detected.
-+ */
-+void
-+reference(void *ctx, const xmlChar *name)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr ret;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.reference(%s)\n", name);
-+#endif
-+ if (name[0] == '#')
-+ ret = xmlNewCharRef(ctxt->myDoc, name);
-+ else
-+ ret = xmlNewReference(ctxt->myDoc, name);
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "add reference %s to %s \n", name, ctxt->node->name);
-+#endif
-+ xmlAddChild(ctxt->node, ret);
-+}
-+
-+/**
-+ * characters:
-+ * @ctx: the user data (XML parser context)
-+ * @ch: a xmlChar string
-+ * @len: the number of xmlChar
-+ *
-+ * receiving some chars from the parser.
-+ * Question: how much at a time ???
-+ */
-+void
-+characters(void *ctx, const xmlChar *ch, int len)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr lastChild;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.characters(%.30s, %d)\n", ch, len);
-+#endif
-+ /*
-+ * Handle the data if any. If there is no child
-+ * add it as content, otherwise if the last child is text,
-+ * concatenate it, else create a new node of type text.
-+ */
-+
-+ if (ctxt->node == NULL) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "add chars: ctxt->node == NULL !\n");
-+#endif
-+ return;
-+ }
-+ lastChild = xmlGetLastChild(ctxt->node);
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "add chars to %s \n", ctxt->node->name);
-+#endif
-+
-+ /*
-+ * Here we needed an accelerator mechanism in case of very large
-+ * elements. Use an attribute in the structure !!!
-+ */
-+ if (lastChild == NULL) {
-+ /* first node, first time */
-+ xmlNodeAddContentLen(ctxt->node, ch, len);
-+#ifndef XML_USE_BUFFER_CONTENT
-+ if (ctxt->node->children != NULL) {
-+ ctxt->nodelen = len;
-+ ctxt->nodemem = len + 1;
-+ }
-+#endif
-+ } else {
-+ if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ /*
-+ * The whole point of maintaining nodelen and nodemem,
-+ * xmlTextConcat is too costly, i.e. compute lenght,
-+ * reallocate a new buffer, move data, append ch. Here
-+ * We try to minimaze realloc() uses and avoid copying
-+ * and recomputing lenght over and over.
-+ */
-+ if (ctxt->nodelen + len >= ctxt->nodemem) {
-+ xmlChar *newbuf;
-+ int size;
-+
-+ size = ctxt->nodemem + len;
-+ size *= 2;
-+ newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
-+ if (newbuf == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "SAX.characters(): out of memory\n");
-+ return;
-+ }
-+ ctxt->nodemem = size;
-+ lastChild->content = newbuf;
-+ }
-+ memcpy(&lastChild->content[ctxt->nodelen], ch, len);
-+ ctxt->nodelen += len;
-+ lastChild->content[ctxt->nodelen] = 0;
-+#else
-+ xmlTextConcat(lastChild, ch, len);
-+#endif
-+ } else {
-+ /* Mixed content, first time */
-+ lastChild = xmlNewTextLen(ch, len);
-+ xmlAddChild(ctxt->node, lastChild);
-+#ifndef XML_USE_BUFFER_CONTENT
-+ if (ctxt->node->children != NULL) {
-+ ctxt->nodelen = len;
-+ ctxt->nodemem = len + 1;
-+ }
-+#endif
-+ }
-+ }
-+}
-+
-+/**
-+ * ignorableWhitespace:
-+ * @ctx: the user data (XML parser context)
-+ * @ch: a xmlChar string
-+ * @len: the number of xmlChar
-+ *
-+ * receiving some ignorable whitespaces from the parser.
-+ * Question: how much at a time ???
-+ */
-+void
-+ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
-+{
-+ /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
-+#endif
-+}
-+
-+/**
-+ * processingInstruction:
-+ * @ctx: the user data (XML parser context)
-+ * @target: the target name
-+ * @data: the PI data's
-+ *
-+ * A processing instruction has been parsed.
-+ */
-+void
-+processingInstruction(void *ctx, const xmlChar *target,
-+ const xmlChar *data)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr ret;
-+ xmlNodePtr parent = ctxt->node;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.processingInstruction(%s, %s)\n", target, data);
-+#endif
-+
-+ ret = xmlNewPI(target, data);
-+ if (ret == NULL) return;
-+ parent = ctxt->node;
-+
-+ if (ctxt->inSubset == 1) {
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
-+ return;
-+ } else if (ctxt->inSubset == 2) {
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
-+ return;
-+ }
-+ if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Setting PI %s as root\n", target);
-+#endif
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-+ return;
-+ }
-+ if (parent->type == XML_ELEMENT_NODE) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "adding PI %s child to %s\n", target, parent->name);
-+#endif
-+ xmlAddChild(parent, ret);
-+ } else {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "adding PI %s sibling to ", target);
-+ xmlDebugDumpOneNode(stderr, parent, 0);
-+#endif
-+ xmlAddSibling(parent, ret);
-+ }
-+}
-+
-+/**
-+ * globalNamespace:
-+ * @ctx: the user data (XML parser context)
-+ * @href: the namespace associated URN
-+ * @prefix: the namespace prefix
-+ *
-+ * An old global namespace has been parsed.
-+ */
-+void
-+globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.globalNamespace(%s, %s)\n", href, prefix);
-+#endif
-+ xmlNewGlobalNs(ctxt->myDoc, href, prefix);
-+}
-+
-+/**
-+ * setNamespace:
-+ * @ctx: the user data (XML parser context)
-+ * @name: the namespace prefix
-+ *
-+ * Set the current element namespace.
-+ */
-+
-+void
-+setNamespace(void *ctx, const xmlChar *name)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNsPtr ns;
-+ xmlNodePtr parent;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext, "SAX.setNamespace(%s)\n", name);
-+#endif
-+ ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
-+ if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
-+ if (ctxt->nodeNr >= 2) {
-+ parent = ctxt->nodeTab[ctxt->nodeNr - 2];
-+ if (parent != NULL)
-+ ns = xmlSearchNs(ctxt->myDoc, parent, name);
-+ }
-+ }
-+ xmlSetNs(ctxt->node, ns);
-+}
-+
-+/**
-+ * getNamespace:
-+ * @ctx: the user data (XML parser context)
-+ *
-+ * Get the current element namespace.
-+ *
-+ * Returns the xmlNsPtr or NULL if none
-+ */
-+
-+xmlNsPtr
-+getNamespace(void *ctx)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNsPtr ret;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext, "SAX.getNamespace()\n");
-+#endif
-+ ret = ctxt->node->ns;
-+ return(ret);
-+}
-+
-+/**
-+ * checkNamespace:
-+ * @ctx: the user data (XML parser context)
-+ * @namespace: the namespace to check against
-+ *
-+ * Check that the current element namespace is the same as the
-+ * one read upon parsing.
-+ *
-+ * Returns 1 if true 0 otherwise
-+ */
-+
-+int
-+checkNamespace(void *ctx, xmlChar *namespace)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr cur = ctxt->node;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.checkNamespace(%s)\n", namespace);
-+#endif
-+
-+ /*
-+ * Check that the Name in the ETag is the same as in the STag.
-+ */
-+ if (namespace == NULL) {
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "End tags for %s don't hold the namespace %s\n",
-+ cur->name, cur->ns->prefix);
-+ ctxt->wellFormed = 0;
-+ }
-+ } else {
-+ if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "End tags %s holds a prefix %s not used by the open tag\n",
-+ cur->name, namespace);
-+ ctxt->wellFormed = 0;
-+ } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt,
-+ "Start and End tags for %s don't use the same namespaces: %s and %s\n",
-+ cur->name, cur->ns->prefix, namespace);
-+ ctxt->wellFormed = 0;
-+ } else
-+ return(1);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * namespaceDecl:
-+ * @ctx: the user data (XML parser context)
-+ * @href: the namespace associated URN
-+ * @prefix: the namespace prefix
-+ *
-+ * A namespace has been parsed.
-+ */
-+void
-+namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+#ifdef DEBUG_SAX
-+ if (prefix == NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.namespaceDecl(%s, NULL)\n", href);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.namespaceDecl(%s, %s)\n", href, prefix);
-+#endif
-+ xmlNewNs(ctxt->node, href, prefix);
-+}
-+
-+/**
-+ * comment:
-+ * @ctx: the user data (XML parser context)
-+ * @value: the comment content
-+ *
-+ * A comment has been parsed.
-+ */
-+void
-+comment(void *ctx, const xmlChar *value)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr ret;
-+ xmlNodePtr parent = ctxt->node;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext, "SAX.comment(%s)\n", value);
-+#endif
-+ ret = xmlNewDocComment(ctxt->myDoc, value);
-+ if (ret == NULL) return;
-+
-+ if (ctxt->inSubset == 1) {
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
-+ return;
-+ } else if (ctxt->inSubset == 2) {
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
-+ return;
-+ }
-+ if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Setting comment as root\n");
-+#endif
-+ xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-+ return;
-+ }
-+ if (parent->type == XML_ELEMENT_NODE) {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "adding comment child to %s\n", parent->name);
-+#endif
-+ xmlAddChild(parent, ret);
-+ } else {
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "adding comment sibling to ");
-+ xmlDebugDumpOneNode(stderr, parent, 0);
-+#endif
-+ xmlAddSibling(parent, ret);
-+ }
-+}
-+
-+/**
-+ * cdataBlock:
-+ * @ctx: the user data (XML parser context)
-+ * @value: The pcdata content
-+ * @len: the block length
-+ *
-+ * called when a pcdata block has been parsed
-+ */
-+void
-+cdataBlock(void *ctx, const xmlChar *value, int len)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlNodePtr ret, lastChild;
-+
-+#ifdef DEBUG_SAX
-+ xmlGenericError(xmlGenericErrorContext,
-+ "SAX.pcdata(%.10s, %d)\n", value, len);
-+#endif
-+ lastChild = xmlGetLastChild(ctxt->node);
-+#ifdef DEBUG_SAX_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "add chars to %s \n", ctxt->node->name);
-+#endif
-+ if ((lastChild != NULL) &&
-+ (lastChild->type == XML_CDATA_SECTION_NODE)) {
-+ xmlTextConcat(lastChild, value, len);
-+ } else {
-+ ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
-+ xmlAddChild(ctxt->node, ret);
-+ }
-+}
-+
-+/*
-+ * Default handler for XML, builds the DOM tree
-+ */
-+xmlSAXHandler xmlDefaultSAXHandler = {
-+ internalSubset,
-+ isStandalone,
-+ hasInternalSubset,
-+ hasExternalSubset,
-+ resolveEntity,
-+ getEntity,
-+ entityDecl,
-+ notationDecl,
-+ attributeDecl,
-+ elementDecl,
-+ unparsedEntityDecl,
-+ setDocumentLocator,
-+ startDocument,
-+ endDocument,
-+ startElement,
-+ endElement,
-+ reference,
-+ characters,
-+ ignorableWhitespace,
-+ processingInstruction,
-+ comment,
-+ xmlParserWarning,
-+ xmlParserError,
-+ xmlParserError,
-+ getParameterEntity,
-+ cdataBlock,
-+ externalSubset,
-+};
-+
-+/**
-+ * xmlDefaultSAXHandlerInit:
-+ *
-+ * Initialize the default SAX handler
-+ */
-+void
-+xmlDefaultSAXHandlerInit(void)
-+{
-+ xmlDefaultSAXHandler.internalSubset = internalSubset;
-+ xmlDefaultSAXHandler.externalSubset = externalSubset;
-+ xmlDefaultSAXHandler.isStandalone = isStandalone;
-+ xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
-+ xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
-+ xmlDefaultSAXHandler.resolveEntity = resolveEntity;
-+ xmlDefaultSAXHandler.getEntity = getEntity;
-+ xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
-+ xmlDefaultSAXHandler.entityDecl = entityDecl;
-+ xmlDefaultSAXHandler.attributeDecl = attributeDecl;
-+ xmlDefaultSAXHandler.elementDecl = elementDecl;
-+ xmlDefaultSAXHandler.notationDecl = notationDecl;
-+ xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
-+ xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
-+ xmlDefaultSAXHandler.startDocument = startDocument;
-+ xmlDefaultSAXHandler.endDocument = endDocument;
-+ xmlDefaultSAXHandler.startElement = startElement;
-+ xmlDefaultSAXHandler.endElement = endElement;
-+ xmlDefaultSAXHandler.reference = reference;
-+ xmlDefaultSAXHandler.characters = characters;
-+ xmlDefaultSAXHandler.cdataBlock = cdataBlock;
-+ xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
-+ xmlDefaultSAXHandler.processingInstruction = processingInstruction;
-+ xmlDefaultSAXHandler.comment = comment;
-+ if (xmlGetWarningsDefaultValue == 0)
-+ xmlDefaultSAXHandler.warning = NULL;
-+ else
-+ xmlDefaultSAXHandler.warning = xmlParserWarning;
-+ xmlDefaultSAXHandler.error = xmlParserError;
-+ xmlDefaultSAXHandler.fatalError = xmlParserError;
-+}
-+
-+/*
-+ * Default handler for HTML, builds the DOM tree
-+ */
-+xmlSAXHandler htmlDefaultSAXHandler = {
-+ internalSubset,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ getEntity,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ setDocumentLocator,
-+ startDocument,
-+ endDocument,
-+ startElement,
-+ endElement,
-+ NULL,
-+ characters,
-+ ignorableWhitespace,
-+ NULL,
-+ comment,
-+ xmlParserWarning,
-+ xmlParserError,
-+ xmlParserError,
-+ getParameterEntity,
-+ cdataBlock,
-+ NULL,
-+};
-+
-+/**
-+ * htmlDefaultSAXHandlerInit:
-+ *
-+ * Initialize the default SAX handler
-+ */
-+void
-+htmlDefaultSAXHandlerInit(void)
-+{
-+ htmlDefaultSAXHandler.internalSubset = internalSubset;
-+ htmlDefaultSAXHandler.externalSubset = NULL;
-+ htmlDefaultSAXHandler.isStandalone = NULL;
-+ htmlDefaultSAXHandler.hasInternalSubset = NULL;
-+ htmlDefaultSAXHandler.hasExternalSubset = NULL;
-+ htmlDefaultSAXHandler.resolveEntity = NULL;
-+ htmlDefaultSAXHandler.getEntity = getEntity;
-+ htmlDefaultSAXHandler.getParameterEntity = NULL;
-+ htmlDefaultSAXHandler.entityDecl = NULL;
-+ htmlDefaultSAXHandler.attributeDecl = NULL;
-+ htmlDefaultSAXHandler.elementDecl = NULL;
-+ htmlDefaultSAXHandler.notationDecl = NULL;
-+ htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
-+ htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
-+ htmlDefaultSAXHandler.startDocument = startDocument;
-+ htmlDefaultSAXHandler.endDocument = endDocument;
-+ htmlDefaultSAXHandler.startElement = startElement;
-+ htmlDefaultSAXHandler.endElement = endElement;
-+ htmlDefaultSAXHandler.reference = NULL;
-+ htmlDefaultSAXHandler.characters = characters;
-+ htmlDefaultSAXHandler.cdataBlock = cdataBlock;
-+ htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
-+ htmlDefaultSAXHandler.processingInstruction = NULL;
-+ htmlDefaultSAXHandler.comment = comment;
-+ htmlDefaultSAXHandler.warning = xmlParserWarning;
-+ htmlDefaultSAXHandler.error = xmlParserError;
-+ htmlDefaultSAXHandler.fatalError = xmlParserError;
-+}
-+
-+/*
-+ * Default handler for HTML, builds the DOM tree
-+ */
-+xmlSAXHandler sgmlDefaultSAXHandler = {
-+ internalSubset,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ getEntity,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ setDocumentLocator,
-+ startDocument,
-+ endDocument,
-+ startElement,
-+ endElement,
-+ NULL,
-+ characters,
-+ ignorableWhitespace,
-+ NULL,
-+ comment,
-+ xmlParserWarning,
-+ xmlParserError,
-+ xmlParserError,
-+ getParameterEntity,
-+ NULL,
-+ NULL,
-+};
-+
-+/**
-+ * sgmlDefaultSAXHandlerInit:
-+ *
-+ * Initialize the default SAX handler
-+ */
-+void
-+sgmlDefaultSAXHandlerInit(void)
-+{
-+ sgmlDefaultSAXHandler.internalSubset = internalSubset;
-+ sgmlDefaultSAXHandler.externalSubset = NULL;
-+ sgmlDefaultSAXHandler.isStandalone = NULL;
-+ sgmlDefaultSAXHandler.hasInternalSubset = NULL;
-+ sgmlDefaultSAXHandler.hasExternalSubset = NULL;
-+ sgmlDefaultSAXHandler.resolveEntity = NULL;
-+ sgmlDefaultSAXHandler.getEntity = getEntity;
-+ sgmlDefaultSAXHandler.getParameterEntity = NULL;
-+ sgmlDefaultSAXHandler.entityDecl = NULL;
-+ sgmlDefaultSAXHandler.attributeDecl = NULL;
-+ sgmlDefaultSAXHandler.elementDecl = NULL;
-+ sgmlDefaultSAXHandler.notationDecl = NULL;
-+ sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
-+ sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
-+ sgmlDefaultSAXHandler.startDocument = startDocument;
-+ sgmlDefaultSAXHandler.endDocument = endDocument;
-+ sgmlDefaultSAXHandler.startElement = startElement;
-+ sgmlDefaultSAXHandler.endElement = endElement;
-+ sgmlDefaultSAXHandler.reference = NULL;
-+ sgmlDefaultSAXHandler.characters = characters;
-+ sgmlDefaultSAXHandler.cdataBlock = NULL;
-+ sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
-+ sgmlDefaultSAXHandler.processingInstruction = NULL;
-+ sgmlDefaultSAXHandler.comment = comment;
-+ sgmlDefaultSAXHandler.warning = xmlParserWarning;
-+ sgmlDefaultSAXHandler.error = xmlParserError;
-+ sgmlDefaultSAXHandler.fatalError = xmlParserError;
-+}
-diff -Nru libxml2-2.3.0/libxml/SAX.h libxml2-2.3.0.new/libxml/SAX.h
---- libxml2-2.3.0/libxml/SAX.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/SAX.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,120 @@
-+/*
-+ * SAX.h : Default SAX handler interfaces.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel Veillard <Daniel.Veillard@w3.org>
-+ */
-+
-+
-+#ifndef __XML_SAX_H__
-+#define __XML_SAX_H__
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <libxml/parser.h>
-+#include <libxml/xlink.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+const xmlChar * getPublicId (void *ctx);
-+const xmlChar * getSystemId (void *ctx);
-+void setDocumentLocator (void *ctx,
-+ xmlSAXLocatorPtr loc);
-+
-+int getLineNumber (void *ctx);
-+int getColumnNumber (void *ctx);
-+
-+int isStandalone (void *ctx);
-+int hasInternalSubset (void *ctx);
-+int hasExternalSubset (void *ctx);
-+
-+void internalSubset (void *ctx,
-+ const xmlChar *name,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+void externalSubset (void *ctx,
-+ const xmlChar *name,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+xmlEntityPtr getEntity (void *ctx,
-+ const xmlChar *name);
-+xmlEntityPtr getParameterEntity (void *ctx,
-+ const xmlChar *name);
-+xmlParserInputPtr resolveEntity (void *ctx,
-+ const xmlChar *publicId,
-+ const xmlChar *systemId);
-+
-+void entityDecl (void *ctx,
-+ const xmlChar *name,
-+ int type,
-+ const xmlChar *publicId,
-+ const xmlChar *systemId,
-+ xmlChar *content);
-+void attributeDecl (void *ctx,
-+ const xmlChar *elem,
-+ const xmlChar *name,
-+ int type,
-+ int def,
-+ const xmlChar *defaultValue,
-+ xmlEnumerationPtr tree);
-+void elementDecl (void *ctx,
-+ const xmlChar *name,
-+ int type,
-+ xmlElementContentPtr content);
-+void notationDecl (void *ctx,
-+ const xmlChar *name,
-+ const xmlChar *publicId,
-+ const xmlChar *systemId);
-+void unparsedEntityDecl (void *ctx,
-+ const xmlChar *name,
-+ const xmlChar *publicId,
-+ const xmlChar *systemId,
-+ const xmlChar *notationName);
-+
-+void startDocument (void *ctx);
-+void endDocument (void *ctx);
-+void attribute (void *ctx,
-+ const xmlChar *fullname,
-+ const xmlChar *value);
-+void startElement (void *ctx,
-+ const xmlChar *fullname,
-+ const xmlChar **atts);
-+void endElement (void *ctx,
-+ const xmlChar *name);
-+void reference (void *ctx,
-+ const xmlChar *name);
-+void characters (void *ctx,
-+ const xmlChar *ch,
-+ int len);
-+void ignorableWhitespace (void *ctx,
-+ const xmlChar *ch,
-+ int len);
-+void processingInstruction (void *ctx,
-+ const xmlChar *target,
-+ const xmlChar *data);
-+void globalNamespace (void *ctx,
-+ const xmlChar *href,
-+ const xmlChar *prefix);
-+void setNamespace (void *ctx,
-+ const xmlChar *name);
-+xmlNsPtr getNamespace (void *ctx);
-+int checkNamespace (void *ctx,
-+ xmlChar *nameSpace);
-+void namespaceDecl (void *ctx,
-+ const xmlChar *href,
-+ const xmlChar *prefix);
-+void comment (void *ctx,
-+ const xmlChar *value);
-+void cdataBlock (void *ctx,
-+ const xmlChar *value,
-+ int len);
-+
-+void xmlDefaultSAXHandlerInit (void);
-+void htmlDefaultSAXHandlerInit (void);
-+void sgmlDefaultSAXHandlerInit (void);
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_SAX_H__ */
-diff -Nru libxml2-2.3.0/libxml/debugXML.c libxml2-2.3.0.new/libxml/debugXML.c
---- libxml2-2.3.0/libxml/debugXML.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/debugXML.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,1888 @@
-+/*
-+ * debugXML.c : This is a set of routines used for debugging the tree
-+ * produced by the XML parser.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel Veillard <Daniel.Veillard@w3.org>
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_DEBUG_ENABLED
-+
-+#include <stdio.h>
-+#include <string.h>
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_STRING_H
-+#include <string.h>
-+#endif
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/valid.h>
-+#include <libxml/debugXML.h>
-+#include <libxml/HTMLtree.h>
-+#include <libxml/HTMLparser.h>
-+#include <libxml/xmlerror.h>
-+
-+#define IS_BLANK(c) \
-+ (((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
-+
-+void xmlDebugDumpString(FILE *output, const xmlChar *str) {
-+ int i;
-+ if (str == NULL) {
-+ fprintf(output, "(NULL)");
-+ return;
-+ }
-+ for (i = 0;i < 40;i++)
-+ if (str[i] == 0) return;
-+ else if (IS_BLANK(str[i])) fputc(' ', output);
-+ else if (str[i] >= 0x80)
-+ fprintf(output, "#%X", str[i]);
-+ else fputc(str[i], output);
-+ fprintf(output, "...");
-+}
-+
-+void xmlDebugDumpDtd(FILE *output, xmlDtdPtr dtd, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+
-+ if (dtd->type != XML_DTD_NODE) {
-+ fprintf(output, "PBM: not a DTD\n");
-+ return;
-+ }
-+ if (dtd->name != NULL)
-+ fprintf(output, "DTD(%s)", dtd->name);
-+ else
-+ fprintf(output, "DTD");
-+ if (dtd->ExternalID != NULL)
-+ fprintf(output, ", PUBLIC %s", dtd->ExternalID);
-+ if (dtd->SystemID != NULL)
-+ fprintf(output, ", SYSTEM %s", dtd->SystemID);
-+ fprintf(output, "\n");
-+ /*
-+ * Do a bit of checking
-+ */
-+ if (dtd->parent == NULL)
-+ fprintf(output, "PBM: Dtd has no parent\n");
-+ if (dtd->doc == NULL)
-+ fprintf(output, "PBM: Dtd has no doc\n");
-+ if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
-+ fprintf(output, "PBM: Dtd doc differs from parent's one\n");
-+ if (dtd->prev == NULL) {
-+ if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
-+ fprintf(output, "PBM: Dtd has no prev and not first of list\n");
-+ } else {
-+ if (dtd->prev->next != (xmlNodePtr) dtd)
-+ fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
-+ }
-+ if (dtd->next == NULL) {
-+ if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
-+ fprintf(output, "PBM: Dtd has no next and not last of list\n");
-+ } else {
-+ if (dtd->next->prev != (xmlNodePtr) dtd)
-+ fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
-+ }
-+}
-+
-+void xmlDebugDumpAttrDecl(FILE *output, xmlAttributePtr attr, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+
-+ if (attr->type != XML_ATTRIBUTE_DECL) {
-+ fprintf(output, "PBM: not a Attr\n");
-+ return;
-+ }
-+ if (attr->name != NULL)
-+ fprintf(output, "ATTRDECL(%s)", attr->name);
-+ else
-+ fprintf(output, "PBM ATTRDECL noname!!!");
-+ if (attr->elem != NULL)
-+ fprintf(output, " for %s", attr->elem);
-+ else
-+ fprintf(output, " PBM noelem!!!");
-+ switch (attr->atype) {
-+ case XML_ATTRIBUTE_CDATA:
-+ fprintf(output, " CDATA");
-+ break;
-+ case XML_ATTRIBUTE_ID:
-+ fprintf(output, " ID");
-+ break;
-+ case XML_ATTRIBUTE_IDREF:
-+ fprintf(output, " IDREF");
-+ break;
-+ case XML_ATTRIBUTE_IDREFS:
-+ fprintf(output, " IDREFS");
-+ break;
-+ case XML_ATTRIBUTE_ENTITY:
-+ fprintf(output, " ENTITY");
-+ break;
-+ case XML_ATTRIBUTE_ENTITIES:
-+ fprintf(output, " ENTITIES");
-+ break;
-+ case XML_ATTRIBUTE_NMTOKEN:
-+ fprintf(output, " NMTOKEN");
-+ break;
-+ case XML_ATTRIBUTE_NMTOKENS:
-+ fprintf(output, " NMTOKENS");
-+ break;
-+ case XML_ATTRIBUTE_ENUMERATION:
-+ fprintf(output, " ENUMERATION");
-+ break;
-+ case XML_ATTRIBUTE_NOTATION:
-+ fprintf(output, " NOTATION ");
-+ break;
-+ }
-+ if (attr->tree != NULL) {
-+ int i;
-+ xmlEnumerationPtr cur = attr->tree;
-+
-+ for (i = 0;i < 5; i++) {
-+ if (i != 0)
-+ fprintf(output, "|%s", cur->name);
-+ else
-+ fprintf(output, " (%s", cur->name);
-+ cur = cur->next;
-+ if (cur == NULL) break;
-+ }
-+ if (cur == NULL)
-+ fprintf(output, ")");
-+ else
-+ fprintf(output, "...)");
-+ }
-+ switch (attr->def) {
-+ case XML_ATTRIBUTE_NONE:
-+ break;
-+ case XML_ATTRIBUTE_REQUIRED:
-+ fprintf(output, " REQUIRED");
-+ break;
-+ case XML_ATTRIBUTE_IMPLIED:
-+ fprintf(output, " IMPLIED");
-+ break;
-+ case XML_ATTRIBUTE_FIXED:
-+ fprintf(output, " FIXED");
-+ break;
-+ }
-+ if (attr->defaultValue != NULL) {
-+ fprintf(output, "\"");
-+ xmlDebugDumpString(output, attr->defaultValue);
-+ fprintf(output, "\"");
-+ }
-+ printf("\n");
-+
-+ /*
-+ * Do a bit of checking
-+ */
-+ if (attr->parent == NULL)
-+ fprintf(output, "PBM: Attr has no parent\n");
-+ if (attr->doc == NULL)
-+ fprintf(output, "PBM: Attr has no doc\n");
-+ if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
-+ fprintf(output, "PBM: Attr doc differs from parent's one\n");
-+ if (attr->prev == NULL) {
-+ if ((attr->parent != NULL) && (attr->parent->children != (xmlNodePtr)attr))
-+ fprintf(output, "PBM: Attr has no prev and not first of list\n");
-+ } else {
-+ if (attr->prev->next != (xmlNodePtr) attr)
-+ fprintf(output, "PBM: Attr prev->next : back link wrong\n");
-+ }
-+ if (attr->next == NULL) {
-+ if ((attr->parent != NULL) && (attr->parent->last != (xmlNodePtr) attr))
-+ fprintf(output, "PBM: Attr has no next and not last of list\n");
-+ } else {
-+ if (attr->next->prev != (xmlNodePtr) attr)
-+ fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
-+ }
-+}
-+
-+void xmlDebugDumpElemDecl(FILE *output, xmlElementPtr elem, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+
-+ if (elem->type != XML_ELEMENT_DECL) {
-+ fprintf(output, "PBM: not a Elem\n");
-+ return;
-+ }
-+ if (elem->name != NULL) {
-+ fprintf(output, "ELEMDECL(");
-+ xmlDebugDumpString(output, elem->name);
-+ fprintf(output, ")");
-+ } else
-+ fprintf(output, "PBM ELEMDECL noname!!!");
-+ switch (elem->etype) {
-+ case XML_ELEMENT_TYPE_EMPTY:
-+ fprintf(output, ", EMPTY");
-+ break;
-+ case XML_ELEMENT_TYPE_ANY:
-+ fprintf(output, ", ANY");
-+ break;
-+ case XML_ELEMENT_TYPE_MIXED:
-+ fprintf(output, ", MIXED ");
-+ break;
-+ case XML_ELEMENT_TYPE_ELEMENT:
-+ fprintf(output, ", MIXED ");
-+ break;
-+ }
-+ if (elem->content != NULL) {
-+ char buf[5001];
-+
-+ buf[0] = 0;
-+ xmlSprintfElementContent(buf, elem->content, 1);
-+ buf[5000] = 0;
-+ fprintf(output, "%s", buf);
-+ }
-+ printf("\n");
-+
-+ /*
-+ * Do a bit of checking
-+ */
-+ if (elem->parent == NULL)
-+ fprintf(output, "PBM: Elem has no parent\n");
-+ if (elem->doc == NULL)
-+ fprintf(output, "PBM: Elem has no doc\n");
-+ if ((elem->parent != NULL) && (elem->doc != elem->parent->doc))
-+ fprintf(output, "PBM: Elem doc differs from parent's one\n");
-+ if (elem->prev == NULL) {
-+ if ((elem->parent != NULL) && (elem->parent->children != (xmlNodePtr)elem))
-+ fprintf(output, "PBM: Elem has no prev and not first of list\n");
-+ } else {
-+ if (elem->prev->next != (xmlNodePtr) elem)
-+ fprintf(output, "PBM: Elem prev->next : back link wrong\n");
-+ }
-+ if (elem->next == NULL) {
-+ if ((elem->parent != NULL) && (elem->parent->last != (xmlNodePtr) elem))
-+ fprintf(output, "PBM: Elem has no next and not last of list\n");
-+ } else {
-+ if (elem->next->prev != (xmlNodePtr) elem)
-+ fprintf(output, "PBM: Elem next->prev : forward link wrong\n");
-+ }
-+}
-+
-+void xmlDebugDumpEntityDecl(FILE *output, xmlEntityPtr ent, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+
-+ if (ent->type != XML_ENTITY_DECL) {
-+ fprintf(output, "PBM: not a Entity decl\n");
-+ return;
-+ }
-+ if (ent->name != NULL) {
-+ fprintf(output, "ENTITYDECL(");
-+ xmlDebugDumpString(output, ent->name);
-+ fprintf(output, ")");
-+ } else
-+ fprintf(output, "PBM ENTITYDECL noname!!!");
-+ switch (ent->etype) {
-+ case XML_INTERNAL_GENERAL_ENTITY:
-+ fprintf(output, ", internal\n");
-+ break;
-+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-+ fprintf(output, ", external parsed\n");
-+ break;
-+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-+ fprintf(output, ", unparsed\n");
-+ break;
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ fprintf(output, ", parameter\n");
-+ break;
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ fprintf(output, ", external parameter\n");
-+ break;
-+ case XML_INTERNAL_PREDEFINED_ENTITY:
-+ fprintf(output, ", predefined\n");
-+ break;
-+ }
-+ if (ent->ExternalID) {
-+ fprintf(output, shift);
-+ fprintf(output, " ExternalID=%s\n", ent->ExternalID);
-+ }
-+ if (ent->SystemID) {
-+ fprintf(output, shift);
-+ fprintf(output, " SystemID=%s\n", ent->SystemID);
-+ }
-+ if (ent->URI != NULL) {
-+ fprintf(output, shift);
-+ fprintf(output, " URI=%s\n", ent->URI);
-+ }
-+ if (ent->content) {
-+ fprintf(output, shift);
-+ fprintf(output, " content=");
-+ xmlDebugDumpString(output, ent->content);
-+ fprintf(output, "\n");
-+ }
-+
-+ /*
-+ * Do a bit of checking
-+ */
-+ if (ent->parent == NULL)
-+ fprintf(output, "PBM: Ent has no parent\n");
-+ if (ent->doc == NULL)
-+ fprintf(output, "PBM: Ent has no doc\n");
-+ if ((ent->parent != NULL) && (ent->doc != ent->parent->doc))
-+ fprintf(output, "PBM: Ent doc differs from parent's one\n");
-+ if (ent->prev == NULL) {
-+ if ((ent->parent != NULL) && (ent->parent->children != (xmlNodePtr)ent))
-+ fprintf(output, "PBM: Ent has no prev and not first of list\n");
-+ } else {
-+ if (ent->prev->next != (xmlNodePtr) ent)
-+ fprintf(output, "PBM: Ent prev->next : back link wrong\n");
-+ }
-+ if (ent->next == NULL) {
-+ if ((ent->parent != NULL) && (ent->parent->last != (xmlNodePtr) ent))
-+ fprintf(output, "PBM: Ent has no next and not last of list\n");
-+ } else {
-+ if (ent->next->prev != (xmlNodePtr) ent)
-+ fprintf(output, "PBM: Ent next->prev : forward link wrong\n");
-+ }
-+}
-+
-+void xmlDebugDumpNamespace(FILE *output, xmlNsPtr ns, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+ if (ns->type != XML_NAMESPACE_DECL) {
-+ fprintf(output, "invalid namespace node %d\n", ns->type);
-+ return;
-+ }
-+ if (ns->href == NULL) {
-+ if (ns->prefix != NULL)
-+ fprintf(output, "incomplete namespace %s href=NULL\n", ns->prefix);
-+ else
-+ fprintf(output, "incomplete default namespace href=NULL\n");
-+ } else {
-+ if (ns->prefix != NULL)
-+ fprintf(output, "namespace %s href=", ns->prefix);
-+ else
-+ fprintf(output, "default namespace href=");
-+
-+ xmlDebugDumpString(output, ns->href);
-+ fprintf(output, "\n");
-+ }
-+}
-+
-+void xmlDebugDumpNamespaceList(FILE *output, xmlNsPtr ns, int depth) {
-+ while (ns != NULL) {
-+ xmlDebugDumpNamespace(output, ns, depth);
-+ ns = ns->next;
-+ }
-+}
-+
-+void xmlDebugDumpEntity(FILE *output, xmlEntityPtr ent, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+ switch (ent->etype) {
-+ case XML_INTERNAL_GENERAL_ENTITY:
-+ fprintf(output, "INTERNAL_GENERAL_ENTITY ");
-+ break;
-+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-+ fprintf(output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
-+ break;
-+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-+ fprintf(output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
-+ break;
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ fprintf(output, "INTERNAL_PARAMETER_ENTITY ");
-+ break;
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ fprintf(output, "EXTERNAL_PARAMETER_ENTITY ");
-+ break;
-+ default:
-+ fprintf(output, "ENTITY_%d ! ", ent->etype);
-+ }
-+ fprintf(output, "%s\n", ent->name);
-+ if (ent->ExternalID) {
-+ fprintf(output, shift);
-+ fprintf(output, "ExternalID=%s\n", ent->ExternalID);
-+ }
-+ if (ent->SystemID) {
-+ fprintf(output, shift);
-+ fprintf(output, "SystemID=%s\n", ent->SystemID);
-+ }
-+ if (ent->URI) {
-+ fprintf(output, shift);
-+ fprintf(output, "URI=%s\n", ent->URI);
-+ }
-+ if (ent->content) {
-+ fprintf(output, shift);
-+ fprintf(output, "content=");
-+ xmlDebugDumpString(output, ent->content);
-+ fprintf(output, "\n");
-+ }
-+}
-+
-+void xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+
-+ fprintf(output, "ATTRIBUTE ");
-+ xmlDebugDumpString(output, attr->name);
-+ fprintf(output, "\n");
-+ if (attr->children != NULL)
-+ xmlDebugDumpNodeList(output, attr->children, depth + 1);
-+
-+ /*
-+ * Do a bit of checking
-+ */
-+ if (attr->parent == NULL)
-+ fprintf(output, "PBM: Attr has no parent\n");
-+ if (attr->doc == NULL)
-+ fprintf(output, "PBM: Attr has no doc\n");
-+ if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
-+ fprintf(output, "PBM: Attr doc differs from parent's one\n");
-+ if (attr->prev == NULL) {
-+ if ((attr->parent != NULL) && (attr->parent->properties != attr))
-+ fprintf(output, "PBM: Attr has no prev and not first of list\n");
-+ } else {
-+ if (attr->prev->next != attr)
-+ fprintf(output, "PBM: Attr prev->next : back link wrong\n");
-+ }
-+ if (attr->next != NULL) {
-+ if (attr->next->prev != attr)
-+ fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
-+ }
-+}
-+
-+void xmlDebugDumpAttrList(FILE *output, xmlAttrPtr attr, int depth) {
-+ while (attr != NULL) {
-+ xmlDebugDumpAttr(output, attr, depth);
-+ attr = attr->next;
-+ }
-+}
-+
-+void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ switch (node->type) {
-+ case XML_ELEMENT_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "ELEMENT ");
-+ if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
-+ xmlDebugDumpString(output, node->ns->prefix);
-+ fprintf(output, ":");
-+ }
-+ xmlDebugDumpString(output, node->name);
-+ fprintf(output, "\n");
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "Error, ATTRIBUTE found here\n");
-+ break;
-+ case XML_TEXT_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "TEXT\n");
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "CDATA_SECTION\n");
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "ENTITY_REF(%s)\n", node->name);
-+ break;
-+ case XML_ENTITY_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "ENTITY\n");
-+ break;
-+ case XML_PI_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "PI %s\n", node->name);
-+ break;
-+ case XML_COMMENT_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "COMMENT\n");
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "Error, DOCUMENT found here\n");
-+ break;
-+ case XML_DOCUMENT_TYPE_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "DOCUMENT_TYPE\n");
-+ break;
-+ case XML_DOCUMENT_FRAG_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "DOCUMENT_FRAG\n");
-+ break;
-+ case XML_NOTATION_NODE:
-+ fprintf(output, shift);
-+ fprintf(output, "NOTATION\n");
-+ break;
-+ case XML_DTD_NODE:
-+ xmlDebugDumpDtd(output, (xmlDtdPtr) node, depth);
-+ return;
-+ case XML_ELEMENT_DECL:
-+ xmlDebugDumpElemDecl(output, (xmlElementPtr) node, depth);
-+ return;
-+ case XML_ATTRIBUTE_DECL:
-+ xmlDebugDumpAttrDecl(output, (xmlAttributePtr) node, depth);
-+ return;
-+ case XML_ENTITY_DECL:
-+ xmlDebugDumpEntityDecl(output, (xmlEntityPtr) node, depth);
-+ return;
-+ case XML_NAMESPACE_DECL:
-+ xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
-+ return;
-+ case XML_XINCLUDE_START:
-+ fprintf(output, shift);
-+ fprintf(output, "INCLUDE START\n");
-+ return;
-+ case XML_XINCLUDE_END:
-+ fprintf(output, shift);
-+ fprintf(output, "INCLUDE END\n");
-+ return;
-+ default:
-+ fprintf(output, shift);
-+ fprintf(output, "NODE_%d !!!\n", node->type);
-+ return;
-+ }
-+ if (node->doc == NULL) {
-+ fprintf(output, shift);
-+ fprintf(output, "doc == NULL !!!\n");
-+ }
-+ if (node->nsDef != NULL)
-+ xmlDebugDumpNamespaceList(output, node->nsDef, depth + 1);
-+ if (node->properties != NULL)
-+ xmlDebugDumpAttrList(output, node->properties, depth + 1);
-+ if (node->type != XML_ENTITY_REF_NODE) {
-+ if (node->content != NULL) {
-+ shift[2 * i] = shift[2 * i + 1] = ' ' ;
-+ shift[2 * i + 2] = shift[2 * i + 3] = 0 ;
-+ fprintf(output, shift);
-+ fprintf(output, "content=");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlDebugDumpString(output, node->content);
-+#else
-+ xmlDebugDumpString(output, xmlBufferContent(node->content));
-+#endif
-+ fprintf(output, "\n");
-+ }
-+ } else {
-+ xmlEntityPtr ent;
-+ ent = xmlGetDocEntity(node->doc, node->name);
-+ if (ent != NULL)
-+ xmlDebugDumpEntity(output, ent, depth + 1);
-+ }
-+ /*
-+ * Do a bit of checking
-+ */
-+ if (node->parent == NULL)
-+ fprintf(output, "PBM: Node has no parent\n");
-+ if (node->doc == NULL)
-+ fprintf(output, "PBM: Node has no doc\n");
-+ if ((node->parent != NULL) && (node->doc != node->parent->doc))
-+ fprintf(output, "PBM: Node doc differs from parent's one\n");
-+ if (node->prev == NULL) {
-+ if ((node->parent != NULL) && (node->parent->children != node))
-+ fprintf(output, "PBM: Node has no prev and not first of list\n");
-+ } else {
-+ if (node->prev->next != node)
-+ fprintf(output, "PBM: Node prev->next : back link wrong\n");
-+ }
-+ if (node->next == NULL) {
-+ if ((node->parent != NULL) && (node->parent->last != node))
-+ fprintf(output, "PBM: Node has no next and not last of list\n");
-+ } else {
-+ if (node->next->prev != node)
-+ fprintf(output, "PBM: Node next->prev : forward link wrong\n");
-+ }
-+}
-+
-+void xmlDebugDumpNode(FILE *output, xmlNodePtr node, int depth) {
-+ xmlDebugDumpOneNode(output, node, depth);
-+ if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
-+ xmlDebugDumpNodeList(output, node->children, depth + 1);
-+}
-+
-+void xmlDebugDumpNodeList(FILE *output, xmlNodePtr node, int depth) {
-+ while (node != NULL) {
-+ xmlDebugDumpNode(output, node, depth);
-+ node = node->next;
-+ }
-+}
-+
-+
-+void xmlDebugDumpDocumentHead(FILE *output, xmlDocPtr doc) {
-+ if (output == NULL) output = stdout;
-+ if (doc == NULL) {
-+ fprintf(output, "DOCUMENT == NULL !\n");
-+ return;
-+ }
-+
-+ switch (doc->type) {
-+ case XML_ELEMENT_NODE:
-+ fprintf(output, "Error, ELEMENT found here ");
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ fprintf(output, "Error, ATTRIBUTE found here\n");
-+ break;
-+ case XML_TEXT_NODE:
-+ fprintf(output, "Error, TEXT\n");
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ fprintf(output, "Error, CDATA_SECTION\n");
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ fprintf(output, "Error, ENTITY_REF\n");
-+ break;
-+ case XML_ENTITY_NODE:
-+ fprintf(output, "Error, ENTITY\n");
-+ break;
-+ case XML_PI_NODE:
-+ fprintf(output, "Error, PI\n");
-+ break;
-+ case XML_COMMENT_NODE:
-+ fprintf(output, "Error, COMMENT\n");
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ fprintf(output, "DOCUMENT\n");
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+ fprintf(output, "HTML DOCUMENT\n");
-+ break;
-+ case XML_DOCUMENT_TYPE_NODE:
-+ fprintf(output, "Error, DOCUMENT_TYPE\n");
-+ break;
-+ case XML_DOCUMENT_FRAG_NODE:
-+ fprintf(output, "Error, DOCUMENT_FRAG\n");
-+ break;
-+ case XML_NOTATION_NODE:
-+ fprintf(output, "Error, NOTATION\n");
-+ break;
-+ default:
-+ fprintf(output, "NODE_%d\n", doc->type);
-+ }
-+ if (doc->name != NULL) {
-+ fprintf(output, "name=");
-+ xmlDebugDumpString(output, BAD_CAST doc->name);
-+ fprintf(output, "\n");
-+ }
-+ if (doc->version != NULL) {
-+ fprintf(output, "version=");
-+ xmlDebugDumpString(output, doc->version);
-+ fprintf(output, "\n");
-+ }
-+ if (doc->encoding != NULL) {
-+ fprintf(output, "encoding=");
-+ xmlDebugDumpString(output, doc->encoding);
-+ fprintf(output, "\n");
-+ }
-+ if (doc->URL != NULL) {
-+ fprintf(output, "URL=");
-+ xmlDebugDumpString(output, doc->URL);
-+ fprintf(output, "\n");
-+ }
-+ if (doc->standalone)
-+ fprintf(output, "standalone=true\n");
-+ if (doc->oldNs != NULL)
-+ xmlDebugDumpNamespaceList(output, doc->oldNs, 0);
-+}
-+
-+void xmlDebugDumpDocument(FILE *output, xmlDocPtr doc) {
-+ if (output == NULL) output = stdout;
-+ if (doc == NULL) {
-+ fprintf(output, "DOCUMENT == NULL !\n");
-+ return;
-+ }
-+ xmlDebugDumpDocumentHead(output, doc);
-+ if (((doc->type == XML_DOCUMENT_NODE) ||
-+ (doc->type == XML_HTML_DOCUMENT_NODE)) &&
-+ (doc->children != NULL))
-+ xmlDebugDumpNodeList(output, doc->children, 1);
-+}
-+
-+void xmlDebugDumpDTD(FILE *output, xmlDtdPtr dtd) {
-+ if (dtd == NULL)
-+ return;
-+ if (dtd->type != XML_DTD_NODE) {
-+ fprintf(output, "PBM: not a DTD\n");
-+ return;
-+ }
-+ if (dtd->name != NULL)
-+ fprintf(output, "DTD(%s)", dtd->name);
-+ else
-+ fprintf(output, "DTD");
-+ if (dtd->ExternalID != NULL)
-+ fprintf(output, ", PUBLIC %s", dtd->ExternalID);
-+ if (dtd->SystemID != NULL)
-+ fprintf(output, ", SYSTEM %s", dtd->SystemID);
-+ fprintf(output, "\n");
-+ /*
-+ * Do a bit of checking
-+ */
-+ if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
-+ fprintf(output, "PBM: Dtd doc differs from parent's one\n");
-+ if (dtd->prev == NULL) {
-+ if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
-+ fprintf(output, "PBM: Dtd has no prev and not first of list\n");
-+ } else {
-+ if (dtd->prev->next != (xmlNodePtr) dtd)
-+ fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
-+ }
-+ if (dtd->next == NULL) {
-+ if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
-+ fprintf(output, "PBM: Dtd has no next and not last of list\n");
-+ } else {
-+ if (dtd->next->prev != (xmlNodePtr) dtd)
-+ fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
-+ }
-+ if (dtd->children == NULL)
-+ fprintf(output, " DTD is empty\n");
-+ else
-+ xmlDebugDumpNodeList(output, dtd->children, 1);
-+}
-+
-+void xmlDebugDumpEntityCallback(xmlEntityPtr cur, FILE *output,
-+ const xmlChar *name) {
-+ fprintf(output, "%s : ", cur->name);
-+ switch (cur->etype) {
-+ case XML_INTERNAL_GENERAL_ENTITY:
-+ fprintf(output, "INTERNAL GENERAL, ");
-+ break;
-+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-+ fprintf(output, "EXTERNAL PARSED, ");
-+ break;
-+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-+ fprintf(output, "EXTERNAL UNPARSED, ");
-+ break;
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ fprintf(output, "INTERNAL PARAMETER, ");
-+ break;
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ fprintf(output, "EXTERNAL PARAMETER, ");
-+ break;
-+ default:
-+ fprintf(output, "UNKNOWN TYPE %d",
-+ cur->etype);
-+ }
-+ if (cur->ExternalID != NULL)
-+ fprintf(output, "ID \"%s\"", cur->ExternalID);
-+ if (cur->SystemID != NULL)
-+ fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
-+ if (cur->orig != NULL)
-+ fprintf(output, "\n orig \"%s\"", cur->orig);
-+ if (cur->content != NULL)
-+ fprintf(output, "\n content \"%s\"", cur->content);
-+ fprintf(output, "\n");
-+}
-+
-+void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
-+ if (output == NULL) output = stdout;
-+ if (doc == NULL) {
-+ fprintf(output, "DOCUMENT == NULL !\n");
-+ return;
-+ }
-+
-+ switch (doc->type) {
-+ case XML_ELEMENT_NODE:
-+ fprintf(output, "Error, ELEMENT found here ");
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ fprintf(output, "Error, ATTRIBUTE found here\n");
-+ break;
-+ case XML_TEXT_NODE:
-+ fprintf(output, "Error, TEXT\n");
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ fprintf(output, "Error, CDATA_SECTION\n");
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ fprintf(output, "Error, ENTITY_REF\n");
-+ break;
-+ case XML_ENTITY_NODE:
-+ fprintf(output, "Error, ENTITY\n");
-+ break;
-+ case XML_PI_NODE:
-+ fprintf(output, "Error, PI\n");
-+ break;
-+ case XML_COMMENT_NODE:
-+ fprintf(output, "Error, COMMENT\n");
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ fprintf(output, "DOCUMENT\n");
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+ fprintf(output, "HTML DOCUMENT\n");
-+ break;
-+ case XML_DOCUMENT_TYPE_NODE:
-+ fprintf(output, "Error, DOCUMENT_TYPE\n");
-+ break;
-+ case XML_DOCUMENT_FRAG_NODE:
-+ fprintf(output, "Error, DOCUMENT_FRAG\n");
-+ break;
-+ case XML_NOTATION_NODE:
-+ fprintf(output, "Error, NOTATION\n");
-+ break;
-+ default:
-+ fprintf(output, "NODE_%d\n", doc->type);
-+ }
-+ if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
-+ xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
-+ doc->intSubset->entities;
-+ fprintf(output, "Entities in internal subset\n");
-+ xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
-+ } else
-+ fprintf(output, "No entities in internal subset\n");
-+ if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-+ xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
-+ doc->extSubset->entities;
-+ fprintf(output, "Entities in external subset\n");
-+ xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
-+ } else
-+ fprintf(output, "No entities in external subset\n");
-+}
-+
-+static int xmlLsCountNode(xmlNodePtr node) {
-+ int ret = 0;
-+ xmlNodePtr list = NULL;
-+
-+ switch (node->type) {
-+ case XML_ELEMENT_NODE:
-+ list = node->children;
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ list = ((xmlDocPtr) node)->children;
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ list = ((xmlAttrPtr) node)->children;
-+ break;
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ if (node->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret = xmlStrlen(node->content);
-+#else
-+ ret = xmlBufferLength(node->content);
-+#endif
-+ }
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ ret = 1;
-+ break;
-+ }
-+ for (;list != NULL;ret++)
-+ list = list->next;
-+ return(ret);
-+}
-+
-+void xmlLsOneNode(FILE *output, xmlNodePtr node) {
-+ switch (node->type) {
-+ case XML_ELEMENT_NODE:
-+ fprintf(output, "-");
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ fprintf(output, "a");
-+ break;
-+ case XML_TEXT_NODE:
-+ fprintf(output, "t");
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ fprintf(output, "c");
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ fprintf(output, "e");
-+ break;
-+ case XML_ENTITY_NODE:
-+ fprintf(output, "E");
-+ break;
-+ case XML_PI_NODE:
-+ fprintf(output, "p");
-+ break;
-+ case XML_COMMENT_NODE:
-+ fprintf(output, "c");
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ fprintf(output, "d");
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+ fprintf(output, "h");
-+ break;
-+ case XML_DOCUMENT_TYPE_NODE:
-+ fprintf(output, "T");
-+ break;
-+ case XML_DOCUMENT_FRAG_NODE:
-+ fprintf(output, "F");
-+ break;
-+ case XML_NOTATION_NODE:
-+ fprintf(output, "N");
-+ break;
-+ default:
-+ fprintf(output, "?");
-+ }
-+ if (node->properties != NULL)
-+ fprintf(output, "a");
-+ else
-+ fprintf(output, "-");
-+ if (node->nsDef != NULL)
-+ fprintf(output, "n");
-+ else
-+ fprintf(output, "-");
-+
-+ fprintf(output, " %8d ", xmlLsCountNode(node));
-+
-+ switch (node->type) {
-+ case XML_ELEMENT_NODE:
-+ if (node->name != NULL)
-+ fprintf(output, "%s", node->name);
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ if (node->name != NULL)
-+ fprintf(output, "%s", node->name);
-+ break;
-+ case XML_TEXT_NODE:
-+ if (node->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlDebugDumpString(output, node->content);
-+#else
-+ xmlDebugDumpString(output, xmlBufferContent(node->content));
-+#endif
-+ }
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ if (node->name != NULL)
-+ fprintf(output, "%s", node->name);
-+ break;
-+ case XML_ENTITY_NODE:
-+ if (node->name != NULL)
-+ fprintf(output, "%s", node->name);
-+ break;
-+ case XML_PI_NODE:
-+ if (node->name != NULL)
-+ fprintf(output, "%s", node->name);
-+ break;
-+ case XML_COMMENT_NODE:
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+ break;
-+ case XML_DOCUMENT_TYPE_NODE:
-+ break;
-+ case XML_DOCUMENT_FRAG_NODE:
-+ break;
-+ case XML_NOTATION_NODE:
-+ break;
-+ default:
-+ if (node->name != NULL)
-+ fprintf(output, "%s", node->name);
-+ }
-+ fprintf(output, "\n");
-+}
-+
-+/****************************************************************
-+ * *
-+ * The XML shell related functions *
-+ * *
-+ ****************************************************************/
-+
-+/*
-+ * TODO: Improvement/cleanups for the XML shell
-+ * - allow to shell out an editor on a subpart
-+ * - cleanup function registrations (with help) and calling
-+ * - provide registration routines
-+ */
-+
-+/**
-+ * xmlShellList:
-+ * @ctxt: the shell context
-+ * @arg: unused
-+ * @node: a node
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "ls"
-+ * Does an Unix like listing of the given node (like a directory)
-+ *
-+ * Returns 0
-+ */
-+int
-+xmlShellList(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ xmlNodePtr cur;
-+
-+ if ((node->type == XML_DOCUMENT_NODE) ||
-+ (node->type == XML_HTML_DOCUMENT_NODE)) {
-+ cur = ((xmlDocPtr) node)->children;
-+ } else if (node->children != NULL) {
-+ cur = node->children;
-+ } else {
-+ xmlLsOneNode(stdout, node);
-+ return(0);
-+ }
-+ while (cur != NULL) {
-+ xmlLsOneNode(stdout, cur);
-+ cur = cur->next;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellDir:
-+ * @ctxt: the shell context
-+ * @arg: unused
-+ * @node: a node
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "dir"
-+ * dumps informations about the node (namespace, attributes, content).
-+ *
-+ * Returns 0
-+ */
-+int
-+xmlShellDir(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ if ((node->type == XML_DOCUMENT_NODE) ||
-+ (node->type == XML_HTML_DOCUMENT_NODE)) {
-+ xmlDebugDumpDocumentHead(stdout, (xmlDocPtr) node);
-+ } else if (node->type == XML_ATTRIBUTE_NODE) {
-+ xmlDebugDumpAttr(stdout, (xmlAttrPtr) node, 0);
-+ } else {
-+ xmlDebugDumpOneNode(stdout, node, 0);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellCat:
-+ * @ctxt: the shell context
-+ * @arg: unused
-+ * @node: a node
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "cat"
-+ * dumps the serialization node content (XML or HTML).
-+ *
-+ * Returns 0
-+ */
-+int
-+xmlShellCat(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
-+#ifdef LIBXML_HTML_ENABLED
-+ if (node->type == XML_HTML_DOCUMENT_NODE)
-+ htmlDocDump(stdout, (htmlDocPtr) node);
-+ else
-+ htmlNodeDumpFile(stdout, ctxt->doc, node);
-+#else
-+ if (node->type == XML_DOCUMENT_NODE)
-+ xmlDocDump(stdout, (xmlDocPtr) node);
-+ else
-+ xmlElemDump(stdout, ctxt->doc, node);
-+#endif /* LIBXML_HTML_ENABLED */
-+ } else {
-+ if (node->type == XML_DOCUMENT_NODE)
-+ xmlDocDump(stdout, (xmlDocPtr) node);
-+ else
-+ xmlElemDump(stdout, ctxt->doc, node);
-+ }
-+ printf("\n");
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellLoad:
-+ * @ctxt: the shell context
-+ * @filename: the file name
-+ * @node: unused
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "load"
-+ * loads a new document specified by the filename
-+ *
-+ * Returns 0 or -1 if loading failed
-+ */
-+int
-+xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ xmlDocPtr doc;
-+ int html = 0;
-+
-+ if (ctxt->doc != NULL)
-+ html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
-+
-+ if (html) {
-+#ifdef LIBXML_HTML_ENABLED
-+ doc = htmlParseFile(filename, NULL);
-+#else
-+ printf("HTML support not compiled in\n");
-+ doc = NULL;
-+#endif /* LIBXML_HTML_ENABLED */
-+ } else {
-+ doc = xmlParseFile(filename);
-+ }
-+ if (doc != NULL) {
-+ if (ctxt->loaded == 1) {
-+ xmlFreeDoc(ctxt->doc);
-+ }
-+ ctxt->loaded = 1;
-+#ifdef LIBXML_XPATH_ENABLED
-+ xmlXPathFreeContext(ctxt->pctxt);
-+#endif /* LIBXML_XPATH_ENABLED */
-+ xmlFree(ctxt->filename);
-+ ctxt->doc = doc;
-+ ctxt->node = (xmlNodePtr) doc;
-+#ifdef LIBXML_XPATH_ENABLED
-+ ctxt->pctxt = xmlXPathNewContext(doc);
-+#endif /* LIBXML_XPATH_ENABLED */
-+ ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
-+ } else
-+ return(-1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellWrite:
-+ * @ctxt: the shell context
-+ * @filename: the file name
-+ * @node: a node in the tree
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "write"
-+ * Write the current node to the filename, it saves the serailization
-+ * of the subtree under the @node specified
-+ *
-+ * Returns 0 or -1 in case of error
-+ */
-+int
-+xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ if (node == NULL)
-+ return(-1);
-+ if ((filename == NULL) || (filename[0] == 0)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Write command requires a filename argument\n");
-+ return(-1);
-+ }
-+#ifdef W_OK
-+ if (access((char *) filename, W_OK)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Cannot write to %s\n", filename);
-+ return(-1);
-+ }
-+#endif
-+ switch(node->type) {
-+ case XML_DOCUMENT_NODE:
-+ if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to write to %s\n", filename);
-+ return(-1);
-+ }
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_HTML_ENABLED
-+ if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to write to %s\n", filename);
-+ return(-1);
-+ }
-+#else
-+ if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to write to %s\n", filename);
-+ return(-1);
-+ }
-+#endif /* LIBXML_HTML_ENABLED */
-+ break;
-+ default: {
-+ FILE *f;
-+
-+ f = fopen((char *) filename, "w");
-+ if (f == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to write to %s\n", filename);
-+ return(-1);
-+ }
-+ xmlElemDump(f, ctxt->doc, node);
-+ fclose(f);
-+ }
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellSave:
-+ * @ctxt: the shell context
-+ * @filename: the file name (optionnal)
-+ * @node: unused
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "save"
-+ * Write the current document to the filename, or it's original name
-+ *
-+ * Returns 0 or -1 in case of error
-+ */
-+int
-+xmlShellSave(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ if (ctxt->doc == NULL)
-+ return(-1);
-+ if ((filename == NULL) || (filename[0] == 0))
-+ filename = ctxt->filename;
-+#ifdef W_OK
-+ if (access((char *) filename, W_OK)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Cannot save to %s\n", filename);
-+ return(-1);
-+ }
-+#endif
-+ switch(ctxt->doc->type) {
-+ case XML_DOCUMENT_NODE:
-+ if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to save to %s\n", filename);
-+ }
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_HTML_ENABLED
-+ if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to save to %s\n", filename);
-+ }
-+#else
-+ if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to save to %s\n", filename);
-+ }
-+#endif /* LIBXML_HTML_ENABLED */
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "To save to subparts of a document use the 'write' command\n");
-+ return(-1);
-+
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellValidate:
-+ * @ctxt: the shell context
-+ * @dtd: the DTD URI (optionnal)
-+ * @node: unused
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "validate"
-+ * Validate the document, if a DTD path is provided, then the validation
-+ * is done against the given DTD.
-+ *
-+ * Returns 0 or -1 in case of error
-+ */
-+int
-+xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ xmlValidCtxt vctxt;
-+ int res = -1;
-+
-+ vctxt.userData = stderr;
-+ vctxt.error = (xmlValidityErrorFunc) fprintf;
-+ vctxt.warning = (xmlValidityWarningFunc) fprintf;
-+
-+ if ((dtd == NULL) || (dtd[0] == 0)) {
-+ res = xmlValidateDocument(&vctxt, ctxt->doc);
-+ } else {
-+ xmlDtdPtr subset;
-+
-+ subset = xmlParseDTD(NULL, (xmlChar *) dtd);
-+ if (subset != NULL) {
-+ res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
-+
-+ xmlFreeDtd(subset);
-+ }
-+ }
-+ return(res);
-+}
-+
-+/**
-+ * xmlShellDu:
-+ * @ctxt: the shell context
-+ * @arg: unused
-+ * @tree: a node defining a subtree
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "du"
-+ * show the structure of the subtree under node @tree
-+ * If @tree is null, the command works on the current node.
-+ *
-+ * Returns 0 or -1 in case of error
-+ */
-+int
-+xmlShellDu(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr tree,
-+ xmlNodePtr node2) {
-+ xmlNodePtr node;
-+ int indent = 0,i;
-+
-+ if (tree == NULL) return(-1);
-+ node = tree;
-+ while (node != NULL) {
-+ if ((node->type == XML_DOCUMENT_NODE) ||
-+ (node->type == XML_HTML_DOCUMENT_NODE)) {
-+ printf("/\n");
-+ } else if (node->type == XML_ELEMENT_NODE) {
-+ for (i = 0;i < indent;i++)
-+ printf(" ");
-+ printf("%s\n", node->name);
-+ } else {
-+ }
-+
-+ /*
-+ * Browse the full subtree, deep first
-+ */
-+
-+ if ((node->type == XML_DOCUMENT_NODE) ||
-+ (node->type == XML_HTML_DOCUMENT_NODE)) {
-+ node = ((xmlDocPtr) node)->children;
-+ } else if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
-+ /* deep first */
-+ node = node->children;
-+ indent++;
-+ } else if ((node != tree) && (node->next != NULL)) {
-+ /* then siblings */
-+ node = node->next;
-+ } else if (node != tree) {
-+ /* go up to parents->next if needed */
-+ while (node != tree) {
-+ if (node->parent != NULL) {
-+ node = node->parent;
-+ indent--;
-+ }
-+ if ((node != tree) && (node->next != NULL)) {
-+ node = node->next;
-+ break;
-+ }
-+ if (node->parent == NULL) {
-+ node = NULL;
-+ break;
-+ }
-+ if (node == tree) {
-+ node = NULL;
-+ break;
-+ }
-+ }
-+ /* exit condition */
-+ if (node == tree)
-+ node = NULL;
-+ } else
-+ node = NULL;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlShellPwd:
-+ * @ctxt: the shell context
-+ * @buffer: the output buffer
-+ * @tree: a node
-+ * @node2: unused
-+ *
-+ * Implements the XML shell function "pwd"
-+ * Show the full path from the root to the node, if needed building
-+ * thumblers when similar elements exists at a given ancestor level.
-+ * The output is compatible with XPath commands.
-+ *
-+ * Returns 0 or -1 in case of error
-+ */
-+int
-+xmlShellPwd(xmlShellCtxtPtr ctxt, char *buffer, xmlNodePtr node,
-+ xmlNodePtr node2) {
-+ xmlNodePtr cur, tmp, next;
-+ char buf[500];
-+ char sep;
-+ const char *name;
-+ int occur = 0;
-+
-+ buffer[0] = 0;
-+ if (node == NULL) return(-1);
-+ cur = node;
-+ do {
-+ name = "";
-+ sep= '?';
-+ occur = 0;
-+ if ((cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ sep = '/';
-+ next = NULL;
-+ } else if (cur->type == XML_ELEMENT_NODE) {
-+ sep = '/';
-+ name = (const char *)cur->name;
-+ next = cur->parent;
-+
-+ /*
-+ * Thumbler index computation
-+ */
-+ tmp = cur->prev;
-+ while (tmp != NULL) {
-+ if (xmlStrEqual(cur->name, tmp->name))
-+ occur++;
-+ tmp = tmp->prev;
-+ }
-+ if (occur == 0) {
-+ tmp = cur->next;
-+ while (tmp != NULL) {
-+ if (xmlStrEqual(cur->name, tmp->name))
-+ occur++;
-+ tmp = tmp->next;
-+ }
-+ if (occur != 0) occur = 1;
-+ } else
-+ occur++;
-+ } else if (cur->type == XML_ATTRIBUTE_NODE) {
-+ sep = '@';
-+ name = (const char *) (((xmlAttrPtr) cur)->name);
-+ next = ((xmlAttrPtr) cur)->parent;
-+ } else {
-+ next = cur->parent;
-+ }
-+ if (occur == 0)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
-+#else
-+ sprintf(buf, "%c%s%s", sep, name, buffer);
-+#endif
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "%c%s[%d]%s",
-+ sep, name, occur, buffer);
-+#else
-+ sprintf(buf, "%c%s[%d]%s", sep, name, occur, buffer);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ /*
-+ * This test prevents buffer overflow, because this routine
-+ * is only called by xmlShell, in which the second argument is
-+ * 500 chars long.
-+ * It is a dirty hack before a cleaner solution is found.
-+ * Documentation should mention that the second argument must
-+ * be at least 500 chars long, and could be stripped if too long.
-+ */
-+ if (strlen(buffer) + strlen(buf) > 499)
-+ break;
-+ strcpy(buffer, buf);
-+ cur = next;
-+ } while (cur != NULL);
-+ return(0);
-+}
-+
-+/**
-+ * xmlShell
-+ * @doc: the initial document
-+ * @filename: the output buffer
-+ * @input: the line reading function
-+ * @output: the output FILE*
-+ *
-+ * Implements the XML shell
-+ * This allow to load, validate, view, modify and save a document
-+ * using a environment similar to a UNIX commandline.
-+ */
-+void
-+xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
-+ FILE *output) {
-+ char prompt[500] = "/ > ";
-+ char *cmdline = NULL, *cur;
-+ int nbargs;
-+ char command[100];
-+ char arg[400];
-+ int i;
-+ xmlShellCtxtPtr ctxt;
-+ xmlXPathObjectPtr list;
-+
-+ if (doc == NULL)
-+ return;
-+ if (filename == NULL)
-+ return;
-+ if (input == NULL)
-+ return;
-+ if (output == NULL)
-+ return;
-+ ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
-+ if (ctxt == NULL)
-+ return;
-+ ctxt->loaded = 0;
-+ ctxt->doc = doc;
-+ ctxt->input = input;
-+ ctxt->output = output;
-+ ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
-+ ctxt->node = (xmlNodePtr) ctxt->doc;
-+
-+#ifdef LIBXML_XPATH_ENABLED
-+ ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
-+ if (ctxt->pctxt == NULL) {
-+ xmlFree(ctxt);
-+ return;
-+ }
-+#endif /* LIBXML_XPATH_ENABLED */
-+ while (1) {
-+ if (ctxt->node == (xmlNodePtr) ctxt->doc)
-+ sprintf(prompt, "%s > ", "/");
-+ else if (ctxt->node->name)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
-+#else
-+ sprintf(prompt, "%s > ", ctxt->node->name);
-+#endif
-+ else
-+ sprintf(prompt, "? > ");
-+ prompt[sizeof(prompt) - 1] = 0;
-+
-+ /*
-+ * Get a new command line
-+ */
-+ cmdline = ctxt->input(prompt);
-+ if (cmdline == NULL) break;
-+
-+ /*
-+ * Parse the command itself
-+ */
-+ cur = cmdline;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ i = 0;
-+ while ((*cur != ' ') && (*cur != '\t') &&
-+ (*cur != '\n') && (*cur != '\r')) {
-+ if (*cur == 0)
-+ break;
-+ command[i++] = *cur++;
-+ }
-+ command[i] = 0;
-+ if (i == 0) continue;
-+ nbargs++;
-+
-+ /*
-+ * Parse the argument
-+ */
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ i = 0;
-+ while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
-+ if (*cur == 0)
-+ break;
-+ arg[i++] = *cur++;
-+ }
-+ arg[i] = 0;
-+ if (i != 0)
-+ nbargs++;
-+
-+ /*
-+ * start interpreting the command
-+ */
-+ if (!strcmp(command, "exit"))
-+ break;
-+ if (!strcmp(command, "quit"))
-+ break;
-+ if (!strcmp(command, "bye"))
-+ break;
-+ if (!strcmp(command, "validate")) {
-+ xmlShellValidate(ctxt, arg, NULL, NULL);
-+ } else if (!strcmp(command, "load")) {
-+ xmlShellLoad(ctxt, arg, NULL, NULL);
-+ } else if (!strcmp(command, "save")) {
-+ xmlShellSave(ctxt, arg, NULL, NULL);
-+ } else if (!strcmp(command, "write")) {
-+ xmlShellWrite(ctxt, arg, NULL, NULL);
-+ } else if (!strcmp(command, "free")) {
-+ if (arg[0] == 0) {
-+ xmlMemShow(stdout, 0);
-+ } else {
-+ int len = 0;
-+ sscanf(arg, "%d", &len);
-+ xmlMemShow(stdout, len);
-+ }
-+ } else if (!strcmp(command, "pwd")) {
-+ char dir[500];
-+ if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
-+ printf("%s\n", dir);
-+ } else if (!strcmp(command, "du")) {
-+ xmlShellDu(ctxt, NULL, ctxt->node, NULL);
-+ } else if ((!strcmp(command, "ls")) ||
-+ (!strcmp(command, "dir"))) {
-+ int dir = (!strcmp(command, "dir"));
-+ if (arg[0] == 0) {
-+ if (dir)
-+ xmlShellDir(ctxt, NULL, ctxt->node, NULL);
-+ else
-+ xmlShellList(ctxt, NULL, ctxt->node, NULL);
-+ } else {
-+ ctxt->pctxt->node = ctxt->node;
-+#ifdef LIBXML_XPATH_ENABLED
-+ ctxt->pctxt->node = ctxt->node;
-+ list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-+#else
-+ list = NULL;
-+#endif /* LIBXML_XPATH_ENABLED */
-+ if (list != NULL) {
-+ switch (list->type) {
-+ case XPATH_UNDEFINED:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: no such node\n", arg);
-+ break;
-+ case XPATH_NODESET: {
-+ int i;
-+
-+ for (i = 0;i < list->nodesetval->nodeNr;i++) {
-+ if (dir)
-+ xmlShellDir(ctxt, NULL,
-+ list->nodesetval->nodeTab[i], NULL);
-+ else
-+ xmlShellList(ctxt, NULL,
-+ list->nodesetval->nodeTab[i], NULL);
-+ }
-+ break;
-+ }
-+ case XPATH_BOOLEAN:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a Boolean\n", arg);
-+ break;
-+ case XPATH_NUMBER:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a number\n", arg);
-+ break;
-+ case XPATH_STRING:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a string\n", arg);
-+ break;
-+ case XPATH_POINT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a point\n", arg);
-+ break;
-+ case XPATH_RANGE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a range\n", arg);
-+ break;
-+ case XPATH_LOCATIONSET:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a range\n", arg);
-+ break;
-+ case XPATH_USERS:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is user-defined\n", arg);
-+ break;
-+ case XPATH_XSLT_TREE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is an XSLT value tree\n", arg);
-+ break;
-+ }
-+ xmlXPathFreeNodeSetList(list);
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: no such node\n", arg);
-+ }
-+ ctxt->pctxt->node = NULL;
-+ }
-+ } else if (!strcmp(command, "cd")) {
-+ if (arg[0] == 0) {
-+ ctxt->node = (xmlNodePtr) ctxt->doc;
-+ } else {
-+#ifdef LIBXML_XPATH_ENABLED
-+ ctxt->pctxt->node = ctxt->node;
-+ list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-+#else
-+ list = NULL;
-+#endif /* LIBXML_XPATH_ENABLED */
-+ if (list != NULL) {
-+ switch (list->type) {
-+ case XPATH_UNDEFINED:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: no such node\n", arg);
-+ break;
-+ case XPATH_NODESET:
-+ if (list->nodesetval->nodeNr == 1) {
-+ ctxt->node = list->nodesetval->nodeTab[0];
-+ } else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a %d Node Set\n",
-+ arg, list->nodesetval->nodeNr);
-+ break;
-+ case XPATH_BOOLEAN:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a Boolean\n", arg);
-+ break;
-+ case XPATH_NUMBER:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a number\n", arg);
-+ break;
-+ case XPATH_STRING:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a string\n", arg);
-+ break;
-+ case XPATH_POINT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a point\n", arg);
-+ break;
-+ case XPATH_RANGE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a range\n", arg);
-+ break;
-+ case XPATH_LOCATIONSET:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a range\n", arg);
-+ break;
-+ case XPATH_USERS:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is user-defined\n", arg);
-+ break;
-+ case XPATH_XSLT_TREE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is an XSLT value tree\n", arg);
-+ break;
-+ }
-+ xmlXPathFreeNodeSetList(list);
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: no such node\n", arg);
-+ }
-+ ctxt->pctxt->node = NULL;
-+ }
-+ } else if (!strcmp(command, "cat")) {
-+ if (arg[0] == 0) {
-+ xmlShellCat(ctxt, NULL, ctxt->node, NULL);
-+ } else {
-+ ctxt->pctxt->node = ctxt->node;
-+#ifdef LIBXML_XPATH_ENABLED
-+ ctxt->pctxt->node = ctxt->node;
-+ list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-+#else
-+ list = NULL;
-+#endif /* LIBXML_XPATH_ENABLED */
-+ if (list != NULL) {
-+ switch (list->type) {
-+ case XPATH_UNDEFINED:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: no such node\n", arg);
-+ break;
-+ case XPATH_NODESET: {
-+ int i;
-+
-+ for (i = 0;i < list->nodesetval->nodeNr;i++) {
-+ if (i > 0) printf(" -------\n");
-+ xmlShellCat(ctxt, NULL,
-+ list->nodesetval->nodeTab[i], NULL);
-+ }
-+ break;
-+ }
-+ case XPATH_BOOLEAN:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a Boolean\n", arg);
-+ break;
-+ case XPATH_NUMBER:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a number\n", arg);
-+ break;
-+ case XPATH_STRING:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a string\n", arg);
-+ break;
-+ case XPATH_POINT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a point\n", arg);
-+ break;
-+ case XPATH_RANGE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a range\n", arg);
-+ break;
-+ case XPATH_LOCATIONSET:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is a range\n", arg);
-+ break;
-+ case XPATH_USERS:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is user-defined\n", arg);
-+ break;
-+ case XPATH_XSLT_TREE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s is an XSLT value tree\n", arg);
-+ break;
-+ }
-+ xmlXPathFreeNodeSetList(list);
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: no such node\n", arg);
-+ }
-+ ctxt->pctxt->node = NULL;
-+ }
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Unknown command %s\n", command);
-+ }
-+ free(cmdline); /* not xmlFree here ! */
-+ }
-+#ifdef LIBXML_XPATH_ENABLED
-+ xmlXPathFreeContext(ctxt->pctxt);
-+#endif /* LIBXML_XPATH_ENABLED */
-+ if (ctxt->loaded) {
-+ xmlFreeDoc(ctxt->doc);
-+ }
-+ xmlFree(ctxt);
-+ if (cmdline != NULL)
-+ free(cmdline); /* not xmlFree here ! */
-+}
-+
-+#endif /* LIBXML_DEBUG_ENABLED */
-diff -Nru libxml2-2.3.0/libxml/debugXML.h libxml2-2.3.0.new/libxml/debugXML.h
---- libxml2-2.3.0/libxml/debugXML.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/debugXML.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,113 @@
-+/*
-+ * debugXML.h : Interfaces to a set of routines used for debugging the tree
-+ * produced by the XML parser.
-+ *
-+ * Daniel Veillard <Daniel.Veillard@w3.org>
-+ */
-+
-+#ifndef __DEBUG_XML__
-+#define __DEBUG_XML__
-+#include <stdio.h>
-+#include <libxml/tree.h>
-+
-+#ifdef LIBXML_DEBUG_ENABLED
-+
-+#include <libxml/xpath.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * The standard Dump routines
-+ */
-+void xmlDebugDumpString (FILE *output,
-+ const xmlChar *str);
-+void xmlDebugDumpAttr (FILE *output,
-+ xmlAttrPtr attr,
-+ int depth);
-+void xmlDebugDumpAttrList (FILE *output,
-+ xmlAttrPtr attr,
-+ int depth);
-+void xmlDebugDumpOneNode (FILE *output,
-+ xmlNodePtr node,
-+ int depth);
-+void xmlDebugDumpNode (FILE *output,
-+ xmlNodePtr node,
-+ int depth);
-+void xmlDebugDumpNodeList (FILE *output,
-+ xmlNodePtr node,
-+ int depth);
-+void xmlDebugDumpDocumentHead(FILE *output,
-+ xmlDocPtr doc);
-+void xmlDebugDumpDocument (FILE *output,
-+ xmlDocPtr doc);
-+void xmlDebugDumpDTD (FILE *output,
-+ xmlDtdPtr doc);
-+void xmlDebugDumpEntities (FILE *output,
-+ xmlDocPtr doc);
-+void xmlLsOneNode (FILE *output,
-+ xmlNodePtr node);
-+
-+/****************************************************************
-+ * *
-+ * The XML shell related structures and functions *
-+ * *
-+ ****************************************************************/
-+
-+/**
-+ * xmlShellReadlineFunc:
-+ * @prompt: a string prompt
-+ *
-+ * This is a generic signature for the XML shell input function
-+ *
-+ * Returns a string which will be freed by the Shell
-+ */
-+typedef char * (* xmlShellReadlineFunc)(char *prompt);
-+
-+/*
-+ * The shell context itself
-+ * TODO: add the defined function tables.
-+ */
-+typedef struct _xmlShellCtxt xmlShellCtxt;
-+typedef xmlShellCtxt *xmlShellCtxtPtr;
-+struct _xmlShellCtxt {
-+ char *filename;
-+ xmlDocPtr doc;
-+ xmlNodePtr node;
-+ xmlXPathContextPtr pctxt;
-+ int loaded;
-+ FILE *output;
-+ xmlShellReadlineFunc input;
-+};
-+
-+/**
-+ * xmlShellCmd:
-+ * @ctxt: a shell context
-+ * @arg: a string argument
-+ * @node: a first node
-+ * @node2: a second node
-+ *
-+ * This is a generic signature for the XML shell functions
-+ *
-+ * Returns an int, negative returns indicating errors
-+ */
-+typedef int (* xmlShellCmd) (xmlShellCtxtPtr ctxt,
-+ char *arg,
-+ xmlNodePtr node,
-+ xmlNodePtr node2);
-+
-+/*
-+ * The Shell interface.
-+ */
-+void xmlShell (xmlDocPtr doc,
-+ char *filename,
-+ xmlShellReadlineFunc input,
-+ FILE *output);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* LIBXML_DEBUG_ENABLED */
-+#endif /* __DEBUG_XML__ */
-diff -Nru libxml2-2.3.0/libxml/encoding.c libxml2-2.3.0.new/libxml/encoding.c
---- libxml2-2.3.0/libxml/encoding.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/encoding.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,2078 @@
-+/*
-+ * encoding.c : implements the encoding conversion functions needed for XML
-+ *
-+ * Related specs:
-+ * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
-+ * rfc2781 UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau
-+ * [ISO-10646] UTF-8 and UTF-16 in Annexes
-+ * [ISO-8859-1] ISO Latin-1 characters codes.
-+ * [UNICODE] The Unicode Consortium, "The Unicode Standard --
-+ * Worldwide Character Encoding -- Version 1.0", Addison-
-+ * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
-+ * described in Unicode Technical Report #4.
-+ * [US-ASCII] Coded Character Set--7-bit American Standard Code for
-+ * Information Interchange, ANSI X3.4-1986.
-+ *
-+ * Original code for IsoLatin1 and UTF-16 by "Martin J. Duerst" <duerst@w3.org>
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_ICONV_ENABLED
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#endif
-+#include <libxml/encoding.h>
-+#include <libxml/xmlmemory.h>
-+#ifdef LIBXML_HTML_ENABLED
-+#include <libxml/HTMLparser.h>
-+#endif
-+#include <libxml/xmlerror.h>
-+
-+xmlCharEncodingHandlerPtr xmlUTF16LEHandler = NULL;
-+xmlCharEncodingHandlerPtr xmlUTF16BEHandler = NULL;
-+
-+typedef struct _xmlCharEncodingAlias xmlCharEncodingAlias;
-+typedef xmlCharEncodingAlias *xmlCharEncodingAliasPtr;
-+struct _xmlCharEncodingAlias {
-+ const char *name;
-+ const char *alias;
-+};
-+
-+static xmlCharEncodingAliasPtr xmlCharEncodingAliases = NULL;
-+static int xmlCharEncodingAliasesNb = 0;
-+static int xmlCharEncodingAliasesMax = 0;
-+
-+#ifdef LIBXML_ICONV_ENABLED
-+#if 0
-+#define DEBUG_ENCODING /* Define this to get encoding traces */
-+#endif
-+#endif
-+
-+static int xmlLittleEndian = 1;
-+
-+/*
-+ * From rfc2044: encoding of the Unicode values on UTF-8:
-+ *
-+ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-+ * 0000 0000-0000 007F 0xxxxxxx
-+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-+ *
-+ * I hope we won't use values > 0xFFFF anytime soon !
-+ */
-+
-+/**
-+ * xmlGetUTF8Char:
-+ * @utf: a sequence of UTF-8 encoded bytes
-+ * @len: a pointer to @bytes len
-+ *
-+ * Read one UTF8 Char from @utf
-+ *
-+ * Returns the char value or -1 in case of error and update @len with the
-+ * number of bytes used
-+ */
-+int
-+xmlGetUTF8Char(const unsigned char *utf, int *len) {
-+ unsigned int c;
-+
-+ if (utf == NULL)
-+ goto error;
-+ if (len == NULL)
-+ goto error;
-+ if (*len < 1)
-+ goto error;
-+
-+ c = utf[0];
-+ if (c & 0x80) {
-+ if (*len < 2)
-+ goto error;
-+ if ((utf[1] & 0xc0) != 0x80)
-+ goto error;
-+ if ((c & 0xe0) == 0xe0) {
-+ if (*len < 3)
-+ goto error;
-+ if ((utf[2] & 0xc0) != 0x80)
-+ goto error;
-+ if ((c & 0xf0) == 0xf0) {
-+ if (*len < 4)
-+ goto error;
-+ if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
-+ goto error;
-+ *len = 4;
-+ /* 4-byte code */
-+ c = (utf[0] & 0x7) << 18;
-+ c |= (utf[1] & 0x3f) << 12;
-+ c |= (utf[2] & 0x3f) << 6;
-+ c |= utf[3] & 0x3f;
-+ } else {
-+ /* 3-byte code */
-+ *len = 3;
-+ c = (utf[0] & 0xf) << 12;
-+ c |= (utf[1] & 0x3f) << 6;
-+ c |= utf[2] & 0x3f;
-+ }
-+ } else {
-+ /* 2-byte code */
-+ *len = 2;
-+ c = (utf[0] & 0x1f) << 6;
-+ c |= utf[1] & 0x3f;
-+ }
-+ } else {
-+ /* 1-byte code */
-+ *len = 1;
-+ }
-+ return(c);
-+
-+error:
-+ *len = 0;
-+ return(-1);
-+}
-+
-+/**
-+ * xmlCheckUTF8: Check utf-8 string for legality.
-+ * @utf: Pointer to putative utf-8 encoded string.
-+ *
-+ * Checks @utf for being valid utf-8. @utf is assumed to be
-+ * null-terminated. This function is not super-strict, as it will
-+ * allow longer utf-8 sequences than necessary. Note that Java is
-+ * capable of producing these sequences if provoked. Also note, this
-+ * routine checks for the 4-byte maxiumum size, but does not check for
-+ * 0x10ffff maximum value.
-+ *
-+ * Return value: true if @utf is valid.
-+ **/
-+int
-+xmlCheckUTF8(const unsigned char *utf)
-+{
-+ int ix;
-+ unsigned char c;
-+
-+ for (ix = 0; (c = utf[ix]);) {
-+ if (c & 0x80) {
-+ if ((utf[ix + 1] & 0xc0) != 0x80)
-+ return(0);
-+ if ((c & 0xe0) == 0xe0) {
-+ if ((utf[ix + 2] & 0xc0) != 0x80)
-+ return(0);
-+ if ((c & 0xf0) == 0xf0) {
-+ if ((c & 0xf8) != 0xf0 || (utf[ix + 3] & 0xc0) != 0x80)
-+ return(0);
-+ ix += 4;
-+ /* 4-byte code */
-+ } else
-+ /* 3-byte code */
-+ ix += 3;
-+ } else
-+ /* 2-byte code */
-+ ix += 2;
-+ } else
-+ /* 1-byte code */
-+ ix++;
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * asciiToUTF8:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of ASCII chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of ASCII chars in and try to convert it to an UTF-8
-+ * block of chars out.
-+ * Returns 0 if success, or -1 otherwise
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+int
-+asciiToUTF8(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen) {
-+ unsigned char* outstart = out;
-+ const unsigned char* base = in;
-+ const unsigned char* processed = in;
-+ unsigned char* outend = out + *outlen;
-+ const unsigned char* inend;
-+ unsigned int c;
-+ int bits;
-+
-+ inend = in + (*inlen);
-+ while ((in < inend) && (out - outstart + 5 < *outlen)) {
-+ c= *in++;
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (out >= outend)
-+ break;
-+ if (c < 0x80) { *out++= c; bits= -6; }
-+ else {
-+ *outlen = out - outstart;
-+ *inlen = processed - base;
-+ return(-1);
-+ }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ if (out >= outend)
-+ break;
-+ *out++= ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ processed = (const unsigned char*) in;
-+ }
-+ *outlen = out - outstart;
-+ *inlen = processed - base;
-+ return(0);
-+}
-+
-+/**
-+ * UTF8Toascii:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of UTF-8 chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
-+ * block of chars out.
-+ *
-+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+int
-+UTF8Toascii(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen) {
-+ const unsigned char* processed = in;
-+ const unsigned char* outend;
-+ const unsigned char* outstart = out;
-+ const unsigned char* instart = in;
-+ const unsigned char* inend;
-+ unsigned int c, d;
-+ int trailing;
-+
-+ if (in == NULL) {
-+ /*
-+ * initialization nothing to do
-+ */
-+ *outlen = 0;
-+ *inlen = 0;
-+ return(0);
-+ }
-+ inend = in + (*inlen);
-+ outend = out + (*outlen);
-+ while (in < inend) {
-+ d = *in++;
-+ if (d < 0x80) { c= d; trailing= 0; }
-+ else if (d < 0xC0) {
-+ /* trailing byte in leading position */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-+ else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-+ else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-+ else {
-+ /* no chance for this in Ascii */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+
-+ if (inend - in < trailing) {
-+ break;
-+ }
-+
-+ for ( ; trailing; trailing--) {
-+ if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
-+ break;
-+ c <<= 6;
-+ c |= d & 0x3F;
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (c < 0x80) {
-+ if (out >= outend)
-+ break;
-+ *out++ = c;
-+ } else {
-+ /* no chance for this in Ascii */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+ processed = in;
-+ }
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(0);
-+}
-+
-+/**
-+ * isolat1ToUTF8:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of ISO Latin 1 chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of ISO Latin 1 chars in and try to convert it to an UTF-8
-+ * block of chars out.
-+ * Returns 0 if success, or -1 otherwise
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+int
-+isolat1ToUTF8(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen) {
-+ unsigned char* outstart = out;
-+ const unsigned char* base = in;
-+ const unsigned char* processed = in;
-+ unsigned char* outend = out + *outlen;
-+ const unsigned char* inend;
-+ unsigned int c;
-+ int bits;
-+
-+ inend = in + (*inlen);
-+ while ((in < inend) && (out - outstart + 5 < *outlen)) {
-+ c= *in++;
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (out >= outend)
-+ break;
-+ if (c < 0x80) { *out++= c; bits= -6; }
-+ else { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ if (out >= outend)
-+ break;
-+ *out++= ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ processed = (const unsigned char*) in;
-+ }
-+ *outlen = out - outstart;
-+ *inlen = processed - base;
-+ return(0);
-+}
-+
-+/**
-+ * UTF8Toisolat1:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of UTF-8 chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an ISO Latin 1
-+ * block of chars out.
-+ *
-+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+int
-+UTF8Toisolat1(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen) {
-+ const unsigned char* processed = in;
-+ const unsigned char* outend;
-+ const unsigned char* outstart = out;
-+ const unsigned char* instart = in;
-+ const unsigned char* inend;
-+ unsigned int c, d;
-+ int trailing;
-+
-+ if (in == NULL) {
-+ /*
-+ * initialization nothing to do
-+ */
-+ *outlen = 0;
-+ *inlen = 0;
-+ return(0);
-+ }
-+ inend = in + (*inlen);
-+ outend = out + (*outlen);
-+ while (in < inend) {
-+ d = *in++;
-+ if (d < 0x80) { c= d; trailing= 0; }
-+ else if (d < 0xC0) {
-+ /* trailing byte in leading position */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-+ else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-+ else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-+ else {
-+ /* no chance for this in IsoLat1 */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+
-+ if (inend - in < trailing) {
-+ break;
-+ }
-+
-+ for ( ; trailing; trailing--) {
-+ if (in >= inend)
-+ break;
-+ if (((d= *in++) & 0xC0) != 0x80) {
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+ c <<= 6;
-+ c |= d & 0x3F;
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (c <= 0xFF) {
-+ if (out >= outend)
-+ break;
-+ *out++ = c;
-+ } else {
-+ /* no chance for this in IsoLat1 */
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(-2);
-+ }
-+ processed = in;
-+ }
-+ *outlen = out - outstart;
-+ *inlen = processed - instart;
-+ return(0);
-+}
-+
-+/**
-+ * UTF16LEToUTF8:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @inb: a pointer to an array of UTF-16LE passwd as a byte array
-+ * @inlenb: the length of @in in UTF-16LE chars
-+ *
-+ * Take a block of UTF-16LE ushorts in and try to convert it to an UTF-8
-+ * block of chars out. This function assume the endian properity
-+ * is the same between the native type of this machine and the
-+ * inputed one.
-+ *
-+ * Returns the number of byte written, or -1 by lack of space, or -2
-+ * if the transcoding fails (for *in is not valid utf16 string)
-+ * The value of *inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ */
-+int
-+UTF16LEToUTF8(unsigned char* out, int *outlen,
-+ const unsigned char* inb, int *inlenb)
-+{
-+ unsigned char* outstart = out;
-+ const unsigned char* processed = inb;
-+ unsigned char* outend = out + *outlen;
-+ unsigned short* in = (unsigned short*) inb;
-+ unsigned short* inend;
-+ unsigned int c, d, inlen;
-+ unsigned char *tmp;
-+ int bits;
-+
-+ if ((*inlenb % 2) == 1)
-+ (*inlenb)--;
-+ inlen = *inlenb / 2;
-+ inend = in + inlen;
-+ while ((in < inend) && (out - outstart + 5 < *outlen)) {
-+ if (xmlLittleEndian) {
-+ c= *in++;
-+ } else {
-+ tmp = (unsigned char *) in;
-+ c = *tmp++;
-+ c = c | (((unsigned int)*tmp) << 8);
-+ in++;
-+ }
-+ if ((c & 0xFC00) == 0xD800) { /* surrogates */
-+ if (in >= inend) { /* (in > inend) shouldn't happens */
-+ break;
-+ }
-+ if (xmlLittleEndian) {
-+ d = *in++;
-+ } else {
-+ tmp = (unsigned char *) in;
-+ d = *tmp++;
-+ d = d | (((unsigned int)*tmp) << 8);
-+ in++;
-+ }
-+ if ((d & 0xFC00) == 0xDC00) {
-+ c &= 0x03FF;
-+ c <<= 10;
-+ c |= d & 0x03FF;
-+ c += 0x10000;
-+ }
-+ else {
-+ *outlen = out - outstart;
-+ *inlenb = processed - inb;
-+ return(-2);
-+ }
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (out >= outend)
-+ break;
-+ if (c < 0x80) { *out++= c; bits= -6; }
-+ else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ if (out >= outend)
-+ break;
-+ *out++= ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ processed = (const unsigned char*) in;
-+ }
-+ *outlen = out - outstart;
-+ *inlenb = processed - inb;
-+ return(0);
-+}
-+
-+/**
-+ * UTF8ToUTF16LE:
-+ * @outb: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @outb
-+ * @in: a pointer to an array of UTF-8 chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an UTF-16LE
-+ * block of chars out.
-+ *
-+ * Returns the number of byte written, or -1 by lack of space, or -2
-+ * if the transcoding failed.
-+ */
-+int
-+UTF8ToUTF16LE(unsigned char* outb, int *outlen,
-+ const unsigned char* in, int *inlen)
-+{
-+ unsigned short* out = (unsigned short*) outb;
-+ const unsigned char* processed = in;
-+ unsigned short* outstart= out;
-+ unsigned short* outend;
-+ const unsigned char* inend= in+*inlen;
-+ unsigned int c, d;
-+ int trailing;
-+ unsigned char *tmp;
-+ unsigned short tmp1, tmp2;
-+
-+ if (in == NULL) {
-+ /*
-+ * initialization, add the Byte Order Mark
-+ */
-+ if (*outlen >= 2) {
-+ outb[0] = 0xFF;
-+ outb[1] = 0xFE;
-+ *outlen = 2;
-+ *inlen = 0;
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Added FFFE Byte Order Mark\n");
-+#endif
-+ return(2);
-+ }
-+ *outlen = 0;
-+ *inlen = 0;
-+ return(0);
-+ }
-+ outend = out + (*outlen / 2);
-+ while (in < inend) {
-+ d= *in++;
-+ if (d < 0x80) { c= d; trailing= 0; }
-+ else if (d < 0xC0) {
-+ /* trailing byte in leading position */
-+ *outlen = (out - outstart) * 2;
-+ *inlen = processed - in;
-+ return(-2);
-+ } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-+ else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-+ else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-+ else {
-+ /* no chance for this in UTF-16 */
-+ *outlen = (out - outstart) * 2;
-+ *inlen = processed - in;
-+ return(-2);
-+ }
-+
-+ if (inend - in < trailing) {
-+ break;
-+ }
-+
-+ for ( ; trailing; trailing--) {
-+ if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
-+ break;
-+ c <<= 6;
-+ c |= d & 0x3F;
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (c < 0x10000) {
-+ if (out >= outend)
-+ break;
-+ if (xmlLittleEndian) {
-+ *out++ = c;
-+ } else {
-+ tmp = (unsigned char *) out;
-+ *tmp = c ;
-+ *(tmp + 1) = c >> 8 ;
-+ out++;
-+ }
-+ }
-+ else if (c < 0x110000) {
-+ if (out+1 >= outend)
-+ break;
-+ c -= 0x10000;
-+ if (xmlLittleEndian) {
-+ *out++ = 0xD800 | (c >> 10);
-+ *out++ = 0xDC00 | (c & 0x03FF);
-+ } else {
-+ tmp1 = 0xD800 | (c >> 10);
-+ tmp = (unsigned char *) out;
-+ *tmp = (unsigned char) tmp1;
-+ *(tmp + 1) = tmp1 >> 8;
-+ out++;
-+
-+ tmp2 = 0xDC00 | (c & 0x03FF);
-+ tmp = (unsigned char *) out;
-+ *tmp = (unsigned char) tmp2;
-+ *(tmp + 1) = tmp2 >> 8;
-+ out++;
-+ }
-+ }
-+ else
-+ break;
-+ processed = in;
-+ }
-+ *outlen = (out - outstart) * 2;
-+ *inlen = processed - in;
-+ return(0);
-+}
-+
-+/**
-+ * UTF16BEToUTF8:
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @inb: a pointer to an array of UTF-16 passwd as a byte array
-+ * @inlenb: the length of @in in UTF-16 chars
-+ *
-+ * Take a block of UTF-16 ushorts in and try to convert it to an UTF-8
-+ * block of chars out. This function assume the endian properity
-+ * is the same between the native type of this machine and the
-+ * inputed one.
-+ *
-+ * Returns the number of byte written, or -1 by lack of space, or -2
-+ * if the transcoding fails (for *in is not valid utf16 string)
-+ * The value of *inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ */
-+int
-+UTF16BEToUTF8(unsigned char* out, int *outlen,
-+ const unsigned char* inb, int *inlenb)
-+{
-+ unsigned char* outstart = out;
-+ const unsigned char* processed = inb;
-+ unsigned char* outend = out + *outlen;
-+ unsigned short* in = (unsigned short*) inb;
-+ unsigned short* inend;
-+ unsigned int c, d, inlen;
-+ unsigned char *tmp;
-+ int bits;
-+
-+ if ((*inlenb % 2) == 1)
-+ (*inlenb)--;
-+ inlen = *inlenb / 2;
-+ inend= in + inlen;
-+ while (in < inend) {
-+ if (xmlLittleEndian) {
-+ tmp = (unsigned char *) in;
-+ c = *tmp++;
-+ c = c << 8;
-+ c = c | (unsigned int) *tmp;
-+ in++;
-+ } else {
-+ c= *in++;
-+ }
-+ if ((c & 0xFC00) == 0xD800) { /* surrogates */
-+ if (in >= inend) { /* (in > inend) shouldn't happens */
-+ *outlen = out - outstart;
-+ *inlenb = processed - inb;
-+ return(-2);
-+ }
-+ if (xmlLittleEndian) {
-+ tmp = (unsigned char *) in;
-+ d = *tmp++;
-+ d = d << 8;
-+ d = d | (unsigned int) *tmp;
-+ in++;
-+ } else {
-+ d= *in++;
-+ }
-+ if ((d & 0xFC00) == 0xDC00) {
-+ c &= 0x03FF;
-+ c <<= 10;
-+ c |= d & 0x03FF;
-+ c += 0x10000;
-+ }
-+ else {
-+ *outlen = out - outstart;
-+ *inlenb = processed - inb;
-+ return(-2);
-+ }
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (out >= outend)
-+ break;
-+ if (c < 0x80) { *out++= c; bits= -6; }
-+ else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
-+ else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
-+ else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6) {
-+ if (out >= outend)
-+ break;
-+ *out++= ((c >> bits) & 0x3F) | 0x80;
-+ }
-+ processed = (const unsigned char*) in;
-+ }
-+ *outlen = out - outstart;
-+ *inlenb = processed - inb;
-+ return(0);
-+}
-+
-+/**
-+ * UTF8ToUTF16BE:
-+ * @outb: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @outb
-+ * @in: a pointer to an array of UTF-8 chars
-+ * @inlen: the length of @in
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an UTF-16BE
-+ * block of chars out.
-+ *
-+ * Returns the number of byte written, or -1 by lack of space, or -2
-+ * if the transcoding failed.
-+ */
-+int
-+UTF8ToUTF16BE(unsigned char* outb, int *outlen,
-+ const unsigned char* in, int *inlen)
-+{
-+ unsigned short* out = (unsigned short*) outb;
-+ const unsigned char* processed = in;
-+ unsigned short* outstart= out;
-+ unsigned short* outend;
-+ const unsigned char* inend= in+*inlen;
-+ unsigned int c, d;
-+ int trailing;
-+ unsigned char *tmp;
-+ unsigned short tmp1, tmp2;
-+
-+ if (in == NULL) {
-+ /*
-+ * initialization, add the Byte Order Mark
-+ */
-+ if (*outlen >= 2) {
-+ outb[0] = 0xFE;
-+ outb[1] = 0xFF;
-+ *outlen = 2;
-+ *inlen = 0;
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Added FEFF Byte Order Mark\n");
-+#endif
-+ return(2);
-+ }
-+ *outlen = 0;
-+ *inlen = 0;
-+ return(0);
-+ }
-+ outend = out + (*outlen / 2);
-+ while (in < inend) {
-+ d= *in++;
-+ if (d < 0x80) { c= d; trailing= 0; }
-+ else if (d < 0xC0) {
-+ /* trailing byte in leading position */
-+ *outlen = out - outstart;
-+ *inlen = processed - in;
-+ return(-2);
-+ } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
-+ else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
-+ else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
-+ else {
-+ /* no chance for this in UTF-16 */
-+ *outlen = out - outstart;
-+ *inlen = processed - in;
-+ return(-2);
-+ }
-+
-+ if (inend - in < trailing) {
-+ break;
-+ }
-+
-+ for ( ; trailing; trailing--) {
-+ if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80)) break;
-+ c <<= 6;
-+ c |= d & 0x3F;
-+ }
-+
-+ /* assertion: c is a single UTF-4 value */
-+ if (c < 0x10000) {
-+ if (out >= outend) break;
-+ if (xmlLittleEndian) {
-+ tmp = (unsigned char *) out;
-+ *tmp = c >> 8;
-+ *(tmp + 1) = c;
-+ out++;
-+ } else {
-+ *out++ = c;
-+ }
-+ }
-+ else if (c < 0x110000) {
-+ if (out+1 >= outend) break;
-+ c -= 0x10000;
-+ if (xmlLittleEndian) {
-+ tmp1 = 0xD800 | (c >> 10);
-+ tmp = (unsigned char *) out;
-+ *tmp = tmp1 >> 8;
-+ *(tmp + 1) = (unsigned char) tmp1;
-+ out++;
-+
-+ tmp2 = 0xDC00 | (c & 0x03FF);
-+ tmp = (unsigned char *) out;
-+ *tmp = tmp2 >> 8;
-+ *(tmp + 1) = (unsigned char) tmp2;
-+ out++;
-+ } else {
-+ *out++ = 0xD800 | (c >> 10);
-+ *out++ = 0xDC00 | (c & 0x03FF);
-+ }
-+ }
-+ else
-+ break;
-+ processed = in;
-+ }
-+ *outlen = (out - outstart) * 2;
-+ *inlen = processed - in;
-+ return(0);
-+}
-+
-+/**
-+ * xmlDetectCharEncoding:
-+ * @in: a pointer to the first bytes of the XML entity, must be at least
-+ * 4 bytes long.
-+ * @len: pointer to the length of the buffer
-+ *
-+ * Guess the encoding of the entity using the first bytes of the entity content
-+ * accordingly of the non-normative appendix F of the XML-1.0 recommendation.
-+ *
-+ * Returns one of the XML_CHAR_ENCODING_... values.
-+ */
-+xmlCharEncoding
-+xmlDetectCharEncoding(const unsigned char* in, int len)
-+{
-+ if (len >= 4) {
-+ if ((in[0] == 0x00) && (in[1] == 0x00) &&
-+ (in[2] == 0x00) && (in[3] == 0x3C))
-+ return(XML_CHAR_ENCODING_UCS4BE);
-+ if ((in[0] == 0x3C) && (in[1] == 0x00) &&
-+ (in[2] == 0x00) && (in[3] == 0x00))
-+ return(XML_CHAR_ENCODING_UCS4LE);
-+ if ((in[0] == 0x00) && (in[1] == 0x00) &&
-+ (in[2] == 0x3C) && (in[3] == 0x00))
-+ return(XML_CHAR_ENCODING_UCS4_2143);
-+ if ((in[0] == 0x00) && (in[1] == 0x3C) &&
-+ (in[2] == 0x00) && (in[3] == 0x00))
-+ return(XML_CHAR_ENCODING_UCS4_3412);
-+ if ((in[0] == 0x4C) && (in[1] == 0x6F) &&
-+ (in[2] == 0xA7) && (in[3] == 0x94))
-+ return(XML_CHAR_ENCODING_EBCDIC);
-+ if ((in[0] == 0x3C) && (in[1] == 0x3F) &&
-+ (in[2] == 0x78) && (in[3] == 0x6D))
-+ return(XML_CHAR_ENCODING_UTF8);
-+ }
-+ if (len >= 2) {
-+ if ((in[0] == 0xFE) && (in[1] == 0xFF))
-+ return(XML_CHAR_ENCODING_UTF16BE);
-+ if ((in[0] == 0xFF) && (in[1] == 0xFE))
-+ return(XML_CHAR_ENCODING_UTF16LE);
-+ }
-+ return(XML_CHAR_ENCODING_NONE);
-+}
-+
-+/**
-+ * xmlCleanupEncodingAliases:
-+ *
-+ * Unregisters all aliases
-+ */
-+void
-+xmlCleanupEncodingAliases(void) {
-+ int i;
-+
-+ if (xmlCharEncodingAliases == NULL)
-+ return;
-+
-+ for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-+ if (xmlCharEncodingAliases[i].name != NULL)
-+ xmlFree((char *) xmlCharEncodingAliases[i].name);
-+ if (xmlCharEncodingAliases[i].alias != NULL)
-+ xmlFree((char *) xmlCharEncodingAliases[i].alias);
-+ }
-+ xmlCharEncodingAliasesNb = 0;
-+ xmlCharEncodingAliasesMax = 0;
-+ xmlFree(xmlCharEncodingAliases);
-+}
-+
-+/**
-+ * xmlGetEncodingAlias:
-+ * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
-+ *
-+ * Lookup an encoding name for the given alias.
-+ *
-+ * Returns NULL if not found the original name otherwise
-+ */
-+const char *
-+xmlGetEncodingAlias(const char *alias) {
-+ int i;
-+ char upper[100];
-+
-+ if (alias == NULL)
-+ return(NULL);
-+
-+ if (xmlCharEncodingAliases == NULL)
-+ return(NULL);
-+
-+ for (i = 0;i < 99;i++) {
-+ upper[i] = toupper(alias[i]);
-+ if (upper[i] == 0) break;
-+ }
-+ upper[i] = 0;
-+
-+ /*
-+ * Walk down the list looking for a definition of the alias
-+ */
-+ for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-+ if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
-+ return(xmlCharEncodingAliases[i].name);
-+ }
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlAddEncodingAlias:
-+ * @name: the encoding name as parsed, in UTF-8 format (ASCII actually)
-+ * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
-+ *
-+ * Registers and alias @alias for an encoding named @name. Existing alias
-+ * will be overwritten.
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlAddEncodingAlias(const char *name, const char *alias) {
-+ int i;
-+ char upper[100];
-+
-+ if ((name == NULL) || (alias == NULL))
-+ return(-1);
-+
-+ for (i = 0;i < 99;i++) {
-+ upper[i] = toupper(alias[i]);
-+ if (upper[i] == 0) break;
-+ }
-+ upper[i] = 0;
-+
-+ if (xmlCharEncodingAliases == NULL) {
-+ xmlCharEncodingAliasesNb = 0;
-+ xmlCharEncodingAliasesMax = 20;
-+ xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
-+ xmlMalloc(xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
-+ if (xmlCharEncodingAliases == NULL)
-+ return(-1);
-+ } else if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
-+ xmlCharEncodingAliasesMax *= 2;
-+ xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
-+ xmlRealloc(xmlCharEncodingAliases,
-+ xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
-+ }
-+ /*
-+ * Walk down the list looking for a definition of the alias
-+ */
-+ for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-+ if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
-+ /*
-+ * Replace the definition.
-+ */
-+ xmlFree((char *) xmlCharEncodingAliases[i].name);
-+ xmlCharEncodingAliases[i].name = xmlMemStrdup(name);
-+ return(0);
-+ }
-+ }
-+ /*
-+ * Add the definition
-+ */
-+ xmlCharEncodingAliases[xmlCharEncodingAliasesNb].name = xmlMemStrdup(name);
-+ xmlCharEncodingAliases[xmlCharEncodingAliasesNb].alias = xmlMemStrdup(upper);
-+ xmlCharEncodingAliasesNb++;
-+ return(0);
-+}
-+
-+/**
-+ * xmlDelEncodingAlias:
-+ * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
-+ *
-+ * Unregisters an encoding alias @alias
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlDelEncodingAlias(const char *alias) {
-+ int i;
-+
-+ if (alias == NULL)
-+ return(-1);
-+
-+ if (xmlCharEncodingAliases == NULL)
-+ return(-1);
-+ /*
-+ * Walk down the list looking for a definition of the alias
-+ */
-+ for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
-+ if (!strcmp(xmlCharEncodingAliases[i].alias, alias)) {
-+ xmlFree((char *) xmlCharEncodingAliases[i].name);
-+ xmlFree((char *) xmlCharEncodingAliases[i].alias);
-+ xmlCharEncodingAliasesNb--;
-+ memmove(&xmlCharEncodingAliases[i], &xmlCharEncodingAliases[i + 1],
-+ sizeof(xmlCharEncodingAlias) * (xmlCharEncodingAliasesNb - i));
-+ return(0);
-+ }
-+ }
-+ return(-1);
-+}
-+
-+/**
-+ * xmlParseCharEncoding:
-+ * @name: the encoding name as parsed, in UTF-8 format (ASCII actually)
-+ *
-+ * Conpare the string to the known encoding schemes already known. Note
-+ * that the comparison is case insensitive accordingly to the section
-+ * [XML] 4.3.3 Character Encoding in Entities.
-+ *
-+ * Returns one of the XML_CHAR_ENCODING_... values or XML_CHAR_ENCODING_NONE
-+ * if not recognized.
-+ */
-+xmlCharEncoding
-+xmlParseCharEncoding(const char* name)
-+{
-+ const char *alias;
-+ char upper[500];
-+ int i;
-+
-+ if (name == NULL)
-+ return(XML_CHAR_ENCODING_NONE);
-+
-+ /*
-+ * Do the alias resolution
-+ */
-+ alias = xmlGetEncodingAlias(name);
-+ if (alias != NULL)
-+ name = alias;
-+
-+ for (i = 0;i < 499;i++) {
-+ upper[i] = toupper(name[i]);
-+ if (upper[i] == 0) break;
-+ }
-+ upper[i] = 0;
-+
-+ if (!strcmp(upper, "")) return(XML_CHAR_ENCODING_NONE);
-+ if (!strcmp(upper, "UTF-8")) return(XML_CHAR_ENCODING_UTF8);
-+ if (!strcmp(upper, "UTF8")) return(XML_CHAR_ENCODING_UTF8);
-+
-+ /*
-+ * NOTE: if we were able to parse this, the endianness of UTF16 is
-+ * already found and in use
-+ */
-+ if (!strcmp(upper, "UTF-16")) return(XML_CHAR_ENCODING_UTF16LE);
-+ if (!strcmp(upper, "UTF16")) return(XML_CHAR_ENCODING_UTF16LE);
-+
-+ if (!strcmp(upper, "ISO-10646-UCS-2")) return(XML_CHAR_ENCODING_UCS2);
-+ if (!strcmp(upper, "UCS-2")) return(XML_CHAR_ENCODING_UCS2);
-+ if (!strcmp(upper, "UCS2")) return(XML_CHAR_ENCODING_UCS2);
-+
-+ /*
-+ * NOTE: if we were able to parse this, the endianness of UCS4 is
-+ * already found and in use
-+ */
-+ if (!strcmp(upper, "ISO-10646-UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
-+ if (!strcmp(upper, "UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
-+ if (!strcmp(upper, "UCS4")) return(XML_CHAR_ENCODING_UCS4LE);
-+
-+
-+ if (!strcmp(upper, "ISO-8859-1")) return(XML_CHAR_ENCODING_8859_1);
-+ if (!strcmp(upper, "ISO-LATIN-1")) return(XML_CHAR_ENCODING_8859_1);
-+ if (!strcmp(upper, "ISO LATIN 1")) return(XML_CHAR_ENCODING_8859_1);
-+
-+ if (!strcmp(upper, "ISO-8859-2")) return(XML_CHAR_ENCODING_8859_2);
-+ if (!strcmp(upper, "ISO-LATIN-2")) return(XML_CHAR_ENCODING_8859_2);
-+ if (!strcmp(upper, "ISO LATIN 2")) return(XML_CHAR_ENCODING_8859_2);
-+
-+ if (!strcmp(upper, "ISO-8859-3")) return(XML_CHAR_ENCODING_8859_3);
-+ if (!strcmp(upper, "ISO-8859-4")) return(XML_CHAR_ENCODING_8859_4);
-+ if (!strcmp(upper, "ISO-8859-5")) return(XML_CHAR_ENCODING_8859_5);
-+ if (!strcmp(upper, "ISO-8859-6")) return(XML_CHAR_ENCODING_8859_6);
-+ if (!strcmp(upper, "ISO-8859-7")) return(XML_CHAR_ENCODING_8859_7);
-+ if (!strcmp(upper, "ISO-8859-8")) return(XML_CHAR_ENCODING_8859_8);
-+ if (!strcmp(upper, "ISO-8859-9")) return(XML_CHAR_ENCODING_8859_9);
-+
-+ if (!strcmp(upper, "ISO-2022-JP")) return(XML_CHAR_ENCODING_2022_JP);
-+ if (!strcmp(upper, "SHIFT_JIS")) return(XML_CHAR_ENCODING_SHIFT_JIS);
-+ if (!strcmp(upper, "EUC-JP")) return(XML_CHAR_ENCODING_EUC_JP);
-+
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext, "Unknown encoding %s\n", name);
-+#endif
-+ return(XML_CHAR_ENCODING_ERROR);
-+}
-+
-+/**
-+ * xmlGetCharEncodingName:
-+ * @enc: the encoding
-+ *
-+ * The "canonical" name for XML encoding.
-+ * C.f. http://www.w3.org/TR/REC-xml#charencoding
-+ * Section 4.3.3 Character Encoding in Entities
-+ *
-+ * Returns the canonical name for the given encoding
-+ */
-+
-+const char*
-+xmlGetCharEncodingName(xmlCharEncoding enc) {
-+ switch (enc) {
-+ case XML_CHAR_ENCODING_ERROR:
-+ return(NULL);
-+ case XML_CHAR_ENCODING_NONE:
-+ return(NULL);
-+ case XML_CHAR_ENCODING_UTF8:
-+ return("UTF-8");
-+ case XML_CHAR_ENCODING_UTF16LE:
-+ return("UTF-16");
-+ case XML_CHAR_ENCODING_UTF16BE:
-+ return("UTF-16");
-+ case XML_CHAR_ENCODING_EBCDIC:
-+ return("EBCDIC");
-+ case XML_CHAR_ENCODING_UCS4LE:
-+ return("ISO-10646-UCS-4");
-+ case XML_CHAR_ENCODING_UCS4BE:
-+ return("ISO-10646-UCS-4");
-+ case XML_CHAR_ENCODING_UCS4_2143:
-+ return("ISO-10646-UCS-4");
-+ case XML_CHAR_ENCODING_UCS4_3412:
-+ return("ISO-10646-UCS-4");
-+ case XML_CHAR_ENCODING_UCS2:
-+ return("ISO-10646-UCS-2");
-+ case XML_CHAR_ENCODING_8859_1:
-+ return("ISO-8859-1");
-+ case XML_CHAR_ENCODING_8859_2:
-+ return("ISO-8859-2");
-+ case XML_CHAR_ENCODING_8859_3:
-+ return("ISO-8859-3");
-+ case XML_CHAR_ENCODING_8859_4:
-+ return("ISO-8859-4");
-+ case XML_CHAR_ENCODING_8859_5:
-+ return("ISO-8859-5");
-+ case XML_CHAR_ENCODING_8859_6:
-+ return("ISO-8859-6");
-+ case XML_CHAR_ENCODING_8859_7:
-+ return("ISO-8859-7");
-+ case XML_CHAR_ENCODING_8859_8:
-+ return("ISO-8859-8");
-+ case XML_CHAR_ENCODING_8859_9:
-+ return("ISO-8859-9");
-+ case XML_CHAR_ENCODING_2022_JP:
-+ return("ISO-2022-JP");
-+ case XML_CHAR_ENCODING_SHIFT_JIS:
-+ return("Shift-JIS");
-+ case XML_CHAR_ENCODING_EUC_JP:
-+ return("EUC-JP");
-+ case XML_CHAR_ENCODING_ASCII:
-+ return(NULL);
-+ }
-+ return(NULL);
-+}
-+
-+/****************************************************************
-+ * *
-+ * Char encoding handlers *
-+ * *
-+ ****************************************************************/
-+
-+/* the size should be growable, but it's not a big deal ... */
-+#define MAX_ENCODING_HANDLERS 50
-+static xmlCharEncodingHandlerPtr *handlers = NULL;
-+static int nbCharEncodingHandler = 0;
-+
-+/*
-+ * The default is UTF-8 for XML, that's also the default used for the
-+ * parser internals, so the default encoding handler is NULL
-+ */
-+
-+static xmlCharEncodingHandlerPtr xmlDefaultCharEncodingHandler = NULL;
-+
-+/**
-+ * xmlNewCharEncodingHandler:
-+ * @name: the encoding name, in UTF-8 format (ASCII actually)
-+ * @input: the xmlCharEncodingInputFunc to read that encoding
-+ * @output: the xmlCharEncodingOutputFunc to write that encoding
-+ *
-+ * Create and registers an xmlCharEncodingHandler.
-+ * Returns the xmlCharEncodingHandlerPtr created (or NULL in case of error).
-+ */
-+xmlCharEncodingHandlerPtr
-+xmlNewCharEncodingHandler(const char *name,
-+ xmlCharEncodingInputFunc input,
-+ xmlCharEncodingOutputFunc output) {
-+ xmlCharEncodingHandlerPtr handler;
-+ const char *alias;
-+ char upper[500];
-+ int i;
-+ char *up = 0;
-+
-+ /*
-+ * Do the alias resolution
-+ */
-+ alias = xmlGetEncodingAlias(name);
-+ if (alias != NULL)
-+ name = alias;
-+
-+ /*
-+ * Keep only the uppercase version of the encoding.
-+ */
-+ if (name == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewCharEncodingHandler : no name !\n");
-+ return(NULL);
-+ }
-+ for (i = 0;i < 499;i++) {
-+ upper[i] = toupper(name[i]);
-+ if (upper[i] == 0) break;
-+ }
-+ upper[i] = 0;
-+ up = xmlMemStrdup(upper);
-+ if (up == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewCharEncodingHandler : out of memory !\n");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * allocate and fill-up an handler block.
-+ */
-+ handler = (xmlCharEncodingHandlerPtr)
-+ xmlMalloc(sizeof(xmlCharEncodingHandler));
-+ if (handler == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewCharEncodingHandler : out of memory !\n");
-+ return(NULL);
-+ }
-+ handler->input = input;
-+ handler->output = output;
-+ handler->name = up;
-+
-+#ifdef LIBXML_ICONV_ENABLED
-+ handler->iconv_in = NULL;
-+ handler->iconv_out = NULL;
-+#endif /* LIBXML_ICONV_ENABLED */
-+
-+ /*
-+ * registers and returns the handler.
-+ */
-+ xmlRegisterCharEncodingHandler(handler);
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Registered encoding handler for %s\n", name);
-+#endif
-+ return(handler);
-+}
-+
-+/**
-+ * xmlInitCharEncodingHandlers:
-+ *
-+ * Initialize the char encoding support, it registers the default
-+ * encoding supported.
-+ * NOTE: while public, this function usually doesn't need to be called
-+ * in normal processing.
-+ */
-+void
-+xmlInitCharEncodingHandlers(void) {
-+ unsigned short int tst = 0x1234;
-+ unsigned char *ptr = (unsigned char *) &tst;
-+
-+ if (handlers != NULL) return;
-+
-+ handlers = (xmlCharEncodingHandlerPtr *)
-+ xmlMalloc(MAX_ENCODING_HANDLERS * sizeof(xmlCharEncodingHandlerPtr));
-+
-+ if (*ptr == 0x12) xmlLittleEndian = 0;
-+ else if (*ptr == 0x34) xmlLittleEndian = 1;
-+ else xmlGenericError(xmlGenericErrorContext,
-+ "Odd problem at endianness detection\n");
-+
-+ if (handlers == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitCharEncodingHandlers : out of memory !\n");
-+ return;
-+ }
-+ xmlNewCharEncodingHandler("UTF-8", NULL, NULL);
-+ xmlUTF16LEHandler =
-+ xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, UTF8ToUTF16LE);
-+ xmlUTF16BEHandler =
-+ xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, UTF8ToUTF16BE);
-+ xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, UTF8Toisolat1);
-+ xmlNewCharEncodingHandler("ASCII", asciiToUTF8, UTF8Toascii);
-+#ifdef LIBXML_HTML_ENABLED
-+ xmlNewCharEncodingHandler("HTML", NULL, UTF8ToHtml);
-+#endif
-+}
-+
-+/**
-+ * xmlCleanupCharEncodingHandlers:
-+ *
-+ * Cleanup the memory allocated for the char encoding support, it
-+ * unregisters all the encoding handlers and the aliases.
-+ */
-+void
-+xmlCleanupCharEncodingHandlers(void) {
-+ xmlCleanupEncodingAliases();
-+
-+ if (handlers == NULL) return;
-+
-+ for (;nbCharEncodingHandler > 0;) {
-+ nbCharEncodingHandler--;
-+ if (handlers[nbCharEncodingHandler] != NULL) {
-+ if (handlers[nbCharEncodingHandler]->name != NULL)
-+ xmlFree(handlers[nbCharEncodingHandler]->name);
-+ xmlFree(handlers[nbCharEncodingHandler]);
-+ }
-+ }
-+ xmlFree(handlers);
-+ handlers = NULL;
-+ nbCharEncodingHandler = 0;
-+ xmlDefaultCharEncodingHandler = NULL;
-+}
-+
-+/**
-+ * xmlRegisterCharEncodingHandler:
-+ * @handler: the xmlCharEncodingHandlerPtr handler block
-+ *
-+ * Register the char encoding handler, surprizing, isn't it ?
-+ */
-+void
-+xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
-+ if (handlers == NULL) xmlInitCharEncodingHandlers();
-+ if (handler == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlRegisterCharEncodingHandler: NULL handler !\n");
-+ return;
-+ }
-+
-+ if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlRegisterCharEncodingHandler: Too many handler registered\n");
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\tincrease MAX_ENCODING_HANDLERS : %s\n", __FILE__);
-+ return;
-+ }
-+ handlers[nbCharEncodingHandler++] = handler;
-+}
-+
-+/**
-+ * xmlGetCharEncodingHandler:
-+ * @enc: an xmlCharEncoding value.
-+ *
-+ * Search in the registrered set the handler able to read/write that encoding.
-+ *
-+ * Returns the handler or NULL if not found
-+ */
-+xmlCharEncodingHandlerPtr
-+xmlGetCharEncodingHandler(xmlCharEncoding enc) {
-+ xmlCharEncodingHandlerPtr handler;
-+
-+ if (handlers == NULL) xmlInitCharEncodingHandlers();
-+ switch (enc) {
-+ case XML_CHAR_ENCODING_ERROR:
-+ return(NULL);
-+ case XML_CHAR_ENCODING_NONE:
-+ return(NULL);
-+ case XML_CHAR_ENCODING_UTF8:
-+ return(NULL);
-+ case XML_CHAR_ENCODING_UTF16LE:
-+ return(xmlUTF16LEHandler);
-+ case XML_CHAR_ENCODING_UTF16BE:
-+ return(xmlUTF16BEHandler);
-+ case XML_CHAR_ENCODING_EBCDIC:
-+ handler = xmlFindCharEncodingHandler("EBCDIC");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("ebcdic");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_UCS4BE:
-+ handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("UCS-4");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("UCS4");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_UCS4LE:
-+ handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("UCS-4");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("UCS4");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_UCS4_2143:
-+ break;
-+ case XML_CHAR_ENCODING_UCS4_3412:
-+ break;
-+ case XML_CHAR_ENCODING_UCS2:
-+ handler = xmlFindCharEncodingHandler("ISO-10646-UCS-2");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("UCS-2");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("UCS2");
-+ if (handler != NULL) return(handler);
-+ break;
-+
-+ /*
-+ * We used to keep ISO Latin encodings native in the
-+ * generated data. This led to so many problems that
-+ * this has been removed. One can still change this
-+ * back by registering no-ops encoders for those
-+ */
-+ case XML_CHAR_ENCODING_8859_1:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-1");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_2:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-2");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_3:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-3");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_4:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-4");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_5:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-5");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_6:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-6");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_7:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-7");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_8:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-8");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_8859_9:
-+ handler = xmlFindCharEncodingHandler("ISO-8859-9");
-+ if (handler != NULL) return(handler);
-+ break;
-+
-+
-+ case XML_CHAR_ENCODING_2022_JP:
-+ handler = xmlFindCharEncodingHandler("ISO-2022-JP");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_SHIFT_JIS:
-+ handler = xmlFindCharEncodingHandler("SHIFT-JIS");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("SHIFT_JIS");
-+ if (handler != NULL) return(handler);
-+ handler = xmlFindCharEncodingHandler("Shift_JIS");
-+ if (handler != NULL) return(handler);
-+ break;
-+ case XML_CHAR_ENCODING_EUC_JP:
-+ handler = xmlFindCharEncodingHandler("EUC-JP");
-+ if (handler != NULL) return(handler);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "No handler found for encoding %d\n", enc);
-+#endif
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlGetCharEncodingHandler:
-+ * @enc: a string describing the char encoding.
-+ *
-+ * Search in the registrered set the handler able to read/write that encoding.
-+ *
-+ * Returns the handler or NULL if not found
-+ */
-+xmlCharEncodingHandlerPtr
-+xmlFindCharEncodingHandler(const char *name) {
-+ const char *nalias;
-+ const char *norig;
-+ xmlCharEncoding alias;
-+#ifdef LIBXML_ICONV_ENABLED
-+ xmlCharEncodingHandlerPtr enc;
-+ iconv_t icv_in, icv_out;
-+#endif /* LIBXML_ICONV_ENABLED */
-+ char upper[100];
-+ int i;
-+
-+ if (handlers == NULL) xmlInitCharEncodingHandlers();
-+ if (name == NULL) return(xmlDefaultCharEncodingHandler);
-+ if (name[0] == 0) return(xmlDefaultCharEncodingHandler);
-+
-+ /*
-+ * Do the alias resolution
-+ */
-+ norig = name;
-+ nalias = xmlGetEncodingAlias(name);
-+ if (nalias != NULL)
-+ name = nalias;
-+
-+ /*
-+ * Check first for directly registered encoding names
-+ */
-+ for (i = 0;i < 99;i++) {
-+ upper[i] = toupper(name[i]);
-+ if (upper[i] == 0) break;
-+ }
-+ upper[i] = 0;
-+
-+ for (i = 0;i < nbCharEncodingHandler; i++)
-+ if (!strcmp(upper, handlers[i]->name)) {
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Found registered handler for encoding %s\n", name);
-+#endif
-+ return(handlers[i]);
-+ }
-+
-+#ifdef LIBXML_ICONV_ENABLED
-+ /* check whether iconv can handle this */
-+ icv_in = iconv_open("UTF-8", name);
-+ icv_out = iconv_open(name, "UTF-8");
-+ if ((icv_in != (iconv_t) -1) && (icv_out != (iconv_t) -1)) {
-+ enc = (xmlCharEncodingHandlerPtr)
-+ xmlMalloc(sizeof(xmlCharEncodingHandler));
-+ if (enc == NULL) {
-+ iconv_close(icv_in);
-+ iconv_close(icv_out);
-+ return(NULL);
-+ }
-+ enc->name = xmlMemStrdup(name);
-+ enc->input = NULL;
-+ enc->output = NULL;
-+ enc->iconv_in = icv_in;
-+ enc->iconv_out = icv_out;
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Found iconv handler for encoding %s\n", name);
-+#endif
-+ return enc;
-+ } else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "iconv : problems with filters for '%s'\n", name);
-+ }
-+#endif /* LIBXML_ICONV_ENABLED */
-+
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "No handler found for encoding %s\n", name);
-+#endif
-+
-+ /*
-+ * Fallback using the canonical names
-+ */
-+ alias = xmlParseCharEncoding(norig);
-+ if (alias != XML_CHAR_ENCODING_ERROR) {
-+ const char* canon;
-+ canon = xmlGetCharEncodingName(alias);
-+ if ((canon != NULL) && (strcmp(name, canon))) {
-+ return(xmlFindCharEncodingHandler(canon));
-+ }
-+ }
-+
-+ return(NULL);
-+}
-+
-+#ifdef LIBXML_ICONV_ENABLED
-+/**
-+ * xmlIconvWrapper:
-+ * @cd: iconv converter data structure
-+ * @out: a pointer to an array of bytes to store the result
-+ * @outlen: the length of @out
-+ * @in: a pointer to an array of ISO Latin 1 chars
-+ * @inlen: the length of @in
-+ *
-+ * Returns 0 if success, or
-+ * -1 by lack of space, or
-+ * -2 if the transcoding fails (for *in is not valid utf8 string or
-+ * the result of transformation can't fit into the encoding we want), or
-+ * -3 if there the last byte can't form a single output char.
-+ *
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+static int
-+xmlIconvWrapper(iconv_t cd,
-+ unsigned char *out, int *outlen,
-+ const unsigned char *in, int *inlen) {
-+
-+ size_t icv_inlen = *inlen, icv_outlen = *outlen;
-+ const char *icv_in = (const char *) in;
-+ char *icv_out = (char *) out;
-+ int ret;
-+
-+ ret = iconv(cd,
-+ &icv_in, &icv_inlen,
-+ &icv_out, &icv_outlen);
-+ if (in != NULL) {
-+ *inlen -= icv_inlen;
-+ *outlen -= icv_outlen;
-+ } else {
-+ *inlen = 0;
-+ *outlen = 0;
-+ }
-+ if (icv_inlen != 0 || ret == (size_t) -1) {
-+#ifdef EILSEQ
-+ if (errno == EILSEQ) {
-+ return -2;
-+ } else
-+#endif
-+#ifdef E2BIG
-+ if (errno == E2BIG) {
-+ return -1;
-+ } else
-+#endif
-+#ifdef EINVAL
-+ if (errno == EINVAL) {
-+ return -3;
-+ } else
-+#endif
-+ {
-+ return -3;
-+ }
-+ }
-+ return 0;
-+}
-+#endif /* LIBXML_ICONV_ENABLED */
-+
-+/**
-+ * xmlCharEncFirstLine:
-+ * @handler: char enconding transformation data structure
-+ * @out: an xmlBuffer for the output.
-+ * @in: an xmlBuffer for the input
-+ *
-+ * Front-end for the encoding handler input function, but handle only
-+ * the very first line, i.e. limit itself to 45 chars.
-+ *
-+ * Returns the number of byte written if success, or
-+ * -1 general error
-+ * -2 if the transcoding fails (for *in is not valid utf8 string or
-+ * the result of transformation can't fit into the encoding we want), or
-+ */
-+int
-+xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
-+ xmlBufferPtr in) {
-+ int ret = -2;
-+ int written;
-+ int toconv;
-+
-+ if (handler == NULL) return(-1);
-+ if (out == NULL) return(-1);
-+ if (in == NULL) return(-1);
-+
-+ written = out->size - out->use;
-+ toconv = in->use;
-+ if (toconv * 2 >= written) {
-+ xmlBufferGrow(out, toconv);
-+ written = out->size - out->use - 1;
-+ }
-+
-+ /*
-+ * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
-+ * 45 chars should be sufficient to reach the end of the encoding
-+ * decalration without going too far inside the document content.
-+ */
-+ written = 45;
-+
-+ if (handler->input != NULL) {
-+ ret = handler->input(&out->content[out->use], &written,
-+ in->content, &toconv);
-+ xmlBufferShrink(in, toconv);
-+ out->use += written;
-+ out->content[out->use] = 0;
-+ }
-+#ifdef LIBXML_ICONV_ENABLED
-+ else if (handler->iconv_in != NULL) {
-+ ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
-+ &written, in->content, &toconv);
-+ xmlBufferShrink(in, toconv);
-+ out->use += written;
-+ out->content[out->use] = 0;
-+ if (ret == -1) ret = -3;
-+ }
-+#endif /* LIBXML_ICONV_ENABLED */
-+#ifdef DEBUG_ENCODING
-+ switch (ret) {
-+ case 0:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "converted %d bytes to %d bytes of input\n",
-+ toconv, written);
-+ break;
-+ case -1:
-+ xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-+ toconv, written, in->use);
-+ break;
-+ case -2:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "input conversion failed due to input error\n");
-+ break;
-+ case -3:
-+ xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-+ toconv, written, in->use);
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,"Unknown input conversion failed %d\n", ret);
-+ }
-+#endif
-+ /*
-+ * Ignore when input buffer is not on a boundary
-+ */
-+ if (ret == -3) ret = 0;
-+ if (ret == -1) ret = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCharEncInFunc:
-+ * @handler: char enconding transformation data structure
-+ * @out: an xmlBuffer for the output.
-+ * @in: an xmlBuffer for the input
-+ *
-+ * Generic front-end for the encoding handler input function
-+ *
-+ * Returns the number of byte written if success, or
-+ * -1 general error
-+ * -2 if the transcoding fails (for *in is not valid utf8 string or
-+ * the result of transformation can't fit into the encoding we want), or
-+ */
-+int
-+xmlCharEncInFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
-+ xmlBufferPtr in) {
-+ int ret = -2;
-+ int written;
-+ int toconv;
-+
-+ if (handler == NULL) return(-1);
-+ if (out == NULL) return(-1);
-+ if (in == NULL) return(-1);
-+
-+ toconv = in->use;
-+ if (toconv == 0)
-+ return(0);
-+ written = out->size - out->use;
-+ if (toconv * 2 >= written) {
-+ xmlBufferGrow(out, out->size + toconv * 2);
-+ written = out->size - out->use - 1;
-+ }
-+ if (handler->input != NULL) {
-+ ret = handler->input(&out->content[out->use], &written,
-+ in->content, &toconv);
-+ xmlBufferShrink(in, toconv);
-+ out->use += written;
-+ out->content[out->use] = 0;
-+ }
-+#ifdef LIBXML_ICONV_ENABLED
-+ else if (handler->iconv_in != NULL) {
-+ ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
-+ &written, in->content, &toconv);
-+ xmlBufferShrink(in, toconv);
-+ out->use += written;
-+ out->content[out->use] = 0;
-+ if (ret == -1) ret = -3;
-+ }
-+#endif /* LIBXML_ICONV_ENABLED */
-+ switch (ret) {
-+#ifdef DEBUG_ENCODING
-+ case 0:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "converted %d bytes to %d bytes of input\n",
-+ toconv, written);
-+ break;
-+ case -1:
-+ xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-+ toconv, written, in->use);
-+ break;
-+ case -3:
-+ xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
-+ toconv, written, in->use);
-+ break;
-+#endif
-+ case -2:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "input conversion failed due to input error\n");
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ in->content[0], in->content[1],
-+ in->content[2], in->content[3]);
-+ }
-+ /*
-+ * Ignore when input buffer is not on a boundary
-+ */
-+ if (ret == -3) ret = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCharEncOutFunc:
-+ * @handler: char enconding transformation data structure
-+ * @out: an xmlBuffer for the output.
-+ * @in: an xmlBuffer for the input
-+ *
-+ * Generic front-end for the encoding handler output function
-+ * a first call with @in == NULL has to be made firs to initiate the
-+ * output in case of non-stateless encoding needing to initiate their
-+ * state or the output (like the BOM in UTF16).
-+ * In case of UTF8 sequence conversion errors for the given encoder,
-+ * the content will be automatically remapped to a CharRef sequence.
-+ *
-+ * Returns the number of byte written if success, or
-+ * -1 general error
-+ * -2 if the transcoding fails (for *in is not valid utf8 string or
-+ * the result of transformation can't fit into the encoding we want), or
-+ */
-+int
-+xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
-+ xmlBufferPtr in) {
-+ int ret = -2;
-+ int written;
-+ int writtentot = 0;
-+ int toconv;
-+ int output = 0;
-+
-+ if (handler == NULL) return(-1);
-+ if (out == NULL) return(-1);
-+
-+retry:
-+
-+ written = out->size - out->use;
-+
-+ /*
-+ * First specific handling of in = NULL, i.e. the initialization call
-+ */
-+ if (in == NULL) {
-+ toconv = 0;
-+ if (handler->output != NULL) {
-+ ret = handler->output(&out->content[out->use], &written,
-+ NULL, &toconv);
-+ out->use += written;
-+ out->content[out->use] = 0;
-+ }
-+#ifdef LIBXML_ICONV_ENABLED
-+ else if (handler->iconv_out != NULL) {
-+ ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
-+ &written, NULL, &toconv);
-+ out->use += written;
-+ out->content[out->use] = 0;
-+ }
-+#endif /* LIBXML_ICONV_ENABLED */
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "initialized encoder\n");
-+#endif
-+ return(0);
-+ }
-+
-+ /*
-+ * Convertion itself.
-+ */
-+ toconv = in->use;
-+ if (toconv == 0)
-+ return(0);
-+ if (toconv * 2 >= written) {
-+ xmlBufferGrow(out, toconv * 2);
-+ written = out->size - out->use - 1;
-+ }
-+ if (handler->output != NULL) {
-+ ret = handler->output(&out->content[out->use], &written,
-+ in->content, &toconv);
-+ xmlBufferShrink(in, toconv);
-+ out->use += written;
-+ writtentot += written;
-+ out->content[out->use] = 0;
-+ }
-+#ifdef LIBXML_ICONV_ENABLED
-+ else if (handler->iconv_out != NULL) {
-+ ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
-+ &written, in->content, &toconv);
-+ xmlBufferShrink(in, toconv);
-+ out->use += written;
-+ writtentot += written;
-+ out->content[out->use] = 0;
-+ if (ret == -1) {
-+ if (written > 0) {
-+ /*
-+ * Can be a limitation of iconv
-+ */
-+ goto retry;
-+ }
-+ ret = -3;
-+ }
-+ }
-+#endif /* LIBXML_ICONV_ENABLED */
-+ else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCharEncOutFunc: no output function !\n");
-+ return(-1);
-+ }
-+
-+ if (ret >= 0) output += ret;
-+
-+ /*
-+ * Attempt to handle error cases
-+ */
-+ switch (ret) {
-+#ifdef DEBUG_ENCODING
-+ case 0:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "converted %d bytes to %d bytes of output\n",
-+ toconv, written);
-+ break;
-+ case -1:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "output conversion failed by lack of space\n");
-+ break;
-+#endif
-+ case -3:
-+ xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n",
-+ toconv, written, in->use);
-+ break;
-+ case -2: {
-+ int len = in->use;
-+ const xmlChar *utf = (const xmlChar *) in->content;
-+ int cur;
-+
-+ cur = xmlGetUTF8Char(utf, &len);
-+ if (cur > 0) {
-+ xmlChar charref[20];
-+
-+#ifdef DEBUG_ENCODING
-+ xmlGenericError(xmlGenericErrorContext,
-+ "handling output conversion error\n");
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ in->content[0], in->content[1],
-+ in->content[2], in->content[3]);
-+#endif
-+ /*
-+ * Removes the UTF8 sequence, and replace it by a charref
-+ * and continue the transcoding phase, hoping the error
-+ * did not mangle the encoder state.
-+ */
-+ sprintf((char *) charref, "&#x%X;", cur);
-+ xmlBufferShrink(in, len);
-+ xmlBufferAddHead(in, charref, -1);
-+
-+ goto retry;
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "output conversion failed due to conv error\n");
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ in->content[0], in->content[1],
-+ in->content[2], in->content[3]);
-+ in->content[0] = ' ';
-+ }
-+ break;
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCharEncCloseFunc:
-+ * @handler: char enconding transformation data structure
-+ *
-+ * Generic front-end for hencoding handler close function
-+ *
-+ * Returns 0 if success, or -1 in case of error
-+ */
-+int
-+xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
-+ int ret = 0;
-+ if (handler == NULL) return(-1);
-+ if (handler->name == NULL) return(-1);
-+#ifdef LIBXML_ICONV_ENABLED
-+ /*
-+ * Iconv handlers can be oused only once, free the whole block.
-+ * and the associated icon resources.
-+ */
-+ if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
-+ if (handler->name != NULL)
-+ xmlFree(handler->name);
-+ handler->name = NULL;
-+ if (handler->iconv_out != NULL) {
-+ if (iconv_close(handler->iconv_out))
-+ ret = -1;
-+ handler->iconv_out = NULL;
-+ }
-+ if (handler->iconv_in != NULL) {
-+ if (iconv_close(handler->iconv_in))
-+ ret = -1;
-+ handler->iconv_in = NULL;
-+ }
-+ xmlFree(handler);
-+ }
-+#endif /* LIBXML_ICONV_ENABLED */
-+#ifdef DEBUG_ENCODING
-+ if (ret)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "failed to close the encoding handler\n");
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "closed the encoding handler\n");
-+
-+#endif
-+ return(ret);
-+}
-+
-diff -Nru libxml2-2.3.0/libxml/encoding.h libxml2-2.3.0.new/libxml/encoding.h
---- libxml2-2.3.0/libxml/encoding.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/encoding.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,187 @@
-+/*
-+ * encoding.h : interface for the encoding conversion functions needed for
-+ * XML
-+ *
-+ * Related specs:
-+ * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
-+ * [ISO-10646] UTF-8 and UTF-16 in Annexes
-+ * [ISO-8859-1] ISO Latin-1 characters codes.
-+ * [UNICODE] The Unicode Consortium, "The Unicode Standard --
-+ * Worldwide Character Encoding -- Version 1.0", Addison-
-+ * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
-+ * described in Unicode Technical Report #4.
-+ * [US-ASCII] Coded Character Set--7-bit American Standard Code for
-+ * Information Interchange, ANSI X3.4-1986.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_CHAR_ENCODING_H__
-+#define __XML_CHAR_ENCODING_H__
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_ICONV_ENABLED
-+#include <iconv.h>
-+#endif
-+#include <libxml/tree.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/**
-+ * Predefined values for some standard encodings
-+ * Libxml don't do beforehand translation on UTF8, ISOLatinX
-+ * It also support UTF16 (LE and BE) by default.
-+ *
-+ * Anything else would have to be translated to UTF8 before being
-+ * given to the parser itself. The BOM for UTF16 and the encoding
-+ * declaration are looked at and a converter is looked for at that
-+ * point. If not found the parser stops here as asked by the XML REC
-+ * Converter can be registered by the user using xmlRegisterCharEncodingHandler
-+ * but the currentl form doesn't allow stateful transcoding (a serious
-+ * problem agreed !). If iconv has been found it will be used
-+ * automatically and allow stateful transcoding, the simplest is then
-+ * to be sure to enable icon and to provide iconv libs for the encoding
-+ * support needed.
-+ */
-+typedef enum {
-+ XML_CHAR_ENCODING_ERROR= -1, /* No char encoding detected */
-+ XML_CHAR_ENCODING_NONE= 0, /* No char encoding detected */
-+ XML_CHAR_ENCODING_UTF8= 1, /* UTF-8 */
-+ XML_CHAR_ENCODING_UTF16LE= 2, /* UTF-16 little endian */
-+ XML_CHAR_ENCODING_UTF16BE= 3, /* UTF-16 big endian */
-+ XML_CHAR_ENCODING_UCS4LE= 4, /* UCS-4 little endian */
-+ XML_CHAR_ENCODING_UCS4BE= 5, /* UCS-4 big endian */
-+ XML_CHAR_ENCODING_EBCDIC= 6, /* EBCDIC uh! */
-+ XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */
-+ XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */
-+ XML_CHAR_ENCODING_UCS2= 9, /* UCS-2 */
-+ XML_CHAR_ENCODING_8859_1= 10,/* ISO-8859-1 ISO Latin 1 */
-+ XML_CHAR_ENCODING_8859_2= 11,/* ISO-8859-2 ISO Latin 2 */
-+ XML_CHAR_ENCODING_8859_3= 12,/* ISO-8859-3 */
-+ XML_CHAR_ENCODING_8859_4= 13,/* ISO-8859-4 */
-+ XML_CHAR_ENCODING_8859_5= 14,/* ISO-8859-5 */
-+ XML_CHAR_ENCODING_8859_6= 15,/* ISO-8859-6 */
-+ XML_CHAR_ENCODING_8859_7= 16,/* ISO-8859-7 */
-+ XML_CHAR_ENCODING_8859_8= 17,/* ISO-8859-8 */
-+ XML_CHAR_ENCODING_8859_9= 18,/* ISO-8859-9 */
-+ XML_CHAR_ENCODING_2022_JP= 19,/* ISO-2022-JP */
-+ XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */
-+ XML_CHAR_ENCODING_EUC_JP= 21,/* EUC-JP */
-+ XML_CHAR_ENCODING_ASCII= 22 /* pure ASCII */
-+} xmlCharEncoding;
-+
-+/**
-+ * xmlCharEncodingInputFunc:
-+ * @out: a pointer ot an array of bytes to store the UTF-8 result
-+ * @outlen: the lenght of @out
-+ * @in: a pointer ot an array of chars in the original encoding
-+ * @inlen: the lenght of @in
-+ *
-+ * Take a block of chars in the original encoding and try to convert
-+ * it to an UTF-8 block of chars out.
-+ *
-+ * Returns the number of byte written, or -1 by lack of space, or -2
-+ * if the transcoding failed.
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+typedef int (* xmlCharEncodingInputFunc)(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen);
-+
-+
-+/**
-+ * xmlCharEncodingOutputFunc:
-+ * @out: a pointer ot an array of bytes to store the result
-+ * @outlen: the lenght of @out
-+ * @in: a pointer ot an array of UTF-8 chars
-+ * @inlen: the lenght of @in
-+ *
-+ * Take a block of UTF-8 chars in and try to convert it to an other
-+ * encoding.
-+ * Note: a first call designed to produce heading info is called with
-+ * in = NULL. If stateful this should also initialize the encoder state
-+ *
-+ * Returns the number of byte written, or -1 by lack of space, or -2
-+ * if the transcoding failed.
-+ * The value of @inlen after return is the number of octets consumed
-+ * as the return value is positive, else unpredictiable.
-+ * The value of @outlen after return is the number of ocetes consumed.
-+ */
-+typedef int (* xmlCharEncodingOutputFunc)(unsigned char* out, int *outlen,
-+ const unsigned char* in, int *inlen);
-+
-+
-+/*
-+ * Block defining the handlers for non UTF-8 encodings.
-+ * If iconv is supported, there is two extra fields
-+ */
-+
-+typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
-+typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
-+struct _xmlCharEncodingHandler {
-+ char *name;
-+ xmlCharEncodingInputFunc input;
-+ xmlCharEncodingOutputFunc output;
-+#ifdef LIBXML_ICONV_ENABLED
-+ iconv_t iconv_in;
-+ iconv_t iconv_out;
-+#endif /* LIBXML_ICONV_ENABLED */
-+};
-+
-+/*
-+ * Interfaces for encoding handlers
-+ */
-+void xmlInitCharEncodingHandlers (void);
-+void xmlCleanupCharEncodingHandlers (void);
-+void xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler);
-+xmlCharEncodingHandlerPtr
-+ xmlGetCharEncodingHandler (xmlCharEncoding enc);
-+xmlCharEncodingHandlerPtr
-+ xmlFindCharEncodingHandler (const char *name);
-+
-+
-+/*
-+ * Interfaces for encoding names and aliases
-+ */
-+int xmlAddEncodingAlias (const char *name,
-+ const char *alias);
-+int xmlDelEncodingAlias (const char *alias);
-+const char *
-+ xmlGetEncodingAlias (const char *alias);
-+void xmlCleanupEncodingAliases (void);
-+xmlCharEncoding
-+ xmlParseCharEncoding (const char* name);
-+const char*
-+ xmlGetCharEncodingName (xmlCharEncoding enc);
-+
-+/*
-+ * Interfaces directly used by the parsers.
-+ */
-+xmlCharEncoding
-+ xmlDetectCharEncoding (const unsigned char* in,
-+ int len);
-+
-+int xmlCheckUTF8 (const unsigned char *utf);
-+
-+int xmlCharEncOutFunc (xmlCharEncodingHandler *handler,
-+ xmlBufferPtr out,
-+ xmlBufferPtr in);
-+
-+int xmlCharEncInFunc (xmlCharEncodingHandler *handler,
-+ xmlBufferPtr out,
-+ xmlBufferPtr in);
-+int xmlCharEncFirstLine (xmlCharEncodingHandler *handler,
-+ xmlBufferPtr out,
-+ xmlBufferPtr in);
-+int xmlCharEncCloseFunc (xmlCharEncodingHandler *handler);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __XML_CHAR_ENCODING_H__ */
-diff -Nru libxml2-2.3.0/libxml/entities.c libxml2-2.3.0.new/libxml/entities.c
---- libxml2-2.3.0/libxml/entities.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/entities.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,1034 @@
-+/*
-+ * entities.c : implementation for the XML entities handking
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#include <libxml/xmlmemory.h>
-+#include <libxml/hash.h>
-+#include <libxml/entities.h>
-+#include <libxml/parser.h>
-+#include <libxml/xmlerror.h>
-+
-+#define DEBUG_ENT_REF /* debugging of cross entities dependancies */
-+#define ENTITY_HASH_SIZE 256 /* modify xmlEntityComputeHash accordingly */
-+
-+/*
-+ * xmlEntityComputeHash:
-+ *
-+ * Computes the hash value for this given entity
-+ */
-+int
-+xmlEntityComputeHash(const xmlChar *name) {
-+ register const unsigned char *cur = (const unsigned char *) name;
-+ register unsigned char val = 0;
-+
-+ if (name == NULL)
-+ return(val);
-+ while (*cur) val += *cur++;
-+ return(val);
-+}
-+
-+/*
-+ * The XML predefined entities.
-+ */
-+
-+struct xmlPredefinedEntityValue {
-+ const char *name;
-+ const char *value;
-+};
-+struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
-+ { "lt", "<" },
-+ { "gt", ">" },
-+ { "apos", "'" },
-+ { "quot", "\"" },
-+ { "amp", "&" }
-+};
-+
-+/*
-+ * TODO: !!!!!!! This is GROSS, allocation of a 256 entry hash for
-+ * a fixed number of 4 elements !
-+ */
-+xmlHashTablePtr xmlPredefinedEntities = NULL;
-+
-+/*
-+ * xmlFreeEntity : clean-up an entity record.
-+ */
-+void xmlFreeEntity(xmlEntityPtr entity) {
-+ if (entity == NULL) return;
-+
-+ if (entity->children)
-+ xmlFreeNodeList(entity->children);
-+ if (entity->name != NULL)
-+ xmlFree((char *) entity->name);
-+ if (entity->ExternalID != NULL)
-+ xmlFree((char *) entity->ExternalID);
-+ if (entity->SystemID != NULL)
-+ xmlFree((char *) entity->SystemID);
-+ if (entity->URI != NULL)
-+ xmlFree((char *) entity->URI);
-+ if (entity->content != NULL)
-+ xmlFree((char *) entity->content);
-+ if (entity->orig != NULL)
-+ xmlFree((char *) entity->orig);
-+ memset(entity, -1, sizeof(xmlEntity));
-+ xmlFree(entity);
-+}
-+
-+/*
-+ * xmlAddEntity : register a new entity for an entities table.
-+ */
-+static xmlEntityPtr
-+xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
-+ const xmlChar *ExternalID, const xmlChar *SystemID,
-+ const xmlChar *content) {
-+ xmlEntitiesTablePtr table = NULL;
-+ xmlEntityPtr ret;
-+
-+ if (name == NULL)
-+ return(NULL);
-+ switch (type) {
-+ case XML_INTERNAL_GENERAL_ENTITY:
-+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-+ if (dtd->entities == NULL)
-+ dtd->entities = xmlHashCreate(0);
-+ table = dtd->entities;
-+ break;
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ if (dtd->pentities == NULL)
-+ dtd->pentities = xmlHashCreate(0);
-+ table = dtd->pentities;
-+ break;
-+ case XML_INTERNAL_PREDEFINED_ENTITY:
-+ if (xmlPredefinedEntities == NULL)
-+ xmlPredefinedEntities = xmlHashCreate(8);
-+ table = xmlPredefinedEntities;
-+ }
-+ if (table == NULL)
-+ return(NULL);
-+ ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddEntity: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlEntity));
-+ ret->type = XML_ENTITY_DECL;
-+
-+ /*
-+ * fill the structure.
-+ */
-+ ret->name = xmlStrdup(name);
-+ ret->etype = (xmlEntityType) type;
-+ if (ExternalID != NULL)
-+ ret->ExternalID = xmlStrdup(ExternalID);
-+ if (SystemID != NULL)
-+ ret->SystemID = xmlStrdup(SystemID);
-+ if (content != NULL) {
-+ ret->length = xmlStrlen(content);
-+ ret->content = xmlStrndup(content, ret->length);
-+ } else {
-+ ret->length = 0;
-+ ret->content = NULL;
-+ }
-+ ret->URI = NULL; /* to be computed by the layer knowing
-+ the defining entity */
-+ ret->orig = NULL;
-+
-+ if (xmlHashAddEntry(table, name, ret)) {
-+ /*
-+ * entity was already defined at another level.
-+ */
-+ xmlFreeEntity(ret);
-+ return(NULL);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlInitializePredefinedEntities:
-+ *
-+ * Set up the predefined entities.
-+ */
-+void xmlInitializePredefinedEntities(void) {
-+ int i;
-+ xmlChar name[50];
-+ xmlChar value[50];
-+ const char *in;
-+ xmlChar *out;
-+
-+ if (xmlPredefinedEntities != NULL) return;
-+
-+ xmlPredefinedEntities = xmlCreateEntitiesTable();
-+ for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
-+ sizeof(xmlPredefinedEntityValues[0]);i++) {
-+ in = xmlPredefinedEntityValues[i].name;
-+ out = &name[0];
-+ for (;(*out++ = (xmlChar) *in);)in++;
-+ in = xmlPredefinedEntityValues[i].value;
-+ out = &value[0];
-+ for (;(*out++ = (xmlChar) *in);)in++;
-+
-+ xmlAddEntity(NULL, (const xmlChar *) &name[0],
-+ XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
-+ &value[0]);
-+ }
-+}
-+
-+/**
-+ * xmlCleanupPredefinedEntities:
-+ *
-+ * Cleanup up the predefined entities table.
-+ */
-+void xmlCleanupPredefinedEntities(void) {
-+ if (xmlPredefinedEntities == NULL) return;
-+
-+ xmlFreeEntitiesTable(xmlPredefinedEntities);
-+ xmlPredefinedEntities = NULL;
-+}
-+
-+/**
-+ * xmlGetPredefinedEntity:
-+ * @name: the entity name
-+ *
-+ * Check whether this name is an predefined entity.
-+ *
-+ * Returns NULL if not, othervise the entity
-+ */
-+xmlEntityPtr
-+xmlGetPredefinedEntity(const xmlChar *name) {
-+ if (xmlPredefinedEntities == NULL)
-+ xmlInitializePredefinedEntities();
-+ return((xmlEntityPtr) xmlHashLookup(xmlPredefinedEntities, name));
-+}
-+
-+/**
-+ * xmlAddDtdEntity:
-+ * @doc: the document
-+ * @name: the entity name
-+ * @type: the entity type XML_xxx_yyy_ENTITY
-+ * @ExternalID: the entity external ID if available
-+ * @SystemID: the entity system ID if available
-+ * @content: the entity content
-+ *
-+ * Register a new entity for this document DTD external subset.
-+ *
-+ * Returns a pointer to the entity or NULL in case of error
-+ */
-+xmlEntityPtr
-+xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
-+ const xmlChar *ExternalID, const xmlChar *SystemID,
-+ const xmlChar *content) {
-+ xmlEntityPtr ret;
-+ xmlDtdPtr dtd;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddDtdEntity: doc == NULL !\n");
-+ return(NULL);
-+ }
-+ if (doc->extSubset == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddDtdEntity: document without external subset !\n");
-+ return(NULL);
-+ }
-+ dtd = doc->extSubset;
-+ ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
-+ if (ret == NULL) return(NULL);
-+
-+ /*
-+ * Link it to the Dtd
-+ */
-+ ret->parent = dtd;
-+ ret->doc = dtd->doc;
-+ if (dtd->last == NULL) {
-+ dtd->children = dtd->last = (xmlNodePtr) ret;
-+ } else {
-+ dtd->last->next = (xmlNodePtr) ret;
-+ ret->prev = dtd->last;
-+ dtd->last = (xmlNodePtr) ret;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlAddDocEntity:
-+ * @doc: the document
-+ * @name: the entity name
-+ * @type: the entity type XML_xxx_yyy_ENTITY
-+ * @ExternalID: the entity external ID if available
-+ * @SystemID: the entity system ID if available
-+ * @content: the entity content
-+ *
-+ * Register a new entity for this document.
-+ *
-+ * Returns a pointer to the entity or NULL in case of error
-+ */
-+xmlEntityPtr
-+xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
-+ const xmlChar *ExternalID, const xmlChar *SystemID,
-+ const xmlChar *content) {
-+ xmlEntityPtr ret;
-+ xmlDtdPtr dtd;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddDocEntity: document is NULL !\n");
-+ return(NULL);
-+ }
-+ if (doc->intSubset == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddDtdEntity: document without internal subset !\n");
-+ return(NULL);
-+ }
-+ dtd = doc->intSubset;
-+ ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
-+ if (ret == NULL) return(NULL);
-+
-+ /*
-+ * Link it to the Dtd
-+ */
-+ ret->parent = dtd;
-+ ret->doc = dtd->doc;
-+ if (dtd->last == NULL) {
-+ dtd->children = dtd->last = (xmlNodePtr) ret;
-+ } else {
-+ dtd->last->next = (xmlNodePtr) ret;
-+ ret->prev = dtd->last;
-+ dtd->last = (xmlNodePtr) ret;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlGetEntityFromTable:
-+ * @table: an entity table
-+ * @name: the entity name
-+ * @parameter: look for parameter entities
-+ *
-+ * Do an entity lookup in the table.
-+ * returns the corresponding parameter entity, if found.
-+ *
-+ * Returns A pointer to the entity structure or NULL if not found.
-+ */
-+xmlEntityPtr
-+xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) {
-+ return((xmlEntityPtr) xmlHashLookup(table, name));
-+}
-+
-+/**
-+ * xmlGetParameterEntity:
-+ * @doc: the document referencing the entity
-+ * @name: the entity name
-+ *
-+ * Do an entity lookup in the internal and external subsets and
-+ * returns the corresponding parameter entity, if found.
-+ *
-+ * Returns A pointer to the entity structure or NULL if not found.
-+ */
-+xmlEntityPtr
-+xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
-+ xmlEntitiesTablePtr table;
-+ xmlEntityPtr ret;
-+
-+ if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) {
-+ table = (xmlEntitiesTablePtr) doc->intSubset->pentities;
-+ ret = xmlGetEntityFromTable(table, name);
-+ if (ret != NULL)
-+ return(ret);
-+ }
-+ if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) {
-+ table = (xmlEntitiesTablePtr) doc->extSubset->pentities;
-+ return(xmlGetEntityFromTable(table, name));
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlGetDtdEntity:
-+ * @doc: the document referencing the entity
-+ * @name: the entity name
-+ *
-+ * Do an entity lookup in the Dtd entity hash table and
-+ * returns the corresponding entity, if found.
-+ *
-+ * Returns A pointer to the entity structure or NULL if not found.
-+ */
-+xmlEntityPtr
-+xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
-+ xmlEntitiesTablePtr table;
-+
-+ if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-+ table = (xmlEntitiesTablePtr) doc->extSubset->entities;
-+ return(xmlGetEntityFromTable(table, name));
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlGetDocEntity:
-+ * @doc: the document referencing the entity
-+ * @name: the entity name
-+ *
-+ * Do an entity lookup in the document entity hash table and
-+ * returns the corrsponding entity, otherwise a lookup is done
-+ * in the predefined entities too.
-+ *
-+ * Returns A pointer to the entity structure or NULL if not found.
-+ */
-+xmlEntityPtr
-+xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
-+ xmlEntityPtr cur;
-+ xmlEntitiesTablePtr table;
-+
-+ if (doc != NULL) {
-+ if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
-+ table = (xmlEntitiesTablePtr) doc->intSubset->entities;
-+ cur = xmlGetEntityFromTable(table, name);
-+ if (cur != NULL)
-+ return(cur);
-+ }
-+ if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-+ table = (xmlEntitiesTablePtr) doc->extSubset->entities;
-+ cur = xmlGetEntityFromTable(table, name);
-+ if (cur != NULL)
-+ return(cur);
-+ }
-+ }
-+ if (xmlPredefinedEntities == NULL)
-+ xmlInitializePredefinedEntities();
-+ table = xmlPredefinedEntities;
-+ return(xmlGetEntityFromTable(table, name));
-+}
-+
-+/*
-+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-+ * | [#x10000-#x10FFFF]
-+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
-+ */
-+#define IS_CHAR(c) \
-+ (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
-+ (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
-+
-+/*
-+ * A buffer used for converting entities to their equivalent and back.
-+ */
-+static int buffer_size = 0;
-+static xmlChar *buffer = NULL;
-+
-+int growBuffer(void) {
-+ buffer_size *= 2;
-+ buffer = (xmlChar *) xmlRealloc(buffer, buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("realloc failed");
-+ return(-1);
-+ }
-+ return(0);
-+}
-+
-+
-+/**
-+ * xmlEncodeEntities:
-+ * @doc: the document containing the string
-+ * @input: A string to convert to XML.
-+ *
-+ * Do a global encoding of a string, replacing the predefined entities
-+ * and non ASCII values with their entities and CharRef counterparts.
-+ *
-+ * TODO: remove xmlEncodeEntities, once we are not afraid of breaking binary
-+ * compatibility
-+ *
-+ * People must migrate their code to xmlEncodeEntitiesReentrant !
-+ * This routine will issue a warning when encountered.
-+ *
-+ * Returns A newly allocated string with the substitution done.
-+ */
-+const xmlChar *
-+xmlEncodeEntities(xmlDocPtr doc, const xmlChar *input) {
-+ const xmlChar *cur = input;
-+ xmlChar *out = buffer;
-+ static int warning = 1;
-+ int html = 0;
-+
-+
-+ if (warning) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Deprecated API xmlEncodeEntities() used\n");
-+ xmlGenericError(xmlGenericErrorContext,
-+ " change code to use xmlEncodeEntitiesReentrant()\n");
-+ warning = 0;
-+ }
-+
-+ if (input == NULL) return(NULL);
-+ if (doc != NULL)
-+ html = (doc->type == XML_HTML_DOCUMENT_NODE);
-+
-+ if (buffer == NULL) {
-+ buffer_size = 1000;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("malloc failed");
-+ return(NULL);
-+ }
-+ out = buffer;
-+ }
-+ while (*cur != '\0') {
-+ if (out - buffer > buffer_size - 100) {
-+ int index = out - buffer;
-+
-+ growBuffer();
-+ out = &buffer[index];
-+ }
-+
-+ /*
-+ * By default one have to encode at least '<', '>', '"' and '&' !
-+ */
-+ if (*cur == '<') {
-+ *out++ = '&';
-+ *out++ = 'l';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if (*cur == '>') {
-+ *out++ = '&';
-+ *out++ = 'g';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if (*cur == '&') {
-+ *out++ = '&';
-+ *out++ = 'a';
-+ *out++ = 'm';
-+ *out++ = 'p';
-+ *out++ = ';';
-+ } else if (*cur == '"') {
-+ *out++ = '&';
-+ *out++ = 'q';
-+ *out++ = 'u';
-+ *out++ = 'o';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if ((*cur == '\'') && (!html)) {
-+ *out++ = '&';
-+ *out++ = 'a';
-+ *out++ = 'p';
-+ *out++ = 'o';
-+ *out++ = 's';
-+ *out++ = ';';
-+ } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
-+ (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
-+ /*
-+ * default case, just copy !
-+ */
-+ *out++ = *cur;
-+#ifndef USE_UTF_8
-+ } else if ((sizeof(xmlChar) == 1) && (*cur >= 0x80)) {
-+ char buf[10], *ptr;
-+
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "&#%d;", *cur);
-+#else
-+ sprintf(buf, "&#%d;", *cur);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ ptr = buf;
-+ while (*ptr != 0) *out++ = *ptr++;
-+#endif
-+ } else if (IS_CHAR(*cur)) {
-+ char buf[10], *ptr;
-+
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "&#%d;", *cur);
-+#else
-+ sprintf(buf, "&#%d;", *cur);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ ptr = buf;
-+ while (*ptr != 0) *out++ = *ptr++;
-+ }
-+#if 0
-+ else {
-+ /*
-+ * default case, this is not a valid char !
-+ * Skip it...
-+ */
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlEncodeEntities: invalid char %d\n", (int) *cur);
-+ }
-+#endif
-+ cur++;
-+ }
-+ *out++ = 0;
-+ return(buffer);
-+}
-+
-+/*
-+ * Macro used to grow the current buffer.
-+ */
-+#define growBufferReentrant() { \
-+ buffer_size *= 2; \
-+ buffer = (xmlChar *) \
-+ xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
-+ if (buffer == NULL) { \
-+ perror("realloc failed"); \
-+ return(NULL); \
-+ } \
-+}
-+
-+
-+/**
-+ * xmlEncodeEntitiesReentrant:
-+ * @doc: the document containing the string
-+ * @input: A string to convert to XML.
-+ *
-+ * Do a global encoding of a string, replacing the predefined entities
-+ * and non ASCII values with their entities and CharRef counterparts.
-+ * Contrary to xmlEncodeEntities, this routine is reentrant, and result
-+ * must be deallocated.
-+ *
-+ * Returns A newly allocated string with the substitution done.
-+ */
-+xmlChar *
-+xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
-+ const xmlChar *cur = input;
-+ xmlChar *buffer = NULL;
-+ xmlChar *out = NULL;
-+ int buffer_size = 0;
-+ int html = 0;
-+
-+ if (input == NULL) return(NULL);
-+ if (doc != NULL)
-+ html = (doc->type == XML_HTML_DOCUMENT_NODE);
-+
-+ /*
-+ * allocate an translation buffer.
-+ */
-+ buffer_size = 1000;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("malloc failed");
-+ return(NULL);
-+ }
-+ out = buffer;
-+
-+ while (*cur != '\0') {
-+ if (out - buffer > buffer_size - 100) {
-+ int index = out - buffer;
-+
-+ growBufferReentrant();
-+ out = &buffer[index];
-+ }
-+
-+ /*
-+ * By default one have to encode at least '<', '>', '"' and '&' !
-+ */
-+ if (*cur == '<') {
-+ *out++ = '&';
-+ *out++ = 'l';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if (*cur == '>') {
-+ *out++ = '&';
-+ *out++ = 'g';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if (*cur == '&') {
-+ *out++ = '&';
-+ *out++ = 'a';
-+ *out++ = 'm';
-+ *out++ = 'p';
-+ *out++ = ';';
-+ } else if (*cur == '"') {
-+ *out++ = '&';
-+ *out++ = 'q';
-+ *out++ = 'u';
-+ *out++ = 'o';
-+ *out++ = 't';
-+ *out++ = ';';
-+#if 0
-+ } else if ((*cur == '\'') && (!html)) {
-+ *out++ = '&';
-+ *out++ = 'a';
-+ *out++ = 'p';
-+ *out++ = 'o';
-+ *out++ = 's';
-+ *out++ = ';';
-+#endif
-+ } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
-+ (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
-+ /*
-+ * default case, just copy !
-+ */
-+ *out++ = *cur;
-+ } else if (*cur >= 0x80) {
-+ if ((doc->encoding != NULL) || (html)) {
-+ /*
-+ * Bjørn Reese <br@sseusa.com> provided the patch
-+ xmlChar xc;
-+ xc = (*cur & 0x3F) << 6;
-+ if (cur[1] != 0) {
-+ xc += *(++cur) & 0x3F;
-+ *out++ = xc;
-+ } else
-+ */
-+ *out++ = *cur;
-+ } else {
-+ /*
-+ * We assume we have UTF-8 input.
-+ */
-+ char buf[10], *ptr;
-+ int val = 0, l = 1;
-+
-+ if (*cur < 0xC0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlEncodeEntitiesReentrant : input not UTF-8\n");
-+ doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "&#%d;", *cur);
-+#else
-+ sprintf(buf, "&#%d;", *cur);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ ptr = buf;
-+ while (*ptr != 0) *out++ = *ptr++;
-+ continue;
-+ } else if (*cur < 0xE0) {
-+ val = (cur[0]) & 0x1F;
-+ val <<= 6;
-+ val |= (cur[1]) & 0x3F;
-+ l = 2;
-+ } else if (*cur < 0xF0) {
-+ val = (cur[0]) & 0x0F;
-+ val <<= 6;
-+ val |= (cur[1]) & 0x3F;
-+ val <<= 6;
-+ val |= (cur[2]) & 0x3F;
-+ l = 3;
-+ } else if (*cur < 0xF8) {
-+ val = (cur[0]) & 0x07;
-+ val <<= 6;
-+ val |= (cur[1]) & 0x3F;
-+ val <<= 6;
-+ val |= (cur[2]) & 0x3F;
-+ val <<= 6;
-+ val |= (cur[3]) & 0x3F;
-+ l = 4;
-+ }
-+ if ((l == 1) || (!IS_CHAR(val))) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlEncodeEntitiesReentrant : char out of range\n");
-+ doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "&#%d;", *cur);
-+#else
-+ sprintf(buf, "&#%d;", *cur);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ ptr = buf;
-+ while (*ptr != 0) *out++ = *ptr++;
-+ cur++;
-+ continue;
-+ }
-+ /*
-+ * We could do multiple things here. Just save as a char ref
-+ */
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "&#x%X;", val);
-+#else
-+ sprintf(buf, "&#x%X;", val);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ ptr = buf;
-+ while (*ptr != 0) *out++ = *ptr++;
-+ cur += l;
-+ continue;
-+ }
-+ } else if (IS_CHAR(*cur)) {
-+ char buf[10], *ptr;
-+
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "&#%d;", *cur);
-+#else
-+ sprintf(buf, "&#%d;", *cur);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ ptr = buf;
-+ while (*ptr != 0) *out++ = *ptr++;
-+ }
-+#if 0
-+ else {
-+ /*
-+ * default case, this is not a valid char !
-+ * Skip it...
-+ */
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlEncodeEntities: invalid char %d\n", (int) *cur);
-+ }
-+#endif
-+ cur++;
-+ }
-+ *out++ = 0;
-+ return(buffer);
-+}
-+
-+/**
-+ * xmlEncodeSpecialChars:
-+ * @doc: the document containing the string
-+ * @input: A string to convert to XML.
-+ *
-+ * Do a global encoding of a string, replacing the predefined entities
-+ * this routine is reentrant, and result must be deallocated.
-+ *
-+ * Returns A newly allocated string with the substitution done.
-+ */
-+xmlChar *
-+xmlEncodeSpecialChars(xmlDocPtr doc, const xmlChar *input) {
-+ const xmlChar *cur = input;
-+ xmlChar *buffer = NULL;
-+ xmlChar *out = NULL;
-+ int buffer_size = 0;
-+ int html = 0;
-+
-+ if (input == NULL) return(NULL);
-+ if (doc != NULL)
-+ html = (doc->type == XML_HTML_DOCUMENT_NODE);
-+
-+ /*
-+ * allocate an translation buffer.
-+ */
-+ buffer_size = 1000;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("malloc failed");
-+ return(NULL);
-+ }
-+ out = buffer;
-+
-+ while (*cur != '\0') {
-+ if (out - buffer > buffer_size - 10) {
-+ int index = out - buffer;
-+
-+ growBufferReentrant();
-+ out = &buffer[index];
-+ }
-+
-+ /*
-+ * By default one have to encode at least '<', '>', '"' and '&' !
-+ */
-+ if (*cur == '<') {
-+ *out++ = '&';
-+ *out++ = 'l';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if (*cur == '>') {
-+ *out++ = '&';
-+ *out++ = 'g';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else if (*cur == '&') {
-+ *out++ = '&';
-+ *out++ = 'a';
-+ *out++ = 'm';
-+ *out++ = 'p';
-+ *out++ = ';';
-+ } else if (*cur == '"') {
-+ *out++ = '&';
-+ *out++ = 'q';
-+ *out++ = 'u';
-+ *out++ = 'o';
-+ *out++ = 't';
-+ *out++ = ';';
-+ } else {
-+ /*
-+ * Works because on UTF-8, all extended sequences cannot
-+ * result in bytes in the ASCII range.
-+ */
-+ *out++ = *cur;
-+ }
-+ cur++;
-+ }
-+ *out++ = 0;
-+ return(buffer);
-+}
-+
-+/**
-+ * xmlCreateEntitiesTable:
-+ *
-+ * create and initialize an empty entities hash table.
-+ *
-+ * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
-+ */
-+xmlEntitiesTablePtr
-+xmlCreateEntitiesTable(void) {
-+ return((xmlEntitiesTablePtr) xmlHashCreate(0));
-+}
-+
-+/**
-+ * xmlFreeEntitiesTable:
-+ * @table: An entity table
-+ *
-+ * Deallocate the memory used by an entities hash table.
-+ */
-+void
-+xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
-+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntity);
-+}
-+
-+/**
-+ * xmlCopyEntity:
-+ * @ent: An entity
-+ *
-+ * Build a copy of an entity
-+ *
-+ * Returns the new xmlEntitiesPtr or NULL in case of error.
-+ */
-+xmlEntityPtr
-+xmlCopyEntity(xmlEntityPtr ent) {
-+ xmlEntityPtr cur;
-+
-+ cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCopyEntity: out of memory !\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlEntity));
-+ cur->type = XML_ELEMENT_DECL;
-+
-+ cur->etype = ent->etype;
-+ if (ent->name != NULL)
-+ cur->name = xmlStrdup(ent->name);
-+ if (ent->ExternalID != NULL)
-+ cur->ExternalID = xmlStrdup(ent->ExternalID);
-+ if (ent->SystemID != NULL)
-+ cur->SystemID = xmlStrdup(ent->SystemID);
-+ if (ent->content != NULL)
-+ cur->content = xmlStrdup(ent->content);
-+ if (ent->orig != NULL)
-+ cur->orig = xmlStrdup(ent->orig);
-+ return(cur);
-+}
-+
-+/**
-+ * xmlCopyEntitiesTable:
-+ * @table: An entity table
-+ *
-+ * Build a copy of an entity table.
-+ *
-+ * Returns the new xmlEntitiesTablePtr or NULL in case of error.
-+ */
-+xmlEntitiesTablePtr
-+xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
-+ return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity));
-+}
-+
-+/**
-+ * xmlDumpEntityDecl:
-+ * @buf: An XML buffer.
-+ * @ent: An entity table
-+ *
-+ * This will dump the content of the entity table as an XML DTD definition
-+ */
-+void
-+xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
-+ switch (ent->etype) {
-+ case XML_INTERNAL_GENERAL_ENTITY:
-+ xmlBufferWriteChar(buf, "<!ENTITY ");
-+ xmlBufferWriteCHAR(buf, ent->name);
-+ xmlBufferWriteChar(buf, " ");
-+ if (ent->orig != NULL)
-+ xmlBufferWriteQuotedString(buf, ent->orig);
-+ else
-+ xmlBufferWriteQuotedString(buf, ent->content);
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-+ xmlBufferWriteChar(buf, "<!ENTITY ");
-+ xmlBufferWriteCHAR(buf, ent->name);
-+ if (ent->ExternalID != NULL) {
-+ xmlBufferWriteChar(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf, ent->ExternalID);
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteQuotedString(buf, ent->SystemID);
-+ } else {
-+ xmlBufferWriteChar(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf, ent->SystemID);
-+ }
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-+ xmlBufferWriteChar(buf, "<!ENTITY ");
-+ xmlBufferWriteCHAR(buf, ent->name);
-+ if (ent->ExternalID != NULL) {
-+ xmlBufferWriteChar(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf, ent->ExternalID);
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteQuotedString(buf, ent->SystemID);
-+ } else {
-+ xmlBufferWriteChar(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf, ent->SystemID);
-+ }
-+ if (ent->content != NULL) { /* Should be true ! */
-+ xmlBufferWriteChar(buf, " NDATA ");
-+ if (ent->orig != NULL)
-+ xmlBufferWriteCHAR(buf, ent->orig);
-+ else
-+ xmlBufferWriteCHAR(buf, ent->content);
-+ }
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ xmlBufferWriteChar(buf, "<!ENTITY % ");
-+ xmlBufferWriteCHAR(buf, ent->name);
-+ xmlBufferWriteChar(buf, " ");
-+ if (ent->orig == NULL)
-+ xmlBufferWriteQuotedString(buf, ent->content);
-+ else
-+ xmlBufferWriteQuotedString(buf, ent->orig);
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ xmlBufferWriteChar(buf, "<!ENTITY % ");
-+ xmlBufferWriteCHAR(buf, ent->name);
-+ if (ent->ExternalID != NULL) {
-+ xmlBufferWriteChar(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf, ent->ExternalID);
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteQuotedString(buf, ent->SystemID);
-+ } else {
-+ xmlBufferWriteChar(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf, ent->SystemID);
-+ }
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDumpEntitiesTable: internal: unknown type %d\n",
-+ ent->etype);
-+ }
-+}
-+
-+/**
-+ * xmlDumpEntitiesTable:
-+ * @buf: An XML buffer.
-+ * @table: An entity table
-+ *
-+ * This will dump the content of the entity table as an XML DTD definition
-+ */
-+void
-+xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
-+ xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDecl, buf);
-+}
-diff -Nru libxml2-2.3.0/libxml/entities.h libxml2-2.3.0.new/libxml/entities.h
---- libxml2-2.3.0/libxml/entities.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/entities.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,114 @@
-+/*
-+ * entities.h : interface for the XML entities handking
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_ENTITIES_H__
-+#define __XML_ENTITIES_H__
-+
-+#include <libxml/tree.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * The different valid entity types
-+ */
-+typedef enum {
-+ XML_INTERNAL_GENERAL_ENTITY = 1,
-+ XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
-+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
-+ XML_INTERNAL_PARAMETER_ENTITY = 4,
-+ XML_EXTERNAL_PARAMETER_ENTITY = 5,
-+ XML_INTERNAL_PREDEFINED_ENTITY = 6
-+} xmlEntityType;
-+
-+/*
-+ * An unit of storage for an entity, contains the string, the value
-+ * and the linkind data needed for the linking in the hash table.
-+ */
-+
-+typedef struct _xmlEntity xmlEntity;
-+typedef xmlEntity *xmlEntityPtr;
-+struct _xmlEntity {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* XML_ENTITY_DECL, must be second ! */
-+ const xmlChar *name; /* Attribute name */
-+ struct _xmlNode *children; /* NULL */
-+ struct _xmlNode *last; /* NULL */
-+ struct _xmlDtd *parent; /* -> DTD */
-+ struct _xmlNode *next; /* next sibling link */
-+ struct _xmlNode *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* the containing document */
-+
-+ xmlChar *orig; /* content without ref substitution */
-+ xmlChar *content; /* content or ndata if unparsed */
-+ int length; /* the content length */
-+ xmlEntityType etype; /* The entity type */
-+ const xmlChar *ExternalID; /* External identifier for PUBLIC */
-+ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */
-+
-+ struct _xmlEntity *nexte; /* unused */
-+ const xmlChar *URI; /* the full URI as computed */
-+};
-+
-+/*
-+ * ALl entities are stored in an hash table
-+ * there is 2 separate hash tables for global and parmeter entities
-+ */
-+
-+typedef struct _xmlHashTable xmlEntitiesTable;
-+typedef xmlEntitiesTable *xmlEntitiesTablePtr;
-+
-+/*
-+ * External functions :
-+ */
-+
-+void xmlInitializePredefinedEntities (void);
-+xmlEntityPtr xmlAddDocEntity (xmlDocPtr doc,
-+ const xmlChar *name,
-+ int type,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID,
-+ const xmlChar *content);
-+xmlEntityPtr xmlAddDtdEntity (xmlDocPtr doc,
-+ const xmlChar *name,
-+ int type,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID,
-+ const xmlChar *content);
-+xmlEntityPtr xmlGetPredefinedEntity (const xmlChar *name);
-+xmlEntityPtr xmlGetDocEntity (xmlDocPtr doc,
-+ const xmlChar *name);
-+xmlEntityPtr xmlGetDtdEntity (xmlDocPtr doc,
-+ const xmlChar *name);
-+xmlEntityPtr xmlGetParameterEntity (xmlDocPtr doc,
-+ const xmlChar *name);
-+const xmlChar * xmlEncodeEntities (xmlDocPtr doc,
-+ const xmlChar *input);
-+xmlChar * xmlEncodeEntitiesReentrant(xmlDocPtr doc,
-+ const xmlChar *input);
-+xmlChar * xmlEncodeSpecialChars (xmlDocPtr doc,
-+ const xmlChar *input);
-+xmlEntitiesTablePtr xmlCreateEntitiesTable (void);
-+xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table);
-+void xmlFreeEntitiesTable (xmlEntitiesTablePtr table);
-+void xmlDumpEntitiesTable (xmlBufferPtr buf,
-+ xmlEntitiesTablePtr table);
-+void xmlDumpEntityDecl (xmlBufferPtr buf,
-+ xmlEntityPtr ent);
-+xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table);
-+void xmlCleanupPredefinedEntities(void);
-+
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+# endif /* __XML_ENTITIES_H__ */
-diff -Nru libxml2-2.3.0/libxml/error.c libxml2-2.3.0.new/libxml/error.c
---- libxml2-2.3.0/libxml/error.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/error.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,298 @@
-+/*
-+ * error.c: module displaying/handling XML parser errors
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel Veillard <Daniel.Veillard@w3.org>
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <stdarg.h>
-+#include <libxml/parser.h>
-+#include <libxml/xmlerror.h>
-+
-+/************************************************************************
-+ * *
-+ * Handling of out of context errors *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlGenericErrorDefaultFunc:
-+ * @ctx: an error context
-+ * @msg: the message to display/transmit
-+ * @...: extra parameters for the message display
-+ *
-+ * Default handler for out of context error messages.
-+ */
-+void
-+xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...) {
-+ va_list args;
-+
-+ if (xmlGenericErrorContext == NULL)
-+ xmlGenericErrorContext = (void *) stderr;
-+
-+ va_start(args, msg);
-+ vfprintf((FILE *)xmlGenericErrorContext, msg, args);
-+ va_end(args);
-+}
-+
-+xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
-+void *xmlGenericErrorContext = NULL;
-+
-+
-+/**
-+ * xmlSetGenericErrorFunc:
-+ * @ctx: the new error handling context
-+ * @handler: the new handler function
-+ *
-+ * Function to reset the handler and the error context for out of
-+ * context error messages.
-+ * This simply means that @handler will be called for subsequent
-+ * error messages while not parsing nor validating. And @ctx will
-+ * be passed as first argument to @handler
-+ * One can simply force messages to be emitted to another FILE * than
-+ * stderr by setting @ctx to this file handle and @handler to NULL.
-+ */
-+void
-+xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
-+ xmlGenericErrorContext = ctx;
-+ if (handler != NULL)
-+ xmlGenericError = handler;
-+ else
-+ xmlGenericError = xmlGenericErrorDefaultFunc;
-+}
-+
-+/************************************************************************
-+ * *
-+ * Handling of parsing errors *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlParserPrintFileInfo:
-+ * @input: an xmlParserInputPtr input
-+ *
-+ * Displays the associated file and line informations for the current input
-+ */
-+
-+void
-+xmlParserPrintFileInfo(xmlParserInputPtr input) {
-+ if (input != NULL) {
-+ if (input->filename)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s:%d: ", input->filename,
-+ input->line);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Entity: line %d: ", input->line);
-+ }
-+}
-+
-+/**
-+ * xmlParserPrintFileContext:
-+ * @input: an xmlParserInputPtr input
-+ *
-+ * Displays current context within the input content for error tracking
-+ */
-+
-+void
-+xmlParserPrintFileContext(xmlParserInputPtr input) {
-+ const xmlChar *cur, *base;
-+ int n;
-+
-+ if (input == NULL) return;
-+ cur = input->cur;
-+ base = input->base;
-+ while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
-+ cur--;
-+ }
-+ n = 0;
-+ while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
-+ cur--;
-+ if ((*cur == '\n') || (*cur == '\r')) cur++;
-+ base = cur;
-+ n = 0;
-+ while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%c", (unsigned char) *cur++);
-+ n++;
-+ }
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+ cur = input->cur;
-+ while ((*cur == '\n') || (*cur == '\r'))
-+ cur--;
-+ n = 0;
-+ while ((cur != base) && (n++ < 80)) {
-+ xmlGenericError(xmlGenericErrorContext, " ");
-+ base++;
-+ }
-+ xmlGenericError(xmlGenericErrorContext,"^\n");
-+}
-+
-+/**
-+ * xmlParserError:
-+ * @ctx: an XML parser context
-+ * @msg: the message to display/transmit
-+ * @...: extra parameters for the message display
-+ *
-+ * Display and format an error messages, gives file, line, position and
-+ * extra parameters.
-+ */
-+void
-+xmlParserError(void *ctx, const char *msg, ...)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlParserInputPtr input = NULL;
-+ xmlParserInputPtr cur = NULL;
-+ va_list args;
-+
-+ if (ctxt != NULL) {
-+ input = ctxt->input;
-+ if ((input != NULL) && (input->filename == NULL) &&
-+ (ctxt->inputNr > 1)) {
-+ cur = input;
-+ input = ctxt->inputTab[ctxt->inputNr - 2];
-+ }
-+ xmlParserPrintFileInfo(input);
-+ }
-+
-+ xmlGenericError(xmlGenericErrorContext, "error: ");
-+ va_start(args, msg);
-+ vfprintf(xmlGenericErrorContext, msg, args);
-+ va_end(args);
-+
-+ if (ctxt != NULL) {
-+ xmlParserPrintFileContext(input);
-+ if (cur != NULL) {
-+ xmlParserPrintFileInfo(cur);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+ xmlParserPrintFileContext(cur);
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlParserWarning:
-+ * @ctx: an XML parser context
-+ * @msg: the message to display/transmit
-+ * @...: extra parameters for the message display
-+ *
-+ * Display and format a warning messages, gives file, line, position and
-+ * extra parameters.
-+ */
-+void
-+xmlParserWarning(void *ctx, const char *msg, ...)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlParserInputPtr input = NULL;
-+ xmlParserInputPtr cur = NULL;
-+ va_list args;
-+
-+ if (ctxt != NULL) {
-+ input = ctxt->input;
-+ if ((input != NULL) && (input->filename == NULL) &&
-+ (ctxt->inputNr > 1)) {
-+ cur = input;
-+ input = ctxt->inputTab[ctxt->inputNr - 2];
-+ }
-+ xmlParserPrintFileInfo(input);
-+ }
-+
-+ xmlGenericError(xmlGenericErrorContext, "warning: ");
-+ va_start(args, msg);
-+ vfprintf(xmlGenericErrorContext, msg, args);
-+ va_end(args);
-+
-+
-+ if (ctxt != NULL) {
-+ xmlParserPrintFileContext(input);
-+ if (cur != NULL) {
-+ xmlParserPrintFileInfo(cur);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+ xmlParserPrintFileContext(cur);
-+ }
-+ }
-+}
-+
-+/************************************************************************
-+ * *
-+ * Handling of validation errors *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlParserValidityError:
-+ * @ctx: an XML parser context
-+ * @msg: the message to display/transmit
-+ * @...: extra parameters for the message display
-+ *
-+ * Display and format an validity error messages, gives file,
-+ * line, position and extra parameters.
-+ */
-+void
-+xmlParserValidityError(void *ctx, const char *msg, ...)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlParserInputPtr input = NULL;
-+ va_list args;
-+
-+ if (ctxt != NULL) {
-+ input = ctxt->input;
-+ if ((input->filename == NULL) && (ctxt->inputNr > 1))
-+ input = ctxt->inputTab[ctxt->inputNr - 2];
-+
-+ xmlParserPrintFileInfo(input);
-+ }
-+
-+ xmlGenericError(xmlGenericErrorContext, "validity error: ");
-+ va_start(args, msg);
-+ vfprintf(xmlGenericErrorContext, msg, args);
-+ va_end(args);
-+
-+ if (ctxt != NULL) {
-+ xmlParserPrintFileContext(input);
-+ }
-+}
-+
-+/**
-+ * xmlParserValidityWarning:
-+ * @ctx: an XML parser context
-+ * @msg: the message to display/transmit
-+ * @...: extra parameters for the message display
-+ *
-+ * Display and format a validity warning messages, gives file, line,
-+ * position and extra parameters.
-+ */
-+void
-+xmlParserValidityWarning(void *ctx, const char *msg, ...)
-+{
-+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-+ xmlParserInputPtr input = NULL;
-+ va_list args;
-+
-+ if (ctxt != NULL) {
-+ input = ctxt->input;
-+ if ((input->filename == NULL) && (ctxt->inputNr > 1))
-+ input = ctxt->inputTab[ctxt->inputNr - 2];
-+
-+ xmlParserPrintFileInfo(input);
-+ }
-+
-+ xmlGenericError(xmlGenericErrorContext, "validity warning: ");
-+ va_start(args, msg);
-+ vfprintf(xmlGenericErrorContext, msg, args);
-+ va_end(args);
-+
-+ if (ctxt != NULL) {
-+ xmlParserPrintFileContext(input);
-+ }
-+}
-+
-+
-diff -Nru libxml2-2.3.0/libxml/hash.c libxml2-2.3.0.new/libxml/hash.c
---- libxml2-2.3.0/libxml/hash.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/hash.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,533 @@
-+/*
-+ * hash.c: chained hash tables
-+ *
-+ * Reference: Your favorite introductory book on algorithms
-+ *
-+ * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-+ *
-+ * Author: bjorn.reese@systematic.dk
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <string.h>
-+#include <libxml/hash.h>
-+#include <libxml/xmlmemory.h>
-+#include <libxml/parser.h>
-+
-+/*
-+ * A single entry in the hash table
-+ */
-+typedef struct _xmlHashEntry xmlHashEntry;
-+typedef xmlHashEntry *xmlHashEntryPtr;
-+struct _xmlHashEntry {
-+ struct _xmlHashEntry *next;
-+ xmlChar *name;
-+ xmlChar *name2;
-+ xmlChar *name3;
-+ void *payload;
-+};
-+
-+/*
-+ * The entire hash table
-+ */
-+struct _xmlHashTable {
-+ struct _xmlHashEntry **table;
-+ int size;
-+ int nbElems;
-+};
-+
-+/*
-+ * xmlHashComputeKey:
-+ * Calculate the hash key
-+ */
-+static unsigned long
-+xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *string) {
-+ unsigned long value = 0L;
-+ char ch;
-+
-+ while ((ch = *string++) != 0) {
-+ /* value *= 31; */
-+ value += (unsigned long)ch;
-+ }
-+ return (value % table->size);
-+}
-+
-+/**
-+ * xmlHashCreate:
-+ * @size: the size of the hash table
-+ *
-+ * Create a new xmlHashTablePtr.
-+ *
-+ * Returns the newly created object, or NULL if an error occured.
-+ */
-+xmlHashTablePtr
-+xmlHashCreate(int size) {
-+ xmlHashTablePtr table;
-+
-+ if (size <= 0)
-+ size = 256;
-+
-+ table = xmlMalloc(sizeof(xmlHashTable));
-+ if (table) {
-+ table->size = size;
-+ table->nbElems = 0;
-+ table->table = xmlMalloc(size * sizeof(xmlHashEntry));
-+ if (table->table) {
-+ memset(table->table, 0, size * sizeof(xmlHashEntry));
-+ return(table);
-+ }
-+ xmlFree(table);
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlHashFree:
-+ * @table: the hash table
-+ * @f: the deallocator function for items in the hash
-+ *
-+ * Free the hash table and its contents. The userdata is
-+ * deallocated with f if provided.
-+ */
-+void
-+xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
-+ int i;
-+ xmlHashEntryPtr iter;
-+ xmlHashEntryPtr next;
-+
-+ if (table == NULL)
-+ return;
-+ if (table->table) {
-+ for(i = 0; i < table->size; i++) {
-+ iter = table->table[i];
-+ while (iter) {
-+ next = iter->next;
-+ if (iter->name)
-+ xmlFree(iter->name);
-+ if (iter->name2)
-+ xmlFree(iter->name2);
-+ if (iter->name3)
-+ xmlFree(iter->name3);
-+ if (f)
-+ f(iter->payload, iter->name);
-+ iter->payload = NULL;
-+ xmlFree(iter);
-+ iter = next;
-+ }
-+ table->table[i] = NULL;
-+ }
-+ xmlFree(table->table);
-+ }
-+ xmlFree(table);
-+}
-+
-+/**
-+ * xmlHashAddEntry:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @userdata: a pointer to the userdata
-+ *
-+ * Add the userdata to the hash table. This can later be retrieved
-+ * by using the name. Duplicate names generate errors.
-+ *
-+ * Returns 0 the addition succeeded and -1 in case of error.
-+ */
-+int
-+xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
-+ return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
-+}
-+
-+/**
-+ * xmlHashAddEntry2:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @name2: a second name of the userdata
-+ * @userdata: a pointer to the userdata
-+ *
-+ * Add the userdata to the hash table. This can later be retrieved
-+ * by using the (name, name2) tuple. Duplicate tuples generate errors.
-+ *
-+ * Returns 0 the addition succeeded and -1 in case of error.
-+ */
-+int
-+xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2, void *userdata) {
-+ return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
-+}
-+
-+/**
-+ * xmlHashUpdateEntry:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @userdata: a pointer to the userdata
-+ * @f: the deallocator function for replaced item (if any)
-+ *
-+ * Add the userdata to the hash table. This can later be retrieved
-+ * by using the name. Existing entry for this name will be removed
-+ * and freed with @f if found.
-+ *
-+ * Returns 0 the addition succeeded and -1 in case of error.
-+ */
-+int
-+xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
-+ void *userdata, xmlHashDeallocator f) {
-+ return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
-+}
-+
-+/**
-+ * xmlHashUpdateEntry2:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @name2: a second name of the userdata
-+ * @userdata: a pointer to the userdata
-+ * @f: the deallocator function for replaced item (if any)
-+ *
-+ * Add the userdata to the hash table. This can later be retrieved
-+ * by using the (name, name2) tuple. Existing entry for this tuple will
-+ * be removed and freed with @f if found.
-+ *
-+ * Returns 0 the addition succeeded and -1 in case of error.
-+ */
-+int
-+xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2, void *userdata,
-+ xmlHashDeallocator f) {
-+ return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
-+}
-+
-+/**
-+ * xmlHashLookup:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ *
-+ * Find the userdata specified by the name.
-+ *
-+ * Returns the a pointer to the userdata
-+ */
-+void *
-+xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
-+ return(xmlHashLookup3(table, name, NULL, NULL));
-+}
-+
-+/**
-+ * xmlHashLookup2:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @name2: a second name of the userdata
-+ *
-+ * Find the userdata specified by the (name, name2) tuple.
-+ *
-+ * Returns the a pointer to the userdata
-+ */
-+void *
-+xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2) {
-+ return(xmlHashLookup3(table, name, name2, NULL));
-+}
-+
-+/**
-+ * xmlHashAddEntry3:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @name2: a second name of the userdata
-+ * @name3: a third name of the userdata
-+ * @userdata: a pointer to the userdata
-+ *
-+ * Add the userdata to the hash table. This can later be retrieved
-+ * by using the tuple (name, name2, name3). Duplicate entries generate
-+ * errors.
-+ *
-+ * Returns 0 the addition succeeded and -1 in case of error.
-+ */
-+int
-+xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2, const xmlChar *name3,
-+ void *userdata) {
-+ unsigned long key;
-+ xmlHashEntryPtr entry;
-+ xmlHashEntryPtr insert;
-+
-+ if ((table == NULL) || name == NULL)
-+ return(-1);
-+
-+ /*
-+ * Check for duplicate and insertion location.
-+ */
-+ key = xmlHashComputeKey(table, name);
-+ if (table->table[key] == NULL) {
-+ insert = NULL;
-+ } else {
-+ for (insert = table->table[key]; insert->next != NULL;
-+ insert = insert->next) {
-+ if ((xmlStrEqual(insert->name, name)) &&
-+ (xmlStrEqual(insert->name2, name2)) &&
-+ (xmlStrEqual(insert->name3, name3)))
-+ return(-1);
-+ }
-+ if ((xmlStrEqual(insert->name, name)) &&
-+ (xmlStrEqual(insert->name2, name2)) &&
-+ (xmlStrEqual(insert->name3, name3)))
-+ return(-1);
-+ }
-+
-+ entry = xmlMalloc(sizeof(xmlHashEntry));
-+ if (entry == NULL)
-+ return(-1);
-+ entry->name = xmlStrdup(name);
-+ entry->name2 = xmlStrdup(name2);
-+ entry->name3 = xmlStrdup(name3);
-+ entry->payload = userdata;
-+ entry->next = NULL;
-+
-+
-+ if (insert == NULL) {
-+ table->table[key] = entry;
-+ } else {
-+ insert->next = entry;
-+ }
-+ table->nbElems++;
-+ return(0);
-+}
-+
-+/**
-+ * xmlHashUpdateEntry3:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @name2: a second name of the userdata
-+ * @name3: a third name of the userdata
-+ * @userdata: a pointer to the userdata
-+ * @f: the deallocator function for replaced item (if any)
-+ *
-+ * Add the userdata to the hash table. This can later be retrieved
-+ * by using the tuple (name, name2, name3). Existing entry for this tuple
-+ * will be removed and freed with @f if found.
-+ *
-+ * Returns 0 the addition succeeded and -1 in case of error.
-+ */
-+int
-+xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2, const xmlChar *name3,
-+ void *userdata, xmlHashDeallocator f) {
-+ unsigned long key;
-+ xmlHashEntryPtr entry;
-+ xmlHashEntryPtr insert;
-+
-+ if ((table == NULL) || name == NULL)
-+ return(-1);
-+
-+ /*
-+ * Check for duplicate and insertion location.
-+ */
-+ key = xmlHashComputeKey(table, name);
-+ if (table->table[key] == NULL) {
-+ insert = NULL;
-+ } else {
-+ for (insert = table->table[key]; insert->next != NULL;
-+ insert = insert->next) {
-+ if ((xmlStrEqual(insert->name, name)) &&
-+ (xmlStrEqual(insert->name2, name2)) &&
-+ (xmlStrEqual(insert->name3, name3))) {
-+ if (f)
-+ f(insert->payload, insert->name);
-+ insert->payload = userdata;
-+ return(0);
-+ }
-+ }
-+ if ((xmlStrEqual(insert->name, name)) &&
-+ (xmlStrEqual(insert->name2, name2)) &&
-+ (xmlStrEqual(insert->name3, name3))) {
-+ if (f)
-+ f(insert->payload, insert->name);
-+ insert->payload = userdata;
-+ return(0);
-+ }
-+ }
-+
-+ entry = xmlMalloc(sizeof(xmlHashEntry));
-+ if (entry == NULL)
-+ return(-1);
-+ entry->name = xmlStrdup(name);
-+ entry->name2 = xmlStrdup(name2);
-+ entry->name3 = xmlStrdup(name3);
-+ entry->payload = userdata;
-+ entry->next = NULL;
-+ table->nbElems++;
-+
-+
-+ if (insert == NULL) {
-+ table->table[key] = entry;
-+ } else {
-+ insert->next = entry;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlHashLookup:
-+ * @table: the hash table
-+ * @name: the name of the userdata
-+ * @name2: a second name of the userdata
-+ * @name3: a third name of the userdata
-+ *
-+ * Find the userdata specified by the (name, name2, name3) tuple.
-+ *
-+ * Returns the a pointer to the userdata
-+ */
-+void *
-+xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2, const xmlChar *name3) {
-+ unsigned long key;
-+ xmlHashEntryPtr entry;
-+
-+ if (table == NULL)
-+ return(NULL);
-+ if (name == NULL)
-+ return(NULL);
-+ key = xmlHashComputeKey(table, name);
-+ for (entry = table->table[key]; entry != NULL; entry = entry->next) {
-+ if ((xmlStrEqual(entry->name, name)) &&
-+ (xmlStrEqual(entry->name2, name2)) &&
-+ (xmlStrEqual(entry->name3, name3)))
-+ return(entry->payload);
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlHashScan:
-+ * @table: the hash table
-+ * @f: the scanner function for items in the hash
-+ * @data: extra data passed to f
-+ *
-+ * Scan the hash table and applied f to each value.
-+ */
-+void
-+xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
-+ int i;
-+ xmlHashEntryPtr iter;
-+ xmlHashEntryPtr next;
-+
-+ if (table == NULL)
-+ return;
-+ if (f == NULL)
-+ return;
-+
-+ if (table->table) {
-+ for(i = 0; i < table->size; i++) {
-+ iter = table->table[i];
-+ while (iter) {
-+ next = iter->next;
-+ if (f)
-+ f(iter->payload, data, iter->name);
-+ iter = next;
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlHashScan3:
-+ * @table: the hash table
-+ * @name: the name of the userdata or NULL
-+ * @name2: a second name of the userdata or NULL
-+ * @name3: a third name of the userdata or NULL
-+ * @f: the scanner function for items in the hash
-+ * @data: extra data passed to f
-+ *
-+ * Scan the hash table and applied f to each value matching
-+ * (name, name2, name3) tuple. If one of the names is null,
-+ * the comparison is considered to match.
-+ */
-+void
-+xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
-+ const xmlChar *name2, const xmlChar *name3,
-+ xmlHashScanner f, void *data) {
-+ int i;
-+ xmlHashEntryPtr iter;
-+ xmlHashEntryPtr next;
-+
-+ if (table == NULL)
-+ return;
-+ if (f == NULL)
-+ return;
-+
-+ if (table->table) {
-+ for(i = 0; i < table->size; i++) {
-+ iter = table->table[i];
-+ while (iter) {
-+ next = iter->next;
-+ if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
-+ ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
-+ ((name3 == NULL) || (xmlStrEqual(name3, iter->name3)))) {
-+ f(iter->payload, data, iter->name);
-+ }
-+ iter = next;
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlHashCopy:
-+ * @table: the hash table
-+ * @f: the copier function for items in the hash
-+ *
-+ * Scan the hash table and applied f to each value.
-+ *
-+ * Returns the new table or NULL in case of error.
-+ */
-+xmlHashTablePtr
-+xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
-+ int i;
-+ xmlHashEntryPtr iter;
-+ xmlHashEntryPtr next;
-+ xmlHashTablePtr ret;
-+
-+ if (table == NULL)
-+ return(NULL);
-+ if (f == NULL)
-+ return(NULL);
-+
-+ ret = xmlHashCreate(table->size);
-+ if (table->table) {
-+ for(i = 0; i < table->size; i++) {
-+ iter = table->table[i];
-+ while (iter) {
-+ next = iter->next;
-+ xmlHashAddEntry3(ret, iter->name, iter->name2,
-+ iter->name3, f(iter->payload, iter->name));
-+ iter = next;
-+ }
-+ }
-+ }
-+ ret->nbElems = table->nbElems;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlHashSize:
-+ * @table: the hash table
-+ *
-+ * Returns the number of elements in the hash table or
-+ * -1 in case of error
-+ */
-+int
-+xmlHashSize(xmlHashTablePtr table) {
-+ if (table == NULL)
-+ return(-1);
-+ return(table->nbElems);
-+}
-diff -Nru libxml2-2.3.0/libxml/hash.h libxml2-2.3.0.new/libxml/hash.h
---- libxml2-2.3.0/libxml/hash.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/hash.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,117 @@
-+/*
-+ * hash.c: chained hash tables
-+ *
-+ * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-+ *
-+ * Author: bjorn.reese@systematic.dk
-+ */
-+
-+#ifndef __XML_HASH_H__
-+#define __XML_HASH_H__
-+
-+#include <libxml/parser.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * The hash table
-+ */
-+typedef struct _xmlHashTable xmlHashTable;
-+typedef xmlHashTable *xmlHashTablePtr;
-+
-+/*
-+ * function types:
-+ */
-+typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
-+typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
-+typedef void *(*xmlHashScanner)(void *payload, void *data, xmlChar *name);
-+
-+/*
-+ * Constructor and destructor
-+ */
-+xmlHashTablePtr xmlHashCreate (int size);
-+void xmlHashFree (xmlHashTablePtr table,
-+ xmlHashDeallocator f);
-+
-+/*
-+ * Add a new entry to the hash table
-+ */
-+int xmlHashAddEntry (xmlHashTablePtr table,
-+ const xmlChar *name,
-+ void *userdata);
-+int xmlHashUpdateEntry(xmlHashTablePtr table,
-+ const xmlChar *name,
-+ void *userdata,
-+ xmlHashDeallocator f);
-+int xmlHashAddEntry2(xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ void *userdata);
-+int xmlHashUpdateEntry2(xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ void *userdata,
-+ xmlHashDeallocator f);
-+int xmlHashAddEntry3(xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ const xmlChar *name3,
-+ void *userdata);
-+int xmlHashUpdateEntry3(xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ const xmlChar *name3,
-+ void *userdata,
-+ xmlHashDeallocator f);
-+/*
-+ * Retrieve the userdata
-+ */
-+void * xmlHashLookup (xmlHashTablePtr table,
-+ const xmlChar *name);
-+void * xmlHashLookup2 (xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2);
-+void * xmlHashLookup3 (xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ const xmlChar *name3);
-+
-+/*
-+ * Helpers
-+ */
-+xmlHashTablePtr xmlHashCopy (xmlHashTablePtr table,
-+ xmlHashCopier f);
-+int xmlHashSize (xmlHashTablePtr);
-+void xmlHashScan (xmlHashTablePtr table,
-+ xmlHashScanner f,
-+ void *data);
-+void xmlHashScan1 (xmlHashTablePtr table,
-+ const xmlChar *name,
-+ xmlHashScanner f,
-+ void *data);
-+void xmlHashScan2 (xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ xmlHashScanner f,
-+ void *data);
-+void xmlHashScan3 (xmlHashTablePtr table,
-+ const xmlChar *name,
-+ const xmlChar *name2,
-+ const xmlChar *name3,
-+ xmlHashScanner f,
-+ void *data);
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* ! __XML_HASH_H__ */
-diff -Nru libxml2-2.3.0/libxml/libxml.4 libxml2-2.3.0.new/libxml/libxml.4
---- libxml2-2.3.0/libxml/libxml.4 Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/libxml.4 Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,66 @@
-+.TH libxml 4 "12 April 2000"
-+.SH NAME
-+libxml \- library used to parse XML files
-+.SH DESCRIPTION
-+The
-+.I libxml
-+library is used to parse XML files.
-+Its internal document repesentation is as close as possible to the
-+.I DOM
-+(Document Object Model) interface,
-+an API for accessing XML or HTML structured documents.
-+.LP
-+The
-+.I libxml
-+library also has a
-+.IR SAX -like
-+interface,
-+which is designed to be compatible with
-+.IR expat (1).
-+NOTE:
-+.IR SAX ,
-+the Simple API for XML,
-+is a standard interface for event-based XML parsing,
-+developed collaboratively by the members of the XML-DEV mailing list,
-+currently hosted by OASIS.
-+The
-+.I expat
-+library is a XML 1.0 parser written in C,
-+which aims to be fully conforming.
-+It is currently not a validating XML processor.
-+.LP
-+The
-+.I libxml
-+library now includes a nearly complete
-+.I XPath
-+implementation.
-+The
-+.I XPath
-+(XML Path Language) is a language for addressing parts of an
-+XML document,
-+designed to be used by both
-+.I XSLT
-+and
-+.IR XPointer .
-+.LP
-+The
-+.I libxml
-+library exports Push and Pull type parser interfaces for both XML and
-+.IR html .
-+.SH FILES
-+.TP 2.2i
-+.B /depot/lib/libxml_2.0.0/libxml.a
-+static library
-+.TP
-+.B /depot/lib/libxml_2.0.0/libxml.so
-+shareable library
-+.TP
-+.B /depot/package/libxml_2.0.0/bin/xmllint
-+binary application for parsing XML files
-+.SH AUTHORS
-+Daniel Veillard (Daniel.Veillard@w3.org).
-+If you download and install this package please send the author email.
-+Manual page by Ziying Sherwin (sherwin@nlm.nih.gov),
-+Lister Hill National Center for Biomedical Communications,
-+U.S. National Library of Medicine.
-+.\" end of manual page
-diff -Nru libxml2-2.3.0/libxml/libxml.m4 libxml2-2.3.0.new/libxml/libxml.m4
---- libxml2-2.3.0/libxml/libxml.m4 Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/libxml.m4 Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,148 @@
-+dnl Code shamelessly stolen from glib-config by Sebastian Rittau
-+dnl AM_PATH_XML([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-+AC_DEFUN(AM_PATH_XML,[
-+AC_ARG_WITH(xml-prefix,
-+ [ --with-xml-prefix=PFX Prefix where libxml is installed (optional)],
-+ xml_config_prefix="$withval", xml_config_prefix="")
-+AC_ARG_ENABLE(xmltest,
-+ [ --disable-xmltest Do not try to compile and run a test XML program],,
-+ enable_xmltest=yes)
-+
-+ if test x$xml_config_prefix != x ; then
-+ xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
-+ if test x${XML_CONFIG+set} != xset ; then
-+ XML_CONFIG=$xml_config_prefix/bin/xml-config
-+ fi
-+ fi
-+
-+ AC_PATH_PROG(XML_CONFIG, xml-config, no)
-+ min_xml_version=ifelse([$1], ,2.0.0, [$1])
-+ AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
-+ no_xml=""
-+ if test "$XML_CONFIG" = "no" ; then
-+ no_xml=yes
-+ else
-+ XML_CFLAGS=`$XML_CONFIG $xml_config_args --cflags`
-+ XML_LIBS=`$XML_CONFIG $xml_config_args --libs`
-+ xml_config_major_version=`$XML_CONFIG $xml_config_args --version | \
-+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
-+ xml_config_minor_version=`$XML_CONFIG $xml_config_args --version | \
-+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
-+ xml_config_micro_version=`$XML_CONFIG $xml_config_args --version | \
-+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
-+ if test "x$enable_xmltest" = "xyes" ; then
-+ ac_save_CFLAGS="$CFLAGS"
-+ ac_save_LIBS="$LIBS"
-+ CFLAGS="$CFLAGS $XML_CFLAGS"
-+ LIBS="$XML_LIBS $LIBS"
-+dnl
-+dnl Now check if the installed libxml is sufficiently new.
-+dnl
-+ rm -f conf.xmltest
-+ AC_TRY_RUN([
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <xmlversion.h>
-+#include <parser.h>
-+
-+int
-+main()
-+{
-+ int xml_major_version, xml_minor_version, xml_micro_version;
-+ int major, minor, micro;
-+ char *tmp_version;
-+
-+ system("touch conf.xmltest");
-+
-+ tmp_version = xmlStrdup("$min_xml_version");
-+ if(sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
-+ printf("%s, bad version string\n", "$min_xml_version");
-+ exit(1);
-+ }
-+
-+ tmp_version = xmlStrdup(LIBXML_DOTTED_VERSION);
-+ if(sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
-+ printf("%s, bad version string\n", "$min_xml_version");
-+ exit(1);
-+ }
-+
-+ if((xml_major_version != $xml_config_major_version) ||
-+ (xml_minor_version != $xml_config_minor_version) ||
-+ (xml_micro_version != $xml_config_micro_version))
-+ {
-+ printf("\n*** 'xml-config --version' returned %d.%d.%d, but libxml (%d.%d.%d)\n",
-+ $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version,
-+ xml_major_version, xml_minor_version, xml_micro_version);
-+ printf("*** was found! If xml-config was correct, then it is best\n");
-+ printf("*** to remove the old version of libxml. You may also be able to fix the error\n");
-+ printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
-+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
-+ printf("*** required on your system.\n");
-+ printf("*** If xml-config was wrong, set the environment variable XML_CONFIG\n");
-+ printf("*** to point to the correct copy of xml-config, and remove the file config.cache\n");
-+ printf("*** before re-running configure\n");
-+ }
-+ else
-+ {
-+ if ((xml_major_version > major) ||
-+ ((xml_major_version == major) && (xml_minor_version > minor)) ||
-+ ((xml_major_version == major) && (xml_minor_version == minor) &&
-+ (xml_micro_version >= micro)))
-+ {
-+ return 0;
-+ }
-+ else
-+ {
-+ printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
-+ xml_major_version, xml_minor_version, xml_micro_version);
-+ printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
-+ major, minor, micro);
-+ printf("*** libxml is always available from ftp://ftp.gnome.org.\n");
-+ printf("***\n");
-+ printf("*** If you have already installed a sufficiently new version, this error\n");
-+ printf("*** probably means that the wrong copy of the xml-config shell script is\n");
-+ printf("*** being found. The easiest way to fix this is to remove the old version\n");
-+ printf("*** of libxml, but you can also set the XML_CONFIG environment to point to the\n");
-+ printf("*** correct copy of xml-config. (In this case, you will have to\n");
-+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
-+ printf("*** so that the correct libraries are found at run-time))\n");
-+ }
-+ }
-+ return 1;
-+}
-+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
-+
-+ CFLAGS="$ac_save_CFLAGS"
-+ LIBS="$ac_save_LIBS"
-+ fi
-+ fi
-+
-+ if test "x$no_xml" = x ; then
-+ AC_MSG_RESULT(yes)
-+ ifelse([$2], , :, [$2])
-+ else
-+ AC_MSG_RESULT(no)
-+ if test "$XML_CONFIG" = "no" ; then
-+ echo "*** The xml-config script installed by libxml could not be found"
-+ echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
-+ echo "*** your path, or set the XML_CONFIG environment variable to the"
-+ echo "*** full path to xml-config."
-+ else
-+ if test -f conf.xmltest ; then
-+ :
-+ else
-+ echo "*** Could not run libxml test program, checking why..."
-+ CFLAGS="$CFLAGS $XML_CFLAGS"
-+ LIBS="$LIBS $XML_LIBS"
-+ dnl FIXME: AC_TRY_LINK
-+ fi
-+ fi
-+
-+ XML_CFLAGS=""
-+ XML_LIBS=""
-+ ifelse([$3], , :, [$3])
-+ fi
-+ AC_SUBST(XML_CFLAGS)
-+ AC_SUBST(XML_LIBS)
-+ rm -f conf.xmltest
-+])
-diff -Nru libxml2-2.3.0/libxml/libxml.pc.in libxml2-2.3.0.new/libxml/libxml.pc.in
---- libxml2-2.3.0/libxml/libxml.pc.in Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/libxml.pc.in Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,12 @@
-+prefix=@prefix@
-+exec_prefix=@exec_prefix@
-+libdir=@libdir@
-+includedir=@includedir@
-+
-+
-+Name: libXML
-+Version: @VERSION@
-+Description: libXML library.
-+Requires:
-+Libs: -L${libdir} -lxml @Z_LIBS@ @M_LIBS@ @LIBS@
-+Cflags: @XML_INCLUDEDIR@ @XML_CFLAGS@
-diff -Nru libxml2-2.3.0/libxml/nanoftp.c libxml2-2.3.0.new/libxml/nanoftp.c
---- libxml2-2.3.0/libxml/nanoftp.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/nanoftp.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,1964 @@
-+/*
-+ * nanoftp.c: basic FTP client support
-+ *
-+ * Reference: RFC 959
-+ */
-+
-+#ifdef TESTING
-+#define STANDALONE
-+#define HAVE_STDLIB_H
-+#define HAVE_UNISTD_H
-+#define HAVE_SYS_SOCKET_H
-+#define HAVE_NETINET_IN_H
-+#define HAVE_NETDB_H
-+#define HAVE_SYS_TIME_H
-+#else /* STANDALONE */
-+#ifdef WIN32
-+#define INCLUDE_WINSOCK
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+#endif /* STANDALONE */
-+
-+#include <libxml/xmlversion.h>
-+
-+#ifdef LIBXML_FTP_ENABLED
-+#include <stdio.h>
-+#include <string.h>
-+
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_SYS_SOCKET_H
-+#include <sys/socket.h>
-+#endif
-+#ifdef HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+#ifdef HAVE_ARPA_INET_H
-+#include <arpa/inet.h>
-+#endif
-+#ifdef HAVE_NETDB_H
-+#include <netdb.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#ifdef HAVE_SYS_TIME_H
-+#include <sys/time.h>
-+#endif
-+#ifdef HAVE_SYS_SELECT_H
-+#include <sys/select.h>
-+#endif
-+#ifdef HAVE_STRINGS_H
-+#include <strings.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/nanoftp.h>
-+#include <libxml/xmlerror.h>
-+
-+/* #define DEBUG_FTP 1 */
-+#ifdef STANDALONE
-+#ifndef DEBUG_FTP
-+#define DEBUG_FTP 1
-+#endif
-+#endif
-+
-+/**
-+ * A couple portability macros
-+ */
-+#ifndef _WINSOCKAPI_
-+#define closesocket(s) close(s)
-+#define SOCKET int
-+#endif
-+
-+static char hostname[100];
-+
-+#define FTP_COMMAND_OK 200
-+#define FTP_SYNTAX_ERROR 500
-+#define FTP_GET_PASSWD 331
-+#define FTP_BUF_SIZE 512
-+
-+typedef struct xmlNanoFTPCtxt {
-+ char *protocol; /* the protocol name */
-+ char *hostname; /* the host name */
-+ int port; /* the port */
-+ char *path; /* the path within the URL */
-+ char *user; /* user string */
-+ char *passwd; /* passwd string */
-+ struct sockaddr_in ftpAddr; /* the socket address struct */
-+ int passive; /* currently we support only passive !!! */
-+ SOCKET controlFd; /* the file descriptor for the control socket */
-+ SOCKET dataFd; /* the file descriptor for the data socket */
-+ int state; /* WRITE / READ / CLOSED */
-+ int returnValue; /* the protocol return value */
-+ /* buffer for data received from the control connection */
-+ char controlBuf[FTP_BUF_SIZE + 1];
-+ int controlBufIndex;
-+ int controlBufUsed;
-+ int controlBufAnswer;
-+} xmlNanoFTPCtxt, *xmlNanoFTPCtxtPtr;
-+
-+static int initialized = 0;
-+static char *proxy = NULL; /* the proxy name if any */
-+static int proxyPort = 0; /* the proxy port if any */
-+static char *proxyUser = NULL; /* user for proxy authentication */
-+static char *proxyPasswd = NULL;/* passwd for proxy authentication */
-+static int proxyType = 0; /* uses TYPE or a@b ? */
-+
-+/**
-+ * xmlNanoFTPInit:
-+ *
-+ * Initialize the FTP protocol layer.
-+ * Currently it just checks for proxy informations,
-+ * and get the hostname
-+ */
-+
-+void
-+xmlNanoFTPInit(void) {
-+ const char *env;
-+#ifdef _WINSOCKAPI_
-+ WSADATA wsaData;
-+#endif
-+
-+ if (initialized)
-+ return;
-+
-+#ifdef _WINSOCKAPI_
-+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
-+ return;
-+#endif
-+
-+ gethostname(hostname, sizeof(hostname));
-+
-+ proxyPort = 21;
-+ env = getenv("no_proxy");
-+ if (env != NULL)
-+ return;
-+ env = getenv("ftp_proxy");
-+ if (env != NULL) {
-+ xmlNanoFTPScanProxy(env);
-+ } else {
-+ env = getenv("FTP_PROXY");
-+ if (env != NULL) {
-+ xmlNanoFTPScanProxy(env);
-+ }
-+ }
-+ env = getenv("ftp_proxy_user");
-+ if (env != NULL) {
-+ proxyUser = xmlMemStrdup(env);
-+ }
-+ env = getenv("ftp_proxy_password");
-+ if (env != NULL) {
-+ proxyPasswd = xmlMemStrdup(env);
-+ }
-+ initialized = 1;
-+}
-+
-+/**
-+ * xmlNanoFTPClenup:
-+ *
-+ * Cleanup the FTP protocol layer. This cleanup proxy informations.
-+ */
-+
-+void
-+xmlNanoFTPCleanup(void) {
-+ if (proxy != NULL) {
-+ xmlFree(proxy);
-+ proxy = NULL;
-+ }
-+ if (proxyUser != NULL) {
-+ xmlFree(proxyUser);
-+ proxyUser = NULL;
-+ }
-+ if (proxyPasswd != NULL) {
-+ xmlFree(proxyPasswd);
-+ proxyPasswd = NULL;
-+ }
-+ hostname[0] = 0;
-+#ifdef _WINSOCKAPI_
-+ if (initialized)
-+ WSACleanup();
-+#endif
-+ initialized = 0;
-+ return;
-+}
-+
-+/**
-+ * xmlNanoFTPProxy:
-+ * @host: the proxy host name
-+ * @port: the proxy port
-+ * @user: the proxy user name
-+ * @passwd: the proxy password
-+ * @type: the type of proxy 1 for using SITE, 2 for USER a@b
-+ *
-+ * Setup the FTP proxy informations.
-+ * This can also be done by using ftp_proxy ftp_proxy_user and
-+ * ftp_proxy_password environment variables.
-+ */
-+
-+void
-+xmlNanoFTPProxy(const char *host, int port, const char *user,
-+ const char *passwd, int type) {
-+ if (proxy != NULL)
-+ xmlFree(proxy);
-+ if (proxyUser != NULL)
-+ xmlFree(proxyUser);
-+ if (proxyPasswd != NULL)
-+ xmlFree(proxyPasswd);
-+ if (host)
-+ proxy = xmlMemStrdup(host);
-+ if (user)
-+ proxyUser = xmlMemStrdup(user);
-+ if (passwd)
-+ proxyPasswd = xmlMemStrdup(passwd);
-+ proxyPort = port;
-+ proxyType = type;
-+}
-+
-+/**
-+ * xmlNanoFTPScanURL:
-+ * @ctx: an FTP context
-+ * @URL: The URL used to initialize the context
-+ *
-+ * (Re)Initialize an FTP context by parsing the URL and finding
-+ * the protocol host port and path it indicates.
-+ */
-+
-+static void
-+xmlNanoFTPScanURL(void *ctx, const char *URL) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ const char *cur = URL;
-+ char buf[4096];
-+ int index = 0;
-+ int port = 0;
-+
-+ if (ctxt->protocol != NULL) {
-+ xmlFree(ctxt->protocol);
-+ ctxt->protocol = NULL;
-+ }
-+ if (ctxt->hostname != NULL) {
-+ xmlFree(ctxt->hostname);
-+ ctxt->hostname = NULL;
-+ }
-+ if (ctxt->path != NULL) {
-+ xmlFree(ctxt->path);
-+ ctxt->path = NULL;
-+ }
-+ if (URL == NULL) return;
-+ buf[index] = 0;
-+ while (*cur != 0) {
-+ if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-+ buf[index] = 0;
-+ ctxt->protocol = xmlMemStrdup(buf);
-+ index = 0;
-+ cur += 3;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0) return;
-+
-+ buf[index] = 0;
-+ while (1) {
-+ if (cur[0] == ':') {
-+ buf[index] = 0;
-+ ctxt->hostname = xmlMemStrdup(buf);
-+ index = 0;
-+ cur += 1;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ port *= 10;
-+ port += *cur - '0';
-+ cur++;
-+ }
-+ if (port != 0) ctxt->port = port;
-+ while ((cur[0] != '/') && (*cur != 0))
-+ cur++;
-+ break;
-+ }
-+ if ((*cur == '/') || (*cur == 0)) {
-+ buf[index] = 0;
-+ ctxt->hostname = xmlMemStrdup(buf);
-+ index = 0;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0)
-+ ctxt->path = xmlMemStrdup("/");
-+ else {
-+ index = 0;
-+ buf[index] = 0;
-+ while (*cur != 0)
-+ buf[index++] = *cur++;
-+ buf[index] = 0;
-+ ctxt->path = xmlMemStrdup(buf);
-+ }
-+}
-+
-+/**
-+ * xmlNanoFTPUpdateURL:
-+ * @ctx: an FTP context
-+ * @URL: The URL used to update the context
-+ *
-+ * Update an FTP context by parsing the URL and finding
-+ * new path it indicates. If there is an error in the
-+ * protocol, hostname, port or other information, the
-+ * error is raised. It indicates a new connection has to
-+ * be established.
-+ *
-+ * Returns 0 if Ok, -1 in case of error (other host).
-+ */
-+
-+int
-+xmlNanoFTPUpdateURL(void *ctx, const char *URL) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ const char *cur = URL;
-+ char buf[4096];
-+ int index = 0;
-+ int port = 0;
-+
-+ if (URL == NULL)
-+ return(-1);
-+ if (ctxt == NULL)
-+ return(-1);
-+ if (ctxt->protocol == NULL)
-+ return(-1);
-+ if (ctxt->hostname == NULL)
-+ return(-1);
-+ buf[index] = 0;
-+ while (*cur != 0) {
-+ if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-+ buf[index] = 0;
-+ if (strcmp(ctxt->protocol, buf))
-+ return(-1);
-+ index = 0;
-+ cur += 3;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0)
-+ return(-1);
-+
-+ buf[index] = 0;
-+ while (1) {
-+ if (cur[0] == ':') {
-+ buf[index] = 0;
-+ if (strcmp(ctxt->hostname, buf))
-+ return(-1);
-+ index = 0;
-+ cur += 1;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ port *= 10;
-+ port += *cur - '0';
-+ cur++;
-+ }
-+ if (port != ctxt->port)
-+ return(-1);
-+ while ((cur[0] != '/') && (*cur != 0))
-+ cur++;
-+ break;
-+ }
-+ if ((*cur == '/') || (*cur == 0)) {
-+ buf[index] = 0;
-+ if (strcmp(ctxt->hostname, buf))
-+ return(-1);
-+ index = 0;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (ctxt->path != NULL) {
-+ xmlFree(ctxt->path);
-+ ctxt->path = NULL;
-+ }
-+
-+ if (*cur == 0)
-+ ctxt->path = xmlMemStrdup("/");
-+ else {
-+ index = 0;
-+ buf[index] = 0;
-+ while (*cur != 0)
-+ buf[index++] = *cur++;
-+ buf[index] = 0;
-+ ctxt->path = xmlMemStrdup(buf);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPScanProxy:
-+ * @URL: The proxy URL used to initialize the proxy context
-+ *
-+ * (Re)Initialize the FTP Proxy context by parsing the URL and finding
-+ * the protocol host port it indicates.
-+ * Should be like ftp://myproxy/ or ftp://myproxy:3128/
-+ * A NULL URL cleans up proxy informations.
-+ */
-+
-+void
-+xmlNanoFTPScanProxy(const char *URL) {
-+ const char *cur = URL;
-+ char buf[4096];
-+ int index = 0;
-+ int port = 0;
-+
-+ if (proxy != NULL) {
-+ xmlFree(proxy);
-+ proxy = NULL;
-+ }
-+ if (proxyPort != 0) {
-+ proxyPort = 0;
-+ }
-+#ifdef DEBUG_FTP
-+ if (URL == NULL)
-+ xmlGenericError(xmlGenericErrorContext, "Removing FTP proxy info\n");
-+ else
-+ xmlGenericError(xmlGenericErrorContext, "Using FTP proxy %s\n", URL);
-+#endif
-+ if (URL == NULL) return;
-+ buf[index] = 0;
-+ while (*cur != 0) {
-+ if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-+ buf[index] = 0;
-+ index = 0;
-+ cur += 3;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0) return;
-+
-+ buf[index] = 0;
-+ while (1) {
-+ if (cur[0] == ':') {
-+ buf[index] = 0;
-+ proxy = xmlMemStrdup(buf);
-+ index = 0;
-+ cur += 1;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ port *= 10;
-+ port += *cur - '0';
-+ cur++;
-+ }
-+ if (port != 0) proxyPort = port;
-+ while ((cur[0] != '/') && (*cur != 0))
-+ cur++;
-+ break;
-+ }
-+ if ((*cur == '/') || (*cur == 0)) {
-+ buf[index] = 0;
-+ proxy = xmlMemStrdup(buf);
-+ index = 0;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+}
-+
-+/**
-+ * xmlNanoFTPNewCtxt:
-+ * @URL: The URL used to initialize the context
-+ *
-+ * Allocate and initialize a new FTP context.
-+ *
-+ * Returns an FTP context or NULL in case of error.
-+ */
-+
-+void*
-+xmlNanoFTPNewCtxt(const char *URL) {
-+ xmlNanoFTPCtxtPtr ret;
-+
-+ ret = (xmlNanoFTPCtxtPtr) xmlMalloc(sizeof(xmlNanoFTPCtxt));
-+ if (ret == NULL) return(NULL);
-+
-+ memset(ret, 0, sizeof(xmlNanoFTPCtxt));
-+ ret->port = 21;
-+ ret->passive = 1;
-+ ret->returnValue = 0;
-+ ret->controlBufIndex = 0;
-+ ret->controlBufUsed = 0;
-+
-+ if (URL != NULL)
-+ xmlNanoFTPScanURL(ret, URL);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlNanoFTPFreeCtxt:
-+ * @ctx: an FTP context
-+ *
-+ * Frees the context after closing the connection.
-+ */
-+
-+void
-+xmlNanoFTPFreeCtxt(void * ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ if (ctxt == NULL) return;
-+ if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
-+ if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
-+ if (ctxt->path != NULL) xmlFree(ctxt->path);
-+ ctxt->passive = 1;
-+ if (ctxt->controlFd >= 0) closesocket(ctxt->controlFd);
-+ ctxt->controlFd = -1;
-+ ctxt->controlBufIndex = -1;
-+ ctxt->controlBufUsed = -1;
-+ xmlFree(ctxt);
-+}
-+
-+/**
-+ * xmlNanoFTPParseResponse:
-+ * @ctx: the FTP connection context
-+ * @buf: the buffer containing the response
-+ * @len: the buffer length
-+ *
-+ * Parsing of the server answer, we just extract the code.
-+ *
-+ * returns 0 for errors
-+ * +XXX for last line of response
-+ * -XXX for response to be continued
-+ */
-+static int
-+xmlNanoFTPParseResponse(void *ctx, char *buf, int len) {
-+ int val = 0;
-+
-+ if (len < 3) return(-1);
-+ if ((*buf >= '0') && (*buf <= '9'))
-+ val = val * 10 + (*buf - '0');
-+ else
-+ return(0);
-+ buf++;
-+ if ((*buf >= '0') && (*buf <= '9'))
-+ val = val * 10 + (*buf - '0');
-+ else
-+ return(0);
-+ buf++;
-+ if ((*buf >= '0') && (*buf <= '9'))
-+ val = val * 10 + (*buf - '0');
-+ else
-+ return(0);
-+ buf++;
-+ if (*buf == '-')
-+ return(-val);
-+ return(val);
-+}
-+
-+/**
-+ * xmlNanoFTPGetMore:
-+ * @ctx: an FTP context
-+ *
-+ * Read more information from the FTP control connection
-+ * Returns the number of bytes read, < 0 indicates an error
-+ */
-+static int
-+xmlNanoFTPGetMore(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ int len;
-+ int size;
-+
-+ if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPGetMore : controlBufIndex = %d\n",
-+ ctxt->controlBufIndex);
-+#endif
-+ return(-1);
-+ }
-+
-+ if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPGetMore : controlBufUsed = %d\n",
-+ ctxt->controlBufUsed);
-+#endif
-+ return(-1);
-+ }
-+ if (ctxt->controlBufIndex > ctxt->controlBufUsed) {
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",
-+ ctxt->controlBufIndex, ctxt->controlBufUsed);
-+#endif
-+ return(-1);
-+ }
-+
-+ /*
-+ * First pack the control buffer
-+ */
-+ if (ctxt->controlBufIndex > 0) {
-+ memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],
-+ ctxt->controlBufUsed - ctxt->controlBufIndex);
-+ ctxt->controlBufUsed -= ctxt->controlBufIndex;
-+ ctxt->controlBufIndex = 0;
-+ }
-+ size = FTP_BUF_SIZE - ctxt->controlBufUsed;
-+ if (size == 0) {
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);
-+#endif
-+ return(0);
-+ }
-+
-+ /*
-+ * Read the amount left on teh control connection
-+ */
-+ if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
-+ size, 0)) < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPGetMore : read %d [%d - %d]\n", len,
-+ ctxt->controlBufUsed, ctxt->controlBufUsed + len);
-+#endif
-+ ctxt->controlBufUsed += len;
-+ ctxt->controlBuf[ctxt->controlBufUsed] = 0;
-+
-+ return(len);
-+}
-+
-+/**
-+ * xmlNanoFTPReadResponse:
-+ * @ctx: an FTP context
-+ *
-+ * Read the response from the FTP server after a command.
-+ * Returns the code number
-+ */
-+static int
-+xmlNanoFTPReadResponse(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char *ptr, *end;
-+ int len;
-+ int res = -1, cur = -1;
-+
-+get_more:
-+ /*
-+ * Assumes everything up to controlBuf[controlBufIndex] has been read
-+ * and analyzed.
-+ */
-+ len = xmlNanoFTPGetMore(ctx);
-+ if (len < 0) {
-+ return(-1);
-+ }
-+ if ((ctxt->controlBufUsed == 0) && (len == 0)) {
-+ return(-1);
-+ }
-+ ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
-+ end = &ctxt->controlBuf[ctxt->controlBufUsed];
-+
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\n<<<\n%s\n--\n", ptr);
-+#endif
-+ while (ptr < end) {
-+ cur = xmlNanoFTPParseResponse(ctxt, ptr, end - ptr);
-+ if (cur > 0) {
-+ /*
-+ * Successfully scanned the control code, scratch
-+ * till the end of the line, but keep the index to be
-+ * able to analyze the result if needed.
-+ */
-+ res = cur;
-+ ptr += 3;
-+ ctxt->controlBufAnswer = ptr - ctxt->controlBuf;
-+ while ((ptr < end) && (*ptr != '\n')) ptr++;
-+ if (*ptr == '\n') ptr++;
-+ if (*ptr == '\r') ptr++;
-+ break;
-+ }
-+ while ((ptr < end) && (*ptr != '\n')) ptr++;
-+ if (ptr >= end) {
-+ ctxt->controlBufIndex = ctxt->controlBufUsed;
-+ goto get_more;
-+ }
-+ if (*ptr != '\r') ptr++;
-+ }
-+
-+ if (res < 0) goto get_more;
-+ ctxt->controlBufIndex = ptr - ctxt->controlBuf;
-+#ifdef DEBUG_FTP
-+ ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
-+ xmlGenericError(xmlGenericErrorContext, "\n---\n%s\n--\n", ptr);
-+#endif
-+
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, "Got %d\n", res);
-+#endif
-+ return(res / 100);
-+}
-+
-+/**
-+ * xmlNanoFTPGetResponse:
-+ * @ctx: an FTP context
-+ *
-+ * Get the response from the FTP server after a command.
-+ * Returns the code number
-+ */
-+
-+int
-+xmlNanoFTPGetResponse(void *ctx) {
-+ int res;
-+
-+ res = xmlNanoFTPReadResponse(ctx);
-+
-+ return(res);
-+}
-+
-+/**
-+ * xmlNanoFTPCheckResponse:
-+ * @ctx: an FTP context
-+ *
-+ * Check if there is a response from the FTP server after a command.
-+ * Returns the code number, or 0
-+ */
-+
-+int
-+xmlNanoFTPCheckResponse(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ fd_set rfd;
-+ struct timeval tv;
-+
-+ tv.tv_sec = 0;
-+ tv.tv_usec = 0;
-+ FD_ZERO(&rfd);
-+ FD_SET(ctxt->controlFd, &rfd);
-+ switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) {
-+ case 0:
-+ return(0);
-+ case -1:
-+#ifdef DEBUG_FTP
-+ perror("select");
-+#endif
-+ return(-1);
-+
-+ }
-+
-+ return(xmlNanoFTPReadResponse(ctx));
-+}
-+
-+/**
-+ * Send the user authentification
-+ */
-+
-+static int
-+xmlNanoFTPSendUser(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[200];
-+ int len;
-+ int res;
-+
-+ if (ctxt->user == NULL)
-+ sprintf(buf, "USER anonymous\r\n");
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
-+#else
-+ sprintf(buf, "USER %s\r\n", ctxt->user);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) return(res);
-+ return(0);
-+}
-+
-+/**
-+ * Send the password authentification
-+ */
-+
-+static int
-+xmlNanoFTPSendPasswd(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[200];
-+ int len;
-+ int res;
-+
-+ if (ctxt->passwd == NULL)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
-+#else
-+ sprintf(buf, "PASS libxml@%s\r\n", hostname);
-+#endif
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
-+#else
-+ sprintf(buf, "PASS %s\r\n", ctxt->passwd);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) return(res);
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPQuit:
-+ * @ctx: an FTP context
-+ *
-+ * Send a QUIT command to the server
-+ *
-+ * Returns -1 in case of error, 0 otherwise
-+ */
-+
-+
-+int
-+xmlNanoFTPQuit(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[200];
-+ int len;
-+ int res;
-+
-+ sprintf(buf, "QUIT\r\n");
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPConnect:
-+ * @ctx: an FTP context
-+ *
-+ * Tries to open a control connection
-+ *
-+ * Returns -1 in case of error, 0 otherwise
-+ */
-+
-+int
-+xmlNanoFTPConnect(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ struct hostent *hp;
-+ int port;
-+ int res;
-+
-+ if (ctxt == NULL)
-+ return(-1);
-+ if (ctxt->hostname == NULL)
-+ return(-1);
-+
-+ /*
-+ * do the blocking DNS query.
-+ */
-+ if (proxy)
-+ hp = gethostbyname(proxy);
-+ else
-+ hp = gethostbyname(ctxt->hostname);
-+ if (hp == NULL)
-+ return(-1);
-+
-+ /*
-+ * Prepare the socket
-+ */
-+ memset(&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
-+ ctxt->ftpAddr.sin_family = AF_INET;
-+ memcpy(&ctxt->ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
-+ if (proxy) {
-+ port = proxyPort;
-+ } else {
-+ port = ctxt->port;
-+ }
-+ if (port == 0)
-+ port = 21;
-+ ctxt->ftpAddr.sin_port = htons(port);
-+ ctxt->controlFd = socket(AF_INET, SOCK_STREAM, 0);
-+ if (ctxt->controlFd < 0)
-+ return(-1);
-+
-+ /*
-+ * Do the connect.
-+ */
-+ if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
-+ sizeof(struct sockaddr_in)) < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+
-+ /*
-+ * Wait for the HELLO from the server.
-+ */
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if (res != 2) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+
-+ /*
-+ * State diagram for the login operation on the FTP server
-+ *
-+ * Reference: RFC 959
-+ *
-+ * 1
-+ * +---+ USER +---+------------->+---+
-+ * | B |---------->| W | 2 ---->| E |
-+ * +---+ +---+------ | -->+---+
-+ * | | | | |
-+ * 3 | | 4,5 | | |
-+ * -------------- ----- | | |
-+ * | | | | |
-+ * | | | | |
-+ * | --------- |
-+ * | 1| | | |
-+ * V | | | |
-+ * +---+ PASS +---+ 2 | ------>+---+
-+ * | |---------->| W |------------->| S |
-+ * +---+ +---+ ---------->+---+
-+ * | | | | |
-+ * 3 | |4,5| | |
-+ * -------------- -------- |
-+ * | | | | |
-+ * | | | | |
-+ * | -----------
-+ * | 1,3| | | |
-+ * V | 2| | |
-+ * +---+ ACCT +---+-- | ----->+---+
-+ * | |---------->| W | 4,5 -------->| F |
-+ * +---+ +---+------------->+---+
-+ *
-+ * Of course in case of using a proxy this get really nasty and is not
-+ * standardized at all :-(
-+ */
-+ if (proxy) {
-+ int len;
-+ char buf[400];
-+
-+ if (proxyUser != NULL) {
-+ /*
-+ * We need proxy auth
-+ */
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
-+#else
-+ sprintf(buf, "USER %s\r\n", proxyUser);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd);
-+ ctxt->controlFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ switch (res) {
-+ case 2:
-+ if (proxyPasswd == NULL)
-+ break;
-+ case 3:
-+ if (proxyPasswd != NULL)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
-+#else
-+ sprintf(buf, "PASS %s\r\n", proxyPasswd);
-+#endif
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n",
-+ hostname);
-+#else
-+ sprintf(buf, "PASS libxml@%s\r\n", hostname);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd);
-+ ctxt->controlFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if (res > 3) {
-+ closesocket(ctxt->controlFd);
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ break;
-+ case 1:
-+ break;
-+ case 4:
-+ case 5:
-+ case -1:
-+ default:
-+ closesocket(ctxt->controlFd);
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ }
-+
-+ /*
-+ * We assume we don't need more authentication to the proxy
-+ * and that it succeeded :-\
-+ */
-+ switch (proxyType) {
-+ case 0:
-+ /* we will try in seqence */
-+ case 1:
-+ /* Using SITE command */
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
-+#else
-+ sprintf(buf, "SITE %s\r\n", ctxt->hostname);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if (res == 2) {
-+ /* we assume it worked :-\ 1 is error for SITE command */
-+ proxyType = 1;
-+ break;
-+ }
-+ if (proxyType == 1) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ case 2:
-+ /* USER user@host command */
-+ if (ctxt->user == NULL)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
-+ ctxt->hostname);
-+#else
-+ sprintf(buf, "USER anonymous@%s\r\n", ctxt->hostname);
-+#endif
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
-+ ctxt->user, ctxt->hostname);
-+#else
-+ sprintf(buf, "USER %s@%s\r\n",
-+ ctxt->user, ctxt->hostname);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if ((res == 1) || (res == 2)) {
-+ /* we assume it worked :-\ */
-+ proxyType = 2;
-+ return(0);
-+ }
-+ if (ctxt->passwd == NULL)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
-+#else
-+ sprintf(buf, "PASS libxml@%s\r\n", hostname);
-+#endif
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
-+#else
-+ sprintf(buf, "PASS %s\r\n", ctxt->passwd);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if ((res == 1) || (res == 2)) {
-+ /* we assume it worked :-\ */
-+ proxyType = 2;
-+ return(0);
-+ }
-+ if (proxyType == 2) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ case 3:
-+ /*
-+ * If you need support for other Proxy authentication scheme
-+ * send the code or at least the sequence in use.
-+ */
-+ default:
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ }
-+ /*
-+ * Non-proxy handling.
-+ */
-+ res = xmlNanoFTPSendUser(ctxt);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ switch (res) {
-+ case 2:
-+ return(0);
-+ case 3:
-+ break;
-+ case 1:
-+ case 4:
-+ case 5:
-+ case -1:
-+ default:
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ res = xmlNanoFTPSendPasswd(ctxt);
-+ if (res < 0) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ switch (res) {
-+ case 2:
-+ break;
-+ case 3:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "FTP server asking for ACCNT on anonymous\n");
-+ case 1:
-+ case 4:
-+ case 5:
-+ case -1:
-+ default:
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPConnectTo:
-+ * @server: an FTP server name
-+ * @port: the port (use 21 if 0)
-+ *
-+ * Tries to open a control connection to the given server/port
-+ *
-+ * Returns an fTP context or NULL if it failed
-+ */
-+
-+void*
-+xmlNanoFTPConnectTo(const char *server, int port) {
-+ xmlNanoFTPCtxtPtr ctxt;
-+ int res;
-+
-+ xmlNanoFTPInit();
-+ if (server == NULL)
-+ return(NULL);
-+ ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
-+ ctxt->hostname = xmlMemStrdup(server);
-+ if (port != 0)
-+ ctxt->port = port;
-+ res = xmlNanoFTPConnect(ctxt);
-+ if (res < 0) {
-+ xmlNanoFTPFreeCtxt(ctxt);
-+ return(NULL);
-+ }
-+ return(ctxt);
-+}
-+
-+/**
-+ * xmlNanoFTPCwd:
-+ * @ctx: an FTP context
-+ * @directory: a directory on the server
-+ *
-+ * Tries to change the remote directory
-+ *
-+ * Returns -1 incase of error, 1 if CWD worked, 0 if it failed
-+ */
-+
-+int
-+xmlNanoFTPCwd(void *ctx, char *directory) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[400];
-+ int len;
-+ int res;
-+
-+ /*
-+ * Expected response code for CWD:
-+ *
-+ * CWD
-+ * 250
-+ * 500, 501, 502, 421, 530, 550
-+ */
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
-+#else
-+ sprintf(buf, "CWD %s\r\n", directory);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) return(res);
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if (res == 4) {
-+ return(-1);
-+ }
-+ if (res == 2) return(1);
-+ if (res == 5) {
-+ return(0);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPGetConnection:
-+ * @ctx: an FTP context
-+ *
-+ * Try to open a data connection to the server. Currently only
-+ * passive mode is supported.
-+ *
-+ * Returns -1 incase of error, 0 otherwise
-+ */
-+
-+int
-+xmlNanoFTPGetConnection(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[200], *cur;
-+ int len, i;
-+ int res;
-+ unsigned char ad[6], *adp, *portp;
-+ unsigned int temp[6];
-+ struct sockaddr_in dataAddr;
-+ SOCKLEN_T dataAddrLen;
-+
-+ ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
-+ if (ctxt->dataFd < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPGetConnection: failed to create socket\n");
-+ return(-1);
-+ }
-+ dataAddrLen = sizeof(dataAddr);
-+ memset(&dataAddr, 0, dataAddrLen);
-+ dataAddr.sin_family = AF_INET;
-+
-+ if (ctxt->passive) {
-+ sprintf(buf, "PASV\r\n");
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPReadResponse(ctx);
-+ if (res != 2) {
-+ if (res == 5) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-1);
-+ } else {
-+ /*
-+ * retry with an active connection
-+ */
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ ctxt->passive = 0;
-+ }
-+ }
-+ cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
-+ while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
-+ if (sscanf(cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
-+ &temp[3], &temp[4], &temp[5]) != 6) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Invalid answer to PASV\n");
-+ if (ctxt->dataFd != -1) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ }
-+ return(-1);
-+ }
-+ for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
-+ memcpy(&dataAddr.sin_addr, &ad[0], 4);
-+ memcpy(&dataAddr.sin_port, &ad[4], 2);
-+ if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to create a data connection\n");
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return (-1);
-+ }
-+ } else {
-+ getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
-+ dataAddr.sin_port = 0;
-+ if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to bind a port\n");
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return (-1);
-+ }
-+ getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
-+
-+ if (listen(ctxt->dataFd, 1) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Could not listen on port %d\n",
-+ ntohs(dataAddr.sin_port));
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return (-1);
-+ }
-+ adp = (unsigned char *) &dataAddr.sin_addr;
-+ portp = (unsigned char *) &dataAddr.sin_port;
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
-+ adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
-+ portp[0] & 0xff, portp[1] & 0xff);
-+#else
-+ sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",
-+ adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
-+ portp[0] & 0xff, portp[1] & 0xff);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if (res != 2) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+ }
-+ return(ctxt->dataFd);
-+
-+}
-+
-+/**
-+ * xmlNanoFTPCloseConnection:
-+ * @ctx: an FTP context
-+ *
-+ * Close the data connection from the server
-+ *
-+ * Returns -1 incase of error, 0 otherwise
-+ */
-+
-+int
-+xmlNanoFTPCloseConnection(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ int res;
-+ fd_set rfd, efd;
-+ struct timeval tv;
-+
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ tv.tv_sec = 15;
-+ tv.tv_usec = 0;
-+ FD_ZERO(&rfd);
-+ FD_SET(ctxt->controlFd, &rfd);
-+ FD_ZERO(&efd);
-+ FD_SET(ctxt->controlFd, &efd);
-+ res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);
-+ if (res < 0) {
-+#ifdef DEBUG_FTP
-+ perror("select");
-+#endif
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ if (res == 0) {
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNanoFTPCloseConnection: timeout\n");
-+#endif
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ } else {
-+ res = xmlNanoFTPGetResponse(ctxt);
-+ if (res != 2) {
-+ closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-+ return(-1);
-+ }
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPParseList:
-+ * @list: some data listing received from the server
-+ * @callback: the user callback
-+ * @userData: the user callback data
-+ *
-+ * Parse at most one entry from the listing.
-+ *
-+ * Returns -1 incase of error, the lenght of data parsed otherwise
-+ */
-+
-+static int
-+xmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) {
-+ const char *cur = list;
-+ char filename[151];
-+ char attrib[11];
-+ char owner[11];
-+ char group[11];
-+ char month[4];
-+ int year = 0;
-+ int minute = 0;
-+ int hour = 0;
-+ int day = 0;
-+ unsigned long size = 0;
-+ int links = 0;
-+ int i;
-+
-+ if (!strncmp(cur, "total", 5)) {
-+ cur += 5;
-+ while (*cur == ' ') cur++;
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ links = (links * 10) + (*cur++ - '0');
-+ while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
-+ cur++;
-+ return(cur - list);
-+ } else if (*list == '+') {
-+ return(0);
-+ } else {
-+ while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
-+ cur++;
-+ if (*cur == 0) return(0);
-+ i = 0;
-+ while (*cur != ' ') {
-+ if (i < 10)
-+ attrib[i++] = *cur;
-+ cur++;
-+ if (*cur == 0) return(0);
-+ }
-+ attrib[10] = 0;
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ links = (links * 10) + (*cur++ - '0');
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ i = 0;
-+ while (*cur != ' ') {
-+ if (i < 10)
-+ owner[i++] = *cur;
-+ cur++;
-+ if (*cur == 0) return(0);
-+ }
-+ owner[i] = 0;
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ i = 0;
-+ while (*cur != ' ') {
-+ if (i < 10)
-+ group[i++] = *cur;
-+ cur++;
-+ if (*cur == 0) return(0);
-+ }
-+ group[i] = 0;
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ size = (size * 10) + (*cur++ - '0');
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ i = 0;
-+ while (*cur != ' ') {
-+ if (i < 3)
-+ month[i++] = *cur;
-+ cur++;
-+ if (*cur == 0) return(0);
-+ }
-+ month[i] = 0;
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ day = (day * 10) + (*cur++ - '0');
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ if ((cur[1] == 0) || (cur[2] == 0)) return(0);
-+ if ((cur[1] == ':') || (cur[2] == ':')) {
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ hour = (hour * 10) + (*cur++ - '0');
-+ if (*cur == ':') cur++;
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ minute = (minute * 10) + (*cur++ - '0');
-+ } else {
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ year = (year * 10) + (*cur++ - '0');
-+ }
-+ while (*cur == ' ') cur++;
-+ if (*cur == 0) return(0);
-+ i = 0;
-+ while ((*cur != '\n') && (*cur != '\r')) {
-+ if (i < 150)
-+ filename[i++] = *cur;
-+ cur++;
-+ if (*cur == 0) return(0);
-+ }
-+ filename[i] = 0;
-+ if ((*cur != '\n') && (*cur != '\r'))
-+ return(0);
-+ while ((*cur == '\n') || (*cur == '\r'))
-+ cur++;
-+ }
-+ if (callback != NULL) {
-+ callback(userData, filename, attrib, owner, group, size, links,
-+ year, month, day, hour, minute);
-+ }
-+ return(cur - list);
-+}
-+
-+/**
-+ * xmlNanoFTPList:
-+ * @ctx: an FTP context
-+ * @callback: the user callback
-+ * @userData: the user callback data
-+ * @filename: optional files to list
-+ *
-+ * Do a listing on the server. All files info are passed back
-+ * in the callbacks.
-+ *
-+ * Returns -1 incase of error, 0 otherwise
-+ */
-+
-+int
-+xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
-+ char *filename) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[4096 + 1];
-+ int len, res;
-+ int index = 0, base;
-+ fd_set rfd, efd;
-+ struct timeval tv;
-+
-+ if (filename == NULL) {
-+ if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
-+ return(-1);
-+ ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-+ if (ctxt->dataFd == -1)
-+ return(-1);
-+ sprintf(buf, "LIST -L\r\n");
-+ } else {
-+ if (filename[0] != '/') {
-+ if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
-+ return(-1);
-+ }
-+ ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-+ if (ctxt->dataFd == -1)
-+ return(-1);
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
-+#else
-+ sprintf(buf, "LIST -L %s\r\n", filename);
-+#endif
-+ }
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPReadResponse(ctxt);
-+ if (res != 1) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-res);
-+ }
-+
-+ do {
-+ tv.tv_sec = 1;
-+ tv.tv_usec = 0;
-+ FD_ZERO(&rfd);
-+ FD_SET(ctxt->dataFd, &rfd);
-+ FD_ZERO(&efd);
-+ FD_SET(ctxt->dataFd, &efd);
-+ res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv);
-+ if (res < 0) {
-+#ifdef DEBUG_FTP
-+ perror("select");
-+#endif
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+ if (res == 0) {
-+ res = xmlNanoFTPCheckResponse(ctxt);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+ if (res == 2) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(0);
-+ }
-+
-+ continue;
-+ }
-+
-+ if ((len = recv(ctxt->dataFd, &buf[index], sizeof(buf) - (index + 1), 0)) < 0) {
-+#ifdef DEBUG_FTP
-+ perror("recv");
-+#endif
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+#ifdef DEBUG_FTP
-+ write(1, &buf[index], len);
-+#endif
-+ index += len;
-+ buf[index] = 0;
-+ base = 0;
-+ do {
-+ res = xmlNanoFTPParseList(&buf[base], callback, userData);
-+ base += res;
-+ } while (res > 0);
-+
-+ memmove(&buf[0], &buf[base], index - base);
-+ index -= base;
-+ } while (len != 0);
-+ xmlNanoFTPCloseConnection(ctxt);
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoFTPGetSocket:
-+ * @ctx: an FTP context
-+ * @filename: the file to retrieve (or NULL if path is in context).
-+ *
-+ * Initiate fetch of the given file from the server.
-+ *
-+ * Returns the socket for the data connection, or <0 in case of error
-+ */
-+
-+
-+int
-+xmlNanoFTPGetSocket(void *ctx, const char *filename) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[300];
-+ int res, len;
-+ if ((filename == NULL) && (ctxt->path == NULL))
-+ return(-1);
-+ ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-+ if (ctxt->dataFd == -1)
-+ return(-1);
-+
-+ sprintf(buf, "TYPE I\r\n");
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPReadResponse(ctxt);
-+ if (res != 2) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-res);
-+ }
-+ if (filename == NULL)
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
-+#else
-+ sprintf(buf, "RETR %s\r\n", ctxt->path);
-+#endif
-+ else
-+#ifdef HAVE_SNPRINTF
-+ snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
-+#else
-+ sprintf(buf, "RETR %s\r\n", filename);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ len = strlen(buf);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, buf);
-+#endif
-+ res = send(ctxt->controlFd, buf, len, 0);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(res);
-+ }
-+ res = xmlNanoFTPReadResponse(ctxt);
-+ if (res != 1) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-res);
-+ }
-+ return(ctxt->dataFd);
-+}
-+
-+/**
-+ * xmlNanoFTPGet:
-+ * @ctx: an FTP context
-+ * @callback: the user callback
-+ * @userData: the user callback data
-+ * @filename: the file to retrieve
-+ *
-+ * Fetch the given file from the server. All data are passed back
-+ * in the callbacks. The last callback has a size of 0 block.
-+ *
-+ * Returns -1 incase of error, 0 otherwise
-+ */
-+
-+int
-+xmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
-+ const char *filename) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+ char buf[4096];
-+ int len = 0, res;
-+ fd_set rfd;
-+ struct timeval tv;
-+
-+ if ((filename == NULL) && (ctxt->path == NULL))
-+ return(-1);
-+ if (callback == NULL)
-+ return(-1);
-+ if (xmlNanoFTPGetSocket(ctxt, filename) < 0)
-+ return(-1);
-+
-+ do {
-+ tv.tv_sec = 1;
-+ tv.tv_usec = 0;
-+ FD_ZERO(&rfd);
-+ FD_SET(ctxt->dataFd, &rfd);
-+ res = select(ctxt->dataFd + 1, &rfd, NULL, NULL, &tv);
-+ if (res < 0) {
-+#ifdef DEBUG_FTP
-+ perror("select");
-+#endif
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+ if (res == 0) {
-+ res = xmlNanoFTPCheckResponse(ctxt);
-+ if (res < 0) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+ if (res == 2) {
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(0);
-+ }
-+
-+ continue;
-+ }
-+ if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
-+ callback(userData, buf, len);
-+ closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-+ return(-1);
-+ }
-+ callback(userData, buf, len);
-+ } while (len != 0);
-+
-+ return(xmlNanoFTPCloseConnection(ctxt));
-+}
-+
-+/**
-+ * xmlNanoFTPRead:
-+ * @ctx: the FTP context
-+ * @dest: a buffer
-+ * @len: the buffer length
-+ *
-+ * This function tries to read @len bytes from the existing FTP connection
-+ * and saves them in @dest. This is a blocking call.
-+ *
-+ * Returns the number of byte read. 0 is an indication of an end of connection.
-+ * -1 indicates a parameter error.
-+ */
-+int
-+xmlNanoFTPRead(void *ctx, void *dest, int len) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+
-+ if (ctx == NULL) return(-1);
-+ if (ctxt->dataFd < 0) return(0);
-+ if (dest == NULL) return(-1);
-+ if (len <= 0) return(0);
-+
-+ len = recv(ctxt->dataFd, dest, len, 0);
-+#ifdef DEBUG_FTP
-+ xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
-+#endif
-+ if (len <= 0) {
-+ xmlNanoFTPCloseConnection(ctxt);
-+ }
-+ return(len);
-+}
-+
-+/**
-+ * xmlNanoFTPOpen:
-+ * @URL: the URL to the resource
-+ *
-+ * Start to fetch the given ftp:// resource
-+ *
-+ * Returns an FTP context, or NULL
-+ */
-+
-+void*
-+xmlNanoFTPOpen(const char *URL) {
-+ xmlNanoFTPCtxtPtr ctxt;
-+ int sock;
-+
-+ xmlNanoFTPInit();
-+ if (URL == NULL) return(NULL);
-+ if (strncmp("ftp://", URL, 6)) return(NULL);
-+
-+ ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(URL);
-+ if (ctxt == NULL) return(NULL);
-+ if (xmlNanoFTPConnect(ctxt) < 0) {
-+ xmlNanoFTPFreeCtxt(ctxt);
-+ return(NULL);
-+ }
-+ sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
-+ if (sock < 0) {
-+ xmlNanoFTPFreeCtxt(ctxt);
-+ return(NULL);
-+ }
-+ return(ctxt);
-+}
-+
-+/**
-+ * xmlNanoFTPClose:
-+ * @ctx: an FTP context
-+ *
-+ * Close the connection and both control and transport
-+ *
-+ * Returns -1 incase of error, 0 otherwise
-+ */
-+
-+int
-+xmlNanoFTPClose(void *ctx) {
-+ xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-+
-+ if (ctxt == NULL)
-+ return(-1);
-+
-+ if (ctxt->dataFd >= 0) {
-+ closesocket(ctxt->dataFd);
-+ ctxt->dataFd = -1;
-+ }
-+ if (ctxt->controlFd >= 0) {
-+ xmlNanoFTPQuit(ctxt);
-+ closesocket(ctxt->controlFd);
-+ ctxt->controlFd = -1;
-+ }
-+ xmlNanoFTPFreeCtxt(ctxt);
-+ return(0);
-+}
-+
-+#ifdef STANDALONE
-+/************************************************************************
-+ * *
-+ * Basic test in Standalone mode *
-+ * *
-+ ************************************************************************/
-+void ftpList(void *userData, const char *filename, const char* attrib,
-+ const char *owner, const char *group, unsigned long size, int links,
-+ int year, const char *month, int day, int hour, int minute) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s %s %s %ld %s\n", attrib, owner, group, size, filename);
-+}
-+void ftpData(void *userData, const char *data, int len) {
-+ if (userData == NULL) return;
-+ if (len <= 0) {
-+ fclose(userData);
-+ return;
-+ }
-+ fwrite(data, len, 1, userData);
-+}
-+
-+int main(int argc, char **argv) {
-+ void *ctxt;
-+ FILE *output;
-+ char *tstfile = NULL;
-+
-+ xmlNanoFTPInit();
-+ if (argc > 1) {
-+ ctxt = xmlNanoFTPNewCtxt(argv[1]);
-+ if (xmlNanoFTPConnect(ctxt) < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Couldn't connect to %s\n", argv[1]);
-+ exit(1);
-+ }
-+ if (argc > 2)
-+ tstfile = argv[2];
-+ } else
-+ ctxt = xmlNanoFTPConnectTo("localhost", 0);
-+ if (ctxt == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Couldn't connect to localhost\n");
-+ exit(1);
-+ }
-+ xmlNanoFTPList(ctxt, ftpList, NULL, tstfile);
-+ output = fopen("/tmp/tstdata", "w");
-+ if (output != NULL) {
-+ if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Failed to get file\n");
-+
-+ }
-+ xmlNanoFTPClose(ctxt);
-+ xmlMemoryDump();
-+ exit(0);
-+}
-+#endif /* STANDALONE */
-+#else /* !LIBXML_FTP_ENABLED */
-+#ifdef STANDALONE
-+#include <stdio.h>
-+int main(int argc, char **argv) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s : FTP support not compiled in\n", argv[0]);
-+ return(0);
-+}
-+#endif /* STANDALONE */
-+#endif /* LIBXML_FTP_ENABLED */
-diff -Nru libxml2-2.3.0/libxml/nanoftp.h libxml2-2.3.0.new/libxml/nanoftp.h
---- libxml2-2.3.0/libxml/nanoftp.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/nanoftp.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,110 @@
-+/*
-+ * nanohttp.c: minimalist FTP implementation to fetch external subsets.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __NANO_FTP_H__
-+#define __NANO_FTP_H__
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_FTP_ENABLED
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/**
-+ * ftpListCallback:
-+ * @userData: user provided data for the callback
-+ * @filename: the file name (including "->" when links are shown)
-+ * @attrib: the attribute string
-+ * @owner: the owner string
-+ * @group: the group string
-+ * @size: the file size
-+ * @links: the link count
-+ * @year: the year
-+ * @month: the month
-+ * @day: the day
-+ * @hour: the hour
-+ * @minute: the minute
-+ *
-+ * A callback for the xmlNanoFTPList command
-+ * Note that only one of year and day:minute are specified
-+ */
-+typedef void (*ftpListCallback) (void *userData,
-+ const char *filename, const char* attrib,
-+ const char *owner, const char *group,
-+ unsigned long size, int links, int year,
-+ const char *month, int day, int hour,
-+ int minute);
-+/**
-+ * ftpDataCallback:
-+ * A callback for the xmlNanoFTPGet command
-+ */
-+typedef void (*ftpDataCallback) (void *userData, const char *data, int len);
-+
-+/*
-+ * Init
-+ */
-+void xmlNanoFTPInit (void);
-+void xmlNanoFTPCleanup (void);
-+
-+/*
-+ * Creating/freeing contexts
-+ */
-+void * xmlNanoFTPNewCtxt (const char *URL);
-+void xmlNanoFTPFreeCtxt (void * ctx);
-+void * xmlNanoFTPConnectTo (const char *server,
-+ int port);
-+/*
-+ * Opening/closing session connections
-+ */
-+void * xmlNanoFTPOpen (const char *URL);
-+int xmlNanoFTPConnect (void *ctx);
-+int xmlNanoFTPClose (void *ctx);
-+int xmlNanoFTPQuit (void *ctx);
-+void xmlNanoFTPScanProxy (const char *URL);
-+void xmlNanoFTPProxy (const char *host,
-+ int port,
-+ const char *user,
-+ const char *passwd,
-+ int type);
-+int xmlNanoFTPUpdateURL (void *ctx,
-+ const char *URL);
-+
-+/*
-+ * Rathern internal commands
-+ */
-+int xmlNanoFTPGetResponse (void *ctx);
-+int xmlNanoFTPCheckResponse (void *ctx);
-+
-+/*
-+ * CD/DIR/GET handlers
-+ */
-+int xmlNanoFTPCwd (void *ctx,
-+ char *directory);
-+
-+int xmlNanoFTPGetConnection (void *ctx);
-+int xmlNanoFTPCloseConnection(void *ctx);
-+int xmlNanoFTPList (void *ctx,
-+ ftpListCallback callback,
-+ void *userData,
-+ char *filename);
-+int xmlNanoFTPGetSocket (void *ctx,
-+ const char *filename);
-+int xmlNanoFTPGet (void *ctx,
-+ ftpDataCallback callback,
-+ void *userData,
-+ const char *filename);
-+int xmlNanoFTPRead (void *ctx,
-+ void *dest,
-+ int len);
-+
-+#ifdef __cplusplus
-+}
-+#endif /* LIBXML_FTP_ENABLED */
-+#endif
-+#endif /* __NANO_FTP_H__ */
-diff -Nru libxml2-2.3.0/libxml/nanohttp.c libxml2-2.3.0.new/libxml/nanohttp.c
---- libxml2-2.3.0/libxml/nanohttp.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/nanohttp.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,1202 @@
-+/*
-+ * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets.
-+ * focuses on size, streamability, reentrancy and portability
-+ *
-+ * This is clearly not a general purpose HTTP implementation
-+ * If you look for one, check:
-+ * http://www.w3.org/Library/
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+/* TODO add compression support, Send the Accept- , and decompress on the
-+ fly with ZLIB if found at compile-time */
-+
-+#ifdef WIN32
-+#define INCLUDE_WINSOCK
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <libxml/xmlversion.h>
-+
-+#ifdef LIBXML_HTTP_ENABLED
-+#include <stdio.h>
-+#include <string.h>
-+
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_SYS_SOCKET_H
-+#include <sys/socket.h>
-+#endif
-+#ifdef HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+#ifdef HAVE_ARPA_INET_H
-+#include <arpa/inet.h>
-+#endif
-+#ifdef HAVE_NETDB_H
-+#include <netdb.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#ifdef HAVE_SYS_TIME_H
-+#include <sys/time.h>
-+#endif
-+#ifdef HAVE_SYS_SELECT_H
-+#include <sys/select.h>
-+#endif
-+#ifdef HAVE_STRINGS_H
-+#include <strings.h>
-+#endif
-+#ifdef SUPPORT_IP6
-+#include <resolv.h>
-+#endif
-+
-+#ifdef VMS
-+#include <stropts>
-+#define SOCKLEN_T unsigned int
-+#define SOCKET int
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/parser.h> /* for xmlStr(n)casecmp() */
-+#include <libxml/nanohttp.h>
-+
-+/**
-+ * A couple portability macros
-+ */
-+#ifndef _WINSOCKAPI_
-+#define closesocket(s) close(s)
-+#define SOCKET int
-+#endif
-+
-+#ifdef STANDALONE
-+#define DEBUG_HTTP
-+#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n)
-+#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b)
-+#endif
-+
-+#define XML_NANO_HTTP_MAX_REDIR 10
-+
-+#define XML_NANO_HTTP_CHUNK 4096
-+
-+#define XML_NANO_HTTP_CLOSED 0
-+#define XML_NANO_HTTP_WRITE 1
-+#define XML_NANO_HTTP_READ 2
-+#define XML_NANO_HTTP_NONE 4
-+
-+typedef struct xmlNanoHTTPCtxt {
-+ char *protocol; /* the protocol name */
-+ char *hostname; /* the host name */
-+ int port; /* the port */
-+ char *path; /* the path within the URL */
-+ SOCKET fd; /* the file descriptor for the socket */
-+ int state; /* WRITE / READ / CLOSED */
-+ char *out; /* buffer sent (zero terminated) */
-+ char *outptr; /* index within the buffer sent */
-+ char *in; /* the receiving buffer */
-+ char *content; /* the start of the content */
-+ char *inptr; /* the next byte to read from network */
-+ char *inrptr; /* the next byte to give back to the client */
-+ int inlen; /* len of the input buffer */
-+ int last; /* return code for last operation */
-+ int returnValue; /* the protocol return value */
-+ char *contentType; /* the MIME type for the input */
-+ char *location; /* the new URL in case of redirect */
-+ char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */
-+} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr;
-+
-+static int initialized = 0;
-+static char *proxy = NULL; /* the proxy name if any */
-+static int proxyPort; /* the proxy port if any */
-+static unsigned int timeout = 60;/* the select() timeout in seconds */
-+
-+/**
-+ * A portability function
-+ */
-+int socket_errno(void) {
-+#ifdef _WINSOCKAPI_
-+ return(WSAGetLastError());
-+#else
-+ return(errno);
-+#endif
-+}
-+
-+/**
-+ * xmlNanoHTTPInit:
-+ *
-+ * Initialize the HTTP protocol layer.
-+ * Currently it just checks for proxy informations
-+ */
-+
-+void
-+xmlNanoHTTPInit(void) {
-+ const char *env;
-+#ifdef _WINSOCKAPI_
-+ WSADATA wsaData;
-+#endif
-+
-+ if (initialized)
-+ return;
-+
-+#ifdef _WINSOCKAPI_
-+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
-+ return;
-+#endif
-+
-+ if (proxy == NULL) {
-+ proxyPort = 80;
-+ env = getenv("no_proxy");
-+ if (env != NULL)
-+ goto done;
-+ env = getenv("http_proxy");
-+ if (env != NULL) {
-+ xmlNanoHTTPScanProxy(env);
-+ goto done;
-+ }
-+ env = getenv("HTTP_PROXY");
-+ if (env != NULL) {
-+ xmlNanoHTTPScanProxy(env);
-+ goto done;
-+ }
-+ }
-+done:
-+ initialized = 1;
-+}
-+
-+/**
-+ * xmlNanoHTTPClenup:
-+ *
-+ * Cleanup the HTTP protocol layer.
-+ */
-+
-+void
-+xmlNanoHTTPCleanup(void) {
-+ if (proxy != NULL)
-+ xmlFree(proxy);
-+#ifdef _WINSOCKAPI_
-+ if (initialized)
-+ WSACleanup();
-+#endif
-+ initialized = 0;
-+ return;
-+}
-+
-+/**
-+ * xmlNanoHTTPTimeout:
-+ * @delay: the delay in seconds
-+ *
-+ * Set the HTTP timeout, (default is 60secs). 0 means immediate
-+ * return, while -1 infinite.
-+ */
-+
-+void
-+xmlNanoHTTPTimeout(int delay) {
-+ timeout = (unsigned int) delay;
-+}
-+
-+/**
-+ * xmlNanoHTTPScanURL:
-+ * @ctxt: an HTTP context
-+ * @URL: The URL used to initialize the context
-+ *
-+ * (Re)Initialize an HTTP context by parsing the URL and finding
-+ * the protocol host port and path it indicates.
-+ */
-+
-+static void
-+xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) {
-+ const char *cur = URL;
-+ char buf[4096];
-+ int index = 0;
-+ int port = 0;
-+
-+ if (ctxt->protocol != NULL) {
-+ xmlFree(ctxt->protocol);
-+ ctxt->protocol = NULL;
-+ }
-+ if (ctxt->hostname != NULL) {
-+ xmlFree(ctxt->hostname);
-+ ctxt->hostname = NULL;
-+ }
-+ if (ctxt->path != NULL) {
-+ xmlFree(ctxt->path);
-+ ctxt->path = NULL;
-+ }
-+ if (URL == NULL) return;
-+ buf[index] = 0;
-+ while (*cur != 0) {
-+ if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-+ buf[index] = 0;
-+ ctxt->protocol = xmlMemStrdup(buf);
-+ index = 0;
-+ cur += 3;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0) return;
-+
-+ buf[index] = 0;
-+ while (1) {
-+ if (cur[0] == ':') {
-+ buf[index] = 0;
-+ ctxt->hostname = xmlMemStrdup(buf);
-+ index = 0;
-+ cur += 1;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ port *= 10;
-+ port += *cur - '0';
-+ cur++;
-+ }
-+ if (port != 0) ctxt->port = port;
-+ while ((cur[0] != '/') && (*cur != 0))
-+ cur++;
-+ break;
-+ }
-+ if ((*cur == '/') || (*cur == 0)) {
-+ buf[index] = 0;
-+ ctxt->hostname = xmlMemStrdup(buf);
-+ index = 0;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0)
-+ ctxt->path = xmlMemStrdup("/");
-+ else {
-+ index = 0;
-+ buf[index] = 0;
-+ while (*cur != 0)
-+ buf[index++] = *cur++;
-+ buf[index] = 0;
-+ ctxt->path = xmlMemStrdup(buf);
-+ }
-+}
-+
-+/**
-+ * xmlNanoHTTPScanProxy:
-+ * @URL: The proxy URL used to initialize the proxy context
-+ *
-+ * (Re)Initialize the HTTP Proxy context by parsing the URL and finding
-+ * the protocol host port it indicates.
-+ * Should be like http://myproxy/ or http://myproxy:3128/
-+ * A NULL URL cleans up proxy informations.
-+ */
-+
-+void
-+xmlNanoHTTPScanProxy(const char *URL) {
-+ const char *cur = URL;
-+ char buf[4096];
-+ int index = 0;
-+ int port = 0;
-+
-+ if (proxy != NULL) {
-+ xmlFree(proxy);
-+ proxy = NULL;
-+ }
-+ if (proxyPort != 0) {
-+ proxyPort = 0;
-+ }
-+#ifdef DEBUG_HTTP
-+ if (URL == NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Removing HTTP proxy info\n");
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Using HTTP proxy %s\n", URL);
-+#endif
-+ if (URL == NULL) return;
-+ buf[index] = 0;
-+ while (*cur != 0) {
-+ if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-+ buf[index] = 0;
-+ index = 0;
-+ cur += 3;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+ if (*cur == 0) return;
-+
-+ buf[index] = 0;
-+ while (1) {
-+ if (cur[0] == ':') {
-+ buf[index] = 0;
-+ proxy = xmlMemStrdup(buf);
-+ index = 0;
-+ cur += 1;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ port *= 10;
-+ port += *cur - '0';
-+ cur++;
-+ }
-+ if (port != 0) proxyPort = port;
-+ while ((cur[0] != '/') && (*cur != 0))
-+ cur++;
-+ break;
-+ }
-+ if ((*cur == '/') || (*cur == 0)) {
-+ buf[index] = 0;
-+ proxy = xmlMemStrdup(buf);
-+ index = 0;
-+ break;
-+ }
-+ buf[index++] = *cur++;
-+ }
-+}
-+
-+/**
-+ * xmlNanoHTTPNewCtxt:
-+ * @URL: The URL used to initialize the context
-+ *
-+ * Allocate and initialize a new HTTP context.
-+ *
-+ * Returns an HTTP context or NULL in case of error.
-+ */
-+
-+static xmlNanoHTTPCtxtPtr
-+xmlNanoHTTPNewCtxt(const char *URL) {
-+ xmlNanoHTTPCtxtPtr ret;
-+
-+ ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt));
-+ if (ret == NULL) return(NULL);
-+
-+ memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
-+ ret->port = 80;
-+ ret->returnValue = 0;
-+ ret->fd = -1;
-+
-+ xmlNanoHTTPScanURL(ret, URL);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlNanoHTTPFreeCtxt:
-+ * @ctxt: an HTTP context
-+ *
-+ * Frees the context after closing the connection.
-+ */
-+
-+static void
-+xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) {
-+ if (ctxt == NULL) return;
-+ if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
-+ if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
-+ if (ctxt->path != NULL) xmlFree(ctxt->path);
-+ if (ctxt->out != NULL) xmlFree(ctxt->out);
-+ if (ctxt->in != NULL) xmlFree(ctxt->in);
-+ if (ctxt->contentType != NULL) xmlFree(ctxt->contentType);
-+ if (ctxt->location != NULL) xmlFree(ctxt->location);
-+ if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader);
-+ ctxt->state = XML_NANO_HTTP_NONE;
-+ if (ctxt->fd >= 0) closesocket(ctxt->fd);
-+ ctxt->fd = -1;
-+ xmlFree(ctxt);
-+}
-+
-+/**
-+ * xmlNanoHTTPSend:
-+ * @ctxt: an HTTP context
-+ *
-+ * Send the input needed to initiate the processing on the server side
-+ */
-+
-+static void
-+xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt) {
-+ if (ctxt->state & XML_NANO_HTTP_WRITE) {
-+ int total_sent = 0;
-+ while (total_sent <strlen(ctxt->outptr)) {
-+ int nsent = send(ctxt->fd, ctxt->outptr+total_sent,
-+ strlen(ctxt->outptr)-total_sent, 0);
-+ if (nsent>0)
-+ total_sent += nsent;
-+}
-+
-+ ctxt->last = total_sent;
-+ }
-+}
-+
-+/**
-+ * xmlNanoHTTPRecv:
-+ * @ctxt: an HTTP context
-+ *
-+ * Read information coming from the HTTP connection.
-+ * This is a blocking call (but it blocks in select(), not read()).
-+ *
-+ * Returns the number of byte read or -1 in case of error.
-+ */
-+
-+static int
-+xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) {
-+ fd_set rfd;
-+ struct timeval tv;
-+
-+
-+ while (ctxt->state & XML_NANO_HTTP_READ) {
-+ if (ctxt->in == NULL) {
-+ ctxt->in = (char *) xmlMalloc(65000 * sizeof(char));
-+ if (ctxt->in == NULL) {
-+ ctxt->last = -1;
-+ return(-1);
-+ }
-+ ctxt->inlen = 65000;
-+ ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
-+ }
-+ if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
-+ int delta = ctxt->inrptr - ctxt->in;
-+ int len = ctxt->inptr - ctxt->inrptr;
-+
-+ memmove(ctxt->in, ctxt->inrptr, len);
-+ ctxt->inrptr -= delta;
-+ ctxt->content -= delta;
-+ ctxt->inptr -= delta;
-+ }
-+ if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
-+ int d_inptr = ctxt->inptr - ctxt->in;
-+ int d_content = ctxt->content - ctxt->in;
-+ int d_inrptr = ctxt->inrptr - ctxt->in;
-+
-+ ctxt->inlen *= 2;
-+ ctxt->in = (char *) xmlRealloc(ctxt->in, ctxt->inlen);
-+ if (ctxt->in == NULL) {
-+ ctxt->last = -1;
-+ return(-1);
-+ }
-+ ctxt->inptr = ctxt->in + d_inptr;
-+ ctxt->content = ctxt->in + d_content;
-+ ctxt->inrptr = ctxt->in + d_inrptr;
-+ }
-+ ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
-+ if (ctxt->last > 0) {
-+ ctxt->inptr += ctxt->last;
-+ return(ctxt->last);
-+ }
-+ if (ctxt->last == 0) {
-+ return(0);
-+ }
-+ if (ctxt->last == -1) {
-+ switch (socket_errno()) {
-+ case EINPROGRESS:
-+ case EWOULDBLOCK:
-+#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
-+ case EAGAIN:
-+#endif
-+ break;
-+ default:
-+ return(0);
-+ }
-+ }
-+
-+ tv.tv_sec = timeout;
-+ tv.tv_usec = 0;
-+ FD_ZERO(&rfd);
-+ FD_SET(ctxt->fd, &rfd);
-+
-+ if (select(ctxt->fd+1, &rfd, NULL, NULL, &tv)<1)
-+ return(0);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoHTTPReadLine:
-+ * @ctxt: an HTTP context
-+ *
-+ * Read one line in the HTTP server output, usually for extracting
-+ * the HTTP protocol informations from the answer header.
-+ *
-+ * Returns a newly allocated string with a copy of the line, or NULL
-+ * which indicate the end of the input.
-+ */
-+
-+static char *
-+xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) {
-+ char buf[4096];
-+ char *bp = buf;
-+
-+ while (bp - buf < 4095) {
-+ if (ctxt->inrptr == ctxt->inptr) {
-+ if (xmlNanoHTTPRecv(ctxt) == 0) {
-+ if (bp == buf)
-+ return(NULL);
-+ else
-+ *bp = 0;
-+ return(xmlMemStrdup(buf));
-+ }
-+ }
-+ *bp = *ctxt->inrptr++;
-+ if (*bp == '\n') {
-+ *bp = 0;
-+ return(xmlMemStrdup(buf));
-+ }
-+ if (*bp != '\r')
-+ bp++;
-+ }
-+ buf[4095] = 0;
-+ return(xmlMemStrdup(buf));
-+}
-+
-+
-+/**
-+ * xmlNanoHTTPScanAnswer:
-+ * @ctxt: an HTTP context
-+ * @line: an HTTP header line
-+ *
-+ * Try to extract useful informations from the server answer.
-+ * We currently parse and process:
-+ * - The HTTP revision/ return code
-+ * - The Content-Type
-+ * - The Location for redirrect processing.
-+ *
-+ * Returns -1 in case of failure, the file descriptor number otherwise
-+ */
-+
-+static void
-+xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) {
-+ const char *cur = line;
-+
-+ if (line == NULL) return;
-+
-+ if (!strncmp(line, "HTTP/", 5)) {
-+ int version = 0;
-+ int ret = 0;
-+
-+ cur += 5;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ version *= 10;
-+ version += *cur - '0';
-+ cur++;
-+ }
-+ if (*cur == '.') {
-+ cur++;
-+ if ((*cur >= '0') && (*cur <= '9')) {
-+ version *= 10;
-+ version += *cur - '0';
-+ cur++;
-+ }
-+ while ((*cur >= '0') && (*cur <= '9'))
-+ cur++;
-+ } else
-+ version *= 10;
-+ if ((*cur != ' ') && (*cur != '\t')) return;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ if ((*cur < '0') || (*cur > '9')) return;
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ ret *= 10;
-+ ret += *cur - '0';
-+ cur++;
-+ }
-+ if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;
-+ ctxt->returnValue = ret;
-+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {
-+ cur += 13;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ if (ctxt->contentType != NULL)
-+ xmlFree(ctxt->contentType);
-+ ctxt->contentType = xmlMemStrdup(cur);
-+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) {
-+ cur += 12;
-+ if (ctxt->contentType != NULL) return;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ ctxt->contentType = xmlMemStrdup(cur);
-+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) {
-+ cur += 9;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ if (ctxt->location != NULL)
-+ xmlFree(ctxt->location);
-+ ctxt->location = xmlMemStrdup(cur);
-+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) {
-+ cur += 17;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ if (ctxt->authHeader != NULL)
-+ xmlFree(ctxt->authHeader);
-+ ctxt->authHeader = xmlMemStrdup(cur);
-+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) {
-+ cur += 19;
-+ while ((*cur == ' ') || (*cur == '\t')) cur++;
-+ if (ctxt->authHeader != NULL)
-+ xmlFree(ctxt->authHeader);
-+ ctxt->authHeader = xmlMemStrdup(cur);
-+ }
-+}
-+
-+/**
-+ * xmlNanoHTTPConnectAttempt:
-+ * @ia: an internet adress structure
-+ * @port: the port number
-+ *
-+ * Attempt a connection to the given IP:port endpoint. It forces
-+ * non-blocking semantic on the socket, and allow 60 seconds for
-+ * the host to answer.
-+ *
-+ * Returns -1 in case of failure, the file descriptor number otherwise
-+ */
-+
-+static int
-+xmlNanoHTTPConnectAttempt(struct sockaddr *addr, int port)
-+{
-+ SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-+ fd_set wfd;
-+ struct timeval tv;
-+ int status;
-+
-+ if (s==-1) {
-+#ifdef DEBUG_HTTP
-+ perror("socket");
-+#endif
-+ return(-1);
-+ }
-+
-+#ifdef _WINSOCKAPI_
-+ {
-+ u_long one = 1;
-+
-+ status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
-+ }
-+#else /* _WINSOCKAPI_ */
-+#if defined(VMS)
-+ {
-+ int enable = 1;
-+ status = ioctl(s, FIONBIO, &enable);
-+ }
-+#else /* VMS */
-+ if ((status = fcntl(s, F_GETFL, 0)) != -1) {
-+#ifdef O_NONBLOCK
-+ status |= O_NONBLOCK;
-+#else /* O_NONBLOCK */
-+#ifdef F_NDELAY
-+ status |= F_NDELAY;
-+#endif /* F_NDELAY */
-+#endif /* !O_NONBLOCK */
-+ status = fcntl(s, F_SETFL, status);
-+ }
-+ if (status < 0) {
-+#ifdef DEBUG_HTTP
-+ perror("nonblocking");
-+#endif
-+ closesocket(s);
-+ return(-1);
-+ }
-+#endif /* !VMS */
-+#endif /* !_WINSOCKAPI_ */
-+
-+
-+ if ((connect(s, addr, sizeof(*addr))==-1)) {
-+ switch (socket_errno()) {
-+ case EINPROGRESS:
-+ case EWOULDBLOCK:
-+ break;
-+ default:
-+ perror("connect");
-+ closesocket(s);
-+ return(-1);
-+ }
-+ }
-+
-+ tv.tv_sec = timeout;
-+ tv.tv_usec = 0;
-+
-+ FD_ZERO(&wfd);
-+ FD_SET(s, &wfd);
-+
-+ switch(select(s+1, NULL, &wfd, NULL, &tv))
-+ {
-+ case 0:
-+ /* Time out */
-+ closesocket(s);
-+ return(-1);
-+ case -1:
-+ /* Ermm.. ?? */
-+#ifdef DEBUG_HTTP
-+ perror("select");
-+#endif
-+ closesocket(s);
-+ return(-1);
-+ }
-+
-+ if ( FD_ISSET(s, &wfd) ) {
-+ SOCKLEN_T len;
-+ len = sizeof(status);
-+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {
-+ /* Solaris error code */
-+ return (-1);
-+ }
-+ if ( status ) {
-+ closesocket(s);
-+ errno = status;
-+ return (-1);
-+ }
-+ } else {
-+ /* pbm */
-+ return (-1);
-+ }
-+
-+ return(s);
-+}
-+
-+/**
-+ * xmlNanoHTTPConnectHost:
-+ * @host: the host name
-+ * @port: the port number
-+ *
-+ * Attempt a connection to the given host:port endpoint. It tries
-+ * the multiple IP provided by the DNS if available.
-+ *
-+ * Returns -1 in case of failure, the file descriptor number otherwise
-+ */
-+
-+static int
-+xmlNanoHTTPConnectHost(const char *host, int port)
-+{
-+ struct hostent *h;
-+ struct sockaddr *addr;
-+ struct in_addr ia;
-+ struct sockaddr_in sin;
-+#ifdef SUPPORT_IP6
-+ struct in6_addr ia6;
-+ struct sockaddr_in6 sin6;
-+#endif
-+ int i;
-+ int s;
-+
-+#if defined(SUPPORT_IP6) && defined(RES_USE_INET6)
-+ if (!(_res.options & RES_INIT))
-+ res_init();
-+ _res.options |= RES_USE_INET6;
-+#endif
-+ h=gethostbyname(host);
-+ if (h==NULL)
-+ {
-+#ifdef DEBUG_HTTP
-+ xmlGenericError(xmlGenericErrorContext,"unable to resolve '%s'.\n", host);
-+#endif
-+ return(-1);
-+ }
-+
-+ for(i=0; h->h_addr_list[i]; i++)
-+ {
-+ if (h->h_addrtype == AF_INET) {
-+ /* A records (IPv4) */
-+ memcpy(&ia, h->h_addr_list[i], h->h_length);
-+ sin.sin_family = h->h_addrtype;
-+ sin.sin_addr = ia;
-+ sin.sin_port = htons(port);
-+ addr = (struct sockaddr *)&sin;
-+#ifdef SUPPORT_IP6
-+ } else if (h->h_addrtype == AF_INET6) {
-+ /* AAAA records (IPv6) */
-+ memcpy(&ia6, h->h_addr_list[i], h->h_length);
-+ sin6.sin_family = h->h_addrtype;
-+ sin6.sin_addr = ia6;
-+ sin6.sin_port = htons(port);
-+ addr = (struct sockaddr *)&sin6;
-+#endif
-+ } else
-+ break; /* for */
-+
-+ s = xmlNanoHTTPConnectAttempt(addr, port);
-+ if (s != -1)
-+ return(s);
-+ }
-+
-+#ifdef DEBUG_HTTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "unable to connect to '%s'.\n", host);
-+#endif
-+ return(-1);
-+}
-+
-+
-+/**
-+ * xmlNanoHTTPOpen:
-+ * @URL: The URL to load
-+ * @contentType: if available the Content-Type information will be
-+ * returned at that location
-+ *
-+ * This function try to open a connection to the indicated resource
-+ * via HTTP GET.
-+ *
-+ * Returns NULL in case of failure, otherwise a request handler.
-+ * The contentType, if provided must be freed by the caller
-+ */
-+
-+void*
-+xmlNanoHTTPOpen(const char *URL, char **contentType) {
-+ if (contentType != NULL) *contentType = NULL;
-+ return xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL);
-+}
-+
-+/**
-+ * xmlNanoHTTPRead:
-+ * @ctx: the HTTP context
-+ * @dest: a buffer
-+ * @len: the buffer length
-+ *
-+ * This function tries to read @len bytes from the existing HTTP connection
-+ * and saves them in @dest. This is a blocking call.
-+ *
-+ * Returns the number of byte read. 0 is an indication of an end of connection.
-+ * -1 indicates a parameter error.
-+ */
-+int
-+xmlNanoHTTPRead(void *ctx, void *dest, int len) {
-+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-+
-+ if (ctx == NULL) return(-1);
-+ if (dest == NULL) return(-1);
-+ if (len <= 0) return(0);
-+
-+ while (ctxt->inptr - ctxt->inrptr < len) {
-+ if (xmlNanoHTTPRecv(ctxt) == 0) break;
-+ }
-+ if (ctxt->inptr - ctxt->inrptr < len)
-+ len = ctxt->inptr - ctxt->inrptr;
-+ memcpy(dest, ctxt->inrptr, len);
-+ ctxt->inrptr += len;
-+ return(len);
-+}
-+
-+/**
-+ * xmlNanoHTTPClose:
-+ * @ctx: the HTTP context
-+ *
-+ * This function closes an HTTP context, it ends up the connection and
-+ * free all data related to it.
-+ */
-+void
-+xmlNanoHTTPClose(void *ctx) {
-+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-+
-+ if (ctx == NULL) return;
-+
-+ xmlNanoHTTPFreeCtxt(ctxt);
-+}
-+
-+/**
-+ * xmlNanoHTTPMethod:
-+ * @URL: The URL to load
-+ * @method: the HTTP method to use
-+ * @input: the input string if any
-+ * @contentType: the Content-Type information IN and OUT
-+ * @headers: the extra headers
-+ *
-+ * This function try to open a connection to the indicated resource
-+ * via HTTP using the given @method, adding the given extra headers
-+ * and the input buffer for the request content.
-+ *
-+ * Returns NULL in case of failure, otherwise a request handler.
-+ * The contentType, if provided must be freed by the caller
-+ */
-+
-+void*
-+xmlNanoHTTPMethod(const char *URL, const char *method, const char *input,
-+ char **contentType, const char *headers) {
-+ xmlNanoHTTPCtxtPtr ctxt;
-+ char *bp, *p;
-+ int blen, ilen, ret;
-+ int head;
-+ int nbRedirects = 0;
-+ char *redirURL = NULL;
-+
-+ if (URL == NULL) return(NULL);
-+ if (method == NULL) method = "GET";
-+ xmlNanoHTTPInit();
-+
-+retry:
-+ if (redirURL == NULL)
-+ ctxt = xmlNanoHTTPNewCtxt(URL);
-+ else {
-+ ctxt = xmlNanoHTTPNewCtxt(redirURL);
-+ xmlFree(redirURL);
-+ redirURL = NULL;
-+ }
-+
-+ if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
-+ xmlNanoHTTPFreeCtxt(ctxt);
-+ if (redirURL != NULL) xmlFree(redirURL);
-+ return(NULL);
-+ }
-+ if (ctxt->hostname == NULL) {
-+ xmlNanoHTTPFreeCtxt(ctxt);
-+ return(NULL);
-+ }
-+ if (proxy) {
-+ blen = strlen(ctxt->hostname) * 2 + 16;
-+ ret = xmlNanoHTTPConnectHost(proxy, proxyPort);
-+ }
-+ else {
-+ blen = strlen(ctxt->hostname);
-+ ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
-+ }
-+ if (ret < 0) {
-+ xmlNanoHTTPFreeCtxt(ctxt);
-+ return(NULL);
-+ }
-+ ctxt->fd = ret;
-+
-+ if (input != NULL) {
-+ ilen = strlen(input);
-+ blen += ilen + 32;
-+ }
-+ else
-+ ilen = 0;
-+ if (headers != NULL)
-+ blen += strlen(headers);
-+ if (contentType && *contentType)
-+ blen += strlen(*contentType) + 16;
-+ blen += strlen(method) + strlen(ctxt->path) + 23;
-+ bp = xmlMalloc(blen);
-+ if (proxy) {
-+ if (ctxt->port != 80) {
-+ sprintf(bp, "%s http://%s:%d%s", method, ctxt->hostname,
-+ ctxt->port, ctxt->path);
-+ }
-+ else
-+ sprintf(bp, "%s http://%s%s", method, ctxt->hostname, ctxt->path);
-+ }
-+ else
-+ sprintf(bp, "%s %s", method, ctxt->path);
-+ p = bp + strlen(bp);
-+ sprintf(p, " HTTP/1.0\r\nHost: %s\r\n", ctxt->hostname);
-+ p += strlen(p);
-+ if (contentType != NULL && *contentType) {
-+ sprintf(p, "Content-Type: %s\r\n", *contentType);
-+ p += strlen(p);
-+ }
-+ if (headers != NULL) {
-+ strcpy(p, headers);
-+ p += strlen(p);
-+ }
-+ if (input != NULL)
-+ sprintf(p, "Content-Length: %d\r\n\r\n%s", ilen, input);
-+ else
-+ strcpy(p, "\r\n");
-+#ifdef DEBUG_HTTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "-> %s%s", proxy? "(Proxy) " : "", bp);
-+ if ((blen -= strlen(bp)+1) < 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "ERROR: overflowed buffer by %d bytes\n", -blen);
-+#endif
-+ ctxt->outptr = ctxt->out = bp;
-+ ctxt->state = XML_NANO_HTTP_WRITE;
-+ xmlNanoHTTPSend(ctxt);
-+ ctxt->state = XML_NANO_HTTP_READ;
-+ head = 1;
-+
-+ while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
-+ if (head && (*p == 0)) {
-+ head = 0;
-+ ctxt->content = ctxt->inrptr;
-+ xmlFree(p);
-+ break;
-+ }
-+ xmlNanoHTTPScanAnswer(ctxt, p);
-+
-+#ifdef DEBUG_HTTP
-+ xmlGenericError(xmlGenericErrorContext, "<- %s\n", p);
-+#endif
-+ xmlFree(p);
-+ }
-+
-+ if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) &&
-+ (ctxt->returnValue < 400)) {
-+#ifdef DEBUG_HTTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\nRedirect to: %s\n", ctxt->location);
-+#endif
-+ while (xmlNanoHTTPRecv(ctxt)) ;
-+ if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
-+ nbRedirects++;
-+ redirURL = xmlMemStrdup(ctxt->location);
-+ xmlNanoHTTPFreeCtxt(ctxt);
-+ goto retry;
-+ }
-+ xmlNanoHTTPFreeCtxt(ctxt);
-+#ifdef DEBUG_HTTP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Too many redirects, aborting ...\n");
-+#endif
-+ return(NULL);
-+
-+ }
-+
-+ if (contentType != NULL) {
-+ if (ctxt->contentType != NULL)
-+ *contentType = xmlMemStrdup(ctxt->contentType);
-+ else
-+ *contentType = NULL;
-+ }
-+
-+#ifdef DEBUG_HTTP
-+ if (ctxt->contentType != NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\nCode %d, content-type '%s'\n\n",
-+ ctxt->returnValue, ctxt->contentType);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\nCode %d, no content-type\n\n",
-+ ctxt->returnValue);
-+#endif
-+
-+ return((void *) ctxt);
-+}
-+
-+/**
-+ * xmlNanoHTTPFetch:
-+ * @URL: The URL to load
-+ * @filename: the filename where the content should be saved
-+ * @contentType: if available the Content-Type information will be
-+ * returned at that location
-+ *
-+ * This function try to fetch the indicated resource via HTTP GET
-+ * and save it's content in the file.
-+ *
-+ * Returns -1 in case of failure, 0 incase of success. The contentType,
-+ * if provided must be freed by the caller
-+ */
-+int
-+xmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) {
-+ void *ctxt;
-+ char buf[4096];
-+ int fd;
-+ int len;
-+
-+ ctxt = xmlNanoHTTPOpen(URL, contentType);
-+ if (ctxt == NULL) return(-1);
-+
-+ if (!strcmp(filename, "-"))
-+ fd = 0;
-+ else {
-+ fd = open(filename, O_CREAT | O_WRONLY, 00644);
-+ if (fd < 0) {
-+ xmlNanoHTTPClose(ctxt);
-+ if ((contentType != NULL) && (*contentType != NULL)) {
-+ xmlFree(*contentType);
-+ *contentType = NULL;
-+ }
-+ return(-1);
-+ }
-+ }
-+
-+ while ((len = xmlNanoHTTPRead(ctxt, buf, sizeof(buf))) > 0) {
-+ write(fd, buf, len);
-+ }
-+
-+ xmlNanoHTTPClose(ctxt);
-+ close(fd);
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoHTTPSave:
-+ * @ctxt: the HTTP context
-+ * @filename: the filename where the content should be saved
-+ *
-+ * This function saves the output of the HTTP transaction to a file
-+ * It closes and free the context at the end
-+ *
-+ * Returns -1 in case of failure, 0 incase of success.
-+ */
-+int
-+xmlNanoHTTPSave(void *ctxt, const char *filename) {
-+ char buf[4096];
-+ int fd;
-+ int len;
-+
-+ if (ctxt == NULL) return(-1);
-+
-+ if (!strcmp(filename, "-"))
-+ fd = 0;
-+ else {
-+ fd = open(filename, O_CREAT | O_WRONLY);
-+ if (fd < 0) {
-+ xmlNanoHTTPClose(ctxt);
-+ return(-1);
-+ }
-+ }
-+
-+ while ((len = xmlNanoHTTPRead(ctxt, buf, sizeof(buf))) > 0) {
-+ write(fd, buf, len);
-+ }
-+
-+ xmlNanoHTTPClose(ctxt);
-+ return(0);
-+}
-+
-+/**
-+ * xmlNanoHTTPReturnCode:
-+ * @ctx: the HTTP context
-+ *
-+ * Returns the HTTP return code for the request.
-+ */
-+int
-+xmlNanoHTTPReturnCode(void *ctx) {
-+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-+
-+ if (ctxt == NULL) return(-1);
-+
-+ return(ctxt->returnValue);
-+}
-+
-+/**
-+ * xmlNanoHTTPAuthHeader:
-+ * @ctx: the HTTP context
-+ *
-+ * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate
-+ * header.
-+ */
-+const char *
-+xmlNanoHTTPAuthHeader(void *ctx) {
-+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-+
-+ if (ctxt == NULL) return(NULL);
-+
-+ return(ctxt->authHeader);
-+}
-+
-+#ifdef STANDALONE
-+int main(int argc, char **argv) {
-+ char *contentType = NULL;
-+
-+ if (argv[1] != NULL) {
-+ if (argv[2] != NULL)
-+ xmlNanoHTTPFetch(argv[1], argv[2], &contentType);
-+ else
-+ xmlNanoHTTPFetch(argv[1], "-", &contentType);
-+ if (contentType != NULL) xmlFree(contentType);
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: minimal HTTP GET implementation\n", argv[0]);
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\tusage %s [ URL [ filename ] ]\n", argv[0]);
-+ }
-+ xmlNanoHTTPCleanup();
-+ xmlMemoryDump();
-+ return(0);
-+}
-+#endif /* STANDALONE */
-+#else /* !LIBXML_HTTP_ENABLED */
-+#ifdef STANDALONE
-+#include <stdio.h>
-+int main(int argc, char **argv) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s : HTTP support not compiled in\n", argv[0]);
-+ return(0);
-+}
-+#endif /* STANDALONE */
-+#endif /* LIBXML_HTTP_ENABLED */
-diff -Nru libxml2-2.3.0/libxml/nanohttp.h libxml2-2.3.0.new/libxml/nanohttp.h
---- libxml2-2.3.0/libxml/nanohttp.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/nanohttp.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,44 @@
-+/*
-+ * nanohttp.c: minimalist HTTP implementation to fetch external subsets.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __NANO_HTTP_H__
-+#define __NANO_HTTP_H__
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_HTTP_ENABLED
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+void xmlNanoHTTPInit (void);
-+void xmlNanoHTTPCleanup (void);
-+void xmlNanoHTTPScanProxy (const char *URL);
-+int xmlNanoHTTPFetch (const char *URL,
-+ const char *filename,
-+ char **contentType);
-+void * xmlNanoHTTPMethod (const char *URL,
-+ const char *method,
-+ const char *input,
-+ char **contentType,
-+ const char *headers);
-+void * xmlNanoHTTPOpen (const char *URL,
-+ char **contentType);
-+int xmlNanoHTTPReturnCode (void *ctx);
-+const char * xmlNanoHTTPAuthHeader(void *ctx);
-+int xmlNanoHTTPRead (void *ctx,
-+ void *dest,
-+ int len);
-+int xmlNanoHTTPSave (void *ctxt,
-+ const char *filename);
-+void xmlNanoHTTPClose (void *ctx);
-+#ifdef __cplusplus
-+}
-+
-+#endif /* LIBXML_HTTP_ENABLED */
-+#endif
-+#endif /* __NANO_HTTP_H__ */
-diff -Nru libxml2-2.3.0/libxml/parser.c libxml2-2.3.0.new/libxml/parser.c
---- libxml2-2.3.0/libxml/parser.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/parser.c Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,9863 @@
-+/*
-+ * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
-+ * implemented on top of the SAX interfaces
-+ *
-+ * References:
-+ * The XML specification:
-+ * http://www.w3.org/TR/REC-xml
-+ * Original 1.0 version:
-+ * http://www.w3.org/TR/1998/REC-xml-19980210
-+ * XML second edition working draft
-+ * http://www.w3.org/TR/2000/WD-xml-2e-20000814
-+ *
-+ * Okay this is a big file, the parser core is around 7000 lines, then it
-+ * is followed by the progressive parser top routines, then the various
-+ * high level APIs to call the parser and a few miscelaneous functions.
-+ * A number of helper functions and deprecated ones have been moved to
-+ * parserInternals.c to reduce this file size.
-+ * As much as possible the functions are associated with their relative
-+ * production in the XML specification. A few productions defining the
-+ * different ranges of character are actually implanted either in
-+ * parserInternals.h or parserInternals.c
-+ * The DOM tree build is realized from the default SAX callbacks in
-+ * the module SAX.c.
-+ * The routines doing the validation checks are in valid.c and called either
-+ * from the SAx callbacks or as standalones functions using a preparsed
-+ * document.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ *
-+ * 14 Nov 2000 ht - truncated definitions of xmlSubstituteEntitiesDefaultValue
-+ * and xmlDoValidityCheckingDefaultValue for VMS
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#define XML_DIR_SEP '\\'
-+#else
-+#include "config.h"
-+#define XML_DIR_SEP '/'
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/valid.h>
-+#include <libxml/entities.h>
-+#include <libxml/xmlerror.h>
-+#include <libxml/encoding.h>
-+#include <libxml/xmlIO.h>
-+#include <libxml/uri.h>
-+
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_ZLIB_H
-+#include <zlib.h>
-+#endif
-+
-+
-+#define XML_PARSER_BIG_BUFFER_SIZE 1000
-+#define XML_PARSER_BUFFER_SIZE 100
-+
-+/*
-+ * Various global defaults for parsing
-+ */
-+int xmlGetWarningsDefaultValue = 1;
-+int xmlParserDebugEntities = 0;
-+#ifdef VMS
-+int xmlSubstituteEntitiesDefaultVal = 0;
-+#define xmlSubstituteEntitiesDefaultValue xmlSubstituteEntitiesDefaultVal
-+int xmlDoValidityCheckingDefaultVal = 0;
-+#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
-+#else
-+int xmlSubstituteEntitiesDefaultValue = 0;
-+int xmlDoValidityCheckingDefaultValue = 0;
-+#endif
-+int xmlLoadExtDtdDefaultValue = 0;
-+int xmlPedanticParserDefaultValue = 0;
-+int xmlKeepBlanksDefaultValue = 1;
-+
-+/*
-+ * List of XML prefixed PI allowed by W3C specs
-+ */
-+
-+const char *xmlW3CPIs[] = {
-+ "xml-stylesheet",
-+ NULL
-+};
-+
-+/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
-+void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
-+xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
-+ const xmlChar **str);
-+
-+
-+/************************************************************************
-+ * *
-+ * Parser stacks related functions and macros *
-+ * *
-+ ************************************************************************/
-+
-+xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
-+ const xmlChar ** str);
-+
-+/*
-+ * Generic function for accessing stacks in the Parser Context
-+ */
-+
-+#define PUSH_AND_POP(scope, type, name) \
-+scope int name##Push(xmlParserCtxtPtr ctxt, type value) { \
-+ if (ctxt->name##Nr >= ctxt->name##Max) { \
-+ ctxt->name##Max *= 2; \
-+ ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-+ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-+ if (ctxt->name##Tab == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "realloc failed !\n"); \
-+ return(0); \
-+ } \
-+ } \
-+ ctxt->name##Tab[ctxt->name##Nr] = value; \
-+ ctxt->name = value; \
-+ return(ctxt->name##Nr++); \
-+} \
-+scope type name##Pop(xmlParserCtxtPtr ctxt) { \
-+ type ret; \
-+ if (ctxt->name##Nr <= 0) return(0); \
-+ ctxt->name##Nr--; \
-+ if (ctxt->name##Nr > 0) \
-+ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-+ else \
-+ ctxt->name = NULL; \
-+ ret = ctxt->name##Tab[ctxt->name##Nr]; \
-+ ctxt->name##Tab[ctxt->name##Nr] = 0; \
-+ return(ret); \
-+} \
-+
-+/*
-+ * Those macros actually generate the functions
-+ */
-+PUSH_AND_POP(extern, xmlParserInputPtr, input)
-+PUSH_AND_POP(extern, xmlNodePtr, node)
-+PUSH_AND_POP(extern, xmlChar*, name)
-+
-+int spacePush(xmlParserCtxtPtr ctxt, int val) {
-+ if (ctxt->spaceNr >= ctxt->spaceMax) {
-+ ctxt->spaceMax *= 2;
-+ ctxt->spaceTab = (int *) xmlRealloc(ctxt->spaceTab,
-+ ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
-+ if (ctxt->spaceTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return(0);
-+ }
-+ }
-+ ctxt->spaceTab[ctxt->spaceNr] = val;
-+ ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
-+ return(ctxt->spaceNr++);
-+}
-+
-+int spacePop(xmlParserCtxtPtr ctxt) {
-+ int ret;
-+ if (ctxt->spaceNr <= 0) return(0);
-+ ctxt->spaceNr--;
-+ if (ctxt->spaceNr > 0)
-+ ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
-+ else
-+ ctxt->space = NULL;
-+ ret = ctxt->spaceTab[ctxt->spaceNr];
-+ ctxt->spaceTab[ctxt->spaceNr] = -1;
-+ return(ret);
-+}
-+
-+/*
-+ * Macros for accessing the content. Those should be used only by the parser,
-+ * and not exported.
-+ *
-+ * Dirty macros, i.e. one often need to make assumption on the context to
-+ * use them
-+ *
-+ * CUR_PTR return the current pointer to the xmlChar to be parsed.
-+ * To be used with extreme caution since operations consuming
-+ * characters may move the input buffer to a different location !
-+ * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
-+ * This should be used internally by the parser
-+ * only to compare to ASCII values otherwise it would break when
-+ * running with UTF-8 encoding.
-+ * RAW same as CUR but in the input buffer, bypass any token
-+ * extraction that may have been done
-+ * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-+ * to compare on ASCII based substring.
-+ * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-+ * strings within the parser.
-+ *
-+ * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
-+ *
-+ * NEXT Skip to the next character, this does the proper decoding
-+ * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-+ * NEXTL(l) Skip l xmlChars in the input buffer
-+ * CUR_CHAR(l) returns the current unicode character (int), set l
-+ * to the number of xmlChars used for the encoding [0-5].
-+ * CUR_SCHAR same but operate on a string instead of the context
-+ * COPY_BUF copy the current unicode char to the target buffer, increment
-+ * the index
-+ * GROW, SHRINK handling of input buffers
-+ */
-+
-+#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-+#define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
-+#define NXT(val) ctxt->input->cur[(val)]
-+#define CUR_PTR ctxt->input->cur
-+
-+#define SKIP(val) do { \
-+ ctxt->nbChars += (val),ctxt->input->cur += (val); \
-+ if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
-+ /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
-+ if ((*ctxt->input->cur == 0) && \
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
-+ xmlPopInput(ctxt); \
-+ } while (0)
-+
-+#define SHRINK do { \
-+ xmlParserInputShrink(ctxt->input); \
-+ if ((*ctxt->input->cur == 0) && \
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
-+ xmlPopInput(ctxt); \
-+ } while (0)
-+
-+#define GROW do { \
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \
-+ if ((*ctxt->input->cur == 0) && \
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
-+ xmlPopInput(ctxt); \
-+ } while (0)
-+
-+#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
-+
-+#define NEXT xmlNextChar(ctxt)
-+
-+#define NEXTL(l) do { \
-+ if (*(ctxt->input->cur) == '\n') { \
-+ ctxt->input->line++; ctxt->input->col = 1; \
-+ } else ctxt->input->col++; \
-+ ctxt->token = 0; ctxt->input->cur += l; \
-+ if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
-+ /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
-+ } while (0)
-+
-+#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
-+#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
-+
-+#define COPY_BUF(l,b,i,v) \
-+ if (l == 1) b[i++] = (xmlChar) v; \
-+ else i += xmlCopyChar(l,&b[i],v)
-+
-+/**
-+ * xmlSkipBlankChars:
-+ * @ctxt: the XML parser context
-+ *
-+ * skip all blanks character found at that point in the input streams.
-+ * It pops up finished entities in the process if allowable at that point.
-+ *
-+ * Returns the number of space chars skipped
-+ */
-+
-+int
-+xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
-+ int cur, res = 0;
-+
-+ /*
-+ * It's Okay to use CUR/NEXT here since all the blanks are on
-+ * the ASCII range.
-+ */
-+ do {
-+ cur = CUR;
-+ while (IS_BLANK(cur)) { /* CHECKED tstblanks.xml */
-+ NEXT;
-+ cur = CUR;
-+ res++;
-+ }
-+ while ((cur == 0) && (ctxt->inputNr > 1) &&
-+ (ctxt->instate != XML_PARSER_COMMENT)) {
-+ xmlPopInput(ctxt);
-+ cur = CUR;
-+ }
-+ /*
-+ * Need to handle support of entities branching here
-+ */
-+ if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
-+ /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */
-+ } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
-+ return(res);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to handle entities *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlPopInput:
-+ * @ctxt: an XML parser context
-+ *
-+ * xmlPopInput: the current input pointed by ctxt->input came to an end
-+ * pop it and return the next char.
-+ *
-+ * Returns the current xmlChar in the parser context
-+ */
-+xmlChar
-+xmlPopInput(xmlParserCtxtPtr ctxt) {
-+ if (ctxt->inputNr == 1) return(0); /* End of main Input */
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Popping input %d\n", ctxt->inputNr);
-+ xmlFreeInputStream(inputPop(ctxt));
-+ if ((*ctxt->input->cur == 0) &&
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-+ return(xmlPopInput(ctxt));
-+ return(CUR);
-+}
-+
-+/**
-+ * xmlPushInput:
-+ * @ctxt: an XML parser context
-+ * @input: an XML parser input fragment (entity, XML fragment ...).
-+ *
-+ * xmlPushInput: switch to a new input stream which is stacked on top
-+ * of the previous one(s).
-+ */
-+void
-+xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
-+ if (input == NULL) return;
-+
-+ if (xmlParserDebugEntities) {
-+ if ((ctxt->input != NULL) && (ctxt->input->filename))
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s(%d): ", ctxt->input->filename,
-+ ctxt->input->line);
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
-+ }
-+ inputPush(ctxt, input);
-+ GROW;
-+}
-+
-+/**
-+ * xmlParseCharRef:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse Reference declarations
-+ *
-+ * [66] CharRef ::= '&#' [0-9]+ ';' |
-+ * '&#x' [0-9a-fA-F]+ ';'
-+ *
-+ * [ WFC: Legal Character ]
-+ * Characters referred to using character references must match the
-+ * production for Char.
-+ *
-+ * Returns the value parsed (as an int), 0 in case of error
-+ */
-+int
-+xmlParseCharRef(xmlParserCtxtPtr ctxt) {
-+ int val = 0;
-+ int count = 0;
-+
-+ if (ctxt->token != 0) {
-+ val = ctxt->token;
-+ ctxt->token = 0;
-+ return(val);
-+ }
-+ /*
-+ * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
-+ */
-+ if ((RAW == '&') && (NXT(1) == '#') &&
-+ (NXT(2) == 'x')) {
-+ SKIP(3);
-+ GROW;
-+ while (RAW != ';') { /* loop blocked by count */
-+ if ((RAW >= '0') && (RAW <= '9') && (count < 20))
-+ val = val * 16 + (CUR - '0');
-+ else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
-+ val = val * 16 + (CUR - 'a') + 10;
-+ else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
-+ val = val * 16 + (CUR - 'A') + 10;
-+ else {
-+ ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseCharRef: invalid hexadecimal value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ val = 0;
-+ break;
-+ }
-+ NEXT;
-+ count++;
-+ }
-+ if (RAW == ';') {
-+ /* on purpose to avoid reentrancy problems with NEXT and SKIP */
-+ ctxt->nbChars ++;
-+ ctxt->input->cur++;
-+ }
-+ } else if ((RAW == '&') && (NXT(1) == '#')) {
-+ SKIP(2);
-+ GROW;
-+ while (RAW != ';') { /* loop blocked by count */
-+ if ((RAW >= '0') && (RAW <= '9') && (count < 20))
-+ val = val * 10 + (CUR - '0');
-+ else {
-+ ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseCharRef: invalid decimal value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ val = 0;
-+ break;
-+ }
-+ NEXT;
-+ count++;
-+ }
-+ if (RAW == ';') {
-+ /* on purpose to avoid reentrancy problems with NEXT and SKIP */
-+ ctxt->nbChars ++;
-+ ctxt->input->cur++;
-+ }
-+ } else {
-+ ctxt->errNo = XML_ERR_INVALID_CHARREF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseCharRef: invalid value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * [ WFC: Legal Character ]
-+ * Characters referred to using character references must match the
-+ * production for Char.
-+ */
-+ if (IS_CHAR(val)) {
-+ return(val);
-+ } else {
-+ ctxt->errNo = XML_ERR_INVALID_CHAR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "CharRef: invalid xmlChar value %d\n",
-+ val);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseStringCharRef:
-+ * @ctxt: an XML parser context
-+ * @str: a pointer to an index in the string
-+ *
-+ * parse Reference declarations, variant parsing from a string rather
-+ * than an an input flow.
-+ *
-+ * [66] CharRef ::= '&#' [0-9]+ ';' |
-+ * '&#x' [0-9a-fA-F]+ ';'
-+ *
-+ * [ WFC: Legal Character ]
-+ * Characters referred to using character references must match the
-+ * production for Char.
-+ *
-+ * Returns the value parsed (as an int), 0 in case of error, str will be
-+ * updated to the current value of the index
-+ */
-+int
-+xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
-+ const xmlChar *ptr;
-+ xmlChar cur;
-+ int val = 0;
-+
-+ if ((str == NULL) || (*str == NULL)) return(0);
-+ ptr = *str;
-+ cur = *ptr;
-+ if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
-+ ptr += 3;
-+ cur = *ptr;
-+ while (cur != ';') { /* Non input consuming loop */
-+ if ((cur >= '0') && (cur <= '9'))
-+ val = val * 16 + (cur - '0');
-+ else if ((cur >= 'a') && (cur <= 'f'))
-+ val = val * 16 + (cur - 'a') + 10;
-+ else if ((cur >= 'A') && (cur <= 'F'))
-+ val = val * 16 + (cur - 'A') + 10;
-+ else {
-+ ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStringCharRef: invalid hexadecimal value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ val = 0;
-+ break;
-+ }
-+ ptr++;
-+ cur = *ptr;
-+ }
-+ if (cur == ';')
-+ ptr++;
-+ } else if ((cur == '&') && (ptr[1] == '#')){
-+ ptr += 2;
-+ cur = *ptr;
-+ while (cur != ';') { /* Non input consuming loops */
-+ if ((cur >= '0') && (cur <= '9'))
-+ val = val * 10 + (cur - '0');
-+ else {
-+ ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStringCharRef: invalid decimal value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ val = 0;
-+ break;
-+ }
-+ ptr++;
-+ cur = *ptr;
-+ }
-+ if (cur == ';')
-+ ptr++;
-+ } else {
-+ ctxt->errNo = XML_ERR_INVALID_CHARREF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseCharRef: invalid value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(0);
-+ }
-+ *str = ptr;
-+
-+ /*
-+ * [ WFC: Legal Character ]
-+ * Characters referred to using character references must match the
-+ * production for Char.
-+ */
-+ if (IS_CHAR(val)) {
-+ return(val);
-+ } else {
-+ ctxt->errNo = XML_ERR_INVALID_CHAR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "CharRef: invalid xmlChar value %d\n", val);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlParserHandlePEReference:
-+ * @ctxt: the parser context
-+ *
-+ * [69] PEReference ::= '%' Name ';'
-+ *
-+ * [ WFC: No Recursion ]
-+ * A parsed entity must not contain a recursive
-+ * reference to itself, either directly or indirectly.
-+ *
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an internal DTD
-+ * subset which contains no parameter entity references, or a document
-+ * with "standalone='yes'", ... ... The declaration of a parameter
-+ * entity must precede any reference to it...
-+ *
-+ * [ VC: Entity Declared ]
-+ * In a document with an external subset or external parameter entities
-+ * with "standalone='no'", ... ... The declaration of a parameter entity
-+ * must precede any reference to it...
-+ *
-+ * [ WFC: In DTD ]
-+ * Parameter-entity references may only appear in the DTD.
-+ * NOTE: misleading but this is handled.
-+ *
-+ * A PEReference may have been detected in the current input stream
-+ * the handling is done accordingly to
-+ * http://www.w3.org/TR/REC-xml#entproc
-+ * i.e.
-+ * - Included in literal in entity values
-+ * - Included as Paraemeter Entity reference within DTDs
-+ */
-+void
-+xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlEntityPtr entity = NULL;
-+ xmlParserInputPtr input;
-+
-+ if (ctxt->token != 0) {
-+ return;
-+ }
-+ if (RAW != '%') return;
-+ switch(ctxt->instate) {
-+ case XML_PARSER_CDATA_SECTION:
-+ return;
-+ case XML_PARSER_COMMENT:
-+ return;
-+ case XML_PARSER_START_TAG:
-+ return;
-+ case XML_PARSER_END_TAG:
-+ return;
-+ case XML_PARSER_EOF:
-+ ctxt->errNo = XML_ERR_PEREF_AT_EOF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "PEReference at EOF\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_PROLOG:
-+ case XML_PARSER_START:
-+ case XML_PARSER_MISC:
-+ ctxt->errNo = XML_ERR_PEREF_IN_PROLOG;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "PEReference in prolog!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_ENTITY_DECL:
-+ case XML_PARSER_CONTENT:
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ case XML_PARSER_PI:
-+ case XML_PARSER_SYSTEM_LITERAL:
-+ /* we just ignore it there */
-+ return;
-+ case XML_PARSER_EPILOG:
-+ ctxt->errNo = XML_ERR_PEREF_IN_EPILOG;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "PEReference in epilog!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_ENTITY_VALUE:
-+ /*
-+ * NOTE: in the case of entity values, we don't do the
-+ * substitution here since we need the literal
-+ * entity value to be able to save the internal
-+ * subset of the document.
-+ * This will be handled by xmlStringDecodeEntities
-+ */
-+ return;
-+ case XML_PARSER_DTD:
-+ /*
-+ * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
-+ * In the internal DTD subset, parameter-entity references
-+ * can occur only where markup declarations can occur, not
-+ * within markup declarations.
-+ * In that case this is handled in xmlParseMarkupDecl
-+ */
-+ if ((ctxt->external == 0) && (ctxt->inputNr == 1))
-+ return;
-+ break;
-+ case XML_PARSER_IGNORE:
-+ return;
-+ }
-+
-+ NEXT;
-+ name = xmlParseName(ctxt);
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PE Reference: %s\n", name);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_PEREF_NO_NAME;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "xmlHandlePEReference: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (RAW == ';') {
-+ NEXT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
-+ entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
-+ if (entity == NULL) {
-+
-+ /*
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an
-+ * internal DTD subset which contains no parameter entity
-+ * references, or a document with "standalone='yes'", ...
-+ * ... The declaration of a parameter entity must precede
-+ * any reference to it...
-+ */
-+ if ((ctxt->standalone == 1) ||
-+ ((ctxt->hasExternalSubset == 0) &&
-+ (ctxt->hasPErefs == 0))) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "PEReference: %%%s; not found\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ /*
-+ * [ VC: Entity Declared ]
-+ * In a document with an external subset or external
-+ * parameter entities with "standalone='no'", ...
-+ * ... The declaration of a parameter entity must precede
-+ * any reference to it...
-+ */
-+ if ((!ctxt->disableSAX) &&
-+ (ctxt->validate) && (ctxt->vctxt.error != NULL)) {
-+ ctxt->vctxt.error(ctxt->vctxt.userData,
-+ "PEReference: %%%s; not found\n", name);
-+ } else if ((!ctxt->disableSAX) &&
-+ (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "PEReference: %%%s; not found\n", name);
-+ ctxt->valid = 0;
-+ }
-+ } else {
-+ if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
-+ (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
-+ /*
-+ * handle the extra spaces added before and after
-+ * c.f. http://www.w3.org/TR/REC-xml#as-PE
-+ * this is done independantly.
-+ */
-+ input = xmlNewEntityInputStream(ctxt, entity);
-+ xmlPushInput(ctxt, input);
-+ if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-+ (RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+ xmlParseTextDecl(ctxt);
-+ }
-+ if (ctxt->token == 0)
-+ ctxt->token = ' ';
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlHandlePEReference: %s is not a parameter entity\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+ } else {
-+ ctxt->errNo = XML_ERR_PEREF_SEMICOL_MISSING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlHandlePEReference: expecting ';'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlFree(name);
-+ }
-+}
-+
-+/*
-+ * Macro used to grow the current buffer.
-+ */
-+#define growBuffer(buffer) { \
-+ buffer##_size *= 2; \
-+ buffer = (xmlChar *) \
-+ xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
-+ if (buffer == NULL) { \
-+ perror("realloc failed"); \
-+ return(NULL); \
-+ } \
-+}
-+
-+/**
-+ * xmlStringDecodeEntities:
-+ * @ctxt: the parser context
-+ * @str: the input string
-+ * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
-+ * @end: an end marker xmlChar, 0 if none
-+ * @end2: an end marker xmlChar, 0 if none
-+ * @end3: an end marker xmlChar, 0 if none
-+ *
-+ * Takes a entity string content and process to do the adequate subtitutions.
-+ *
-+ * [67] Reference ::= EntityRef | CharRef
-+ *
-+ * [69] PEReference ::= '%' Name ';'
-+ *
-+ * Returns A newly allocated string with the substitution done. The caller
-+ * must deallocate it !
-+ */
-+xmlChar *
-+xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
-+ xmlChar end, xmlChar end2, xmlChar end3) {
-+ xmlChar *buffer = NULL;
-+ int buffer_size = 0;
-+
-+ xmlChar *current = NULL;
-+ xmlEntityPtr ent;
-+ int c,l;
-+ int nbchars = 0;
-+
-+ if (str == NULL)
-+ return(NULL);
-+
-+ if (ctxt->depth > 40) {
-+ ctxt->errNo = XML_ERR_ENTITY_LOOP;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Detected entity reference loop\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * allocate a translation buffer.
-+ */
-+ buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("xmlDecodeEntities: malloc failed");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Ok loop until we reach one of the ending char or a size limit.
-+ * we are operating on already parsed values.
-+ */
-+ c = CUR_SCHAR(str, l);
-+ while ((c != 0) && (c != end) && /* non input consuming loop */
-+ (c != end2) && (c != end3)) {
-+
-+ if (c == 0) break;
-+ if ((c == '&') && (str[1] == '#')) {
-+ int val = xmlParseStringCharRef(ctxt, &str);
-+ if (val != 0) {
-+ COPY_BUF(0,buffer,nbchars,val);
-+ }
-+ } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "String decoding Entity Reference: %.30s\n",
-+ str);
-+ ent = xmlParseStringEntityRef(ctxt, &str);
-+ if ((ent != NULL) &&
-+ (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-+ if (ent->content != NULL) {
-+ COPY_BUF(0,buffer,nbchars,ent->content[0]);
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "internal error entity has no content\n");
-+ }
-+ } else if ((ent != NULL) && (ent->content != NULL)) {
-+ xmlChar *rep;
-+
-+ ctxt->depth++;
-+ rep = xmlStringDecodeEntities(ctxt, ent->content, what,
-+ 0, 0, 0);
-+ ctxt->depth--;
-+ if (rep != NULL) {
-+ current = rep;
-+ while (*current != 0) { /* non input consuming loop */
-+ buffer[nbchars++] = *current++;
-+ if (nbchars >
-+ buffer_size - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ }
-+ xmlFree(rep);
-+ }
-+ } else if (ent != NULL) {
-+ int i = xmlStrlen(ent->name);
-+ const xmlChar *cur = ent->name;
-+
-+ buffer[nbchars++] = '&';
-+ if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ for (;i > 0;i--)
-+ buffer[nbchars++] = *cur++;
-+ buffer[nbchars++] = ';';
-+ }
-+ } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "String decoding PE Reference: %.30s\n", str);
-+ ent = xmlParseStringPEReference(ctxt, &str);
-+ if (ent != NULL) {
-+ xmlChar *rep;
-+
-+ ctxt->depth++;
-+ rep = xmlStringDecodeEntities(ctxt, ent->content, what,
-+ 0, 0, 0);
-+ ctxt->depth--;
-+ if (rep != NULL) {
-+ current = rep;
-+ while (*current != 0) { /* non input consuming loop */
-+ buffer[nbchars++] = *current++;
-+ if (nbchars >
-+ buffer_size - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ }
-+ xmlFree(rep);
-+ }
-+ }
-+ } else {
-+ COPY_BUF(l,buffer,nbchars,c);
-+ str += l;
-+ if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ }
-+ c = CUR_SCHAR(str, l);
-+ }
-+ buffer[nbchars++] = 0;
-+ return(buffer);
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to handle xmlChars *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlStrndup:
-+ * @cur: the input xmlChar *
-+ * @len: the len of @cur
-+ *
-+ * a strndup for array of xmlChar's
-+ *
-+ * Returns a new xmlChar * or NULL
-+ */
-+xmlChar *
-+xmlStrndup(const xmlChar *cur, int len) {
-+ xmlChar *ret;
-+
-+ if ((cur == NULL) || (len < 0)) return(NULL);
-+ ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %ld byte failed\n",
-+ (len + 1) * (long)sizeof(xmlChar));
-+ return(NULL);
-+ }
-+ memcpy(ret, cur, len * sizeof(xmlChar));
-+ ret[len] = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlStrdup:
-+ * @cur: the input xmlChar *
-+ *
-+ * a strdup for array of xmlChar's. Since they are supposed to be
-+ * encoded in UTF-8 or an encoding with 8bit based chars, we assume
-+ * a termination mark of '0'.
-+ *
-+ * Returns a new xmlChar * or NULL
-+ */
-+xmlChar *
-+xmlStrdup(const xmlChar *cur) {
-+ const xmlChar *p = cur;
-+
-+ if (cur == NULL) return(NULL);
-+ while (*p != 0) p++; /* non input consuming */
-+ return(xmlStrndup(cur, p - cur));
-+}
-+
-+/**
-+ * xmlCharStrndup:
-+ * @cur: the input char *
-+ * @len: the len of @cur
-+ *
-+ * a strndup for char's to xmlChar's
-+ *
-+ * Returns a new xmlChar * or NULL
-+ */
-+
-+xmlChar *
-+xmlCharStrndup(const char *cur, int len) {
-+ int i;
-+ xmlChar *ret;
-+
-+ if ((cur == NULL) || (len < 0)) return(NULL);
-+ ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n",
-+ (len + 1) * (long)sizeof(xmlChar));
-+ return(NULL);
-+ }
-+ for (i = 0;i < len;i++)
-+ ret[i] = (xmlChar) cur[i];
-+ ret[len] = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCharStrdup:
-+ * @cur: the input char *
-+ * @len: the len of @cur
-+ *
-+ * a strdup for char's to xmlChar's
-+ *
-+ * Returns a new xmlChar * or NULL
-+ */
-+
-+xmlChar *
-+xmlCharStrdup(const char *cur) {
-+ const char *p = cur;
-+
-+ if (cur == NULL) return(NULL);
-+ while (*p != '\0') p++; /* non input consuming */
-+ return(xmlCharStrndup(cur, p - cur));
-+}
-+
-+/**
-+ * xmlStrcmp:
-+ * @str1: the first xmlChar *
-+ * @str2: the second xmlChar *
-+ *
-+ * a strcmp for xmlChar's
-+ *
-+ * Returns the integer result of the comparison
-+ */
-+
-+int
-+xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
-+ register int tmp;
-+
-+ if (str1 == str2) return(0);
-+ if (str1 == NULL) return(-1);
-+ if (str2 == NULL) return(1);
-+ do {
-+ tmp = *str1++ - *str2;
-+ if (tmp != 0) return(tmp);
-+ } while (*str2++ != 0);
-+ return 0;
-+}
-+
-+/**
-+ * xmlStrEqual:
-+ * @str1: the first xmlChar *
-+ * @str2: the second xmlChar *
-+ *
-+ * Check if both string are equal of have same content
-+ * Should be a bit more readable and faster than xmlStrEqual()
-+ *
-+ * Returns 1 if they are equal, 0 if they are different
-+ */
-+
-+int
-+xmlStrEqual(const xmlChar *str1, const xmlChar *str2) {
-+ if (str1 == str2) return(1);
-+ if (str1 == NULL) return(0);
-+ if (str2 == NULL) return(0);
-+ do {
-+ if (*str1++ != *str2) return(0);
-+ } while (*str2++);
-+ return(1);
-+}
-+
-+/**
-+ * xmlStrncmp:
-+ * @str1: the first xmlChar *
-+ * @str2: the second xmlChar *
-+ * @len: the max comparison length
-+ *
-+ * a strncmp for xmlChar's
-+ *
-+ * Returns the integer result of the comparison
-+ */
-+
-+int
-+xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
-+ register int tmp;
-+
-+ if (len <= 0) return(0);
-+ if (str1 == str2) return(0);
-+ if (str1 == NULL) return(-1);
-+ if (str2 == NULL) return(1);
-+ do {
-+ tmp = *str1++ - *str2;
-+ if (tmp != 0 || --len == 0) return(tmp);
-+ } while (*str2++ != 0);
-+ return 0;
-+}
-+
-+static xmlChar casemap[256] = {
-+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
-+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+ 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
-+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
-+ 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
-+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
-+ 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
-+ 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
-+ 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
-+ 0x78,0x79,0x7A,0x7B,0x5C,0x5D,0x5E,0x5F,
-+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
-+ 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
-+ 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
-+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
-+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
-+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
-+ 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
-+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
-+ 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
-+ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
-+ 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
-+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
-+ 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
-+ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
-+ 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
-+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
-+ 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
-+ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
-+ 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
-+};
-+
-+/**
-+ * xmlStrcasecmp:
-+ * @str1: the first xmlChar *
-+ * @str2: the second xmlChar *
-+ *
-+ * a strcasecmp for xmlChar's
-+ *
-+ * Returns the integer result of the comparison
-+ */
-+
-+int
-+xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) {
-+ register int tmp;
-+
-+ if (str1 == str2) return(0);
-+ if (str1 == NULL) return(-1);
-+ if (str2 == NULL) return(1);
-+ do {
-+ tmp = casemap[*str1++] - casemap[*str2];
-+ if (tmp != 0) return(tmp);
-+ } while (*str2++ != 0);
-+ return 0;
-+}
-+
-+/**
-+ * xmlStrncasecmp:
-+ * @str1: the first xmlChar *
-+ * @str2: the second xmlChar *
-+ * @len: the max comparison length
-+ *
-+ * a strncasecmp for xmlChar's
-+ *
-+ * Returns the integer result of the comparison
-+ */
-+
-+int
-+xmlStrncasecmp(const xmlChar *str1, const xmlChar *str2, int len) {
-+ register int tmp;
-+
-+ if (len <= 0) return(0);
-+ if (str1 == str2) return(0);
-+ if (str1 == NULL) return(-1);
-+ if (str2 == NULL) return(1);
-+ do {
-+ tmp = casemap[*str1++] - casemap[*str2];
-+ if (tmp != 0 || --len == 0) return(tmp);
-+ } while (*str2++ != 0);
-+ return 0;
-+}
-+
-+/**
-+ * xmlStrchr:
-+ * @str: the xmlChar * array
-+ * @val: the xmlChar to search
-+ *
-+ * a strchr for xmlChar's
-+ *
-+ * Returns the xmlChar * for the first occurence or NULL.
-+ */
-+
-+const xmlChar *
-+xmlStrchr(const xmlChar *str, xmlChar val) {
-+ if (str == NULL) return(NULL);
-+ while (*str != 0) { /* non input consuming */
-+ if (*str == val) return((xmlChar *) str);
-+ str++;
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlStrstr:
-+ * @str: the xmlChar * array (haystack)
-+ * @val: the xmlChar to search (needle)
-+ *
-+ * a strstr for xmlChar's
-+ *
-+ * Returns the xmlChar * for the first occurence or NULL.
-+ */
-+
-+const xmlChar *
-+xmlStrstr(const xmlChar *str, xmlChar *val) {
-+ int n;
-+
-+ if (str == NULL) return(NULL);
-+ if (val == NULL) return(NULL);
-+ n = xmlStrlen(val);
-+
-+ if (n == 0) return(str);
-+ while (*str != 0) { /* non input consuming */
-+ if (*str == *val) {
-+ if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
-+ }
-+ str++;
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlStrcasestr:
-+ * @str: the xmlChar * array (haystack)
-+ * @val: the xmlChar to search (needle)
-+ *
-+ * a case-ignoring strstr for xmlChar's
-+ *
-+ * Returns the xmlChar * for the first occurence or NULL.
-+ */
-+
-+const xmlChar *
-+xmlStrcasestr(const xmlChar *str, xmlChar *val) {
-+ int n;
-+
-+ if (str == NULL) return(NULL);
-+ if (val == NULL) return(NULL);
-+ n = xmlStrlen(val);
-+
-+ if (n == 0) return(str);
-+ while (*str != 0) { /* non input consuming */
-+ if (casemap[*str] == casemap[*val])
-+ if (!xmlStrncasecmp(str, val, n)) return(str);
-+ str++;
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlStrsub:
-+ * @str: the xmlChar * array (haystack)
-+ * @start: the index of the first char (zero based)
-+ * @len: the length of the substring
-+ *
-+ * Extract a substring of a given string
-+ *
-+ * Returns the xmlChar * for the first occurence or NULL.
-+ */
-+
-+xmlChar *
-+xmlStrsub(const xmlChar *str, int start, int len) {
-+ int i;
-+
-+ if (str == NULL) return(NULL);
-+ if (start < 0) return(NULL);
-+ if (len < 0) return(NULL);
-+
-+ for (i = 0;i < start;i++) {
-+ if (*str == 0) return(NULL);
-+ str++;
-+ }
-+ if (*str == 0) return(NULL);
-+ return(xmlStrndup(str, len));
-+}
-+
-+/**
-+ * xmlStrlen:
-+ * @str: the xmlChar * array
-+ *
-+ * length of a xmlChar's string
-+ *
-+ * Returns the number of xmlChar contained in the ARRAY.
-+ */
-+
-+int
-+xmlStrlen(const xmlChar *str) {
-+ int len = 0;
-+
-+ if (str == NULL) return(0);
-+ while (*str != 0) { /* non input consuming */
-+ str++;
-+ len++;
-+ }
-+ return(len);
-+}
-+
-+/**
-+ * xmlStrncat:
-+ * @cur: the original xmlChar * array
-+ * @add: the xmlChar * array added
-+ * @len: the length of @add
-+ *
-+ * a strncat for array of xmlChar's, it will extend cur with the len
-+ * first bytes of @add.
-+ *
-+ * Returns a new xmlChar *, the original @cur is reallocated if needed
-+ * and should not be freed
-+ */
-+
-+xmlChar *
-+xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
-+ int size;
-+ xmlChar *ret;
-+
-+ if ((add == NULL) || (len == 0))
-+ return(cur);
-+ if (cur == NULL)
-+ return(xmlStrndup(add, len));
-+
-+ size = xmlStrlen(cur);
-+ ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlStrncat: realloc of %ld byte failed\n",
-+ (size + len + 1) * (long)sizeof(xmlChar));
-+ return(cur);
-+ }
-+ memcpy(&ret[size], add, len * sizeof(xmlChar));
-+ ret[size + len] = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlStrcat:
-+ * @cur: the original xmlChar * array
-+ * @add: the xmlChar * array added
-+ *
-+ * a strcat for array of xmlChar's. Since they are supposed to be
-+ * encoded in UTF-8 or an encoding with 8bit based chars, we assume
-+ * a termination mark of '0'.
-+ *
-+ * Returns a new xmlChar * containing the concatenated string.
-+ */
-+xmlChar *
-+xmlStrcat(xmlChar *cur, const xmlChar *add) {
-+ const xmlChar *p = add;
-+
-+ if (add == NULL) return(cur);
-+ if (cur == NULL)
-+ return(xmlStrdup(add));
-+
-+ while (*p != 0) p++; /* non input consuming */
-+ return(xmlStrncat(cur, add, p - add));
-+}
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions, cleanup needed ? *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * areBlanks:
-+ * @ctxt: an XML parser context
-+ * @str: a xmlChar *
-+ * @len: the size of @str
-+ *
-+ * Is this a sequence of blank chars that one can ignore ?
-+ *
-+ * Returns 1 if ignorable 0 otherwise.
-+ */
-+
-+static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
-+ int i, ret;
-+ xmlNodePtr lastChild;
-+
-+ /*
-+ * Check for xml:space value.
-+ */
-+ if (*(ctxt->space) == 1)
-+ return(0);
-+
-+ /*
-+ * Check that the string is made of blanks
-+ */
-+ for (i = 0;i < len;i++)
-+ if (!(IS_BLANK(str[i]))) return(0);
-+
-+ /*
-+ * Look if the element is mixed content in the Dtd if available
-+ */
-+ if (ctxt->myDoc != NULL) {
-+ ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
-+ if (ret == 0) return(1);
-+ if (ret == 1) return(0);
-+ }
-+
-+ /*
-+ * Otherwise, heuristic :-\
-+ */
-+ if (ctxt->keepBlanks)
-+ return(0);
-+ if (RAW != '<') return(0);
-+ if (ctxt->node == NULL) return(0);
-+ if ((ctxt->node->children == NULL) &&
-+ (RAW == '<') && (NXT(1) == '/')) return(0);
-+
-+ lastChild = xmlGetLastChild(ctxt->node);
-+ if (lastChild == NULL) {
-+ if (ctxt->node->content != NULL) return(0);
-+ } else if (xmlNodeIsText(lastChild))
-+ return(0);
-+ else if ((ctxt->node->children != NULL) &&
-+ (xmlNodeIsText(ctxt->node->children)))
-+ return(0);
-+ return(1);
-+}
-+
-+/*
-+ * Forward definition for recusive behaviour.
-+ */
-+void xmlParsePEReference(xmlParserCtxtPtr ctxt);
-+void xmlParseReference(xmlParserCtxtPtr ctxt);
-+
-+/************************************************************************
-+ * *
-+ * Extra stuff for namespace support *
-+ * Relates to http://www.w3.org/TR/WD-xml-names *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlSplitQName:
-+ * @ctxt: an XML parser context
-+ * @name: an XML parser context
-+ * @prefix: a xmlChar **
-+ *
-+ * parse an UTF8 encoded XML qualified name string
-+ *
-+ * [NS 5] QName ::= (Prefix ':')? LocalPart
-+ *
-+ * [NS 6] Prefix ::= NCName
-+ *
-+ * [NS 7] LocalPart ::= NCName
-+ *
-+ * Returns the local part, and prefix is updated
-+ * to get the Prefix if any.
-+ */
-+
-+xmlChar *
-+xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
-+ xmlChar buf[XML_MAX_NAMELEN + 5];
-+ xmlChar *buffer = NULL;
-+ int len = 0;
-+ int max = XML_MAX_NAMELEN;
-+ xmlChar *ret = NULL;
-+ const xmlChar *cur = name;
-+ int c;
-+
-+ *prefix = NULL;
-+
-+ /* xml: prefix is not really a namespace */
-+ if ((cur[0] == 'x') && (cur[1] == 'm') &&
-+ (cur[2] == 'l') && (cur[3] == ':'))
-+ return(xmlStrdup(name));
-+
-+ /* nasty but valid */
-+ if (cur[0] == ':')
-+ return(xmlStrdup(name));
-+
-+ c = *cur++;
-+ while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
-+ buf[len++] = c;
-+ c = *cur++;
-+ }
-+ if (len >= max) {
-+ /*
-+ * Okay someone managed to make a huge name, so he's ready to pay
-+ * for the processing speed.
-+ */
-+ max = len * 2;
-+
-+ buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlSplitQName: out of memory\n");
-+ return(NULL);
-+ }
-+ memcpy(buffer, buf, len);
-+ while ((c != 0) && (c != ':')) { /* tested bigname.xml */
-+ if (len + 10 > max) {
-+ max *= 2;
-+ buffer = (xmlChar *) xmlRealloc(buffer,
-+ max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlSplitQName: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ buffer[len++] = c;
-+ c = *cur++;
-+ }
-+ buffer[len] = 0;
-+ }
-+
-+ if (buffer == NULL)
-+ ret = xmlStrndup(buf, len);
-+ else {
-+ ret = buffer;
-+ buffer = NULL;
-+ max = XML_MAX_NAMELEN;
-+ }
-+
-+
-+ if (c == ':') {
-+ c = *cur++;
-+ if (c == 0) return(ret);
-+ *prefix = ret;
-+ len = 0;
-+
-+ while ((c != 0) && (len < max)) { /* tested bigname2.xml */
-+ buf[len++] = c;
-+ c = *cur++;
-+ }
-+ if (len >= max) {
-+ /*
-+ * Okay someone managed to make a huge name, so he's ready to pay
-+ * for the processing speed.
-+ */
-+ max = len * 2;
-+
-+ buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlSplitQName: out of memory\n");
-+ return(NULL);
-+ }
-+ memcpy(buffer, buf, len);
-+ while (c != 0) { /* tested bigname2.xml */
-+ if (len + 10 > max) {
-+ max *= 2;
-+ buffer = (xmlChar *) xmlRealloc(buffer,
-+ max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlSplitQName: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ buffer[len++] = c;
-+ c = *cur++;
-+ }
-+ buffer[len] = 0;
-+ }
-+
-+ if (buffer == NULL)
-+ ret = xmlStrndup(buf, len);
-+ else {
-+ ret = buffer;
-+ }
-+ }
-+
-+ return(ret);
-+}
-+
-+/************************************************************************
-+ * *
-+ * The parser itself *
-+ * Relates to http://www.w3.org/TR/REC-xml *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlParseName:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML name.
-+ *
-+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-+ * CombiningChar | Extender
-+ *
-+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-+ *
-+ * [6] Names ::= Name (S Name)*
-+ *
-+ * Returns the Name parsed or NULL
-+ */
-+
-+xmlChar *
-+xmlParseName(xmlParserCtxtPtr ctxt) {
-+ xmlChar buf[XML_MAX_NAMELEN + 5];
-+ int len = 0, l;
-+ int c;
-+ int count = 0;
-+
-+ GROW;
-+ c = CUR_CHAR(l);
-+ if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
-+ (!IS_LETTER(c) && (c != '_') &&
-+ (c != ':'))) {
-+ return(NULL);
-+ }
-+
-+ while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
-+ ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
-+ (c == '.') || (c == '-') ||
-+ (c == '_') || (c == ':') ||
-+ (IS_COMBINING(c)) ||
-+ (IS_EXTENDER(c)))) {
-+ if (count++ > 100) {
-+ count = 0;
-+ GROW;
-+ }
-+ COPY_BUF(l,buf,len,c);
-+ NEXTL(l);
-+ c = CUR_CHAR(l);
-+ if (len >= XML_MAX_NAMELEN) {
-+ /*
-+ * Okay someone managed to make a huge name, so he's ready to pay
-+ * for the processing speed.
-+ */
-+ xmlChar *buffer;
-+ int max = len * 2;
-+
-+ buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseName: out of memory\n");
-+ return(NULL);
-+ }
-+ memcpy(buffer, buf, len);
-+ while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
-+ (c == '.') || (c == '-') ||
-+ (c == '_') || (c == ':') ||
-+ (IS_COMBINING(c)) ||
-+ (IS_EXTENDER(c))) {
-+ if (count++ > 100) {
-+ count = 0;
-+ GROW;
-+ }
-+ if (len + 10 > max) {
-+ max *= 2;
-+ buffer = (xmlChar *) xmlRealloc(buffer,
-+ max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseName: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ COPY_BUF(l,buffer,len,c);
-+ NEXTL(l);
-+ c = CUR_CHAR(l);
-+ }
-+ buffer[len] = 0;
-+ return(buffer);
-+ }
-+ }
-+ return(xmlStrndup(buf, len));
-+}
-+
-+/**
-+ * xmlParseStringName:
-+ * @ctxt: an XML parser context
-+ * @str: a pointer to the string pointer (IN/OUT)
-+ *
-+ * parse an XML name.
-+ *
-+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-+ * CombiningChar | Extender
-+ *
-+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-+ *
-+ * [6] Names ::= Name (S Name)*
-+ *
-+ * Returns the Name parsed or NULL. The str pointer
-+ * is updated to the current location in the string.
-+ */
-+
-+xmlChar *
-+xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
-+ xmlChar buf[XML_MAX_NAMELEN + 5];
-+ const xmlChar *cur = *str;
-+ int len = 0, l;
-+ int c;
-+
-+ c = CUR_SCHAR(cur, l);
-+ if (!IS_LETTER(c) && (c != '_') &&
-+ (c != ':')) {
-+ return(NULL);
-+ }
-+
-+ while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
-+ (c == '.') || (c == '-') ||
-+ (c == '_') || (c == ':') ||
-+ (IS_COMBINING(c)) ||
-+ (IS_EXTENDER(c))) {
-+ COPY_BUF(l,buf,len,c);
-+ cur += l;
-+ c = CUR_SCHAR(cur, l);
-+ if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
-+ /*
-+ * Okay someone managed to make a huge name, so he's ready to pay
-+ * for the processing speed.
-+ */
-+ xmlChar *buffer;
-+ int max = len * 2;
-+
-+ buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStringName: out of memory\n");
-+ return(NULL);
-+ }
-+ memcpy(buffer, buf, len);
-+ while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
-+ (c == '.') || (c == '-') ||
-+ (c == '_') || (c == ':') ||
-+ (IS_COMBINING(c)) ||
-+ (IS_EXTENDER(c))) {
-+ if (len + 10 > max) {
-+ max *= 2;
-+ buffer = (xmlChar *) xmlRealloc(buffer,
-+ max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStringName: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ COPY_BUF(l,buffer,len,c);
-+ cur += l;
-+ c = CUR_SCHAR(cur, l);
-+ }
-+ buffer[len] = 0;
-+ *str = cur;
-+ return(buffer);
-+ }
-+ }
-+ *str = cur;
-+ return(xmlStrndup(buf, len));
-+}
-+
-+/**
-+ * xmlParseNmtoken:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML Nmtoken.
-+ *
-+ * [7] Nmtoken ::= (NameChar)+
-+ *
-+ * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
-+ *
-+ * Returns the Nmtoken parsed or NULL
-+ */
-+
-+xmlChar *
-+xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
-+ xmlChar buf[XML_MAX_NAMELEN + 5];
-+ int len = 0, l;
-+ int c;
-+ int count = 0;
-+
-+ GROW;
-+ c = CUR_CHAR(l);
-+
-+ while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
-+ (c == '.') || (c == '-') ||
-+ (c == '_') || (c == ':') ||
-+ (IS_COMBINING(c)) ||
-+ (IS_EXTENDER(c))) {
-+ if (count++ > 100) {
-+ count = 0;
-+ GROW;
-+ }
-+ COPY_BUF(l,buf,len,c);
-+ NEXTL(l);
-+ c = CUR_CHAR(l);
-+ if (len >= XML_MAX_NAMELEN) {
-+ /*
-+ * Okay someone managed to make a huge token, so he's ready to pay
-+ * for the processing speed.
-+ */
-+ xmlChar *buffer;
-+ int max = len * 2;
-+
-+ buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseNmtoken: out of memory\n");
-+ return(NULL);
-+ }
-+ memcpy(buffer, buf, len);
-+ while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
-+ (c == '.') || (c == '-') ||
-+ (c == '_') || (c == ':') ||
-+ (IS_COMBINING(c)) ||
-+ (IS_EXTENDER(c))) {
-+ if (count++ > 100) {
-+ count = 0;
-+ GROW;
-+ }
-+ if (len + 10 > max) {
-+ max *= 2;
-+ buffer = (xmlChar *) xmlRealloc(buffer,
-+ max * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseName: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ COPY_BUF(l,buffer,len,c);
-+ NEXTL(l);
-+ c = CUR_CHAR(l);
-+ }
-+ buffer[len] = 0;
-+ return(buffer);
-+ }
-+ }
-+ if (len == 0)
-+ return(NULL);
-+ return(xmlStrndup(buf, len));
-+}
-+
-+/**
-+ * xmlParseEntityValue:
-+ * @ctxt: an XML parser context
-+ * @orig: if non-NULL store a copy of the original entity value
-+ *
-+ * parse a value for ENTITY declarations
-+ *
-+ * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
-+ * "'" ([^%&'] | PEReference | Reference)* "'"
-+ *
-+ * Returns the EntityValue parsed with reference substitued or NULL
-+ */
-+
-+xmlChar *
-+xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ int c, l;
-+ xmlChar stop;
-+ xmlChar *ret = NULL;
-+ const xmlChar *cur = NULL;
-+ xmlParserInputPtr input;
-+
-+ if (RAW == '"') stop = '"';
-+ else if (RAW == '\'') stop = '\'';
-+ else {
-+ ctxt->errNo = XML_ERR_ENTITY_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "EntityValue: \" or ' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * The content of the entity definition is copied in a buffer.
-+ */
-+
-+ ctxt->instate = XML_PARSER_ENTITY_VALUE;
-+ input = ctxt->input;
-+ GROW;
-+ NEXT;
-+ c = CUR_CHAR(l);
-+ /*
-+ * NOTE: 4.4.5 Included in Literal
-+ * When a parameter entity reference appears in a literal entity
-+ * value, ... a single or double quote character in the replacement
-+ * text is always treated as a normal data character and will not
-+ * terminate the literal.
-+ * In practice it means we stop the loop only when back at parsing
-+ * the initial entity and the quote is found
-+ */
-+ while ((IS_CHAR(c)) && ((c != stop) || /* checked */
-+ (ctxt->input != input))) {
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ }
-+ COPY_BUF(l,buf,len,c);
-+ NEXTL(l);
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
-+ xmlPopInput(ctxt);
-+
-+ GROW;
-+ c = CUR_CHAR(l);
-+ if (c == 0) {
-+ GROW;
-+ c = CUR_CHAR(l);
-+ }
-+ }
-+ buf[len] = 0;
-+
-+ /*
-+ * Raise problem w.r.t. '&' and '%' being used in non-entities
-+ * reference constructs. Note Charref will be handled in
-+ * xmlStringDecodeEntities()
-+ */
-+ cur = buf;
-+ while (*cur != 0) { /* non input consuming */
-+ if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
-+ xmlChar *name;
-+ xmlChar tmp = *cur;
-+
-+ cur++;
-+ name = xmlParseStringName(ctxt, &cur);
-+ if ((name == NULL) || (*cur != ';')) {
-+ ctxt->errNo = XML_ERR_ENTITY_CHAR_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "EntityValue: '%c' forbidden except for entities references\n",
-+ tmp);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if ((ctxt->inSubset == 1) && (tmp == '%')) {
-+ ctxt->errNo = XML_ERR_ENTITY_PE_INTERNAL;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "EntityValue: PEReferences forbidden in internal subset\n",
-+ tmp);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (name != NULL)
-+ xmlFree(name);
-+ }
-+ cur++;
-+ }
-+
-+ /*
-+ * Then PEReference entities are substituted.
-+ */
-+ if (c != stop) {
-+ ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "EntityValue: \" expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFree(buf);
-+ } else {
-+ NEXT;
-+ /*
-+ * NOTE: 4.4.7 Bypassed
-+ * When a general entity reference appears in the EntityValue in
-+ * an entity declaration, it is bypassed and left as is.
-+ * so XML_SUBSTITUTE_REF is not set here.
-+ */
-+ ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
-+ 0, 0, 0);
-+ if (orig != NULL)
-+ *orig = buf;
-+ else
-+ xmlFree(buf);
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseAttValue:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse a value for an attribute
-+ * Note: the parser won't do substitution of entities here, this
-+ * will be handled later in xmlStringGetNodeList
-+ *
-+ * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
-+ * "'" ([^<&'] | Reference)* "'"
-+ *
-+ * 3.3.3 Attribute-Value Normalization:
-+ * Before the value of an attribute is passed to the application or
-+ * checked for validity, the XML processor must normalize it as follows:
-+ * - a character reference is processed by appending the referenced
-+ * character to the attribute value
-+ * - an entity reference is processed by recursively processing the
-+ * replacement text of the entity
-+ * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
-+ * appending #x20 to the normalized value, except that only a single
-+ * #x20 is appended for a "#xD#xA" sequence that is part of an external
-+ * parsed entity or the literal entity value of an internal parsed entity
-+ * - other characters are processed by appending them to the normalized value
-+ * If the declared value is not CDATA, then the XML processor must further
-+ * process the normalized attribute value by discarding any leading and
-+ * trailing space (#x20) characters, and by replacing sequences of space
-+ * (#x20) characters by a single space (#x20) character.
-+ * All attributes for which no declaration has been read should be treated
-+ * by a non-validating parser as if declared CDATA.
-+ *
-+ * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
-+ */
-+
-+xmlChar *
-+xmlParseAttValue(xmlParserCtxtPtr ctxt) {
-+ xmlChar limit = 0;
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int buf_size = 0;
-+ int c, l;
-+ xmlChar *current = NULL;
-+ xmlEntityPtr ent;
-+
-+
-+ SHRINK;
-+ if (NXT(0) == '"') {
-+ ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
-+ limit = '"';
-+ NEXT;
-+ } else if (NXT(0) == '\'') {
-+ limit = '\'';
-+ ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "AttValue: \" or ' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * allocate a translation buffer.
-+ */
-+ buf_size = XML_PARSER_BUFFER_SIZE;
-+ buf = (xmlChar *) xmlMalloc(buf_size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ perror("xmlParseAttValue: malloc failed");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Ok loop until we reach one of the ending char or a size limit.
-+ */
-+ c = CUR_CHAR(l);
-+ while (((NXT(0) != limit) && /* checked */
-+ (c != '<')) || (ctxt->token != 0)) {
-+ if (c == 0) break;
-+ if (ctxt->token == '&') {
-+ /*
-+ * The reparsing will be done in xmlStringGetNodeList()
-+ * called by the attribute() function in SAX.c
-+ */
-+ static xmlChar buffer[6] = "&";
-+
-+ if (len > buf_size - 10) {
-+ growBuffer(buf);
-+ }
-+ current = &buffer[0];
-+ while (*current != 0) { /* non input consuming */
-+ buf[len++] = *current++;
-+ }
-+ ctxt->token = 0;
-+ } else if (c == '&') {
-+ if (NXT(1) == '#') {
-+ int val = xmlParseCharRef(ctxt);
-+ if (val == '&') {
-+ /*
-+ * The reparsing will be done in xmlStringGetNodeList()
-+ * called by the attribute() function in SAX.c
-+ */
-+ static xmlChar buffer[6] = "&";
-+
-+ if (len > buf_size - 10) {
-+ growBuffer(buf);
-+ }
-+ current = &buffer[0];
-+ while (*current != 0) { /* non input consuming */
-+ buf[len++] = *current++;
-+ }
-+ } else {
-+ len += xmlCopyChar(0, &buf[len], val);
-+ }
-+ } else {
-+ ent = xmlParseEntityRef(ctxt);
-+ if ((ent != NULL) &&
-+ (ctxt->replaceEntities != 0)) {
-+ xmlChar *rep;
-+
-+ if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
-+ rep = xmlStringDecodeEntities(ctxt, ent->content,
-+ XML_SUBSTITUTE_REF, 0, 0, 0);
-+ if (rep != NULL) {
-+ current = rep;
-+ while (*current != 0) { /* non input consuming */
-+ buf[len++] = *current++;
-+ if (len > buf_size - 10) {
-+ growBuffer(buf);
-+ }
-+ }
-+ xmlFree(rep);
-+ }
-+ } else {
-+ if (ent->content != NULL)
-+ buf[len++] = ent->content[0];
-+ }
-+ } else if (ent != NULL) {
-+ int i = xmlStrlen(ent->name);
-+ const xmlChar *cur = ent->name;
-+
-+ /*
-+ * This may look absurd but is needed to detect
-+ * entities problems
-+ */
-+ if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
-+ (ent->content != NULL)) {
-+ xmlChar *rep;
-+ rep = xmlStringDecodeEntities(ctxt, ent->content,
-+ XML_SUBSTITUTE_REF, 0, 0, 0);
-+ if (rep != NULL)
-+ xmlFree(rep);
-+ }
-+
-+ /*
-+ * Just output the reference
-+ */
-+ buf[len++] = '&';
-+ if (len > buf_size - i - 10) {
-+ growBuffer(buf);
-+ }
-+ for (;i > 0;i--)
-+ buf[len++] = *cur++;
-+ buf[len++] = ';';
-+ }
-+ }
-+ } else {
-+ if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
-+ COPY_BUF(l,buf,len,0x20);
-+ if (len > buf_size - 10) {
-+ growBuffer(buf);
-+ }
-+ } else {
-+ COPY_BUF(l,buf,len,c);
-+ if (len > buf_size - 10) {
-+ growBuffer(buf);
-+ }
-+ }
-+ NEXTL(l);
-+ }
-+ GROW;
-+ c = CUR_CHAR(l);
-+ }
-+ buf[len++] = 0;
-+ if (RAW == '<') {
-+ ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Unescaped '<' not allowed in attributes values\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if (RAW != limit) {
-+ ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ return(buf);
-+}
-+
-+/**
-+ * xmlParseSystemLiteral:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML Literal
-+ *
-+ * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
-+ *
-+ * Returns the SystemLiteral parsed or NULL
-+ */
-+
-+xmlChar *
-+xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ int cur, l;
-+ xmlChar stop;
-+ int state = ctxt->instate;
-+ int count = 0;
-+
-+ SHRINK;
-+ if (RAW == '"') {
-+ NEXT;
-+ stop = '"';
-+ } else if (RAW == '\'') {
-+ NEXT;
-+ stop = '\'';
-+ } else {
-+ ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "SystemLiteral \" or ' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
-+ cur = CUR_CHAR(l);
-+ while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ ctxt->instate = (xmlParserInputState) state;
-+ return(NULL);
-+ }
-+ }
-+ count++;
-+ if (count > 50) {
-+ GROW;
-+ count = 0;
-+ }
-+ COPY_BUF(l,buf,len,cur);
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ if (cur == 0) {
-+ GROW;
-+ SHRINK;
-+ cur = CUR_CHAR(l);
-+ }
-+ }
-+ buf[len] = 0;
-+ ctxt->instate = (xmlParserInputState) state;
-+ if (!IS_CHAR(cur)) {
-+ ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ NEXT;
-+ }
-+ return(buf);
-+}
-+
-+/**
-+ * xmlParsePubidLiteral:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML public literal
-+ *
-+ * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
-+ *
-+ * Returns the PubidLiteral parsed or NULL.
-+ */
-+
-+xmlChar *
-+xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ xmlChar cur;
-+ xmlChar stop;
-+ int count = 0;
-+
-+ SHRINK;
-+ if (RAW == '"') {
-+ NEXT;
-+ stop = '"';
-+ } else if (RAW == '\'') {
-+ NEXT;
-+ stop = '\'';
-+ } else {
-+ ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "SystemLiteral \" or ' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ cur = CUR;
-+ while ((IS_PUBIDCHAR(cur)) && (cur != stop)) { /* checked */
-+ if (len + 1 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ }
-+ buf[len++] = cur;
-+ count++;
-+ if (count > 50) {
-+ GROW;
-+ count = 0;
-+ }
-+ NEXT;
-+ cur = CUR;
-+ if (cur == 0) {
-+ GROW;
-+ SHRINK;
-+ cur = CUR;
-+ }
-+ }
-+ buf[len] = 0;
-+ if (cur != stop) {
-+ ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ NEXT;
-+ }
-+ return(buf);
-+}
-+
-+/**
-+ * xmlParseCharData:
-+ * @ctxt: an XML parser context
-+ * @cdata: int indicating whether we are within a CDATA section
-+ *
-+ * parse a CharData section.
-+ * if we are within a CDATA section ']]>' marks an end of section.
-+ *
-+ * The right angle bracket (>) may be represented using the string ">",
-+ * and must, for compatibility, be escaped using ">" or a character
-+ * reference when it appears in the string "]]>" in content, when that
-+ * string is not marking the end of a CDATA section.
-+ *
-+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-+ */
-+
-+void
-+xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
-+ xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
-+ int nbchar = 0;
-+ int cur, l;
-+ int count = 0;
-+
-+ SHRINK;
-+ GROW;
-+ cur = CUR_CHAR(l);
-+ while (((cur != '<') || (ctxt->token == '<')) && /* checked */
-+ ((cur != '&') || (ctxt->token == '&')) &&
-+ (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
-+ if ((cur == ']') && (NXT(1) == ']') &&
-+ (NXT(2) == '>')) {
-+ if (cdata) break;
-+ else {
-+ ctxt->errNo = XML_ERR_MISPLACED_CDATA_END;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Sequence ']]>' not allowed in content\n");
-+ /* Should this be relaxed ??? I see a "must here */
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+ COPY_BUF(l,buf,nbchar,cur);
-+ if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
-+ /*
-+ * Ok the segment is to be consumed as chars.
-+ */
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (areBlanks(ctxt, buf, nbchar)) {
-+ if (ctxt->sax->ignorableWhitespace != NULL)
-+ ctxt->sax->ignorableWhitespace(ctxt->userData,
-+ buf, nbchar);
-+ } else {
-+ if (ctxt->sax->characters != NULL)
-+ ctxt->sax->characters(ctxt->userData, buf, nbchar);
-+ }
-+ }
-+ nbchar = 0;
-+ }
-+ count++;
-+ if (count > 50) {
-+ GROW;
-+ count = 0;
-+ }
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ }
-+ if (nbchar != 0) {
-+ /*
-+ * Ok the segment is to be consumed as chars.
-+ */
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (areBlanks(ctxt, buf, nbchar)) {
-+ if (ctxt->sax->ignorableWhitespace != NULL)
-+ ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
-+ } else {
-+ if (ctxt->sax->characters != NULL)
-+ ctxt->sax->characters(ctxt->userData, buf, nbchar);
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlParseExternalID:
-+ * @ctxt: an XML parser context
-+ * @publicID: a xmlChar** receiving PubidLiteral
-+ * @strict: indicate whether we should restrict parsing to only
-+ * production [75], see NOTE below
-+ *
-+ * Parse an External ID or a Public ID
-+ *
-+ * NOTE: Productions [75] and [83] interract badly since [75] can generate
-+ * 'PUBLIC' S PubidLiteral S SystemLiteral
-+ *
-+ * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-+ * | 'PUBLIC' S PubidLiteral S SystemLiteral
-+ *
-+ * [83] PublicID ::= 'PUBLIC' S PubidLiteral
-+ *
-+ * Returns the function returns SystemLiteral and in the second
-+ * case publicID receives PubidLiteral, is strict is off
-+ * it is possible to return NULL and have publicID set.
-+ */
-+
-+xmlChar *
-+xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
-+ xmlChar *URI = NULL;
-+
-+ SHRINK;
-+ if ((RAW == 'S') && (NXT(1) == 'Y') &&
-+ (NXT(2) == 'S') && (NXT(3) == 'T') &&
-+ (NXT(4) == 'E') && (NXT(5) == 'M')) {
-+ SKIP(6);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'SYSTEM'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ URI = xmlParseSystemLiteral(ctxt);
-+ if (URI == NULL) {
-+ ctxt->errNo = XML_ERR_URI_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseExternalID: SYSTEM, no URI\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ } else if ((RAW == 'P') && (NXT(1) == 'U') &&
-+ (NXT(2) == 'B') && (NXT(3) == 'L') &&
-+ (NXT(4) == 'I') && (NXT(5) == 'C')) {
-+ SKIP(6);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'PUBLIC'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ *publicID = xmlParsePubidLiteral(ctxt);
-+ if (*publicID == NULL) {
-+ ctxt->errNo = XML_ERR_PUBID_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseExternalID: PUBLIC, no Public Identifier\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (strict) {
-+ /*
-+ * We don't handle [83] so "S SystemLiteral" is required.
-+ */
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the Public Identifier\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ } else {
-+ /*
-+ * We handle [83] so we return immediately, if
-+ * "S SystemLiteral" is not detected. From a purely parsing
-+ * point of view that's a nice mess.
-+ */
-+ const xmlChar *ptr;
-+ GROW;
-+
-+ ptr = CUR_PTR;
-+ if (!IS_BLANK(*ptr)) return(NULL);
-+
-+ while (IS_BLANK(*ptr)) ptr++; /* TODO: dangerous, fix ! */
-+ if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
-+ }
-+ SKIP_BLANKS;
-+ URI = xmlParseSystemLiteral(ctxt);
-+ if (URI == NULL) {
-+ ctxt->errNo = XML_ERR_URI_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseExternalID: PUBLIC, no URI\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+ return(URI);
-+}
-+
-+/**
-+ * xmlParseComment:
-+ * @ctxt: an XML parser context
-+ *
-+ * Skip an XML (SGML) comment <!-- .... -->
-+ * The spec says that "For compatibility, the string "--" (double-hyphen)
-+ * must not occur within comments. "
-+ *
-+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-+ */
-+void
-+xmlParseComment(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ int q, ql;
-+ int r, rl;
-+ int cur, l;
-+ xmlParserInputState state;
-+ xmlParserInputPtr input = ctxt->input;
-+ int count = 0;
-+
-+ /*
-+ * Check that there is a comment right here.
-+ */
-+ if ((RAW != '<') || (NXT(1) != '!') ||
-+ (NXT(2) != '-') || (NXT(3) != '-')) return;
-+
-+ state = ctxt->instate;
-+ ctxt->instate = XML_PARSER_COMMENT;
-+ SHRINK;
-+ SKIP(4);
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ ctxt->instate = state;
-+ return;
-+ }
-+ q = CUR_CHAR(ql);
-+ NEXTL(ql);
-+ r = CUR_CHAR(rl);
-+ NEXTL(rl);
-+ cur = CUR_CHAR(l);
-+ len = 0;
-+ while (IS_CHAR(cur) && /* checked */
-+ ((cur != '>') ||
-+ (r != '-') || (q != '-'))) {
-+ if ((r == '-') && (q == '-') && (len > 1)) {
-+ ctxt->errNo = XML_ERR_HYPHEN_IN_COMMENT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Comment must not contain '--' (double-hyphen)`\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ ctxt->instate = state;
-+ return;
-+ }
-+ }
-+ COPY_BUF(ql,buf,len,q);
-+ q = r;
-+ ql = rl;
-+ r = cur;
-+ rl = l;
-+
-+ count++;
-+ if (count > 50) {
-+ GROW;
-+ count = 0;
-+ }
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ if (cur == 0) {
-+ SHRINK;
-+ GROW;
-+ cur = CUR_CHAR(l);
-+ }
-+ }
-+ buf[len] = 0;
-+ if (!IS_CHAR(cur)) {
-+ ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Comment not terminated \n<!--%.50s\n", buf);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFree(buf);
-+ } else {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Comment doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ NEXT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->comment(ctxt->userData, buf);
-+ xmlFree(buf);
-+ }
-+ ctxt->instate = state;
-+}
-+
-+/**
-+ * xmlParsePITarget:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the name of a PI
-+ *
-+ * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
-+ *
-+ * Returns the PITarget name or NULL
-+ */
-+
-+xmlChar *
-+xmlParsePITarget(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+
-+ name = xmlParseName(ctxt);
-+ if ((name != NULL) &&
-+ ((name[0] == 'x') || (name[0] == 'X')) &&
-+ ((name[1] == 'm') || (name[1] == 'M')) &&
-+ ((name[2] == 'l') || (name[2] == 'L'))) {
-+ int i;
-+ if ((name[0] == 'x') && (name[1] == 'm') &&
-+ (name[2] == 'l') && (name[3] == 0)) {
-+ ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML declaration allowed only at the start of the document\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(name);
-+ } else if (name[3] == 0) {
-+ ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Invalid PI name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(name);
-+ }
-+ for (i = 0;;i++) {
-+ if (xmlW3CPIs[i] == NULL) break;
-+ if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
-+ return(name);
-+ }
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) {
-+ ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
-+ ctxt->sax->warning(ctxt->userData,
-+ "xmlParsePItarget: invalid name prefix 'xml'\n");
-+ }
-+ }
-+ return(name);
-+}
-+
-+/**
-+ * xmlParsePI:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML Processing Instruction.
-+ *
-+ * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
-+ *
-+ * The processing is transfered to SAX once parsed.
-+ */
-+
-+void
-+xmlParsePI(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ int cur, l;
-+ xmlChar *target;
-+ xmlParserInputState state;
-+ int count = 0;
-+
-+ if ((RAW == '<') && (NXT(1) == '?')) {
-+ xmlParserInputPtr input = ctxt->input;
-+ state = ctxt->instate;
-+ ctxt->instate = XML_PARSER_PI;
-+ /*
-+ * this is a Processing Instruction.
-+ */
-+ SKIP(2);
-+ SHRINK;
-+
-+ /*
-+ * Parse the target name and check for special support like
-+ * namespace.
-+ */
-+ target = xmlParsePITarget(ctxt);
-+ if (target != NULL) {
-+ if ((RAW == '?') && (NXT(1) == '>')) {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "PI declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP(2);
-+
-+ /*
-+ * SAX: PI detected.
-+ */
-+ if ((ctxt->sax) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->processingInstruction != NULL))
-+ ctxt->sax->processingInstruction(ctxt->userData,
-+ target, NULL);
-+ ctxt->instate = state;
-+ xmlFree(target);
-+ return;
-+ }
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ ctxt->instate = state;
-+ return;
-+ }
-+ cur = CUR;
-+ if (!IS_BLANK(cur)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParsePI: PI %s space expected\n", target);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ cur = CUR_CHAR(l);
-+ while (IS_CHAR(cur) && /* checked */
-+ ((cur != '?') || (NXT(1) != '>'))) {
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ ctxt->instate = state;
-+ return;
-+ }
-+ }
-+ count++;
-+ if (count > 50) {
-+ GROW;
-+ count = 0;
-+ }
-+ COPY_BUF(l,buf,len,cur);
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ if (cur == 0) {
-+ SHRINK;
-+ GROW;
-+ cur = CUR_CHAR(l);
-+ }
-+ }
-+ buf[len] = 0;
-+ if (cur != '?') {
-+ ctxt->errNo = XML_ERR_PI_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParsePI: PI %s never end ...\n", target);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "PI declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP(2);
-+
-+ /*
-+ * SAX: PI detected.
-+ */
-+ if ((ctxt->sax) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->processingInstruction != NULL))
-+ ctxt->sax->processingInstruction(ctxt->userData,
-+ target, buf);
-+ }
-+ xmlFree(buf);
-+ xmlFree(target);
-+ } else {
-+ ctxt->errNo = XML_ERR_PI_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParsePI : no target name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ ctxt->instate = state;
-+ }
-+}
-+
-+/**
-+ * xmlParseNotationDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse a notation declaration
-+ *
-+ * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
-+ *
-+ * Hence there is actually 3 choices:
-+ * 'PUBLIC' S PubidLiteral
-+ * 'PUBLIC' S PubidLiteral S SystemLiteral
-+ * and 'SYSTEM' S SystemLiteral
-+ *
-+ * See the NOTE on xmlParseExternalID().
-+ */
-+
-+void
-+xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *Pubid;
-+ xmlChar *Systemid;
-+
-+ if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == 'N') && (NXT(3) == 'O') &&
-+ (NXT(4) == 'T') && (NXT(5) == 'A') &&
-+ (NXT(6) == 'T') && (NXT(7) == 'I') &&
-+ (NXT(8) == 'O') && (NXT(9) == 'N')) {
-+ xmlParserInputPtr input = ctxt->input;
-+ SHRINK;
-+ SKIP(10);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after '<!NOTATION'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ SKIP_BLANKS;
-+
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "NOTATION: Name expected here\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the NOTATION name'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Parse the IDs.
-+ */
-+ Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
-+ SKIP_BLANKS;
-+
-+ if (RAW == '>') {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Notation declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ NEXT;
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->notationDecl != NULL))
-+ ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
-+ } else {
-+ ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "'>' required to close NOTATION declaration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlFree(name);
-+ if (Systemid != NULL) xmlFree(Systemid);
-+ if (Pubid != NULL) xmlFree(Pubid);
-+ }
-+}
-+
-+/**
-+ * xmlParseEntityDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse <!ENTITY declarations
-+ *
-+ * [70] EntityDecl ::= GEDecl | PEDecl
-+ *
-+ * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
-+ *
-+ * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
-+ *
-+ * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
-+ *
-+ * [74] PEDef ::= EntityValue | ExternalID
-+ *
-+ * [76] NDataDecl ::= S 'NDATA' S Name
-+ *
-+ * [ VC: Notation Declared ]
-+ * The Name must match the declared name of a notation.
-+ */
-+
-+void
-+xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name = NULL;
-+ xmlChar *value = NULL;
-+ xmlChar *URI = NULL, *literal = NULL;
-+ xmlChar *ndata = NULL;
-+ int isParameter = 0;
-+ xmlChar *orig = NULL;
-+
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == 'E') && (NXT(3) == 'N') &&
-+ (NXT(4) == 'T') && (NXT(5) == 'I') &&
-+ (NXT(6) == 'T') && (NXT(7) == 'Y')) {
-+ xmlParserInputPtr input = ctxt->input;
-+ ctxt->instate = XML_PARSER_ENTITY_DECL;
-+ SHRINK;
-+ SKIP(8);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after '<!ENTITY'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+
-+ if (RAW == '%') {
-+ NEXT;
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after '%'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ isParameter = 1;
-+ }
-+
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "xmlParseEntityDecl: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the entity name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+
-+ /*
-+ * handle the various case of definitions...
-+ */
-+ if (isParameter) {
-+ if ((RAW == '"') || (RAW == '\'')) {
-+ value = xmlParseEntityValue(ctxt, &orig);
-+ if (value) {
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
-+ ctxt->sax->entityDecl(ctxt->userData, name,
-+ XML_INTERNAL_PARAMETER_ENTITY,
-+ NULL, NULL, value);
-+ }
-+ } else {
-+ URI = xmlParseExternalID(ctxt, &literal, 1);
-+ if ((URI == NULL) && (literal == NULL)) {
-+ ctxt->errNo = XML_ERR_VALUE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity value required\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (URI) {
-+ xmlURIPtr uri;
-+
-+ uri = xmlParseURI((const char *) URI);
-+ if (uri == NULL) {
-+ ctxt->errNo = XML_ERR_INVALID_URI;
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Invalid URI: %s\n", URI);
-+ ctxt->wellFormed = 0;
-+ } else {
-+ if (uri->fragment != NULL) {
-+ ctxt->errNo = XML_ERR_URI_FRAGMENT;
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Fragment not allowed: %s\n", URI);
-+ ctxt->wellFormed = 0;
-+ } else {
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) &&
-+ (ctxt->sax->entityDecl != NULL))
-+ ctxt->sax->entityDecl(ctxt->userData, name,
-+ XML_EXTERNAL_PARAMETER_ENTITY,
-+ literal, URI, NULL);
-+ }
-+ xmlFreeURI(uri);
-+ }
-+ }
-+ }
-+ } else {
-+ if ((RAW == '"') || (RAW == '\'')) {
-+ value = xmlParseEntityValue(ctxt, &orig);
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
-+ ctxt->sax->entityDecl(ctxt->userData, name,
-+ XML_INTERNAL_GENERAL_ENTITY,
-+ NULL, NULL, value);
-+ } else {
-+ URI = xmlParseExternalID(ctxt, &literal, 1);
-+ if ((URI == NULL) && (literal == NULL)) {
-+ ctxt->errNo = XML_ERR_VALUE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity value required\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (URI) {
-+ xmlURIPtr uri;
-+
-+ uri = xmlParseURI((const char *)URI);
-+ if (uri == NULL) {
-+ ctxt->errNo = XML_ERR_INVALID_URI;
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Invalid URI: %s\n", URI);
-+ ctxt->wellFormed = 0;
-+ } else {
-+ if (uri->fragment != NULL) {
-+ ctxt->errNo = XML_ERR_URI_FRAGMENT;
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Fragment not allowed: %s\n", URI);
-+ ctxt->wellFormed = 0;
-+ }
-+ xmlFreeURI(uri);
-+ }
-+ }
-+ if ((RAW != '>') && (!IS_BLANK(CUR))) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required before 'NDATA'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ if ((RAW == 'N') && (NXT(1) == 'D') &&
-+ (NXT(2) == 'A') && (NXT(3) == 'T') &&
-+ (NXT(4) == 'A')) {
-+ SKIP(5);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'NDATA'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ ndata = xmlParseName(ctxt);
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->unparsedEntityDecl != NULL))
-+ ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
-+ literal, URI, ndata);
-+ } else {
-+ if ((ctxt->sax != NULL) &&
-+ (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
-+ ctxt->sax->entityDecl(ctxt->userData, name,
-+ XML_EXTERNAL_GENERAL_PARSED_ENTITY,
-+ literal, URI, NULL);
-+ }
-+ }
-+ }
-+ SKIP_BLANKS;
-+ if (RAW != '>') {
-+ ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEntityDecl: entity %s not terminated\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Entity declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ NEXT;
-+ }
-+ if (orig != NULL) {
-+ /*
-+ * Ugly mechanism to save the raw entity value.
-+ */
-+ xmlEntityPtr cur = NULL;
-+
-+ if (isParameter) {
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->getParameterEntity != NULL))
-+ cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
-+ } else {
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->getEntity != NULL))
-+ cur = ctxt->sax->getEntity(ctxt->userData, name);
-+ }
-+ if (cur != NULL) {
-+ if (cur->orig != NULL)
-+ xmlFree(orig);
-+ else
-+ cur->orig = orig;
-+ } else
-+ xmlFree(orig);
-+ }
-+ if (name != NULL) xmlFree(name);
-+ if (value != NULL) xmlFree(value);
-+ if (URI != NULL) xmlFree(URI);
-+ if (literal != NULL) xmlFree(literal);
-+ if (ndata != NULL) xmlFree(ndata);
-+ }
-+}
-+
-+/**
-+ * xmlParseDefaultDecl:
-+ * @ctxt: an XML parser context
-+ * @value: Receive a possible fixed default value for the attribute
-+ *
-+ * Parse an attribute default declaration
-+ *
-+ * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
-+ *
-+ * [ VC: Required Attribute ]
-+ * if the default declaration is the keyword #REQUIRED, then the
-+ * attribute must be specified for all elements of the type in the
-+ * attribute-list declaration.
-+ *
-+ * [ VC: Attribute Default Legal ]
-+ * The declared default value must meet the lexical constraints of
-+ * the declared attribute type c.f. xmlValidateAttributeDecl()
-+ *
-+ * [ VC: Fixed Attribute Default ]
-+ * if an attribute has a default value declared with the #FIXED
-+ * keyword, instances of that attribute must match the default value.
-+ *
-+ * [ WFC: No < in Attribute Values ]
-+ * handled in xmlParseAttValue()
-+ *
-+ * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
-+ * or XML_ATTRIBUTE_FIXED.
-+ */
-+
-+int
-+xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
-+ int val;
-+ xmlChar *ret;
-+
-+ *value = NULL;
-+ if ((RAW == '#') && (NXT(1) == 'R') &&
-+ (NXT(2) == 'E') && (NXT(3) == 'Q') &&
-+ (NXT(4) == 'U') && (NXT(5) == 'I') &&
-+ (NXT(6) == 'R') && (NXT(7) == 'E') &&
-+ (NXT(8) == 'D')) {
-+ SKIP(9);
-+ return(XML_ATTRIBUTE_REQUIRED);
-+ }
-+ if ((RAW == '#') && (NXT(1) == 'I') &&
-+ (NXT(2) == 'M') && (NXT(3) == 'P') &&
-+ (NXT(4) == 'L') && (NXT(5) == 'I') &&
-+ (NXT(6) == 'E') && (NXT(7) == 'D')) {
-+ SKIP(8);
-+ return(XML_ATTRIBUTE_IMPLIED);
-+ }
-+ val = XML_ATTRIBUTE_NONE;
-+ if ((RAW == '#') && (NXT(1) == 'F') &&
-+ (NXT(2) == 'I') && (NXT(3) == 'X') &&
-+ (NXT(4) == 'E') && (NXT(5) == 'D')) {
-+ SKIP(6);
-+ val = XML_ATTRIBUTE_FIXED;
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after '#FIXED'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ }
-+ ret = xmlParseAttValue(ctxt);
-+ ctxt->instate = XML_PARSER_DTD;
-+ if (ret == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attribute default value declaration error\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ *value = ret;
-+ return(val);
-+}
-+
-+/**
-+ * xmlParseNotationType:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an Notation attribute type.
-+ *
-+ * Note: the leading 'NOTATION' S part has already being parsed...
-+ *
-+ * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
-+ *
-+ * [ VC: Notation Attributes ]
-+ * Values of this type must match one of the notation names included
-+ * in the declaration; all notation names in the declaration must be declared.
-+ *
-+ * Returns: the notation attribute tree built while parsing
-+ */
-+
-+xmlEnumerationPtr
-+xmlParseNotationType(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlEnumerationPtr ret = NULL, last = NULL, cur;
-+
-+ if (RAW != '(') {
-+ ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "'(' required to start 'NOTATION'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ SHRINK;
-+ do {
-+ NEXT;
-+ SKIP_BLANKS;
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Name expected in NOTATION declaration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(ret);
-+ }
-+ cur = xmlCreateEnumeration(name);
-+ xmlFree(name);
-+ if (cur == NULL) return(ret);
-+ if (last == NULL) ret = last = cur;
-+ else {
-+ last->next = cur;
-+ last = cur;
-+ }
-+ SKIP_BLANKS;
-+ } while (RAW == '|');
-+ if (RAW != ')') {
-+ ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "')' required to finish NOTATION declaration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if ((last != NULL) && (last != ret))
-+ xmlFreeEnumeration(last);
-+ return(ret);
-+ }
-+ NEXT;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseEnumerationType:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an Enumeration attribute type.
-+ *
-+ * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
-+ *
-+ * [ VC: Enumeration ]
-+ * Values of this type must match one of the Nmtoken tokens in
-+ * the declaration
-+ *
-+ * Returns: the enumeration attribute tree built while parsing
-+ */
-+
-+xmlEnumerationPtr
-+xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlEnumerationPtr ret = NULL, last = NULL, cur;
-+
-+ if (RAW != '(') {
-+ ctxt->errNo = XML_ERR_ATTLIST_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "'(' required to start ATTLIST enumeration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ SHRINK;
-+ do {
-+ NEXT;
-+ SKIP_BLANKS;
-+ name = xmlParseNmtoken(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NMTOKEN_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "NmToken expected in ATTLIST enumeration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(ret);
-+ }
-+ cur = xmlCreateEnumeration(name);
-+ xmlFree(name);
-+ if (cur == NULL) return(ret);
-+ if (last == NULL) ret = last = cur;
-+ else {
-+ last->next = cur;
-+ last = cur;
-+ }
-+ SKIP_BLANKS;
-+ } while (RAW == '|');
-+ if (RAW != ')') {
-+ ctxt->errNo = XML_ERR_ATTLIST_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "')' required to finish ATTLIST enumeration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(ret);
-+ }
-+ NEXT;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseEnumeratedType:
-+ * @ctxt: an XML parser context
-+ * @tree: the enumeration tree built while parsing
-+ *
-+ * parse an Enumerated attribute type.
-+ *
-+ * [57] EnumeratedType ::= NotationType | Enumeration
-+ *
-+ * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
-+ *
-+ *
-+ * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
-+ */
-+
-+int
-+xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
-+ if ((RAW == 'N') && (NXT(1) == 'O') &&
-+ (NXT(2) == 'T') && (NXT(3) == 'A') &&
-+ (NXT(4) == 'T') && (NXT(5) == 'I') &&
-+ (NXT(6) == 'O') && (NXT(7) == 'N')) {
-+ SKIP(8);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'NOTATION'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(0);
-+ }
-+ SKIP_BLANKS;
-+ *tree = xmlParseNotationType(ctxt);
-+ if (*tree == NULL) return(0);
-+ return(XML_ATTRIBUTE_NOTATION);
-+ }
-+ *tree = xmlParseEnumerationType(ctxt);
-+ if (*tree == NULL) return(0);
-+ return(XML_ATTRIBUTE_ENUMERATION);
-+}
-+
-+/**
-+ * xmlParseAttributeType:
-+ * @ctxt: an XML parser context
-+ * @tree: the enumeration tree built while parsing
-+ *
-+ * parse the Attribute list def for an element
-+ *
-+ * [54] AttType ::= StringType | TokenizedType | EnumeratedType
-+ *
-+ * [55] StringType ::= 'CDATA'
-+ *
-+ * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
-+ * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
-+ *
-+ * Validity constraints for attribute values syntax are checked in
-+ * xmlValidateAttributeValue()
-+ *
-+ * [ VC: ID ]
-+ * Values of type ID must match the Name production. A name must not
-+ * appear more than once in an XML document as a value of this type;
-+ * i.e., ID values must uniquely identify the elements which bear them.
-+ *
-+ * [ VC: One ID per Element Type ]
-+ * No element type may have more than one ID attribute specified.
-+ *
-+ * [ VC: ID Attribute Default ]
-+ * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
-+ *
-+ * [ VC: IDREF ]
-+ * Values of type IDREF must match the Name production, and values
-+ * of type IDREFS must match Names; each IDREF Name must match the value
-+ * of an ID attribute on some element in the XML document; i.e. IDREF
-+ * values must match the value of some ID attribute.
-+ *
-+ * [ VC: Entity Name ]
-+ * Values of type ENTITY must match the Name production, values
-+ * of type ENTITIES must match Names; each Entity Name must match the
-+ * name of an unparsed entity declared in the DTD.
-+ *
-+ * [ VC: Name Token ]
-+ * Values of type NMTOKEN must match the Nmtoken production; values
-+ * of type NMTOKENS must match Nmtokens.
-+ *
-+ * Returns the attribute type
-+ */
-+int
-+xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
-+ SHRINK;
-+ if ((RAW == 'C') && (NXT(1) == 'D') &&
-+ (NXT(2) == 'A') && (NXT(3) == 'T') &&
-+ (NXT(4) == 'A')) {
-+ SKIP(5);
-+ return(XML_ATTRIBUTE_CDATA);
-+ } else if ((RAW == 'I') && (NXT(1) == 'D') &&
-+ (NXT(2) == 'R') && (NXT(3) == 'E') &&
-+ (NXT(4) == 'F') && (NXT(5) == 'S')) {
-+ SKIP(6);
-+ return(XML_ATTRIBUTE_IDREFS);
-+ } else if ((RAW == 'I') && (NXT(1) == 'D') &&
-+ (NXT(2) == 'R') && (NXT(3) == 'E') &&
-+ (NXT(4) == 'F')) {
-+ SKIP(5);
-+ return(XML_ATTRIBUTE_IDREF);
-+ } else if ((RAW == 'I') && (NXT(1) == 'D')) {
-+ SKIP(2);
-+ return(XML_ATTRIBUTE_ID);
-+ } else if ((RAW == 'E') && (NXT(1) == 'N') &&
-+ (NXT(2) == 'T') && (NXT(3) == 'I') &&
-+ (NXT(4) == 'T') && (NXT(5) == 'Y')) {
-+ SKIP(6);
-+ return(XML_ATTRIBUTE_ENTITY);
-+ } else if ((RAW == 'E') && (NXT(1) == 'N') &&
-+ (NXT(2) == 'T') && (NXT(3) == 'I') &&
-+ (NXT(4) == 'T') && (NXT(5) == 'I') &&
-+ (NXT(6) == 'E') && (NXT(7) == 'S')) {
-+ SKIP(8);
-+ return(XML_ATTRIBUTE_ENTITIES);
-+ } else if ((RAW == 'N') && (NXT(1) == 'M') &&
-+ (NXT(2) == 'T') && (NXT(3) == 'O') &&
-+ (NXT(4) == 'K') && (NXT(5) == 'E') &&
-+ (NXT(6) == 'N') && (NXT(7) == 'S')) {
-+ SKIP(8);
-+ return(XML_ATTRIBUTE_NMTOKENS);
-+ } else if ((RAW == 'N') && (NXT(1) == 'M') &&
-+ (NXT(2) == 'T') && (NXT(3) == 'O') &&
-+ (NXT(4) == 'K') && (NXT(5) == 'E') &&
-+ (NXT(6) == 'N')) {
-+ SKIP(7);
-+ return(XML_ATTRIBUTE_NMTOKEN);
-+ }
-+ return(xmlParseEnumeratedType(ctxt, tree));
-+}
-+
-+/**
-+ * xmlParseAttributeListDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * : parse the Attribute list def for an element
-+ *
-+ * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
-+ *
-+ * [53] AttDef ::= S Name S AttType S DefaultDecl
-+ *
-+ */
-+void
-+xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *elemName;
-+ xmlChar *attrName;
-+ xmlEnumerationPtr tree;
-+
-+ if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == 'A') && (NXT(3) == 'T') &&
-+ (NXT(4) == 'T') && (NXT(5) == 'L') &&
-+ (NXT(6) == 'I') && (NXT(7) == 'S') &&
-+ (NXT(8) == 'T')) {
-+ xmlParserInputPtr input = ctxt->input;
-+
-+ SKIP(9);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after '<!ATTLIST'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ elemName = xmlParseName(ctxt);
-+ if (elemName == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "ATTLIST: no name for Element\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ SKIP_BLANKS;
-+ GROW;
-+ while (RAW != '>') {
-+ const xmlChar *check = CUR_PTR;
-+ int type;
-+ int def;
-+ xmlChar *defaultValue = NULL;
-+
-+ GROW;
-+ tree = NULL;
-+ attrName = xmlParseName(ctxt);
-+ if (attrName == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "ATTLIST: no name for Attribute\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ }
-+ GROW;
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the attribute name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ break;
-+ }
-+ SKIP_BLANKS;
-+
-+ type = xmlParseAttributeType(ctxt, &tree);
-+ if (type <= 0) {
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ break;
-+ }
-+
-+ GROW;
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the attribute type\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ if (tree != NULL)
-+ xmlFreeEnumeration(tree);
-+ break;
-+ }
-+ SKIP_BLANKS;
-+
-+ def = xmlParseDefaultDecl(ctxt, &defaultValue);
-+ if (def <= 0) {
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ if (tree != NULL)
-+ xmlFreeEnumeration(tree);
-+ break;
-+ }
-+
-+ GROW;
-+ if (RAW != '>') {
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the attribute default value\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ if (tree != NULL)
-+ xmlFreeEnumeration(tree);
-+ break;
-+ }
-+ SKIP_BLANKS;
-+ }
-+ if (check == CUR_PTR) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseAttributeListDecl: detected internal error\n");
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ if (tree != NULL)
-+ xmlFreeEnumeration(tree);
-+ break;
-+ }
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->attributeDecl != NULL))
-+ ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
-+ type, def, defaultValue, tree);
-+ if (attrName != NULL)
-+ xmlFree(attrName);
-+ if (defaultValue != NULL)
-+ xmlFree(defaultValue);
-+ GROW;
-+ }
-+ if (RAW == '>') {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Attribute list declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ NEXT;
-+ }
-+
-+ xmlFree(elemName);
-+ }
-+}
-+
-+/**
-+ * xmlParseElementMixedContentDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the declaration for a Mixed Element content
-+ * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
-+ *
-+ * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
-+ * '(' S? '#PCDATA' S? ')'
-+ *
-+ * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
-+ *
-+ * [ VC: No Duplicate Types ]
-+ * The same name must not appear more than once in a single
-+ * mixed-content declaration.
-+ *
-+ * returns: the list of the xmlElementContentPtr describing the element choices
-+ */
-+xmlElementContentPtr
-+xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt) {
-+ xmlElementContentPtr ret = NULL, cur = NULL, n;
-+ xmlChar *elem = NULL;
-+
-+ GROW;
-+ if ((RAW == '#') && (NXT(1) == 'P') &&
-+ (NXT(2) == 'C') && (NXT(3) == 'D') &&
-+ (NXT(4) == 'A') && (NXT(5) == 'T') &&
-+ (NXT(6) == 'A')) {
-+ SKIP(7);
-+ SKIP_BLANKS;
-+ SHRINK;
-+ if (RAW == ')') {
-+ ctxt->entity = ctxt->input;
-+ NEXT;
-+ ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
-+ if (RAW == '*') {
-+ ret->ocur = XML_ELEMENT_CONTENT_MULT;
-+ NEXT;
-+ }
-+ return(ret);
-+ }
-+ if ((RAW == '(') || (RAW == '|')) {
-+ ret = cur = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
-+ if (ret == NULL) return(NULL);
-+ }
-+ while (RAW == '|') {
-+ NEXT;
-+ if (elem == NULL) {
-+ ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
-+ if (ret == NULL) return(NULL);
-+ ret->c1 = cur;
-+ cur = ret;
-+ } else {
-+ n = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
-+ if (n == NULL) return(NULL);
-+ n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
-+ cur->c2 = n;
-+ cur = n;
-+ xmlFree(elem);
-+ }
-+ SKIP_BLANKS;
-+ elem = xmlParseName(ctxt);
-+ if (elem == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementMixedContentDecl : Name expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFreeElementContent(cur);
-+ return(NULL);
-+ }
-+ SKIP_BLANKS;
-+ GROW;
-+ }
-+ if ((RAW == ')') && (NXT(1) == '*')) {
-+ if (elem != NULL) {
-+ cur->c2 = xmlNewElementContent(elem,
-+ XML_ELEMENT_CONTENT_ELEMENT);
-+ xmlFree(elem);
-+ }
-+ ret->ocur = XML_ELEMENT_CONTENT_MULT;
-+ ctxt->entity = ctxt->input;
-+ SKIP(2);
-+ } else {
-+ if (elem != NULL) xmlFree(elem);
-+ xmlFreeElementContent(ret);
-+ ctxt->errNo = XML_ERR_MIXED_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementMixedContentDecl : '|' or ')*' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ } else {
-+ ctxt->errNo = XML_ERR_PCDATA_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementMixedContentDecl : '#PCDATA' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseElementChildrenContentDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the declaration for a Mixed Element content
-+ * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
-+ *
-+ *
-+ * [47] children ::= (choice | seq) ('?' | '*' | '+')?
-+ *
-+ * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
-+ *
-+ * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
-+ *
-+ * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
-+ *
-+ * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
-+ * TODO Parameter-entity replacement text must be properly nested
-+ * with parenthetized groups. That is to say, if either of the
-+ * opening or closing parentheses in a choice, seq, or Mixed
-+ * construct is contained in the replacement text for a parameter
-+ * entity, both must be contained in the same replacement text. For
-+ * interoperability, if a parameter-entity reference appears in a
-+ * choice, seq, or Mixed construct, its replacement text should not
-+ * be empty, and neither the first nor last non-blank character of
-+ * the replacement text should be a connector (| or ,).
-+ *
-+ * returns: the tree of xmlElementContentPtr describing the element
-+ * hierarchy.
-+ */
-+xmlElementContentPtr
-+#ifdef VMS
-+xmlParseElementChildrenContentD
-+#else
-+xmlParseElementChildrenContentDecl
-+#endif
-+(xmlParserCtxtPtr ctxt) {
-+ xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
-+ xmlChar *elem;
-+ xmlChar type = 0;
-+
-+ SKIP_BLANKS;
-+ GROW;
-+ if (RAW == '(') {
-+ /* Recurse on first child */
-+ NEXT;
-+ SKIP_BLANKS;
-+ cur = ret = xmlParseElementChildrenContentDecl(ctxt);
-+ SKIP_BLANKS;
-+ GROW;
-+ } else {
-+ elem = xmlParseName(ctxt);
-+ if (elem == NULL) {
-+ ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
-+ GROW;
-+ if (RAW == '?') {
-+ cur->ocur = XML_ELEMENT_CONTENT_OPT;
-+ NEXT;
-+ } else if (RAW == '*') {
-+ cur->ocur = XML_ELEMENT_CONTENT_MULT;
-+ NEXT;
-+ } else if (RAW == '+') {
-+ cur->ocur = XML_ELEMENT_CONTENT_PLUS;
-+ NEXT;
-+ } else {
-+ cur->ocur = XML_ELEMENT_CONTENT_ONCE;
-+ }
-+ xmlFree(elem);
-+ GROW;
-+ }
-+ SKIP_BLANKS;
-+ SHRINK;
-+ while (RAW != ')') {
-+ /*
-+ * Each loop we parse one separator and one element.
-+ */
-+ if (RAW == ',') {
-+ if (type == 0) type = CUR;
-+
-+ /*
-+ * Detect "Name | Name , Name" error
-+ */
-+ else if (type != CUR) {
-+ ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementChildrenContentDecl : '%c' expected\n",
-+ type);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if ((op != NULL) && (op != ret))
-+ xmlFreeElementContent(op);
-+ if ((last != NULL) && (last != ret) &&
-+ (last != ret->c1) && (last != ret->c2))
-+ xmlFreeElementContent(last);
-+ if (ret != NULL)
-+ xmlFreeElementContent(ret);
-+ return(NULL);
-+ }
-+ NEXT;
-+
-+ op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_SEQ);
-+ if (op == NULL) {
-+ xmlFreeElementContent(ret);
-+ return(NULL);
-+ }
-+ if (last == NULL) {
-+ op->c1 = ret;
-+ ret = cur = op;
-+ } else {
-+ cur->c2 = op;
-+ op->c1 = last;
-+ cur =op;
-+ last = NULL;
-+ }
-+ } else if (RAW == '|') {
-+ if (type == 0) type = CUR;
-+
-+ /*
-+ * Detect "Name , Name | Name" error
-+ */
-+ else if (type != CUR) {
-+ ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementChildrenContentDecl : '%c' expected\n",
-+ type);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if ((op != NULL) && (op != ret) && (op != last))
-+ xmlFreeElementContent(op);
-+ if ((last != NULL) && (last != ret) &&
-+ (last != ret->c1) && (last != ret->c2))
-+ xmlFreeElementContent(last);
-+ if (ret != NULL)
-+ xmlFreeElementContent(ret);
-+ return(NULL);
-+ }
-+ NEXT;
-+
-+ op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
-+ if (op == NULL) {
-+ if ((op != NULL) && (op != ret))
-+ xmlFreeElementContent(op);
-+ if ((last != NULL) && (last != ret) &&
-+ (last != ret->c1) && (last != ret->c2))
-+ xmlFreeElementContent(last);
-+ if (ret != NULL)
-+ xmlFreeElementContent(ret);
-+ return(NULL);
-+ }
-+ if (last == NULL) {
-+ op->c1 = ret;
-+ ret = cur = op;
-+ } else {
-+ cur->c2 = op;
-+ op->c1 = last;
-+ cur =op;
-+ last = NULL;
-+ }
-+ } else {
-+ ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementChildrenContentDecl : ',' '|' or ')' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if ((op != NULL) && (op != ret))
-+ xmlFreeElementContent(op);
-+ if ((last != NULL) && (last != ret) &&
-+ (last != ret->c1) && (last != ret->c2))
-+ xmlFreeElementContent(last);
-+ if (ret != NULL)
-+ xmlFreeElementContent(ret);
-+ return(NULL);
-+ }
-+ GROW;
-+ SKIP_BLANKS;
-+ GROW;
-+ if (RAW == '(') {
-+ /* Recurse on second child */
-+ NEXT;
-+ SKIP_BLANKS;
-+ last = xmlParseElementChildrenContentDecl(ctxt);
-+ SKIP_BLANKS;
-+ } else {
-+ elem = xmlParseName(ctxt);
-+ if (elem == NULL) {
-+ ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if ((op != NULL) && (op != ret))
-+ xmlFreeElementContent(op);
-+ if ((last != NULL) && (last != ret) &&
-+ (last != ret->c1) && (last != ret->c2))
-+ xmlFreeElementContent(last);
-+ if (ret != NULL)
-+ xmlFreeElementContent(ret);
-+ return(NULL);
-+ }
-+ last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
-+ xmlFree(elem);
-+ if (RAW == '?') {
-+ last->ocur = XML_ELEMENT_CONTENT_OPT;
-+ NEXT;
-+ } else if (RAW == '*') {
-+ last->ocur = XML_ELEMENT_CONTENT_MULT;
-+ NEXT;
-+ } else if (RAW == '+') {
-+ last->ocur = XML_ELEMENT_CONTENT_PLUS;
-+ NEXT;
-+ } else {
-+ last->ocur = XML_ELEMENT_CONTENT_ONCE;
-+ }
-+ }
-+ SKIP_BLANKS;
-+ GROW;
-+ }
-+ if ((cur != NULL) && (last != NULL)) {
-+ cur->c2 = last;
-+ }
-+ ctxt->entity = ctxt->input;
-+ NEXT;
-+ if (RAW == '?') {
-+ ret->ocur = XML_ELEMENT_CONTENT_OPT;
-+ NEXT;
-+ } else if (RAW == '*') {
-+ ret->ocur = XML_ELEMENT_CONTENT_MULT;
-+ NEXT;
-+ } else if (RAW == '+') {
-+ ret->ocur = XML_ELEMENT_CONTENT_PLUS;
-+ NEXT;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseElementContentDecl:
-+ * @ctxt: an XML parser context
-+ * @name: the name of the element being defined.
-+ * @result: the Element Content pointer will be stored here if any
-+ *
-+ * parse the declaration for an Element content either Mixed or Children,
-+ * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
-+ *
-+ * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
-+ *
-+ * returns: the type of element content XML_ELEMENT_TYPE_xxx
-+ */
-+
-+int
-+xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, xmlChar *name,
-+ xmlElementContentPtr *result) {
-+
-+ xmlElementContentPtr tree = NULL;
-+ xmlParserInputPtr input = ctxt->input;
-+ int res;
-+
-+ *result = NULL;
-+
-+ if (RAW != '(') {
-+ ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementContentDecl : '(' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(-1);
-+ }
-+ NEXT;
-+ GROW;
-+ SKIP_BLANKS;
-+ if ((RAW == '#') && (NXT(1) == 'P') &&
-+ (NXT(2) == 'C') && (NXT(3) == 'D') &&
-+ (NXT(4) == 'A') && (NXT(5) == 'T') &&
-+ (NXT(6) == 'A')) {
-+ tree = xmlParseElementMixedContentDecl(ctxt);
-+ res = XML_ELEMENT_TYPE_MIXED;
-+ } else {
-+ tree = xmlParseElementChildrenContentDecl(ctxt);
-+ res = XML_ELEMENT_TYPE_ELEMENT;
-+ }
-+ if ((ctxt->entity != NULL) && (input != ctxt->entity)) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Element content declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ *result = tree;
-+ return(res);
-+}
-+
-+/**
-+ * xmlParseElementDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an Element declaration.
-+ *
-+ * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
-+ *
-+ * [ VC: Unique Element Type Declaration ]
-+ * No element type may be declared more than once
-+ *
-+ * Returns the type of the element, or -1 in case of error
-+ */
-+int
-+xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ int ret = -1;
-+ xmlElementContentPtr content = NULL;
-+
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == 'E') && (NXT(3) == 'L') &&
-+ (NXT(4) == 'E') && (NXT(5) == 'M') &&
-+ (NXT(6) == 'E') && (NXT(7) == 'N') &&
-+ (NXT(8) == 'T')) {
-+ xmlParserInputPtr input = ctxt->input;
-+
-+ SKIP(9);
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after 'ELEMENT'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementDecl: no name for Element\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(-1);
-+ }
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space required after the element name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ if ((RAW == 'E') && (NXT(1) == 'M') &&
-+ (NXT(2) == 'P') && (NXT(3) == 'T') &&
-+ (NXT(4) == 'Y')) {
-+ SKIP(5);
-+ /*
-+ * Element must always be empty.
-+ */
-+ ret = XML_ELEMENT_TYPE_EMPTY;
-+ } else if ((RAW == 'A') && (NXT(1) == 'N') &&
-+ (NXT(2) == 'Y')) {
-+ SKIP(3);
-+ /*
-+ * Element is a generic container.
-+ */
-+ ret = XML_ELEMENT_TYPE_ANY;
-+ } else if (RAW == '(') {
-+ ret = xmlParseElementContentDecl(ctxt, name, &content);
-+ } else {
-+ /*
-+ * [ WFC: PEs in Internal Subset ] error handling.
-+ */
-+ if ((RAW == '%') && (ctxt->external == 0) &&
-+ (ctxt->inputNr == 1)) {
-+ ctxt->errNo = XML_ERR_PEREF_IN_INT_SUBSET;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "PEReference: forbidden within markup decl in internal subset\n");
-+ } else {
-+ ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
-+ }
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ if (name != NULL) xmlFree(name);
-+ return(-1);
-+ }
-+
-+ SKIP_BLANKS;
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+ SKIP_BLANKS;
-+
-+ if (RAW != '>') {
-+ ctxt->errNo = XML_ERR_GT_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseElementDecl: expected '>' at the end\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (input != ctxt->input) {
-+ ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Element declaration doesn't start and stop in the same entity\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ NEXT;
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->elementDecl != NULL))
-+ ctxt->sax->elementDecl(ctxt->userData, name, ret,
-+ content);
-+ }
-+ if (content != NULL) {
-+ xmlFreeElementContent(content);
-+ }
-+ if (name != NULL) {
-+ xmlFree(name);
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseMarkupDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse Markup declarations
-+ *
-+ * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
-+ * NotationDecl | PI | Comment
-+ *
-+ * [ VC: Proper Declaration/PE Nesting ]
-+ * Parameter-entity replacement text must be properly nested with
-+ * markup declarations. That is to say, if either the first character
-+ * or the last character of a markup declaration (markupdecl above) is
-+ * contained in the replacement text for a parameter-entity reference,
-+ * both must be contained in the same replacement text.
-+ *
-+ * [ WFC: PEs in Internal Subset ]
-+ * In the internal DTD subset, parameter-entity references can occur
-+ * only where markup declarations can occur, not within markup declarations.
-+ * (This does not apply to references that occur in external parameter
-+ * entities or to the external subset.)
-+ */
-+void
-+xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
-+ GROW;
-+ xmlParseElementDecl(ctxt);
-+ xmlParseAttributeListDecl(ctxt);
-+ xmlParseEntityDecl(ctxt);
-+ xmlParseNotationDecl(ctxt);
-+ xmlParsePI(ctxt);
-+ xmlParseComment(ctxt);
-+ /*
-+ * This is only for internal subset. On external entities,
-+ * the replacement is done before parsing stage
-+ */
-+ if ((ctxt->external == 0) && (ctxt->inputNr == 1))
-+ xmlParsePEReference(ctxt);
-+ ctxt->instate = XML_PARSER_DTD;
-+}
-+
-+/**
-+ * xmlParseTextDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML declaration header for external entities
-+ *
-+ * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-+ *
-+ * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
-+ */
-+
-+void
-+xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *version;
-+
-+ /*
-+ * We know that '<?xml' is here.
-+ */
-+ if ((RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+ SKIP(5);
-+ } else {
-+ ctxt->errNo = XML_ERR_XMLDECL_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Text declaration '<?xml' required\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+
-+ return;
-+ }
-+
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Space needed after '<?xml'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+
-+ /*
-+ * We may have the VersionInfo here.
-+ */
-+ version = xmlParseVersionInfo(ctxt);
-+ if (version == NULL)
-+ version = xmlCharStrdup(XML_DEFAULT_VERSION);
-+ ctxt->input->version = version;
-+
-+ /*
-+ * We must have the encoding declaration
-+ */
-+ if (!IS_BLANK(CUR)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Space needed here\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlParseEncodingDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right here
-+ */
-+ return;
-+ }
-+
-+ SKIP_BLANKS;
-+ if ((RAW == '?') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ } else if (RAW == '>') {
-+ /* Deprecated old WD ... */
-+ ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML declaration must end-up with '?>'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "parsing XML declaration: '?>' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ MOVETO_ENDTAG(CUR_PTR);
-+ NEXT;
-+ }
-+}
-+
-+/*
-+ * xmlParseConditionalSections
-+ * @ctxt: an XML parser context
-+ *
-+ * [61] conditionalSect ::= includeSect | ignoreSect
-+ * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
-+ * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
-+ * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
-+ * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
-+ */
-+
-+void
-+xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
-+ SKIP(3);
-+ SKIP_BLANKS;
-+ if ((RAW == 'I') && (NXT(1) == 'N') && (NXT(2) == 'C') &&
-+ (NXT(3) == 'L') && (NXT(4) == 'U') && (NXT(5) == 'D') &&
-+ (NXT(6) == 'E')) {
-+ SKIP(7);
-+ SKIP_BLANKS;
-+ if (RAW != '[') {
-+ ctxt->errNo = XML_ERR_CONDSEC_INVALID;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML conditional section '[' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ NEXT;
-+ }
-+ if (xmlParserDebugEntities) {
-+ if ((ctxt->input != NULL) && (ctxt->input->filename))
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s(%d): ", ctxt->input->filename,
-+ ctxt->input->line);
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Entering INCLUDE Conditional Section\n");
-+ }
-+
-+ while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
-+ (NXT(2) != '>'))) {
-+ const xmlChar *check = CUR_PTR;
-+ int cons = ctxt->input->consumed;
-+ int tok = ctxt->token;
-+
-+ if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-+ xmlParseConditionalSections(ctxt);
-+ } else if (IS_BLANK(CUR)) {
-+ NEXT;
-+ } else if (RAW == '%') {
-+ xmlParsePEReference(ctxt);
-+ } else
-+ xmlParseMarkupDecl(ctxt);
-+
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+
-+ if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
-+ (tok == ctxt->token)) {
-+ ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Content error in the external subset\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ }
-+ }
-+ if (xmlParserDebugEntities) {
-+ if ((ctxt->input != NULL) && (ctxt->input->filename))
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s(%d): ", ctxt->input->filename,
-+ ctxt->input->line);
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Leaving INCLUDE Conditional Section\n");
-+ }
-+
-+ } else if ((RAW == 'I') && (NXT(1) == 'G') && (NXT(2) == 'N') &&
-+ (NXT(3) == 'O') && (NXT(4) == 'R') && (NXT(5) == 'E')) {
-+ int state;
-+ int instate;
-+ int depth = 0;
-+
-+ SKIP(6);
-+ SKIP_BLANKS;
-+ if (RAW != '[') {
-+ ctxt->errNo = XML_ERR_CONDSEC_INVALID;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML conditional section '[' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ NEXT;
-+ }
-+ if (xmlParserDebugEntities) {
-+ if ((ctxt->input != NULL) && (ctxt->input->filename))
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s(%d): ", ctxt->input->filename,
-+ ctxt->input->line);
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Entering IGNORE Conditional Section\n");
-+ }
-+
-+ /*
-+ * Parse up to the end of the conditionnal section
-+ * But disable SAX event generating DTD building in the meantime
-+ */
-+ state = ctxt->disableSAX;
-+ instate = ctxt->instate;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_IGNORE;
-+
-+ while (depth >= 0) {
-+ if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-+ depth++;
-+ SKIP(3);
-+ continue;
-+ }
-+ if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
-+ if (--depth >= 0) SKIP(3);
-+ continue;
-+ }
-+ NEXT;
-+ continue;
-+ }
-+
-+ ctxt->disableSAX = state;
-+ ctxt->instate = instate;
-+
-+ if (xmlParserDebugEntities) {
-+ if ((ctxt->input != NULL) && (ctxt->input->filename))
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s(%d): ", ctxt->input->filename,
-+ ctxt->input->line);
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Leaving IGNORE Conditional Section\n");
-+ }
-+
-+ } else {
-+ ctxt->errNo = XML_ERR_CONDSEC_INVALID;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML conditional section INCLUDE or IGNORE keyword expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ if (RAW == 0)
-+ SHRINK;
-+
-+ if (RAW == 0) {
-+ ctxt->errNo = XML_ERR_CONDSEC_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML conditional section not closed\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ SKIP(3);
-+ }
-+}
-+
-+/**
-+ * xmlParseExternalSubset:
-+ * @ctxt: an XML parser context
-+ * @ExternalID: the external identifier
-+ * @SystemID: the system identifier (or URL)
-+ *
-+ * parse Markup declarations from an external subset
-+ *
-+ * [30] extSubset ::= textDecl? extSubsetDecl
-+ *
-+ * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
-+ */
-+void
-+xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
-+ const xmlChar *SystemID) {
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l')) {
-+ xmlParseTextDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right here
-+ */
-+ ctxt->instate = XML_PARSER_EOF;
-+ return;
-+ }
-+ }
-+ if (ctxt->myDoc == NULL) {
-+ ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-+ }
-+ if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
-+ xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
-+
-+ ctxt->instate = XML_PARSER_DTD;
-+ ctxt->external = 1;
-+ while (((RAW == '<') && (NXT(1) == '?')) ||
-+ ((RAW == '<') && (NXT(1) == '!')) ||
-+ IS_BLANK(CUR)) {
-+ const xmlChar *check = CUR_PTR;
-+ int cons = ctxt->input->consumed;
-+ int tok = ctxt->token;
-+
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-+ xmlParseConditionalSections(ctxt);
-+ } else if (IS_BLANK(CUR)) {
-+ NEXT;
-+ } else if (RAW == '%') {
-+ xmlParsePEReference(ctxt);
-+ } else
-+ xmlParseMarkupDecl(ctxt);
-+
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+
-+ if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
-+ (tok == ctxt->token)) {
-+ ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Content error in the external subset\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ }
-+ }
-+
-+ if (RAW != 0) {
-+ ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra content at the end of the document\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+}
-+
-+/**
-+ * xmlParseReference:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse and handle entity references in content, depending on the SAX
-+ * interface, this may end-up in a call to character() if this is a
-+ * CharRef, a predefined entity, if there is no reference() callback.
-+ * or if the parser was asked to switch to that mode.
-+ *
-+ * [67] Reference ::= EntityRef | CharRef
-+ */
-+void
-+xmlParseReference(xmlParserCtxtPtr ctxt) {
-+ xmlEntityPtr ent;
-+ xmlChar *val;
-+ if (RAW != '&') return;
-+
-+ if (NXT(1) == '#') {
-+ int i = 0;
-+ xmlChar out[10];
-+ int hex = NXT(2);
-+ int val = xmlParseCharRef(ctxt);
-+
-+ if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * So we are using non-UTF-8 buffers
-+ * Check that the char fit on 8bits, if not
-+ * generate a CharRef.
-+ */
-+ if (val <= 0xFF) {
-+ out[0] = val;
-+ out[1] = 0;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->characters(ctxt->userData, out, 1);
-+ } else {
-+ if ((hex == 'x') || (hex == 'X'))
-+ sprintf((char *)out, "#x%X", val);
-+ else
-+ sprintf((char *)out, "#%d", val);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->reference(ctxt->userData, out);
-+ }
-+ } else {
-+ /*
-+ * Just encode the value in UTF-8
-+ */
-+ COPY_BUF(0 ,out, i, val);
-+ out[i] = 0;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->characters(ctxt->userData, out, i);
-+ }
-+ } else {
-+ ent = xmlParseEntityRef(ctxt);
-+ if (ent == NULL) return;
-+ if ((ent->name != NULL) &&
-+ (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
-+ xmlNodePtr list = NULL;
-+ int ret;
-+
-+
-+ /*
-+ * The first reference to the entity trigger a parsing phase
-+ * where the ent->children is filled with the result from
-+ * the parsing.
-+ */
-+ if (ent->children == NULL) {
-+ xmlChar *value;
-+ value = ent->content;
-+
-+ /*
-+ * Check that this entity is well formed
-+ */
-+ if ((value != NULL) &&
-+ (value[1] == 0) && (value[0] == '<') &&
-+ (xmlStrEqual(ent->name, BAD_CAST "lt"))) {
-+ /*
-+ * DONE: get definite answer on this !!!
-+ * Lots of entity decls are used to declare a single
-+ * char
-+ * <!ENTITY lt "<">
-+ * Which seems to be valid since
-+ * 2.4: The ampersand character (&) and the left angle
-+ * bracket (<) may appear in their literal form only
-+ * when used ... They are also legal within the literal
-+ * entity value of an internal entity declaration;i
-+ * see "4.3.2 Well-Formed Parsed Entities".
-+ * IMHO 2.4 and 4.3.2 are directly in contradiction.
-+ * Looking at the OASIS test suite and James Clark
-+ * tests, this is broken. However the XML REC uses
-+ * it. Is the XML REC not well-formed ????
-+ * This is a hack to avoid this problem
-+ *
-+ * ANSWER: since lt gt amp .. are already defined,
-+ * this is a redefinition and hence the fact that the
-+ * contentis not well balanced is not a Wf error, this
-+ * is lousy but acceptable.
-+ */
-+ list = xmlNewDocText(ctxt->myDoc, value);
-+ if (list != NULL) {
-+ if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
-+ (ent->children == NULL)) {
-+ ent->children = list;
-+ ent->last = list;
-+ list->parent = (xmlNodePtr) ent;
-+ } else {
-+ xmlFreeNodeList(list);
-+ }
-+ } else if (list != NULL) {
-+ xmlFreeNodeList(list);
-+ }
-+ } else {
-+ /*
-+ * 4.3.2: An internal general parsed entity is well-formed
-+ * if its replacement text matches the production labeled
-+ * content.
-+ */
-+ if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
-+ ctxt->depth++;
-+ ret = xmlParseBalancedChunkMemory(ctxt->myDoc,
-+ ctxt->sax, NULL, ctxt->depth,
-+ value, &list);
-+ ctxt->depth--;
-+ } else if (ent->etype ==
-+ XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
-+ ctxt->depth++;
-+ ret = xmlParseExternalEntity(ctxt->myDoc,
-+ ctxt->sax, NULL, ctxt->depth,
-+ ent->URI, ent->ExternalID, &list);
-+ ctxt->depth--;
-+ } else {
-+ ret = -1;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Internal: invalid entity type\n");
-+ }
-+ if (ret == XML_ERR_ENTITY_LOOP) {
-+ ctxt->errNo = XML_ERR_ENTITY_LOOP;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Detected entity reference loop\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if ((ret == 0) && (list != NULL)) {
-+ if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
-+ (ent->children == NULL)) {
-+ ent->children = list;
-+ while (list != NULL) {
-+ list->parent = (xmlNodePtr) ent;
-+ if (list->next == NULL)
-+ ent->last = list;
-+ list = list->next;
-+ }
-+ } else {
-+ xmlFreeNodeList(list);
-+ }
-+ } else if (ret > 0) {
-+ ctxt->errNo = ret;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity value required\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if (list != NULL) {
-+ xmlFreeNodeList(list);
-+ }
-+ }
-+ }
-+ if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
-+ (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
-+ /*
-+ * Create a node.
-+ */
-+ ctxt->sax->reference(ctxt->userData, ent->name);
-+ return;
-+ } else if (ctxt->replaceEntities) {
-+ if ((ctxt->node != NULL) && (ent->children != NULL)) {
-+ /*
-+ * Seems we are generating the DOM content, do
-+ * a simple tree copy
-+ */
-+ xmlNodePtr new;
-+ new = xmlCopyNodeList(ent->children);
-+
-+ xmlAddChildList(ctxt->node, new);
-+ /*
-+ * This is to avoid a nasty side effect, see
-+ * characters() in SAX.c
-+ */
-+ ctxt->nodemem = 0;
-+ ctxt->nodelen = 0;
-+ return;
-+ } else {
-+ /*
-+ * Probably running in SAX mode
-+ */
-+ xmlParserInputPtr input;
-+
-+ input = xmlNewEntityInputStream(ctxt, ent);
-+ xmlPushInput(ctxt, input);
-+ if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) &&
-+ (RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+ xmlParseTextDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right here
-+ */
-+ ctxt->instate = XML_PARSER_EOF;
-+ return;
-+ }
-+ if (input->standalone == 1) {
-+ ctxt->errNo = XML_ERR_EXT_ENTITY_STANDALONE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "external parsed entities cannot be standalone\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+ return;
-+ }
-+ }
-+ } else {
-+ val = ent->content;
-+ if (val == NULL) return;
-+ /*
-+ * inline the entity.
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlParseEntityRef:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse ENTITY references declarations
-+ *
-+ * [68] EntityRef ::= '&' Name ';'
-+ *
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an internal DTD
-+ * subset which contains no parameter entity references, or a document
-+ * with "standalone='yes'", the Name given in the entity reference
-+ * must match that in an entity declaration, except that well-formed
-+ * documents need not declare any of the following entities: amp, lt,
-+ * gt, apos, quot. The declaration of a parameter entity must precede
-+ * any reference to it. Similarly, the declaration of a general entity
-+ * must precede any reference to it which appears in a default value in an
-+ * attribute-list declaration. Note that if entities are declared in the
-+ * external subset or in external parameter entities, a non-validating
-+ * processor is not obligated to read and process their declarations;
-+ * for such documents, the rule that an entity must be declared is a
-+ * well-formedness constraint only if standalone='yes'.
-+ *
-+ * [ WFC: Parsed Entity ]
-+ * An entity reference must not contain the name of an unparsed entity
-+ *
-+ * Returns the xmlEntityPtr if found, or NULL otherwise.
-+ */
-+xmlEntityPtr
-+xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlEntityPtr ent = NULL;
-+
-+ GROW;
-+
-+ if (RAW == '&') {
-+ NEXT;
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEntityRef: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (RAW == ';') {
-+ NEXT;
-+ /*
-+ * Ask first SAX for entity resolution, otherwise try the
-+ * predefined set.
-+ */
-+ if (ctxt->sax != NULL) {
-+ if (ctxt->sax->getEntity != NULL)
-+ ent = ctxt->sax->getEntity(ctxt->userData, name);
-+ if (ent == NULL)
-+ ent = xmlGetPredefinedEntity(name);
-+ }
-+ /*
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an
-+ * internal DTD subset which contains no parameter entity
-+ * references, or a document with "standalone='yes'", the
-+ * Name given in the entity reference must match that in an
-+ * entity declaration, except that well-formed documents
-+ * need not declare any of the following entities: amp, lt,
-+ * gt, apos, quot.
-+ * The declaration of a parameter entity must precede any
-+ * reference to it.
-+ * Similarly, the declaration of a general entity must
-+ * precede any reference to it which appears in a default
-+ * value in an attribute-list declaration. Note that if
-+ * entities are declared in the external subset or in
-+ * external parameter entities, a non-validating processor
-+ * is not obligated to read and process their declarations;
-+ * for such documents, the rule that an entity must be
-+ * declared is a well-formedness constraint only if
-+ * standalone='yes'.
-+ */
-+ if (ent == NULL) {
-+ if ((ctxt->standalone == 1) ||
-+ ((ctxt->hasExternalSubset == 0) &&
-+ (ctxt->hasPErefs == 0))) {
-+ ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity '%s' not defined\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Entity '%s' not defined\n", name);
-+ }
-+ }
-+
-+ /*
-+ * [ WFC: Parsed Entity ]
-+ * An entity reference must not contain the name of an
-+ * unparsed entity
-+ */
-+ else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-+ ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity reference to unparsed entity %s\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * [ WFC: No External Entity References ]
-+ * Attribute values cannot contain direct or indirect
-+ * entity references to external entities.
-+ */
-+ else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-+ (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-+ ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attribute references external entity '%s'\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ /*
-+ * [ WFC: No < in Attribute Values ]
-+ * The replacement text of any entity referred to directly or
-+ * indirectly in an attribute value (other than "<") must
-+ * not contain a <.
-+ */
-+ else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-+ (ent != NULL) &&
-+ (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
-+ (ent->content != NULL) &&
-+ (xmlStrchr(ent->content, '<'))) {
-+ ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "'<' in entity '%s' is not allowed in attributes values\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * Internal check, no parameter entities here ...
-+ */
-+ else {
-+ switch (ent->etype) {
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attempt to reference the parameter entity '%s'\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * [ WFC: No Recursion ]
-+ * A parsed entity must not contain a recursive reference
-+ * to itself, either directly or indirectly.
-+ * Done somewhere else
-+ */
-+
-+ } else {
-+ ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEntityRef: expecting ';'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlFree(name);
-+ }
-+ }
-+ return(ent);
-+}
-+
-+/**
-+ * xmlParseStringEntityRef:
-+ * @ctxt: an XML parser context
-+ * @str: a pointer to an index in the string
-+ *
-+ * parse ENTITY references declarations, but this version parses it from
-+ * a string value.
-+ *
-+ * [68] EntityRef ::= '&' Name ';'
-+ *
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an internal DTD
-+ * subset which contains no parameter entity references, or a document
-+ * with "standalone='yes'", the Name given in the entity reference
-+ * must match that in an entity declaration, except that well-formed
-+ * documents need not declare any of the following entities: amp, lt,
-+ * gt, apos, quot. The declaration of a parameter entity must precede
-+ * any reference to it. Similarly, the declaration of a general entity
-+ * must precede any reference to it which appears in a default value in an
-+ * attribute-list declaration. Note that if entities are declared in the
-+ * external subset or in external parameter entities, a non-validating
-+ * processor is not obligated to read and process their declarations;
-+ * for such documents, the rule that an entity must be declared is a
-+ * well-formedness constraint only if standalone='yes'.
-+ *
-+ * [ WFC: Parsed Entity ]
-+ * An entity reference must not contain the name of an unparsed entity
-+ *
-+ * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
-+ * is updated to the current location in the string.
-+ */
-+xmlEntityPtr
-+xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
-+ xmlChar *name;
-+ const xmlChar *ptr;
-+ xmlChar cur;
-+ xmlEntityPtr ent = NULL;
-+
-+ if ((str == NULL) || (*str == NULL))
-+ return(NULL);
-+ ptr = *str;
-+ cur = *ptr;
-+ if (cur == '&') {
-+ ptr++;
-+ cur = *ptr;
-+ name = xmlParseStringName(ctxt, &ptr);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEntityRef: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (*ptr == ';') {
-+ ptr++;
-+ /*
-+ * Ask first SAX for entity resolution, otherwise try the
-+ * predefined set.
-+ */
-+ if (ctxt->sax != NULL) {
-+ if (ctxt->sax->getEntity != NULL)
-+ ent = ctxt->sax->getEntity(ctxt->userData, name);
-+ if (ent == NULL)
-+ ent = xmlGetPredefinedEntity(name);
-+ }
-+ /*
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an
-+ * internal DTD subset which contains no parameter entity
-+ * references, or a document with "standalone='yes'", the
-+ * Name given in the entity reference must match that in an
-+ * entity declaration, except that well-formed documents
-+ * need not declare any of the following entities: amp, lt,
-+ * gt, apos, quot.
-+ * The declaration of a parameter entity must precede any
-+ * reference to it.
-+ * Similarly, the declaration of a general entity must
-+ * precede any reference to it which appears in a default
-+ * value in an attribute-list declaration. Note that if
-+ * entities are declared in the external subset or in
-+ * external parameter entities, a non-validating processor
-+ * is not obligated to read and process their declarations;
-+ * for such documents, the rule that an entity must be
-+ * declared is a well-formedness constraint only if
-+ * standalone='yes'.
-+ */
-+ if (ent == NULL) {
-+ if ((ctxt->standalone == 1) ||
-+ ((ctxt->hasExternalSubset == 0) &&
-+ (ctxt->hasPErefs == 0))) {
-+ ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity '%s' not defined\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Entity '%s' not defined\n", name);
-+ }
-+ }
-+
-+ /*
-+ * [ WFC: Parsed Entity ]
-+ * An entity reference must not contain the name of an
-+ * unparsed entity
-+ */
-+ else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-+ ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity reference to unparsed entity %s\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * [ WFC: No External Entity References ]
-+ * Attribute values cannot contain direct or indirect
-+ * entity references to external entities.
-+ */
-+ else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-+ (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-+ ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attribute references external entity '%s'\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ /*
-+ * [ WFC: No < in Attribute Values ]
-+ * The replacement text of any entity referred to directly or
-+ * indirectly in an attribute value (other than "<") must
-+ * not contain a <.
-+ */
-+ else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-+ (ent != NULL) &&
-+ (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
-+ (ent->content != NULL) &&
-+ (xmlStrchr(ent->content, '<'))) {
-+ ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "'<' in entity '%s' is not allowed in attributes values\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * Internal check, no parameter entities here ...
-+ */
-+ else {
-+ switch (ent->etype) {
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attempt to reference the parameter entity '%s'\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * [ WFC: No Recursion ]
-+ * A parsed entity must not contain a recursive reference
-+ * to itself, either directly or indirectly.
-+ * Done somewhwere else
-+ */
-+
-+ } else {
-+ ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEntityRef: expecting ';'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlFree(name);
-+ }
-+ }
-+ *str = ptr;
-+ return(ent);
-+}
-+
-+/**
-+ * xmlParsePEReference:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse PEReference declarations
-+ * The entity content is handled directly by pushing it's content as
-+ * a new input stream.
-+ *
-+ * [69] PEReference ::= '%' Name ';'
-+ *
-+ * [ WFC: No Recursion ]
-+ * A parsed entity must not contain a recursive
-+ * reference to itself, either directly or indirectly.
-+ *
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an internal DTD
-+ * subset which contains no parameter entity references, or a document
-+ * with "standalone='yes'", ... ... The declaration of a parameter
-+ * entity must precede any reference to it...
-+ *
-+ * [ VC: Entity Declared ]
-+ * In a document with an external subset or external parameter entities
-+ * with "standalone='no'", ... ... The declaration of a parameter entity
-+ * must precede any reference to it...
-+ *
-+ * [ WFC: In DTD ]
-+ * Parameter-entity references may only appear in the DTD.
-+ * NOTE: misleading but this is handled.
-+ */
-+void
-+xmlParsePEReference(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlEntityPtr entity = NULL;
-+ xmlParserInputPtr input;
-+
-+ if (RAW == '%') {
-+ NEXT;
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParsePEReference: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ if (RAW == ';') {
-+ NEXT;
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->getParameterEntity != NULL))
-+ entity = ctxt->sax->getParameterEntity(ctxt->userData,
-+ name);
-+ if (entity == NULL) {
-+ /*
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an
-+ * internal DTD subset which contains no parameter entity
-+ * references, or a document with "standalone='yes'", ...
-+ * ... The declaration of a parameter entity must precede
-+ * any reference to it...
-+ */
-+ if ((ctxt->standalone == 1) ||
-+ ((ctxt->hasExternalSubset == 0) &&
-+ (ctxt->hasPErefs == 0))) {
-+ ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-+ if ((!ctxt->disableSAX) &&
-+ (ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "PEReference: %%%s; not found\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ /*
-+ * [ VC: Entity Declared ]
-+ * In a document with an external subset or external
-+ * parameter entities with "standalone='no'", ...
-+ * ... The declaration of a parameter entity must precede
-+ * any reference to it...
-+ */
-+ if ((!ctxt->disableSAX) &&
-+ (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "PEReference: %%%s; not found\n", name);
-+ ctxt->valid = 0;
-+ }
-+ } else {
-+ /*
-+ * Internal checking in case the entity quest barfed
-+ */
-+ if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
-+ (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Internal: %%%s; is not a parameter entity\n", name);
-+ } else {
-+ /*
-+ * TODO !!!
-+ * handle the extra spaces added before and after
-+ * c.f. http://www.w3.org/TR/REC-xml#as-PE
-+ */
-+ input = xmlNewEntityInputStream(ctxt, entity);
-+ xmlPushInput(ctxt, input);
-+ if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-+ (RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+ xmlParseTextDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing
-+ * right here
-+ */
-+ ctxt->instate = XML_PARSER_EOF;
-+ xmlFree(name);
-+ return;
-+ }
-+ }
-+ if (ctxt->token == 0)
-+ ctxt->token = ' ';
-+ }
-+ }
-+ ctxt->hasPErefs = 1;
-+ } else {
-+ ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParsePEReference: expecting ';'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlFree(name);
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlParseStringPEReference:
-+ * @ctxt: an XML parser context
-+ * @str: a pointer to an index in the string
-+ *
-+ * parse PEReference declarations
-+ *
-+ * [69] PEReference ::= '%' Name ';'
-+ *
-+ * [ WFC: No Recursion ]
-+ * A parsed entity must not contain a recursive
-+ * reference to itself, either directly or indirectly.
-+ *
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an internal DTD
-+ * subset which contains no parameter entity references, or a document
-+ * with "standalone='yes'", ... ... The declaration of a parameter
-+ * entity must precede any reference to it...
-+ *
-+ * [ VC: Entity Declared ]
-+ * In a document with an external subset or external parameter entities
-+ * with "standalone='no'", ... ... The declaration of a parameter entity
-+ * must precede any reference to it...
-+ *
-+ * [ WFC: In DTD ]
-+ * Parameter-entity references may only appear in the DTD.
-+ * NOTE: misleading but this is handled.
-+ *
-+ * Returns the string of the entity content.
-+ * str is updated to the current value of the index
-+ */
-+xmlEntityPtr
-+xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
-+ const xmlChar *ptr;
-+ xmlChar cur;
-+ xmlChar *name;
-+ xmlEntityPtr entity = NULL;
-+
-+ if ((str == NULL) || (*str == NULL)) return(NULL);
-+ ptr = *str;
-+ cur = *ptr;
-+ if (cur == '%') {
-+ ptr++;
-+ cur = *ptr;
-+ name = xmlParseStringName(ctxt, &ptr);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStringPEReference: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ cur = *ptr;
-+ if (cur == ';') {
-+ ptr++;
-+ cur = *ptr;
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->getParameterEntity != NULL))
-+ entity = ctxt->sax->getParameterEntity(ctxt->userData,
-+ name);
-+ if (entity == NULL) {
-+ /*
-+ * [ WFC: Entity Declared ]
-+ * In a document without any DTD, a document with only an
-+ * internal DTD subset which contains no parameter entity
-+ * references, or a document with "standalone='yes'", ...
-+ * ... The declaration of a parameter entity must precede
-+ * any reference to it...
-+ */
-+ if ((ctxt->standalone == 1) ||
-+ ((ctxt->hasExternalSubset == 0) &&
-+ (ctxt->hasPErefs == 0))) {
-+ ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "PEReference: %%%s; not found\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ /*
-+ * [ VC: Entity Declared ]
-+ * In a document with an external subset or external
-+ * parameter entities with "standalone='no'", ...
-+ * ... The declaration of a parameter entity must
-+ * precede any reference to it...
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "PEReference: %%%s; not found\n", name);
-+ ctxt->valid = 0;
-+ }
-+ } else {
-+ /*
-+ * Internal checking in case the entity quest barfed
-+ */
-+ if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
-+ (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Internal: %%%s; is not a parameter entity\n", name);
-+ }
-+ }
-+ ctxt->hasPErefs = 1;
-+ } else {
-+ ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStringPEReference: expecting ';'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlFree(name);
-+ }
-+ }
-+ *str = ptr;
-+ return(entity);
-+}
-+
-+/**
-+ * xmlParseDocTypeDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse a DOCTYPE declaration
-+ *
-+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-+ * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-+ *
-+ * [ VC: Root Element Type ]
-+ * The Name in the document type declaration must match the element
-+ * type of the root element.
-+ */
-+
-+void
-+xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name = NULL;
-+ xmlChar *ExternalID = NULL;
-+ xmlChar *URI = NULL;
-+
-+ /*
-+ * We know that '<!DOCTYPE' has been detected.
-+ */
-+ SKIP(9);
-+
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Parse the DOCTYPE name.
-+ */
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseDocTypeDecl : no DOCTYPE name !\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ ctxt->intSubName = name;
-+
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Check for SystemID and ExternalID
-+ */
-+ URI = xmlParseExternalID(ctxt, &ExternalID, 1);
-+
-+ if ((URI != NULL) || (ExternalID != NULL)) {
-+ ctxt->hasExternalSubset = 1;
-+ }
-+ ctxt->extSubURI = URI;
-+ ctxt->extSubSystem = ExternalID;
-+
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Create and update the internal subset.
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
-+
-+ /*
-+ * Is there any internal subset declarations ?
-+ * they are handled separately in xmlParseInternalSubset()
-+ */
-+ if (RAW == '[')
-+ return;
-+
-+ /*
-+ * We should be at the end of the DOCTYPE declaration.
-+ */
-+ if (RAW != '>') {
-+ ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ NEXT;
-+}
-+
-+/**
-+ * xmlParseInternalsubset:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the internal subset declaration
-+ *
-+ * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-+ */
-+
-+void
-+xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
-+ /*
-+ * Is there any DTD definition ?
-+ */
-+ if (RAW == '[') {
-+ ctxt->instate = XML_PARSER_DTD;
-+ NEXT;
-+ /*
-+ * Parse the succession of Markup declarations and
-+ * PEReferences.
-+ * Subsequence (markupdecl | PEReference | S)*
-+ */
-+ while (RAW != ']') {
-+ const xmlChar *check = CUR_PTR;
-+ int cons = ctxt->input->consumed;
-+
-+ SKIP_BLANKS;
-+ xmlParseMarkupDecl(ctxt);
-+ xmlParsePEReference(ctxt);
-+
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+
-+ if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseInternalSubset: error detected in Markup declaration\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ }
-+ }
-+ if (RAW == ']') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ }
-+ }
-+
-+ /*
-+ * We should be at the end of the DOCTYPE declaration.
-+ */
-+ if (RAW != '>') {
-+ ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ NEXT;
-+}
-+
-+/**
-+ * xmlParseAttribute:
-+ * @ctxt: an XML parser context
-+ * @value: a xmlChar ** used to store the value of the attribute
-+ *
-+ * parse an attribute
-+ *
-+ * [41] Attribute ::= Name Eq AttValue
-+ *
-+ * [ WFC: No External Entity References ]
-+ * Attribute values cannot contain direct or indirect entity references
-+ * to external entities.
-+ *
-+ * [ WFC: No < in Attribute Values ]
-+ * The replacement text of any entity referred to directly or indirectly in
-+ * an attribute value (other than "<") must not contain a <.
-+ *
-+ * [ VC: Attribute Value Type ]
-+ * The attribute must have been declared; the value must be of the type
-+ * declared for it.
-+ *
-+ * [25] Eq ::= S? '=' S?
-+ *
-+ * With namespace:
-+ *
-+ * [NS 11] Attribute ::= QName Eq AttValue
-+ *
-+ * Also the case QName == xmlns:??? is handled independently as a namespace
-+ * definition.
-+ *
-+ * Returns the attribute name, and the value in *value.
-+ */
-+
-+xmlChar *
-+xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
-+ xmlChar *name, *val;
-+
-+ *value = NULL;
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * read the value
-+ */
-+ SKIP_BLANKS;
-+ if (RAW == '=') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ val = xmlParseAttValue(ctxt);
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ } else {
-+ ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Specification mandate value for attribute %s\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFree(name);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Check that xml:lang conforms to the specification
-+ * No more registered as an error, just generate a warning now
-+ * since this was deprecated in XML second edition
-+ */
-+ if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
-+ if (!xmlCheckLanguageID(val)) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt->userData,
-+ "Malformed value for xml:lang : %s\n", val);
-+ }
-+ }
-+
-+ /*
-+ * Check that xml:space conforms to the specification
-+ */
-+ if (xmlStrEqual(name, BAD_CAST "xml:space")) {
-+ if (xmlStrEqual(val, BAD_CAST "default"))
-+ *(ctxt->space) = 0;
-+ else if (xmlStrEqual(val, BAD_CAST "preserve"))
-+ *(ctxt->space) = 1;
-+ else {
-+ ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+"Invalid value for xml:space : \"%s\", \"default\" or \"preserve\" expected\n",
-+ val);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+
-+ *value = val;
-+ return(name);
-+}
-+
-+/**
-+ * xmlParseStartTag:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse a start of tag either for rule element or
-+ * EmptyElement. In both case we don't parse the tag closing chars.
-+ *
-+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
-+ *
-+ * [ WFC: Unique Att Spec ]
-+ * No attribute name may appear more than once in the same start-tag or
-+ * empty-element tag.
-+ *
-+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
-+ *
-+ * [ WFC: Unique Att Spec ]
-+ * No attribute name may appear more than once in the same start-tag or
-+ * empty-element tag.
-+ *
-+ * With namespace:
-+ *
-+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
-+ *
-+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
-+ *
-+ * Returns the element name parsed
-+ */
-+
-+xmlChar *
-+xmlParseStartTag(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *attname;
-+ xmlChar *attvalue;
-+ const xmlChar **atts = NULL;
-+ int nbatts = 0;
-+ int maxatts = 0;
-+ int i;
-+
-+ if (RAW != '<') return(NULL);
-+ NEXT;
-+
-+ name = xmlParseName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_NAME_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStartTag: invalid element name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Now parse the attributes, it ends up with the ending
-+ *
-+ * (S Attribute)* S?
-+ */
-+ SKIP_BLANKS;
-+ GROW;
-+
-+ while ((IS_CHAR(RAW)) &&
-+ (RAW != '>') &&
-+ ((RAW != '/') || (NXT(1) != '>'))) {
-+ const xmlChar *q = CUR_PTR;
-+ int cons = ctxt->input->consumed;
-+
-+ attname = xmlParseAttribute(ctxt, &attvalue);
-+ if ((attname != NULL) && (attvalue != NULL)) {
-+ /*
-+ * [ WFC: Unique Att Spec ]
-+ * No attribute name may appear more than once in the same
-+ * start-tag or empty-element tag.
-+ */
-+ for (i = 0; i < nbatts;i += 2) {
-+ if (xmlStrEqual(atts[i], attname)) {
-+ ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Attribute %s redefined\n",
-+ attname);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFree(attname);
-+ xmlFree(attvalue);
-+ goto failed;
-+ }
-+ }
-+
-+ /*
-+ * Add the pair to atts
-+ */
-+ if (atts == NULL) {
-+ maxatts = 10;
-+ atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
-+ if (atts == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %ld byte failed\n",
-+ maxatts * (long)sizeof(xmlChar *));
-+ return(NULL);
-+ }
-+ } else if (nbatts + 4 > maxatts) {
-+ maxatts *= 2;
-+ atts = (const xmlChar **) xmlRealloc((void *) atts,
-+ maxatts * sizeof(xmlChar *));
-+ if (atts == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %ld byte failed\n",
-+ maxatts * (long)sizeof(xmlChar *));
-+ return(NULL);
-+ }
-+ }
-+ atts[nbatts++] = attname;
-+ atts[nbatts++] = attvalue;
-+ atts[nbatts] = NULL;
-+ atts[nbatts + 1] = NULL;
-+ } else {
-+ if (attname != NULL)
-+ xmlFree(attname);
-+ if (attvalue != NULL)
-+ xmlFree(attvalue);
-+ }
-+
-+failed:
-+
-+ if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
-+ break;
-+ if (!IS_BLANK(RAW)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "attributes construct error\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ if ((cons == ctxt->input->consumed) && (q == CUR_PTR)) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseStartTag: problem parsing attributes\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ }
-+ GROW;
-+ }
-+
-+ /*
-+ * SAX: Start of Element !
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->startElement(ctxt->userData, name, atts);
-+
-+ if (atts != NULL) {
-+ for (i = 0;i < nbatts;i++) xmlFree((xmlChar *) atts[i]);
-+ xmlFree((void *) atts);
-+ }
-+ return(name);
-+}
-+
-+/**
-+ * xmlParseEndTag:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an end of tag
-+ *
-+ * [42] ETag ::= '</' Name S? '>'
-+ *
-+ * With namespace
-+ *
-+ * [NS 9] ETag ::= '</' QName S? '>'
-+ */
-+
-+void
-+xmlParseEndTag(xmlParserCtxtPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *oldname;
-+
-+ GROW;
-+ if ((RAW != '<') || (NXT(1) != '/')) {
-+ ctxt->errNo = XML_ERR_LTSLASH_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "xmlParseEndTag: '</' not found\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ SKIP(2);
-+
-+ name = xmlParseName(ctxt);
-+
-+ /*
-+ * We should definitely be at the ending "S? '>'" part
-+ */
-+ GROW;
-+ SKIP_BLANKS;
-+ if ((!IS_CHAR(RAW)) || (RAW != '>')) {
-+ ctxt->errNo = XML_ERR_GT_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+
-+ /*
-+ * [ WFC: Element Type Match ]
-+ * The Name in an element's end-tag must match the element type in the
-+ * start-tag.
-+ *
-+ */
-+ if ((name == NULL) || (ctxt->name == NULL) ||
-+ (!xmlStrEqual(name, ctxt->name))) {
-+ ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-+ if ((name != NULL) && (ctxt->name != NULL)) {
-+ ctxt->sax->error(ctxt->userData,
-+ "Opening and ending tag mismatch: %s and %s\n",
-+ ctxt->name, name);
-+ } else if (ctxt->name != NULL) {
-+ ctxt->sax->error(ctxt->userData,
-+ "Ending tag eror for: %s\n", ctxt->name);
-+ } else {
-+ ctxt->sax->error(ctxt->userData,
-+ "Ending tag error: internal error ???\n");
-+ }
-+
-+ }
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * SAX: End of Tag
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+
-+ if (name != NULL)
-+ xmlFree(name);
-+ oldname = namePop(ctxt);
-+ spacePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG_STACK
-+ xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ return;
-+}
-+
-+/**
-+ * xmlParseCDSect:
-+ * @ctxt: an XML parser context
-+ *
-+ * Parse escaped pure raw content.
-+ *
-+ * [18] CDSect ::= CDStart CData CDEnd
-+ *
-+ * [19] CDStart ::= '<![CDATA['
-+ *
-+ * [20] Data ::= (Char* - (Char* ']]>' Char*))
-+ *
-+ * [21] CDEnd ::= ']]>'
-+ */
-+void
-+xmlParseCDSect(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ int r, rl;
-+ int s, sl;
-+ int cur, l;
-+ int count = 0;
-+
-+ if ((NXT(0) == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '[') && (NXT(3) == 'C') &&
-+ (NXT(4) == 'D') && (NXT(5) == 'A') &&
-+ (NXT(6) == 'T') && (NXT(7) == 'A') &&
-+ (NXT(8) == '[')) {
-+ SKIP(9);
-+ } else
-+ return;
-+
-+ ctxt->instate = XML_PARSER_CDATA_SECTION;
-+ r = CUR_CHAR(rl);
-+ if (!IS_CHAR(r)) {
-+ ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "CData section not finished\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ return;
-+ }
-+ NEXTL(rl);
-+ s = CUR_CHAR(sl);
-+ if (!IS_CHAR(s)) {
-+ ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "CData section not finished\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ return;
-+ }
-+ NEXTL(sl);
-+ cur = CUR_CHAR(l);
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return;
-+ }
-+ while (IS_CHAR(cur) &&
-+ ((r != ']') || (s != ']') || (cur != '>'))) {
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return;
-+ }
-+ }
-+ COPY_BUF(rl,buf,len,r);
-+ r = s;
-+ rl = sl;
-+ s = cur;
-+ sl = l;
-+ count++;
-+ if (count > 50) {
-+ GROW;
-+ count = 0;
-+ }
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ }
-+ buf[len] = 0;
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ if (cur != '>') {
-+ ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "CData section not finished\n%.50s\n", buf);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFree(buf);
-+ return;
-+ }
-+ NEXTL(l);
-+
-+ /*
-+ * Ok the buffer is to be consumed as cdata.
-+ */
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (ctxt->sax->cdataBlock != NULL)
-+ ctxt->sax->cdataBlock(ctxt->userData, buf, len);
-+ }
-+ xmlFree(buf);
-+}
-+
-+/**
-+ * xmlParseContent:
-+ * @ctxt: an XML parser context
-+ *
-+ * Parse a content:
-+ *
-+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-+ */
-+
-+void
-+xmlParseContent(xmlParserCtxtPtr ctxt) {
-+ GROW;
-+ while (((RAW != 0) || (ctxt->token != 0)) &&
-+ ((RAW != '<') || (NXT(1) != '/'))) {
-+ const xmlChar *test = CUR_PTR;
-+ int cons = ctxt->input->consumed;
-+ xmlChar tok = ctxt->token;
-+
-+ /*
-+ * Handle possible processed charrefs.
-+ */
-+ if (ctxt->token != 0) {
-+ xmlParseCharData(ctxt, 0);
-+ }
-+ /*
-+ * First case : a Processing Instruction.
-+ */
-+ else if ((RAW == '<') && (NXT(1) == '?')) {
-+ xmlParsePI(ctxt);
-+ }
-+
-+ /*
-+ * Second case : a CDSection
-+ */
-+ else if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '[') && (NXT(3) == 'C') &&
-+ (NXT(4) == 'D') && (NXT(5) == 'A') &&
-+ (NXT(6) == 'T') && (NXT(7) == 'A') &&
-+ (NXT(8) == '[')) {
-+ xmlParseCDSect(ctxt);
-+ }
-+
-+ /*
-+ * Third case : a comment
-+ */
-+ else if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '-') && (NXT(3) == '-')) {
-+ xmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ }
-+
-+ /*
-+ * Fourth case : a sub-element.
-+ */
-+ else if (RAW == '<') {
-+ xmlParseElement(ctxt);
-+ }
-+
-+ /*
-+ * Fifth case : a reference. If if has not been resolved,
-+ * parsing returns it's Name, create the node
-+ */
-+
-+ else if (RAW == '&') {
-+ xmlParseReference(ctxt);
-+ }
-+
-+ /*
-+ * Last case, text. Note that References are handled directly.
-+ */
-+ else {
-+ xmlParseCharData(ctxt, 0);
-+ }
-+
-+ GROW;
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+ SHRINK;
-+
-+ if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
-+ (tok == ctxt->token)) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "detected an error in element content\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_EOF;
-+ break;
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlParseElement:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML element, this is highly recursive
-+ *
-+ * [39] element ::= EmptyElemTag | STag content ETag
-+ *
-+ * [ WFC: Element Type Match ]
-+ * The Name in an element's end-tag must match the element type in the
-+ * start-tag.
-+ *
-+ * [ VC: Element Valid ]
-+ * An element is valid if there is a declaration matching elementdecl
-+ * where the Name matches the element type and one of the following holds:
-+ * - The declaration matches EMPTY and the element has no content.
-+ * - The declaration matches children and the sequence of child elements
-+ * belongs to the language generated by the regular expression in the
-+ * content model, with optional white space (characters matching the
-+ * nonterminal S) between each pair of child elements.
-+ * - The declaration matches Mixed and the content consists of character
-+ * data and child elements whose types match names in the content model.
-+ * - The declaration matches ANY, and the types of any child elements have
-+ * been declared.
-+ */
-+
-+void
-+xmlParseElement(xmlParserCtxtPtr ctxt) {
-+ const xmlChar *openTag = CUR_PTR;
-+ xmlChar *name;
-+ xmlChar *oldname;
-+ xmlParserNodeInfo node_info;
-+ xmlNodePtr ret;
-+
-+ /* Capture start position */
-+ if (ctxt->record_info) {
-+ node_info.begin_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.begin_line = ctxt->input->line;
-+ }
-+
-+ if (ctxt->spaceNr == 0)
-+ spacePush(ctxt, -1);
-+ else
-+ spacePush(ctxt, *ctxt->space);
-+
-+ name = xmlParseStartTag(ctxt);
-+ if (name == NULL) {
-+ spacePop(ctxt);
-+ return;
-+ }
-+ namePush(ctxt, name);
-+ ret = ctxt->node;
-+
-+ /*
-+ * [ VC: Root Element Type ]
-+ * The Name in the document type declaration must match the element
-+ * type of the root element.
-+ */
-+ if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
-+ ctxt->node && (ctxt->node == ctxt->myDoc->children))
-+ ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-+
-+ /*
-+ * Check for an Empty Element.
-+ */
-+ if ((RAW == '/') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ oldname = namePop(ctxt);
-+ spacePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG_STACK
-+ xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ if ( ret != NULL && ctxt->record_info ) {
-+ node_info.end_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.end_line = ctxt->input->line;
-+ node_info.node = ret;
-+ xmlParserAddNodeInfo(ctxt, &node_info);
-+ }
-+ return;
-+ }
-+ if (RAW == '>') {
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_GT_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Couldn't find end of Start Tag\n%.30s\n",
-+ openTag);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+ nodePop(ctxt);
-+ oldname = namePop(ctxt);
-+ spacePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG_STACK
-+ xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+
-+ /*
-+ * Capture end position and add node
-+ */
-+ if ( ret != NULL && ctxt->record_info ) {
-+ node_info.end_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.end_line = ctxt->input->line;
-+ node_info.node = ret;
-+ xmlParserAddNodeInfo(ctxt, &node_info);
-+ }
-+ return;
-+ }
-+
-+ /*
-+ * Parse the content of the element:
-+ */
-+ xmlParseContent(ctxt);
-+ if (!IS_CHAR(RAW)) {
-+ ctxt->errNo = XML_ERR_TAG_NOT_FINISED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Premature end of data in tag %.30s\n", openTag);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+ nodePop(ctxt);
-+ oldname = namePop(ctxt);
-+ spacePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG_STACK
-+ xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ return;
-+ }
-+
-+ /*
-+ * parse the end of tag: '</' should be here.
-+ */
-+ xmlParseEndTag(ctxt);
-+
-+ /*
-+ * Capture end position and add node
-+ */
-+ if ( ret != NULL && ctxt->record_info ) {
-+ node_info.end_pos = ctxt->input->consumed +
-+ (CUR_PTR - ctxt->input->base);
-+ node_info.end_line = ctxt->input->line;
-+ node_info.node = ret;
-+ xmlParserAddNodeInfo(ctxt, &node_info);
-+ }
-+}
-+
-+/**
-+ * xmlParseVersionNum:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the XML version value.
-+ *
-+ * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
-+ *
-+ * Returns the string giving the XML version number, or NULL
-+ */
-+xmlChar *
-+xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = 10;
-+ xmlChar cur;
-+
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ cur = CUR;
-+ while (((cur >= 'a') && (cur <= 'z')) ||
-+ ((cur >= 'A') && (cur <= 'Z')) ||
-+ ((cur >= '0') && (cur <= '9')) ||
-+ (cur == '_') || (cur == '.') ||
-+ (cur == ':') || (cur == '-')) {
-+ if (len + 1 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ }
-+ buf[len++] = cur;
-+ NEXT;
-+ cur=CUR;
-+ }
-+ buf[len] = 0;
-+ return(buf);
-+}
-+
-+/**
-+ * xmlParseVersionInfo:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the XML version.
-+ *
-+ * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-+ *
-+ * [25] Eq ::= S? '=' S?
-+ *
-+ * Returns the version string, e.g. "1.0"
-+ */
-+
-+xmlChar *
-+xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
-+ xmlChar *version = NULL;
-+ const xmlChar *q;
-+
-+ if ((RAW == 'v') && (NXT(1) == 'e') &&
-+ (NXT(2) == 'r') && (NXT(3) == 's') &&
-+ (NXT(4) == 'i') && (NXT(5) == 'o') &&
-+ (NXT(6) == 'n')) {
-+ SKIP(7);
-+ SKIP_BLANKS;
-+ if (RAW != '=') {
-+ ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseVersionInfo : expected '='\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ if (RAW == '"') {
-+ NEXT;
-+ q = CUR_PTR;
-+ version = xmlParseVersionNum(ctxt);
-+ if (RAW != '"') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "String not closed\n%.50s\n", q);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ } else if (RAW == '\''){
-+ NEXT;
-+ q = CUR_PTR;
-+ version = xmlParseVersionNum(ctxt);
-+ if (RAW != '\'') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "String not closed\n%.50s\n", q);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseVersionInfo : expected ' or \"\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+ return(version);
-+}
-+
-+/**
-+ * xmlParseEncName:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the XML encoding name
-+ *
-+ * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-+ *
-+ * Returns the encoding name value or NULL
-+ */
-+xmlChar *
-+xmlParseEncName(xmlParserCtxtPtr ctxt) {
-+ xmlChar *buf = NULL;
-+ int len = 0;
-+ int size = 10;
-+ xmlChar cur;
-+
-+ cur = CUR;
-+ if (((cur >= 'a') && (cur <= 'z')) ||
-+ ((cur >= 'A') && (cur <= 'Z'))) {
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+
-+ buf[len++] = cur;
-+ NEXT;
-+ cur = CUR;
-+ while (((cur >= 'a') && (cur <= 'z')) ||
-+ ((cur >= 'A') && (cur <= 'Z')) ||
-+ ((cur >= '0') && (cur <= '9')) ||
-+ (cur == '.') || (cur == '_') ||
-+ (cur == '-')) {
-+ if (len + 1 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ }
-+ buf[len++] = cur;
-+ NEXT;
-+ cur = CUR;
-+ if (cur == 0) {
-+ SHRINK;
-+ GROW;
-+ cur = CUR;
-+ }
-+ }
-+ buf[len] = 0;
-+ } else {
-+ ctxt->errNo = XML_ERR_ENCODING_NAME;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Invalid XML encoding name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(buf);
-+}
-+
-+/**
-+ * xmlParseEncodingDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the XML encoding declaration
-+ *
-+ * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'")
-+ *
-+ * this setups the conversion filters.
-+ *
-+ * Returns the encoding value or NULL
-+ */
-+
-+xmlChar *
-+xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *encoding = NULL;
-+ const xmlChar *q;
-+
-+ SKIP_BLANKS;
-+ if ((RAW == 'e') && (NXT(1) == 'n') &&
-+ (NXT(2) == 'c') && (NXT(3) == 'o') &&
-+ (NXT(4) == 'd') && (NXT(5) == 'i') &&
-+ (NXT(6) == 'n') && (NXT(7) == 'g')) {
-+ SKIP(8);
-+ SKIP_BLANKS;
-+ if (RAW != '=') {
-+ ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEncodingDecl : expected '='\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(NULL);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ if (RAW == '"') {
-+ NEXT;
-+ q = CUR_PTR;
-+ encoding = xmlParseEncName(ctxt);
-+ if (RAW != '"') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "String not closed\n%.50s\n", q);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ } else if (RAW == '\''){
-+ NEXT;
-+ q = CUR_PTR;
-+ encoding = xmlParseEncName(ctxt);
-+ if (RAW != '\'') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "String not closed\n%.50s\n", q);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ } else if (RAW == '"'){
-+ ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseEncodingDecl : expected ' or \"\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+ xmlCharEncodingHandlerPtr handler;
-+
-+ if (ctxt->input->encoding != NULL)
-+ xmlFree((xmlChar *) ctxt->input->encoding);
-+ ctxt->input->encoding = encoding;
-+
-+ enc = xmlParseCharEncoding((const char *) encoding);
-+ /*
-+ * registered set of known encodings
-+ */
-+ if (enc != XML_CHAR_ENCODING_ERROR) {
-+ xmlSwitchEncoding(ctxt, enc);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ xmlFree(encoding);
-+ return(NULL);
-+ }
-+ } else {
-+ /*
-+ * fallback for unknown encodings
-+ */
-+ handler = xmlFindCharEncodingHandler((const char *) encoding);
-+ if (handler != NULL) {
-+ xmlSwitchToEncoding(ctxt, handler);
-+ } else {
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Unsupported encoding %s\n", encoding);
-+ return(NULL);
-+ }
-+ }
-+ }
-+ }
-+ return(encoding);
-+}
-+
-+/**
-+ * xmlParseSDDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse the XML standalone declaration
-+ *
-+ * [32] SDDecl ::= S 'standalone' Eq
-+ * (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
-+ *
-+ * [ VC: Standalone Document Declaration ]
-+ * TODO The standalone document declaration must have the value "no"
-+ * if any external markup declarations contain declarations of:
-+ * - attributes with default values, if elements to which these
-+ * attributes apply appear in the document without specifications
-+ * of values for these attributes, or
-+ * - entities (other than amp, lt, gt, apos, quot), if references
-+ * to those entities appear in the document, or
-+ * - attributes with values subject to normalization, where the
-+ * attribute appears in the document with a value which will change
-+ * as a result of normalization, or
-+ * - element types with element content, if white space occurs directly
-+ * within any instance of those types.
-+ *
-+ * Returns 1 if standalone, 0 otherwise
-+ */
-+
-+int
-+xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
-+ int standalone = -1;
-+
-+ SKIP_BLANKS;
-+ if ((RAW == 's') && (NXT(1) == 't') &&
-+ (NXT(2) == 'a') && (NXT(3) == 'n') &&
-+ (NXT(4) == 'd') && (NXT(5) == 'a') &&
-+ (NXT(6) == 'l') && (NXT(7) == 'o') &&
-+ (NXT(8) == 'n') && (NXT(9) == 'e')) {
-+ SKIP(10);
-+ SKIP_BLANKS;
-+ if (RAW != '=') {
-+ ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML standalone declaration : expected '='\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return(standalone);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ if (RAW == '\''){
-+ NEXT;
-+ if ((RAW == 'n') && (NXT(1) == 'o')) {
-+ standalone = 0;
-+ SKIP(2);
-+ } else if ((RAW == 'y') && (NXT(1) == 'e') &&
-+ (NXT(2) == 's')) {
-+ standalone = 1;
-+ SKIP(3);
-+ } else {
-+ ctxt->errNo = XML_ERR_STANDALONE_VALUE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "standalone accepts only 'yes' or 'no'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (RAW != '\'') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "String not closed\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ } else if (RAW == '"'){
-+ NEXT;
-+ if ((RAW == 'n') && (NXT(1) == 'o')) {
-+ standalone = 0;
-+ SKIP(2);
-+ } else if ((RAW == 'y') && (NXT(1) == 'e') &&
-+ (NXT(2) == 's')) {
-+ standalone = 1;
-+ SKIP(3);
-+ } else {
-+ ctxt->errNo = XML_ERR_STANDALONE_VALUE;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "standalone accepts only 'yes' or 'no'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (RAW != '"') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "String not closed\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Standalone value not found\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ }
-+ return(standalone);
-+}
-+
-+/**
-+ * xmlParseXMLDecl:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML declaration header
-+ *
-+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-+ */
-+
-+void
-+xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
-+ xmlChar *version;
-+
-+ /*
-+ * We know that '<?xml' is here.
-+ */
-+ SKIP(5);
-+
-+ if (!IS_BLANK(RAW)) {
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Blank needed after '<?xml'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+
-+ /*
-+ * We should have the VersionInfo here.
-+ */
-+ version = xmlParseVersionInfo(ctxt);
-+ if (version == NULL)
-+ version = xmlCharStrdup(XML_DEFAULT_VERSION);
-+ ctxt->version = xmlStrdup(version);
-+ xmlFree(version);
-+
-+ /*
-+ * We may have the encoding declaration
-+ */
-+ if (!IS_BLANK(RAW)) {
-+ if ((RAW == '?') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ return;
-+ }
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Blank needed here\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ xmlParseEncodingDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right here
-+ */
-+ return;
-+ }
-+
-+ /*
-+ * We may have the standalone status.
-+ */
-+ if ((ctxt->input->encoding != NULL) && (!IS_BLANK(RAW))) {
-+ if ((RAW == '?') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ return;
-+ }
-+ ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Blank needed here\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ SKIP_BLANKS;
-+ ctxt->input->standalone = xmlParseSDDecl(ctxt);
-+
-+ SKIP_BLANKS;
-+ if ((RAW == '?') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ } else if (RAW == '>') {
-+ /* Deprecated old WD ... */
-+ ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "XML declaration must end-up with '?>'\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "parsing XML declaration: '?>' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ MOVETO_ENDTAG(CUR_PTR);
-+ NEXT;
-+ }
-+}
-+
-+/**
-+ * xmlParseMisc:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML Misc* optionnal field.
-+ *
-+ * [27] Misc ::= Comment | PI | S
-+ */
-+
-+void
-+xmlParseMisc(xmlParserCtxtPtr ctxt) {
-+ while (((RAW == '<') && (NXT(1) == '?')) ||
-+ ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == '-') && (NXT(3) == '-')) ||
-+ IS_BLANK(CUR)) {
-+ if ((RAW == '<') && (NXT(1) == '?')) {
-+ xmlParsePI(ctxt);
-+ } else if (IS_BLANK(CUR)) {
-+ NEXT;
-+ } else
-+ xmlParseComment(ctxt);
-+ }
-+}
-+
-+/**
-+ * xmlParseDocument:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML document (and build a tree if using the standard SAX
-+ * interface).
-+ *
-+ * [1] document ::= prolog element Misc*
-+ *
-+ * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
-+ *
-+ * Returns 0, -1 in case of error. the parser context is augmented
-+ * as a result of the parsing.
-+ */
-+
-+int
-+xmlParseDocument(xmlParserCtxtPtr ctxt) {
-+ xmlChar start[4];
-+ xmlCharEncoding enc;
-+
-+ xmlInitParser();
-+
-+ GROW;
-+
-+ /*
-+ * SAX: beginning of the document processing.
-+ */
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-+
-+ /*
-+ * Get the 4 first bytes and decode the charset
-+ * if enc != XML_CHAR_ENCODING_NONE
-+ * plug some encoding conversion routines.
-+ */
-+ start[0] = RAW;
-+ start[1] = NXT(1);
-+ start[2] = NXT(2);
-+ start[3] = NXT(3);
-+ enc = xmlDetectCharEncoding(start, 4);
-+ if (enc != XML_CHAR_ENCODING_NONE) {
-+ xmlSwitchEncoding(ctxt, enc);
-+ }
-+
-+
-+ if (CUR == 0) {
-+ ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Document is empty\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * Check for the XMLDecl in the Prolog.
-+ */
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+
-+ /*
-+ * Note that we will switch encoding on the fly.
-+ */
-+ xmlParseXMLDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right here
-+ */
-+ return(-1);
-+ }
-+ ctxt->standalone = ctxt->input->standalone;
-+ SKIP_BLANKS;
-+ } else {
-+ ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-+ }
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+
-+ /*
-+ * The Misc part of the Prolog
-+ */
-+ GROW;
-+ xmlParseMisc(ctxt);
-+
-+ /*
-+ * Then possibly doc type declaration(s) and more Misc
-+ * (doctypedecl Misc*)?
-+ */
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '!') &&
-+ (NXT(2) == 'D') && (NXT(3) == 'O') &&
-+ (NXT(4) == 'C') && (NXT(5) == 'T') &&
-+ (NXT(6) == 'Y') && (NXT(7) == 'P') &&
-+ (NXT(8) == 'E')) {
-+
-+ ctxt->inSubset = 1;
-+ xmlParseDocTypeDecl(ctxt);
-+ if (RAW == '[') {
-+ ctxt->instate = XML_PARSER_DTD;
-+ xmlParseInternalSubset(ctxt);
-+ }
-+
-+ /*
-+ * Create and update the external subset.
-+ */
-+ ctxt->inSubset = 2;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
-+ ctxt->extSubSystem, ctxt->extSubURI);
-+ ctxt->inSubset = 0;
-+
-+
-+ ctxt->instate = XML_PARSER_PROLOG;
-+ xmlParseMisc(ctxt);
-+ }
-+
-+ /*
-+ * Time to start parsing the tree itself
-+ */
-+ GROW;
-+ if (RAW != '<') {
-+ ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Start tag expected, '<' not found\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_EOF;
-+ } else {
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ xmlParseElement(ctxt);
-+ ctxt->instate = XML_PARSER_EPILOG;
-+
-+
-+ /*
-+ * The Misc part at the end
-+ */
-+ xmlParseMisc(ctxt);
-+
-+ if (RAW != 0) {
-+ ctxt->errNo = XML_ERR_DOCUMENT_END;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra content at the end of the document\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ ctxt->instate = XML_PARSER_EOF;
-+ }
-+
-+ /*
-+ * SAX: end of the document processing.
-+ */
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endDocument(ctxt->userData);
-+
-+ if (! ctxt->wellFormed) return(-1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseExtParsedEnt:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse a genreral parsed entity
-+ * An external general parsed entity is well-formed if it matches the
-+ * production labeled extParsedEnt.
-+ *
-+ * [78] extParsedEnt ::= TextDecl? content
-+ *
-+ * Returns 0, -1 in case of error. the parser context is augmented
-+ * as a result of the parsing.
-+ */
-+
-+int
-+xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
-+ xmlChar start[4];
-+ xmlCharEncoding enc;
-+
-+ xmlDefaultSAXHandlerInit();
-+
-+ GROW;
-+
-+ /*
-+ * SAX: beginning of the document processing.
-+ */
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-+
-+ /*
-+ * Get the 4 first bytes and decode the charset
-+ * if enc != XML_CHAR_ENCODING_NONE
-+ * plug some encoding conversion routines.
-+ */
-+ start[0] = RAW;
-+ start[1] = NXT(1);
-+ start[2] = NXT(2);
-+ start[3] = NXT(3);
-+ enc = xmlDetectCharEncoding(start, 4);
-+ if (enc != XML_CHAR_ENCODING_NONE) {
-+ xmlSwitchEncoding(ctxt, enc);
-+ }
-+
-+
-+ if (CUR == 0) {
-+ ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Document is empty\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * Check for the XMLDecl in the Prolog.
-+ */
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+
-+ /*
-+ * Note that we will switch encoding on the fly.
-+ */
-+ xmlParseXMLDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right here
-+ */
-+ return(-1);
-+ }
-+ SKIP_BLANKS;
-+ } else {
-+ ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-+ }
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+
-+ /*
-+ * Doing validity checking on chunk doesn't make sense
-+ */
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->validate = 0;
-+ ctxt->loadsubset = 0;
-+ ctxt->depth = 0;
-+
-+ xmlParseContent(ctxt);
-+
-+ if ((RAW == '<') && (NXT(1) == '/')) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if (RAW != 0) {
-+ ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "extra content at the end of well balanced chunk\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ /*
-+ * SAX: end of the document processing.
-+ */
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endDocument(ctxt->userData);
-+
-+ if (! ctxt->wellFormed) return(-1);
-+ return(0);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Progressive parsing interfaces *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlParseLookupSequence:
-+ * @ctxt: an XML parser context
-+ * @first: the first char to lookup
-+ * @next: the next char to lookup or zero
-+ * @third: the next char to lookup or zero
-+ *
-+ * Try to find if a sequence (first, next, third) or just (first next) or
-+ * (first) is available in the input stream.
-+ * This function has a side effect of (possibly) incrementing ctxt->checkIndex
-+ * to avoid rescanning sequences of bytes, it DOES change the state of the
-+ * parser, do not use liberally.
-+ *
-+ * Returns the index to the current parsing point if the full sequence
-+ * is available, -1 otherwise.
-+ */
-+int
-+xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
-+ xmlChar next, xmlChar third) {
-+ int base, len;
-+ xmlParserInputPtr in;
-+ const xmlChar *buf;
-+
-+ in = ctxt->input;
-+ if (in == NULL) return(-1);
-+ base = in->cur - in->base;
-+ if (base < 0) return(-1);
-+ if (ctxt->checkIndex > base)
-+ base = ctxt->checkIndex;
-+ if (in->buf == NULL) {
-+ buf = in->base;
-+ len = in->length;
-+ } else {
-+ buf = in->buf->buffer->content;
-+ len = in->buf->buffer->use;
-+ }
-+ /* take into account the sequence length */
-+ if (third) len -= 2;
-+ else if (next) len --;
-+ for (;base < len;base++) {
-+ if (buf[base] == first) {
-+ if (third != 0) {
-+ if ((buf[base + 1] != next) ||
-+ (buf[base + 2] != third)) continue;
-+ } else if (next != 0) {
-+ if (buf[base + 1] != next) continue;
-+ }
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ if (next == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup '%c' found at %d\n",
-+ first, base);
-+ else if (third == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup '%c%c' found at %d\n",
-+ first, next, base);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup '%c%c%c' found at %d\n",
-+ first, next, third, base);
-+#endif
-+ return(base - (in->cur - in->base));
-+ }
-+ }
-+ ctxt->checkIndex = base;
-+#ifdef DEBUG_PUSH
-+ if (next == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup '%c' failed\n", first);
-+ else if (third == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup '%c%c' failed\n", first, next);
-+ else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup '%c%c%c' failed\n", first, next, third);
-+#endif
-+ return(-1);
-+}
-+
-+/**
-+ * xmlParseTryOrFinish:
-+ * @ctxt: an XML parser context
-+ * @terminate: last chunk indicator
-+ *
-+ * Try to progress on parsing
-+ *
-+ * Returns zero if no parsing was possible
-+ */
-+int
-+xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
-+ int ret = 0;
-+ int avail;
-+ xmlChar cur, next;
-+
-+#ifdef DEBUG_PUSH
-+ switch (ctxt->instate) {
-+ case XML_PARSER_EOF:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try EOF\n"); break;
-+ case XML_PARSER_START:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try START\n"); break;
-+ case XML_PARSER_MISC:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try MISC\n");break;
-+ case XML_PARSER_COMMENT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try COMMENT\n");break;
-+ case XML_PARSER_PROLOG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try PROLOG\n");break;
-+ case XML_PARSER_START_TAG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try START_TAG\n");break;
-+ case XML_PARSER_CONTENT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try CONTENT\n");break;
-+ case XML_PARSER_CDATA_SECTION:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try CDATA_SECTION\n");break;
-+ case XML_PARSER_END_TAG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try END_TAG\n");break;
-+ case XML_PARSER_ENTITY_DECL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try ENTITY_DECL\n");break;
-+ case XML_PARSER_ENTITY_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try ENTITY_VALUE\n");break;
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try ATTRIBUTE_VALUE\n");break;
-+ case XML_PARSER_DTD:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try DTD\n");break;
-+ case XML_PARSER_EPILOG:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try EPILOG\n");break;
-+ case XML_PARSER_PI:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try PI\n");break;
-+ case XML_PARSER_IGNORE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: try IGNORE\n");break;
-+ }
-+#endif
-+
-+ while (1) {
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+
-+ if (ctxt->input ==NULL) break;
-+ if (ctxt->input->buf == NULL)
-+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-+ else
-+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-+ if (avail < 1)
-+ goto done;
-+ switch (ctxt->instate) {
-+ case XML_PARSER_EOF:
-+ /*
-+ * Document parsing is done !
-+ */
-+ goto done;
-+ case XML_PARSER_START:
-+ /*
-+ * Very first chars read from the document flow.
-+ */
-+ cur = ctxt->input->cur[0];
-+ if (IS_BLANK(cur)) {
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData,
-+ &xmlDefaultSAXLocator);
-+ ctxt->errNo = XML_ERR_DOCUMENT_START;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra spaces at the beginning of the document are not allowed\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ SKIP_BLANKS;
-+ ret++;
-+ if (ctxt->input->buf == NULL)
-+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-+ else
-+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-+ }
-+ if (avail < 2)
-+ goto done;
-+
-+ cur = ctxt->input->cur[0];
-+ next = ctxt->input->cur[1];
-+ if (cur == 0) {
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData,
-+ &xmlDefaultSAXLocator);
-+ ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Document is empty\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_EOF;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering EOF\n");
-+#endif
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ goto done;
-+ }
-+ if ((cur == '<') && (next == '?')) {
-+ /* PI or XML decl */
-+ if (avail < 5) return(ret);
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-+ return(ret);
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData,
-+ &xmlDefaultSAXLocator);
-+ if ((ctxt->input->cur[2] == 'x') &&
-+ (ctxt->input->cur[3] == 'm') &&
-+ (ctxt->input->cur[4] == 'l') &&
-+ (IS_BLANK(ctxt->input->cur[5]))) {
-+ ret += 5;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing XML Decl\n");
-+#endif
-+ xmlParseXMLDecl(ctxt);
-+ if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-+ /*
-+ * The XML REC instructs us to stop parsing right
-+ * here
-+ */
-+ ctxt->instate = XML_PARSER_EOF;
-+ return(0);
-+ }
-+ ctxt->standalone = ctxt->input->standalone;
-+ if ((ctxt->encoding == NULL) &&
-+ (ctxt->input->encoding != NULL))
-+ ctxt->encoding = xmlStrdup(ctxt->input->encoding);
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+ ctxt->instate = XML_PARSER_MISC;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering MISC\n");
-+#endif
-+ } else {
-+ ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+ ctxt->instate = XML_PARSER_MISC;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering MISC\n");
-+#endif
-+ }
-+ } else {
-+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-+ ctxt->sax->setDocumentLocator(ctxt->userData,
-+ &xmlDefaultSAXLocator);
-+ ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-+ if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->startDocument(ctxt->userData);
-+ ctxt->instate = XML_PARSER_MISC;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering MISC\n");
-+#endif
-+ }
-+ break;
-+ case XML_PARSER_MISC:
-+ SKIP_BLANKS;
-+ if (ctxt->input->buf == NULL)
-+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-+ else
-+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-+ if (avail < 2)
-+ goto done;
-+ cur = ctxt->input->cur[0];
-+ next = ctxt->input->cur[1];
-+ if ((cur == '<') && (next == '?')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing PI\n");
-+#endif
-+ xmlParsePI(ctxt);
-+ } else if ((cur == '<') && (next == '!') &&
-+ (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing Comment\n");
-+#endif
-+ xmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_MISC;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (ctxt->input->cur[2] == 'D') && (ctxt->input->cur[3] == 'O') &&
-+ (ctxt->input->cur[4] == 'C') && (ctxt->input->cur[5] == 'T') &&
-+ (ctxt->input->cur[6] == 'Y') && (ctxt->input->cur[7] == 'P') &&
-+ (ctxt->input->cur[8] == 'E')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing internal subset\n");
-+#endif
-+ ctxt->inSubset = 1;
-+ xmlParseDocTypeDecl(ctxt);
-+ if (RAW == '[') {
-+ ctxt->instate = XML_PARSER_DTD;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering DTD\n");
-+#endif
-+ } else {
-+ /*
-+ * Create and update the external subset.
-+ */
-+ ctxt->inSubset = 2;
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->externalSubset != NULL))
-+ ctxt->sax->externalSubset(ctxt->userData,
-+ ctxt->intSubName, ctxt->extSubSystem,
-+ ctxt->extSubURI);
-+ ctxt->inSubset = 0;
-+ ctxt->instate = XML_PARSER_PROLOG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering PROLOG\n");
-+#endif
-+ }
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 9)) {
-+ goto done;
-+ } else {
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering START_TAG\n");
-+#endif
-+ }
-+ break;
-+ case XML_PARSER_IGNORE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == IGNORE");
-+ ctxt->instate = XML_PARSER_DTD;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering DTD\n");
-+#endif
-+ break;
-+ case XML_PARSER_PROLOG:
-+ SKIP_BLANKS;
-+ if (ctxt->input->buf == NULL)
-+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-+ else
-+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-+ if (avail < 2)
-+ goto done;
-+ cur = ctxt->input->cur[0];
-+ next = ctxt->input->cur[1];
-+ if ((cur == '<') && (next == '?')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing PI\n");
-+#endif
-+ xmlParsePI(ctxt);
-+ } else if ((cur == '<') && (next == '!') &&
-+ (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing Comment\n");
-+#endif
-+ xmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_PROLOG;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 4)) {
-+ goto done;
-+ } else {
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering START_TAG\n");
-+#endif
-+ }
-+ break;
-+ case XML_PARSER_EPILOG:
-+ SKIP_BLANKS;
-+ if (ctxt->input->buf == NULL)
-+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-+ else
-+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-+ if (avail < 2)
-+ goto done;
-+ cur = ctxt->input->cur[0];
-+ next = ctxt->input->cur[1];
-+ if ((cur == '<') && (next == '?')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing PI\n");
-+#endif
-+ xmlParsePI(ctxt);
-+ ctxt->instate = XML_PARSER_EPILOG;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing Comment\n");
-+#endif
-+ xmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_EPILOG;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 4)) {
-+ goto done;
-+ } else {
-+ ctxt->errNo = XML_ERR_DOCUMENT_END;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra content at the end of the document\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_EOF;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering EOF\n");
-+#endif
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ goto done;
-+ }
-+ break;
-+ case XML_PARSER_START_TAG: {
-+ xmlChar *name, *oldname;
-+
-+ if ((avail < 2) && (ctxt->inputNr == 1))
-+ goto done;
-+ cur = ctxt->input->cur[0];
-+ if (cur != '<') {
-+ ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Start tag expect, '<' not found\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_EOF;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering EOF\n");
-+#endif
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ goto done;
-+ }
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+ if (ctxt->spaceNr == 0)
-+ spacePush(ctxt, -1);
-+ else
-+ spacePush(ctxt, *ctxt->space);
-+ name = xmlParseStartTag(ctxt);
-+ if (name == NULL) {
-+ spacePop(ctxt);
-+ ctxt->instate = XML_PARSER_EOF;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering EOF\n");
-+#endif
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ goto done;
-+ }
-+ namePush(ctxt, xmlStrdup(name));
-+
-+ /*
-+ * [ VC: Root Element Type ]
-+ * The Name in the document type declaration must match
-+ * the element type of the root element.
-+ */
-+ if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
-+ ctxt->node && (ctxt->node == ctxt->myDoc->children))
-+ ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-+
-+ /*
-+ * Check for an Empty Element.
-+ */
-+ if ((RAW == '/') && (NXT(1) == '>')) {
-+ SKIP(2);
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->endElement != NULL) && (!ctxt->disableSAX))
-+ ctxt->sax->endElement(ctxt->userData, name);
-+ xmlFree(name);
-+ oldname = namePop(ctxt);
-+ spacePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG_STACK
-+ xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ if (ctxt->name == NULL) {
-+ ctxt->instate = XML_PARSER_EPILOG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering EPILOG\n");
-+#endif
-+ } else {
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CONTENT\n");
-+#endif
-+ }
-+ break;
-+ }
-+ if (RAW == '>') {
-+ NEXT;
-+ } else {
-+ ctxt->errNo = XML_ERR_GT_REQUIRED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Couldn't find end of Start Tag %s\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+
-+ /*
-+ * end of parsing of this node.
-+ */
-+ nodePop(ctxt);
-+ oldname = namePop(ctxt);
-+ spacePop(ctxt);
-+ if (oldname != NULL) {
-+#ifdef DEBUG_STACK
-+ xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-+#endif
-+ xmlFree(oldname);
-+ }
-+ }
-+ xmlFree(name);
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CONTENT\n");
-+#endif
-+ break;
-+ }
-+ case XML_PARSER_CONTENT: {
-+ const xmlChar *test;
-+ int cons;
-+ xmlChar tok;
-+
-+ /*
-+ * Handle preparsed entities and charRef
-+ */
-+ if (ctxt->token != 0) {
-+ xmlChar cur[2] = { 0 , 0 } ;
-+
-+ cur[0] = (xmlChar) ctxt->token;
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, cur, 1);
-+ ctxt->token = 0;
-+ }
-+ if ((avail < 2) && (ctxt->inputNr == 1))
-+ goto done;
-+ cur = ctxt->input->cur[0];
-+ next = ctxt->input->cur[1];
-+
-+ test = CUR_PTR;
-+ cons = ctxt->input->consumed;
-+ tok = ctxt->token;
-+ if ((cur == '<') && (next == '?')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing PI\n");
-+#endif
-+ xmlParsePI(ctxt);
-+ } else if ((cur == '<') && (next == '!') &&
-+ (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing Comment\n");
-+#endif
-+ xmlParseComment(ctxt);
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
-+ (ctxt->input->cur[2] == '[') && (NXT(3) == 'C') &&
-+ (ctxt->input->cur[4] == 'D') && (NXT(5) == 'A') &&
-+ (ctxt->input->cur[6] == 'T') && (NXT(7) == 'A') &&
-+ (ctxt->input->cur[8] == '[')) {
-+ SKIP(9);
-+ ctxt->instate = XML_PARSER_CDATA_SECTION;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CDATA_SECTION\n");
-+#endif
-+ break;
-+ } else if ((cur == '<') && (next == '!') &&
-+ (avail < 9)) {
-+ goto done;
-+ } else if ((cur == '<') && (next == '/')) {
-+ ctxt->instate = XML_PARSER_END_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering END_TAG\n");
-+#endif
-+ break;
-+ } else if (cur == '<') {
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering START_TAG\n");
-+#endif
-+ break;
-+ } else if (cur == '&') {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
-+ goto done;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing Reference\n");
-+#endif
-+ xmlParseReference(ctxt);
-+ } else {
-+ /* TODO Avoid the extra copy, handle directly !!! */
-+ /*
-+ * Goal of the following test is:
-+ * - minimize calls to the SAX 'character' callback
-+ * when they are mergeable
-+ * - handle an problem for isBlank when we only parse
-+ * a sequence of blank chars and the next one is
-+ * not available to check against '<' presence.
-+ * - tries to homogenize the differences in SAX
-+ * callbacks beween the push and pull versions
-+ * of the parser.
-+ */
-+ if ((ctxt->inputNr == 1) &&
-+ (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
-+ goto done;
-+ }
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: Parsing char data\n");
-+#endif
-+ xmlParseCharData(ctxt, 0);
-+ }
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1))
-+ xmlPopInput(ctxt);
-+ if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
-+ (tok == ctxt->token)) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "detected an error in element content\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->instate = XML_PARSER_EOF;
-+ break;
-+ }
-+ break;
-+ }
-+ case XML_PARSER_CDATA_SECTION: {
-+ /*
-+ * The Push mode need to have the SAX callback for
-+ * cdataBlock merge back contiguous callbacks.
-+ */
-+ int base;
-+
-+ base = xmlParseLookupSequence(ctxt, ']', ']', '>');
-+ if (base < 0) {
-+ if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-+ if (ctxt->sax->cdataBlock != NULL)
-+ ctxt->sax->cdataBlock(ctxt->userData, ctxt->input->cur,
-+ XML_PARSER_BIG_BUFFER_SIZE);
-+ }
-+ SKIP(XML_PARSER_BIG_BUFFER_SIZE);
-+ ctxt->checkIndex = 0;
-+ }
-+ goto done;
-+ } else {
-+ if ((ctxt->sax != NULL) && (base > 0) &&
-+ (!ctxt->disableSAX)) {
-+ if (ctxt->sax->cdataBlock != NULL)
-+ ctxt->sax->cdataBlock(ctxt->userData,
-+ ctxt->input->cur, base);
-+ }
-+ SKIP(base + 3);
-+ ctxt->checkIndex = 0;
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CONTENT\n");
-+#endif
-+ }
-+ break;
-+ }
-+ case XML_PARSER_END_TAG:
-+ if (avail < 2)
-+ goto done;
-+ if ((!terminate) &&
-+ (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-+ goto done;
-+ xmlParseEndTag(ctxt);
-+ if (ctxt->name == NULL) {
-+ ctxt->instate = XML_PARSER_EPILOG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering EPILOG\n");
-+#endif
-+ } else {
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CONTENT\n");
-+#endif
-+ }
-+ break;
-+ case XML_PARSER_DTD: {
-+ /*
-+ * Sorry but progressive parsing of the internal subset
-+ * is not expected to be supported. We first check that
-+ * the full content of the internal subset is available and
-+ * the parsing is launched only at that point.
-+ * Internal subset ends up with "']' S? '>'" in an unescaped
-+ * section and not in a ']]>' sequence which are conditional
-+ * sections (whoever argued to keep that crap in XML deserve
-+ * a place in hell !).
-+ */
-+ int base, i;
-+ xmlChar *buf;
-+ xmlChar quote = 0;
-+
-+ base = ctxt->input->cur - ctxt->input->base;
-+ if (base < 0) return(0);
-+ if (ctxt->checkIndex > base)
-+ base = ctxt->checkIndex;
-+ buf = ctxt->input->buf->buffer->content;
-+ for (;(unsigned int) base < ctxt->input->buf->buffer->use;
-+ base++) {
-+ if (quote != 0) {
-+ if (buf[base] == quote)
-+ quote = 0;
-+ continue;
-+ }
-+ if (buf[base] == '"') {
-+ quote = '"';
-+ continue;
-+ }
-+ if (buf[base] == '\'') {
-+ quote = '\'';
-+ continue;
-+ }
-+ if (buf[base] == ']') {
-+ if ((unsigned int) base +1 >=
-+ ctxt->input->buf->buffer->use)
-+ break;
-+ if (buf[base + 1] == ']') {
-+ /* conditional crap, skip both ']' ! */
-+ base++;
-+ continue;
-+ }
-+ for (i = 0;
-+ (unsigned int) base + i < ctxt->input->buf->buffer->use;
-+ i++) {
-+ if (buf[base + i] == '>')
-+ goto found_end_int_subset;
-+ }
-+ break;
-+ }
-+ }
-+ /*
-+ * We didn't found the end of the Internal subset
-+ */
-+ if (quote == 0)
-+ ctxt->checkIndex = base;
-+#ifdef DEBUG_PUSH
-+ if (next == 0)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: lookup of int subset end filed\n");
-+#endif
-+ goto done;
-+
-+found_end_int_subset:
-+ xmlParseInternalSubset(ctxt);
-+ ctxt->inSubset = 2;
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->externalSubset != NULL))
-+ ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
-+ ctxt->extSubSystem, ctxt->extSubURI);
-+ ctxt->inSubset = 0;
-+ ctxt->instate = XML_PARSER_PROLOG;
-+ ctxt->checkIndex = 0;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering PROLOG\n");
-+#endif
-+ break;
-+ }
-+ case XML_PARSER_COMMENT:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == COMMENT\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_PI:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == PI\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering CONTENT\n");
-+#endif
-+ break;
-+ case XML_PARSER_ENTITY_DECL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == ENTITY_DECL\n");
-+ ctxt->instate = XML_PARSER_DTD;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering DTD\n");
-+#endif
-+ break;
-+ case XML_PARSER_ENTITY_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == ENTITY_VALUE\n");
-+ ctxt->instate = XML_PARSER_CONTENT;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering DTD\n");
-+#endif
-+ break;
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == ATTRIBUTE_VALUE\n");
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering START_TAG\n");
-+#endif
-+ break;
-+ case XML_PARSER_SYSTEM_LITERAL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: internal error, state == SYSTEM_LITERAL\n");
-+ ctxt->instate = XML_PARSER_START_TAG;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PP: entering START_TAG\n");
-+#endif
-+ break;
-+ }
-+ }
-+done:
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
-+#endif
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseTry:
-+ * @ctxt: an XML parser context
-+ *
-+ * Try to progress on parsing
-+ *
-+ * Returns zero if no parsing was possible
-+ */
-+int
-+xmlParseTry(xmlParserCtxtPtr ctxt) {
-+ return(xmlParseTryOrFinish(ctxt, 0));
-+}
-+
-+/**
-+ * xmlParseChunk:
-+ * @ctxt: an XML parser context
-+ * @chunk: an char array
-+ * @size: the size in byte of the chunk
-+ * @terminate: last chunk indicator
-+ *
-+ * Parse a Chunk of memory
-+ *
-+ * Returns zero if no error, the xmlParserErrors otherwise.
-+ */
-+int
-+xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
-+ int terminate) {
-+ if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-+ (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
-+ int base = ctxt->input->base - ctxt->input->buf->buffer->content;
-+ int cur = ctxt->input->cur - ctxt->input->base;
-+
-+ xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-+ ctxt->input->base = ctxt->input->buf->buffer->content + base;
-+ ctxt->input->cur = ctxt->input->base + cur;
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-+#endif
-+
-+ if ((terminate) || (ctxt->input->buf->buffer->use > 80))
-+ xmlParseTryOrFinish(ctxt, terminate);
-+ } else if (ctxt->instate != XML_PARSER_EOF) {
-+ if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
-+ xmlParserInputBufferPtr in = ctxt->input->buf;
-+ if ((in->encoder != NULL) && (in->buffer != NULL) &&
-+ (in->raw != NULL)) {
-+ int nbchars;
-+
-+ nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-+ if (nbchars < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseChunk: encoder error\n");
-+ return(XML_ERR_INVALID_ENCODING);
-+ }
-+ }
-+ }
-+ }
-+ xmlParseTryOrFinish(ctxt, terminate);
-+ if (terminate) {
-+ /*
-+ * Check for termination
-+ */
-+ if ((ctxt->instate != XML_PARSER_EOF) &&
-+ (ctxt->instate != XML_PARSER_EPILOG)) {
-+ ctxt->errNo = XML_ERR_DOCUMENT_END;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Extra content at the end of the document\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (ctxt->instate != XML_PARSER_EOF) {
-+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-+ (!ctxt->disableSAX))
-+ ctxt->sax->endDocument(ctxt->userData);
-+ }
-+ ctxt->instate = XML_PARSER_EOF;
-+ }
-+ return((xmlParserErrors) ctxt->errNo);
-+}
-+
-+/************************************************************************
-+ * *
-+ * I/O front end functions to the parser *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlStopParser:
-+ * @ctxt: an XML parser context
-+ *
-+ * Blocks further parser processing
-+ */
-+void
-+xmlStopParser(xmlParserCtxtPtr ctxt) {
-+ ctxt->instate = XML_PARSER_EOF;
-+ if (ctxt->input != NULL)
-+ ctxt->input->cur = BAD_CAST"";
-+}
-+
-+/**
-+ * xmlCreatePushParserCtxt:
-+ * @sax: a SAX handler
-+ * @user_data: The user data returned on SAX callbacks
-+ * @chunk: a pointer to an array of chars
-+ * @size: number of chars in the array
-+ * @filename: an optional file name or URI
-+ *
-+ * Create a parser context for using the XML parser in push mode
-+ * To allow content encoding detection, @size should be >= 4
-+ * The value of @filename is used for fetching external entities
-+ * and error/warning reports.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+xmlParserCtxtPtr
-+xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
-+ const char *chunk, int size, const char *filename) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr inputStream;
-+ xmlParserInputBufferPtr buf;
-+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
-+
-+ /*
-+ * plug some encoding conversion routines
-+ */
-+ if ((chunk != NULL) && (size >= 4))
-+ enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
-+
-+ buf = xmlAllocParserInputBuffer(enc);
-+ if (buf == NULL) return(NULL);
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL) {
-+ xmlFree(buf);
-+ return(NULL);
-+ }
-+ if (sax != NULL) {
-+ if (ctxt->sax != &xmlDefaultSAXHandler)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
-+ if (ctxt->sax == NULL) {
-+ xmlFree(buf);
-+ xmlFree(ctxt);
-+ return(NULL);
-+ }
-+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
-+ if (user_data != NULL)
-+ ctxt->userData = user_data;
-+ }
-+ if (filename == NULL) {
-+ ctxt->directory = NULL;
-+ } else {
-+ ctxt->directory = xmlParserGetDirectory(filename);
-+ }
-+
-+ inputStream = xmlNewInputStream(ctxt);
-+ if (inputStream == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ if (filename == NULL)
-+ inputStream->filename = NULL;
-+ else
-+ inputStream->filename = xmlMemStrdup(filename);
-+ inputStream->buf = buf;
-+ inputStream->base = inputStream->buf->buffer->content;
-+ inputStream->cur = inputStream->buf->buffer->content;
-+ if (enc != XML_CHAR_ENCODING_NONE) {
-+ xmlSwitchEncoding(ctxt, enc);
-+ }
-+
-+ inputPush(ctxt, inputStream);
-+
-+ if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-+ (ctxt->input->buf != NULL)) {
-+ xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-+#ifdef DEBUG_PUSH
-+ xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-+#endif
-+ }
-+
-+ return(ctxt);
-+}
-+
-+/**
-+ * xmlCreateIOParserCtxt:
-+ * @sax: a SAX handler
-+ * @user_data: The user data returned on SAX callbacks
-+ * @ioread: an I/O read function
-+ * @ioclose: an I/O close function
-+ * @ioctx: an I/O handler
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a parser context for using the XML parser with an existing
-+ * I/O stream
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+xmlParserCtxtPtr
-+xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
-+ xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
-+ void *ioctx, xmlCharEncoding enc) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr inputStream;
-+ xmlParserInputBufferPtr buf;
-+
-+ buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
-+ if (buf == NULL) return(NULL);
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL) {
-+ xmlFree(buf);
-+ return(NULL);
-+ }
-+ if (sax != NULL) {
-+ if (ctxt->sax != &xmlDefaultSAXHandler)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
-+ if (ctxt->sax == NULL) {
-+ xmlFree(buf);
-+ xmlFree(ctxt);
-+ return(NULL);
-+ }
-+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
-+ if (user_data != NULL)
-+ ctxt->userData = user_data;
-+ }
-+
-+ inputStream = xmlNewIOInputStream(ctxt, buf, enc);
-+ if (inputStream == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+ inputPush(ctxt, inputStream);
-+
-+ return(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Front ends when parsing a Dtd *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlIOParseDTD:
-+ * @sax: the SAX handler block or NULL
-+ * @input: an Input Buffer
-+ * @enc: the charset encoding if known
-+ *
-+ * Load and parse a DTD
-+ *
-+ * Returns the resulting xmlDtdPtr or NULL in case of error.
-+ * @input will be freed at parsing end.
-+ */
-+
-+xmlDtdPtr
-+xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
-+ xmlCharEncoding enc) {
-+ xmlDtdPtr ret = NULL;
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr pinput = NULL;
-+
-+ if (input == NULL)
-+ return(NULL);
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL) {
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Set-up the SAX context
-+ */
-+ if (sax != NULL) {
-+ if (ctxt->sax != NULL)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = sax;
-+ ctxt->userData = NULL;
-+ }
-+
-+ /*
-+ * generate a parser input from the I/O handler
-+ */
-+
-+ pinput = xmlNewIOInputStream(ctxt, input, enc);
-+ if (pinput == NULL) {
-+ if (sax != NULL) ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * plug some encoding conversion routines here.
-+ */
-+ xmlPushInput(ctxt, pinput);
-+
-+ pinput->filename = NULL;
-+ pinput->line = 1;
-+ pinput->col = 1;
-+ pinput->base = ctxt->input->cur;
-+ pinput->cur = ctxt->input->cur;
-+ pinput->free = NULL;
-+
-+ /*
-+ * let's parse that entity knowing it's an external subset.
-+ */
-+ ctxt->inSubset = 2;
-+ ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-+ ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
-+ BAD_CAST "none", BAD_CAST "none");
-+ xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
-+
-+ if (ctxt->myDoc != NULL) {
-+ if (ctxt->wellFormed) {
-+ ret = ctxt->myDoc->extSubset;
-+ ctxt->myDoc->extSubset = NULL;
-+ } else {
-+ ret = NULL;
-+ }
-+ xmlFreeDoc(ctxt->myDoc);
-+ ctxt->myDoc = NULL;
-+ }
-+ if (sax != NULL) ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSAXParseDTD:
-+ * @sax: the SAX handler block
-+ * @ExternalID: a NAME* containing the External ID of the DTD
-+ * @SystemID: a NAME* containing the URL to the DTD
-+ *
-+ * Load and parse an external subset.
-+ *
-+ * Returns the resulting xmlDtdPtr or NULL in case of error.
-+ */
-+
-+xmlDtdPtr
-+xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
-+ const xmlChar *SystemID) {
-+ xmlDtdPtr ret = NULL;
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr input = NULL;
-+ xmlCharEncoding enc;
-+
-+ if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL) {
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Set-up the SAX context
-+ */
-+ if (sax != NULL) {
-+ if (ctxt->sax != NULL)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = sax;
-+ ctxt->userData = NULL;
-+ }
-+
-+ /*
-+ * Ask the Entity resolver to load the damn thing
-+ */
-+
-+ if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
-+ input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, SystemID);
-+ if (input == NULL) {
-+ if (sax != NULL) ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * plug some encoding conversion routines here.
-+ */
-+ xmlPushInput(ctxt, input);
-+ enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
-+ xmlSwitchEncoding(ctxt, enc);
-+
-+ if (input->filename == NULL)
-+ input->filename = (char *) xmlStrdup(SystemID);
-+ input->line = 1;
-+ input->col = 1;
-+ input->base = ctxt->input->cur;
-+ input->cur = ctxt->input->cur;
-+ input->free = NULL;
-+
-+ /*
-+ * let's parse that entity knowing it's an external subset.
-+ */
-+ ctxt->inSubset = 2;
-+ ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-+ ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
-+ ExternalID, SystemID);
-+ xmlParseExternalSubset(ctxt, ExternalID, SystemID);
-+
-+ if (ctxt->myDoc != NULL) {
-+ if (ctxt->wellFormed) {
-+ ret = ctxt->myDoc->extSubset;
-+ ctxt->myDoc->extSubset = NULL;
-+ } else {
-+ ret = NULL;
-+ }
-+ xmlFreeDoc(ctxt->myDoc);
-+ ctxt->myDoc = NULL;
-+ }
-+ if (sax != NULL) ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseDTD:
-+ * @ExternalID: a NAME* containing the External ID of the DTD
-+ * @SystemID: a NAME* containing the URL to the DTD
-+ *
-+ * Load and parse an external subset.
-+ *
-+ * Returns the resulting xmlDtdPtr or NULL in case of error.
-+ */
-+
-+xmlDtdPtr
-+xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
-+ return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
-+}
-+
-+/************************************************************************
-+ * *
-+ * Front ends when parsing an Entity *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlSAXParseBalancedChunk:
-+ * @ctx: an XML parser context (possibly NULL)
-+ * @sax: the SAX handler bloc (possibly NULL)
-+ * @user_data: The user data returned on SAX callbacks (possibly NULL)
-+ * @input: a parser input stream
-+ * @enc: the encoding
-+ *
-+ * Parse a well-balanced chunk of an XML document
-+ * The user has to provide SAX callback block whose routines will be
-+ * called by the parser
-+ * The allowed sequence for the Well Balanced Chunk is the one defined by
-+ * the content production in the XML grammar:
-+ *
-+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-+ *
-+ * Returns 0 if the chunk is well balanced, -1 in case of args problem and
-+ * the error code otherwise
-+ */
-+
-+int
-+xmlSAXParseBalancedChunk(xmlParserCtxtPtr ctx, xmlSAXHandlerPtr sax,
-+ void *user_data, xmlParserInputPtr input,
-+ xmlCharEncoding enc) {
-+ xmlParserCtxtPtr ctxt;
-+ int ret;
-+
-+ if (input == NULL) return(-1);
-+
-+ if (ctx != NULL)
-+ ctxt = ctx;
-+ else {
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL)
-+ return(-1);
-+ if (sax == NULL)
-+ ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-+ }
-+
-+ /*
-+ * Set-up the SAX context
-+ */
-+ if (sax != NULL) {
-+ if (ctxt->sax != NULL)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = sax;
-+ ctxt->userData = user_data;
-+ }
-+
-+ /*
-+ * plug some encoding conversion routines here.
-+ */
-+ xmlPushInput(ctxt, input);
-+ if (enc != XML_CHAR_ENCODING_NONE)
-+ xmlSwitchEncoding(ctxt, enc);
-+
-+ /*
-+ * let's parse that entity knowing it's an external subset.
-+ */
-+ xmlParseContent(ctxt);
-+ ret = ctxt->errNo;
-+
-+ if (ctx == NULL) {
-+ if (sax != NULL)
-+ ctxt->sax = NULL;
-+ else
-+ xmlFreeDoc(ctxt->myDoc);
-+ xmlFreeParserCtxt(ctxt);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseCtxtExternalEntity:
-+ * @ctx: the existing parsing context
-+ * @URL: the URL for the entity to load
-+ * @ID: the System ID for the entity to load
-+ * @list: the return value for the set of parsed nodes
-+ *
-+ * Parse an external general entity within an existing parsing context
-+ * An external general parsed entity is well-formed if it matches the
-+ * production labeled extParsedEnt.
-+ *
-+ * [78] extParsedEnt ::= TextDecl? content
-+ *
-+ * Returns 0 if the entity is well formed, -1 in case of args problem and
-+ * the parser error code otherwise
-+ */
-+
-+int
-+xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
-+ const xmlChar *ID, xmlNodePtr *list) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlDocPtr newDoc;
-+ xmlSAXHandlerPtr oldsax = NULL;
-+ int ret = 0;
-+
-+ if (ctx->depth > 40) {
-+ return(XML_ERR_ENTITY_LOOP);
-+ }
-+
-+ if (list != NULL)
-+ *list = NULL;
-+ if ((URL == NULL) && (ID == NULL))
-+ return(-1);
-+ if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
-+ return(-1);
-+
-+
-+ ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
-+ if (ctxt == NULL) return(-1);
-+ ctxt->userData = ctxt;
-+ oldsax = ctxt->sax;
-+ ctxt->sax = ctx->sax;
-+ newDoc = xmlNewDoc(BAD_CAST "1.0");
-+ if (newDoc == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(-1);
-+ }
-+ if (ctx->myDoc != NULL) {
-+ newDoc->intSubset = ctx->myDoc->intSubset;
-+ newDoc->extSubset = ctx->myDoc->extSubset;
-+ }
-+ if (ctx->myDoc->URL != NULL) {
-+ newDoc->URL = xmlStrdup(ctx->myDoc->URL);
-+ }
-+ newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-+ if (newDoc->children == NULL) {
-+ ctxt->sax = oldsax;
-+ xmlFreeParserCtxt(ctxt);
-+ newDoc->intSubset = NULL;
-+ newDoc->extSubset = NULL;
-+ xmlFreeDoc(newDoc);
-+ return(-1);
-+ }
-+ nodePush(ctxt, newDoc->children);
-+ if (ctx->myDoc == NULL) {
-+ ctxt->myDoc = newDoc;
-+ } else {
-+ ctxt->myDoc = ctx->myDoc;
-+ newDoc->children->doc = ctx->myDoc;
-+ }
-+
-+ /*
-+ * Parse a possible text declaration first
-+ */
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+ xmlParseTextDecl(ctxt);
-+ }
-+
-+ /*
-+ * Doing validity checking on chunk doesn't make sense
-+ */
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->validate = ctx->validate;
-+ ctxt->loadsubset = ctx->loadsubset;
-+ ctxt->depth = ctx->depth + 1;
-+ ctxt->replaceEntities = ctx->replaceEntities;
-+ if (ctxt->validate) {
-+ ctxt->vctxt.error = ctx->vctxt.error;
-+ ctxt->vctxt.warning = ctx->vctxt.warning;
-+ /* Allocate the Node stack */
-+ ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
-+ if (ctxt->vctxt.nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseCtxtExternalEntity: out of memory\n");
-+ ctxt->validate = 0;
-+ ctxt->vctxt.error = NULL;
-+ ctxt->vctxt.warning = NULL;
-+ } else {
-+ ctxt->vctxt.nodeNr = 0;
-+ ctxt->vctxt.nodeMax = 4;
-+ ctxt->vctxt.node = NULL;
-+ }
-+ } else {
-+ ctxt->vctxt.error = NULL;
-+ ctxt->vctxt.warning = NULL;
-+ }
-+
-+ xmlParseContent(ctxt);
-+
-+ if ((RAW == '<') && (NXT(1) == '/')) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if (RAW != 0) {
-+ ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "extra content at the end of well balanced chunk\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (ctxt->node != newDoc->children) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ if (!ctxt->wellFormed) {
-+ if (ctxt->errNo == 0)
-+ ret = 1;
-+ else
-+ ret = ctxt->errNo;
-+ } else {
-+ if (list != NULL) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Return the newly created nodeset after unlinking it from
-+ * they pseudo parent.
-+ */
-+ cur = newDoc->children->children;
-+ *list = cur;
-+ while (cur != NULL) {
-+ cur->parent = NULL;
-+ cur = cur->next;
-+ }
-+ newDoc->children->children = NULL;
-+ }
-+ ret = 0;
-+ }
-+ ctxt->sax = oldsax;
-+ xmlFreeParserCtxt(ctxt);
-+ newDoc->intSubset = NULL;
-+ newDoc->extSubset = NULL;
-+ xmlFreeDoc(newDoc);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseExternalEntity:
-+ * @doc: the document the chunk pertains to
-+ * @sax: the SAX handler bloc (possibly NULL)
-+ * @user_data: The user data returned on SAX callbacks (possibly NULL)
-+ * @depth: Used for loop detection, use 0
-+ * @URL: the URL for the entity to load
-+ * @ID: the System ID for the entity to load
-+ * @list: the return value for the set of parsed nodes
-+ *
-+ * Parse an external general entity
-+ * An external general parsed entity is well-formed if it matches the
-+ * production labeled extParsedEnt.
-+ *
-+ * [78] extParsedEnt ::= TextDecl? content
-+ *
-+ * Returns 0 if the entity is well formed, -1 in case of args problem and
-+ * the parser error code otherwise
-+ */
-+
-+int
-+xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
-+ int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *list) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlDocPtr newDoc;
-+ xmlSAXHandlerPtr oldsax = NULL;
-+ int ret = 0;
-+
-+ if (depth > 40) {
-+ return(XML_ERR_ENTITY_LOOP);
-+ }
-+
-+
-+
-+ if (list != NULL)
-+ *list = NULL;
-+ if ((URL == NULL) && (ID == NULL))
-+ return(-1);
-+ if (doc == NULL) /* @@ relax but check for dereferences */
-+ return(-1);
-+
-+
-+ ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
-+ if (ctxt == NULL) return(-1);
-+ ctxt->userData = ctxt;
-+ if (sax != NULL) {
-+ oldsax = ctxt->sax;
-+ ctxt->sax = sax;
-+ if (user_data != NULL)
-+ ctxt->userData = user_data;
-+ }
-+ newDoc = xmlNewDoc(BAD_CAST "1.0");
-+ if (newDoc == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(-1);
-+ }
-+ if (doc != NULL) {
-+ newDoc->intSubset = doc->intSubset;
-+ newDoc->extSubset = doc->extSubset;
-+ }
-+ if (doc->URL != NULL) {
-+ newDoc->URL = xmlStrdup(doc->URL);
-+ }
-+ newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-+ if (newDoc->children == NULL) {
-+ if (sax != NULL)
-+ ctxt->sax = oldsax;
-+ xmlFreeParserCtxt(ctxt);
-+ newDoc->intSubset = NULL;
-+ newDoc->extSubset = NULL;
-+ xmlFreeDoc(newDoc);
-+ return(-1);
-+ }
-+ nodePush(ctxt, newDoc->children);
-+ if (doc == NULL) {
-+ ctxt->myDoc = newDoc;
-+ } else {
-+ ctxt->myDoc = doc;
-+ newDoc->children->doc = doc;
-+ }
-+
-+ /*
-+ * Parse a possible text declaration first
-+ */
-+ GROW;
-+ if ((RAW == '<') && (NXT(1) == '?') &&
-+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
-+ (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-+ xmlParseTextDecl(ctxt);
-+ }
-+
-+ /*
-+ * Doing validity checking on chunk doesn't make sense
-+ */
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->validate = 0;
-+ ctxt->loadsubset = 0;
-+ ctxt->depth = depth;
-+
-+ xmlParseContent(ctxt);
-+
-+ if ((RAW == '<') && (NXT(1) == '/')) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if (RAW != 0) {
-+ ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "extra content at the end of well balanced chunk\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (ctxt->node != newDoc->children) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ if (!ctxt->wellFormed) {
-+ if (ctxt->errNo == 0)
-+ ret = 1;
-+ else
-+ ret = ctxt->errNo;
-+ } else {
-+ if (list != NULL) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Return the newly created nodeset after unlinking it from
-+ * they pseudo parent.
-+ */
-+ cur = newDoc->children->children;
-+ *list = cur;
-+ while (cur != NULL) {
-+ cur->parent = NULL;
-+ cur = cur->next;
-+ }
-+ newDoc->children->children = NULL;
-+ }
-+ ret = 0;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = oldsax;
-+ xmlFreeParserCtxt(ctxt);
-+ newDoc->intSubset = NULL;
-+ newDoc->extSubset = NULL;
-+ xmlFreeDoc(newDoc);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseBalancedChunk:
-+ * @doc: the document the chunk pertains to
-+ * @sax: the SAX handler bloc (possibly NULL)
-+ * @user_data: The user data returned on SAX callbacks (possibly NULL)
-+ * @depth: Used for loop detection, use 0
-+ * @string: the input string in UTF8 or ISO-Latin (zero terminated)
-+ * @list: the return value for the set of parsed nodes
-+ *
-+ * Parse a well-balanced chunk of an XML document
-+ * called by the parser
-+ * The allowed sequence for the Well Balanced Chunk is the one defined by
-+ * the content production in the XML grammar:
-+ *
-+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-+ *
-+ * Returns 0 if the chunk is well balanced, -1 in case of args problem and
-+ * the parser error code otherwise
-+ */
-+
-+int
-+xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
-+ void *user_data, int depth, const xmlChar *string, xmlNodePtr *list) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlDocPtr newDoc;
-+ xmlSAXHandlerPtr oldsax = NULL;
-+ int size;
-+ int ret = 0;
-+
-+ if (depth > 40) {
-+ return(XML_ERR_ENTITY_LOOP);
-+ }
-+
-+
-+ if (list != NULL)
-+ *list = NULL;
-+ if (string == NULL)
-+ return(-1);
-+
-+ size = xmlStrlen(string);
-+
-+ ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
-+ if (ctxt == NULL) return(-1);
-+ ctxt->userData = ctxt;
-+ if (sax != NULL) {
-+ oldsax = ctxt->sax;
-+ ctxt->sax = sax;
-+ if (user_data != NULL)
-+ ctxt->userData = user_data;
-+ }
-+ newDoc = xmlNewDoc(BAD_CAST "1.0");
-+ if (newDoc == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(-1);
-+ }
-+ if (doc != NULL) {
-+ newDoc->intSubset = doc->intSubset;
-+ newDoc->extSubset = doc->extSubset;
-+ }
-+ newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-+ if (newDoc->children == NULL) {
-+ if (sax != NULL)
-+ ctxt->sax = oldsax;
-+ xmlFreeParserCtxt(ctxt);
-+ newDoc->intSubset = NULL;
-+ newDoc->extSubset = NULL;
-+ xmlFreeDoc(newDoc);
-+ return(-1);
-+ }
-+ nodePush(ctxt, newDoc->children);
-+ if (doc == NULL) {
-+ ctxt->myDoc = newDoc;
-+ } else {
-+ ctxt->myDoc = doc;
-+ newDoc->children->doc = doc;
-+ }
-+ ctxt->instate = XML_PARSER_CONTENT;
-+ ctxt->depth = depth;
-+
-+ /*
-+ * Doing validity checking on chunk doesn't make sense
-+ */
-+ ctxt->validate = 0;
-+ ctxt->loadsubset = 0;
-+
-+ xmlParseContent(ctxt);
-+
-+ if ((RAW == '<') && (NXT(1) == '/')) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else if (RAW != 0) {
-+ ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "extra content at the end of well balanced chunk\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ if (ctxt->node != newDoc->children) {
-+ ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "chunk is not well balanced\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ if (!ctxt->wellFormed) {
-+ if (ctxt->errNo == 0)
-+ ret = 1;
-+ else
-+ ret = ctxt->errNo;
-+ } else {
-+ if (list != NULL) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Return the newly created nodeset after unlinking it from
-+ * they pseudo parent.
-+ */
-+ cur = newDoc->children->children;
-+ *list = cur;
-+ while (cur != NULL) {
-+ cur->parent = NULL;
-+ cur = cur->next;
-+ }
-+ newDoc->children->children = NULL;
-+ }
-+ ret = 0;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = oldsax;
-+ xmlFreeParserCtxt(ctxt);
-+ newDoc->intSubset = NULL;
-+ newDoc->extSubset = NULL;
-+ xmlFreeDoc(newDoc);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSAXParseEntity:
-+ * @sax: the SAX handler block
-+ * @filename: the filename
-+ *
-+ * parse an XML external entity out of context and build a tree.
-+ * It use the given SAX function block to handle the parsing callback.
-+ * If sax is NULL, fallback to the default DOM tree building routines.
-+ *
-+ * [78] extParsedEnt ::= TextDecl? content
-+ *
-+ * This correspond to a "Well Balanced" chunk
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
-+ xmlDocPtr ret;
-+ xmlParserCtxtPtr ctxt;
-+ char *directory = NULL;
-+
-+ ctxt = xmlCreateFileParserCtxt(filename);
-+ if (ctxt == NULL) {
-+ return(NULL);
-+ }
-+ if (sax != NULL) {
-+ if (ctxt->sax != NULL)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = sax;
-+ ctxt->userData = NULL;
-+ }
-+
-+ if ((ctxt->directory == NULL) && (directory == NULL))
-+ directory = xmlParserGetDirectory(filename);
-+
-+ xmlParseExtParsedEnt(ctxt);
-+
-+ if (ctxt->wellFormed)
-+ ret = ctxt->myDoc;
-+ else {
-+ ret = NULL;
-+ xmlFreeDoc(ctxt->myDoc);
-+ ctxt->myDoc = NULL;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseEntity:
-+ * @filename: the filename
-+ *
-+ * parse an XML external entity out of context and build a tree.
-+ *
-+ * [78] extParsedEnt ::= TextDecl? content
-+ *
-+ * This correspond to a "Well Balanced" chunk
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlParseEntity(const char *filename) {
-+ return(xmlSAXParseEntity(NULL, filename));
-+}
-+
-+/**
-+ * xmlCreateEntityParserCtxt:
-+ * @URL: the entity URL
-+ * @ID: the entity PUBLIC ID
-+ * @base: a posible base for the target URI
-+ *
-+ * Create a parser context for an external entity
-+ * Automatic support for ZLIB/Compress compressed document is provided
-+ * by default if found at compile-time.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+xmlParserCtxtPtr
-+xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
-+ const xmlChar *base) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr inputStream;
-+ char *directory = NULL;
-+ xmlChar *uri;
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL) {
-+ return(NULL);
-+ }
-+
-+ uri = xmlBuildURI(URL, base);
-+
-+ if (uri == NULL) {
-+ inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
-+ if (inputStream == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ inputPush(ctxt, inputStream);
-+
-+ if ((ctxt->directory == NULL) && (directory == NULL))
-+ directory = xmlParserGetDirectory((char *)URL);
-+ if ((ctxt->directory == NULL) && (directory != NULL))
-+ ctxt->directory = directory;
-+ } else {
-+ inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
-+ if (inputStream == NULL) {
-+ xmlFree(uri);
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ inputPush(ctxt, inputStream);
-+
-+ if ((ctxt->directory == NULL) && (directory == NULL))
-+ directory = xmlParserGetDirectory((char *)uri);
-+ if ((ctxt->directory == NULL) && (directory != NULL))
-+ ctxt->directory = directory;
-+ xmlFree(uri);
-+ }
-+
-+ return(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Front ends when parsing from a file *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlCreateFileParserCtxt:
-+ * @filename: the filename
-+ *
-+ * Create a parser context for a file content.
-+ * Automatic support for ZLIB/Compress compressed document is provided
-+ * by default if found at compile-time.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+xmlParserCtxtPtr
-+xmlCreateFileParserCtxt(const char *filename)
-+{
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr inputStream;
-+ xmlParserInputBufferPtr buf;
-+ char *directory = NULL;
-+
-+ buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-+ if (buf == NULL) {
-+ return(NULL);
-+ }
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL) {
-+ if (xmlDefaultSAXHandler.error != NULL) {
-+ xmlDefaultSAXHandler.error(NULL, "out of memory\n");
-+ }
-+ return(NULL);
-+ }
-+
-+ inputStream = xmlNewInputStream(ctxt);
-+ if (inputStream == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ inputStream->filename = xmlMemStrdup(filename);
-+ inputStream->buf = buf;
-+ inputStream->base = inputStream->buf->buffer->content;
-+ inputStream->cur = inputStream->buf->buffer->content;
-+
-+ inputPush(ctxt, inputStream);
-+ if ((ctxt->directory == NULL) && (directory == NULL))
-+ directory = xmlParserGetDirectory(filename);
-+ if ((ctxt->directory == NULL) && (directory != NULL))
-+ ctxt->directory = directory;
-+
-+ return(ctxt);
-+}
-+
-+/**
-+ * xmlSAXParseFile:
-+ * @sax: the SAX handler block
-+ * @filename: the filename
-+ * @recovery: work in recovery mode, i.e. tries to read no Well Formed
-+ * documents
-+ *
-+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
-+ * compressed document is provided by default if found at compile-time.
-+ * It use the given SAX function block to handle the parsing callback.
-+ * If sax is NULL, fallback to the default DOM tree building routines.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
-+ int recovery) {
-+ xmlDocPtr ret;
-+ xmlParserCtxtPtr ctxt;
-+ char *directory = NULL;
-+
-+ ctxt = xmlCreateFileParserCtxt(filename);
-+ if (ctxt == NULL) {
-+ return(NULL);
-+ }
-+ if (sax != NULL) {
-+ if (ctxt->sax != NULL)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = sax;
-+ ctxt->userData = NULL;
-+ }
-+
-+ if ((ctxt->directory == NULL) && (directory == NULL))
-+ directory = xmlParserGetDirectory(filename);
-+ if ((ctxt->directory == NULL) && (directory != NULL))
-+ ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
-+
-+ xmlParseDocument(ctxt);
-+
-+ if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
-+ else {
-+ ret = NULL;
-+ xmlFreeDoc(ctxt->myDoc);
-+ ctxt->myDoc = NULL;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlRecoverDoc:
-+ * @cur: a pointer to an array of xmlChar
-+ *
-+ * parse an XML in-memory document and build a tree.
-+ * In the case the document is not Well Formed, a tree is built anyway
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlRecoverDoc(xmlChar *cur) {
-+ return(xmlSAXParseDoc(NULL, cur, 1));
-+}
-+
-+/**
-+ * xmlParseFile:
-+ * @filename: the filename
-+ *
-+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
-+ * compressed document is provided by default if found at compile-time.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlParseFile(const char *filename) {
-+ return(xmlSAXParseFile(NULL, filename, 0));
-+}
-+
-+/**
-+ * xmlRecoverFile:
-+ * @filename: the filename
-+ *
-+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
-+ * compressed document is provided by default if found at compile-time.
-+ * In the case the document is not Well Formed, a tree is built anyway
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlRecoverFile(const char *filename) {
-+ return(xmlSAXParseFile(NULL, filename, 1));
-+}
-+
-+
-+/**
-+ * xmlSetupParserForBuffer:
-+ * @ctxt: an XML parser context
-+ * @buffer: a xmlChar * buffer
-+ * @filename: a file name
-+ *
-+ * Setup the parser context to parse a new buffer; Clears any prior
-+ * contents from the parser context. The buffer parameter must not be
-+ * NULL, but the filename parameter can be
-+ */
-+void
-+xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
-+ const char* filename)
-+{
-+ xmlParserInputPtr input;
-+
-+ input = xmlNewInputStream(ctxt);
-+ if (input == NULL) {
-+ perror("malloc");
-+ xmlFree(ctxt);
-+ return;
-+ }
-+
-+ xmlClearParserCtxt(ctxt);
-+ if (filename != NULL)
-+ input->filename = xmlMemStrdup(filename);
-+ input->base = buffer;
-+ input->cur = buffer;
-+ inputPush(ctxt, input);
-+}
-+
-+/**
-+ * xmlSAXUserParseFile:
-+ * @sax: a SAX handler
-+ * @user_data: The user data returned on SAX callbacks
-+ * @filename: a file name
-+ *
-+ * parse an XML file and call the given SAX handler routines.
-+ * Automatic support for ZLIB/Compress compressed document is provided
-+ *
-+ * Returns 0 in case of success or a error number otherwise
-+ */
-+int
-+xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
-+ const char *filename) {
-+ int ret = 0;
-+ xmlParserCtxtPtr ctxt;
-+
-+ ctxt = xmlCreateFileParserCtxt(filename);
-+ if (ctxt == NULL) return -1;
-+ if (ctxt->sax != &xmlDefaultSAXHandler)
-+ xmlFree(ctxt->sax);
-+ ctxt->sax = sax;
-+ if (user_data != NULL)
-+ ctxt->userData = user_data;
-+
-+ xmlParseDocument(ctxt);
-+
-+ if (ctxt->wellFormed)
-+ ret = 0;
-+ else {
-+ if (ctxt->errNo != 0)
-+ ret = ctxt->errNo;
-+ else
-+ ret = -1;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return ret;
-+}
-+
-+/************************************************************************
-+ * *
-+ * Front ends when parsing from memory *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlCreateMemoryParserCtxt:
-+ * @buffer: a pointer to a char array
-+ * @size: the size of the array
-+ *
-+ * Create a parser context for an XML in-memory document.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+xmlParserCtxtPtr
-+xmlCreateMemoryParserCtxt(char *buffer, int size) {
-+ xmlParserCtxtPtr ctxt;
-+ xmlParserInputPtr input;
-+ xmlParserInputBufferPtr buf;
-+
-+ if (buffer == NULL)
-+ return(NULL);
-+ if (size <= 0)
-+ return(NULL);
-+
-+ ctxt = xmlNewParserCtxt();
-+ if (ctxt == NULL)
-+ return(NULL);
-+
-+ buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
-+ if (buf == NULL) return(NULL);
-+
-+ input = xmlNewInputStream(ctxt);
-+ if (input == NULL) {
-+ xmlFreeParserCtxt(ctxt);
-+ return(NULL);
-+ }
-+
-+ input->filename = NULL;
-+ input->buf = buf;
-+ input->base = input->buf->buffer->content;
-+ input->cur = input->buf->buffer->content;
-+
-+ inputPush(ctxt, input);
-+ return(ctxt);
-+}
-+
-+/**
-+ * xmlSAXParseMemory:
-+ * @sax: the SAX handler block
-+ * @buffer: an pointer to a char array
-+ * @size: the size of the array
-+ * @recovery: work in recovery mode, i.e. tries to read not Well Formed
-+ * documents
-+ *
-+ * parse an XML in-memory block and use the given SAX function block
-+ * to handle the parsing callback. If sax is NULL, fallback to the default
-+ * DOM tree building routines.
-+ *
-+ * Returns the resulting document tree
-+ */
-+xmlDocPtr
-+xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer, int size, int recovery) {
-+ xmlDocPtr ret;
-+ xmlParserCtxtPtr ctxt;
-+
-+ ctxt = xmlCreateMemoryParserCtxt(buffer, size);
-+ if (ctxt == NULL) return(NULL);
-+ if (sax != NULL) {
-+ ctxt->sax = sax;
-+ ctxt->userData = NULL;
-+ }
-+
-+ xmlParseDocument(ctxt);
-+
-+ if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
-+ else {
-+ ret = NULL;
-+ xmlFreeDoc(ctxt->myDoc);
-+ ctxt->myDoc = NULL;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseMemory:
-+ * @buffer: an pointer to a char array
-+ * @size: the size of the array
-+ *
-+ * parse an XML in-memory block and build a tree.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr xmlParseMemory(char *buffer, int size) {
-+ return(xmlSAXParseMemory(NULL, buffer, size, 0));
-+}
-+
-+/**
-+ * xmlRecoverMemory:
-+ * @buffer: an pointer to a char array
-+ * @size: the size of the array
-+ *
-+ * parse an XML in-memory block and build a tree.
-+ * In the case the document is not Well Formed, a tree is built anyway
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr xmlRecoverMemory(char *buffer, int size) {
-+ return(xmlSAXParseMemory(NULL, buffer, size, 1));
-+}
-+
-+/**
-+ * xmlSAXUserParseMemory:
-+ * @sax: a SAX handler
-+ * @user_data: The user data returned on SAX callbacks
-+ * @buffer: an in-memory XML document input
-+ * @size: the length of the XML document in bytes
-+ *
-+ * A better SAX parsing routine.
-+ * parse an XML in-memory buffer and call the given SAX handler routines.
-+ *
-+ * Returns 0 in case of success or a error number otherwise
-+ */
-+int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
-+ char *buffer, int size) {
-+ int ret = 0;
-+ xmlParserCtxtPtr ctxt;
-+ xmlSAXHandlerPtr oldsax = NULL;
-+
-+ ctxt = xmlCreateMemoryParserCtxt(buffer, size);
-+ if (ctxt == NULL) return -1;
-+ if (sax != NULL) {
-+ oldsax = ctxt->sax;
-+ ctxt->sax = sax;
-+ }
-+ ctxt->userData = user_data;
-+
-+ xmlParseDocument(ctxt);
-+
-+ if (ctxt->wellFormed)
-+ ret = 0;
-+ else {
-+ if (ctxt->errNo != 0)
-+ ret = ctxt->errNo;
-+ else
-+ ret = -1;
-+ }
-+ if (sax != NULL) {
-+ ctxt->sax = oldsax;
-+ }
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return ret;
-+}
-+
-+/**
-+ * xmlCreateDocParserCtxt:
-+ * @cur: a pointer to an array of xmlChar
-+ *
-+ * Creates a parser context for an XML in-memory document.
-+ *
-+ * Returns the new parser context or NULL
-+ */
-+xmlParserCtxtPtr
-+xmlCreateDocParserCtxt(xmlChar *cur) {
-+ int len;
-+
-+ if (cur == NULL)
-+ return(NULL);
-+ len = xmlStrlen(cur);
-+ return(xmlCreateMemoryParserCtxt((char *)cur, len));
-+}
-+
-+/**
-+ * xmlSAXParseDoc:
-+ * @sax: the SAX handler block
-+ * @cur: a pointer to an array of xmlChar
-+ * @recovery: work in recovery mode, i.e. tries to read no Well Formed
-+ * documents
-+ *
-+ * parse an XML in-memory document and build a tree.
-+ * It use the given SAX function block to handle the parsing callback.
-+ * If sax is NULL, fallback to the default DOM tree building routines.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
-+ xmlDocPtr ret;
-+ xmlParserCtxtPtr ctxt;
-+
-+ if (cur == NULL) return(NULL);
-+
-+
-+ ctxt = xmlCreateDocParserCtxt(cur);
-+ if (ctxt == NULL) return(NULL);
-+ if (sax != NULL) {
-+ ctxt->sax = sax;
-+ ctxt->userData = NULL;
-+ }
-+
-+ xmlParseDocument(ctxt);
-+ if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
-+ else {
-+ ret = NULL;
-+ xmlFreeDoc(ctxt->myDoc);
-+ ctxt->myDoc = NULL;
-+ }
-+ if (sax != NULL)
-+ ctxt->sax = NULL;
-+ xmlFreeParserCtxt(ctxt);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseDoc:
-+ * @cur: a pointer to an array of xmlChar
-+ *
-+ * parse an XML in-memory document and build a tree.
-+ *
-+ * Returns the resulting document tree
-+ */
-+
-+xmlDocPtr
-+xmlParseDoc(xmlChar *cur) {
-+ return(xmlSAXParseDoc(NULL, cur, 0));
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Miscellaneous *
-+ * *
-+ ************************************************************************/
-+
-+#ifdef LIBXML_XPATH_ENABLED
-+#include <libxml/xpath.h>
-+#endif
-+
-+static int xmlParserInitialized = 0;
-+
-+/**
-+ * xmlInitParser:
-+ *
-+ * Initialization function for the XML parser.
-+ * This is not reentrant. Call once before processing in case of
-+ * use in multithreaded programs.
-+ */
-+
-+void
-+xmlInitParser(void) {
-+ if (xmlParserInitialized) return;
-+
-+ xmlInitCharEncodingHandlers();
-+ xmlInitializePredefinedEntities();
-+ xmlDefaultSAXHandlerInit();
-+ xmlRegisterDefaultInputCallbacks();
-+ xmlRegisterDefaultOutputCallbacks();
-+#ifdef LIBXML_HTML_ENABLED
-+ htmlInitAutoClose();
-+ htmlDefaultSAXHandlerInit();
-+#endif
-+#ifdef LIBXML_XPATH_ENABLED
-+ xmlXPathInit();
-+#endif
-+ xmlParserInitialized = 1;
-+}
-+
-+/**
-+ * xmlCleanupParser:
-+ *
-+ * Cleanup function for the XML parser. It tries to reclaim all
-+ * parsing related global memory allocated for the parser processing.
-+ * It doesn't deallocate any document related memory. Calling this
-+ * function should not prevent reusing the parser.
-+ */
-+
-+void
-+xmlCleanupParser(void) {
-+ xmlParserInitialized = 0;
-+ xmlCleanupCharEncodingHandlers();
-+ xmlCleanupPredefinedEntities();
-+}
-+
-+/**
-+ * xmlPedanticParserDefault:
-+ * @val: int 0 or 1
-+ *
-+ * Set and return the previous value for enabling pedantic warnings.
-+ *
-+ * Returns the last value for 0 for no substitution, 1 for substitution.
-+ */
-+
-+int
-+xmlPedanticParserDefault(int val) {
-+ int old = xmlPedanticParserDefaultValue;
-+
-+ xmlPedanticParserDefaultValue = val;
-+ return(old);
-+}
-+
-+/**
-+ * xmlSubstituteEntitiesDefault:
-+ * @val: int 0 or 1
-+ *
-+ * Set and return the previous value for default entity support.
-+ * Initially the parser always keep entity references instead of substituting
-+ * entity values in the output. This function has to be used to change the
-+ * default parser behaviour
-+ * SAX::subtituteEntities() has to be used for changing that on a file by
-+ * file basis.
-+ *
-+ * Returns the last value for 0 for no substitution, 1 for substitution.
-+ */
-+
-+int
-+xmlSubstituteEntitiesDefault(int val) {
-+ int old = xmlSubstituteEntitiesDefaultValue;
-+
-+ xmlSubstituteEntitiesDefaultValue = val;
-+ return(old);
-+}
-+
-+/**
-+ * xmlKeepBlanksDefault:
-+ * @val: int 0 or 1
-+ *
-+ * Set and return the previous value for default blanks text nodes support.
-+ * The 1.x version of the parser used an heuristic to try to detect
-+ * ignorable white spaces. As a result the SAX callback was generating
-+ * ignorableWhitespace() callbacks instead of characters() one, and when
-+ * using the DOM output text nodes containing those blanks were not generated.
-+ * The 2.x and later version will switch to the XML standard way and
-+ * ignorableWhitespace() are only generated when running the parser in
-+ * validating mode and when the current element doesn't allow CDATA or
-+ * mixed content.
-+ * This function is provided as a way to force the standard behaviour
-+ * on 1.X libs and to switch back to the old mode for compatibility when
-+ * running 1.X client code on 2.X . Upgrade of 1.X code should be done
-+ * by using xmlIsBlankNode() commodity function to detect the "empty"
-+ * nodes generated.
-+ * This value also affect autogeneration of indentation when saving code
-+ * if blanks sections are kept, indentation is not generated.
-+ *
-+ * Returns the last value for 0 for no substitution, 1 for substitution.
-+ */
-+
-+int
-+xmlKeepBlanksDefault(int val) {
-+ int old = xmlKeepBlanksDefaultValue;
-+
-+ xmlKeepBlanksDefaultValue = val;
-+ xmlIndentTreeOutput = !val;
-+ return(old);
-+}
-+
-diff -Nru libxml2-2.3.0/libxml/parser.h libxml2-2.3.0.new/libxml/parser.h
---- libxml2-2.3.0/libxml/parser.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/parser.h Mon Feb 12 04:07:27 2001
-@@ -0,0 +1,527 @@
-+/*
-+ * parser.h : Interfaces, constants and types related to the XML parser.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_PARSER_H__
-+#define __XML_PARSER_H__
-+
-+#include <libxml/tree.h>
-+#include <libxml/valid.h>
-+#include <libxml/xmlIO.h>
-+#include <libxml/entities.h>
-+
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * Constants.
-+ */
-+#define XML_DEFAULT_VERSION "1.0"
-+
-+/**
-+ * an xmlParserInput is an input flow for the XML processor.
-+ * Each entity parsed is associated an xmlParserInput (except the
-+ * few predefined ones). This is the case both for internal entities
-+ * - in which case the flow is already completely in memory - or
-+ * external entities - in which case we use the buf structure for
-+ * progressive reading and I18N conversions to the internal UTF-8 format.
-+ */
-+
-+typedef void (* xmlParserInputDeallocate)(xmlChar *);
-+typedef struct _xmlParserInput xmlParserInput;
-+typedef xmlParserInput *xmlParserInputPtr;
-+struct _xmlParserInput {
-+ /* Input buffer */
-+ xmlParserInputBufferPtr buf; /* UTF-8 encoded buffer */
-+
-+ const char *filename; /* The file analyzed, if any */
-+ const char *directory; /* the directory/base of teh file */
-+ const xmlChar *base; /* Base of the array to parse */
-+ const xmlChar *cur; /* Current char being parsed */
-+ int length; /* length if known */
-+ int line; /* Current line */
-+ int col; /* Current column */
-+ int consumed; /* How many xmlChars already consumed */
-+ xmlParserInputDeallocate free; /* function to deallocate the base */
-+ const xmlChar *encoding; /* the encoding string for entity */
-+ const xmlChar *version; /* the version string for entity */
-+ int standalone; /* Was that entity marked standalone */
-+};
-+
-+/**
-+ * the parser can be asked to collect Node informations, i.e. at what
-+ * place in the file they were detected.
-+ * NOTE: This is off by default and not very well tested.
-+ */
-+typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
-+typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;
-+
-+struct _xmlParserNodeInfo {
-+ const struct _xmlNode* node;
-+ /* Position & line # that text that created the node begins & ends on */
-+ unsigned long begin_pos;
-+ unsigned long begin_line;
-+ unsigned long end_pos;
-+ unsigned long end_line;
-+};
-+
-+typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
-+typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
-+struct _xmlParserNodeInfoSeq {
-+ unsigned long maximum;
-+ unsigned long length;
-+ xmlParserNodeInfo* buffer;
-+};
-+
-+/**
-+ * The parser is now working also as a state based parser
-+ * The recursive one use the stagte info for entities processing
-+ */
-+typedef enum {
-+ XML_PARSER_EOF = -1, /* nothing is to be parsed */
-+ XML_PARSER_START = 0, /* nothing has been parsed */
-+ XML_PARSER_MISC, /* Misc* before int subset */
-+ XML_PARSER_PI, /* Whithin a processing instruction */
-+ XML_PARSER_DTD, /* within some DTD content */
-+ XML_PARSER_PROLOG, /* Misc* after internal subset */
-+ XML_PARSER_COMMENT, /* within a comment */
-+ XML_PARSER_START_TAG, /* within a start tag */
-+ XML_PARSER_CONTENT, /* within the content */
-+ XML_PARSER_CDATA_SECTION, /* within a CDATA section */
-+ XML_PARSER_END_TAG, /* within a closing tag */
-+ XML_PARSER_ENTITY_DECL, /* within an entity declaration */
-+ XML_PARSER_ENTITY_VALUE, /* within an entity value in a decl */
-+ XML_PARSER_ATTRIBUTE_VALUE, /* within an attribute value */
-+ XML_PARSER_SYSTEM_LITERAL, /* within a SYSTEM value */
-+ XML_PARSER_EPILOG, /* the Misc* after the last end tag */
-+ XML_PARSER_IGNORE /* within an IGNORED section */
-+} xmlParserInputState;
-+
-+/**
-+ * The parser context.
-+ * NOTE This doesn't completely defines the parser state, the (current ?)
-+ * design of the parser uses recursive function calls since this allow
-+ * and easy mapping from the production rules of the specification
-+ * to the actual code. The drawback is that the actual function call
-+ * also reflect the parser state. However most of the parsing routines
-+ * takes as the only argument the parser context pointer, so migrating
-+ * to a state based parser for progressive parsing shouldn't be too hard.
-+ */
-+typedef struct _xmlParserCtxt xmlParserCtxt;
-+typedef xmlParserCtxt *xmlParserCtxtPtr;
-+struct _xmlParserCtxt {
-+ struct _xmlSAXHandler *sax; /* The SAX handler */
-+ void *userData; /* For SAX interface only, used by DOM build */
-+ xmlDocPtr myDoc; /* the document being built */
-+ int wellFormed; /* is the document well formed */
-+ int replaceEntities; /* shall we replace entities ? */
-+ const xmlChar *version; /* the XML version string */
-+ const xmlChar *encoding; /* the declared encoding, if any */
-+ int standalone; /* standalone document */
-+ int html; /* an HTML(1)/Docbook(2) document */
-+
-+ /* Input stream stack */
-+ xmlParserInputPtr input; /* Current input stream */
-+ int inputNr; /* Number of current input streams */
-+ int inputMax; /* Max number of input streams */
-+ xmlParserInputPtr *inputTab; /* stack of inputs */
-+
-+ /* Node analysis stack only used for DOM building */
-+ xmlNodePtr node; /* Current parsed Node */
-+ int nodeNr; /* Depth of the parsing stack */
-+ int nodeMax; /* Max depth of the parsing stack */
-+ xmlNodePtr *nodeTab; /* array of nodes */
-+
-+ int record_info; /* Whether node info should be kept */
-+ xmlParserNodeInfoSeq node_seq; /* info about each node parsed */
-+
-+ int errNo; /* error code */
-+
-+ int hasExternalSubset; /* reference and external subset */
-+ int hasPErefs; /* the internal subset has PE refs */
-+ int external; /* are we parsing an external entity */
-+
-+ int valid; /* is the document valid */
-+ int validate; /* shall we try to validate ? */
-+ xmlValidCtxt vctxt; /* The validity context */
-+
-+ xmlParserInputState instate; /* current type of input */
-+ int token; /* next char look-ahead */
-+
-+ char *directory; /* the data directory */
-+
-+ /* Node name stack */
-+ xmlChar *name; /* Current parsed Node */
-+ int nameNr; /* Depth of the parsing stack */
-+ int nameMax; /* Max depth of the parsing stack */
-+ xmlChar * *nameTab; /* array of nodes */
-+
-+ long nbChars; /* number of xmlChar processed */
-+ long checkIndex; /* used by progressive parsing lookup */
-+ int keepBlanks; /* ugly but ... */
-+ int disableSAX; /* SAX callbacks are disabled */
-+ int inSubset; /* Parsing is in int 1/ext 2 subset */
-+ xmlChar * intSubName; /* name of subset */
-+ xmlChar * extSubURI; /* URI of external subset */
-+ xmlChar * extSubSystem; /* SYSTEM ID of external subset */
-+
-+ /* xml:space values */
-+ int * space; /* Should the parser preserve spaces */
-+ int spaceNr; /* Depth of the parsing stack */
-+ int spaceMax; /* Max depth of the parsing stack */
-+ int * spaceTab; /* array of space infos */
-+
-+ int depth; /* to prevent entity substitution loops */
-+ xmlParserInputPtr entity; /* used to check entities boundaries */
-+ int charset; /* encoding of the in-memory content
-+ actually an xmlCharEncoding */
-+ int nodelen; /* Those two fields are there to */
-+ int nodemem; /* Speed up large node parsing */
-+ int pedantic; /* signal pedantic warnings */
-+ void *_private; /* For user data, libxml won't touch it */
-+
-+ int loadsubset; /* should the external subset be loaded */
-+};
-+
-+/**
-+ * a SAX Locator.
-+ */
-+typedef struct _xmlSAXLocator xmlSAXLocator;
-+typedef xmlSAXLocator *xmlSAXLocatorPtr;
-+struct _xmlSAXLocator {
-+ const xmlChar *(*getPublicId)(void *ctx);
-+ const xmlChar *(*getSystemId)(void *ctx);
-+ int (*getLineNumber)(void *ctx);
-+ int (*getColumnNumber)(void *ctx);
-+};
-+
-+/**
-+ * a SAX handler is bunch of callbacks called by the parser when processing
-+ * of the input generate data or structure informations.
-+ */
-+
-+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (void *ctx,
-+ const xmlChar *publicId, const xmlChar *systemId);
-+typedef void (*internalSubsetSAXFunc) (void *ctx, const xmlChar *name,
-+ const xmlChar *ExternalID, const xmlChar *SystemID);
-+typedef void (*externalSubsetSAXFunc) (void *ctx, const xmlChar *name,
-+ const xmlChar *ExternalID, const xmlChar *SystemID);
-+typedef xmlEntityPtr (*getEntitySAXFunc) (void *ctx,
-+ const xmlChar *name);
-+typedef xmlEntityPtr (*getParameterEntitySAXFunc) (void *ctx,
-+ const xmlChar *name);
-+typedef void (*entityDeclSAXFunc) (void *ctx,
-+ const xmlChar *name, int type, const xmlChar *publicId,
-+ const xmlChar *systemId, xmlChar *content);
-+typedef void (*notationDeclSAXFunc)(void *ctx, const xmlChar *name,
-+ const xmlChar *publicId, const xmlChar *systemId);
-+typedef void (*attributeDeclSAXFunc)(void *ctx, const xmlChar *elem,
-+ const xmlChar *name, int type, int def,
-+ const xmlChar *defaultValue, xmlEnumerationPtr tree);
-+typedef void (*elementDeclSAXFunc)(void *ctx, const xmlChar *name,
-+ int type, xmlElementContentPtr content);
-+typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
-+ const xmlChar *name, const xmlChar *publicId,
-+ const xmlChar *systemId, const xmlChar *notationName);
-+typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
-+ xmlSAXLocatorPtr loc);
-+typedef void (*startDocumentSAXFunc) (void *ctx);
-+typedef void (*endDocumentSAXFunc) (void *ctx);
-+typedef void (*startElementSAXFunc) (void *ctx, const xmlChar *name,
-+ const xmlChar **atts);
-+typedef void (*endElementSAXFunc) (void *ctx, const xmlChar *name);
-+typedef void (*attributeSAXFunc) (void *ctx, const xmlChar *name,
-+ const xmlChar *value);
-+typedef void (*referenceSAXFunc) (void *ctx, const xmlChar *name);
-+typedef void (*charactersSAXFunc) (void *ctx, const xmlChar *ch,
-+ int len);
-+typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
-+ const xmlChar *ch, int len);
-+typedef void (*processingInstructionSAXFunc) (void *ctx,
-+ const xmlChar *target, const xmlChar *data);
-+typedef void (*commentSAXFunc) (void *ctx, const xmlChar *value);
-+typedef void (*cdataBlockSAXFunc) (void *ctx, const xmlChar *value, int len);
-+typedef void (*warningSAXFunc) (void *ctx, const char *msg, ...);
-+typedef void (*errorSAXFunc) (void *ctx, const char *msg, ...);
-+typedef void (*fatalErrorSAXFunc) (void *ctx, const char *msg, ...);
-+typedef int (*isStandaloneSAXFunc) (void *ctx);
-+typedef int (*hasInternalSubsetSAXFunc) (void *ctx);
-+typedef int (*hasExternalSubsetSAXFunc) (void *ctx);
-+
-+typedef struct _xmlSAXHandler xmlSAXHandler;
-+typedef xmlSAXHandler *xmlSAXHandlerPtr;
-+struct _xmlSAXHandler {
-+ internalSubsetSAXFunc internalSubset;
-+ isStandaloneSAXFunc isStandalone;
-+ hasInternalSubsetSAXFunc hasInternalSubset;
-+ hasExternalSubsetSAXFunc hasExternalSubset;
-+ resolveEntitySAXFunc resolveEntity;
-+ getEntitySAXFunc getEntity;
-+ entityDeclSAXFunc entityDecl;
-+ notationDeclSAXFunc notationDecl;
-+ attributeDeclSAXFunc attributeDecl;
-+ elementDeclSAXFunc elementDecl;
-+ unparsedEntityDeclSAXFunc unparsedEntityDecl;
-+ setDocumentLocatorSAXFunc setDocumentLocator;
-+ startDocumentSAXFunc startDocument;
-+ endDocumentSAXFunc endDocument;
-+ startElementSAXFunc startElement;
-+ endElementSAXFunc endElement;
-+ referenceSAXFunc reference;
-+ charactersSAXFunc characters;
-+ ignorableWhitespaceSAXFunc ignorableWhitespace;
-+ processingInstructionSAXFunc processingInstruction;
-+ commentSAXFunc comment;
-+ warningSAXFunc warning;
-+ errorSAXFunc error;
-+ fatalErrorSAXFunc fatalError;
-+ getParameterEntitySAXFunc getParameterEntity;
-+ cdataBlockSAXFunc cdataBlock;
-+ externalSubsetSAXFunc externalSubset;
-+};
-+
-+/**
-+ * External entity loaders types
-+ */
-+typedef xmlParserInputPtr (*xmlExternalEntityLoader)(const char *URL,
-+ const char *ID,
-+ xmlParserCtxtPtr context);
-+
-+/**
-+ * Global variables: just the default SAX interface tables and XML
-+ * version infos.
-+ */
-+LIBXML_DLL_IMPORT extern const char *xmlParserVersion;
-+
-+LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator;
-+LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler;
-+LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler;
-+LIBXML_DLL_IMPORT extern xmlSAXHandler sgmlDefaultSAXHandler;
-+
-+/**
-+ * entity substitution default behaviour.
-+ */
-+
-+#ifdef VMS
-+LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultVal;
-+#define xmlSubstituteEntitiesDefaultValue xmlSubstituteEntitiesDefaultVal
-+#else
-+LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
-+#endif
-+LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
-+
-+
-+/**
-+ * Init/Cleanup
-+ */
-+void xmlInitParser (void);
-+void xmlCleanupParser (void);
-+
-+/**
-+ * Input functions
-+ */
-+int xmlParserInputRead (xmlParserInputPtr in,
-+ int len);
-+int xmlParserInputGrow (xmlParserInputPtr in,
-+ int len);
-+
-+/**
-+ * xmlChar handling
-+ */
-+xmlChar * xmlStrdup (const xmlChar *cur);
-+xmlChar * xmlStrndup (const xmlChar *cur,
-+ int len);
-+xmlChar * xmlStrsub (const xmlChar *str,
-+ int start,
-+ int len);
-+const xmlChar * xmlStrchr (const xmlChar *str,
-+ xmlChar val);
-+const xmlChar * xmlStrstr (const xmlChar *str,
-+ xmlChar *val);
-+const xmlChar * xmlStrcasestr (const xmlChar *str,
-+ xmlChar *val);
-+int xmlStrcmp (const xmlChar *str1,
-+ const xmlChar *str2);
-+int xmlStrncmp (const xmlChar *str1,
-+ const xmlChar *str2,
-+ int len);
-+int xmlStrcasecmp (const xmlChar *str1,
-+ const xmlChar *str2);
-+int xmlStrncasecmp (const xmlChar *str1,
-+ const xmlChar *str2,
-+ int len);
-+int xmlStrEqual (const xmlChar *str1,
-+ const xmlChar *str2);
-+int xmlStrlen (const xmlChar *str);
-+xmlChar * xmlStrcat (xmlChar *cur,
-+ const xmlChar *add);
-+xmlChar * xmlStrncat (xmlChar *cur,
-+ const xmlChar *add,
-+ int len);
-+
-+/**
-+ * Basic parsing Interfaces
-+ */
-+xmlDocPtr xmlParseDoc (xmlChar *cur);
-+xmlDocPtr xmlParseMemory (char *buffer,
-+ int size);
-+xmlDocPtr xmlParseFile (const char *filename);
-+int xmlSubstituteEntitiesDefault(int val);
-+int xmlKeepBlanksDefault (int val);
-+void xmlStopParser (xmlParserCtxtPtr ctxt);
-+int xmlPedanticParserDefault(int val);
-+
-+/**
-+ * Recovery mode
-+ */
-+xmlDocPtr xmlRecoverDoc (xmlChar *cur);
-+xmlDocPtr xmlRecoverMemory (char *buffer,
-+ int size);
-+xmlDocPtr xmlRecoverFile (const char *filename);
-+
-+/**
-+ * Less common routines and SAX interfaces
-+ */
-+int xmlParseDocument (xmlParserCtxtPtr ctxt);
-+int xmlParseExtParsedEnt (xmlParserCtxtPtr ctxt);
-+xmlDocPtr xmlSAXParseDoc (xmlSAXHandlerPtr sax,
-+ xmlChar *cur,
-+ int recovery);
-+int xmlSAXUserParseFile (xmlSAXHandlerPtr sax,
-+ void *user_data,
-+ const char *filename);
-+int xmlSAXUserParseMemory (xmlSAXHandlerPtr sax,
-+ void *user_data,
-+ char *buffer,
-+ int size);
-+xmlDocPtr xmlSAXParseMemory (xmlSAXHandlerPtr sax,
-+ char *buffer,
-+ int size,
-+ int recovery);
-+xmlDocPtr xmlSAXParseFile (xmlSAXHandlerPtr sax,
-+ const char *filename,
-+ int recovery);
-+xmlDocPtr xmlSAXParseEntity (xmlSAXHandlerPtr sax,
-+ const char *filename);
-+xmlDocPtr xmlParseEntity (const char *filename);
-+xmlDtdPtr xmlParseDTD (const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+xmlDtdPtr xmlSAXParseDTD (xmlSAXHandlerPtr sax,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+xmlDtdPtr xmlIOParseDTD (xmlSAXHandlerPtr sax,
-+ xmlParserInputBufferPtr input,
-+ xmlCharEncoding enc);
-+int xmlParseBalancedChunkMemory(xmlDocPtr doc,
-+ xmlSAXHandlerPtr sax,
-+ void *user_data,
-+ int depth,
-+ const xmlChar *string,
-+ xmlNodePtr *list);
-+int xmlParseExternalEntity (xmlDocPtr doc,
-+ xmlSAXHandlerPtr sax,
-+ void *user_data,
-+ int depth,
-+ const xmlChar *URL,
-+ const xmlChar *ID,
-+ xmlNodePtr *list);
-+int xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx,
-+ const xmlChar *URL,
-+ const xmlChar *ID,
-+ xmlNodePtr *list);
-+
-+/**
-+ * SAX initialization routines
-+ */
-+void xmlDefaultSAXHandlerInit(void);
-+void htmlDefaultSAXHandlerInit(void);
-+
-+/**
-+ * Parser contexts handling.
-+ */
-+void xmlInitParserCtxt (xmlParserCtxtPtr ctxt);
-+void xmlClearParserCtxt (xmlParserCtxtPtr ctxt);
-+void xmlFreeParserCtxt (xmlParserCtxtPtr ctxt);
-+void xmlSetupParserForBuffer (xmlParserCtxtPtr ctxt,
-+ const xmlChar* buffer,
-+ const char* filename);
-+xmlParserCtxtPtr xmlCreateDocParserCtxt (xmlChar *cur);
-+
-+/**
-+ * Reading/setting optional parsing features.
-+ */
-+
-+int xmlGetFeaturesList (int *len,
-+ const char **result);
-+int xmlGetFeature (xmlParserCtxtPtr ctxt,
-+ const char *name,
-+ void *result);
-+int xmlSetFeature (xmlParserCtxtPtr ctxt,
-+ const char *name,
-+ void *value);
-+
-+/**
-+ * Interfaces for the Push mode
-+ */
-+xmlParserCtxtPtr xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax,
-+ void *user_data,
-+ const char *chunk,
-+ int size,
-+ const char *filename);
-+int xmlParseChunk (xmlParserCtxtPtr ctxt,
-+ const char *chunk,
-+ int size,
-+ int terminate);
-+
-+/**
-+ * Special I/O mode
-+ */
-+
-+xmlParserCtxtPtr xmlCreateIOParserCtxt (xmlSAXHandlerPtr sax,
-+ void *user_data,
-+ xmlInputReadCallback ioread,
-+ xmlInputCloseCallback ioclose,
-+ void *ioctx,
-+ xmlCharEncoding enc);
-+
-+xmlParserInputPtr xmlNewIOInputStream (xmlParserCtxtPtr ctxt,
-+ xmlParserInputBufferPtr input,
-+ xmlCharEncoding enc);
-+
-+/**
-+ * Node infos
-+ */
-+const xmlParserNodeInfo*
-+ xmlParserFindNodeInfo (const xmlParserCtxt* ctxt,
-+ const xmlNode* node);
-+void xmlInitNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
-+void xmlClearNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
-+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
-+ const xmlNode* node);
-+void xmlParserAddNodeInfo (xmlParserCtxtPtr ctxt,
-+ const xmlParserNodeInfo* info);
-+
-+/*
-+ * External entities handling actually implemented in xmlIO
-+ */
-+
-+void xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
-+xmlExternalEntityLoader
-+ xmlGetExternalEntityLoader(void);
-+xmlParserInputPtr
-+ xmlLoadExternalEntity (const char *URL,
-+ const char *ID,
-+ xmlParserCtxtPtr context);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __XML_PARSER_H__ */
-+
-diff -Nru libxml2-2.3.0/libxml/parserInternals.c libxml2-2.3.0.new/libxml/parserInternals.c
---- libxml2-2.3.0/libxml/parserInternals.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/parserInternals.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,3533 @@
-+/*
-+ * parser.c : Internal routines (and obsolete ones) needed for the
-+ * XML and HTML parsers.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#define XML_DIR_SEP '\\'
-+#else
-+#include "config.h"
-+#define XML_DIR_SEP '/'
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_ZLIB_H
-+#include <zlib.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/valid.h>
-+#include <libxml/entities.h>
-+#include <libxml/xmlerror.h>
-+#include <libxml/encoding.h>
-+#include <libxml/valid.h>
-+#include <libxml/xmlIO.h>
-+#include <libxml/uri.h>
-+
-+
-+/************************************************************************
-+ * *
-+ * Version and Features handling *
-+ * *
-+ ************************************************************************/
-+const char *xmlParserVersion = LIBXML_VERSION_STRING;
-+
-+/*
-+ * xmlCheckVersion:
-+ * @version: the include version number
-+ *
-+ * check the compiled lib version against the include one.
-+ * This can warn or immediately kill the application
-+ */
-+void
-+xmlCheckVersion(int version) {
-+ int myversion = (int) LIBXML_VERSION;
-+
-+ if ((myversion / 10000) != (version / 10000)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Fatal: program compiled against libxml %d using libxml %d\n",
-+ (version / 10000), (myversion / 10000));
-+ exit(1);
-+ }
-+ if ((myversion / 100) < (version / 100)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Warning: program compiled against libxml %d using older %d\n",
-+ (version / 100), (myversion / 100));
-+ }
-+}
-+
-+
-+const char *xmlFeaturesList[] = {
-+ "validate",
-+ "load subset",
-+ "keep blanks",
-+ "disable SAX",
-+ "fetch external entities",
-+ "substitute entities",
-+ "gather line info",
-+ "user data",
-+ "is html",
-+ "is standalone",
-+ "stop parser",
-+ "document",
-+ "is well formed",
-+ "is valid",
-+ "SAX block",
-+ "SAX function internalSubset",
-+ "SAX function isStandalone",
-+ "SAX function hasInternalSubset",
-+ "SAX function hasExternalSubset",
-+ "SAX function resolveEntity",
-+ "SAX function getEntity",
-+ "SAX function entityDecl",
-+ "SAX function notationDecl",
-+ "SAX function attributeDecl",
-+ "SAX function elementDecl",
-+ "SAX function unparsedEntityDecl",
-+ "SAX function setDocumentLocator",
-+ "SAX function startDocument",
-+ "SAX function endDocument",
-+ "SAX function startElement",
-+ "SAX function endElement",
-+ "SAX function reference",
-+ "SAX function characters",
-+ "SAX function ignorableWhitespace",
-+ "SAX function processingInstruction",
-+ "SAX function comment",
-+ "SAX function warning",
-+ "SAX function error",
-+ "SAX function fatalError",
-+ "SAX function getParameterEntity",
-+ "SAX function cdataBlock",
-+ "SAX function externalSubset",
-+};
-+
-+/*
-+ * xmlGetFeaturesList:
-+ * @len: the length of the features name array (input/output)
-+ * @result: an array of string to be filled with the features name.
-+ *
-+ * Copy at most *@len feature names into the @result array
-+ *
-+ * Returns -1 in case or error, or the total number of features,
-+ * len is updated with the number of strings copied,
-+ * strings must not be deallocated
-+ */
-+int
-+xmlGetFeaturesList(int *len, const char **result) {
-+ int ret, i;
-+
-+ ret = sizeof(xmlFeaturesList)/sizeof(xmlFeaturesList[0]);
-+ if ((len == NULL) || (result == NULL))
-+ return(ret);
-+ if ((*len < 0) || (*len >= 1000))
-+ return(-1);
-+ if (*len > ret)
-+ *len = ret;
-+ for (i = 0;i < *len;i++)
-+ result[i] = xmlFeaturesList[i];
-+ return(ret);
-+}
-+
-+/*
-+ * xmlGetFeature:
-+ * @ctxt: an XML/HTML parser context
-+ * @name: the feature name
-+ * @result: location to store the result
-+ *
-+ * Read the current value of one feature of this parser instance
-+ *
-+ * Returns -1 in case or error, 0 otherwise
-+ */
-+int
-+xmlGetFeature(xmlParserCtxtPtr ctxt, const char *name, void *result) {
-+ if ((ctxt == NULL) || (name == NULL) || (result == NULL))
-+ return(-1);
-+
-+ if (!strcmp(name, "validate")) {
-+ *((int *) result) = ctxt->validate;
-+ } else if (!strcmp(name, "keep blanks")) {
-+ *((int *) result) = ctxt->keepBlanks;
-+ } else if (!strcmp(name, "disable SAX")) {
-+ *((int *) result) = ctxt->disableSAX;
-+ } else if (!strcmp(name, "fetch external entities")) {
-+ *((int *) result) = ctxt->loadsubset;
-+ } else if (!strcmp(name, "substitute entities")) {
-+ *((int *) result) = ctxt->replaceEntities;
-+ } else if (!strcmp(name, "gather line info")) {
-+ *((int *) result) = ctxt->record_info;
-+ } else if (!strcmp(name, "user data")) {
-+ *((void **)result) = ctxt->userData;
-+ } else if (!strcmp(name, "is html")) {
-+ *((int *) result) = ctxt->html;
-+ } else if (!strcmp(name, "is standalone")) {
-+ *((int *) result) = ctxt->standalone;
-+ } else if (!strcmp(name, "document")) {
-+ *((xmlDocPtr *) result) = ctxt->myDoc;
-+ } else if (!strcmp(name, "is well formed")) {
-+ *((int *) result) = ctxt->wellFormed;
-+ } else if (!strcmp(name, "is valid")) {
-+ *((int *) result) = ctxt->valid;
-+ } else if (!strcmp(name, "SAX block")) {
-+ *((xmlSAXHandlerPtr *) result) = ctxt->sax;
-+ } else if (!strcmp(name, "SAX function internalSubset")) {
-+ *((internalSubsetSAXFunc *) result) = ctxt->sax->internalSubset;
-+ } else if (!strcmp(name, "SAX function isStandalone")) {
-+ *((isStandaloneSAXFunc *) result) = ctxt->sax->isStandalone;
-+ } else if (!strcmp(name, "SAX function hasInternalSubset")) {
-+ *((hasInternalSubsetSAXFunc *) result) = ctxt->sax->hasInternalSubset;
-+ } else if (!strcmp(name, "SAX function hasExternalSubset")) {
-+ *((hasExternalSubsetSAXFunc *) result) = ctxt->sax->hasExternalSubset;
-+ } else if (!strcmp(name, "SAX function resolveEntity")) {
-+ *((resolveEntitySAXFunc *) result) = ctxt->sax->resolveEntity;
-+ } else if (!strcmp(name, "SAX function getEntity")) {
-+ *((getEntitySAXFunc *) result) = ctxt->sax->getEntity;
-+ } else if (!strcmp(name, "SAX function entityDecl")) {
-+ *((entityDeclSAXFunc *) result) = ctxt->sax->entityDecl;
-+ } else if (!strcmp(name, "SAX function notationDecl")) {
-+ *((notationDeclSAXFunc *) result) = ctxt->sax->notationDecl;
-+ } else if (!strcmp(name, "SAX function attributeDecl")) {
-+ *((attributeDeclSAXFunc *) result) = ctxt->sax->attributeDecl;
-+ } else if (!strcmp(name, "SAX function elementDecl")) {
-+ *((elementDeclSAXFunc *) result) = ctxt->sax->elementDecl;
-+ } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
-+ *((unparsedEntityDeclSAXFunc *) result) = ctxt->sax->unparsedEntityDecl;
-+ } else if (!strcmp(name, "SAX function setDocumentLocator")) {
-+ *((setDocumentLocatorSAXFunc *) result) = ctxt->sax->setDocumentLocator;
-+ } else if (!strcmp(name, "SAX function startDocument")) {
-+ *((startDocumentSAXFunc *) result) = ctxt->sax->startDocument;
-+ } else if (!strcmp(name, "SAX function endDocument")) {
-+ *((endDocumentSAXFunc *) result) = ctxt->sax->endDocument;
-+ } else if (!strcmp(name, "SAX function startElement")) {
-+ *((startElementSAXFunc *) result) = ctxt->sax->startElement;
-+ } else if (!strcmp(name, "SAX function endElement")) {
-+ *((endElementSAXFunc *) result) = ctxt->sax->endElement;
-+ } else if (!strcmp(name, "SAX function reference")) {
-+ *((referenceSAXFunc *) result) = ctxt->sax->reference;
-+ } else if (!strcmp(name, "SAX function characters")) {
-+ *((charactersSAXFunc *) result) = ctxt->sax->characters;
-+ } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
-+ *((ignorableWhitespaceSAXFunc *) result) = ctxt->sax->ignorableWhitespace;
-+ } else if (!strcmp(name, "SAX function processingInstruction")) {
-+ *((processingInstructionSAXFunc *) result) = ctxt->sax->processingInstruction;
-+ } else if (!strcmp(name, "SAX function comment")) {
-+ *((commentSAXFunc *) result) = ctxt->sax->comment;
-+ } else if (!strcmp(name, "SAX function warning")) {
-+ *((warningSAXFunc *) result) = ctxt->sax->warning;
-+ } else if (!strcmp(name, "SAX function error")) {
-+ *((errorSAXFunc *) result) = ctxt->sax->error;
-+ } else if (!strcmp(name, "SAX function fatalError")) {
-+ *((fatalErrorSAXFunc *) result) = ctxt->sax->fatalError;
-+ } else if (!strcmp(name, "SAX function getParameterEntity")) {
-+ *((getParameterEntitySAXFunc *) result) = ctxt->sax->getParameterEntity;
-+ } else if (!strcmp(name, "SAX function cdataBlock")) {
-+ *((cdataBlockSAXFunc *) result) = ctxt->sax->cdataBlock;
-+ } else if (!strcmp(name, "SAX function externalSubset")) {
-+ *((externalSubsetSAXFunc *) result) = ctxt->sax->externalSubset;
-+ } else {
-+ return(-1);
-+ }
-+ return(0);
-+}
-+
-+/*
-+ * xmlSetFeature:
-+ * @ctxt: an XML/HTML parser context
-+ * @name: the feature name
-+ * @value: pointer to the location of the new value
-+ *
-+ * Change the current value of one feature of this parser instance
-+ *
-+ * Returns -1 in case or error, 0 otherwise
-+ */
-+int
-+xmlSetFeature(xmlParserCtxtPtr ctxt, const char *name, void *value) {
-+ if ((ctxt == NULL) || (name == NULL) || (value == NULL))
-+ return(-1);
-+
-+ if (!strcmp(name, "validate")) {
-+ int newvalidate = *((int *) value);
-+ if ((!ctxt->validate) && (newvalidate != 0)) {
-+ if (ctxt->vctxt.warning == NULL)
-+ ctxt->vctxt.warning = xmlParserValidityWarning;
-+ if (ctxt->vctxt.error == NULL)
-+ ctxt->vctxt.error = xmlParserValidityError;
-+ /* Allocate the Node stack */
-+ ctxt->vctxt.nodeTab = (xmlNodePtr *)
-+ xmlMalloc(4 * sizeof(xmlNodePtr));
-+ if (ctxt->vctxt.nodeTab == NULL) {
-+ ctxt->vctxt.nodeMax = 0;
-+ ctxt->validate = 0;
-+ return(-1);
-+ }
-+ ctxt->vctxt.nodeNr = 0;
-+ ctxt->vctxt.nodeMax = 4;
-+ ctxt->vctxt.node = NULL;
-+ }
-+ ctxt->validate = newvalidate;
-+ } else if (!strcmp(name, "keep blanks")) {
-+ ctxt->keepBlanks = *((int *) value);
-+ } else if (!strcmp(name, "disable SAX")) {
-+ ctxt->disableSAX = *((int *) value);
-+ } else if (!strcmp(name, "fetch external entities")) {
-+ ctxt->loadsubset = *((int *) value);
-+ } else if (!strcmp(name, "substitute entities")) {
-+ ctxt->replaceEntities = *((int *) value);
-+ } else if (!strcmp(name, "gather line info")) {
-+ ctxt->record_info = *((int *) value);
-+ } else if (!strcmp(name, "user data")) {
-+ ctxt->userData = *((void **)value);
-+ } else if (!strcmp(name, "is html")) {
-+ ctxt->html = *((int *) value);
-+ } else if (!strcmp(name, "is standalone")) {
-+ ctxt->standalone = *((int *) value);
-+ } else if (!strcmp(name, "document")) {
-+ ctxt->myDoc = *((xmlDocPtr *) value);
-+ } else if (!strcmp(name, "is well formed")) {
-+ ctxt->wellFormed = *((int *) value);
-+ } else if (!strcmp(name, "is valid")) {
-+ ctxt->valid = *((int *) value);
-+ } else if (!strcmp(name, "SAX block")) {
-+ ctxt->sax = *((xmlSAXHandlerPtr *) value);
-+ } else if (!strcmp(name, "SAX function internalSubset")) {
-+ ctxt->sax->internalSubset = *((internalSubsetSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function isStandalone")) {
-+ ctxt->sax->isStandalone = *((isStandaloneSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function hasInternalSubset")) {
-+ ctxt->sax->hasInternalSubset = *((hasInternalSubsetSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function hasExternalSubset")) {
-+ ctxt->sax->hasExternalSubset = *((hasExternalSubsetSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function resolveEntity")) {
-+ ctxt->sax->resolveEntity = *((resolveEntitySAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function getEntity")) {
-+ ctxt->sax->getEntity = *((getEntitySAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function entityDecl")) {
-+ ctxt->sax->entityDecl = *((entityDeclSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function notationDecl")) {
-+ ctxt->sax->notationDecl = *((notationDeclSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function attributeDecl")) {
-+ ctxt->sax->attributeDecl = *((attributeDeclSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function elementDecl")) {
-+ ctxt->sax->elementDecl = *((elementDeclSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
-+ ctxt->sax->unparsedEntityDecl = *((unparsedEntityDeclSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function setDocumentLocator")) {
-+ ctxt->sax->setDocumentLocator = *((setDocumentLocatorSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function startDocument")) {
-+ ctxt->sax->startDocument = *((startDocumentSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function endDocument")) {
-+ ctxt->sax->endDocument = *((endDocumentSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function startElement")) {
-+ ctxt->sax->startElement = *((startElementSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function endElement")) {
-+ ctxt->sax->endElement = *((endElementSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function reference")) {
-+ ctxt->sax->reference = *((referenceSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function characters")) {
-+ ctxt->sax->characters = *((charactersSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
-+ ctxt->sax->ignorableWhitespace = *((ignorableWhitespaceSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function processingInstruction")) {
-+ ctxt->sax->processingInstruction = *((processingInstructionSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function comment")) {
-+ ctxt->sax->comment = *((commentSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function warning")) {
-+ ctxt->sax->warning = *((warningSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function error")) {
-+ ctxt->sax->error = *((errorSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function fatalError")) {
-+ ctxt->sax->fatalError = *((fatalErrorSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function getParameterEntity")) {
-+ ctxt->sax->getParameterEntity = *((getParameterEntitySAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function cdataBlock")) {
-+ ctxt->sax->cdataBlock = *((cdataBlockSAXFunc *) value);
-+ } else if (!strcmp(name, "SAX function externalSubset")) {
-+ ctxt->sax->externalSubset = *((externalSubsetSAXFunc *) value);
-+ } else {
-+ return(-1);
-+ }
-+ return(0);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Some functions to avoid too large macros *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlIsChar:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-+ * | [#x10000-#x10FFFF]
-+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
-+ * Also available as a macro IS_CHAR()
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsChar(int c) {
-+ return(
-+ ((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) ||
-+ (((c) >= 0x20) && ((c) <= 0xD7FF)) ||
-+ (((c) >= 0xE000) && ((c) <= 0xFFFD)) ||
-+ (((c) >= 0x10000) && ((c) <= 0x10FFFF)));
-+}
-+
-+/**
-+ * xmlIsBlank:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
-+ * Also available as a macro IS_BLANK()
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsBlank(int c) {
-+ return(((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || ((c) == 0x0D));
-+}
-+
-+/**
-+ * xmlIsBaseChar:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [85] BaseChar ::= ... long list see REC ...
-+ *
-+ * VI is your friend !
-+ * :1,$ s/\[#x\([0-9A-Z]*\)-#x\([0-9A-Z]*\)\]/ (((c) >= 0x\1) \&\& ((c) <= 0x\2)) ||/
-+ * and
-+ * :1,$ s/#x\([0-9A-Z]*\)/ ((c) == 0x\1) ||/
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+static int xmlBaseArray[] = {
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0000 - 0x000F */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0010 - 0x001F */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0020 - 0x002F */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0030 - 0x003F */
-+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0040 - 0x004F */
-+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x0050 - 0x005F */
-+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0060 - 0x006F */
-+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x0070 - 0x007F */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0080 - 0x008F */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0090 - 0x009F */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00A0 - 0x00AF */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00B0 - 0x00BF */
-+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00C0 - 0x00CF */
-+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00D0 - 0x00DF */
-+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00E0 - 0x00EF */
-+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00F0 - 0x00FF */
-+};
-+
-+int
-+xmlIsBaseChar(int c) {
-+ return(
-+ (((c) < 0x0100) ? xmlBaseArray[c] :
-+ ( /* accelerator */
-+ (((c) >= 0x0100) && ((c) <= 0x0131)) ||
-+ (((c) >= 0x0134) && ((c) <= 0x013E)) ||
-+ (((c) >= 0x0141) && ((c) <= 0x0148)) ||
-+ (((c) >= 0x014A) && ((c) <= 0x017E)) ||
-+ (((c) >= 0x0180) && ((c) <= 0x01C3)) ||
-+ (((c) >= 0x01CD) && ((c) <= 0x01F0)) ||
-+ (((c) >= 0x01F4) && ((c) <= 0x01F5)) ||
-+ (((c) >= 0x01FA) && ((c) <= 0x0217)) ||
-+ (((c) >= 0x0250) && ((c) <= 0x02A8)) ||
-+ (((c) >= 0x02BB) && ((c) <= 0x02C1)) ||
-+ ((c) == 0x0386) ||
-+ (((c) >= 0x0388) && ((c) <= 0x038A)) ||
-+ ((c) == 0x038C) ||
-+ (((c) >= 0x038E) && ((c) <= 0x03A1)) ||
-+ (((c) >= 0x03A3) && ((c) <= 0x03CE)) ||
-+ (((c) >= 0x03D0) && ((c) <= 0x03D6)) ||
-+ ((c) == 0x03DA) ||
-+ ((c) == 0x03DC) ||
-+ ((c) == 0x03DE) ||
-+ ((c) == 0x03E0) ||
-+ (((c) >= 0x03E2) && ((c) <= 0x03F3)) ||
-+ (((c) >= 0x0401) && ((c) <= 0x040C)) ||
-+ (((c) >= 0x040E) && ((c) <= 0x044F)) ||
-+ (((c) >= 0x0451) && ((c) <= 0x045C)) ||
-+ (((c) >= 0x045E) && ((c) <= 0x0481)) ||
-+ (((c) >= 0x0490) && ((c) <= 0x04C4)) ||
-+ (((c) >= 0x04C7) && ((c) <= 0x04C8)) ||
-+ (((c) >= 0x04CB) && ((c) <= 0x04CC)) ||
-+ (((c) >= 0x04D0) && ((c) <= 0x04EB)) ||
-+ (((c) >= 0x04EE) && ((c) <= 0x04F5)) ||
-+ (((c) >= 0x04F8) && ((c) <= 0x04F9)) ||
-+ (((c) >= 0x0531) && ((c) <= 0x0556)) ||
-+ ((c) == 0x0559) ||
-+ (((c) >= 0x0561) && ((c) <= 0x0586)) ||
-+ (((c) >= 0x05D0) && ((c) <= 0x05EA)) ||
-+ (((c) >= 0x05F0) && ((c) <= 0x05F2)) ||
-+ (((c) >= 0x0621) && ((c) <= 0x063A)) ||
-+ (((c) >= 0x0641) && ((c) <= 0x064A)) ||
-+ (((c) >= 0x0671) && ((c) <= 0x06B7)) ||
-+ (((c) >= 0x06BA) && ((c) <= 0x06BE)) ||
-+ (((c) >= 0x06C0) && ((c) <= 0x06CE)) ||
-+ (((c) >= 0x06D0) && ((c) <= 0x06D3)) ||
-+ ((c) == 0x06D5) ||
-+ (((c) >= 0x06E5) && ((c) <= 0x06E6)) ||
-+ (((c) >= 0x905) && ( /* accelerator */
-+ (((c) >= 0x0905) && ((c) <= 0x0939)) ||
-+ ((c) == 0x093D) ||
-+ (((c) >= 0x0958) && ((c) <= 0x0961)) ||
-+ (((c) >= 0x0985) && ((c) <= 0x098C)) ||
-+ (((c) >= 0x098F) && ((c) <= 0x0990)) ||
-+ (((c) >= 0x0993) && ((c) <= 0x09A8)) ||
-+ (((c) >= 0x09AA) && ((c) <= 0x09B0)) ||
-+ ((c) == 0x09B2) ||
-+ (((c) >= 0x09B6) && ((c) <= 0x09B9)) ||
-+ (((c) >= 0x09DC) && ((c) <= 0x09DD)) ||
-+ (((c) >= 0x09DF) && ((c) <= 0x09E1)) ||
-+ (((c) >= 0x09F0) && ((c) <= 0x09F1)) ||
-+ (((c) >= 0x0A05) && ((c) <= 0x0A0A)) ||
-+ (((c) >= 0x0A0F) && ((c) <= 0x0A10)) ||
-+ (((c) >= 0x0A13) && ((c) <= 0x0A28)) ||
-+ (((c) >= 0x0A2A) && ((c) <= 0x0A30)) ||
-+ (((c) >= 0x0A32) && ((c) <= 0x0A33)) ||
-+ (((c) >= 0x0A35) && ((c) <= 0x0A36)) ||
-+ (((c) >= 0x0A38) && ((c) <= 0x0A39)) ||
-+ (((c) >= 0x0A59) && ((c) <= 0x0A5C)) ||
-+ ((c) == 0x0A5E) ||
-+ (((c) >= 0x0A72) && ((c) <= 0x0A74)) ||
-+ (((c) >= 0x0A85) && ((c) <= 0x0A8B)) ||
-+ ((c) == 0x0A8D) ||
-+ (((c) >= 0x0A8F) && ((c) <= 0x0A91)) ||
-+ (((c) >= 0x0A93) && ((c) <= 0x0AA8)) ||
-+ (((c) >= 0x0AAA) && ((c) <= 0x0AB0)) ||
-+ (((c) >= 0x0AB2) && ((c) <= 0x0AB3)) ||
-+ (((c) >= 0x0AB5) && ((c) <= 0x0AB9)) ||
-+ ((c) == 0x0ABD) ||
-+ ((c) == 0x0AE0) ||
-+ (((c) >= 0x0B05) && ((c) <= 0x0B0C)) ||
-+ (((c) >= 0x0B0F) && ((c) <= 0x0B10)) ||
-+ (((c) >= 0x0B13) && ((c) <= 0x0B28)) ||
-+ (((c) >= 0x0B2A) && ((c) <= 0x0B30)) ||
-+ (((c) >= 0x0B32) && ((c) <= 0x0B33)) ||
-+ (((c) >= 0x0B36) && ((c) <= 0x0B39)) ||
-+ ((c) == 0x0B3D) ||
-+ (((c) >= 0x0B5C) && ((c) <= 0x0B5D)) ||
-+ (((c) >= 0x0B5F) && ((c) <= 0x0B61)) ||
-+ (((c) >= 0x0B85) && ((c) <= 0x0B8A)) ||
-+ (((c) >= 0x0B8E) && ((c) <= 0x0B90)) ||
-+ (((c) >= 0x0B92) && ((c) <= 0x0B95)) ||
-+ (((c) >= 0x0B99) && ((c) <= 0x0B9A)) ||
-+ ((c) == 0x0B9C) ||
-+ (((c) >= 0x0B9E) && ((c) <= 0x0B9F)) ||
-+ (((c) >= 0x0BA3) && ((c) <= 0x0BA4)) ||
-+ (((c) >= 0x0BA8) && ((c) <= 0x0BAA)) ||
-+ (((c) >= 0x0BAE) && ((c) <= 0x0BB5)) ||
-+ (((c) >= 0x0BB7) && ((c) <= 0x0BB9)) ||
-+ (((c) >= 0x0C05) && ((c) <= 0x0C0C)) ||
-+ (((c) >= 0x0C0E) && ((c) <= 0x0C10)) ||
-+ (((c) >= 0x0C12) && ((c) <= 0x0C28)) ||
-+ (((c) >= 0x0C2A) && ((c) <= 0x0C33)) ||
-+ (((c) >= 0x0C35) && ((c) <= 0x0C39)) ||
-+ (((c) >= 0x0C60) && ((c) <= 0x0C61)) ||
-+ (((c) >= 0x0C85) && ((c) <= 0x0C8C)) ||
-+ (((c) >= 0x0C8E) && ((c) <= 0x0C90)) ||
-+ (((c) >= 0x0C92) && ((c) <= 0x0CA8)) ||
-+ (((c) >= 0x0CAA) && ((c) <= 0x0CB3)) ||
-+ (((c) >= 0x0CB5) && ((c) <= 0x0CB9)) ||
-+ ((c) == 0x0CDE) ||
-+ (((c) >= 0x0CE0) && ((c) <= 0x0CE1)) ||
-+ (((c) >= 0x0D05) && ((c) <= 0x0D0C)) ||
-+ (((c) >= 0x0D0E) && ((c) <= 0x0D10)) ||
-+ (((c) >= 0x0D12) && ((c) <= 0x0D28)) ||
-+ (((c) >= 0x0D2A) && ((c) <= 0x0D39)) ||
-+ (((c) >= 0x0D60) && ((c) <= 0x0D61)) ||
-+ (((c) >= 0x0E01) && ((c) <= 0x0E2E)) ||
-+ ((c) == 0x0E30) ||
-+ (((c) >= 0x0E32) && ((c) <= 0x0E33)) ||
-+ (((c) >= 0x0E40) && ((c) <= 0x0E45)) ||
-+ (((c) >= 0x0E81) && ((c) <= 0x0E82)) ||
-+ ((c) == 0x0E84) ||
-+ (((c) >= 0x0E87) && ((c) <= 0x0E88)) ||
-+ ((c) == 0x0E8A) ||
-+ ((c) == 0x0E8D) ||
-+ (((c) >= 0x0E94) && ((c) <= 0x0E97)) ||
-+ (((c) >= 0x0E99) && ((c) <= 0x0E9F)) ||
-+ (((c) >= 0x0EA1) && ((c) <= 0x0EA3)) ||
-+ ((c) == 0x0EA5) ||
-+ ((c) == 0x0EA7) ||
-+ (((c) >= 0x0EAA) && ((c) <= 0x0EAB)) ||
-+ (((c) >= 0x0EAD) && ((c) <= 0x0EAE)) ||
-+ ((c) == 0x0EB0) ||
-+ (((c) >= 0x0EB2) && ((c) <= 0x0EB3)) ||
-+ ((c) == 0x0EBD) ||
-+ (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) ||
-+ (((c) >= 0x0F40) && ((c) <= 0x0F47)) ||
-+ (((c) >= 0x0F49) && ((c) <= 0x0F69)) ||
-+ (((c) >= 0x10A0) && ( /* accelerator */
-+ (((c) >= 0x10A0) && ((c) <= 0x10C5)) ||
-+ (((c) >= 0x10D0) && ((c) <= 0x10F6)) ||
-+ ((c) == 0x1100) ||
-+ (((c) >= 0x1102) && ((c) <= 0x1103)) ||
-+ (((c) >= 0x1105) && ((c) <= 0x1107)) ||
-+ ((c) == 0x1109) ||
-+ (((c) >= 0x110B) && ((c) <= 0x110C)) ||
-+ (((c) >= 0x110E) && ((c) <= 0x1112)) ||
-+ ((c) == 0x113C) ||
-+ ((c) == 0x113E) ||
-+ ((c) == 0x1140) ||
-+ ((c) == 0x114C) ||
-+ ((c) == 0x114E) ||
-+ ((c) == 0x1150) ||
-+ (((c) >= 0x1154) && ((c) <= 0x1155)) ||
-+ ((c) == 0x1159) ||
-+ (((c) >= 0x115F) && ((c) <= 0x1161)) ||
-+ ((c) == 0x1163) ||
-+ ((c) == 0x1165) ||
-+ ((c) == 0x1167) ||
-+ ((c) == 0x1169) ||
-+ (((c) >= 0x116D) && ((c) <= 0x116E)) ||
-+ (((c) >= 0x1172) && ((c) <= 0x1173)) ||
-+ ((c) == 0x1175) ||
-+ ((c) == 0x119E) ||
-+ ((c) == 0x11A8) ||
-+ ((c) == 0x11AB) ||
-+ (((c) >= 0x11AE) && ((c) <= 0x11AF)) ||
-+ (((c) >= 0x11B7) && ((c) <= 0x11B8)) ||
-+ ((c) == 0x11BA) ||
-+ (((c) >= 0x11BC) && ((c) <= 0x11C2)) ||
-+ ((c) == 0x11EB) ||
-+ ((c) == 0x11F0) ||
-+ ((c) == 0x11F9) ||
-+ (((c) >= 0x1E00) && ((c) <= 0x1E9B)) ||
-+ (((c) >= 0x1EA0) && ((c) <= 0x1EF9)) ||
-+ (((c) >= 0x1F00) && ((c) <= 0x1F15)) ||
-+ (((c) >= 0x1F18) && ((c) <= 0x1F1D)) ||
-+ (((c) >= 0x1F20) && ((c) <= 0x1F45)) ||
-+ (((c) >= 0x1F48) && ((c) <= 0x1F4D)) ||
-+ (((c) >= 0x1F50) && ((c) <= 0x1F57)) ||
-+ ((c) == 0x1F59) ||
-+ ((c) == 0x1F5B) ||
-+ ((c) == 0x1F5D) ||
-+ (((c) >= 0x1F5F) && ((c) <= 0x1F7D)) ||
-+ (((c) >= 0x1F80) && ((c) <= 0x1FB4)) ||
-+ (((c) >= 0x1FB6) && ((c) <= 0x1FBC)) ||
-+ ((c) == 0x1FBE) ||
-+ (((c) >= 0x1FC2) && ((c) <= 0x1FC4)) ||
-+ (((c) >= 0x1FC6) && ((c) <= 0x1FCC)) ||
-+ (((c) >= 0x1FD0) && ((c) <= 0x1FD3)) ||
-+ (((c) >= 0x1FD6) && ((c) <= 0x1FDB)) ||
-+ (((c) >= 0x1FE0) && ((c) <= 0x1FEC)) ||
-+ (((c) >= 0x1FF2) && ((c) <= 0x1FF4)) ||
-+ (((c) >= 0x1FF6) && ((c) <= 0x1FFC)) ||
-+ ((c) == 0x2126) ||
-+ (((c) >= 0x212A) && ((c) <= 0x212B)) ||
-+ ((c) == 0x212E) ||
-+ (((c) >= 0x2180) && ((c) <= 0x2182)) ||
-+ (((c) >= 0x3041) && ((c) <= 0x3094)) ||
-+ (((c) >= 0x30A1) && ((c) <= 0x30FA)) ||
-+ (((c) >= 0x3105) && ((c) <= 0x312C)) ||
-+ (((c) >= 0xAC00) && ((c) <= 0xD7A3))) /* accelerators */ ))))));
-+}
-+
-+/**
-+ * xmlIsDigit:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [88] Digit ::= ... long list see REC ...
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsDigit(int c) {
-+ return(
-+ (((c) >= 0x0030) && ((c) <= 0x0039)) ||
-+ (((c) >= 0x660) && ( /* accelerator */
-+ (((c) >= 0x0660) && ((c) <= 0x0669)) ||
-+ (((c) >= 0x06F0) && ((c) <= 0x06F9)) ||
-+ (((c) >= 0x0966) && ((c) <= 0x096F)) ||
-+ (((c) >= 0x09E6) && ((c) <= 0x09EF)) ||
-+ (((c) >= 0x0A66) && ((c) <= 0x0A6F)) ||
-+ (((c) >= 0x0AE6) && ((c) <= 0x0AEF)) ||
-+ (((c) >= 0x0B66) && ((c) <= 0x0B6F)) ||
-+ (((c) >= 0x0BE7) && ((c) <= 0x0BEF)) ||
-+ (((c) >= 0x0C66) && ((c) <= 0x0C6F)) ||
-+ (((c) >= 0x0CE6) && ((c) <= 0x0CEF)) ||
-+ (((c) >= 0x0D66) && ((c) <= 0x0D6F)) ||
-+ (((c) >= 0x0E50) && ((c) <= 0x0E59)) ||
-+ (((c) >= 0x0ED0) && ((c) <= 0x0ED9)) ||
-+ (((c) >= 0x0F20) && ((c) <= 0x0F29))) /* accelerator */ ));
-+}
-+
-+/**
-+ * xmlIsCombining:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [87] CombiningChar ::= ... long list see REC ...
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsCombining(int c) {
-+ return(
-+ (((c) >= 0x300) && ( /* accelerator */
-+ (((c) >= 0x0300) && ((c) <= 0x0345)) ||
-+ (((c) >= 0x0360) && ((c) <= 0x0361)) ||
-+ (((c) >= 0x0483) && ((c) <= 0x0486)) ||
-+ (((c) >= 0x0591) && ((c) <= 0x05A1)) ||
-+ (((c) >= 0x05A3) && ((c) <= 0x05B9)) ||
-+ (((c) >= 0x05BB) && ((c) <= 0x05BD)) ||
-+ ((c) == 0x05BF) ||
-+ (((c) >= 0x05C1) && ((c) <= 0x05C2)) ||
-+ ((c) == 0x05C4) ||
-+ (((c) >= 0x064B) && ((c) <= 0x0652)) ||
-+ ((c) == 0x0670) ||
-+ (((c) >= 0x06D6) && ((c) <= 0x06DC)) ||
-+ (((c) >= 0x06DD) && ((c) <= 0x06DF)) ||
-+ (((c) >= 0x06E0) && ((c) <= 0x06E4)) ||
-+ (((c) >= 0x06E7) && ((c) <= 0x06E8)) ||
-+ (((c) >= 0x06EA) && ((c) <= 0x06ED)) ||
-+ (((c) >= 0x0901) && ( /* accelerator */
-+ (((c) >= 0x0901) && ((c) <= 0x0903)) ||
-+ ((c) == 0x093C) ||
-+ (((c) >= 0x093E) && ((c) <= 0x094C)) ||
-+ ((c) == 0x094D) ||
-+ (((c) >= 0x0951) && ((c) <= 0x0954)) ||
-+ (((c) >= 0x0962) && ((c) <= 0x0963)) ||
-+ (((c) >= 0x0981) && ((c) <= 0x0983)) ||
-+ ((c) == 0x09BC) ||
-+ ((c) == 0x09BE) ||
-+ ((c) == 0x09BF) ||
-+ (((c) >= 0x09C0) && ((c) <= 0x09C4)) ||
-+ (((c) >= 0x09C7) && ((c) <= 0x09C8)) ||
-+ (((c) >= 0x09CB) && ((c) <= 0x09CD)) ||
-+ ((c) == 0x09D7) ||
-+ (((c) >= 0x09E2) && ((c) <= 0x09E3)) ||
-+ (((c) >= 0x0A02) && ( /* accelerator */
-+ ((c) == 0x0A02) ||
-+ ((c) == 0x0A3C) ||
-+ ((c) == 0x0A3E) ||
-+ ((c) == 0x0A3F) ||
-+ (((c) >= 0x0A40) && ((c) <= 0x0A42)) ||
-+ (((c) >= 0x0A47) && ((c) <= 0x0A48)) ||
-+ (((c) >= 0x0A4B) && ((c) <= 0x0A4D)) ||
-+ (((c) >= 0x0A70) && ((c) <= 0x0A71)) ||
-+ (((c) >= 0x0A81) && ((c) <= 0x0A83)) ||
-+ ((c) == 0x0ABC) ||
-+ (((c) >= 0x0ABE) && ((c) <= 0x0AC5)) ||
-+ (((c) >= 0x0AC7) && ((c) <= 0x0AC9)) ||
-+ (((c) >= 0x0ACB) && ((c) <= 0x0ACD)) ||
-+ (((c) >= 0x0B01) && ((c) <= 0x0B03)) ||
-+ ((c) == 0x0B3C) ||
-+ (((c) >= 0x0B3E) && ((c) <= 0x0B43)) ||
-+ (((c) >= 0x0B47) && ((c) <= 0x0B48)) ||
-+ (((c) >= 0x0B4B) && ((c) <= 0x0B4D)) ||
-+ (((c) >= 0x0B56) && ((c) <= 0x0B57)) ||
-+ (((c) >= 0x0B82) && ((c) <= 0x0B83)) ||
-+ (((c) >= 0x0BBE) && ((c) <= 0x0BC2)) ||
-+ (((c) >= 0x0BC6) && ((c) <= 0x0BC8)) ||
-+ (((c) >= 0x0BCA) && ((c) <= 0x0BCD)) ||
-+ ((c) == 0x0BD7) ||
-+ (((c) >= 0x0C01) && ((c) <= 0x0C03)) ||
-+ (((c) >= 0x0C3E) && ((c) <= 0x0C44)) ||
-+ (((c) >= 0x0C46) && ((c) <= 0x0C48)) ||
-+ (((c) >= 0x0C4A) && ((c) <= 0x0C4D)) ||
-+ (((c) >= 0x0C55) && ((c) <= 0x0C56)) ||
-+ (((c) >= 0x0C82) && ((c) <= 0x0C83)) ||
-+ (((c) >= 0x0CBE) && ((c) <= 0x0CC4)) ||
-+ (((c) >= 0x0CC6) && ((c) <= 0x0CC8)) ||
-+ (((c) >= 0x0CCA) && ((c) <= 0x0CCD)) ||
-+ (((c) >= 0x0CD5) && ((c) <= 0x0CD6)) ||
-+ (((c) >= 0x0D02) && ((c) <= 0x0D03)) ||
-+ (((c) >= 0x0D3E) && ((c) <= 0x0D43)) ||
-+ (((c) >= 0x0D46) && ((c) <= 0x0D48)) ||
-+ (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) ||
-+ ((c) == 0x0D57) ||
-+ (((c) >= 0x0E31) && ( /* accelerator */
-+ ((c) == 0x0E31) ||
-+ (((c) >= 0x0E34) && ((c) <= 0x0E3A)) ||
-+ (((c) >= 0x0E47) && ((c) <= 0x0E4E)) ||
-+ ((c) == 0x0EB1) ||
-+ (((c) >= 0x0EB4) && ((c) <= 0x0EB9)) ||
-+ (((c) >= 0x0EBB) && ((c) <= 0x0EBC)) ||
-+ (((c) >= 0x0EC8) && ((c) <= 0x0ECD)) ||
-+ (((c) >= 0x0F18) && ((c) <= 0x0F19)) ||
-+ ((c) == 0x0F35) ||
-+ ((c) == 0x0F37) ||
-+ ((c) == 0x0F39) ||
-+ ((c) == 0x0F3E) ||
-+ ((c) == 0x0F3F) ||
-+ (((c) >= 0x0F71) && ((c) <= 0x0F84)) ||
-+ (((c) >= 0x0F86) && ((c) <= 0x0F8B)) ||
-+ (((c) >= 0x0F90) && ((c) <= 0x0F95)) ||
-+ ((c) == 0x0F97) ||
-+ (((c) >= 0x0F99) && ((c) <= 0x0FAD)) ||
-+ (((c) >= 0x0FB1) && ((c) <= 0x0FB7)) ||
-+ ((c) == 0x0FB9) ||
-+ (((c) >= 0x20D0) && ((c) <= 0x20DC)) ||
-+ ((c) == 0x20E1) ||
-+ (((c) >= 0x302A) && ((c) <= 0x302F)) ||
-+ ((c) == 0x3099) ||
-+ ((c) == 0x309A))))))))));
-+}
-+
-+/**
-+ * xmlIsExtender:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
-+ * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
-+ * [#x309D-#x309E] | [#x30FC-#x30FE]
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsExtender(int c) {
-+ switch (c) {
-+ case 0x00B7: case 0x02D0: case 0x02D1: case 0x0387:
-+ case 0x0640: case 0x0E46: case 0x0EC6: case 0x3005:
-+ case 0x3031: case 0x3032: case 0x3033: case 0x3034:
-+ case 0x3035: case 0x309D: case 0x309E: case 0x30FC:
-+ case 0x30FE:
-+ return 1;
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/**
-+ * xmlIsIdeographic:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsIdeographic(int c) {
-+ return(((c) < 0x0100) ? 0 :
-+ (((c) >= 0x4e00) && ((c) <= 0x9fa5)) ||
-+ (((c) >= 0xf900) && ((c) <= 0xfa2d)) ||
-+ (((c) >= 0x3021) && ((c) <= 0x3029)) ||
-+ ((c) == 0x3007));
-+}
-+
-+/**
-+ * xmlIsLetter:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [84] Letter ::= BaseChar | Ideographic
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsLetter(int c) {
-+ return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
-+}
-+
-+/**
-+ * xmlIsPubidChar:
-+ * @c: an unicode character (int)
-+ *
-+ * Check whether the character is allowed by the production
-+ * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-+ *
-+ * Returns 0 if not, non-zero otherwise
-+ */
-+int
-+xmlIsPubidChar(int c) {
-+ return(
-+ ((c) == 0x20) || ((c) == 0x0D) || ((c) == 0x0A) ||
-+ (((c) >= 'a') && ((c) <= 'z')) ||
-+ (((c) >= 'A') && ((c) <= 'Z')) ||
-+ (((c) >= '0') && ((c) <= '9')) ||
-+ ((c) == '-') || ((c) == '\'') || ((c) == '(') || ((c) == ')') ||
-+ ((c) == '+') || ((c) == ',') || ((c) == '.') || ((c) == '/') ||
-+ ((c) == ':') || ((c) == '=') || ((c) == '?') || ((c) == ';') ||
-+ ((c) == '!') || ((c) == '*') || ((c) == '#') || ((c) == '@') ||
-+ ((c) == '$') || ((c) == '_') || ((c) == '%'));
-+}
-+
-+/************************************************************************
-+ * *
-+ * Input handling functions for progressive parsing *
-+ * *
-+ ************************************************************************/
-+
-+/* #define DEBUG_INPUT */
-+/* #define DEBUG_STACK */
-+/* #define DEBUG_PUSH */
-+
-+
-+/* we need to keep enough input to show errors in context */
-+#define LINE_LEN 80
-+
-+#ifdef DEBUG_INPUT
-+#define CHECK_BUFFER(in) check_buffer(in)
-+
-+void check_buffer(xmlParserInputPtr in) {
-+ if (in->base != in->buf->buffer->content) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInput: base mismatch problem\n");
-+ }
-+ if (in->cur < in->base) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInput: cur < base problem\n");
-+ }
-+ if (in->cur > in->base + in->buf->buffer->use) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInput: cur > base + use problem\n");
-+ }
-+ xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d, size %d\n",
-+ (int) in, (int) in->buf->buffer->content, in->cur - in->base,
-+ in->buf->buffer->use, in->buf->buffer->size);
-+}
-+
-+#else
-+#define CHECK_BUFFER(in)
-+#endif
-+
-+
-+/**
-+ * xmlParserInputRead:
-+ * @in: an XML parser input
-+ * @len: an indicative size for the lookahead
-+ *
-+ * This function refresh the input for the parser. It doesn't try to
-+ * preserve pointers to the input buffer, and discard already read data
-+ *
-+ * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
-+ * end of this entity
-+ */
-+int
-+xmlParserInputRead(xmlParserInputPtr in, int len) {
-+ int ret;
-+ int used;
-+ int index;
-+
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext, "Read\n");
-+#endif
-+ if (in->buf == NULL) return(-1);
-+ if (in->base == NULL) return(-1);
-+ if (in->cur == NULL) return(-1);
-+ if (in->buf->buffer == NULL) return(-1);
-+ if (in->buf->readcallback == NULL) return(-1);
-+
-+ CHECK_BUFFER(in);
-+
-+ used = in->cur - in->buf->buffer->content;
-+ ret = xmlBufferShrink(in->buf->buffer, used);
-+ if (ret > 0) {
-+ in->cur -= ret;
-+ in->consumed += ret;
-+ }
-+ ret = xmlParserInputBufferRead(in->buf, len);
-+ if (in->base != in->buf->buffer->content) {
-+ /*
-+ * the buffer has been realloced
-+ */
-+ index = in->cur - in->base;
-+ in->base = in->buf->buffer->content;
-+ in->cur = &in->buf->buffer->content[index];
-+ }
-+
-+ CHECK_BUFFER(in);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputGrow:
-+ * @in: an XML parser input
-+ * @len: an indicative size for the lookahead
-+ *
-+ * This function increase the input for the parser. It tries to
-+ * preserve pointers to the input buffer, and keep already read data
-+ *
-+ * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
-+ * end of this entity
-+ */
-+int
-+xmlParserInputGrow(xmlParserInputPtr in, int len) {
-+ int ret;
-+ int index;
-+
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext, "Grow\n");
-+#endif
-+ if (in->buf == NULL) return(-1);
-+ if (in->base == NULL) return(-1);
-+ if (in->cur == NULL) return(-1);
-+ if (in->buf->buffer == NULL) return(-1);
-+
-+ CHECK_BUFFER(in);
-+
-+ index = in->cur - in->base;
-+ if (in->buf->buffer->use > (unsigned int) index + INPUT_CHUNK) {
-+
-+ CHECK_BUFFER(in);
-+
-+ return(0);
-+ }
-+ if (in->buf->readcallback != NULL)
-+ ret = xmlParserInputBufferGrow(in->buf, len);
-+ else
-+ return(0);
-+
-+ /*
-+ * NOTE : in->base may be a "dandling" i.e. freed pointer in this
-+ * block, but we use it really as an integer to do some
-+ * pointer arithmetic. Insure will raise it as a bug but in
-+ * that specific case, that's not !
-+ */
-+ if (in->base != in->buf->buffer->content) {
-+ /*
-+ * the buffer has been realloced
-+ */
-+ index = in->cur - in->base;
-+ in->base = in->buf->buffer->content;
-+ in->cur = &in->buf->buffer->content[index];
-+ }
-+
-+ CHECK_BUFFER(in);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputShrink:
-+ * @in: an XML parser input
-+ *
-+ * This function removes used input for the parser.
-+ */
-+void
-+xmlParserInputShrink(xmlParserInputPtr in) {
-+ int used;
-+ int ret;
-+ int index;
-+
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext, "Shrink\n");
-+#endif
-+ if (in->buf == NULL) return;
-+ if (in->base == NULL) return;
-+ if (in->cur == NULL) return;
-+ if (in->buf->buffer == NULL) return;
-+
-+ CHECK_BUFFER(in);
-+
-+ used = in->cur - in->buf->buffer->content;
-+ /*
-+ * Do not shrink on large buffers whose only a tiny fraction
-+ * was consumned
-+ */
-+ if (in->buf->buffer->use > used + 2 * INPUT_CHUNK)
-+ return;
-+ if (used > INPUT_CHUNK) {
-+ ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
-+ if (ret > 0) {
-+ in->cur -= ret;
-+ in->consumed += ret;
-+ }
-+ }
-+
-+ CHECK_BUFFER(in);
-+
-+ if (in->buf->buffer->use > INPUT_CHUNK) {
-+ return;
-+ }
-+ xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
-+ if (in->base != in->buf->buffer->content) {
-+ /*
-+ * the buffer has been realloced
-+ */
-+ index = in->cur - in->base;
-+ in->base = in->buf->buffer->content;
-+ in->cur = &in->buf->buffer->content[index];
-+ }
-+
-+ CHECK_BUFFER(in);
-+}
-+
-+/************************************************************************
-+ * *
-+ * UTF8 character input and related functions *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlNextChar:
-+ * @ctxt: the XML parser context
-+ *
-+ * Skip to the next char input char.
-+ */
-+
-+void
-+xmlNextChar(xmlParserCtxtPtr ctxt) {
-+ if (ctxt->instate == XML_PARSER_EOF)
-+ return;
-+
-+ /*
-+ * 2.11 End-of-Line Handling
-+ * the literal two-character sequence "#xD#xA" or a standalone
-+ * literal #xD, an XML processor must pass to the application
-+ * the single character #xA.
-+ */
-+ if (ctxt->token != 0) ctxt->token = 0;
-+ else if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-+ if ((*ctxt->input->cur == 0) &&
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
-+ (ctxt->instate != XML_PARSER_COMMENT)) {
-+ /*
-+ * If we are at the end of the current entity and
-+ * the context allows it, we pop consumed entities
-+ * automatically.
-+ * the auto closing should be blocked in other cases
-+ */
-+ xmlPopInput(ctxt);
-+ } else {
-+ if (*(ctxt->input->cur) == '\n') {
-+ ctxt->input->line++; ctxt->input->col = 1;
-+ } else ctxt->input->col++;
-+ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * We are supposed to handle UTF8, check it's valid
-+ * From rfc2044: encoding of the Unicode values on UTF-8:
-+ *
-+ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-+ * 0000 0000-0000 007F 0xxxxxxx
-+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-+ *
-+ * Check for the 0x110000 limit too
-+ */
-+ const unsigned char *cur = ctxt->input->cur;
-+ unsigned char c;
-+
-+ c = *cur;
-+ if (c & 0x80) {
-+ if (cur[1] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if ((cur[1] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xe0) == 0xe0) {
-+ unsigned int val;
-+
-+ if (cur[2] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if ((cur[2] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xf0) == 0xf0) {
-+ if (cur[3] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if (((c & 0xf8) != 0xf0) ||
-+ ((cur[3] & 0xc0) != 0x80))
-+ goto encoding_error;
-+ /* 4-byte code */
-+ ctxt->input->cur += 4;
-+ val = (cur[0] & 0x7) << 18;
-+ val |= (cur[1] & 0x3f) << 12;
-+ val |= (cur[2] & 0x3f) << 6;
-+ val |= cur[3] & 0x3f;
-+ } else {
-+ /* 3-byte code */
-+ ctxt->input->cur += 3;
-+ val = (cur[0] & 0xf) << 12;
-+ val |= (cur[1] & 0x3f) << 6;
-+ val |= cur[2] & 0x3f;
-+ }
-+ if (((val > 0xd7ff) && (val < 0xe000)) ||
-+ ((val > 0xfffd) && (val < 0x10000)) ||
-+ (val >= 0x110000)) {
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Char 0x%X out of allowed range\n", val);
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ } else
-+ /* 2-byte code */
-+ ctxt->input->cur += 2;
-+ } else
-+ /* 1-byte code */
-+ ctxt->input->cur++;
-+ } else {
-+ /*
-+ * Assume it's a fixed lenght encoding (1) with
-+ * a compatibke encoding for the ASCII set, since
-+ * XML constructs only use < 128 chars
-+ */
-+ ctxt->input->cur++;
-+ }
-+ ctxt->nbChars++;
-+ if (*ctxt->input->cur == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ }
-+ } else {
-+ ctxt->input->cur++;
-+ ctxt->nbChars++;
-+ if (*ctxt->input->cur == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ }
-+ if ((*ctxt->input->cur == '%') && (!ctxt->html))
-+ xmlParserHandlePEReference(ctxt);
-+ if ((*ctxt->input->cur == 0) &&
-+ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-+ xmlPopInput(ctxt);
-+ return;
-+encoding_error:
-+ /*
-+ * If we detect an UTF8 error that probably mean that the
-+ * input encoding didn't get properly advertized in the
-+ * declaration header. Report the error and switch the encoding
-+ * to ISO-Latin-1 (if you don't like this policy, just declare the
-+ * encoding !)
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-+ ctxt->sax->error(ctxt->userData,
-+ "Input is not proper UTF-8, indicate encoding !\n");
-+ ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ ctxt->input->cur[0], ctxt->input->cur[1],
-+ ctxt->input->cur[2], ctxt->input->cur[3]);
-+ }
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+
-+ ctxt->charset = XML_CHAR_ENCODING_8859_1;
-+ ctxt->input->cur++;
-+ return;
-+}
-+
-+/**
-+ * xmlCurrentChar:
-+ * @ctxt: the XML parser context
-+ * @len: pointer to the length of the char read
-+ *
-+ * The current char value, if using UTF-8 this may actaully span multiple
-+ * bytes in the input buffer. Implement the end of line normalization:
-+ * 2.11 End-of-Line Handling
-+ * Wherever an external parsed entity or the literal entity value
-+ * of an internal parsed entity contains either the literal two-character
-+ * sequence "#xD#xA" or a standalone literal #xD, an XML processor
-+ * must pass to the application the single character #xA.
-+ * This behavior can conveniently be produced by normalizing all
-+ * line breaks to #xA on input, before parsing.)
-+ *
-+ * Returns the current char value and its lenght
-+ */
-+
-+int
-+xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
-+ if (ctxt->instate == XML_PARSER_EOF)
-+ return(0);
-+
-+ if (ctxt->token != 0) {
-+ *len = 0;
-+ return(ctxt->token);
-+ }
-+ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * We are supposed to handle UTF8, check it's valid
-+ * From rfc2044: encoding of the Unicode values on UTF-8:
-+ *
-+ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-+ * 0000 0000-0000 007F 0xxxxxxx
-+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-+ *
-+ * Check for the 0x110000 limit too
-+ */
-+ const unsigned char *cur = ctxt->input->cur;
-+ unsigned char c;
-+ unsigned int val;
-+
-+ c = *cur;
-+ if (c & 0x80) {
-+ if (cur[1] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if ((cur[1] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xe0) == 0xe0) {
-+
-+ if (cur[2] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if ((cur[2] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xf0) == 0xf0) {
-+ if (cur[3] == 0)
-+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-+ if (((c & 0xf8) != 0xf0) ||
-+ ((cur[3] & 0xc0) != 0x80))
-+ goto encoding_error;
-+ /* 4-byte code */
-+ *len = 4;
-+ val = (cur[0] & 0x7) << 18;
-+ val |= (cur[1] & 0x3f) << 12;
-+ val |= (cur[2] & 0x3f) << 6;
-+ val |= cur[3] & 0x3f;
-+ } else {
-+ /* 3-byte code */
-+ *len = 3;
-+ val = (cur[0] & 0xf) << 12;
-+ val |= (cur[1] & 0x3f) << 6;
-+ val |= cur[2] & 0x3f;
-+ }
-+ } else {
-+ /* 2-byte code */
-+ *len = 2;
-+ val = (cur[0] & 0x1f) << 6;
-+ val |= cur[1] & 0x3f;
-+ }
-+ if (!IS_CHAR(val)) {
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Char 0x%X out of allowed range\n", val);
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(val);
-+ } else {
-+ /* 1-byte code */
-+ *len = 1;
-+ if (*ctxt->input->cur == 0xD) {
-+ if (ctxt->input->cur[1] == 0xA) {
-+ ctxt->nbChars++;
-+ ctxt->input->cur++;
-+ }
-+ return(0xA);
-+ }
-+ return((int) *ctxt->input->cur);
-+ }
-+ }
-+ /*
-+ * Assume it's a fixed lenght encoding (1) with
-+ * a compatibke encoding for the ASCII set, since
-+ * XML constructs only use < 128 chars
-+ */
-+ *len = 1;
-+ if (*ctxt->input->cur == 0xD) {
-+ if (ctxt->input->cur[1] == 0xA) {
-+ ctxt->nbChars++;
-+ ctxt->input->cur++;
-+ }
-+ return(0xA);
-+ }
-+ return((int) *ctxt->input->cur);
-+encoding_error:
-+ /*
-+ * If we detect an UTF8 error that probably mean that the
-+ * input encoding didn't get properly advertized in the
-+ * declaration header. Report the error and switch the encoding
-+ * to ISO-Latin-1 (if you don't like this policy, just declare the
-+ * encoding !)
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-+ ctxt->sax->error(ctxt->userData,
-+ "Input is not proper UTF-8, indicate encoding !\n");
-+ ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ ctxt->input->cur[0], ctxt->input->cur[1],
-+ ctxt->input->cur[2], ctxt->input->cur[3]);
-+ }
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+
-+ ctxt->charset = XML_CHAR_ENCODING_8859_1;
-+ *len = 1;
-+ return((int) *ctxt->input->cur);
-+}
-+
-+/**
-+ * xmlStringCurrentChar:
-+ * @ctxt: the XML parser context
-+ * @cur: pointer to the beginning of the char
-+ * @len: pointer to the length of the char read
-+ *
-+ * The current char value, if using UTF-8 this may actaully span multiple
-+ * bytes in the input buffer.
-+ *
-+ * Returns the current char value and its lenght
-+ */
-+
-+int
-+xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len) {
-+ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-+ /*
-+ * We are supposed to handle UTF8, check it's valid
-+ * From rfc2044: encoding of the Unicode values on UTF-8:
-+ *
-+ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-+ * 0000 0000-0000 007F 0xxxxxxx
-+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-+ *
-+ * Check for the 0x110000 limit too
-+ */
-+ unsigned char c;
-+ unsigned int val;
-+
-+ c = *cur;
-+ if (c & 0x80) {
-+ if ((cur[1] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xe0) == 0xe0) {
-+
-+ if ((cur[2] & 0xc0) != 0x80)
-+ goto encoding_error;
-+ if ((c & 0xf0) == 0xf0) {
-+ if (((c & 0xf8) != 0xf0) ||
-+ ((cur[3] & 0xc0) != 0x80))
-+ goto encoding_error;
-+ /* 4-byte code */
-+ *len = 4;
-+ val = (cur[0] & 0x7) << 18;
-+ val |= (cur[1] & 0x3f) << 12;
-+ val |= (cur[2] & 0x3f) << 6;
-+ val |= cur[3] & 0x3f;
-+ } else {
-+ /* 3-byte code */
-+ *len = 3;
-+ val = (cur[0] & 0xf) << 12;
-+ val |= (cur[1] & 0x3f) << 6;
-+ val |= cur[2] & 0x3f;
-+ }
-+ } else {
-+ /* 2-byte code */
-+ *len = 2;
-+ val = (cur[0] & 0x1f) << 6;
-+ val |= cur[2] & 0x3f;
-+ }
-+ if (!IS_CHAR(val)) {
-+ if ((ctxt->sax != NULL) &&
-+ (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Char 0x%X out of allowed range\n", val);
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+ return(val);
-+ } else {
-+ /* 1-byte code */
-+ *len = 1;
-+ return((int) *cur);
-+ }
-+ }
-+ /*
-+ * Assume it's a fixed lenght encoding (1) with
-+ * a compatibke encoding for the ASCII set, since
-+ * XML constructs only use < 128 chars
-+ */
-+ *len = 1;
-+ return((int) *cur);
-+encoding_error:
-+ /*
-+ * If we detect an UTF8 error that probably mean that the
-+ * input encoding didn't get properly advertized in the
-+ * declaration header. Report the error and switch the encoding
-+ * to ISO-Latin-1 (if you don't like this policy, just declare the
-+ * encoding !)
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-+ ctxt->sax->error(ctxt->userData,
-+ "Input is not proper UTF-8, indicate encoding !\n");
-+ ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-+ ctxt->input->cur[0], ctxt->input->cur[1],
-+ ctxt->input->cur[2], ctxt->input->cur[3]);
-+ }
-+ ctxt->errNo = XML_ERR_INVALID_ENCODING;
-+
-+ *len = 1;
-+ return((int) *cur);
-+}
-+
-+/**
-+ * xmlCopyChar:
-+ * @len: pointer to the length of the char read (or zero)
-+ * @array: pointer to an arry of xmlChar
-+ * @val: the char value
-+ *
-+ * append the char value in the array
-+ *
-+ * Returns the number of xmlChar written
-+ */
-+
-+int
-+xmlCopyChar(int len, xmlChar *out, int val) {
-+ /*
-+ * We are supposed to handle UTF8, check it's valid
-+ * From rfc2044: encoding of the Unicode values on UTF-8:
-+ *
-+ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-+ * 0000 0000-0000 007F 0xxxxxxx
-+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-+ */
-+ if (len == 0) {
-+ if (val < 0) len = 0;
-+ else if (val < 0x80) len = 1;
-+ else if (val < 0x800) len = 2;
-+ else if (val < 0x10000) len = 3;
-+ else if (val < 0x110000) len = 4;
-+ if (len == 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Internal error, xmlCopyChar 0x%X out of bound\n",
-+ val);
-+ return(0);
-+ }
-+ }
-+ if (len > 1) {
-+ int bits;
-+
-+ if (val < 0x80) { *out++= val; bits= -6; }
-+ else if (val < 0x800) { *out++= (val >> 6) | 0xC0; bits= 0; }
-+ else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6; }
-+ else { *out++= (val >> 18) | 0xF0; bits= 12; }
-+
-+ for ( ; bits >= 0; bits-= 6)
-+ *out++= ((val >> bits) & 0x3F) | 0x80 ;
-+
-+ return(len);
-+ }
-+ *out = (xmlChar) val;
-+ return(1);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to switch encodings *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlSwitchEncoding:
-+ * @ctxt: the parser context
-+ * @enc: the encoding value (number)
-+ *
-+ * change the input functions when discovering the character encoding
-+ * of a given entity.
-+ *
-+ * Returns 0 in case of success, -1 otherwise
-+ */
-+int
-+xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
-+{
-+ xmlCharEncodingHandlerPtr handler;
-+
-+ switch (enc) {
-+ case XML_CHAR_ENCODING_ERROR:
-+ ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "encoding unknown\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ break;
-+ case XML_CHAR_ENCODING_NONE:
-+ /* let's assume it's UTF-8 without the XML decl */
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ return(0);
-+ case XML_CHAR_ENCODING_UTF8:
-+ /* default encoding, no conversion should be needed */
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ return(0);
-+ default:
-+ break;
-+ }
-+ handler = xmlGetCharEncodingHandler(enc);
-+ if (handler == NULL) {
-+ /*
-+ * Default handlers.
-+ */
-+ switch (enc) {
-+ case XML_CHAR_ENCODING_ERROR:
-+ ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "encoding unknown\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ break;
-+ case XML_CHAR_ENCODING_NONE:
-+ /* let's assume it's UTF-8 without the XML decl */
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ return(0);
-+ case XML_CHAR_ENCODING_UTF8:
-+ case XML_CHAR_ENCODING_ASCII:
-+ /* default encoding, no conversion should be needed */
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ return(0);
-+ case XML_CHAR_ENCODING_UTF16LE:
-+ break;
-+ case XML_CHAR_ENCODING_UTF16BE:
-+ break;
-+ case XML_CHAR_ENCODING_UCS4LE:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding USC4 little endian not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_UCS4BE:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding USC4 big endian not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_EBCDIC:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding EBCDIC not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_UCS4_2143:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding UCS4 2143 not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_UCS4_3412:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding UCS4 3412 not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_UCS2:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding UCS2 not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_8859_1:
-+ case XML_CHAR_ENCODING_8859_2:
-+ case XML_CHAR_ENCODING_8859_3:
-+ case XML_CHAR_ENCODING_8859_4:
-+ case XML_CHAR_ENCODING_8859_5:
-+ case XML_CHAR_ENCODING_8859_6:
-+ case XML_CHAR_ENCODING_8859_7:
-+ case XML_CHAR_ENCODING_8859_8:
-+ case XML_CHAR_ENCODING_8859_9:
-+ /*
-+ * We used to keep the internal content in the
-+ * document encoding however this turns being unmaintainable
-+ * So xmlGetCharEncodingHandler() will return non-null
-+ * values for this now.
-+ */
-+ if ((ctxt->inputNr == 1) &&
-+ (ctxt->encoding == NULL) &&
-+ (ctxt->input->encoding != NULL)) {
-+ ctxt->encoding = xmlStrdup(ctxt->input->encoding);
-+ }
-+ ctxt->charset = enc;
-+ return(0);
-+ case XML_CHAR_ENCODING_2022_JP:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding ISO-2022-JPnot supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_SHIFT_JIS:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding Shift_JIS not supported\n");
-+ break;
-+ case XML_CHAR_ENCODING_EUC_JP:
-+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "char encoding EUC-JPnot supported\n");
-+ break;
-+ }
-+ }
-+ if (handler == NULL)
-+ return(-1);
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ return(xmlSwitchToEncoding(ctxt, handler));
-+}
-+
-+/**
-+ * xmlSwitchToEncoding:
-+ * @ctxt: the parser context
-+ * @handler: the encoding handler
-+ *
-+ * change the input functions when discovering the character encoding
-+ * of a given entity.
-+ *
-+ * Returns 0 in case of success, -1 otherwise
-+ */
-+int
-+xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
-+{
-+ int nbchars;
-+
-+ if (handler != NULL) {
-+ if (ctxt->input != NULL) {
-+ if (ctxt->input->buf != NULL) {
-+ if (ctxt->input->buf->encoder != NULL) {
-+ if (ctxt->input->buf->encoder == handler)
-+ return(0);
-+ /*
-+ * Note: this is a bit dangerous, but that's what it
-+ * takes to use nearly compatible signature for different
-+ * encodings.
-+ */
-+ xmlCharEncCloseFunc(ctxt->input->buf->encoder);
-+ ctxt->input->buf->encoder = handler;
-+ return(0);
-+ }
-+ ctxt->input->buf->encoder = handler;
-+
-+ /*
-+ * Is there already some content down the pipe to convert ?
-+ */
-+ if ((ctxt->input->buf->buffer != NULL) &&
-+ (ctxt->input->buf->buffer->use > 0)) {
-+ int processed;
-+
-+ /*
-+ * Specific handling of the Byte Order Mark for
-+ * UTF-16
-+ */
-+ if ((handler->name != NULL) &&
-+ (!strcmp(handler->name, "UTF-16LE")) &&
-+ (ctxt->input->cur[0] == 0xFF) &&
-+ (ctxt->input->cur[1] == 0xFE)) {
-+ ctxt->input->cur += 2;
-+ }
-+ if ((handler->name != NULL) &&
-+ (!strcmp(handler->name, "UTF-16BE")) &&
-+ (ctxt->input->cur[0] == 0xFE) &&
-+ (ctxt->input->cur[1] == 0xFF)) {
-+ ctxt->input->cur += 2;
-+ }
-+
-+ /*
-+ * Shring the current input buffer.
-+ * Move it as the raw buffer and create a new input buffer
-+ */
-+ processed = ctxt->input->cur - ctxt->input->base;
-+ xmlBufferShrink(ctxt->input->buf->buffer, processed);
-+ ctxt->input->buf->raw = ctxt->input->buf->buffer;
-+ ctxt->input->buf->buffer = xmlBufferCreate();
-+
-+ if (ctxt->html) {
-+ /*
-+ * converst as much as possbile of the buffer
-+ */
-+ nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-+ ctxt->input->buf->buffer,
-+ ctxt->input->buf->raw);
-+ } else {
-+ /*
-+ * convert just enough to get
-+ * '<?xml version="1.0" encoding="xxx"?>'
-+ * parsed with the autodetected encoding
-+ * into the parser reading buffer.
-+ */
-+ nbchars = xmlCharEncFirstLine(ctxt->input->buf->encoder,
-+ ctxt->input->buf->buffer,
-+ ctxt->input->buf->raw);
-+ }
-+ if (nbchars < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSwitchToEncoding: encoder error\n");
-+ return(-1);
-+ }
-+ ctxt->input->base =
-+ ctxt->input->cur = ctxt->input->buf->buffer->content;
-+
-+ }
-+ return(0);
-+ } else {
-+ if ((ctxt->input->length == 0) || (ctxt->input->buf == NULL)) {
-+ /*
-+ * When parsing a static memory array one must know the
-+ * size to be able to convert the buffer.
-+ */
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlSwitchEncoding : no input\n");
-+ return(-1);
-+ } else {
-+ int processed;
-+
-+ /*
-+ * Shring the current input buffer.
-+ * Move it as the raw buffer and create a new input buffer
-+ */
-+ processed = ctxt->input->cur - ctxt->input->base;
-+
-+ ctxt->input->buf->raw = xmlBufferCreate();
-+ xmlBufferAdd(ctxt->input->buf->raw, ctxt->input->cur,
-+ ctxt->input->length - processed);
-+ ctxt->input->buf->buffer = xmlBufferCreate();
-+
-+ /*
-+ * convert as much as possible of the raw input
-+ * to the parser reading buffer.
-+ */
-+ nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-+ ctxt->input->buf->buffer,
-+ ctxt->input->buf->raw);
-+ if (nbchars < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSwitchToEncoding: encoder error\n");
-+ return(-1);
-+ }
-+
-+ /*
-+ * Conversion succeeded, get rid of the old buffer
-+ */
-+ if ((ctxt->input->free != NULL) &&
-+ (ctxt->input->base != NULL))
-+ ctxt->input->free((xmlChar *) ctxt->input->base);
-+ ctxt->input->base =
-+ ctxt->input->cur = ctxt->input->buf->buffer->content;
-+ }
-+ }
-+ } else {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlSwitchEncoding : no input\n");
-+ return(-1);
-+ }
-+ /*
-+ * The parsing is now done in UTF8 natively
-+ */
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ } else
-+ return(-1);
-+ return(0);
-+
-+}
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to handle entities processing *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlFreeInputStream:
-+ * @input: an xmlParserInputPtr
-+ *
-+ * Free up an input stream.
-+ */
-+void
-+xmlFreeInputStream(xmlParserInputPtr input) {
-+ if (input == NULL) return;
-+
-+ if (input->filename != NULL) xmlFree((char *) input->filename);
-+ if (input->directory != NULL) xmlFree((char *) input->directory);
-+ if (input->encoding != NULL) xmlFree((char *) input->encoding);
-+ if (input->version != NULL) xmlFree((char *) input->version);
-+ if ((input->free != NULL) && (input->base != NULL))
-+ input->free((xmlChar *) input->base);
-+ if (input->buf != NULL)
-+ xmlFreeParserInputBuffer(input->buf);
-+ memset(input, -1, sizeof(xmlParserInput));
-+ xmlFree(input);
-+}
-+
-+/**
-+ * xmlNewInputStream:
-+ * @ctxt: an XML parser context
-+ *
-+ * Create a new input stream structure
-+ * Returns the new input stream or NULL
-+ */
-+xmlParserInputPtr
-+xmlNewInputStream(xmlParserCtxtPtr ctxt) {
-+ xmlParserInputPtr input;
-+
-+ input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
-+ if (input == NULL) {
-+ if (ctxt != NULL) {
-+ ctxt->errNo = XML_ERR_NO_MEMORY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "malloc: couldn't allocate a new input stream\n");
-+ ctxt->errNo = XML_ERR_NO_MEMORY;
-+ }
-+ return(NULL);
-+ }
-+ memset(input, 0, sizeof(xmlParserInput));
-+ input->line = 1;
-+ input->col = 1;
-+ input->standalone = -1;
-+ return(input);
-+}
-+
-+/**
-+ * xmlNewIOInputStream:
-+ * @ctxt: an XML parser context
-+ * @input: an I/O Input
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a new input stream structure encapsulating the @input into
-+ * a stream suitable for the parser.
-+ *
-+ * Returns the new input stream or NULL
-+ */
-+xmlParserInputPtr
-+xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
-+ xmlCharEncoding enc) {
-+ xmlParserInputPtr inputStream;
-+
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
-+ inputStream = xmlNewInputStream(ctxt);
-+ if (inputStream == NULL) {
-+ return(NULL);
-+ }
-+ inputStream->filename = NULL;
-+ inputStream->buf = input;
-+ inputStream->base = inputStream->buf->buffer->content;
-+ inputStream->cur = inputStream->buf->buffer->content;
-+ if (enc != XML_CHAR_ENCODING_NONE) {
-+ xmlSwitchEncoding(ctxt, enc);
-+ }
-+
-+ return(inputStream);
-+}
-+
-+/**
-+ * xmlNewEntityInputStream:
-+ * @ctxt: an XML parser context
-+ * @entity: an Entity pointer
-+ *
-+ * Create a new input stream based on an xmlEntityPtr
-+ *
-+ * Returns the new input stream or NULL
-+ */
-+xmlParserInputPtr
-+xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-+ xmlParserInputPtr input;
-+
-+ if (entity == NULL) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "internal: xmlNewEntityInputStream entity = NULL\n");
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ return(NULL);
-+ }
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "new input from entity: %s\n", entity->name);
-+ if (entity->content == NULL) {
-+ switch (entity->etype) {
-+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-+ ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlNewEntityInputStream unparsed entity !\n");
-+ break;
-+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-+ case XML_EXTERNAL_PARAMETER_ENTITY:
-+ return(xmlLoadExternalEntity((char *) entity->URI,
-+ (char *) entity->ExternalID, ctxt));
-+ case XML_INTERNAL_GENERAL_ENTITY:
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Internal entity %s without content !\n", entity->name);
-+ break;
-+ case XML_INTERNAL_PARAMETER_ENTITY:
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Internal parameter entity %s without content !\n", entity->name);
-+ break;
-+ case XML_INTERNAL_PREDEFINED_ENTITY:
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Predefined entity %s without content !\n", entity->name);
-+ break;
-+ }
-+ return(NULL);
-+ }
-+ input = xmlNewInputStream(ctxt);
-+ if (input == NULL) {
-+ return(NULL);
-+ }
-+ input->filename = (char *) entity->URI;
-+ input->base = entity->content;
-+ input->cur = entity->content;
-+ input->length = entity->length;
-+ return(input);
-+}
-+
-+/**
-+ * xmlNewStringInputStream:
-+ * @ctxt: an XML parser context
-+ * @buffer: an memory buffer
-+ *
-+ * Create a new input stream based on a memory buffer.
-+ * Returns the new input stream
-+ */
-+xmlParserInputPtr
-+xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
-+ xmlParserInputPtr input;
-+
-+ if (buffer == NULL) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "internal: xmlNewStringInputStream string = NULL\n");
-+ return(NULL);
-+ }
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "new fixed input: %.30s\n", buffer);
-+ input = xmlNewInputStream(ctxt);
-+ if (input == NULL) {
-+ return(NULL);
-+ }
-+ input->base = buffer;
-+ input->cur = buffer;
-+ input->length = xmlStrlen(buffer);
-+ return(input);
-+}
-+
-+/**
-+ * xmlNewInputFromFile:
-+ * @ctxt: an XML parser context
-+ * @filename: the filename to use as entity
-+ *
-+ * Create a new input stream based on a file.
-+ *
-+ * Returns the new input stream or NULL in case of error
-+ */
-+xmlParserInputPtr
-+xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
-+ xmlParserInputBufferPtr buf;
-+ xmlParserInputPtr inputStream;
-+ char *directory = NULL;
-+ xmlChar *URI = NULL;
-+
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "new input from file: %s\n", filename);
-+ if (ctxt == NULL) return(NULL);
-+ buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-+ if (buf == NULL)
-+ return(NULL);
-+
-+ URI = xmlStrdup((xmlChar *) filename);
-+ directory = xmlParserGetDirectory((const char *) URI);
-+
-+ inputStream = xmlNewInputStream(ctxt);
-+ if (inputStream == NULL) {
-+ if (directory != NULL) xmlFree((char *) directory);
-+ if (URI != NULL) xmlFree((char *) URI);
-+ return(NULL);
-+ }
-+
-+ inputStream->filename = (const char *) URI;
-+ inputStream->directory = directory;
-+ inputStream->buf = buf;
-+
-+ inputStream->base = inputStream->buf->buffer->content;
-+ inputStream->cur = inputStream->buf->buffer->content;
-+ if ((ctxt->directory == NULL) && (directory != NULL))
-+ ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
-+ return(inputStream);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Commodity functions to handle parser contexts *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlInitParserCtxt:
-+ * @ctxt: an XML parser context
-+ *
-+ * Initialize a parser context
-+ */
-+
-+void
-+xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
-+{
-+ xmlSAXHandler *sax;
-+
-+ xmlDefaultSAXHandlerInit();
-+
-+ sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
-+ if (sax == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitParserCtxt: out of memory\n");
-+ }
-+ else
-+ memset(sax, 0, sizeof(xmlSAXHandler));
-+
-+ /* Allocate the Input stack */
-+ ctxt->inputTab = (xmlParserInputPtr *)
-+ xmlMalloc(5 * sizeof(xmlParserInputPtr));
-+ if (ctxt->inputTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitParserCtxt: out of memory\n");
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ return;
-+ }
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 5;
-+ ctxt->input = NULL;
-+
-+ ctxt->version = NULL;
-+ ctxt->encoding = NULL;
-+ ctxt->standalone = -1;
-+ ctxt->hasExternalSubset = 0;
-+ ctxt->hasPErefs = 0;
-+ ctxt->html = 0;
-+ ctxt->external = 0;
-+ ctxt->instate = XML_PARSER_START;
-+ ctxt->token = 0;
-+ ctxt->directory = NULL;
-+
-+ /* Allocate the Node stack */
-+ ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
-+ if (ctxt->nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitParserCtxt: out of memory\n");
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 0;
-+ ctxt->node = NULL;
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ return;
-+ }
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 10;
-+ ctxt->node = NULL;
-+
-+ /* Allocate the Name stack */
-+ ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
-+ if (ctxt->nameTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitParserCtxt: out of memory\n");
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 0;
-+ ctxt->node = NULL;
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ ctxt->nameNr = 0;
-+ ctxt->nameMax = 0;
-+ ctxt->name = NULL;
-+ return;
-+ }
-+ ctxt->nameNr = 0;
-+ ctxt->nameMax = 10;
-+ ctxt->name = NULL;
-+
-+ /* Allocate the space stack */
-+ ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
-+ if (ctxt->spaceTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitParserCtxt: out of memory\n");
-+ ctxt->nodeNr = 0;
-+ ctxt->nodeMax = 0;
-+ ctxt->node = NULL;
-+ ctxt->inputNr = 0;
-+ ctxt->inputMax = 0;
-+ ctxt->input = NULL;
-+ ctxt->nameNr = 0;
-+ ctxt->nameMax = 0;
-+ ctxt->name = NULL;
-+ ctxt->spaceNr = 0;
-+ ctxt->spaceMax = 0;
-+ ctxt->space = NULL;
-+ return;
-+ }
-+ ctxt->spaceNr = 1;
-+ ctxt->spaceMax = 10;
-+ ctxt->spaceTab[0] = -1;
-+ ctxt->space = &ctxt->spaceTab[0];
-+
-+ if (sax == NULL) {
-+ ctxt->sax = &xmlDefaultSAXHandler;
-+ } else {
-+ ctxt->sax = sax;
-+ memcpy(sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
-+ }
-+ ctxt->userData = ctxt;
-+ ctxt->myDoc = NULL;
-+ ctxt->wellFormed = 1;
-+ ctxt->valid = 1;
-+ ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
-+ ctxt->validate = xmlDoValidityCheckingDefaultValue;
-+ ctxt->pedantic = xmlPedanticParserDefaultValue;
-+ ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
-+ ctxt->vctxt.userData = ctxt;
-+ if (ctxt->validate) {
-+ ctxt->vctxt.error = xmlParserValidityError;
-+ if (xmlGetWarningsDefaultValue == 0)
-+ ctxt->vctxt.warning = NULL;
-+ else
-+ ctxt->vctxt.warning = xmlParserValidityWarning;
-+ /* Allocate the Node stack */
-+ ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
-+ if (ctxt->vctxt.nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitParserCtxt: out of memory\n");
-+ ctxt->vctxt.nodeMax = 0;
-+ ctxt->validate = 0;
-+ ctxt->vctxt.error = NULL;
-+ ctxt->vctxt.warning = NULL;
-+ } else {
-+ ctxt->vctxt.nodeNr = 0;
-+ ctxt->vctxt.nodeMax = 4;
-+ ctxt->vctxt.node = NULL;
-+ }
-+ } else {
-+ ctxt->vctxt.error = NULL;
-+ ctxt->vctxt.warning = NULL;
-+ }
-+ ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
-+ ctxt->record_info = 0;
-+ ctxt->nbChars = 0;
-+ ctxt->checkIndex = 0;
-+ ctxt->inSubset = 0;
-+ ctxt->errNo = XML_ERR_OK;
-+ ctxt->depth = 0;
-+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
-+ xmlInitNodeInfoSeq(&ctxt->node_seq);
-+}
-+
-+/**
-+ * xmlFreeParserCtxt:
-+ * @ctxt: an XML parser context
-+ *
-+ * Free all the memory used by a parser context. However the parsed
-+ * document in ctxt->myDoc is not freed.
-+ */
-+
-+void
-+xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
-+{
-+ xmlParserInputPtr input;
-+ xmlChar *oldname;
-+
-+ if (ctxt == NULL) return;
-+
-+ while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
-+ xmlFreeInputStream(input);
-+ }
-+ while ((oldname = namePop(ctxt)) != NULL) { /* Non consuming */
-+ xmlFree(oldname);
-+ }
-+ if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
-+ if (ctxt->nameTab != NULL) xmlFree(ctxt->nameTab);
-+ if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
-+ if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
-+ if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
-+ if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
-+ if (ctxt->intSubName != NULL) xmlFree((char *) ctxt->intSubName);
-+ if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
-+ if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
-+ if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
-+ if ((ctxt->sax != NULL) && (ctxt->sax != &xmlDefaultSAXHandler))
-+ xmlFree(ctxt->sax);
-+ if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
-+ xmlFree(ctxt);
-+}
-+
-+/**
-+ * xmlNewParserCtxt:
-+ *
-+ * Allocate and initialize a new parser context.
-+ *
-+ * Returns the xmlParserCtxtPtr or NULL
-+ */
-+
-+xmlParserCtxtPtr
-+xmlNewParserCtxt()
-+{
-+ xmlParserCtxtPtr ctxt;
-+
-+ ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
-+ if (ctxt == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewParserCtxt : cannot allocate context\n");
-+ perror("malloc");
-+ return(NULL);
-+ }
-+ memset(ctxt, 0, sizeof(xmlParserCtxt));
-+ xmlInitParserCtxt(ctxt);
-+ return(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Handling of node informations *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlClearParserCtxt:
-+ * @ctxt: an XML parser context
-+ *
-+ * Clear (release owned resources) and reinitialize a parser context
-+ */
-+
-+void
-+xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
-+{
-+ xmlClearNodeInfoSeq(&ctxt->node_seq);
-+ xmlInitParserCtxt(ctxt);
-+}
-+
-+/**
-+ * xmlParserFindNodeInfo:
-+ * @ctxt: an XML parser context
-+ * @node: an XML node within the tree
-+ *
-+ * Find the parser node info struct for a given node
-+ *
-+ * Returns an xmlParserNodeInfo block pointer or NULL
-+ */
-+const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* ctx,
-+ const xmlNode* node)
-+{
-+ unsigned long pos;
-+
-+ /* Find position where node should be at */
-+ pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
-+ if ( ctx->node_seq.buffer[pos].node == node )
-+ return &ctx->node_seq.buffer[pos];
-+ else
-+ return NULL;
-+}
-+
-+
-+/**
-+ * xmlInitNodeInfoSeq:
-+ * @seq: a node info sequence pointer
-+ *
-+ * -- Initialize (set to initial state) node info sequence
-+ */
-+void
-+xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
-+{
-+ seq->length = 0;
-+ seq->maximum = 0;
-+ seq->buffer = NULL;
-+}
-+
-+/**
-+ * xmlClearNodeInfoSeq:
-+ * @seq: a node info sequence pointer
-+ *
-+ * -- Clear (release memory and reinitialize) node
-+ * info sequence
-+ */
-+void
-+xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
-+{
-+ if ( seq->buffer != NULL )
-+ xmlFree(seq->buffer);
-+ xmlInitNodeInfoSeq(seq);
-+}
-+
-+
-+/**
-+ * xmlParserFindNodeInfoIndex:
-+ * @seq: a node info sequence pointer
-+ * @node: an XML node pointer
-+ *
-+ *
-+ * xmlParserFindNodeInfoIndex : Find the index that the info record for
-+ * the given node is or should be at in a sorted sequence
-+ *
-+ * Returns a long indicating the position of the record
-+ */
-+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
-+ const xmlNode* node)
-+{
-+ unsigned long upper, lower, middle;
-+ int found = 0;
-+
-+ /* Do a binary search for the key */
-+ lower = 1;
-+ upper = seq->length;
-+ middle = 0;
-+ while ( lower <= upper && !found) {
-+ middle = lower + (upper - lower) / 2;
-+ if ( node == seq->buffer[middle - 1].node )
-+ found = 1;
-+ else if ( node < seq->buffer[middle - 1].node )
-+ upper = middle - 1;
-+ else
-+ lower = middle + 1;
-+ }
-+
-+ /* Return position */
-+ if ( middle == 0 || seq->buffer[middle - 1].node < node )
-+ return middle;
-+ else
-+ return middle - 1;
-+}
-+
-+
-+/**
-+ * xmlParserAddNodeInfo:
-+ * @ctxt: an XML parser context
-+ * @info: a node info sequence pointer
-+ *
-+ * Insert node info record into the sorted sequence
-+ */
-+void
-+xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
-+ const xmlParserNodeInfo* info)
-+{
-+ unsigned long pos;
-+ static unsigned int block_size = 5;
-+
-+ /* Find pos and check to see if node is already in the sequence */
-+ pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, info->node);
-+ if ( pos < ctxt->node_seq.length
-+ && ctxt->node_seq.buffer[pos].node == info->node ) {
-+ ctxt->node_seq.buffer[pos] = *info;
-+ }
-+
-+ /* Otherwise, we need to add new node to buffer */
-+ else {
-+ /* Expand buffer by 5 if needed */
-+ if ( ctxt->node_seq.length + 1 > ctxt->node_seq.maximum ) {
-+ xmlParserNodeInfo* tmp_buffer;
-+ unsigned int byte_size = (sizeof(*ctxt->node_seq.buffer)
-+ *(ctxt->node_seq.maximum + block_size));
-+
-+ if ( ctxt->node_seq.buffer == NULL )
-+ tmp_buffer = (xmlParserNodeInfo*) xmlMalloc(byte_size);
-+ else
-+ tmp_buffer = (xmlParserNodeInfo*) xmlRealloc(ctxt->node_seq.buffer, byte_size);
-+
-+ if ( tmp_buffer == NULL ) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Out of memory\n");
-+ ctxt->errNo = XML_ERR_NO_MEMORY;
-+ return;
-+ }
-+ ctxt->node_seq.buffer = tmp_buffer;
-+ ctxt->node_seq.maximum += block_size;
-+ }
-+
-+ /* If position is not at end, move elements out of the way */
-+ if ( pos != ctxt->node_seq.length ) {
-+ unsigned long i;
-+
-+ for ( i = ctxt->node_seq.length; i > pos; i-- )
-+ ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
-+ }
-+
-+ /* Copy element and increase length */
-+ ctxt->node_seq.buffer[pos] = *info;
-+ ctxt->node_seq.length++;
-+ }
-+}
-+
-+/************************************************************************
-+ * *
-+ * Deprecated functions kept for compatibility *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * xmlCheckLanguageID
-+ * @lang: pointer to the string value
-+ *
-+ * Checks that the value conforms to the LanguageID production:
-+ *
-+ * NOTE: this is somewhat deprecated, those productions were removed from
-+ * the XML Second edition.
-+ *
-+ * [33] LanguageID ::= Langcode ('-' Subcode)*
-+ * [34] Langcode ::= ISO639Code | IanaCode | UserCode
-+ * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
-+ * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
-+ * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
-+ * [38] Subcode ::= ([a-z] | [A-Z])+
-+ *
-+ * Returns 1 if correct 0 otherwise
-+ **/
-+int
-+xmlCheckLanguageID(const xmlChar *lang) {
-+ const xmlChar *cur = lang;
-+
-+ if (cur == NULL)
-+ return(0);
-+ if (((cur[0] == 'i') && (cur[1] == '-')) ||
-+ ((cur[0] == 'I') && (cur[1] == '-'))) {
-+ /*
-+ * IANA code
-+ */
-+ cur += 2;
-+ while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
-+ ((cur[0] >= 'a') && (cur[0] <= 'z')))
-+ cur++;
-+ } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
-+ ((cur[0] == 'X') && (cur[1] == '-'))) {
-+ /*
-+ * User code
-+ */
-+ cur += 2;
-+ while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
-+ ((cur[0] >= 'a') && (cur[0] <= 'z')))
-+ cur++;
-+ } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-+ ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
-+ /*
-+ * ISO639
-+ */
-+ cur++;
-+ if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-+ ((cur[0] >= 'a') && (cur[0] <= 'z')))
-+ cur++;
-+ else
-+ return(0);
-+ } else
-+ return(0);
-+ while (cur[0] != 0) { /* non input consuming */
-+ if (cur[0] != '-')
-+ return(0);
-+ cur++;
-+ if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-+ ((cur[0] >= 'a') && (cur[0] <= 'z')))
-+ cur++;
-+ else
-+ return(0);
-+ while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
-+ ((cur[0] >= 'a') && (cur[0] <= 'z')))
-+ cur++;
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * xmlDecodeEntities:
-+ * @ctxt: the parser context
-+ * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
-+ * @len: the len to decode (in bytes !), -1 for no size limit
-+ * @end: an end marker xmlChar, 0 if none
-+ * @end2: an end marker xmlChar, 0 if none
-+ * @end3: an end marker xmlChar, 0 if none
-+ *
-+ * This function is deprecated, we now always process entities content
-+ * through xmlStringDecodeEntities
-+ *
-+ * TODO: remove it in next major release.
-+ *
-+ * [67] Reference ::= EntityRef | CharRef
-+ *
-+ * [69] PEReference ::= '%' Name ';'
-+ *
-+ * Returns A newly allocated string with the substitution done. The caller
-+ * must deallocate it !
-+ */
-+xmlChar *
-+xmlDecodeEntities(xmlParserCtxtPtr ctxt, int len, int what,
-+ xmlChar end, xmlChar end2, xmlChar end3) {
-+#if 0
-+ xmlChar *buffer = NULL;
-+ unsigned int buffer_size = 0;
-+ unsigned int nbchars = 0;
-+
-+ xmlChar *current = NULL;
-+ xmlEntityPtr ent;
-+ unsigned int max = (unsigned int) len;
-+ int c,l;
-+#endif
-+
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDecodeEntities() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+
-+#if 0
-+ if (ctxt->depth > 40) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Detected entity reference loop\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->errNo = XML_ERR_ENTITY_LOOP;
-+ return(NULL);
-+ }
-+
-+ /*
-+ * allocate a translation buffer.
-+ */
-+ buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
-+ buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-+ if (buffer == NULL) {
-+ perror("xmlDecodeEntities: malloc failed");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Ok loop until we reach one of the ending char or a size limit.
-+ */
-+ GROW;
-+ c = CUR_CHAR(l);
-+ while ((nbchars < max) && (c != end) && /* NOTUSED */
-+ (c != end2) && (c != end3)) {
-+ GROW;
-+ if (c == 0) break;
-+ if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
-+ int val = xmlParseCharRef(ctxt);
-+ COPY_BUF(0,buffer,nbchars,val);
-+ NEXTL(l);
-+ } else if ((c == '&') && (ctxt->token != '&') &&
-+ (what & XML_SUBSTITUTE_REF)) {
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "decoding Entity Reference\n");
-+ ent = xmlParseEntityRef(ctxt);
-+ if ((ent != NULL) &&
-+ (ctxt->replaceEntities != 0)) {
-+ current = ent->content;
-+ while (*current != 0) { /* non input consuming loop */
-+ buffer[nbchars++] = *current++;
-+ if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ }
-+ } else if (ent != NULL) {
-+ const xmlChar *cur = ent->name;
-+
-+ buffer[nbchars++] = '&';
-+ if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ while (*cur != 0) { /* non input consuming loop */
-+ buffer[nbchars++] = *cur++;
-+ }
-+ buffer[nbchars++] = ';';
-+ }
-+ } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
-+ /*
-+ * a PEReference induce to switch the entity flow,
-+ * we break here to flush the current set of chars
-+ * parsed if any. We will be called back later.
-+ */
-+ if (xmlParserDebugEntities)
-+ xmlGenericError(xmlGenericErrorContext,
-+ "decoding PE Reference\n");
-+ if (nbchars != 0) break;
-+
-+ xmlParsePEReference(ctxt);
-+
-+ /*
-+ * Pop-up of finished entities.
-+ */
-+ while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
-+ xmlPopInput(ctxt);
-+
-+ break;
-+ } else {
-+ COPY_BUF(l,buffer,nbchars,c);
-+ NEXTL(l);
-+ if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-+ growBuffer(buffer);
-+ }
-+ }
-+ c = CUR_CHAR(l);
-+ }
-+ buffer[nbchars++] = 0;
-+ return(buffer);
-+#endif
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNamespaceParseNCName:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse an XML namespace name.
-+ *
-+ * TODO: this seems not in use anymore, the namespace handling is done on
-+ * top of the SAX interfaces, i.e. not on raw input.
-+ *
-+ * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
-+ *
-+ * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
-+ * CombiningChar | Extender
-+ *
-+ * Returns the namespace name or NULL
-+ */
-+
-+xmlChar *
-+xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt) {
-+#if 0
-+ xmlChar buf[XML_MAX_NAMELEN + 5];
-+ int len = 0, l;
-+ int cur = CUR_CHAR(l);
-+#endif
-+
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNamespaceParseNCName() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+
-+#if 0
-+ /* load first the value of the char !!! */
-+ GROW;
-+ if (!IS_LETTER(cur) && (cur != '_')) return(NULL);
-+
-+xmlGenericError(xmlGenericErrorContext,
-+ "xmlNamespaceParseNCName: reached loop 3\n");
-+ while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) || /* NOT REACHED */
-+ (cur == '.') || (cur == '-') ||
-+ (cur == '_') ||
-+ (IS_COMBINING(cur)) ||
-+ (IS_EXTENDER(cur))) {
-+ COPY_BUF(l,buf,len,cur);
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ if (len >= XML_MAX_NAMELEN) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNamespaceParseNCName: reached XML_MAX_NAMELEN limit\n");
-+ while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||/* NOT REACHED */
-+ (cur == '.') || (cur == '-') ||
-+ (cur == '_') ||
-+ (IS_COMBINING(cur)) ||
-+ (IS_EXTENDER(cur))) {
-+ NEXTL(l);
-+ cur = CUR_CHAR(l);
-+ }
-+ break;
-+ }
-+ }
-+ return(xmlStrndup(buf, len));
-+#endif
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNamespaceParseQName:
-+ * @ctxt: an XML parser context
-+ * @prefix: a xmlChar **
-+ *
-+ * TODO: this seems not in use anymore, the namespace handling is done on
-+ * top of the SAX interfaces, i.e. not on raw input.
-+ *
-+ * parse an XML qualified name
-+ *
-+ * [NS 5] QName ::= (Prefix ':')? LocalPart
-+ *
-+ * [NS 6] Prefix ::= NCName
-+ *
-+ * [NS 7] LocalPart ::= NCName
-+ *
-+ * Returns the local part, and prefix is updated
-+ * to get the Prefix if any.
-+ */
-+
-+xmlChar *
-+xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, xmlChar **prefix) {
-+
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNamespaceParseQName() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+
-+#if 0
-+ xmlChar *ret = NULL;
-+
-+ *prefix = NULL;
-+ ret = xmlNamespaceParseNCName(ctxt);
-+ if (RAW == ':') {
-+ *prefix = ret;
-+ NEXT;
-+ ret = xmlNamespaceParseNCName(ctxt);
-+ }
-+
-+ return(ret);
-+#endif
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNamespaceParseNSDef:
-+ * @ctxt: an XML parser context
-+ *
-+ * parse a namespace prefix declaration
-+ *
-+ * TODO: this seems not in use anymore, the namespace handling is done on
-+ * top of the SAX interfaces, i.e. not on raw input.
-+ *
-+ * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
-+ *
-+ * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
-+ *
-+ * Returns the namespace name
-+ */
-+
-+xmlChar *
-+xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNamespaceParseNSDef() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+ return(NULL);
-+#if 0
-+ xmlChar *name = NULL;
-+
-+ if ((RAW == 'x') && (NXT(1) == 'm') &&
-+ (NXT(2) == 'l') && (NXT(3) == 'n') &&
-+ (NXT(4) == 's')) {
-+ SKIP(5);
-+ if (RAW == ':') {
-+ NEXT;
-+ name = xmlNamespaceParseNCName(ctxt);
-+ }
-+ }
-+ return(name);
-+#endif
-+}
-+
-+/**
-+ * xmlParseQuotedString:
-+ * @ctxt: an XML parser context
-+ *
-+ * Parse and return a string between quotes or doublequotes
-+ *
-+ * TODO: Deprecated, to be removed at next drop of binary compatibility
-+ *
-+ * Returns the string parser or NULL.
-+ */
-+xmlChar *
-+xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseQuotedString() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+ return(NULL);
-+
-+#if 0
-+ xmlChar *buf = NULL;
-+ int len = 0,l;
-+ int size = XML_PARSER_BUFFER_SIZE;
-+ int c;
-+
-+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseQuotedString: reached loop 4\n");
-+ if (RAW == '"') {
-+ NEXT;
-+ c = CUR_CHAR(l);
-+ while (IS_CHAR(c) && (c != '"')) { /* NOTUSED */
-+ if (len + 5 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ }
-+ COPY_BUF(l,buf,len,c);
-+ NEXTL(l);
-+ c = CUR_CHAR(l);
-+ }
-+ if (c != '"') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "String not closed \"%.50s\"\n", buf);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ NEXT;
-+ }
-+ } else if (RAW == '\''){
-+ NEXT;
-+ c = CUR;
-+ while (IS_CHAR(c) && (c != '\'')) { /* NOTUSED */
-+ if (len + 1 >= size) {
-+ size *= 2;
-+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc of %d byte failed\n", size);
-+ return(NULL);
-+ }
-+ }
-+ buf[len++] = c;
-+ NEXT;
-+ c = CUR;
-+ }
-+ if (RAW != '\'') {
-+ ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "String not closed \"%.50s\"\n", buf);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ } else {
-+ NEXT;
-+ }
-+ }
-+ return(buf);
-+#endif
-+}
-+
-+/**
-+ * xmlParseNamespace:
-+ * @ctxt: an XML parser context
-+ *
-+ * xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
-+ *
-+ * This is what the older xml-name Working Draft specified, a bunch of
-+ * other stuff may still rely on it, so support is still here as
-+ * if it was declared on the root of the Tree:-(
-+ *
-+ * TODO: remove from library
-+ *
-+ * To be removed at next drop of binary compatibility
-+ */
-+
-+void
-+xmlParseNamespace(xmlParserCtxtPtr ctxt) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseNamespace() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+
-+#if 0
-+ xmlChar *href = NULL;
-+ xmlChar *prefix = NULL;
-+ int garbage = 0;
-+
-+ /*
-+ * We just skipped "namespace" or "xml:namespace"
-+ */
-+ SKIP_BLANKS;
-+
-+xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseNamespace: reached loop 5\n");
-+ while (IS_CHAR(RAW) && (RAW != '>')) { /* NOT REACHED */
-+ /*
-+ * We can have "ns" or "prefix" attributes
-+ * Old encoding as 'href' or 'AS' attributes is still supported
-+ */
-+ if ((RAW == 'n') && (NXT(1) == 's')) {
-+ garbage = 0;
-+ SKIP(2);
-+ SKIP_BLANKS;
-+
-+ if (RAW != '=') continue;
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ href = xmlParseQuotedString(ctxt);
-+ SKIP_BLANKS;
-+ } else if ((RAW == 'h') && (NXT(1) == 'r') &&
-+ (NXT(2) == 'e') && (NXT(3) == 'f')) {
-+ garbage = 0;
-+ SKIP(4);
-+ SKIP_BLANKS;
-+
-+ if (RAW != '=') continue;
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ href = xmlParseQuotedString(ctxt);
-+ SKIP_BLANKS;
-+ } else if ((RAW == 'p') && (NXT(1) == 'r') &&
-+ (NXT(2) == 'e') && (NXT(3) == 'f') &&
-+ (NXT(4) == 'i') && (NXT(5) == 'x')) {
-+ garbage = 0;
-+ SKIP(6);
-+ SKIP_BLANKS;
-+
-+ if (RAW != '=') continue;
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ prefix = xmlParseQuotedString(ctxt);
-+ SKIP_BLANKS;
-+ } else if ((RAW == 'A') && (NXT(1) == 'S')) {
-+ garbage = 0;
-+ SKIP(2);
-+ SKIP_BLANKS;
-+
-+ if (RAW != '=') continue;
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ prefix = xmlParseQuotedString(ctxt);
-+ SKIP_BLANKS;
-+ } else if ((RAW == '?') && (NXT(1) == '>')) {
-+ garbage = 0;
-+ NEXT;
-+ } else {
-+ /*
-+ * Found garbage when parsing the namespace
-+ */
-+ if (!garbage) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "xmlParseNamespace found garbage\n");
-+ }
-+ ctxt->errNo = XML_ERR_NS_DECL_ERROR;
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ NEXT;
-+ }
-+ }
-+
-+ MOVETO_ENDTAG(CUR_PTR);
-+ NEXT;
-+
-+ /*
-+ * Register the DTD.
-+ if (href != NULL)
-+ if ((ctxt->sax != NULL) && (ctxt->sax->globalNamespace != NULL))
-+ ctxt->sax->globalNamespace(ctxt->userData, href, prefix);
-+ */
-+
-+ if (prefix != NULL) xmlFree(prefix);
-+ if (href != NULL) xmlFree(href);
-+#endif
-+}
-+
-+/**
-+ * xmlScanName:
-+ * @ctxt: an XML parser context
-+ *
-+ * Trickery: parse an XML name but without consuming the input flow
-+ * Needed for rollback cases. Used only when parsing entities references.
-+ *
-+ * TODO: seems deprecated now, only used in the default part of
-+ * xmlParserHandleReference
-+ *
-+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-+ * CombiningChar | Extender
-+ *
-+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-+ *
-+ * [6] Names ::= Name (S Name)*
-+ *
-+ * Returns the Name parsed or NULL
-+ */
-+
-+xmlChar *
-+xmlScanName(xmlParserCtxtPtr ctxt) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlScanName() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+ return(NULL);
-+
-+#if 0
-+ xmlChar buf[XML_MAX_NAMELEN];
-+ int len = 0;
-+
-+ GROW;
-+ if (!IS_LETTER(RAW) && (RAW != '_') &&
-+ (RAW != ':')) {
-+ return(NULL);
-+ }
-+
-+
-+ while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || /* NOT REACHED */
-+ (NXT(len) == '.') || (NXT(len) == '-') ||
-+ (NXT(len) == '_') || (NXT(len) == ':') ||
-+ (IS_COMBINING(NXT(len))) ||
-+ (IS_EXTENDER(NXT(len)))) {
-+ GROW;
-+ buf[len] = NXT(len);
-+ len++;
-+ if (len >= XML_MAX_NAMELEN) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlScanName: reached XML_MAX_NAMELEN limit\n");
-+ while ((IS_LETTER(NXT(len))) || /* NOT REACHED */
-+ (IS_DIGIT(NXT(len))) ||
-+ (NXT(len) == '.') || (NXT(len) == '-') ||
-+ (NXT(len) == '_') || (NXT(len) == ':') ||
-+ (IS_COMBINING(NXT(len))) ||
-+ (IS_EXTENDER(NXT(len))))
-+ len++;
-+ break;
-+ }
-+ }
-+ return(xmlStrndup(buf, len));
-+#endif
-+}
-+
-+/**
-+ * xmlParserHandleReference:
-+ * @ctxt: the parser context
-+ *
-+ * TODO: Remove, now deprecated ... the test is done directly in the
-+ * content parsing
-+ * routines.
-+ *
-+ * [67] Reference ::= EntityRef | CharRef
-+ *
-+ * [68] EntityRef ::= '&' Name ';'
-+ *
-+ * [ WFC: Entity Declared ]
-+ * the Name given in the entity reference must match that in an entity
-+ * declaration, except that well-formed documents need not declare any
-+ * of the following entities: amp, lt, gt, apos, quot.
-+ *
-+ * [ WFC: Parsed Entity ]
-+ * An entity reference must not contain the name of an unparsed entity
-+ *
-+ * [66] CharRef ::= '&#' [0-9]+ ';' |
-+ * '&#x' [0-9a-fA-F]+ ';'
-+ *
-+ * A PEReference may have been detectect in the current input stream
-+ * the handling is done accordingly to
-+ * http://www.w3.org/TR/REC-xml#entproc
-+ */
-+void
-+xmlParserHandleReference(xmlParserCtxtPtr ctxt) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserHandleReference() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+
-+#if 0
-+ xmlParserInputPtr input;
-+ xmlChar *name;
-+ xmlEntityPtr ent = NULL;
-+
-+ if (ctxt->token != 0) {
-+ return;
-+ }
-+ if (RAW != '&') return;
-+ GROW;
-+ if ((RAW == '&') && (NXT(1) == '#')) {
-+ switch(ctxt->instate) {
-+ case XML_PARSER_ENTITY_DECL:
-+ case XML_PARSER_PI:
-+ case XML_PARSER_CDATA_SECTION:
-+ case XML_PARSER_COMMENT:
-+ case XML_PARSER_SYSTEM_LITERAL:
-+ /* we just ignore it there */
-+ return;
-+ case XML_PARSER_START_TAG:
-+ return;
-+ case XML_PARSER_END_TAG:
-+ return;
-+ case XML_PARSER_EOF:
-+ ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "CharRef at EOF\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_PROLOG:
-+ case XML_PARSER_START:
-+ case XML_PARSER_MISC:
-+ ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_EPILOG:
-+ ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "CharRef in epilog!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_DTD:
-+ ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "CharRef are forbiden in DTDs!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_ENTITY_VALUE:
-+ /*
-+ * NOTE: in the case of entity values, we don't do the
-+ * substitution here since we need the literal
-+ * entity value to be able to save the internal
-+ * subset of the document.
-+ * This will be handled by xmlStringDecodeEntities
-+ */
-+ return;
-+ case XML_PARSER_CONTENT:
-+ return;
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ /* ctxt->token = xmlParseCharRef(ctxt); */
-+ return;
-+ case XML_PARSER_IGNORE:
-+ return;
-+ }
-+ return;
-+ }
-+
-+ switch(ctxt->instate) {
-+ case XML_PARSER_CDATA_SECTION:
-+ return;
-+ case XML_PARSER_PI:
-+ case XML_PARSER_COMMENT:
-+ case XML_PARSER_SYSTEM_LITERAL:
-+ case XML_PARSER_CONTENT:
-+ return;
-+ case XML_PARSER_START_TAG:
-+ return;
-+ case XML_PARSER_END_TAG:
-+ return;
-+ case XML_PARSER_EOF:
-+ ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Reference at EOF\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_PROLOG:
-+ case XML_PARSER_START:
-+ case XML_PARSER_MISC:
-+ ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Reference in prolog!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_EPILOG:
-+ ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Reference in epilog!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_ENTITY_VALUE:
-+ /*
-+ * NOTE: in the case of entity values, we don't do the
-+ * substitution here since we need the literal
-+ * entity value to be able to save the internal
-+ * subset of the document.
-+ * This will be handled by xmlStringDecodeEntities
-+ */
-+ return;
-+ case XML_PARSER_ATTRIBUTE_VALUE:
-+ /*
-+ * NOTE: in the case of attributes values, we don't do the
-+ * substitution here unless we are in a mode where
-+ * the parser is explicitely asked to substitute
-+ * entities. The SAX callback is called with values
-+ * without entity substitution.
-+ * This will then be handled by xmlStringDecodeEntities
-+ */
-+ return;
-+ case XML_PARSER_ENTITY_DECL:
-+ /*
-+ * we just ignore it there
-+ * the substitution will be done once the entity is referenced
-+ */
-+ return;
-+ case XML_PARSER_DTD:
-+ ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity references are forbiden in DTDs!\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ case XML_PARSER_IGNORE:
-+ return;
-+ }
-+
-+/* TODO: this seems not reached anymore .... Verify ... */
-+xmlGenericError(xmlGenericErrorContext,
-+ "Reached deprecated section in xmlParserHandleReference()\n");
-+xmlGenericError(xmlGenericErrorContext,
-+ "Please forward the document to Daniel.Veillard@w3.org\n");
-+xmlGenericError(xmlGenericErrorContext,
-+ "indicating the version: %s, thanks !\n", xmlParserVersion);
-+ NEXT;
-+ name = xmlScanName(ctxt);
-+ if (name == NULL) {
-+ ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "Entity reference: no name\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->token = '&';
-+ return;
-+ }
-+ if (NXT(xmlStrlen(name)) != ';') {
-+ ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity reference: ';' expected\n");
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ ctxt->token = '&';
-+ xmlFree(name);
-+ return;
-+ }
-+ SKIP(xmlStrlen(name) + 1);
-+ if (ctxt->sax != NULL) {
-+ if (ctxt->sax->getEntity != NULL)
-+ ent = ctxt->sax->getEntity(ctxt->userData, name);
-+ }
-+
-+ /*
-+ * [ WFC: Entity Declared ]
-+ * the Name given in the entity reference must match that in an entity
-+ * declaration, except that well-formed documents need not declare any
-+ * of the following entities: amp, lt, gt, apos, quot.
-+ */
-+ if (ent == NULL)
-+ ent = xmlGetPredefinedEntity(name);
-+ if (ent == NULL) {
-+ ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity reference: entity %s not declared\n",
-+ name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ xmlFree(name);
-+ return;
-+ }
-+
-+ /*
-+ * [ WFC: Parsed Entity ]
-+ * An entity reference must not contain the name of an unparsed entity
-+ */
-+ if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-+ ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData,
-+ "Entity reference to unparsed entity %s\n", name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ }
-+
-+ if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
-+ ctxt->token = ent->content[0];
-+ xmlFree(name);
-+ return;
-+ }
-+ input = xmlNewEntityInputStream(ctxt, ent);
-+ xmlPushInput(ctxt, input);
-+ xmlFree(name);
-+#endif
-+ return;
-+}
-+
-+/**
-+ * xmlHandleEntity:
-+ * @ctxt: an XML parser context
-+ * @entity: an XML entity pointer.
-+ *
-+ * Default handling of defined entities, when should we define a new input
-+ * stream ? When do we just handle that as a set of chars ?
-+ *
-+ * OBSOLETE: to be removed at some point.
-+ */
-+
-+void
-+xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlHandleEntity() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+
-+#if 0
-+ int len;
-+ xmlParserInputPtr input;
-+
-+ if (entity->content == NULL) {
-+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-+ ctxt->sax->error(ctxt->userData, "xmlHandleEntity %s: content == NULL\n",
-+ entity->name);
-+ ctxt->wellFormed = 0;
-+ ctxt->disableSAX = 1;
-+ return;
-+ }
-+ len = xmlStrlen(entity->content);
-+ if (len <= 2) goto handle_as_char;
-+
-+ /*
-+ * Redefine its content as an input stream.
-+ */
-+ input = xmlNewEntityInputStream(ctxt, entity);
-+ xmlPushInput(ctxt, input);
-+ return;
-+
-+handle_as_char:
-+ /*
-+ * Just handle the content as a set of chars.
-+ */
-+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-+ (ctxt->sax->characters != NULL))
-+ ctxt->sax->characters(ctxt->userData, entity->content, len);
-+#endif
-+}
-+
-+/**
-+ * xmlNewGlobalNs:
-+ * @doc: the document carrying the namespace
-+ * @href: the URI associated
-+ * @prefix: the prefix for the namespace
-+ *
-+ * Creation of a Namespace, the old way using PI and without scoping
-+ * DEPRECATED !!!
-+ * It now create a namespace on the root element of the document if found.
-+ * Returns NULL this functionnality had been removed
-+ */
-+xmlNsPtr
-+xmlNewGlobalNs(xmlDocPtr doc, const xmlChar *href, const xmlChar *prefix) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewGlobalNs() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+ return(NULL);
-+#if 0
-+ xmlNodePtr root;
-+
-+ xmlNsPtr cur;
-+
-+ root = xmlDocGetRootElement(doc);
-+ if (root != NULL)
-+ return(xmlNewNs(root, href, prefix));
-+
-+ /*
-+ * if there is no root element yet, create an old Namespace type
-+ * and it will be moved to the root at save time.
-+ */
-+ cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewGlobalNs : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNs));
-+ cur->type = XML_GLOBAL_NAMESPACE;
-+
-+ if (href != NULL)
-+ cur->href = xmlStrdup(href);
-+ if (prefix != NULL)
-+ cur->prefix = xmlStrdup(prefix);
-+
-+ /*
-+ * Add it at the end to preserve parsing order ...
-+ */
-+ if (doc != NULL) {
-+ if (doc->oldNs == NULL) {
-+ doc->oldNs = cur;
-+ } else {
-+ xmlNsPtr prev = doc->oldNs;
-+
-+ while (prev->next != NULL) prev = prev->next;
-+ prev->next = cur;
-+ }
-+ }
-+
-+ return(NULL);
-+#endif
-+}
-+
-+/**
-+ * xmlUpgradeOldNs:
-+ * @doc: a document pointer
-+ *
-+ * Upgrade old style Namespaces (PI) and move them to the root of the document.
-+ * DEPRECATED
-+ */
-+void
-+xmlUpgradeOldNs(xmlDocPtr doc) {
-+ static int deprecated = 0;
-+ if (!deprecated) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewGlobalNs() deprecated function reached\n");
-+ deprecated = 1;
-+ }
-+#if 0
-+ xmlNsPtr cur;
-+
-+ if ((doc == NULL) || (doc->oldNs == NULL)) return;
-+ if (doc->children == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlUpgradeOldNs: failed no root !\n");
-+#endif
-+ return;
-+ }
-+
-+ cur = doc->oldNs;
-+ while (cur->next != NULL) {
-+ cur->type = XML_LOCAL_NAMESPACE;
-+ cur = cur->next;
-+ }
-+ cur->type = XML_LOCAL_NAMESPACE;
-+ cur->next = doc->children->nsDef;
-+ doc->children->nsDef = doc->oldNs;
-+ doc->oldNs = NULL;
-+#endif
-+}
-+
-diff -Nru libxml2-2.3.0/libxml/parserInternals.h libxml2-2.3.0.new/libxml/parserInternals.h
---- libxml2-2.3.0/libxml/parserInternals.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/parserInternals.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,314 @@
-+/*
-+ * parserInternals.h : internals routines exported by the parser.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ *
-+ * 14 Nov 2000 ht - truncated declaration of xmlParseElementChildrenContentDecl
-+ * for VMS
-+ *
-+ */
-+
-+#ifndef __XML_PARSER_INTERNALS_H__
-+#define __XML_PARSER_INTERNALS_H__
-+
-+#include <libxml/parser.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+ /*
-+ * Identifiers can be longer, but this will be more costly
-+ * at runtime.
-+ */
-+#define XML_MAX_NAMELEN 100
-+
-+/*
-+ * The parser tries to always have that amount of input ready
-+ * one of the point is providing context when reporting errors
-+ */
-+#define INPUT_CHUNK 250
-+
-+/************************************************************************
-+ * *
-+ * UNICODE version of the macros. *
-+ * *
-+ ************************************************************************/
-+/*
-+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-+ * | [#x10000-#x10FFFF]
-+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
-+ */
-+#define IS_CHAR(c) \
-+ (((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) || \
-+ (((c) >= 0x20) && ((c) <= 0xD7FF)) || \
-+ (((c) >= 0xE000) && ((c) <= 0xFFFD)) || \
-+ (((c) >= 0x10000) && ((c) <= 0x10FFFF)))
-+
-+/*
-+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
-+ */
-+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
-+ ((c) == 0x0D))
-+
-+/*
-+ * [85] BaseChar ::= ... long list see REC ...
-+ */
-+#define IS_BASECHAR(c) xmlIsBaseChar(c)
-+
-+/*
-+ * [88] Digit ::= ... long list see REC ...
-+ */
-+#define IS_DIGIT(c) xmlIsDigit(c)
-+
-+/*
-+ * [87] CombiningChar ::= ... long list see REC ...
-+ */
-+#define IS_COMBINING(c) xmlIsCombining(c)
-+
-+/*
-+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
-+ * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
-+ * [#x309D-#x309E] | [#x30FC-#x30FE]
-+ */
-+#define IS_EXTENDER(c) xmlIsExtender(c)
-+
-+/*
-+ * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
-+ */
-+#define IS_IDEOGRAPHIC(c) xmlIsIdeographic(c)
-+
-+/*
-+ * [84] Letter ::= BaseChar | Ideographic
-+ */
-+#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
-+
-+
-+/*
-+ * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-+ */
-+#define IS_PUBIDCHAR(c) xmlIsPubidChar(c)
-+
-+#define SKIP_EOL(p) \
-+ if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; } \
-+ if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
-+
-+#define MOVETO_ENDTAG(p) \
-+ while ((*p) && (*(p) != '>')) (p)++
-+
-+#define MOVETO_STARTTAG(p) \
-+ while ((*p) && (*(p) != '<')) (p)++
-+
-+/**
-+ * Global vaiables affecting the default parser behaviour.
-+ */
-+
-+LIBXML_DLL_IMPORT extern int xmlParserDebugEntities;
-+LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
-+LIBXML_DLL_IMPORT extern int xmlParserDebugEntities;
-+LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
-+LIBXML_DLL_IMPORT extern int xmlDoValidityCheckingDefaultValue;
-+LIBXML_DLL_IMPORT extern int xmlLoadExtDtdDefaultValue;
-+LIBXML_DLL_IMPORT extern int xmlPedanticParserDefaultValue;
-+LIBXML_DLL_IMPORT extern int xmlKeepBlanksDefaultValue;
-+LIBXML_DLL_IMPORT extern xmlChar xmlStringText[];
-+LIBXML_DLL_IMPORT extern xmlChar xmlStringTextNoenc[];
-+LIBXML_DLL_IMPORT extern xmlChar xmlStringComment[];
-+
-+/*
-+ * Function to finish teh work of the macros where needed
-+ */
-+int xmlIsBaseChar (int c);
-+int xmlIsBlank (int c);
-+int xmlIsPubidChar (int c);
-+int xmlIsLetter (int c);
-+int xmlIsDigit (int c);
-+int xmlIsIdeographic(int c);
-+int xmlIsCombining (int c);
-+int xmlIsExtender (int c);
-+int xmlIsCombining (int c);
-+int xmlIsChar (int c);
-+
-+/**
-+ * Parser context
-+ */
-+xmlParserCtxtPtr xmlCreateDocParserCtxt (xmlChar *cur);
-+xmlParserCtxtPtr xmlCreateFileParserCtxt (const char *filename);
-+xmlParserCtxtPtr xmlCreateMemoryParserCtxt(char *buffer,
-+ int size);
-+xmlParserCtxtPtr xmlNewParserCtxt (void);
-+xmlParserCtxtPtr xmlCreateEntityParserCtxt(const xmlChar *URL,
-+ const xmlChar *ID,
-+ const xmlChar *base);
-+int xmlSwitchEncoding (xmlParserCtxtPtr ctxt,
-+ xmlCharEncoding enc);
-+int xmlSwitchToEncoding (xmlParserCtxtPtr ctxt,
-+ xmlCharEncodingHandlerPtr handler);
-+void xmlFreeParserCtxt (xmlParserCtxtPtr ctxt);
-+
-+/**
-+ * Entities
-+ */
-+void xmlHandleEntity (xmlParserCtxtPtr ctxt,
-+ xmlEntityPtr entity);
-+
-+/**
-+ * Input Streams
-+ */
-+xmlParserInputPtr xmlNewEntityInputStream (xmlParserCtxtPtr ctxt,
-+ xmlEntityPtr entity);
-+void xmlPushInput (xmlParserCtxtPtr ctxt,
-+ xmlParserInputPtr input);
-+xmlChar xmlPopInput (xmlParserCtxtPtr ctxt);
-+void xmlFreeInputStream (xmlParserInputPtr input);
-+xmlParserInputPtr xmlNewInputFromFile (xmlParserCtxtPtr ctxt,
-+ const char *filename);
-+xmlParserInputPtr xmlNewInputStream (xmlParserCtxtPtr ctxt);
-+
-+/**
-+ * Namespaces.
-+ */
-+xmlChar * xmlSplitQName (xmlParserCtxtPtr ctxt,
-+ const xmlChar *name,
-+ xmlChar **prefix);
-+xmlChar * xmlNamespaceParseNCName (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlNamespaceParseQName (xmlParserCtxtPtr ctxt,
-+ xmlChar **prefix);
-+xmlChar * xmlNamespaceParseNSDef (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseQuotedString (xmlParserCtxtPtr ctxt);
-+void xmlParseNamespace (xmlParserCtxtPtr ctxt);
-+
-+/**
-+ * Generic production rules
-+ */
-+xmlChar * xmlScanName (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseName (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseNmtoken (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseEntityValue (xmlParserCtxtPtr ctxt,
-+ xmlChar **orig);
-+xmlChar * xmlParseAttValue (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseSystemLiteral (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParsePubidLiteral (xmlParserCtxtPtr ctxt);
-+void xmlParseCharData (xmlParserCtxtPtr ctxt,
-+ int cdata);
-+xmlChar * xmlParseExternalID (xmlParserCtxtPtr ctxt,
-+ xmlChar **publicID,
-+ int strict);
-+void xmlParseComment (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParsePITarget (xmlParserCtxtPtr ctxt);
-+void xmlParsePI (xmlParserCtxtPtr ctxt);
-+void xmlParseNotationDecl (xmlParserCtxtPtr ctxt);
-+void xmlParseEntityDecl (xmlParserCtxtPtr ctxt);
-+int xmlParseDefaultDecl (xmlParserCtxtPtr ctxt,
-+ xmlChar **value);
-+xmlEnumerationPtr xmlParseNotationType (xmlParserCtxtPtr ctxt);
-+xmlEnumerationPtr xmlParseEnumerationType (xmlParserCtxtPtr ctxt);
-+int xmlParseEnumeratedType (xmlParserCtxtPtr ctxt,
-+ xmlEnumerationPtr *tree);
-+int xmlParseAttributeType (xmlParserCtxtPtr ctxt,
-+ xmlEnumerationPtr *tree);
-+void xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt);
-+xmlElementContentPtr xmlParseElementMixedContentDecl
-+ (xmlParserCtxtPtr ctxt);
-+#ifdef VMS
-+xmlElementContentPtr xmlParseElementChildrenContentD
-+ (xmlParserCtxtPtr ctxt);
-+#define xmlParseElementChildrenContentDecl xmlParseElementChildrenContentD
-+#else
-+xmlElementContentPtr xmlParseElementChildrenContentDecl
-+ (xmlParserCtxtPtr ctxt);
-+#endif
-+int xmlParseElementContentDecl(xmlParserCtxtPtr ctxt,
-+ xmlChar *name,
-+ xmlElementContentPtr *result);
-+int xmlParseElementDecl (xmlParserCtxtPtr ctxt);
-+void xmlParseMarkupDecl (xmlParserCtxtPtr ctxt);
-+int xmlParseCharRef (xmlParserCtxtPtr ctxt);
-+xmlEntityPtr xmlParseEntityRef (xmlParserCtxtPtr ctxt);
-+void xmlParseReference (xmlParserCtxtPtr ctxt);
-+void xmlParsePEReference (xmlParserCtxtPtr ctxt);
-+void xmlParseDocTypeDecl (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseAttribute (xmlParserCtxtPtr ctxt,
-+ xmlChar **value);
-+xmlChar * xmlParseStartTag (xmlParserCtxtPtr ctxt);
-+void xmlParseEndTag (xmlParserCtxtPtr ctxt);
-+void xmlParseCDSect (xmlParserCtxtPtr ctxt);
-+void xmlParseContent (xmlParserCtxtPtr ctxt);
-+void xmlParseElement (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseVersionNum (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseVersionInfo (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseEncName (xmlParserCtxtPtr ctxt);
-+xmlChar * xmlParseEncodingDecl (xmlParserCtxtPtr ctxt);
-+int xmlParseSDDecl (xmlParserCtxtPtr ctxt);
-+void xmlParseXMLDecl (xmlParserCtxtPtr ctxt);
-+void xmlParseTextDecl (xmlParserCtxtPtr ctxt);
-+void xmlParseMisc (xmlParserCtxtPtr ctxt);
-+void xmlParseExternalSubset (xmlParserCtxtPtr ctxt,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+/*
-+ * Entities substitution
-+ */
-+#define XML_SUBSTITUTE_NONE 0
-+#define XML_SUBSTITUTE_REF 1
-+#define XML_SUBSTITUTE_PEREF 2
-+#define XML_SUBSTITUTE_BOTH 3
-+
-+xmlChar * xmlDecodeEntities (xmlParserCtxtPtr ctxt,
-+ int len,
-+ int what,
-+ xmlChar end,
-+ xmlChar end2,
-+ xmlChar end3);
-+xmlChar * xmlStringDecodeEntities (xmlParserCtxtPtr ctxt,
-+ const xmlChar *str,
-+ int what,
-+ xmlChar end,
-+ xmlChar end2,
-+ xmlChar end3);
-+
-+/*
-+ * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP
-+ */
-+int nodePush (xmlParserCtxtPtr ctxt,
-+ xmlNodePtr value);
-+xmlNodePtr nodePop (xmlParserCtxtPtr ctxt);
-+int inputPush (xmlParserCtxtPtr ctxt,
-+ xmlParserInputPtr value);
-+xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
-+
-+/*
-+ * other comodities shared between parser.c and parserInternals
-+ */
-+int xmlSkipBlankChars (xmlParserCtxtPtr ctxt);
-+int xmlStringCurrentChar (xmlParserCtxtPtr ctxt,
-+ const xmlChar *cur,
-+ int *len);
-+void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
-+void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
-+xmlChar *namePop (xmlParserCtxtPtr ctxt);
-+int xmlCheckLanguageID (const xmlChar *lang);
-+
-+/*
-+ * Really core function shared with HTML parser
-+ */
-+int xmlCurrentChar (xmlParserCtxtPtr ctxt,
-+ int *len);
-+int xmlCopyChar (int len,
-+ xmlChar *out,
-+ int val);
-+void xmlNextChar (xmlParserCtxtPtr ctxt);
-+void xmlParserInputShrink (xmlParserInputPtr in);
-+
-+#ifdef LIBXML_HTML_ENABLED
-+/*
-+ * Actually comes from the HTML parser but launched from the init stuff
-+ */
-+void htmlInitAutoClose (void);
-+#endif
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_PARSER_INTERNALS_H__ */
-diff -Nru libxml2-2.3.0/libxml/tree.c libxml2-2.3.0.new/libxml/tree.c
---- libxml2-2.3.0/libxml/tree.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/tree.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,6039 @@
-+/*
-+ * tree.c : implemetation of access function for an XML tree.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ *
-+ * 14 Nov 2000 ht - Changed the name of function xmlBufferWriteChar under VMS
-+ * as it was similar to xmlBufferWriteCHAR when compiling without case
-+ * sensitivity.
-+ *
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h> /* for memset() only ! */
-+
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_ZLIB_H
-+#include <zlib.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/entities.h>
-+#include <libxml/valid.h>
-+#include <libxml/xmlerror.h>
-+
-+xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 };
-+xmlChar xmlStringTextNoenc[] =
-+ { 't', 'e', 'x', 't', 'n', 'o', 'e', 'n', 'c', 0 };
-+xmlChar xmlStringComment[] = { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
-+int oldXMLWDcompatibility = 0;
-+int xmlIndentTreeOutput = 0;
-+xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
-+
-+static int xmlCompressMode = 0;
-+static int xmlCheckDTD = 1;
-+int xmlSaveNoEmptyTags = 0;
-+
-+#define IS_BLANK(c) \
-+ (((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
-+
-+#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) { \
-+ xmlNodePtr ulccur = (n)->children; \
-+ if (ulccur == NULL) { \
-+ (n)->last = NULL; \
-+ } else { \
-+ while (ulccur->next != NULL) { \
-+ ulccur->parent = (n); \
-+ ulccur = ulccur->next; \
-+ } \
-+ ulccur->parent = (n); \
-+ (n)->last = ulccur; \
-+}}
-+
-+/* #define DEBUG_BUFFER */
-+/* #define DEBUG_TREE */
-+
-+/************************************************************************
-+ * *
-+ * Allocation and deallocation of basic structures *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlSetBufferAllocationScheme:
-+ * @scheme: allocation method to use
-+ *
-+ * Set the buffer allocation method. Types are
-+ * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
-+ * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
-+ * improves performance
-+ */
-+void
-+xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
-+ xmlBufferAllocScheme = scheme;
-+}
-+
-+/**
-+ * xmlGetBufferAllocationScheme:
-+ *
-+ * Types are
-+ * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
-+ * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
-+ * improves performance
-+ *
-+ * Returns the current allocation scheme
-+ */
-+xmlBufferAllocationScheme
-+xmlGetBufferAllocationScheme() {
-+ return xmlBufferAllocScheme;
-+}
-+
-+/**
-+ * xmlNewNs:
-+ * @node: the element carrying the namespace
-+ * @href: the URI associated
-+ * @prefix: the prefix for the namespace
-+ *
-+ * Creation of a new Namespace. This function will refuse to create
-+ * a namespace with a similar prefix than an existing one present on this
-+ * node.
-+ * We use href==NULL in the case of an element creation where the namespace
-+ * was not defined.
-+ * Returns returns a new namespace pointer or NULL
-+ */
-+xmlNsPtr
-+xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
-+ xmlNsPtr cur;
-+
-+ if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
-+ return(NULL);
-+
-+ /*
-+ * Allocate a new Namespace and fill the fields.
-+ */
-+ cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewNs : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNs));
-+ cur->type = XML_LOCAL_NAMESPACE;
-+
-+ if (href != NULL)
-+ cur->href = xmlStrdup(href);
-+ if (prefix != NULL)
-+ cur->prefix = xmlStrdup(prefix);
-+
-+ /*
-+ * Add it at the end to preserve parsing order ...
-+ * and checks for existing use of the prefix
-+ */
-+ if (node != NULL) {
-+ if (node->nsDef == NULL) {
-+ node->nsDef = cur;
-+ } else {
-+ xmlNsPtr prev = node->nsDef;
-+
-+ if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
-+ (xmlStrEqual(prev->prefix, cur->prefix))) {
-+ xmlFreeNs(cur);
-+ return(NULL);
-+ }
-+ while (prev->next != NULL) {
-+ prev = prev->next;
-+ if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
-+ (xmlStrEqual(prev->prefix, cur->prefix))) {
-+ xmlFreeNs(cur);
-+ return(NULL);
-+ }
-+ }
-+ prev->next = cur;
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlSetNs:
-+ * @node: a node in the document
-+ * @ns: a namespace pointer
-+ *
-+ * Associate a namespace to a node, a posteriori.
-+ */
-+void
-+xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
-+ if (node == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSetNs: node == NULL\n");
-+#endif
-+ return;
-+ }
-+ node->ns = ns;
-+}
-+
-+/**
-+ * xmlFreeNs:
-+ * @cur: the namespace pointer
-+ *
-+ * Free up the structures associated to a namespace
-+ */
-+void
-+xmlFreeNs(xmlNsPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeNs : ns == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->href != NULL) xmlFree((char *) cur->href);
-+ if (cur->prefix != NULL) xmlFree((char *) cur->prefix);
-+ memset(cur, -1, sizeof(xmlNs));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlFreeNsList:
-+ * @cur: the first namespace pointer
-+ *
-+ * Free up all the structures associated to the chained namespaces.
-+ */
-+void
-+xmlFreeNsList(xmlNsPtr cur) {
-+ xmlNsPtr next;
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeNsList : ns == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ next = cur->next;
-+ xmlFreeNs(cur);
-+ cur = next;
-+ }
-+}
-+
-+/**
-+ * xmlNewDtd:
-+ * @doc: the document pointer
-+ * @name: the DTD name
-+ * @ExternalID: the external ID
-+ * @SystemID: the system ID
-+ *
-+ * Creation of a new DTD for the external subset. To create an
-+ * internal subset, use xmlCreateIntSubset().
-+ *
-+ * Returns a pointer to the new DTD structure
-+ */
-+xmlDtdPtr
-+xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
-+ const xmlChar *ExternalID, const xmlChar *SystemID) {
-+ xmlDtdPtr cur;
-+
-+ if ((doc != NULL) && (doc->extSubset != NULL)) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewDtd(%s): document %s already have a DTD %s\n",
-+ /* !!! */ (char *) name, doc->name,
-+ /* !!! */ (char *)doc->extSubset->name);
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new DTD and fill the fields.
-+ */
-+ cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewDtd : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0 , sizeof(xmlDtd));
-+ cur->type = XML_DTD_NODE;
-+
-+ if (name != NULL)
-+ cur->name = xmlStrdup(name);
-+ if (ExternalID != NULL)
-+ cur->ExternalID = xmlStrdup(ExternalID);
-+ if (SystemID != NULL)
-+ cur->SystemID = xmlStrdup(SystemID);
-+ if (doc != NULL)
-+ doc->extSubset = cur;
-+ cur->doc = doc;
-+
-+ return(cur);
-+}
-+
-+/**
-+ * xmlGetIntSubset:
-+ * @doc: the document pointer
-+ *
-+ * Get the internal subset of a document
-+ * Returns a pointer to the DTD structure or NULL if not found
-+ */
-+
-+xmlDtdPtr
-+xmlGetIntSubset(xmlDocPtr doc) {
-+ xmlNodePtr cur;
-+
-+ if (doc == NULL)
-+ return(NULL);
-+ cur = doc->children;
-+ while (cur != NULL) {
-+ if (cur->type == XML_DTD_NODE)
-+ return((xmlDtdPtr) cur);
-+ cur = cur->next;
-+ }
-+ return((xmlDtdPtr) doc->intSubset);
-+}
-+
-+/**
-+ * xmlCreateIntSubset:
-+ * @doc: the document pointer
-+ * @name: the DTD name
-+ * @ExternalID: the external ID
-+ * @SystemID: the system ID
-+ *
-+ * Create the internal subset of a document
-+ * Returns a pointer to the new DTD structure
-+ */
-+xmlDtdPtr
-+xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
-+ const xmlChar *ExternalID, const xmlChar *SystemID) {
-+ xmlDtdPtr cur;
-+
-+ if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+
-+ "xmlCreateIntSubset(): document %s already have an internal subset\n",
-+ doc->name);
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new DTD and fill the fields.
-+ */
-+ cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewDtd : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlDtd));
-+ cur->type = XML_DTD_NODE;
-+
-+ if (name != NULL)
-+ cur->name = xmlStrdup(name);
-+ if (ExternalID != NULL)
-+ cur->ExternalID = xmlStrdup(ExternalID);
-+ if (SystemID != NULL)
-+ cur->SystemID = xmlStrdup(SystemID);
-+ if (doc != NULL) {
-+ doc->intSubset = cur;
-+ cur->parent = doc;
-+ cur->doc = doc;
-+ if (doc->children == NULL) {
-+ doc->children = (xmlNodePtr) cur;
-+ doc->last = (xmlNodePtr) cur;
-+ } else {
-+ xmlNodePtr prev;
-+
-+ if (doc->type == XML_HTML_DOCUMENT_NODE) {
-+ prev = doc->children;
-+ prev->prev = (xmlNodePtr) cur;
-+ cur->next = prev;
-+ doc->children = (xmlNodePtr) cur;
-+ } else {
-+ prev = doc->last;
-+ prev->next = (xmlNodePtr) cur;
-+ cur->prev = prev;
-+ doc->last = (xmlNodePtr) cur;
-+ }
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlFreeDtd:
-+ * @cur: the DTD structure to free up
-+ *
-+ * Free a DTD structure.
-+ */
-+void
-+xmlFreeDtd(xmlDtdPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeDtd : DTD == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->children != NULL) {
-+ xmlNodePtr next, c = cur->children;
-+
-+ /*
-+ * Cleanup all the DTD comments they are not in the Dtd
-+ * indexes.
-+ */
-+ while (c != NULL) {
-+ next = c->next;
-+ if (c->type == XML_COMMENT_NODE) {
-+ xmlUnlinkNode(c);
-+ xmlFreeNode(c);
-+ }
-+ c = next;
-+ }
-+ }
-+ if (cur->name != NULL) xmlFree((char *) cur->name);
-+ if (cur->SystemID != NULL) xmlFree((char *) cur->SystemID);
-+ if (cur->ExternalID != NULL) xmlFree((char *) cur->ExternalID);
-+ /* TODO !!! */
-+ if (cur->notations != NULL)
-+ xmlFreeNotationTable((xmlNotationTablePtr) cur->notations);
-+
-+ if (cur->elements != NULL)
-+ xmlFreeElementTable((xmlElementTablePtr) cur->elements);
-+ if (cur->attributes != NULL)
-+ xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes);
-+ if (cur->entities != NULL)
-+ xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
-+ if (cur->pentities != NULL)
-+ xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
-+
-+ memset(cur, -1, sizeof(xmlDtd));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlNewDoc:
-+ * @version: xmlChar string giving the version of XML "1.0"
-+ *
-+ * Returns a new document
-+ */
-+xmlDocPtr
-+xmlNewDoc(const xmlChar *version) {
-+ xmlDocPtr cur;
-+
-+ if (version == NULL)
-+ version = (const xmlChar *) "1.0";
-+
-+ /*
-+ * Allocate a new document and fill the fields.
-+ */
-+ cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewDoc : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlDoc));
-+ cur->type = XML_DOCUMENT_NODE;
-+
-+ cur->version = xmlStrdup(version);
-+ cur->standalone = -1;
-+ cur->compression = -1; /* not initialized */
-+ cur->doc = cur;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlFreeDoc:
-+ * @cur: pointer to the document
-+ * @:
-+ *
-+ * Free up all the structures used by a document, tree included.
-+ */
-+void
-+xmlFreeDoc(xmlDocPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeDoc : document == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->version != NULL) xmlFree((char *) cur->version);
-+ if (cur->name != NULL) xmlFree((char *) cur->name);
-+ if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
-+ if (cur->children != NULL) xmlFreeNodeList(cur->children);
-+ if (cur->intSubset != NULL) xmlFreeDtd(cur->intSubset);
-+ if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset);
-+ if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
-+ if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
-+ if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
-+ if (cur->URL != NULL) xmlFree((char *) cur->URL);
-+ memset(cur, -1, sizeof(xmlDoc));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlStringLenGetNodeList:
-+ * @doc: the document
-+ * @value: the value of the text
-+ * @len: the length of the string value
-+ *
-+ * Parse the value string and build the node list associated. Should
-+ * produce a flat tree with only TEXTs and ENTITY_REFs.
-+ * Returns a pointer to the first child
-+ */
-+xmlNodePtr
-+xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
-+ xmlNodePtr ret = NULL, last = NULL;
-+ xmlNodePtr node;
-+ xmlChar *val;
-+ const xmlChar *cur = value;
-+ const xmlChar *q;
-+ xmlEntityPtr ent;
-+
-+ if (value == NULL) return(NULL);
-+
-+ q = cur;
-+ while ((*cur != 0) && (cur - value < len)) {
-+ if (*cur == '&') {
-+ /*
-+ * Save the current text.
-+ */
-+ if (cur != q) {
-+ if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-+ xmlNodeAddContentLen(last, q, cur - q);
-+ } else {
-+ node = xmlNewDocTextLen(doc, q, cur - q);
-+ if (node == NULL) return(ret);
-+ if (last == NULL)
-+ last = ret = node;
-+ else {
-+ last->next = node;
-+ node->prev = last;
-+ last = node;
-+ }
-+ }
-+ }
-+ /*
-+ * Read the entity string
-+ */
-+ cur++;
-+ q = cur;
-+ while ((*cur != 0) && (cur - value < len) && (*cur != ';')) cur++;
-+ if ((*cur == 0) || (cur - value >= len)) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlStringLenGetNodeList: unterminated entity %30s\n", q);
-+#endif
-+ return(ret);
-+ }
-+ if (cur != q) {
-+ /*
-+ * Predefined entities don't generate nodes
-+ */
-+ val = xmlStrndup(q, cur - q);
-+ ent = xmlGetDocEntity(doc, val);
-+ if ((ent != NULL) &&
-+ (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-+ if (last == NULL) {
-+ node = xmlNewDocText(doc, ent->content);
-+ last = ret = node;
-+ } else
-+ xmlNodeAddContent(last, ent->content);
-+
-+ } else {
-+ /*
-+ * Create a new REFERENCE_REF node
-+ */
-+ node = xmlNewReference(doc, val);
-+ if (node == NULL) {
-+ if (val != NULL) xmlFree(val);
-+ return(ret);
-+ }
-+ if (last == NULL)
-+ last = ret = node;
-+ else {
-+ last->next = node;
-+ node->prev = last;
-+ last = node;
-+ }
-+ }
-+ xmlFree(val);
-+ }
-+ cur++;
-+ q = cur;
-+ } else
-+ cur++;
-+ }
-+ if (cur != q) {
-+ /*
-+ * Handle the last piece of text.
-+ */
-+ if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-+ xmlNodeAddContentLen(last, q, cur - q);
-+ } else {
-+ node = xmlNewDocTextLen(doc, q, cur - q);
-+ if (node == NULL) return(ret);
-+ if (last == NULL)
-+ last = ret = node;
-+ else {
-+ last->next = node;
-+ node->prev = last;
-+ last = node;
-+ }
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlStringGetNodeList:
-+ * @doc: the document
-+ * @value: the value of the attribute
-+ *
-+ * Parse the value string and build the node list associated. Should
-+ * produce a flat tree with only TEXTs and ENTITY_REFs.
-+ * Returns a pointer to the first child
-+ */
-+xmlNodePtr
-+xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
-+ xmlNodePtr ret = NULL, last = NULL;
-+ xmlNodePtr node;
-+ xmlChar *val;
-+ const xmlChar *cur = value;
-+ const xmlChar *q;
-+ xmlEntityPtr ent;
-+
-+ if (value == NULL) return(NULL);
-+
-+ q = cur;
-+ while (*cur != 0) {
-+ if (*cur == '&') {
-+ /*
-+ * Save the current text.
-+ */
-+ if (cur != q) {
-+ if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-+ xmlNodeAddContentLen(last, q, cur - q);
-+ } else {
-+ node = xmlNewDocTextLen(doc, q, cur - q);
-+ if (node == NULL) return(ret);
-+ if (last == NULL)
-+ last = ret = node;
-+ else {
-+ last->next = node;
-+ node->prev = last;
-+ last = node;
-+ }
-+ }
-+ }
-+ /*
-+ * Read the entity string
-+ */
-+ cur++;
-+ q = cur;
-+ while ((*cur != 0) && (*cur != ';')) cur++;
-+ if (*cur == 0) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlStringGetNodeList: unterminated entity %30s\n", q);
-+#endif
-+ return(ret);
-+ }
-+ if (cur != q) {
-+ /*
-+ * Predefined entities don't generate nodes
-+ */
-+ val = xmlStrndup(q, cur - q);
-+ ent = xmlGetDocEntity(doc, val);
-+ if ((ent != NULL) &&
-+ (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-+ if (last == NULL) {
-+ node = xmlNewDocText(doc, ent->content);
-+ last = ret = node;
-+ } else
-+ xmlNodeAddContent(last, ent->content);
-+
-+ } else {
-+ /*
-+ * Create a new REFERENCE_REF node
-+ */
-+ node = xmlNewReference(doc, val);
-+ if (node == NULL) {
-+ if (val != NULL) xmlFree(val);
-+ return(ret);
-+ }
-+ if (last == NULL)
-+ last = ret = node;
-+ else {
-+ last->next = node;
-+ node->prev = last;
-+ last = node;
-+ }
-+ }
-+ xmlFree(val);
-+ }
-+ cur++;
-+ q = cur;
-+ } else
-+ cur++;
-+ }
-+ if (cur != q) {
-+ /*
-+ * Handle the last piece of text.
-+ */
-+ if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-+ xmlNodeAddContentLen(last, q, cur - q);
-+ } else {
-+ node = xmlNewDocTextLen(doc, q, cur - q);
-+ if (node == NULL) return(ret);
-+ if (last == NULL)
-+ last = ret = node;
-+ else {
-+ last->next = node;
-+ node->prev = last;
-+ last = node;
-+ }
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlNodeListGetString:
-+ * @doc: the document
-+ * @list: a Node list
-+ * @inLine: should we replace entity contents or show their external form
-+ *
-+ * Returns the string equivalent to the text contained in the Node list
-+ * made of TEXTs and ENTITY_REFs
-+ * Returns a pointer to the string copy, the calller must free it.
-+ */
-+xmlChar *
-+xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
-+ xmlNodePtr node = list;
-+ xmlChar *ret = NULL;
-+ xmlEntityPtr ent;
-+
-+ if (list == NULL) return(NULL);
-+
-+ while (node != NULL) {
-+ if ((node->type == XML_TEXT_NODE) ||
-+ (node->type == XML_CDATA_SECTION_NODE)) {
-+ if (inLine) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret = xmlStrcat(ret, node->content);
-+#else
-+ ret = xmlStrcat(ret, xmlBufferContent(node->content));
-+#endif
-+ } else {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeEntitiesReentrant(doc, node->content);
-+#else
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(node->content));
-+#endif
-+ if (buffer != NULL) {
-+ ret = xmlStrcat(ret, buffer);
-+ xmlFree(buffer);
-+ }
-+ }
-+ } else if (node->type == XML_ENTITY_REF_NODE) {
-+ if (inLine) {
-+ ent = xmlGetDocEntity(doc, node->name);
-+ if (ent != NULL)
-+ ret = xmlStrcat(ret, ent->content);
-+ else {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret = xmlStrcat(ret, node->content);
-+#else
-+ ret = xmlStrcat(ret, xmlBufferContent(node->content));
-+#endif
-+ }
-+ } else {
-+ xmlChar buf[2];
-+ buf[0] = '&'; buf[1] = 0;
-+ ret = xmlStrncat(ret, buf, 1);
-+ ret = xmlStrcat(ret, node->name);
-+ buf[0] = ';'; buf[1] = 0;
-+ ret = xmlStrncat(ret, buf, 1);
-+ }
-+ }
-+#if 0
-+ else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlGetNodeListString : invalide node type %d\n",
-+ node->type);
-+ }
-+#endif
-+ node = node->next;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlNodeListGetRawString:
-+ * @doc: the document
-+ * @list: a Node list
-+ * @inLine: should we replace entity contents or show their external form
-+ *
-+ * Returns the string equivalent to the text contained in the Node list
-+ * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
-+ * this function doesn't do any character encoding handling.
-+ *
-+ * Returns a pointer to the string copy, the calller must free it.
-+ */
-+xmlChar *
-+xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
-+ xmlNodePtr node = list;
-+ xmlChar *ret = NULL;
-+ xmlEntityPtr ent;
-+
-+ if (list == NULL) return(NULL);
-+
-+ while (node != NULL) {
-+ if (node->type == XML_TEXT_NODE) {
-+ if (inLine) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret = xmlStrcat(ret, node->content);
-+#else
-+ ret = xmlStrcat(ret, xmlBufferContent(node->content));
-+#endif
-+ } else {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeSpecialChars(doc, node->content);
-+#else
-+ buffer = xmlEncodeSpecialChars(doc,
-+ xmlBufferContent(node->content));
-+#endif
-+ if (buffer != NULL) {
-+ ret = xmlStrcat(ret, buffer);
-+ xmlFree(buffer);
-+ }
-+ }
-+ } else if (node->type == XML_ENTITY_REF_NODE) {
-+ if (inLine) {
-+ ent = xmlGetDocEntity(doc, node->name);
-+ if (ent != NULL)
-+ ret = xmlStrcat(ret, ent->content);
-+ else {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret = xmlStrcat(ret, node->content);
-+#else
-+ ret = xmlStrcat(ret, xmlBufferContent(node->content));
-+#endif
-+ }
-+ } else {
-+ xmlChar buf[2];
-+ buf[0] = '&'; buf[1] = 0;
-+ ret = xmlStrncat(ret, buf, 1);
-+ ret = xmlStrcat(ret, node->name);
-+ buf[0] = ';'; buf[1] = 0;
-+ ret = xmlStrncat(ret, buf, 1);
-+ }
-+ }
-+#if 0
-+ else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlGetNodeListString : invalide node type %d\n",
-+ node->type);
-+ }
-+#endif
-+ node = node->next;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlNewProp:
-+ * @node: the holding node
-+ * @name: the name of the attribute
-+ * @value: the value of the attribute
-+ *
-+ * Create a new property carried by a node.
-+ * Returns a pointer to the attribute
-+ */
-+xmlAttrPtr
-+xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
-+ xmlAttrPtr cur;
-+ xmlDocPtr doc = NULL;
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewProp : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new property and fill the fields.
-+ */
-+ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewProp : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlAttr));
-+ cur->type = XML_ATTRIBUTE_NODE;
-+
-+ cur->parent = node;
-+ if (node != NULL) {
-+ doc = node->doc;
-+ cur->doc = doc;
-+ }
-+ cur->name = xmlStrdup(name);
-+ if (value != NULL) {
-+ xmlChar *buffer;
-+ xmlNodePtr tmp;
-+
-+ buffer = xmlEncodeEntitiesReentrant(doc, value);
-+ cur->children = xmlStringGetNodeList(doc, buffer);
-+ cur->last = NULL;
-+ tmp = cur->children;
-+ while (tmp != NULL) {
-+ tmp->parent = (xmlNodePtr) cur;
-+ tmp->doc = doc;
-+ if (tmp->next == NULL)
-+ cur->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ xmlFree(buffer);
-+ }
-+
-+ /*
-+ * Add it at the end to preserve parsing order ...
-+ */
-+ if (node != NULL) {
-+ if (node->properties == NULL) {
-+ node->properties = cur;
-+ } else {
-+ xmlAttrPtr prev = node->properties;
-+
-+ while (prev->next != NULL) prev = prev->next;
-+ prev->next = cur;
-+ cur->prev = prev;
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewNsProp:
-+ * @node: the holding node
-+ * @ns: the namespace
-+ * @name: the name of the attribute
-+ * @value: the value of the attribute
-+ *
-+ * Create a new property tagged with a namespace and carried by a node.
-+ * Returns a pointer to the attribute
-+ */
-+xmlAttrPtr
-+xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
-+ const xmlChar *value) {
-+ xmlAttrPtr cur;
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewProp : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new property and fill the fields.
-+ */
-+ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewProp : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlAttr));
-+ cur->type = XML_ATTRIBUTE_NODE;
-+
-+ cur->parent = node;
-+ if (node != NULL)
-+ cur->doc = node->doc;
-+ cur->ns = ns;
-+ cur->name = xmlStrdup(name);
-+ if (value != NULL) {
-+ xmlChar *buffer;
-+ xmlNodePtr tmp;
-+
-+ buffer = xmlEncodeEntitiesReentrant(node->doc, value);
-+ cur->children = xmlStringGetNodeList(node->doc, buffer);
-+ cur->last = NULL;
-+ tmp = cur->children;
-+ while (tmp != NULL) {
-+ tmp->parent = (xmlNodePtr) cur;
-+ if (tmp->next == NULL)
-+ cur->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ xmlFree(buffer);
-+ }
-+
-+ /*
-+ * Add it at the end to preserve parsing order ...
-+ */
-+ if (node != NULL) {
-+ if (node->properties == NULL) {
-+ node->properties = cur;
-+ } else {
-+ xmlAttrPtr prev = node->properties;
-+
-+ while (prev->next != NULL) prev = prev->next;
-+ prev->next = cur;
-+ cur->prev = prev;
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewDocProp:
-+ * @doc: the document
-+ * @name: the name of the attribute
-+ * @value: the value of the attribute
-+ *
-+ * Create a new property carried by a document.
-+ * Returns a pointer to the attribute
-+ */
-+xmlAttrPtr
-+xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
-+ xmlAttrPtr cur;
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewProp : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new property and fill the fields.
-+ */
-+ cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewProp : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlAttr));
-+ cur->type = XML_ATTRIBUTE_NODE;
-+
-+ cur->name = xmlStrdup(name);
-+ cur->doc = doc;
-+ if (value != NULL) {
-+ xmlNodePtr tmp;
-+
-+ cur->children = xmlStringGetNodeList(doc, value);
-+ cur->last = NULL;
-+
-+ tmp = cur->children;
-+ while (tmp != NULL) {
-+ tmp->parent = (xmlNodePtr) cur;
-+ if (tmp->next == NULL)
-+ cur->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlFreePropList:
-+ * @cur: the first property in the list
-+ *
-+ * Free a property and all its siblings, all the children are freed too.
-+ */
-+void
-+xmlFreePropList(xmlAttrPtr cur) {
-+ xmlAttrPtr next;
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreePropList : property == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ next = cur->next;
-+ xmlFreeProp(cur);
-+ cur = next;
-+ }
-+}
-+
-+/**
-+ * xmlFreeProp:
-+ * @cur: an attribute
-+ *
-+ * Free one attribute, all the content is freed too
-+ */
-+void
-+xmlFreeProp(xmlAttrPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeProp : property == NULL\n");
-+#endif
-+ return;
-+ }
-+ /* Check for ID removal -> leading to invalid references ! */
-+ if ((cur->parent != NULL) &&
-+ (xmlIsID(cur->parent->doc, cur->parent, cur)))
-+ xmlRemoveID(cur->parent->doc, cur);
-+ if (cur->name != NULL) xmlFree((char *) cur->name);
-+ if (cur->children != NULL) xmlFreeNodeList(cur->children);
-+ memset(cur, -1, sizeof(xmlAttr));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlRemoveProp:
-+ * @cur: an attribute
-+ *
-+ * Unlink and free one attribute, all the content is freed too
-+ * Note this doesn't work for namespace definition attributes
-+ *
-+ * Returns 0 if success and -1 in case of error.
-+ */
-+int
-+xmlRemoveProp(xmlAttrPtr cur) {
-+ xmlAttrPtr tmp;
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlRemoveProp : cur == NULL\n");
-+#endif
-+ return(-1);
-+ }
-+ if (cur->parent == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlRemoveProp : cur->parent == NULL\n");
-+#endif
-+ return(-1);
-+ }
-+ tmp = cur->parent->properties;
-+ if (tmp == cur) {
-+ cur->parent->properties = cur->next;
-+ xmlFreeProp(cur);
-+ return(0);
-+ }
-+ while (tmp != NULL) {
-+ if (tmp->next == cur) {
-+ tmp->next = cur->next;
-+ if (tmp->next != NULL)
-+ tmp->next->prev = tmp;
-+ xmlFreeProp(cur);
-+ return(0);
-+ }
-+ tmp = tmp->next;
-+ }
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlRemoveProp : attribute not owned by its node\n");
-+#endif
-+ return(-1);
-+}
-+
-+/**
-+ * xmlNewPI:
-+ * @name: the processing instruction name
-+ * @content: the PI content
-+ *
-+ * Creation of a processing instruction element.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewPI(const xmlChar *name, const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewPI : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewPI : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_PI_NODE;
-+
-+ cur->name = xmlStrdup(name);
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrdup(content);
-+#else
-+ cur->content = xmlBufferCreateSize(0);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, -1);
-+#endif
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewNode:
-+ * @ns: namespace if any
-+ * @name: the node name
-+ *
-+ * Creation of a new node element. @ns is optionnal (NULL).
-+ *
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewNode(xmlNsPtr ns, const xmlChar *name) {
-+ xmlNodePtr cur;
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewNode : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewNode : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_ELEMENT_NODE;
-+
-+ cur->name = xmlStrdup(name);
-+ cur->ns = ns;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewDocNode:
-+ * @doc: the document
-+ * @ns: namespace if any
-+ * @name: the node name
-+ * @content: the XML text content if any
-+ *
-+ * Creation of a new node element within a document. @ns and @content
-+ * are optionnal (NULL).
-+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
-+ * references, but XML special chars need to be escaped first by using
-+ * xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
-+ * need entities support.
-+ *
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
-+ const xmlChar *name, const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ cur = xmlNewNode(ns, name);
-+ if (cur != NULL) {
-+ cur->doc = doc;
-+ if (content != NULL) {
-+ cur->children = xmlStringGetNodeList(doc, content);
-+ UPDATE_LAST_CHILD_AND_PARENT(cur)
-+ }
-+ }
-+ return(cur);
-+}
-+
-+
-+/**
-+ * xmlNewDocRawNode:
-+ * @doc: the document
-+ * @ns: namespace if any
-+ * @name: the node name
-+ * @content: the text content if any
-+ *
-+ * Creation of a new node element within a document. @ns and @content
-+ * are optionnal (NULL).
-+ *
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
-+ const xmlChar *name, const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ cur = xmlNewNode(ns, name);
-+ if (cur != NULL) {
-+ cur->doc = doc;
-+ if (content != NULL) {
-+ cur->children = xmlNewDocText(doc, content);
-+ UPDATE_LAST_CHILD_AND_PARENT(cur)
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewDocFragment:
-+ * @doc: the document owning the fragment
-+ *
-+ * Creation of a new Fragment node.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewDocFragment(xmlDocPtr doc) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Allocate a new DocumentFragment node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewDocFragment : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_DOCUMENT_FRAG_NODE;
-+
-+ cur->doc = doc;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewText:
-+ * @content: the text content
-+ *
-+ * Creation of a new text node.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewText(const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewText : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_TEXT_NODE;
-+
-+ cur->name = xmlStringText;
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrdup(content);
-+#else
-+ cur->content = xmlBufferCreateSize(0);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, -1);
-+#endif
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewTextChild:
-+ * @parent: the parent node
-+ * @ns: a namespace if any
-+ * @name: the name of the child
-+ * @content: the text content of the child if any.
-+ *
-+ * Creation of a new child element, added at the end of @parent children list.
-+ * @ns and @content parameters are optionnal (NULL). If content is non NULL,
-+ * a child TEXT node will be created containing the string content.
-+ *
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
-+ const xmlChar *name, const xmlChar *content) {
-+ xmlNodePtr cur, prev;
-+
-+ if (parent == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewTextChild : parent == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewTextChild : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new node
-+ */
-+ if (ns == NULL)
-+ cur = xmlNewDocRawNode(parent->doc, parent->ns, name, content);
-+ else
-+ cur = xmlNewDocRawNode(parent->doc, ns, name, content);
-+ if (cur == NULL) return(NULL);
-+
-+ /*
-+ * add the new element at the end of the children list.
-+ */
-+ cur->type = XML_ELEMENT_NODE;
-+ cur->parent = parent;
-+ cur->doc = parent->doc;
-+ if (parent->children == NULL) {
-+ parent->children = cur;
-+ parent->last = cur;
-+ } else {
-+ prev = parent->last;
-+ prev->next = cur;
-+ cur->prev = prev;
-+ parent->last = cur;
-+ }
-+
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewCharRef:
-+ * @doc: the document
-+ * @name: the char ref string, starting with # or "&# ... ;"
-+ *
-+ * Creation of a new character reference node.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewText : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_ENTITY_REF_NODE;
-+
-+ cur->doc = doc;
-+ if (name[0] == '&') {
-+ int len;
-+ name++;
-+ len = xmlStrlen(name);
-+ if (name[len - 1] == ';')
-+ cur->name = xmlStrndup(name, len - 1);
-+ else
-+ cur->name = xmlStrndup(name, len);
-+ } else
-+ cur->name = xmlStrdup(name);
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewReference:
-+ * @doc: the document
-+ * @name: the reference name, or the reference string with & and ;
-+ *
-+ * Creation of a new reference node.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
-+ xmlNodePtr cur;
-+ xmlEntityPtr ent;
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewText : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_ENTITY_REF_NODE;
-+
-+ cur->doc = doc;
-+ if (name[0] == '&') {
-+ int len;
-+ name++;
-+ len = xmlStrlen(name);
-+ if (name[len - 1] == ';')
-+ cur->name = xmlStrndup(name, len - 1);
-+ else
-+ cur->name = xmlStrndup(name, len);
-+ } else
-+ cur->name = xmlStrdup(name);
-+
-+ ent = xmlGetDocEntity(doc, cur->name);
-+ if (ent != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = ent->content;
-+#else
-+ /*
-+ * CJN 11.18.99 this might be a problem, since the xmlBuffer gets
-+ * a copy of this pointer. Let's hope we don't manipulate it
-+ * later
-+ */
-+ cur->content = xmlBufferCreateSize(0);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ if (ent->content != NULL)
-+ xmlBufferAdd(cur->content, ent->content, -1);
-+#endif
-+ /*
-+ * The parent pointer in entity is a Dtd pointer and thus is NOT
-+ * updated. Not sure if this is 100% correct.
-+ * -George
-+ */
-+ cur->children = (xmlNodePtr) ent;
-+ cur->last = (xmlNodePtr) ent;
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewDocText:
-+ * @doc: the document
-+ * @content: the text content
-+ *
-+ * Creation of a new text node within a document.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ cur = xmlNewText(content);
-+ if (cur != NULL) cur->doc = doc;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewTextLen:
-+ * @content: the text content
-+ * @len: the text len.
-+ *
-+ * Creation of a new text node with an extra parameter for the content's lenght
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewTextLen(const xmlChar *content, int len) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewText : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_TEXT_NODE;
-+
-+ cur->name = xmlStringText;
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrndup(content, len);
-+#else
-+ cur->content = xmlBufferCreateSize(len);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, len);
-+#endif
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewDocTextLen:
-+ * @doc: the document
-+ * @content: the text content
-+ * @len: the text len.
-+ *
-+ * Creation of a new text node with an extra content lenght parameter. The
-+ * text node pertain to a given document.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
-+ xmlNodePtr cur;
-+
-+ cur = xmlNewTextLen(content, len);
-+ if (cur != NULL) cur->doc = doc;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewComment:
-+ * @content: the comment content
-+ *
-+ * Creation of a new node containing a comment.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewComment(const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewComment : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_COMMENT_NODE;
-+
-+ cur->name = xmlStringComment;
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrdup(content);
-+#else
-+ cur->content = xmlBufferCreateSize(0);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, -1);
-+#endif
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewCDataBlock:
-+ * @doc: the document
-+ * @content: the CData block content content
-+ * @len: the length of the block
-+ *
-+ * Creation of a new node containing a CData block.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
-+ xmlNodePtr cur;
-+
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewCDataBlock : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlNode));
-+ cur->type = XML_CDATA_SECTION_NODE;
-+
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrndup(content, len);
-+#else
-+ cur->content = xmlBufferCreateSize(len);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, len);
-+#endif
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlNewDocComment:
-+ * @doc: the document
-+ * @content: the comment content
-+ *
-+ * Creation of a new node containing a commentwithin a document.
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
-+ xmlNodePtr cur;
-+
-+ cur = xmlNewComment(content);
-+ if (cur != NULL) cur->doc = doc;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlSetTreeDoc:
-+ * @tree: the top element
-+ * @doc: the document
-+ *
-+ * update all nodes under the tree to point to the right document
-+ */
-+void
-+xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
-+ if (tree == NULL)
-+ return;
-+ if (tree->type == XML_ENTITY_DECL)
-+ return;
-+ if (tree->doc != doc) {
-+ if (tree->children != NULL)
-+ xmlSetListDoc(tree->children, doc);
-+ tree->doc = doc;
-+ }
-+}
-+
-+/**
-+ * xmlSetListDoc:
-+ * @tree: the first element
-+ * @doc: the document
-+ *
-+ * update all nodes in the list to point to the right document
-+ */
-+void
-+xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
-+ xmlNodePtr cur;
-+
-+ if (list == NULL)
-+ return;
-+ cur = list;
-+ while (cur != NULL) {
-+ if (cur->doc != doc)
-+ xmlSetTreeDoc(cur, doc);
-+ cur = cur->next;
-+ }
-+}
-+
-+
-+/**
-+ * xmlNewChild:
-+ * @parent: the parent node
-+ * @ns: a namespace if any
-+ * @name: the name of the child
-+ * @content: the XML content of the child if any.
-+ *
-+ * Creation of a new child element, added at the end of @parent children list.
-+ * @ns and @content parameters are optionnal (NULL). If content is non NULL,
-+ * a child list containing the TEXTs and ENTITY_REFs node will be created.
-+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
-+ * references, but XML special chars need to be escaped first by using
-+ * xmlEncodeEntitiesReentrant(). Use xmlNewTextChild() if entities
-+ * support is not needed.
-+ *
-+ * Returns a pointer to the new node object.
-+ */
-+xmlNodePtr
-+xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
-+ const xmlChar *name, const xmlChar *content) {
-+ xmlNodePtr cur, prev;
-+
-+ if (parent == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewChild : parent == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if (name == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewChild : name == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate a new node
-+ */
-+ if (ns == NULL)
-+ cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
-+ else
-+ cur = xmlNewDocNode(parent->doc, ns, name, content);
-+ if (cur == NULL) return(NULL);
-+
-+ /*
-+ * add the new element at the end of the children list.
-+ */
-+ cur->type = XML_ELEMENT_NODE;
-+ cur->parent = parent;
-+ cur->doc = parent->doc;
-+ if (parent->children == NULL) {
-+ parent->children = cur;
-+ parent->last = cur;
-+ } else {
-+ prev = parent->last;
-+ prev->next = cur;
-+ cur->prev = prev;
-+ parent->last = cur;
-+ }
-+
-+ return(cur);
-+}
-+
-+/**
-+ * xmlAddNextSibling:
-+ * @cur: the child node
-+ * @elem: the new node
-+ *
-+ * Add a new element @elem as the next siblings of @cur
-+ * If the new element was already inserted in a document it is
-+ * first unlinked from its existing context.
-+ * As a result of text merging @elem may be freed.
-+ *
-+ * Returns the new element or NULL in case of error.
-+ */
-+xmlNodePtr
-+xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNextSibling : cur == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+ if (elem == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNextSibling : elem == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ xmlUnlinkNode(elem);
-+
-+ if (elem->type == XML_TEXT_NODE) {
-+ if (cur->type == XML_TEXT_NODE) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(cur, elem->content);
-+#else
-+ xmlNodeAddContent(cur, xmlBufferContent(elem->content));
-+#endif
-+ xmlFreeNode(elem);
-+ return(cur);
-+ }
-+ if ((cur->next != NULL) && (cur->type == XML_TEXT_NODE)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlChar *tmp;
-+
-+ tmp = xmlStrdup(elem->content);
-+ tmp = xmlStrcat(tmp, cur->next->content);
-+ xmlNodeSetContent(cur->next, tmp);
-+ xmlFree(tmp);
-+#else
-+ xmlBufferAddHead(cur->next->content,
-+ xmlBufferContent(elem->content),
-+ xmlBufferLength(elem->content));
-+#endif
-+ xmlFreeNode(elem);
-+ return(cur->next);
-+ }
-+ }
-+
-+ if (elem->doc != cur->doc) {
-+ xmlSetTreeDoc(elem, cur->doc);
-+ }
-+ elem->parent = cur->parent;
-+ elem->prev = cur;
-+ elem->next = cur->next;
-+ cur->next = elem;
-+ if (elem->next != NULL)
-+ elem->next->prev = elem;
-+ if ((elem->parent != NULL) && (elem->parent->last == cur))
-+ elem->parent->last = elem;
-+ return(elem);
-+}
-+
-+/**
-+ * xmlAddPrevSibling:
-+ * @cur: the child node
-+ * @elem: the new node
-+ *
-+ * Add a new element @elem as the previous siblings of @cur
-+ * merging adjacent TEXT nodes (@elem may be freed)
-+ * If the new element was already inserted in a document it is
-+ * first unlinked from its existing context.
-+ *
-+ * Returns the new element or NULL in case of error.
-+ */
-+xmlNodePtr
-+xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddPrevSibling : cur == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+ if (elem == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddPrevSibling : elem == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ xmlUnlinkNode(elem);
-+
-+ if (elem->type == XML_TEXT_NODE) {
-+ if (cur->type == XML_TEXT_NODE) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlChar *tmp;
-+
-+ tmp = xmlStrdup(elem->content);
-+ tmp = xmlStrcat(tmp, cur->content);
-+ xmlNodeSetContent(cur, tmp);
-+ xmlFree(tmp);
-+#else
-+ xmlBufferAddHead(cur->content, xmlBufferContent(elem->content),
-+ xmlBufferLength(elem->content));
-+#endif
-+ xmlFreeNode(elem);
-+ return(cur);
-+ }
-+ if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(cur->prev, elem->content);
-+#else
-+ xmlNodeAddContent(cur->prev, xmlBufferContent(elem->content));
-+#endif
-+ xmlFreeNode(elem);
-+ return(cur->prev);
-+ }
-+ }
-+
-+ if (elem->doc != cur->doc) {
-+ xmlSetTreeDoc(elem, cur->doc);
-+ }
-+ elem->parent = cur->parent;
-+ elem->next = cur;
-+ elem->prev = cur->prev;
-+ cur->prev = elem;
-+ if (elem->prev != NULL)
-+ elem->prev->next = elem;
-+ if ((elem->parent != NULL) && (elem->parent->children == cur))
-+ elem->parent->children = elem;
-+ return(elem);
-+}
-+
-+/**
-+ * xmlAddSibling:
-+ * @cur: the child node
-+ * @elem: the new node
-+ *
-+ * Add a new element @elem to the list of siblings of @cur
-+ * merging adjacent TEXT nodes (@elem may be freed)
-+ * If the new element was already inserted in a document it is
-+ * first unlinked from its existing context.
-+ *
-+ * Returns the new element or NULL in case of error.
-+ */
-+xmlNodePtr
-+xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
-+ xmlNodePtr parent;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddSibling : cur == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if (elem == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddSibling : elem == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Constant time is we can rely on the ->parent->last to find
-+ * the last sibling.
-+ */
-+ if ((cur->parent != NULL) &&
-+ (cur->parent->children != NULL) &&
-+ (cur->parent->last != NULL) &&
-+ (cur->parent->last->next == NULL)) {
-+ cur = cur->parent->last;
-+ } else {
-+ while (cur->next != NULL) cur = cur->next;
-+ }
-+
-+ xmlUnlinkNode(elem);
-+
-+ if ((cur->type == XML_TEXT_NODE) && (elem->type == XML_TEXT_NODE)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(cur, elem->content);
-+#else
-+ xmlNodeAddContent(cur, xmlBufferContent(elem->content));
-+#endif
-+ xmlFreeNode(elem);
-+ return(cur);
-+ }
-+
-+ if (elem->doc != cur->doc) {
-+ xmlSetTreeDoc(elem, cur->doc);
-+ }
-+ parent = cur->parent;
-+ elem->prev = cur;
-+ elem->next = NULL;
-+ elem->parent = parent;
-+ cur->next = elem;
-+ if (parent != NULL)
-+ parent->last = elem;
-+
-+ return(elem);
-+}
-+
-+/**
-+ * xmlAddChildList:
-+ * @parent: the parent node
-+ * @cur: the first node in the list
-+ *
-+ * Add a list of node at the end of the child list of the parent
-+ * merging adjacent TEXT nodes (@cur may be freed)
-+ *
-+ * Returns the last child or NULL in case of error.
-+ */
-+xmlNodePtr
-+xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
-+ xmlNodePtr prev;
-+
-+ if (parent == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddChild : parent == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddChild : child == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if ((cur->doc != NULL) && (parent->doc != NULL) &&
-+ (cur->doc != parent->doc)) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Elements moved to a different document\n");
-+#endif
-+ }
-+
-+ /*
-+ * add the first element at the end of the children list.
-+ */
-+ if (parent->children == NULL) {
-+ parent->children = cur;
-+ } else {
-+ /*
-+ * If cur and parent->last both are TEXT nodes, then merge them.
-+ */
-+ if ((cur->type == XML_TEXT_NODE) &&
-+ (parent->last->type == XML_TEXT_NODE)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(parent->last, cur->content);
-+#else
-+ xmlNodeAddContent(parent->last, xmlBufferContent(cur->content));
-+#endif
-+ /*
-+ * if it's the only child, nothing more to be done.
-+ */
-+ if (cur->next == NULL) {
-+ xmlFreeNode(cur);
-+ return(parent->last);
-+ }
-+ prev = cur;
-+ cur = cur->next;
-+ xmlFreeNode(prev);
-+ }
-+ prev = parent->last;
-+ prev->next = cur;
-+ cur->prev = prev;
-+ }
-+ while (cur->next != NULL) {
-+ cur->parent = parent;
-+ if (cur->doc != parent->doc) {
-+ xmlSetTreeDoc(cur, parent->doc);
-+ }
-+ cur = cur->next;
-+ }
-+ cur->parent = parent;
-+ cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
-+ parent->last = cur;
-+
-+ return(cur);
-+}
-+
-+/**
-+ * xmlAddChild:
-+ * @parent: the parent node
-+ * @cur: the child node
-+ *
-+ * Add a new child element, to @parent, at the end of the child list
-+ * merging adjacent TEXT nodes (in which case @cur is freed)
-+ * Returns the child or NULL in case of error.
-+ */
-+xmlNodePtr
-+xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
-+ xmlNodePtr prev;
-+
-+ if (parent == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddChild : parent == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddChild : child == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+
-+ if ((cur->doc != NULL) && (parent->doc != NULL) &&
-+ (cur->doc != parent->doc)) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Elements moved to a different document\n");
-+#endif
-+ }
-+
-+ /*
-+ * If cur is a TEXT node, merge its content with adjacent TEXT nodes
-+ * or with parent->content if parent->content != NULL.
-+ * cur is then freed.
-+ */
-+ if (cur->type == XML_TEXT_NODE) {
-+ if (((parent->type == XML_ELEMENT_NODE) ||
-+ (parent->type == XML_TEXT_NODE)) &&
-+ (parent->content != NULL)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(parent, cur->content);
-+#else
-+ xmlNodeAddContent(parent, xmlBufferContent(cur->content));
-+#endif
-+ xmlFreeNode(cur);
-+ return(parent);
-+ }
-+ if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(parent->last, cur->content);
-+#else
-+ xmlNodeAddContent(parent->last, xmlBufferContent(cur->content));
-+#endif
-+ xmlFreeNode(cur);
-+ return(parent->last);
-+ }
-+ }
-+
-+ /*
-+ * add the new element at the end of the children list.
-+ */
-+ cur->parent = parent;
-+ if (cur->doc != parent->doc) {
-+ xmlSetTreeDoc(cur, parent->doc);
-+ }
-+
-+ /*
-+ * Handle the case where parent->content != NULL, in that case it will
-+ * create a intermediate TEXT node.
-+ */
-+ if (((parent->type == XML_ELEMENT_NODE) || (parent->type == XML_TEXT_NODE)) &&
-+ (parent->content != NULL)) {
-+ xmlNodePtr text;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ text = xmlNewDocText(parent->doc, parent->content);
-+#else
-+ text = xmlNewDocText(parent->doc, xmlBufferContent(parent->content));
-+#endif
-+ if (text != NULL) {
-+ text->next = parent->children;
-+ if (text->next != NULL)
-+ text->next->prev = text;
-+ parent->children = text;
-+ UPDATE_LAST_CHILD_AND_PARENT(parent)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlFree(parent->content);
-+#else
-+ xmlBufferFree(parent->content);
-+#endif
-+ parent->content = NULL;
-+ }
-+ }
-+ if (parent->children == NULL) {
-+ parent->children = cur;
-+ parent->last = cur;
-+ } else {
-+ prev = parent->last;
-+ prev->next = cur;
-+ cur->prev = prev;
-+ parent->last = cur;
-+ }
-+
-+ return(cur);
-+}
-+
-+/**
-+ * xmlGetLastChild:
-+ * @parent: the parent node
-+ *
-+ * Search the last child of a node.
-+ * Returns the last child or NULL if none.
-+ */
-+xmlNodePtr
-+xmlGetLastChild(xmlNodePtr parent) {
-+ if (parent == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlGetLastChild : parent == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+ return(parent->last);
-+}
-+
-+/**
-+ * xmlFreeNodeList:
-+ * @cur: the first node in the list
-+ *
-+ * Free a node and all its siblings, this is a recursive behaviour, all
-+ * the children are freed too.
-+ */
-+void
-+xmlFreeNodeList(xmlNodePtr cur) {
-+ xmlNodePtr next;
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeNodeList : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ next = cur->next;
-+ xmlFreeNode(cur);
-+ cur = next;
-+ }
-+}
-+
-+/**
-+ * xmlFreeNode:
-+ * @cur: the node
-+ *
-+ * Free a node, this is a recursive behaviour, all the children are freed too.
-+ * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
-+ */
-+void
-+xmlFreeNode(xmlNodePtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeNode : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->type == XML_DTD_NODE)
-+ return;
-+ cur->doc = NULL;
-+ cur->parent = NULL;
-+ cur->next = NULL;
-+ cur->prev = NULL;
-+ if ((cur->children != NULL) &&
-+ (cur->type != XML_ENTITY_REF_NODE))
-+ xmlFreeNodeList(cur->children);
-+ if (cur->properties != NULL) xmlFreePropList(cur->properties);
-+ if (cur->type != XML_ENTITY_REF_NODE)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ if (cur->content != NULL) xmlFree(cur->content);
-+#else
-+ if (cur->content != NULL) xmlBufferFree(cur->content);
-+#endif
-+ if ((cur->name != NULL) &&
-+ (cur->name != xmlStringText) &&
-+ (cur->name != xmlStringTextNoenc) &&
-+ (cur->name != xmlStringComment))
-+ xmlFree((char *) cur->name);
-+ if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
-+ memset(cur, -1, sizeof(xmlNode));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlUnlinkNode:
-+ * @cur: the node
-+ *
-+ * Unlink a node from it's current context, the node is not freed
-+ */
-+void
-+xmlUnlinkNode(xmlNodePtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlUnlinkNode : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ if ((cur->parent != NULL) && (cur->parent->children == cur))
-+ cur->parent->children = cur->next;
-+ if ((cur->parent != NULL) && (cur->parent->last == cur))
-+ cur->parent->last = cur->prev;
-+ if (cur->next != NULL)
-+ cur->next->prev = cur->prev;
-+ if (cur->prev != NULL)
-+ cur->prev->next = cur->next;
-+ cur->next = cur->prev = NULL;
-+ cur->parent = NULL;
-+}
-+
-+/**
-+ * xmlReplaceNode:
-+ * @old: the old node
-+ * @cur: the node
-+ *
-+ * Unlink the old node from it's current context, prune the new one
-+ * at the same place. If cur was already inserted in a document it is
-+ * first unlinked from its existing context.
-+ *
-+ * Returns the old node
-+ */
-+xmlNodePtr
-+xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
-+ if (old == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReplaceNode : old == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+ if (cur == NULL) {
-+ xmlUnlinkNode(old);
-+ return(old);
-+ }
-+ if (cur == old) {
-+ return(old);
-+ }
-+ xmlUnlinkNode(cur);
-+ cur->doc = old->doc;
-+ cur->parent = old->parent;
-+ cur->next = old->next;
-+ if (cur->next != NULL)
-+ cur->next->prev = cur;
-+ cur->prev = old->prev;
-+ if (cur->prev != NULL)
-+ cur->prev->next = cur;
-+ if (cur->parent != NULL) {
-+ if (cur->parent->children == old)
-+ cur->parent->children = cur;
-+ if (cur->parent->last == old)
-+ cur->parent->last = cur;
-+ }
-+ old->next = old->prev = NULL;
-+ old->parent = NULL;
-+ return(old);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Copy operations *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlCopyNamespace:
-+ * @cur: the namespace
-+ *
-+ * Do a copy of the namespace.
-+ *
-+ * Returns: a new xmlNsPtr, or NULL in case of error.
-+ */
-+xmlNsPtr
-+xmlCopyNamespace(xmlNsPtr cur) {
-+ xmlNsPtr ret;
-+
-+ if (cur == NULL) return(NULL);
-+ switch (cur->type) {
-+ case XML_LOCAL_NAMESPACE:
-+ ret = xmlNewNs(NULL, cur->href, cur->prefix);
-+ break;
-+ default:
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCopyNamespace: invalid type %d\n", cur->type);
-+#endif
-+ return(NULL);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyNamespaceList:
-+ * @cur: the first namespace
-+ *
-+ * Do a copy of an namespace list.
-+ *
-+ * Returns: a new xmlNsPtr, or NULL in case of error.
-+ */
-+xmlNsPtr
-+xmlCopyNamespaceList(xmlNsPtr cur) {
-+ xmlNsPtr ret = NULL;
-+ xmlNsPtr p = NULL,q;
-+
-+ while (cur != NULL) {
-+ q = xmlCopyNamespace(cur);
-+ if (p == NULL) {
-+ ret = p = q;
-+ } else {
-+ p->next = q;
-+ p = q;
-+ }
-+ cur = cur->next;
-+ }
-+ return(ret);
-+}
-+
-+static xmlNodePtr
-+xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
-+/**
-+ * xmlCopyProp:
-+ * @target: the element where the attribute will be grafted
-+ * @cur: the attribute
-+ *
-+ * Do a copy of the attribute.
-+ *
-+ * Returns: a new xmlAttrPtr, or NULL in case of error.
-+ */
-+xmlAttrPtr
-+xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
-+ xmlAttrPtr ret;
-+
-+ if (cur == NULL) return(NULL);
-+ if (target != NULL)
-+ ret = xmlNewDocProp(target->doc, cur->name, NULL);
-+ else if (cur->parent != NULL)
-+ ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
-+ else if (cur->children != NULL)
-+ ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
-+ else
-+ ret = xmlNewDocProp(NULL, cur->name, NULL);
-+ if (ret == NULL) return(NULL);
-+ ret->parent = target;
-+
-+ if ((cur->ns != NULL) && (target != NULL)) {
-+ xmlNsPtr ns;
-+
-+ ns = xmlSearchNs(target->doc, target, cur->ns->prefix);
-+ ret->ns = ns;
-+ } else
-+ ret->ns = NULL;
-+
-+ if (cur->children != NULL) {
-+ xmlNodePtr tmp;
-+
-+ ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
-+ ret->last = NULL;
-+ tmp = ret->children;
-+ while (tmp != NULL) {
-+ /* tmp->parent = (xmlNodePtr)ret; */
-+ if (tmp->next == NULL)
-+ ret->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyPropList:
-+ * @target: the element where the attributes will be grafted
-+ * @cur: the first attribute
-+ *
-+ * Do a copy of an attribute list.
-+ *
-+ * Returns: a new xmlAttrPtr, or NULL in case of error.
-+ */
-+xmlAttrPtr
-+xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
-+ xmlAttrPtr ret = NULL;
-+ xmlAttrPtr p = NULL,q;
-+
-+ while (cur != NULL) {
-+ q = xmlCopyProp(target, cur);
-+ if (p == NULL) {
-+ ret = p = q;
-+ } else {
-+ p->next = q;
-+ q->prev = p;
-+ p = q;
-+ }
-+ cur = cur->next;
-+ }
-+ return(ret);
-+}
-+
-+/*
-+ * NOTE abeut the CopyNode operations !
-+ *
-+ * They are splitted into external and internal parts for one
-+ * tricky reason: namespaces. Doing a direct copy of a node
-+ * say RPM:Copyright without changing the namespace pointer to
-+ * something else can produce stale links. One way to do it is
-+ * to keep a reference counter but this doesn't work as soon
-+ * as one move the element or the subtree out of the scope of
-+ * the existing namespace. The actual solution seems to add
-+ * a copy of the namespace at the top of the copied tree if
-+ * not available in the subtree.
-+ * Hence two functions, the public front-end call the inner ones
-+ */
-+
-+static xmlNodePtr
-+xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
-+
-+static xmlNodePtr
-+xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
-+ int recursive) {
-+ xmlNodePtr ret;
-+
-+ if (node == NULL) return(NULL);
-+ /*
-+ * Allocate a new node and fill the fields.
-+ */
-+ ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlStaticCopyNode : malloc failed\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlNode));
-+ ret->type = node->type;
-+
-+ ret->doc = doc;
-+ ret->parent = parent;
-+ if (node->name == xmlStringText)
-+ ret->name = xmlStringText;
-+ else if (node->name == xmlStringTextNoenc)
-+ ret->name = xmlStringTextNoenc;
-+ else if (node->name == xmlStringComment)
-+ ret->name = xmlStringComment;
-+ else if (node->name != NULL)
-+ ret->name = xmlStrdup(node->name);
-+ if ((node->content != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret->content = xmlStrdup(node->content);
-+#else
-+ ret->content = xmlBufferCreateSize(xmlBufferLength(node->content));
-+ xmlBufferSetAllocationScheme(ret->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(ret->content,
-+ xmlBufferContent(node->content),
-+ xmlBufferLength(node->content));
-+#endif
-+ }
-+ if (parent != NULL)
-+ xmlAddChild(parent, ret);
-+
-+ if (!recursive) return(ret);
-+ if (node->nsDef != NULL)
-+ ret->nsDef = xmlCopyNamespaceList(node->nsDef);
-+
-+ if (node->ns != NULL) {
-+ xmlNsPtr ns;
-+
-+ ns = xmlSearchNs(doc, ret, node->ns->prefix);
-+ if (ns == NULL) {
-+ /*
-+ * Humm, we are copying an element whose namespace is defined
-+ * out of the new tree scope. Search it in the original tree
-+ * and add it at the top of the new tree
-+ */
-+ ns = xmlSearchNs(node->doc, node, node->ns->prefix);
-+ if (ns != NULL) {
-+ xmlNodePtr root = ret;
-+
-+ while (root->parent != NULL) root = root->parent;
-+ xmlNewNs(root, ns->href, ns->prefix);
-+ }
-+ } else {
-+ /*
-+ * reference the existing namespace definition in our own tree.
-+ */
-+ ret->ns = ns;
-+ }
-+ }
-+ if (node->properties != NULL)
-+ ret->properties = xmlCopyPropList(ret, node->properties);
-+ if (node->children != NULL)
-+ ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
-+ UPDATE_LAST_CHILD_AND_PARENT(ret)
-+ return(ret);
-+}
-+
-+static xmlNodePtr
-+xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
-+ xmlNodePtr ret = NULL;
-+ xmlNodePtr p = NULL,q;
-+
-+ while (node != NULL) {
-+ if( node->type == XML_DTD_NODE )
-+ q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
-+ else
-+ q = xmlStaticCopyNode(node, doc, parent, 1);
-+ if (ret == NULL) {
-+ q->prev = NULL;
-+ ret = p = q;
-+ } else {
-+ p->next = q;
-+ q->prev = p;
-+ p = q;
-+ }
-+ node = node->next;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyNode:
-+ * @node: the node
-+ * @recursive: if 1 do a recursive copy.
-+ *
-+ * Do a copy of the node.
-+ *
-+ * Returns: a new xmlNodePtr, or NULL in case of error.
-+ */
-+xmlNodePtr
-+xmlCopyNode(xmlNodePtr node, int recursive) {
-+ xmlNodePtr ret;
-+
-+ ret = xmlStaticCopyNode(node, NULL, NULL, recursive);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyNodeList:
-+ * @node: the first node in the list.
-+ *
-+ * Do a recursive copy of the node list.
-+ *
-+ * Returns: a new xmlNodePtr, or NULL in case of error.
-+ */
-+xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
-+ xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyElement:
-+ * @elem: the element
-+ *
-+ * Do a copy of the element definition.
-+ *
-+ * Returns: a new xmlElementPtr, or NULL in case of error.
-+xmlElementPtr
-+xmlCopyElement(xmlElementPtr elem) {
-+ xmlElementPtr ret;
-+
-+ if (elem == NULL) return(NULL);
-+ ret = xmlNewDocElement(elem->doc, elem->ns, elem->name, elem->content);
-+ if (ret == NULL) return(NULL);
-+ if (!recursive) return(ret);
-+ if (elem->properties != NULL)
-+ ret->properties = xmlCopyPropList(elem->properties);
-+
-+ if (elem->nsDef != NULL)
-+ ret->nsDef = xmlCopyNamespaceList(elem->nsDef);
-+ if (elem->children != NULL)
-+ ret->children = xmlCopyElementList(elem->children);
-+ return(ret);
-+}
-+ */
-+
-+/**
-+ * xmlCopyDtd:
-+ * @dtd: the dtd
-+ *
-+ * Do a copy of the dtd.
-+ *
-+ * Returns: a new xmlDtdPtr, or NULL in case of error.
-+ */
-+xmlDtdPtr
-+xmlCopyDtd(xmlDtdPtr dtd) {
-+ xmlDtdPtr ret;
-+
-+ if (dtd == NULL) return(NULL);
-+ ret = xmlNewDtd(NULL, dtd->name, dtd->ExternalID, dtd->SystemID);
-+ if (ret == NULL) return(NULL);
-+ if (dtd->entities != NULL)
-+ ret->entities = (void *) xmlCopyEntitiesTable(
-+ (xmlEntitiesTablePtr) dtd->entities);
-+ if (dtd->notations != NULL)
-+ ret->notations = (void *) xmlCopyNotationTable(
-+ (xmlNotationTablePtr) dtd->notations);
-+ if (dtd->elements != NULL)
-+ ret->elements = (void *) xmlCopyElementTable(
-+ (xmlElementTablePtr) dtd->elements);
-+ if (dtd->attributes != NULL)
-+ ret->attributes = (void *) xmlCopyAttributeTable(
-+ (xmlAttributeTablePtr) dtd->attributes);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyDoc:
-+ * @doc: the document
-+ * @recursive: if 1 do a recursive copy.
-+ *
-+ * Do a copy of the document info. If recursive, the content tree will
-+ * be copied too as well as Dtd, namespaces and entities.
-+ *
-+ * Returns: a new xmlDocPtr, or NULL in case of error.
-+ */
-+xmlDocPtr
-+xmlCopyDoc(xmlDocPtr doc, int recursive) {
-+ xmlDocPtr ret;
-+
-+ if (doc == NULL) return(NULL);
-+ ret = xmlNewDoc(doc->version);
-+ if (ret == NULL) return(NULL);
-+ if (doc->name != NULL)
-+ ret->name = xmlMemStrdup(doc->name);
-+ if (doc->encoding != NULL)
-+ ret->encoding = xmlStrdup(doc->encoding);
-+ ret->charset = doc->charset;
-+ ret->compression = doc->compression;
-+ ret->standalone = doc->standalone;
-+ if (!recursive) return(ret);
-+
-+ if (doc->intSubset != NULL)
-+ ret->intSubset = xmlCopyDtd(doc->intSubset);
-+ if (doc->oldNs != NULL)
-+ ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
-+ if (doc->children != NULL) {
-+ xmlNodePtr tmp;
-+ ret->children = xmlStaticCopyNodeList(doc->children, ret,
-+ (xmlNodePtr)ret);
-+ ret->last = NULL;
-+ tmp = ret->children;
-+ while (tmp != NULL) {
-+ if (tmp->next == NULL)
-+ ret->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Content access functions *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlDocGetRootElement:
-+ * @doc: the document
-+ *
-+ * Get the root element of the document (doc->children is a list
-+ * containing possibly comments, PIs, etc ...).
-+ *
-+ * Returns the xmlNodePtr for the root or NULL
-+ */
-+xmlNodePtr
-+xmlDocGetRootElement(xmlDocPtr doc) {
-+ xmlNodePtr ret;
-+
-+ if (doc == NULL) return(NULL);
-+ ret = doc->children;
-+ while (ret != NULL) {
-+ if (ret->type == XML_ELEMENT_NODE)
-+ return(ret);
-+ ret = ret->next;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlDocSetRootElement:
-+ * @doc: the document
-+ * @root: the new document root element
-+ *
-+ * Set the root element of the document (doc->children is a list
-+ * containing possibly comments, PIs, etc ...).
-+ *
-+ * Returns the old root element if any was found
-+ */
-+xmlNodePtr
-+xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
-+ xmlNodePtr old = NULL;
-+
-+ if (doc == NULL) return(NULL);
-+ old = doc->children;
-+ while (old != NULL) {
-+ if (old->type == XML_ELEMENT_NODE)
-+ break;
-+ old = old->next;
-+ }
-+ if (old == NULL) {
-+ if (doc->children == NULL) {
-+ doc->children = root;
-+ doc->last = root;
-+ } else {
-+ xmlAddSibling(doc->children, root);
-+ }
-+ } else {
-+ xmlReplaceNode(old, root);
-+ }
-+ return(old);
-+}
-+
-+/**
-+ * xmlNodeSetLang:
-+ * @cur: the node being changed
-+ * @lang: the langage description
-+ *
-+ * Set the language of a node, i.e. the values of the xml:lang
-+ * attribute.
-+ */
-+void
-+xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
-+ if (cur == NULL) return;
-+ switch(cur->type) {
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_PI_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_NAMESPACE_DECL:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ return;
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ break;
-+ }
-+ xmlSetProp(cur, BAD_CAST "xml:lang", lang);
-+}
-+
-+/**
-+ * xmlNodeGetLang:
-+ * @cur: the node being checked
-+ *
-+ * Searches the language of a node, i.e. the values of the xml:lang
-+ * attribute or the one carried by the nearest ancestor.
-+ *
-+ * Returns a pointer to the lang value, or NULL if not found
-+ * It's up to the caller to free the memory.
-+ */
-+xmlChar *
-+xmlNodeGetLang(xmlNodePtr cur) {
-+ xmlChar *lang;
-+
-+ while (cur != NULL) {
-+ lang = xmlGetProp(cur, BAD_CAST "xml:lang");
-+ if (lang != NULL)
-+ return(lang);
-+ cur = cur->parent;
-+ }
-+ return(NULL);
-+}
-+
-+
-+/**
-+ * xmlNodeSetSpacePreserve:
-+ * @cur: the node being changed
-+ * @val: the xml:space value ("0": default, 1: "preserve")
-+ *
-+ * Set (or reset) the space preserving behaviour of a node, i.e. the
-+ * value of the xml:space attribute.
-+ */
-+void
-+xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
-+ if (cur == NULL) return;
-+ switch(cur->type) {
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_PI_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return;
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ break;
-+ }
-+ switch (val) {
-+ case 0:
-+ xmlSetProp(cur, BAD_CAST "xml:space", BAD_CAST "default");
-+ break;
-+ case 1:
-+ xmlSetProp(cur, BAD_CAST "xml:space",
-+ BAD_CAST "preserve");
-+ break;
-+ }
-+}
-+
-+/**
-+ * xmlNodeGetSpacePreserve:
-+ * @cur: the node being checked
-+ *
-+ * Searches the space preserving behaviour of a node, i.e. the values
-+ * of the xml:space attribute or the one carried by the nearest
-+ * ancestor.
-+ *
-+ * Returns -1 if xml:space is not inheried, 0 if "default", 1 if "preserve"
-+ */
-+int
-+xmlNodeGetSpacePreserve(xmlNodePtr cur) {
-+ xmlChar *space;
-+
-+ while (cur != NULL) {
-+ space = xmlGetProp(cur, BAD_CAST "xml:space");
-+ if (space != NULL) {
-+ if (xmlStrEqual(space, BAD_CAST "preserve")) {
-+ xmlFree(space);
-+ return(1);
-+ }
-+ if (xmlStrEqual(space, BAD_CAST "default")) {
-+ xmlFree(space);
-+ return(0);
-+ }
-+ xmlFree(space);
-+ }
-+ cur = cur->parent;
-+ }
-+ return(-1);
-+}
-+
-+/**
-+ * xmlNodeSetName:
-+ * @cur: the node being changed
-+ * @name: the new tag name
-+ *
-+ * Set (or reset) the name of a node.
-+ */
-+void
-+xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
-+ if (cur == NULL) return;
-+ if (name == NULL) return;
-+ switch(cur->type) {
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return;
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ case XML_PI_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_DTD_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ break;
-+ }
-+ if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-+ cur->name = xmlStrdup(name);
-+}
-+
-+/**
-+ * xmlNodeSetBase:
-+ * @cur: the node being changed
-+ * @uri: the new base URI
-+ *
-+ * Set (or reset) the base URI of a node, i.e. the value of the
-+ * xml:base attribute.
-+ */
-+void
-+xmlNodeSetBase(xmlNodePtr cur, xmlChar* uri) {
-+ if (cur == NULL) return;
-+ switch(cur->type) {
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_PI_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return;
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ break;
-+ }
-+ xmlSetProp(cur, BAD_CAST "xml:base", uri);
-+}
-+
-+/**
-+ * xmlDocumentGetBase:
-+ * @doc: the document
-+ *
-+ * Searches for the Document BASE URL. The code should work on both XML
-+ * and HTML document.
-+ * It returns the base as defined in RFC 2396 section
-+ * 5.1.3. Base URI from the Retrieval URI
-+ * However it does not return the computed base (5.1.1 and 5.1.2), use
-+ * xmlNodeGetBase() for this
-+ *
-+ * Returns a pointer to the base URL, or NULL if not found
-+ * It's up to the caller to free the memory.
-+ */
-+xmlChar *
-+xmlDocumentGetBase(xmlDocPtr doc) {
-+ if (doc == NULL)
-+ return(NULL);
-+ if (doc->type == XML_HTML_DOCUMENT_NODE) {
-+ if (doc->URL != NULL)
-+ return(xmlStrdup(doc->URL));
-+ return(NULL);
-+ }
-+ if (doc->URL != NULL)
-+ return(xmlStrdup(doc->URL));
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNodeGetBase:
-+ * @doc: the document the node pertains to
-+ * @cur: the node being checked
-+ *
-+ * Searches for the BASE URL. The code should work on both XML
-+ * and HTML document even if base mechanisms are completely different.
-+ * It returns the base as defined in RFC 2396 sections
-+ * 5.1.1. Base URI within Document Content
-+ * and
-+ * 5.1.2. Base URI from the Encapsulating Entity
-+ * However it does not return the document base (5.1.3), use
-+ * xmlDocumentGetBase() for this
-+ *
-+ * Returns a pointer to the base URL, or NULL if not found
-+ * It's up to the caller to free the memory.
-+ */
-+xmlChar *
-+xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
-+ xmlChar *base;
-+
-+ if ((cur == NULL) && (doc == NULL))
-+ return(NULL);
-+ if (doc == NULL) doc = cur->doc;
-+ if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
-+ cur = doc->children;
-+ while ((cur != NULL) && (cur->name != NULL)) {
-+ if (cur->type != XML_ELEMENT_NODE) {
-+ cur = cur->next;
-+ continue;
-+ }
-+ if (!xmlStrcasecmp(cur->name, BAD_CAST "html")) {
-+ cur = cur->children;
-+ continue;
-+ }
-+ if (!xmlStrcasecmp(cur->name, BAD_CAST "head")) {
-+ cur = cur->children;
-+ continue;
-+ }
-+ if (!xmlStrcasecmp(cur->name, BAD_CAST "base")) {
-+ return(xmlGetProp(cur, BAD_CAST "href"));
-+ }
-+ cur = cur->next;
-+ }
-+ return(NULL);
-+ }
-+ while (cur != NULL) {
-+ if (cur->type == XML_ENTITY_DECL) {
-+ xmlEntityPtr ent = (xmlEntityPtr) cur;
-+ return(xmlStrdup(ent->URI));
-+ }
-+ base = xmlGetProp(cur, BAD_CAST "xml:base");
-+ if (base != NULL)
-+ return(base);
-+ cur = cur->parent;
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNodeGetContent:
-+ * @cur: the node being read
-+ *
-+ * Read the value of a node, this can be either the text carried
-+ * directly by this node if it's a TEXT node or the aggregate string
-+ * of the values carried by this node child's (TEXT and ENTITY_REF).
-+ * Entity references are substitued.
-+ * Returns a new xmlChar * or NULL if no content is available.
-+ * It's up to the caller to free the memory.
-+ */
-+xmlChar *
-+xmlNodeGetContent(xmlNodePtr cur) {
-+ if (cur == NULL) return(NULL);
-+ switch (cur->type) {
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_ELEMENT_NODE:
-+ return(xmlNodeListGetString(cur->doc, cur->children, 1));
-+ break;
-+ case XML_ATTRIBUTE_NODE: {
-+ xmlAttrPtr attr = (xmlAttrPtr) cur;
-+ if (attr->parent != NULL)
-+ return(xmlNodeListGetString(attr->parent->doc, attr->children, 1));
-+ else
-+ return(xmlNodeListGetString(NULL, attr->children, 1));
-+ break;
-+ }
-+ case XML_COMMENT_NODE:
-+ case XML_PI_NODE:
-+ if (cur->content != NULL)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ return(xmlStrdup(cur->content));
-+#else
-+ return(xmlStrdup(xmlBufferContent(cur->content)));
-+#endif
-+ return(NULL);
-+ case XML_ENTITY_REF_NODE:
-+ /*
-+ * Locate the entity, and get it's content
-+ * @@@
-+ */
-+ return(NULL);
-+ case XML_ENTITY_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_DTD_NODE:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return(NULL);
-+ case XML_NAMESPACE_DECL:
-+ return(xmlStrdup(((xmlNsPtr)cur)->href));
-+ case XML_ELEMENT_DECL:
-+ /* TODO !!! */
-+ return(NULL);
-+ case XML_ATTRIBUTE_DECL:
-+ /* TODO !!! */
-+ return(NULL);
-+ case XML_ENTITY_DECL:
-+ /* TODO !!! */
-+ return(NULL);
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_TEXT_NODE:
-+ if (cur->content != NULL)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ return(xmlStrdup(cur->content));
-+#else
-+ return(xmlStrdup(xmlBufferContent(cur->content)));
-+#endif
-+ return(NULL);
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNodeSetContent:
-+ * @cur: the node being modified
-+ * @content: the new value of the content
-+ *
-+ * Replace the content of a node.
-+ */
-+void
-+xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeSetContent : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ switch (cur->type) {
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_ELEMENT_NODE:
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlFree(cur->content);
-+#else
-+ xmlBufferFree(cur->content);
-+#endif
-+ cur->content = NULL;
-+ }
-+ if (cur->children != NULL) xmlFreeNodeList(cur->children);
-+ cur->children = xmlStringGetNodeList(cur->doc, content);
-+ UPDATE_LAST_CHILD_AND_PARENT(cur)
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ break;
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlFree(cur->content);
-+#else
-+ xmlBufferFree(cur->content);
-+#endif
-+ }
-+ if (cur->children != NULL) xmlFreeNodeList(cur->children);
-+ cur->last = cur->children = NULL;
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrdup(content);
-+#else
-+ cur->content = xmlBufferCreateSize(0);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, -1);
-+#endif
-+ } else
-+ cur->content = NULL;
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ break;
-+ case XML_NOTATION_NODE:
-+ break;
-+ case XML_DTD_NODE:
-+ break;
-+ case XML_NAMESPACE_DECL:
-+ break;
-+ case XML_ELEMENT_DECL:
-+ /* TODO !!! */
-+ break;
-+ case XML_ATTRIBUTE_DECL:
-+ /* TODO !!! */
-+ break;
-+ case XML_ENTITY_DECL:
-+ /* TODO !!! */
-+ break;
-+ }
-+}
-+
-+/**
-+ * xmlNodeSetContentLen:
-+ * @cur: the node being modified
-+ * @content: the new value of the content
-+ * @len: the size of @content
-+ *
-+ * Replace the content of a node.
-+ */
-+void
-+xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeSetContentLen : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ switch (cur->type) {
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_ELEMENT_NODE:
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlFree(cur->content);
-+#else
-+ xmlBufferFree(cur->content);
-+#endif
-+ cur->content = NULL;
-+ }
-+ if (cur->children != NULL) xmlFreeNodeList(cur->children);
-+ cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
-+ UPDATE_LAST_CHILD_AND_PARENT(cur)
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ break;
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlFree(cur->content);
-+#else
-+ xmlBufferFree(cur->content);
-+#endif
-+ }
-+ if (cur->children != NULL) xmlFreeNodeList(cur->children);
-+ cur->children = cur->last = NULL;
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrndup(content, len);
-+#else
-+ cur->content = xmlBufferCreateSize(len);
-+ xmlBufferSetAllocationScheme(cur->content,
-+ xmlGetBufferAllocationScheme());
-+ xmlBufferAdd(cur->content, content, len);
-+#endif
-+ } else
-+ cur->content = NULL;
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ case XML_DTD_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ break;
-+ case XML_ELEMENT_DECL:
-+ /* TODO !!! */
-+ break;
-+ case XML_ATTRIBUTE_DECL:
-+ /* TODO !!! */
-+ break;
-+ case XML_ENTITY_DECL:
-+ /* TODO !!! */
-+ break;
-+ }
-+}
-+
-+/**
-+ * xmlNodeAddContentLen:
-+ * @cur: the node being modified
-+ * @content: extra content
-+ * @len: the size of @content
-+ *
-+ * Append the extra substring to the node content.
-+ */
-+void
-+xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeAddContentLen : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (len <= 0) return;
-+ switch (cur->type) {
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_ELEMENT_NODE: {
-+ xmlNodePtr last = NULL, newNode;
-+
-+ if (cur->children != NULL) {
-+ last = cur->last;
-+ } else {
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->children = xmlStringGetNodeList(cur->doc, cur->content);
-+#else
-+ cur->children = xmlStringGetNodeList(cur->doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ UPDATE_LAST_CHILD_AND_PARENT(cur)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlFree(cur->content);
-+#else
-+ xmlBufferFree(cur->content);
-+#endif
-+ cur->content = NULL;
-+ last = cur->last;
-+ }
-+ }
-+ newNode = xmlNewTextLen(content, len);
-+ if (newNode != NULL) {
-+ xmlAddChild(cur, newNode);
-+ if ((last != NULL) && (last->next == newNode)) {
-+ xmlTextMerge(last, newNode);
-+ }
-+ }
-+ break;
-+ }
-+ case XML_ATTRIBUTE_NODE:
-+ break;
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ if (content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur->content = xmlStrncat(cur->content, content, len);
-+#else
-+ xmlBufferAdd(cur->content, content, len);
-+#endif
-+ }
-+ case XML_DOCUMENT_NODE:
-+ case XML_DTD_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ break;
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ break;
-+ }
-+}
-+
-+/**
-+ * xmlNodeAddContent:
-+ * @cur: the node being modified
-+ * @content: extra content
-+ *
-+ * Append the extra substring to the node content.
-+ */
-+void
-+xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) {
-+ int len;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeAddContent : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (content == NULL) return;
-+ len = xmlStrlen(content);
-+ xmlNodeAddContentLen(cur, content, len);
-+}
-+
-+/**
-+ * xmlTextMerge:
-+ * @first: the first text node
-+ * @second: the second text node being merged
-+ *
-+ * Merge two text nodes into one
-+ * Returns the first text node augmented
-+ */
-+xmlNodePtr
-+xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
-+ if (first == NULL) return(second);
-+ if (second == NULL) return(first);
-+ if (first->type != XML_TEXT_NODE) return(first);
-+ if (second->type != XML_TEXT_NODE) return(first);
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlNodeAddContent(first, second->content);
-+#else
-+ xmlNodeAddContent(first, xmlBufferContent(second->content));
-+#endif
-+ xmlUnlinkNode(second);
-+ xmlFreeNode(second);
-+ return(first);
-+}
-+
-+/**
-+ * xmlGetNsList:
-+ * @doc: the document
-+ * @node: the current node
-+ *
-+ * Search all the namespace applying to a given element.
-+ * Returns an NULL terminated array of all the xmlNsPtr found
-+ * that need to be freed by the caller or NULL if no
-+ * namespace if defined
-+ */
-+xmlNsPtr *
-+xmlGetNsList(xmlDocPtr doc, xmlNodePtr node) {
-+ xmlNsPtr cur;
-+ xmlNsPtr *ret = NULL;
-+ int nbns = 0;
-+ int maxns = 10;
-+ int i;
-+
-+ while (node != NULL) {
-+ cur = node->nsDef;
-+ while (cur != NULL) {
-+ if (ret == NULL) {
-+ ret = (xmlNsPtr *) xmlMalloc((maxns + 1) * sizeof(xmlNsPtr));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlGetNsList : out of memory!\n");
-+ return(NULL);
-+ }
-+ ret[nbns] = NULL;
-+ }
-+ for (i = 0;i < nbns;i++) {
-+ if ((cur->prefix == ret[i]->prefix) ||
-+ (xmlStrEqual(cur->prefix, ret[i]->prefix))) break;
-+ }
-+ if (i >= nbns) {
-+ if (nbns >= maxns) {
-+ maxns *= 2;
-+ ret = (xmlNsPtr *) xmlRealloc(ret,
-+ (maxns + 1) * sizeof(xmlNsPtr));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlGetNsList : realloc failed!\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[nbns++] = cur;
-+ ret[nbns] = NULL;
-+ }
-+
-+ cur = cur->next;
-+ }
-+ node = node->parent;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSearchNs:
-+ * @doc: the document
-+ * @node: the current node
-+ * @nameSpace: the namespace string
-+ *
-+ * Search a Ns registered under a given name space for a document.
-+ * recurse on the parents until it finds the defined namespace
-+ * or return NULL otherwise.
-+ * @nameSpace can be NULL, this is a search for the default namespace.
-+ * We don't allow to cross entities boundaries. If you don't declare
-+ * the namespace within those you will be in troubles !!! A warning
-+ * is generated to cover this case.
-+ *
-+ * Returns the namespace pointer or NULL.
-+ */
-+xmlNsPtr
-+xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
-+ xmlNsPtr cur;
-+
-+ if (node == NULL) return(NULL);
-+ while (node != NULL) {
-+ if ((node->type == XML_ENTITY_REF_NODE) ||
-+ (node->type == XML_ENTITY_NODE) ||
-+ (node->type == XML_ENTITY_DECL))
-+ return(NULL);
-+ if (node->type == XML_ELEMENT_NODE) {
-+ cur = node->nsDef;
-+ while (cur != NULL) {
-+ if ((cur->prefix == NULL) && (nameSpace == NULL) &&
-+ (cur->href != NULL))
-+ return(cur);
-+ if ((cur->prefix != NULL) && (nameSpace != NULL) &&
-+ (cur->href != NULL) &&
-+ (xmlStrEqual(cur->prefix, nameSpace)))
-+ return(cur);
-+ cur = cur->next;
-+ }
-+ }
-+ node = node->parent;
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlSearchNsByHref:
-+ * @doc: the document
-+ * @node: the current node
-+ * @href: the namespace value
-+ *
-+ * Search a Ns aliasing a given URI. Recurse on the parents until it finds
-+ * the defined namespace or return NULL otherwise.
-+ * Returns the namespace pointer or NULL.
-+ */
-+xmlNsPtr
-+xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href) {
-+ xmlNsPtr cur;
-+ xmlNodePtr orig = node;
-+
-+ if ((node == NULL) || (href == NULL)) return(NULL);
-+ while (node != NULL) {
-+ cur = node->nsDef;
-+ while (cur != NULL) {
-+ if ((cur->href != NULL) && (href != NULL) &&
-+ (xmlStrEqual(cur->href, href))) {
-+ /*
-+ * Check that the prefix is not shadowed between orig and node
-+ */
-+ xmlNodePtr check = orig;
-+ xmlNsPtr tst;
-+
-+ while (check != node) {
-+ tst = check->nsDef;
-+ while (tst != NULL) {
-+ if ((tst->prefix == NULL) && (cur->prefix == NULL))
-+ goto shadowed;
-+ if ((tst->prefix != NULL) && (cur->prefix != NULL) &&
-+ (xmlStrEqual(tst->prefix, cur->prefix)))
-+ goto shadowed;
-+ tst = tst->next;
-+ }
-+ check = check->parent;
-+ }
-+ return(cur);
-+ }
-+shadowed:
-+ cur = cur->next;
-+ }
-+ node = node->parent;
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlNewReconciliedNs
-+ * @doc: the document
-+ * @tree: a node expected to hold the new namespace
-+ * @ns: the original namespace
-+ *
-+ * This function tries to locate a namespace definition in a tree
-+ * ancestors, or create a new namespace definition node similar to
-+ * @ns trying to reuse the same prefix. However if the given prefix is
-+ * null (default namespace) or reused within the subtree defined by
-+ * @tree or on one of its ancestors then a new prefix is generated.
-+ * Returns the (new) namespace definition or NULL in case of error
-+ */
-+xmlNsPtr
-+xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
-+ xmlNsPtr def;
-+ xmlChar prefix[50];
-+ int counter = 1;
-+
-+ if (tree == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewReconciliedNs : tree == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+ if (ns == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewReconciliedNs : ns == NULL\n");
-+#endif
-+ return(NULL);
-+ }
-+ /*
-+ * Search an existing namespace definition inherited.
-+ */
-+ def = xmlSearchNsByHref(doc, tree, ns->href);
-+ if (def != NULL)
-+ return(def);
-+
-+ /*
-+ * Find a close prefix which is not already in use.
-+ * Let's strip namespace prefixes longer than 20 chars !
-+ */
-+ sprintf((char *) prefix, "%.20s", ns->prefix);
-+ def = xmlSearchNs(doc, tree, prefix);
-+ while (def != NULL) {
-+ if (counter > 1000) return(NULL);
-+ sprintf((char *) prefix, "%.20s%d", ns->prefix, counter++);
-+ def = xmlSearchNs(doc, tree, prefix);
-+ }
-+
-+ /*
-+ * Ok, now we are ready to create a new one.
-+ */
-+ def = xmlNewNs(tree, ns->href, prefix);
-+ return(def);
-+}
-+
-+/**
-+ * xmlReconciliateNs
-+ * @doc: the document
-+ * @tree: a node defining the subtree to reconciliate
-+ *
-+ * This function checks that all the namespaces declared within the given
-+ * tree are properly declared. This is needed for example after Copy or Cut
-+ * and then paste operations. The subtree may still hold pointers to
-+ * namespace declarations outside the subtree or invalid/masked. As much
-+ * as possible the function try tu reuse the existing namespaces found in
-+ * the new environment. If not possible the new namespaces are redeclared
-+ * on @tree at the top of the given subtree.
-+ * Returns the number of namespace declarations created or -1 in case of error.
-+ */
-+int
-+xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
-+ xmlNsPtr *oldNs = NULL;
-+ xmlNsPtr *newNs = NULL;
-+ int sizeCache = 0;
-+ int nbCache = 0;
-+
-+ xmlNsPtr n;
-+ xmlNodePtr node = tree;
-+ xmlAttrPtr attr;
-+ int ret = 0, i;
-+
-+ while (node != NULL) {
-+ /*
-+ * Reconciliate the node namespace
-+ */
-+ if (node->ns != NULL) {
-+ /*
-+ * initialize the cache if needed
-+ */
-+ if (sizeCache == 0) {
-+ sizeCache = 10;
-+ oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (oldNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ return(-1);
-+ }
-+ newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (newNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ xmlFree(oldNs);
-+ return(-1);
-+ }
-+ }
-+ for (i = 0;i < nbCache;i++) {
-+ if (oldNs[i] == node->ns) {
-+ node->ns = newNs[i];
-+ break;
-+ }
-+ }
-+ if (i == nbCache) {
-+ /*
-+ * Ok we need to recreate a new namespace definition
-+ */
-+ n = xmlNewReconciliedNs(doc, tree, node->ns);
-+ if (n != NULL) { /* :-( what if else ??? */
-+ /*
-+ * check if we need to grow the cache buffers.
-+ */
-+ if (sizeCache <= nbCache) {
-+ sizeCache *= 2;
-+ oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (oldNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ xmlFree(newNs);
-+ return(-1);
-+ }
-+ newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (newNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ xmlFree(oldNs);
-+ return(-1);
-+ }
-+ }
-+ newNs[nbCache] = n;
-+ oldNs[nbCache++] = node->ns;
-+ node->ns = n;
-+ }
-+ }
-+ }
-+ /*
-+ * now check for namespace hold by attributes on the node.
-+ */
-+ attr = node->properties;
-+ while (attr != NULL) {
-+ if (attr->ns != NULL) {
-+ /*
-+ * initialize the cache if needed
-+ */
-+ if (sizeCache == 0) {
-+ sizeCache = 10;
-+ oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (oldNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ return(-1);
-+ }
-+ newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (newNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ xmlFree(oldNs);
-+ return(-1);
-+ }
-+ }
-+ for (i = 0;i < nbCache;i++) {
-+ if (oldNs[i] == attr->ns) {
-+ node->ns = newNs[i];
-+ break;
-+ }
-+ }
-+ if (i == nbCache) {
-+ /*
-+ * Ok we need to recreate a new namespace definition
-+ */
-+ n = xmlNewReconciliedNs(doc, tree, attr->ns);
-+ if (n != NULL) { /* :-( what if else ??? */
-+ /*
-+ * check if we need to grow the cache buffers.
-+ */
-+ if (sizeCache <= nbCache) {
-+ sizeCache *= 2;
-+ oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (oldNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ xmlFree(newNs);
-+ return(-1);
-+ }
-+ newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
-+ sizeof(xmlNsPtr));
-+ if (newNs == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlReconciliateNs : memory pbm\n");
-+ xmlFree(oldNs);
-+ return(-1);
-+ }
-+ }
-+ newNs[nbCache] = n;
-+ oldNs[nbCache++] = attr->ns;
-+ attr->ns = n;
-+ }
-+ }
-+ }
-+ attr = attr->next;
-+ }
-+
-+ /*
-+ * Browse the full subtree, deep first
-+ */
-+ if (node->children != NULL) {
-+ /* deep first */
-+ node = node->children;
-+ } else if ((node != tree) && (node->next != NULL)) {
-+ /* then siblings */
-+ node = node->next;
-+ } else if (node != tree) {
-+ /* go up to parents->next if needed */
-+ while (node != tree) {
-+ if (node->parent != NULL)
-+ node = node->parent;
-+ if ((node != tree) && (node->next != NULL)) {
-+ node = node->next;
-+ break;
-+ }
-+ if (node->parent == NULL) {
-+ node = NULL;
-+ break;
-+ }
-+ }
-+ /* exit condition */
-+ if (node == tree)
-+ node = NULL;
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlHasProp:
-+ * @node: the node
-+ * @name: the attribute name
-+ *
-+ * Search an attribute associated to a node
-+ * This function also looks in DTD attribute declaration for #FIXED or
-+ * default declaration values unless DTD use has been turned off.
-+ *
-+ * Returns the attribute or the attribute declaration or NULL if
-+ * neither was found.
-+ */
-+xmlAttrPtr
-+xmlHasProp(xmlNodePtr node, const xmlChar *name) {
-+ xmlAttrPtr prop;
-+ xmlDocPtr doc;
-+
-+ if ((node == NULL) || (name == NULL)) return(NULL);
-+ /*
-+ * Check on the properties attached to the node
-+ */
-+ prop = node->properties;
-+ while (prop != NULL) {
-+ if (xmlStrEqual(prop->name, name)) {
-+ return(prop);
-+ }
-+ prop = prop->next;
-+ }
-+ if (!xmlCheckDTD) return(NULL);
-+
-+ /*
-+ * Check if there is a default declaration in the internal
-+ * or external subsets
-+ */
-+ doc = node->doc;
-+ if (doc != NULL) {
-+ xmlAttributePtr attrDecl;
-+ if (doc->intSubset != NULL) {
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
-+ if (attrDecl != NULL)
-+ return((xmlAttrPtr) attrDecl);
-+ }
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlGetProp:
-+ * @node: the node
-+ * @name: the attribute name
-+ *
-+ * Search and get the value of an attribute associated to a node
-+ * This does the entity substitution.
-+ * This function looks in DTD attribute declaration for #FIXED or
-+ * default declaration values unless DTD use has been turned off.
-+ *
-+ * Returns the attribute value or NULL if not found.
-+ * It's up to the caller to free the memory.
-+ */
-+xmlChar *
-+xmlGetProp(xmlNodePtr node, const xmlChar *name) {
-+ xmlAttrPtr prop;
-+ xmlDocPtr doc;
-+
-+ if ((node == NULL) || (name == NULL)) return(NULL);
-+ /*
-+ * Check on the properties attached to the node
-+ */
-+ prop = node->properties;
-+ while (prop != NULL) {
-+ if (xmlStrEqual(prop->name, name)) {
-+ xmlChar *ret;
-+
-+ ret = xmlNodeListGetString(node->doc, prop->children, 1);
-+ if (ret == NULL) return(xmlStrdup((xmlChar *)""));
-+ return(ret);
-+ }
-+ prop = prop->next;
-+ }
-+ if (!xmlCheckDTD) return(NULL);
-+
-+ /*
-+ * Check if there is a default declaration in the internal
-+ * or external subsets
-+ */
-+ doc = node->doc;
-+ if (doc != NULL) {
-+ xmlAttributePtr attrDecl;
-+ if (doc->intSubset != NULL) {
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
-+ if (attrDecl != NULL)
-+ return(xmlStrdup(attrDecl->defaultValue));
-+ }
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlGetNsProp:
-+ * @node: the node
-+ * @name: the attribute name
-+ * @namespace: the URI of the namespace
-+ *
-+ * Search and get the value of an attribute associated to a node
-+ * This attribute has to be anchored in the namespace specified.
-+ * This does the entity substitution.
-+ * This function looks in DTD attribute declaration for #FIXED or
-+ * default declaration values unless DTD use has been turned off.
-+ *
-+ * Returns the attribute value or NULL if not found.
-+ * It's up to the caller to free the memory.
-+ */
-+xmlChar *
-+xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) {
-+ xmlAttrPtr prop;
-+ xmlDocPtr doc;
-+ xmlNsPtr ns;
-+
-+ if (node == NULL)
-+ return(NULL);
-+
-+ prop = node->properties;
-+ if (namespace == NULL)
-+ return(xmlGetProp(node, name));
-+ while (prop != NULL) {
-+ /*
-+ * One need to have
-+ * - same attribute names
-+ * - and the attribute carrying that namespace
-+ * or
-+ * no namespace on the attribute and the element carrying it
-+ */
-+ if ((xmlStrEqual(prop->name, name)) &&
-+ (((prop->ns == NULL) && (node->ns != NULL) &&
-+ (xmlStrEqual(node->ns->href, namespace))) ||
-+ ((prop->ns != NULL) && (xmlStrEqual(prop->ns->href, namespace))))) {
-+ xmlChar *ret;
-+
-+ ret = xmlNodeListGetString(node->doc, prop->children, 1);
-+ if (ret == NULL) return(xmlStrdup((xmlChar *)""));
-+ return(ret);
-+ }
-+ prop = prop->next;
-+ }
-+ if (!xmlCheckDTD) return(NULL);
-+
-+ /*
-+ * Check if there is a default declaration in the internal
-+ * or external subsets
-+ */
-+ doc = node->doc;
-+ if (doc != NULL) {
-+ xmlAttributePtr attrDecl;
-+ if (doc->intSubset != NULL) {
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
-+
-+ if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) {
-+ /*
-+ * The DTD declaration only allows a prefix search
-+ */
-+ ns = xmlSearchNs(doc, node, attrDecl->prefix);
-+ if ((ns != NULL) && (xmlStrEqual(ns->href, namespace)))
-+ return(xmlStrdup(attrDecl->defaultValue));
-+ }
-+ }
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlSetProp:
-+ * @node: the node
-+ * @name: the attribute name
-+ * @value: the attribute value
-+ *
-+ * Set (or reset) an attribute carried by a node.
-+ * Returns the attribute pointer.
-+ */
-+xmlAttrPtr
-+xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
-+ xmlAttrPtr prop = node->properties;
-+ xmlDocPtr doc = NULL;
-+
-+ if ((node == NULL) || (name == NULL))
-+ return(NULL);
-+ doc = node->doc;
-+ while (prop != NULL) {
-+ if (xmlStrEqual(prop->name, name)) {
-+ if (prop->children != NULL)
-+ xmlFreeNodeList(prop->children);
-+ prop->children = NULL;
-+ prop->last = NULL;
-+ if (value != NULL) {
-+ xmlChar *buffer;
-+ xmlNodePtr tmp;
-+
-+ buffer = xmlEncodeEntitiesReentrant(node->doc, value);
-+ prop->children = xmlStringGetNodeList(node->doc, buffer);
-+ prop->last = NULL;
-+ prop->doc = doc;
-+ tmp = prop->children;
-+ while (tmp != NULL) {
-+ tmp->parent = (xmlNodePtr) prop;
-+ tmp->doc = doc;
-+ if (tmp->next == NULL)
-+ prop->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ xmlFree(buffer);
-+ }
-+ return(prop);
-+ }
-+ prop = prop->next;
-+ }
-+ prop = xmlNewProp(node, name, value);
-+ return(prop);
-+}
-+
-+/**
-+ * xmlSetNsProp:
-+ * @node: the node
-+ * @ns: the namespace definition
-+ * @name: the attribute name
-+ * @value: the attribute value
-+ *
-+ * Set (or reset) an attribute carried by a node.
-+ * The ns structure must be in scope, this is not checked.
-+ *
-+ * Returns the attribute pointer.
-+ */
-+xmlAttrPtr
-+xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
-+ const xmlChar *value) {
-+ xmlAttrPtr prop;
-+
-+ if ((node == NULL) || (name == NULL))
-+ return(NULL);
-+
-+ if (ns == NULL)
-+ return(xmlSetProp(node, name, value));
-+ if (ns->href == NULL)
-+ return(NULL);
-+ prop = node->properties;
-+
-+ while (prop != NULL) {
-+ /*
-+ * One need to have
-+ * - same attribute names
-+ * - and the attribute carrying that namespace
-+ * or
-+ * no namespace on the attribute and the element carrying it
-+ */
-+ if ((xmlStrEqual(prop->name, name)) &&
-+ (((prop->ns == NULL) && (node->ns != NULL) &&
-+ (xmlStrEqual(node->ns->href, ns->href))) ||
-+ ((prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))))) {
-+ if (prop->children != NULL)
-+ xmlFreeNodeList(prop->children);
-+ prop->children = NULL;
-+ prop->last = NULL;
-+ prop->ns = ns;
-+ if (value != NULL) {
-+ xmlChar *buffer;
-+ xmlNodePtr tmp;
-+
-+ buffer = xmlEncodeEntitiesReentrant(node->doc, value);
-+ prop->children = xmlStringGetNodeList(node->doc, buffer);
-+ prop->last = NULL;
-+ tmp = prop->children;
-+ while (tmp != NULL) {
-+ tmp->parent = (xmlNodePtr) prop;
-+ if (tmp->next == NULL)
-+ prop->last = tmp;
-+ tmp = tmp->next;
-+ }
-+ xmlFree(buffer);
-+ }
-+ return(prop);
-+ }
-+ prop = prop->next;
-+ }
-+ prop = xmlNewNsProp(node, ns, name, value);
-+ return(prop);
-+}
-+
-+/**
-+ * xmlNodeIsText:
-+ * @node: the node
-+ *
-+ * Is this node a Text node ?
-+ * Returns 1 yes, 0 no
-+ */
-+int
-+xmlNodeIsText(xmlNodePtr node) {
-+ if (node == NULL) return(0);
-+
-+ if (node->type == XML_TEXT_NODE) return(1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlIsBlankNode:
-+ * @node: the node
-+ *
-+ * Checks whether this node is an empty or whitespace only
-+ * (and possibly ignorable) text-node.
-+ *
-+ * Returns 1 yes, 0 no
-+ */
-+int
-+xmlIsBlankNode(xmlNodePtr node) {
-+ const xmlChar *cur;
-+ if (node == NULL) return(0);
-+
-+ if (node->type != XML_TEXT_NODE) return(0);
-+ if (node->content == NULL) return(1);
-+#ifndef XML_USE_BUFFER_CONTENT
-+ cur = node->content;
-+#else
-+ cur = xmlBufferContent(node->content);
-+#endif
-+ while (*cur != 0) {
-+ if (!IS_BLANK(*cur)) return(0);
-+ cur++;
-+ }
-+
-+ return(1);
-+}
-+
-+/**
-+ * xmlTextConcat:
-+ * @node: the node
-+ * @content: the content
-+ * @len: @content lenght
-+ *
-+ * Concat the given string at the end of the existing node content
-+ */
-+
-+void
-+xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
-+ if (node == NULL) return;
-+
-+ if ((node->type != XML_TEXT_NODE) &&
-+ (node->type != XML_CDATA_SECTION_NODE)) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlTextConcat: node is not text nor cdata\n");
-+#endif
-+ return;
-+ }
-+#ifndef XML_USE_BUFFER_CONTENT
-+ node->content = xmlStrncat(node->content, content, len);
-+#else
-+ xmlBufferAdd(node->content, content, len);
-+#endif
-+}
-+
-+/************************************************************************
-+ * *
-+ * Output : to a FILE or in memory *
-+ * *
-+ ************************************************************************/
-+
-+#define BASE_BUFFER_SIZE 4000
-+
-+/**
-+ * xmlBufferCreate:
-+ *
-+ * routine to create an XML buffer.
-+ * returns the new structure.
-+ */
-+xmlBufferPtr
-+xmlBufferCreate(void) {
-+ xmlBufferPtr ret;
-+
-+ ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferCreate : out of memory!\n");
-+ return(NULL);
-+ }
-+ ret->use = 0;
-+ ret->size = BASE_BUFFER_SIZE;
-+ ret->alloc = xmlBufferAllocScheme;
-+ ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
-+ if (ret->content == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferCreate : out of memory!\n");
-+ xmlFree(ret);
-+ return(NULL);
-+ }
-+ ret->content[0] = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlBufferCreateSize:
-+ * @size: initial size of buffer
-+ *
-+ * routine to create an XML buffer.
-+ * returns the new structure.
-+ */
-+xmlBufferPtr
-+xmlBufferCreateSize(size_t size) {
-+ xmlBufferPtr ret;
-+
-+ ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferCreate : out of memory!\n");
-+ return(NULL);
-+ }
-+ ret->use = 0;
-+ ret->alloc = xmlBufferAllocScheme;
-+ ret->size = (size ? size+2 : 0); /* +1 for ending null */
-+ if (ret->size){
-+ ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
-+ if (ret->content == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferCreate : out of memory!\n");
-+ xmlFree(ret);
-+ return(NULL);
-+ }
-+ ret->content[0] = 0;
-+ } else
-+ ret->content = NULL;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlBufferSetAllocationScheme:
-+ * @buf: the buffer to free
-+ * @scheme: allocation scheme to use
-+ *
-+ * Sets the allocation scheme for this buffer
-+ */
-+void
-+xmlBufferSetAllocationScheme(xmlBufferPtr buf,
-+ xmlBufferAllocationScheme scheme) {
-+ if (buf == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferSetAllocationScheme: buf == NULL\n");
-+#endif
-+ return;
-+ }
-+
-+ buf->alloc = scheme;
-+}
-+
-+/**
-+ * xmlBufferFree:
-+ * @buf: the buffer to free
-+ *
-+ * Frees an XML buffer.
-+ */
-+void
-+xmlBufferFree(xmlBufferPtr buf) {
-+ if (buf == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferFree: buf == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (buf->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ memset(buf->content, -1, BASE_BUFFER_SIZE);
-+#else
-+ memset(buf->content, -1, buf->size);
-+#endif
-+ xmlFree(buf->content);
-+ }
-+ memset(buf, -1, sizeof(xmlBuffer));
-+ xmlFree(buf);
-+}
-+
-+/**
-+ * xmlBufferEmpty:
-+ * @buf: the buffer
-+ *
-+ * empty a buffer.
-+ */
-+void
-+xmlBufferEmpty(xmlBufferPtr buf) {
-+ if (buf->content == NULL) return;
-+ buf->use = 0;
-+ memset(buf->content, -1, buf->size);/* just for debug */
-+}
-+
-+/**
-+ * xmlBufferShrink:
-+ * @buf: the buffer to dump
-+ * @len: the number of xmlChar to remove
-+ *
-+ * Remove the beginning of an XML buffer.
-+ *
-+ * Returns the number of xmlChar removed, or -1 in case of failure.
-+ */
-+int
-+xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
-+ if (len == 0) return(0);
-+ if (len > buf->use) return(-1);
-+
-+ buf->use -= len;
-+ memmove(buf->content, &buf->content[len], buf->use * sizeof(xmlChar));
-+
-+ buf->content[buf->use] = 0;
-+ return(len);
-+}
-+
-+/**
-+ * xmlBufferGrow:
-+ * @buf: the buffer
-+ * @len: the minimum free size to allocate
-+ *
-+ * Grow the available space of an XML buffer.
-+ *
-+ * Returns the new available space or -1 in case of error
-+ */
-+int
-+xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
-+ int size;
-+ xmlChar *newbuf;
-+
-+ if (len + buf->use < buf->size) return(0);
-+
-+ size = buf->use + len + 100;
-+
-+ newbuf = (xmlChar *) xmlRealloc(buf->content, size);
-+ if (newbuf == NULL) return(-1);
-+ buf->content = newbuf;
-+ buf->size = size;
-+ return(buf->size - buf->use);
-+}
-+
-+/**
-+ * xmlBufferDump:
-+ * @file: the file output
-+ * @buf: the buffer to dump
-+ *
-+ * Dumps an XML buffer to a FILE *.
-+ * Returns the number of xmlChar written
-+ */
-+int
-+xmlBufferDump(FILE *file, xmlBufferPtr buf) {
-+ int ret;
-+
-+ if (buf == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferDump: buf == NULL\n");
-+#endif
-+ return(0);
-+ }
-+ if (buf->content == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferDump: buf->content == NULL\n");
-+#endif
-+ return(0);
-+ }
-+ if (file == NULL) file = stdout;
-+ ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlBufferContent:
-+ * @buf: the buffer to resize
-+ *
-+ * Returns the internal content
-+ */
-+
-+const xmlChar*
-+xmlBufferContent(const xmlBufferPtr buf)
-+{
-+ if(!buf)
-+ return NULL;
-+
-+ return buf->content;
-+}
-+
-+/**
-+ * xmlBufferLength:
-+ * @buf: the buffer
-+ *
-+ * Returns the length of data in the internal content
-+ */
-+
-+int
-+xmlBufferLength(const xmlBufferPtr buf)
-+{
-+ if(!buf)
-+ return 0;
-+
-+ return buf->use;
-+}
-+
-+/**
-+ * xmlBufferResize:
-+ * @buf: the buffer to resize
-+ * @size: the desired size
-+ *
-+ * Resize a buffer to accomodate minimum size of @size.
-+ *
-+ * Returns 0 in case of problems, 1 otherwise
-+ */
-+int
-+xmlBufferResize(xmlBufferPtr buf, unsigned int size)
-+{
-+ unsigned int newSize;
-+ xmlChar* rebuf = NULL;
-+
-+ /*take care of empty case*/
-+ newSize = (buf->size ? buf->size*2 : size);
-+
-+ /* Don't resize if we don't have to */
-+ if (size < buf->size)
-+ return 1;
-+
-+ /* figure out new size */
-+ switch (buf->alloc){
-+ case XML_BUFFER_ALLOC_DOUBLEIT:
-+ while (size > newSize) newSize *= 2;
-+ break;
-+ case XML_BUFFER_ALLOC_EXACT:
-+ newSize = size+10;
-+ break;
-+ default:
-+ newSize = size+10;
-+ break;
-+ }
-+
-+ if (buf->content == NULL)
-+ rebuf = (xmlChar *) xmlMalloc(newSize * sizeof(xmlChar));
-+ else
-+ rebuf = (xmlChar *) xmlRealloc(buf->content,
-+ newSize * sizeof(xmlChar));
-+ if (rebuf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd : out of memory!\n");
-+ return 0;
-+ }
-+ buf->content = rebuf;
-+ buf->size = newSize;
-+
-+ return 1;
-+}
-+
-+/**
-+ * xmlBufferAdd:
-+ * @buf: the buffer to dump
-+ * @str: the xmlChar string
-+ * @len: the number of xmlChar to add
-+ *
-+ * Add a string range to an XML buffer. if len == -1, the lenght of
-+ * str is recomputed.
-+ */
-+void
-+xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
-+ unsigned int needSize;
-+
-+ if (str == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd: str == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (len < -1) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd: len < 0\n");
-+#endif
-+ return;
-+ }
-+ if (len == 0) return;
-+
-+ if (len < 0)
-+ len = xmlStrlen(str);
-+
-+ if (len <= 0) return;
-+
-+ needSize = buf->use + len + 2;
-+ if (needSize > buf->size){
-+ if (!xmlBufferResize(buf, needSize)){
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd : out of memory!\n");
-+ return;
-+ }
-+ }
-+
-+ memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
-+ buf->use += len;
-+ buf->content[buf->use] = 0;
-+}
-+
-+/**
-+ * xmlBufferAddHead:
-+ * @buf: the buffer
-+ * @str: the xmlChar string
-+ * @len: the number of xmlChar to add
-+ *
-+ * Add a string range to the beginning of an XML buffer.
-+ * if len == -1, the lenght of @str is recomputed.
-+ */
-+void
-+xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
-+ unsigned int needSize;
-+
-+ if (str == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd: str == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (len < -1) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd: len < 0\n");
-+#endif
-+ return;
-+ }
-+ if (len == 0) return;
-+
-+ if (len < 0)
-+ len = xmlStrlen(str);
-+
-+ if (len <= 0) return;
-+
-+ needSize = buf->use + len + 2;
-+ if (needSize > buf->size){
-+ if (!xmlBufferResize(buf, needSize)){
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAddHead : out of memory!\n");
-+ return;
-+ }
-+ }
-+
-+ memmove(&buf->content[len], &buf->content[0], buf->use * sizeof(xmlChar));
-+ memmove(&buf->content[0], str, len * sizeof(xmlChar));
-+ buf->use += len;
-+ buf->content[buf->use] = 0;
-+}
-+
-+/**
-+ * xmlBufferCat:
-+ * @buf: the buffer to dump
-+ * @str: the xmlChar string
-+ *
-+ * Append a zero terminated string to an XML buffer.
-+ */
-+void
-+xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
-+ if (str != NULL)
-+ xmlBufferAdd(buf, str, -1);
-+}
-+
-+/**
-+ * xmlBufferCCat:
-+ * @buf: the buffer to dump
-+ * @str: the C char string
-+ *
-+ * Append a zero terminated C string to an XML buffer.
-+ */
-+void
-+xmlBufferCCat(xmlBufferPtr buf, const char *str) {
-+ const char *cur;
-+
-+ if (str == NULL) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferAdd: str == NULL\n");
-+#endif
-+ return;
-+ }
-+ for (cur = str;*cur != 0;cur++) {
-+ if (buf->use + 10 >= buf->size) {
-+ if (!xmlBufferResize(buf, buf->use+10)){
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferCCat : out of memory!\n");
-+ return;
-+ }
-+ }
-+ buf->content[buf->use++] = *cur;
-+ }
-+ buf->content[buf->use] = 0;
-+}
-+
-+/**
-+ * xmlBufferWriteCHAR:
-+ * @buf: the XML buffer
-+ * @string: the string to add
-+ *
-+ * routine which manages and grows an output buffer. This one adds
-+ * xmlChars at the end of the buffer.
-+ */
-+void
-+#ifdef VMS
-+xmlBufferWriteXmlCHAR
-+#else
-+xmlBufferWriteCHAR
-+#endif
-+(xmlBufferPtr buf, const xmlChar *string) {
-+ xmlBufferCat(buf, string);
-+}
-+
-+/**
-+ * xmlBufferWriteChar:
-+ * @buf: the XML buffer output
-+ * @string: the string to add
-+ *
-+ * routine which manage and grows an output buffer. This one add
-+ * C chars at the end of the array.
-+ */
-+void
-+xmlBufferWriteChar(xmlBufferPtr buf, const char *string) {
-+ xmlBufferCCat(buf, string);
-+}
-+
-+
-+/**
-+ * xmlBufferWriteQuotedString:
-+ * @buf: the XML buffer output
-+ * @string: the string to add
-+ *
-+ * routine which manage and grows an output buffer. This one writes
-+ * a quoted or double quoted xmlChar string, checking first if it holds
-+ * quote or double-quotes internally
-+ */
-+void
-+xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
-+ if (xmlStrchr(string, '"')) {
-+ if (xmlStrchr(string, '\'')) {
-+#ifdef DEBUG_BUFFER
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
-+#endif
-+ }
-+ xmlBufferCCat(buf, "'");
-+ xmlBufferCat(buf, string);
-+ xmlBufferCCat(buf, "'");
-+ } else {
-+ xmlBufferCCat(buf, "\"");
-+ xmlBufferCat(buf, string);
-+ xmlBufferCCat(buf, "\"");
-+ }
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Dumping XML tree content to a simple buffer *
-+ * *
-+ ************************************************************************/
-+
-+void
-+xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-+ int format);
-+static void
-+xmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-+ int format);
-+void
-+htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur);
-+
-+/**
-+ * xmlNsDump:
-+ * @buf: the XML buffer output
-+ * @cur: a namespace
-+ *
-+ * Dump a local Namespace definition.
-+ * Should be called in the context of attributes dumps.
-+ */
-+static void
-+xmlNsDump(xmlBufferPtr buf, xmlNsPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNsDump : Ns == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->type == XML_LOCAL_NAMESPACE) {
-+ /* Within the context of an element attributes */
-+ if (cur->prefix != NULL) {
-+ xmlBufferWriteChar(buf, " xmlns:");
-+ xmlBufferWriteCHAR(buf, cur->prefix);
-+ } else
-+ xmlBufferWriteChar(buf, " xmlns");
-+ xmlBufferWriteChar(buf, "=");
-+ xmlBufferWriteQuotedString(buf, cur->href);
-+ }
-+}
-+
-+/**
-+ * xmlNsListDump:
-+ * @buf: the XML buffer output
-+ * @cur: the first namespace
-+ *
-+ * Dump a list of local Namespace definitions.
-+ * Should be called in the context of attributes dumps.
-+ */
-+static void
-+xmlNsListDump(xmlBufferPtr buf, xmlNsPtr cur) {
-+ while (cur != NULL) {
-+ xmlNsDump(buf, cur);
-+ cur = cur->next;
-+ }
-+}
-+
-+/**
-+ * xmlDtdDump:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ *
-+ * Dump the XML document DTD, if any.
-+ */
-+static void
-+xmlDtdDump(xmlBufferPtr buf, xmlDtdPtr dtd) {
-+ if (dtd == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDtdDump : no internal subset\n");
-+#endif
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, "<!DOCTYPE ");
-+ xmlBufferWriteCHAR(buf, dtd->name);
-+ if (dtd->ExternalID != NULL) {
-+ xmlBufferWriteChar(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf, dtd->ExternalID);
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteQuotedString(buf, dtd->SystemID);
-+ } else if (dtd->SystemID != NULL) {
-+ xmlBufferWriteChar(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf, dtd->SystemID);
-+ }
-+ if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
-+ (dtd->attributes == NULL) && (dtd->notations == NULL)) {
-+ xmlBufferWriteChar(buf, ">");
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, " [\n");
-+ xmlNodeListDump(buf, dtd->doc, dtd->children, -1, 0);
-+#if 0
-+ if (dtd->entities != NULL)
-+ xmlDumpEntitiesTable(buf, (xmlEntitiesTablePtr) dtd->entities);
-+ if (dtd->notations != NULL)
-+ xmlDumpNotationTable(buf, (xmlNotationTablePtr) dtd->notations);
-+ if (dtd->elements != NULL)
-+ xmlDumpElementTable(buf, (xmlElementTablePtr) dtd->elements);
-+ if (dtd->attributes != NULL)
-+ xmlDumpAttributeTable(buf, (xmlAttributeTablePtr) dtd->attributes);
-+#endif
-+ xmlBufferWriteChar(buf, "]>");
-+}
-+
-+/**
-+ * xmlAttrDump:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the attribute pointer
-+ *
-+ * Dump an XML attribute
-+ */
-+static void
-+xmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-+ xmlChar *value;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAttrDump : property == NULL\n");
-+#endif
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, " ");
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ xmlBufferWriteCHAR(buf, cur->ns->prefix);
-+ xmlBufferWriteChar(buf, ":");
-+ }
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ value = xmlNodeListGetString(doc, cur->children, 0);
-+ if (value != NULL) {
-+ xmlBufferWriteChar(buf, "=");
-+ xmlBufferWriteQuotedString(buf, value);
-+ xmlFree(value);
-+ } else {
-+ xmlBufferWriteChar(buf, "=\"\"");
-+ }
-+}
-+
-+/**
-+ * xmlAttrListDump:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the first attribute pointer
-+ *
-+ * Dump a list of XML attributes
-+ */
-+static void
-+xmlAttrListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAttrListDump : property == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ xmlAttrDump(buf, doc, cur);
-+ cur = cur->next;
-+ }
-+}
-+
-+
-+
-+/**
-+ * xmlNodeListDump:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the first node
-+ * @level: the imbrication level for indenting
-+ * @format: is formatting allowed
-+ *
-+ * Dump an XML node list, recursive behaviour,children are printed too.
-+ */
-+static void
-+xmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-+ int format) {
-+ int i;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeListDump : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ if ((format) && (xmlIndentTreeOutput) &&
-+ (cur->type == XML_ELEMENT_NODE))
-+ for (i = 0;i < level;i++)
-+ xmlBufferWriteChar(buf, " ");
-+ xmlNodeDump(buf, doc, cur, level, format);
-+ if (format) {
-+ xmlBufferWriteChar(buf, "\n");
-+ }
-+ cur = cur->next;
-+ }
-+}
-+
-+/**
-+ * xmlNodeDump:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the current node
-+ * @level: the imbrication level for indenting
-+ * @format: is formatting allowed
-+ *
-+ * Dump an XML node, recursive behaviour,children are printed too.
-+ */
-+void
-+xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-+ int format) {
-+ int i;
-+ xmlNodePtr tmp;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeDump : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->type == XML_XINCLUDE_START)
-+ return;
-+ if (cur->type == XML_XINCLUDE_END)
-+ return;
-+ if (cur->type == XML_DTD_NODE) {
-+ xmlDtdDump(buf, (xmlDtdPtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_ELEMENT_DECL) {
-+ xmlDumpElementDecl(buf, (xmlElementPtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_ATTRIBUTE_DECL) {
-+ xmlDumpAttributeDecl(buf, (xmlAttributePtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_ENTITY_DECL) {
-+ xmlDumpEntityDecl(buf, (xmlEntityPtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_TEXT_NODE) {
-+ if (cur->content != NULL) {
-+ if ((cur->name == xmlStringText) ||
-+ (cur->name != xmlStringTextNoenc)) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+#else
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlBufferWriteCHAR(buf, buffer);
-+ xmlFree(buffer);
-+ }
-+ } else {
-+ /*
-+ * Disable escaping, needed for XSLT
-+ */
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlBufferWriteCHAR(buf, cur->content);
-+#else
-+ xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
-+#endif
-+ }
-+ }
-+ return;
-+ }
-+ if (cur->type == XML_PI_NODE) {
-+ if (cur->content != NULL) {
-+ xmlBufferWriteChar(buf, "<?");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ if (cur->content != NULL) {
-+ xmlBufferWriteChar(buf, " ");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlBufferWriteCHAR(buf, cur->content);
-+#else
-+ xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
-+#endif
-+ }
-+ xmlBufferWriteChar(buf, "?>");
-+ } else {
-+ xmlBufferWriteChar(buf, "<?");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ xmlBufferWriteChar(buf, "?>");
-+ }
-+ return;
-+ }
-+ if (cur->type == XML_COMMENT_NODE) {
-+ if (cur->content != NULL) {
-+ xmlBufferWriteChar(buf, "<!--");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlBufferWriteCHAR(buf, cur->content);
-+#else
-+ xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
-+#endif
-+ xmlBufferWriteChar(buf, "-->");
-+ }
-+ return;
-+ }
-+ if (cur->type == XML_ENTITY_REF_NODE) {
-+ xmlBufferWriteChar(buf, "&");
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ xmlBufferWriteChar(buf, ";");
-+ return;
-+ }
-+ if (cur->type == XML_CDATA_SECTION_NODE) {
-+ xmlBufferWriteChar(buf, "<![CDATA[");
-+ if (cur->content != NULL)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlBufferWriteCHAR(buf, cur->content);
-+#else
-+ xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
-+#endif
-+ xmlBufferWriteChar(buf, "]]>");
-+ return;
-+ }
-+
-+ if (format == 1) {
-+ tmp = cur->children;
-+ while (tmp != NULL) {
-+ if ((tmp->type == XML_TEXT_NODE) ||
-+ (tmp->type == XML_ENTITY_REF_NODE)) {
-+ format = 0;
-+ break;
-+ }
-+ tmp = tmp->next;
-+ }
-+ }
-+ xmlBufferWriteChar(buf, "<");
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ xmlBufferWriteCHAR(buf, cur->ns->prefix);
-+ xmlBufferWriteChar(buf, ":");
-+ }
-+
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ if (cur->nsDef)
-+ xmlNsListDump(buf, cur->nsDef);
-+ if (cur->properties != NULL)
-+ xmlAttrListDump(buf, doc, cur->properties);
-+
-+ if ((cur->content == NULL) && (cur->children == NULL) &&
-+ (!xmlSaveNoEmptyTags)) {
-+ xmlBufferWriteChar(buf, "/>");
-+ return;
-+ }
-+ xmlBufferWriteChar(buf, ">");
-+ if (cur->content != NULL) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+#else
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlBufferWriteCHAR(buf, buffer);
-+ xmlFree(buffer);
-+ }
-+ }
-+ if (cur->children != NULL) {
-+ if (format) xmlBufferWriteChar(buf, "\n");
-+ xmlNodeListDump(buf, doc, cur->children,
-+ (level >= 0?level+1:-1), format);
-+ if ((xmlIndentTreeOutput) && (format))
-+ for (i = 0;i < level;i++)
-+ xmlBufferWriteChar(buf, " ");
-+ }
-+ xmlBufferWriteChar(buf, "</");
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ xmlBufferWriteCHAR(buf, cur->ns->prefix);
-+ xmlBufferWriteChar(buf, ":");
-+ }
-+
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ xmlBufferWriteChar(buf, ">");
-+}
-+
-+/**
-+ * xmlElemDump:
-+ * @f: the FILE * for the output
-+ * @doc: the document
-+ * @cur: the current node
-+ *
-+ * Dump an XML/HTML node, recursive behaviour,children are printed too.
-+ */
-+void
-+xmlElemDump(FILE *f, xmlDocPtr doc, xmlNodePtr cur) {
-+ xmlBufferPtr buf;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlElemDump : cur == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (doc == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlElemDump : doc == NULL\n");
-+#endif
-+ }
-+ buf = xmlBufferCreate();
-+ if (buf == NULL) return;
-+ if ((doc != NULL) &&
-+ (doc->type == XML_HTML_DOCUMENT_NODE)) {
-+#ifdef LIBXML_HTML_ENABLED
-+ htmlNodeDump(buf, doc, cur);
-+#else
-+ xmlGenericError(xmlGenericErrorContext,
-+ "HTML support not compiled in\n");
-+#endif /* LIBXML_HTML_ENABLED */
-+ } else
-+ xmlNodeDump(buf, doc, cur, 0, 1);
-+ xmlBufferDump(f, buf);
-+ xmlBufferFree(buf);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Dumping XML tree content to an I/O output buffer *
-+ * *
-+ ************************************************************************/
-+
-+void
-+xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
-+ int level, int format, const char *encoding);
-+static void
-+xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
-+ int level, int format, const char *encoding);
-+/**
-+ * xmlNsDumpOutput:
-+ * @buf: the XML buffer output
-+ * @cur: a namespace
-+ *
-+ * Dump a local Namespace definition.
-+ * Should be called in the context of attributes dumps.
-+ */
-+static void
-+xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNsDump : Ns == NULL\n");
-+#endif
-+ return;
-+ }
-+ if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
-+ /* Within the context of an element attributes */
-+ if (cur->prefix != NULL) {
-+ xmlOutputBufferWriteString(buf, " xmlns:");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
-+ } else
-+ xmlOutputBufferWriteString(buf, " xmlns");
-+ xmlOutputBufferWriteString(buf, "=");
-+ xmlBufferWriteQuotedString(buf->buffer, cur->href);
-+ }
-+}
-+
-+/**
-+ * xmlNsListDumpOutput:
-+ * @buf: the XML buffer output
-+ * @cur: the first namespace
-+ *
-+ * Dump a list of local Namespace definitions.
-+ * Should be called in the context of attributes dumps.
-+ */
-+static void
-+xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
-+ while (cur != NULL) {
-+ xmlNsDumpOutput(buf, cur);
-+ cur = cur->next;
-+ }
-+}
-+
-+/**
-+ * xmlDtdDumpOutput:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @encoding: an optional encoding string
-+ *
-+ * Dump the XML document DTD, if any.
-+ */
-+static void
-+xmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDtdPtr dtd, const char *encoding) {
-+ if (dtd == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDtdDump : no internal subset\n");
-+#endif
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
-+ xmlOutputBufferWriteString(buf, (const char *)dtd->name);
-+ if (dtd->ExternalID != NULL) {
-+ xmlOutputBufferWriteString(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID);
-+ xmlOutputBufferWriteString(buf, " ");
-+ xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
-+ } else if (dtd->SystemID != NULL) {
-+ xmlOutputBufferWriteString(buf, " SYSTEM ");
-+ xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
-+ }
-+ if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
-+ (dtd->attributes == NULL) && (dtd->notations == NULL)) {
-+ xmlOutputBufferWriteString(buf, ">");
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, " [\n");
-+ xmlNodeListDumpOutput(buf, dtd->doc, dtd->children, -1, 0, encoding);
-+ xmlOutputBufferWriteString(buf, "]>");
-+}
-+
-+/**
-+ * xmlAttrDumpOutput:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the attribute pointer
-+ * @encoding: an optional encoding string
-+ *
-+ * Dump an XML attribute
-+ */
-+static void
-+xmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
-+ const char *encoding) {
-+ xmlChar *value;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAttrDump : property == NULL\n");
-+#endif
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, " ");
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
-+ xmlOutputBufferWriteString(buf, ":");
-+ }
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ value = xmlNodeListGetString(doc, cur->children, 0);
-+ if (value) {
-+ xmlOutputBufferWriteString(buf, "=");
-+ xmlBufferWriteQuotedString(buf->buffer, value);
-+ xmlFree(value);
-+ } else {
-+ xmlOutputBufferWriteString(buf, "=\"\"");
-+ }
-+}
-+
-+/**
-+ * xmlAttrListDumpOutput:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the first attribute pointer
-+ * @encoding: an optional encoding string
-+ *
-+ * Dump a list of XML attributes
-+ */
-+static void
-+xmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
-+ xmlAttrPtr cur, const char *encoding) {
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAttrListDump : property == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ xmlAttrDumpOutput(buf, doc, cur, encoding);
-+ cur = cur->next;
-+ }
-+}
-+
-+
-+
-+/**
-+ * xmlNodeListDumpOutput:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the first node
-+ * @level: the imbrication level for indenting
-+ * @format: is formatting allowed
-+ * @encoding: an optional encoding string
-+ *
-+ * Dump an XML node list, recursive behaviour,children are printed too.
-+ */
-+static void
-+xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
-+ xmlNodePtr cur, int level, int format, const char *encoding) {
-+ int i;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeListDump : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ while (cur != NULL) {
-+ if ((format) && (xmlIndentTreeOutput) &&
-+ (cur->type == XML_ELEMENT_NODE))
-+ for (i = 0;i < level;i++)
-+ xmlOutputBufferWriteString(buf, " ");
-+ xmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
-+ if (format) {
-+ xmlOutputBufferWriteString(buf, "\n");
-+ }
-+ cur = cur->next;
-+ }
-+}
-+
-+/**
-+ * xmlNodeDumpOutput:
-+ * @buf: the XML buffer output
-+ * @doc: the document
-+ * @cur: the current node
-+ * @level: the imbrication level for indenting
-+ * @format: is formatting allowed
-+ * @encoding: an optional encoding string
-+ *
-+ * Dump an XML node, recursive behaviour,children are printed too.
-+ */
-+void
-+xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
-+ int level, int format, const char *encoding) {
-+ int i;
-+ xmlNodePtr tmp;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNodeDump : node == NULL\n");
-+#endif
-+ return;
-+ }
-+ if (cur->type == XML_XINCLUDE_START)
-+ return;
-+ if (cur->type == XML_XINCLUDE_END)
-+ return;
-+ if (cur->type == XML_DTD_NODE) {
-+ xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
-+ return;
-+ }
-+ if (cur->type == XML_ELEMENT_DECL) {
-+ xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_ATTRIBUTE_DECL) {
-+ xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_ENTITY_DECL) {
-+ xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
-+ return;
-+ }
-+ if (cur->type == XML_TEXT_NODE) {
-+ if (cur->content != NULL) {
-+ if ((cur->name == xmlStringText) ||
-+ (cur->name != xmlStringTextNoenc)) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ if (encoding == NULL)
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+ else
-+ buffer = xmlEncodeSpecialChars(doc, cur->content);
-+#else
-+ if (encoding == NULL)
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+ else
-+ buffer = xmlEncodeSpecialChars(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlOutputBufferWriteString(buf, (const char *)buffer);
-+ xmlFree(buffer);
-+ }
-+ } else {
-+ /*
-+ * Disable escaping, needed for XSLT
-+ */
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *) cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf, xmlBufferContent(cur->content));
-+#endif
-+ }
-+ }
-+
-+ return;
-+ }
-+ if (cur->type == XML_PI_NODE) {
-+ if (cur->content != NULL) {
-+ xmlOutputBufferWriteString(buf, "<?");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ if (cur->content != NULL) {
-+ xmlOutputBufferWriteString(buf, " ");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
-+#endif
-+ }
-+ xmlOutputBufferWriteString(buf, "?>");
-+ } else {
-+ xmlOutputBufferWriteString(buf, "<?");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ xmlOutputBufferWriteString(buf, "?>");
-+ }
-+ return;
-+ }
-+ if (cur->type == XML_COMMENT_NODE) {
-+ if (cur->content != NULL) {
-+ xmlOutputBufferWriteString(buf, "<!--");
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
-+#endif
-+ xmlOutputBufferWriteString(buf, "-->");
-+ }
-+ return;
-+ }
-+ if (cur->type == XML_ENTITY_REF_NODE) {
-+ xmlOutputBufferWriteString(buf, "&");
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ xmlOutputBufferWriteString(buf, ";");
-+ return;
-+ }
-+ if (cur->type == XML_CDATA_SECTION_NODE) {
-+ xmlOutputBufferWriteString(buf, "<![CDATA[");
-+ if (cur->content != NULL)
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
-+#else
-+ xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
-+#endif
-+ xmlOutputBufferWriteString(buf, "]]>");
-+ return;
-+ }
-+
-+ if (format == 1) {
-+ tmp = cur->children;
-+ while (tmp != NULL) {
-+ if ((tmp->type == XML_TEXT_NODE) ||
-+ (tmp->type == XML_ENTITY_REF_NODE)) {
-+ format = 0;
-+ break;
-+ }
-+ tmp = tmp->next;
-+ }
-+ }
-+ xmlOutputBufferWriteString(buf, "<");
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
-+ xmlOutputBufferWriteString(buf, ":");
-+ }
-+
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ if (cur->nsDef)
-+ xmlNsListDumpOutput(buf, cur->nsDef);
-+ if (cur->properties != NULL)
-+ xmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
-+
-+ if ((cur->content == NULL) && (cur->children == NULL) &&
-+ (!xmlSaveNoEmptyTags)) {
-+ xmlOutputBufferWriteString(buf, "/>");
-+ return;
-+ }
-+ xmlOutputBufferWriteString(buf, ">");
-+ if (cur->content != NULL) {
-+ xmlChar *buffer;
-+
-+#ifndef XML_USE_BUFFER_CONTENT
-+ if (encoding == NULL)
-+ buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-+ else
-+ buffer = xmlEncodeSpecialChars(doc, cur->content);
-+#else
-+ if (encoding == NULL)
-+ buffer = xmlEncodeEntitiesReentrant(doc,
-+ xmlBufferContent(cur->content));
-+ else
-+ buffer = xmlEncodeSpecialChars(doc,
-+ xmlBufferContent(cur->content));
-+#endif
-+ if (buffer != NULL) {
-+ xmlOutputBufferWriteString(buf, (const char *)buffer);
-+ xmlFree(buffer);
-+ }
-+ }
-+ if (cur->children != NULL) {
-+ if (format) xmlOutputBufferWriteString(buf, "\n");
-+ xmlNodeListDumpOutput(buf, doc, cur->children,
-+ (level >= 0?level+1:-1), format, encoding);
-+ if ((xmlIndentTreeOutput) && (format))
-+ for (i = 0;i < level;i++)
-+ xmlOutputBufferWriteString(buf, " ");
-+ }
-+ xmlOutputBufferWriteString(buf, "</");
-+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-+ xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
-+ xmlOutputBufferWriteString(buf, ":");
-+ }
-+
-+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
-+ xmlOutputBufferWriteString(buf, ">");
-+}
-+
-+/**
-+ * xmlDocContentDumpOutput:
-+ * @buf: the XML buffer output
-+ * @cur: the document
-+ * @encoding: an optional encoding string
-+ * @format: should formatting spaces been added
-+ *
-+ * Dump an XML document.
-+ */
-+static void
-+xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
-+ const char *encoding, int format) {
-+ xmlOutputBufferWriteString(buf, "<?xml version=");
-+ if (cur->version != NULL)
-+ xmlBufferWriteQuotedString(buf->buffer, cur->version);
-+ else
-+ xmlOutputBufferWriteString(buf, "\"1.0\"");
-+ if (encoding == NULL) {
-+ if (cur->encoding != NULL)
-+ encoding = (const char *) cur->encoding;
-+ else if (cur->charset != XML_CHAR_ENCODING_UTF8)
-+ encoding = xmlGetCharEncodingName((xmlCharEncoding) cur->charset);
-+ }
-+ if (encoding != NULL) {
-+ xmlOutputBufferWriteString(buf, " encoding=");
-+ xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
-+ }
-+ switch (cur->standalone) {
-+ case 0:
-+ xmlOutputBufferWriteString(buf, " standalone=\"no\"");
-+ break;
-+ case 1:
-+ xmlOutputBufferWriteString(buf, " standalone=\"yes\"");
-+ break;
-+ }
-+ xmlOutputBufferWriteString(buf, "?>\n");
-+ if (cur->children != NULL) {
-+ xmlNodePtr child = cur->children;
-+
-+ while (child != NULL) {
-+ xmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
-+ xmlOutputBufferWriteString(buf, "\n");
-+ child = child->next;
-+ }
-+ }
-+}
-+
-+/************************************************************************
-+ * *
-+ * Saving functions front-ends *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlDocDumpMemoryEnc:
-+ * @out_doc: Document to generate XML text from
-+ * @doc_txt_ptr: Memory pointer for allocated XML text
-+ * @doc_txt_len: Length of the generated XML text
-+ * @txt_encoding: Character encoding to use when generating XML text
-+ * @format: should formatting spaces been added
-+ *
-+ * Dump the current DOM tree into memory using the character encoding specified
-+ * by the caller. Note it is up to the caller of this function to free the
-+ * allocated memory.
-+ */
-+
-+void
-+xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
-+ int * doc_txt_len, const char * txt_encoding, int format) {
-+ int dummy = 0;
-+
-+ xmlCharEncoding doc_charset;
-+ xmlOutputBufferPtr out_buff = NULL;
-+ xmlCharEncodingHandlerPtr conv_hdlr = NULL;
-+
-+ if (doc_txt_len == NULL) {
-+ doc_txt_len = &dummy; /* Continue, caller just won't get length */
-+ }
-+
-+ if (doc_txt_ptr == NULL) {
-+ *doc_txt_len = 0;
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDumpFormatMemoryEnc: Null return buffer pointer.");
-+ return;
-+ }
-+
-+ *doc_txt_ptr = NULL;
-+ *doc_txt_len = 0;
-+
-+ if (out_doc == NULL) {
-+ /* No document, no output */
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDumpFormatMemoryEnc: Null DOM tree document pointer.\n");
-+ return;
-+ }
-+
-+ /*
-+ * Validate the encoding value, if provided.
-+ * This logic is copied from xmlSaveFileEnc.
-+ */
-+
-+ if (txt_encoding == NULL)
-+ txt_encoding = (const char *) out_doc->encoding;
-+ if (txt_encoding != NULL) {
-+ doc_charset = xmlParseCharEncoding(txt_encoding);
-+
-+ if (out_doc->charset != XML_CHAR_ENCODING_UTF8) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDumpFormatMemoryEnc: Source document not in UTF8\n");
-+ return;
-+
-+ } else if (doc_charset != XML_CHAR_ENCODING_UTF8) {
-+ conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
-+ if ( conv_hdlr == NULL ) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "%s: %s %s '%s'\n",
-+ "xmlDocDumpFormatMemoryEnc",
-+ "Failed to identify encoding handler for",
-+ "character set",
-+ txt_encoding);
-+ return;
-+ }
-+ }
-+ }
-+
-+ if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDumpFormatMemoryEnc: Failed to allocate output buffer.\n");
-+ return;
-+ }
-+
-+ xmlDocContentDumpOutput(out_buff, out_doc, txt_encoding, 1);
-+ xmlOutputBufferFlush(out_buff);
-+ if (out_buff->conv != NULL) {
-+ *doc_txt_len = out_buff->conv->use;
-+ *doc_txt_ptr = xmlStrndup(out_buff->conv->content, *doc_txt_len);
-+ } else {
-+ *doc_txt_len = out_buff->buffer->use;
-+ *doc_txt_ptr = xmlStrndup(out_buff->buffer->content, *doc_txt_len);
-+ }
-+ (void)xmlOutputBufferClose(out_buff);
-+
-+ if ((*doc_txt_ptr == NULL) && (*doc_txt_len > 0)) {
-+ *doc_txt_len = 0;
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDumpFormatMemoryEnc: %s\n",
-+ "Failed to allocate memory for document text representation.");
-+ }
-+
-+ return;
-+}
-+
-+/**
-+ * xmlDocDumpMemory:
-+ * @cur: the document
-+ * @mem: OUT: the memory pointer
-+ * @size: OUT: the memory lenght
-+ *
-+ * Dump an XML document in memory and return the xmlChar * and it's size.
-+ * It's up to the caller to free the memory.
-+ */
-+void
-+xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
-+ xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
-+}
-+
-+/**
-+ * xmlDocDumpFormatMemory:
-+ * @cur: the document
-+ * @mem: OUT: the memory pointer
-+ * @size: OUT: the memory lenght
-+ * @format: should formatting spaces been added
-+ *
-+ *
-+ * Dump an XML document in memory and return the xmlChar * and it's size.
-+ * It's up to the caller to free the memory.
-+ */
-+void
-+xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
-+ xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
-+}
-+
-+/**
-+ * xmlDocDumpMemoryEnc:
-+ * @out_doc: Document to generate XML text from
-+ * @doc_txt_ptr: Memory pointer for allocated XML text
-+ * @doc_txt_len: Length of the generated XML text
-+ * @txt_encoding: Character encoding to use when generating XML text
-+ *
-+ * Dump the current DOM tree into memory using the character encoding specified
-+ * by the caller. Note it is up to the caller of this function to free the
-+ * allocated memory.
-+ */
-+
-+void
-+xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
-+ int * doc_txt_len, const char * txt_encoding) {
-+ xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
-+ txt_encoding, 1);
-+}
-+
-+/**
-+ * xmlGetDocCompressMode:
-+ * @doc: the document
-+ *
-+ * get the compression ratio for a document, ZLIB based
-+ * Returns 0 (uncompressed) to 9 (max compression)
-+ */
-+int
-+xmlGetDocCompressMode (xmlDocPtr doc) {
-+ if (doc == NULL) return(-1);
-+ return(doc->compression);
-+}
-+
-+/**
-+ * xmlSetDocCompressMode:
-+ * @doc: the document
-+ * @mode: the compression ratio
-+ *
-+ * set the compression ratio for a document, ZLIB based
-+ * Correct values: 0 (uncompressed) to 9 (max compression)
-+ */
-+void
-+xmlSetDocCompressMode (xmlDocPtr doc, int mode) {
-+ if (doc == NULL) return;
-+ if (mode < 0) doc->compression = 0;
-+ else if (mode > 9) doc->compression = 9;
-+ else doc->compression = mode;
-+}
-+
-+/**
-+ * xmlGetCompressMode:
-+ *
-+ * get the default compression mode used, ZLIB based.
-+ * Returns 0 (uncompressed) to 9 (max compression)
-+ */
-+int
-+ xmlGetCompressMode(void) {
-+ return(xmlCompressMode);
-+}
-+
-+/**
-+ * xmlSetCompressMode:
-+ * @mode: the compression ratio
-+ *
-+ * set the default compression mode used, ZLIB based
-+ * Correct values: 0 (uncompressed) to 9 (max compression)
-+ */
-+void
-+xmlSetCompressMode(int mode) {
-+ if (mode < 0) xmlCompressMode = 0;
-+ else if (mode > 9) xmlCompressMode = 9;
-+ else xmlCompressMode = mode;
-+}
-+
-+/**
-+ * xmlDocDump:
-+ * @f: the FILE*
-+ * @cur: the document
-+ *
-+ * Dump an XML document to an open FILE.
-+ *
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+xmlDocDump(FILE *f, xmlDocPtr cur) {
-+ xmlOutputBufferPtr buf;
-+ const char * encoding;
-+ xmlCharEncodingHandlerPtr handler = NULL;
-+ int ret;
-+
-+ if (cur == NULL) {
-+#ifdef DEBUG_TREE
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDump : document == NULL\n");
-+#endif
-+ return(-1);
-+ }
-+ encoding = (const char *) cur->encoding;
-+
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+
-+ enc = xmlParseCharEncoding(encoding);
-+
-+ if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDocDump: document not in UTF8\n");
-+ return(-1);
-+ }
-+ if (enc != XML_CHAR_ENCODING_UTF8) {
-+ handler = xmlFindCharEncodingHandler(encoding);
-+ if (handler == NULL) {
-+ xmlFree((char *) cur->encoding);
-+ cur->encoding = NULL;
-+ }
-+ }
-+ }
-+ buf = xmlOutputBufferCreateFile(f, handler);
-+ if (buf == NULL) return(-1);
-+ xmlDocContentDumpOutput(buf, cur, NULL, 1);
-+
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSaveFileTo:
-+ * @buf: an output I/O buffer
-+ * @cur: the document
-+ * @encoding: the encoding if any assuming the i/O layer handles the trancoding
-+ *
-+ * Dump an XML document to an I/O buffer.
-+ *
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+xmlSaveFileTo(xmlOutputBuffer *buf, xmlDocPtr cur, const char *encoding) {
-+ int ret;
-+
-+ if (buf == NULL) return(0);
-+ xmlDocContentDumpOutput(buf, cur, encoding, 1);
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSaveFileEnc:
-+ * @filename: the filename (or URL)
-+ * @cur: the document
-+ * @encoding: the name of an encoding (or NULL)
-+ *
-+ * Dump an XML document, converting it to the given encoding
-+ *
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
-+ xmlOutputBufferPtr buf;
-+ xmlCharEncodingHandlerPtr handler = NULL;
-+ int ret;
-+
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+
-+ enc = xmlParseCharEncoding(encoding);
-+ if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveFileEnc: document not in UTF8\n");
-+ return(-1);
-+ }
-+ if (enc != XML_CHAR_ENCODING_UTF8) {
-+ handler = xmlFindCharEncodingHandler(encoding);
-+ if (handler == NULL) {
-+ return(-1);
-+ }
-+ }
-+ }
-+
-+ /*
-+ * save the content to a temp buffer.
-+ */
-+ buf = xmlOutputBufferCreateFilename(filename, handler, 0);
-+ if (buf == NULL) return(-1);
-+
-+ xmlDocContentDumpOutput(buf, cur, encoding, 1);
-+
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSaveFile:
-+ * @filename: the filename (or URL)
-+ * @cur: the document
-+ *
-+ * Dump an XML document to a file. Will use compression if
-+ * compiled in and enabled. If @filename is "-" the stdout file is
-+ * used.
-+ * returns: the number of byte written or -1 in case of failure.
-+ */
-+int
-+xmlSaveFile(const char *filename, xmlDocPtr cur) {
-+ xmlOutputBufferPtr buf;
-+ const char *encoding;
-+ xmlCharEncodingHandlerPtr handler = NULL;
-+ int ret;
-+
-+ if (cur == NULL)
-+ return(-1);
-+ encoding = (const char *) cur->encoding;
-+
-+ /*
-+ * save the content to a temp buffer.
-+ */
-+#ifdef HAVE_ZLIB_H
-+ if (cur->compression < 0) cur->compression = xmlCompressMode;
-+#endif
-+ if (encoding != NULL) {
-+ xmlCharEncoding enc;
-+
-+ enc = xmlParseCharEncoding(encoding);
-+
-+ if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveFile: document not in UTF8\n");
-+ return(-1);
-+ }
-+ if (enc != XML_CHAR_ENCODING_UTF8) {
-+ handler = xmlFindCharEncodingHandler(encoding);
-+ if (handler == NULL) {
-+ xmlFree((char *) cur->encoding);
-+ cur->encoding = NULL;
-+ }
-+ }
-+ }
-+
-+ buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
-+ if (buf == NULL) return(-1);
-+
-+ xmlDocContentDumpOutput(buf, cur, NULL, 1);
-+
-+ ret = xmlOutputBufferClose(buf);
-+ return(ret);
-+}
-+
-diff -Nru libxml2-2.3.0/libxml/tree.h libxml2-2.3.0.new/libxml/tree.h
---- libxml2-2.3.0/libxml/tree.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/tree.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,698 @@
-+/*
-+ * tree.h : describes the structures found in an tree resulting
-+ * from an XML parsing.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ *
-+ * 14 Nov 2000 ht - added redefinition of xmlBufferWriteChar for VMS
-+ *
-+ */
-+
-+#ifndef __XML_TREE_H__
-+#define __XML_TREE_H__
-+
-+#include <stdio.h>
-+#include <libxml/xmlversion.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * The different element types carried by an XML tree
-+ *
-+ * NOTE: This is synchronized with DOM Level1 values
-+ * See http://www.w3.org/TR/REC-DOM-Level-1/
-+ *
-+ * Actually this had diverged a bit, and now XML_DOCUMENT_TYPE_NODE should
-+ * be deprecated to use an XML_DTD_NODE.
-+ */
-+typedef enum {
-+ XML_ELEMENT_NODE= 1,
-+ XML_ATTRIBUTE_NODE= 2,
-+ XML_TEXT_NODE= 3,
-+ XML_CDATA_SECTION_NODE= 4,
-+ XML_ENTITY_REF_NODE= 5,
-+ XML_ENTITY_NODE= 6,
-+ XML_PI_NODE= 7,
-+ XML_COMMENT_NODE= 8,
-+ XML_DOCUMENT_NODE= 9,
-+ XML_DOCUMENT_TYPE_NODE= 10,
-+ XML_DOCUMENT_FRAG_NODE= 11,
-+ XML_NOTATION_NODE= 12,
-+ XML_HTML_DOCUMENT_NODE= 13,
-+ XML_DTD_NODE= 14,
-+ XML_ELEMENT_DECL= 15,
-+ XML_ATTRIBUTE_DECL= 16,
-+ XML_ENTITY_DECL= 17,
-+ XML_NAMESPACE_DECL= 18,
-+ XML_XINCLUDE_START= 19,
-+ XML_XINCLUDE_END= 20
-+#ifdef LIBXML_SGML_ENABLED
-+ ,XML_SGML_DOCUMENT_NODE= 21
-+#endif
-+} xmlElementType;
-+
-+/*
-+ * Size of an internal character representation.
-+ *
-+ * We use 8bit chars internal representation for memory efficiency,
-+ * Note that with 8 bits wide xmlChars one can still use UTF-8 to handle
-+ * correctly non ISO-Latin input.
-+ */
-+
-+typedef unsigned char xmlChar;
-+
-+#ifndef WIN32
-+#ifndef CHAR
-+#define CHAR xmlChar
-+#endif
-+#endif
-+
-+#define BAD_CAST (xmlChar *)
-+
-+/*
-+ * a DTD Notation definition
-+ */
-+
-+typedef struct _xmlNotation xmlNotation;
-+typedef xmlNotation *xmlNotationPtr;
-+struct _xmlNotation {
-+ const xmlChar *name; /* Notation name */
-+ const xmlChar *PublicID; /* Public identifier, if any */
-+ const xmlChar *SystemID; /* System identifier, if any */
-+};
-+
-+/*
-+ * a DTD Attribute definition
-+ */
-+
-+typedef enum {
-+ XML_ATTRIBUTE_CDATA = 1,
-+ XML_ATTRIBUTE_ID,
-+ XML_ATTRIBUTE_IDREF ,
-+ XML_ATTRIBUTE_IDREFS,
-+ XML_ATTRIBUTE_ENTITY,
-+ XML_ATTRIBUTE_ENTITIES,
-+ XML_ATTRIBUTE_NMTOKEN,
-+ XML_ATTRIBUTE_NMTOKENS,
-+ XML_ATTRIBUTE_ENUMERATION,
-+ XML_ATTRIBUTE_NOTATION
-+} xmlAttributeType;
-+
-+typedef enum {
-+ XML_ATTRIBUTE_NONE = 1,
-+ XML_ATTRIBUTE_REQUIRED,
-+ XML_ATTRIBUTE_IMPLIED,
-+ XML_ATTRIBUTE_FIXED
-+} xmlAttributeDefault;
-+
-+typedef struct _xmlEnumeration xmlEnumeration;
-+typedef xmlEnumeration *xmlEnumerationPtr;
-+struct _xmlEnumeration {
-+ struct _xmlEnumeration *next; /* next one */
-+ const xmlChar *name; /* Enumeration name */
-+};
-+
-+typedef struct _xmlAttribute xmlAttribute;
-+typedef xmlAttribute *xmlAttributePtr;
-+struct _xmlAttribute {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* XML_ATTRIBUTE_DECL, must be second ! */
-+ const xmlChar *name; /* Attribute name */
-+ struct _xmlNode *children; /* NULL */
-+ struct _xmlNode *last; /* NULL */
-+ struct _xmlDtd *parent; /* -> DTD */
-+ struct _xmlNode *next; /* next sibling link */
-+ struct _xmlNode *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* the containing document */
-+
-+ struct _xmlAttribute *nexth; /* next in hash table */
-+ xmlAttributeType atype; /* The attribute type */
-+ xmlAttributeDefault def; /* the default */
-+ const xmlChar *defaultValue; /* or the default value */
-+ xmlEnumerationPtr tree; /* or the enumeration tree if any */
-+ const xmlChar *prefix; /* the namespace prefix if any */
-+ const xmlChar *elem; /* Element holding the attribute */
-+};
-+
-+/*
-+ * a DTD Element definition.
-+ */
-+typedef enum {
-+ XML_ELEMENT_CONTENT_PCDATA = 1,
-+ XML_ELEMENT_CONTENT_ELEMENT,
-+ XML_ELEMENT_CONTENT_SEQ,
-+ XML_ELEMENT_CONTENT_OR
-+} xmlElementContentType;
-+
-+typedef enum {
-+ XML_ELEMENT_CONTENT_ONCE = 1,
-+ XML_ELEMENT_CONTENT_OPT,
-+ XML_ELEMENT_CONTENT_MULT,
-+ XML_ELEMENT_CONTENT_PLUS
-+} xmlElementContentOccur;
-+
-+typedef struct _xmlElementContent xmlElementContent;
-+typedef xmlElementContent *xmlElementContentPtr;
-+struct _xmlElementContent {
-+ xmlElementContentType type; /* PCDATA, ELEMENT, SEQ or OR */
-+ xmlElementContentOccur ocur; /* ONCE, OPT, MULT or PLUS */
-+ const xmlChar *name; /* Element name */
-+ struct _xmlElementContent *c1; /* first child */
-+ struct _xmlElementContent *c2; /* second child */
-+};
-+
-+typedef enum {
-+ XML_ELEMENT_TYPE_EMPTY = 1,
-+ XML_ELEMENT_TYPE_ANY,
-+ XML_ELEMENT_TYPE_MIXED,
-+ XML_ELEMENT_TYPE_ELEMENT
-+} xmlElementTypeVal;
-+
-+typedef struct _xmlElement xmlElement;
-+typedef xmlElement *xmlElementPtr;
-+struct _xmlElement {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* XML_ELEMENT_DECL, must be second ! */
-+ const xmlChar *name; /* Element name */
-+ struct _xmlNode *children; /* NULL */
-+ struct _xmlNode *last; /* NULL */
-+ struct _xmlDtd *parent; /* -> DTD */
-+ struct _xmlNode *next; /* next sibling link */
-+ struct _xmlNode *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* the containing document */
-+
-+ xmlElementTypeVal etype; /* The type */
-+ xmlElementContentPtr content; /* the allowed element content */
-+ xmlAttributePtr attributes; /* List of the declared attributes */
-+ const xmlChar *prefix; /* the namespace prefix if any */
-+};
-+
-+/*
-+ * An XML namespace.
-+ * Note that prefix == NULL is valid, it defines the default namespace
-+ * within the subtree (until overriden).
-+ *
-+ * XML_GLOBAL_NAMESPACE is now deprecated for good
-+ * xmlNsType is unified with xmlElementType
-+ */
-+
-+#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
-+typedef xmlElementType xmlNsType;
-+
-+typedef struct _xmlNs xmlNs;
-+typedef xmlNs *xmlNsPtr;
-+struct _xmlNs {
-+ struct _xmlNs *next; /* next Ns link for this node */
-+ xmlNsType type; /* global or local */
-+ const xmlChar *href; /* URL for the namespace */
-+ const xmlChar *prefix; /* prefix for the namespace */
-+};
-+
-+/*
-+ * An XML DtD, as defined by <!DOCTYPE.
-+ */
-+typedef struct _xmlDtd xmlDtd;
-+typedef xmlDtd *xmlDtdPtr;
-+struct _xmlDtd {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* XML_DTD_NODE, must be second ! */
-+ const xmlChar *name; /* Name of the DTD */
-+ struct _xmlNode *children; /* the value of the property link */
-+ struct _xmlNode *last; /* last child link */
-+ struct _xmlDoc *parent; /* child->parent link */
-+ struct _xmlNode *next; /* next sibling link */
-+ struct _xmlNode *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* the containing document */
-+
-+ /* End of common part */
-+ void *notations; /* Hash table for notations if any */
-+ void *elements; /* Hash table for elements if any */
-+ void *attributes; /* Hash table for attributes if any */
-+ void *entities; /* Hash table for entities if any */
-+ const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */
-+ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */
-+ void *pentities; /* Hash table for param entities if any */
-+};
-+
-+/*
-+ * A attribute of an XML node.
-+ */
-+typedef struct _xmlAttr xmlAttr;
-+typedef xmlAttr *xmlAttrPtr;
-+struct _xmlAttr {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */
-+ const xmlChar *name; /* the name of the property */
-+ struct _xmlNode *children; /* the value of the property */
-+ struct _xmlNode *last; /* NULL */
-+ struct _xmlNode *parent; /* child->parent link */
-+ struct _xmlAttr *next; /* next sibling link */
-+ struct _xmlAttr *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* the containing document */
-+ xmlNs *ns; /* pointer to the associated namespace */
-+ xmlAttributeType atype; /* the attribute type if validating */
-+};
-+
-+/*
-+ * An XML ID instance.
-+ */
-+
-+typedef struct _xmlID xmlID;
-+typedef xmlID *xmlIDPtr;
-+struct _xmlID {
-+ struct _xmlID *next; /* next ID */
-+ const xmlChar *value; /* The ID name */
-+ xmlAttrPtr attr; /* The attribut holding it */
-+};
-+
-+/*
-+ * An XML IDREF instance.
-+ */
-+
-+typedef struct _xmlRef xmlRef;
-+typedef xmlRef *xmlRefPtr;
-+struct _xmlRef {
-+ struct _xmlRef *next; /* next Ref */
-+ const xmlChar *value; /* The Ref name */
-+ xmlAttrPtr attr; /* The attribut holding it */
-+};
-+
-+/*
-+ * A buffer structure
-+ */
-+
-+typedef enum {
-+ XML_BUFFER_ALLOC_DOUBLEIT,
-+ XML_BUFFER_ALLOC_EXACT
-+} xmlBufferAllocationScheme;
-+
-+typedef struct _xmlBuffer xmlBuffer;
-+typedef xmlBuffer *xmlBufferPtr;
-+struct _xmlBuffer {
-+ xmlChar *content; /* The buffer content UTF8 */
-+ unsigned int use; /* The buffer size used */
-+ unsigned int size; /* The buffer size */
-+ xmlBufferAllocationScheme alloc; /* The realloc method */
-+};
-+
-+/*
-+ * A node in an XML tree.
-+ */
-+typedef struct _xmlNode xmlNode;
-+typedef xmlNode *xmlNodePtr;
-+struct _xmlNode {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* type number, must be second ! */
-+ const xmlChar *name; /* the name of the node, or the entity */
-+ struct _xmlNode *children; /* parent->childs link */
-+ struct _xmlNode *last; /* last child link */
-+ struct _xmlNode *parent; /* child->parent link */
-+ struct _xmlNode *next; /* next sibling link */
-+ struct _xmlNode *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* the containing document */
-+ xmlNs *ns; /* pointer to the associated namespace */
-+#ifndef XML_USE_BUFFER_CONTENT
-+ xmlChar *content; /* the content */
-+#else
-+ xmlBufferPtr content; /* the content in a buffer */
-+#endif
-+
-+ /* End of common part */
-+ struct _xmlAttr *properties;/* properties list */
-+ xmlNs *nsDef; /* namespace definitions on this node */
-+};
-+
-+/*
-+ * An XML document.
-+ */
-+typedef struct _xmlDoc xmlDoc;
-+typedef xmlDoc *xmlDocPtr;
-+struct _xmlDoc {
-+#ifndef XML_WITHOUT_CORBA
-+ void *_private; /* for Corba, must be first ! */
-+#endif
-+ xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */
-+ char *name; /* name/filename/URI of the document */
-+ struct _xmlNode *children; /* the document tree */
-+ struct _xmlNode *last; /* last child link */
-+ struct _xmlNode *parent; /* child->parent link */
-+ struct _xmlNode *next; /* next sibling link */
-+ struct _xmlNode *prev; /* previous sibling link */
-+ struct _xmlDoc *doc; /* autoreference to itself */
-+
-+ /* End of common part */
-+ int compression;/* level of zlib compression */
-+ int standalone; /* standalone document (no external refs) */
-+ struct _xmlDtd *intSubset; /* the document internal subset */
-+ struct _xmlDtd *extSubset; /* the document external subset */
-+ struct _xmlNs *oldNs; /* Global namespace, the old way */
-+ const xmlChar *version; /* the XML version string */
-+ const xmlChar *encoding; /* external initial encoding, if any */
-+ void *ids; /* Hash table for ID attributes if any */
-+ void *refs; /* Hash table for IDREFs attributes if any */
-+ const xmlChar *URL; /* The URI for that document */
-+ int charset; /* encoding of the in-memory content
-+ actually an xmlCharEncoding */
-+};
-+
-+/*
-+ * Compatibility naming layer with libxml1
-+ */
-+#ifndef xmlChildrenNode
-+#define xmlChildrenNode children
-+#define xmlRootNode children
-+#endif
-+
-+/*
-+ * Variables.
-+ */
-+LIBXML_DLL_IMPORT extern xmlNsPtr baseDTD;
-+LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
-+LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
-+LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
-+LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as <empty></empty> */
-+
-+/*
-+ * Handling Buffers.
-+ */
-+
-+xmlBufferPtr xmlBufferCreate (void);
-+xmlBufferPtr xmlBufferCreateSize (size_t size);
-+void xmlBufferFree (xmlBufferPtr buf);
-+int xmlBufferDump (FILE *file,
-+ xmlBufferPtr buf);
-+void xmlBufferAdd (xmlBufferPtr buf,
-+ const xmlChar *str,
-+ int len);
-+void xmlBufferAddHead (xmlBufferPtr buf,
-+ const xmlChar *str,
-+ int len);
-+void xmlBufferCat (xmlBufferPtr buf,
-+ const xmlChar *str);
-+void xmlBufferCCat (xmlBufferPtr buf,
-+ const char *str);
-+int xmlBufferShrink (xmlBufferPtr buf,
-+ unsigned int len);
-+int xmlBufferGrow (xmlBufferPtr buf,
-+ unsigned int len);
-+void xmlBufferEmpty (xmlBufferPtr buf);
-+const xmlChar* xmlBufferContent (const xmlBufferPtr buf);
-+int xmlBufferUse (const xmlBufferPtr buf);
-+void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
-+ xmlBufferAllocationScheme scheme);
-+int xmlBufferLength (const xmlBufferPtr buf);
-+
-+/*
-+ * Creating/freeing new structures
-+ */
-+xmlDtdPtr xmlCreateIntSubset (xmlDocPtr doc,
-+ const xmlChar *name,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+xmlDtdPtr xmlNewDtd (xmlDocPtr doc,
-+ const xmlChar *name,
-+ const xmlChar *ExternalID,
-+ const xmlChar *SystemID);
-+xmlDtdPtr xmlGetIntSubset (xmlDocPtr doc);
-+void xmlFreeDtd (xmlDtdPtr cur);
-+xmlNsPtr xmlNewGlobalNs (xmlDocPtr doc,
-+ const xmlChar *href,
-+ const xmlChar *prefix);
-+xmlNsPtr xmlNewNs (xmlNodePtr node,
-+ const xmlChar *href,
-+ const xmlChar *prefix);
-+void xmlFreeNs (xmlNsPtr cur);
-+xmlDocPtr xmlNewDoc (const xmlChar *version);
-+void xmlFreeDoc (xmlDocPtr cur);
-+xmlAttrPtr xmlNewDocProp (xmlDocPtr doc,
-+ const xmlChar *name,
-+ const xmlChar *value);
-+xmlAttrPtr xmlNewProp (xmlNodePtr node,
-+ const xmlChar *name,
-+ const xmlChar *value);
-+xmlAttrPtr xmlNewNsProp (xmlNodePtr node,
-+ xmlNsPtr ns,
-+ const xmlChar *name,
-+ const xmlChar *value);
-+void xmlFreePropList (xmlAttrPtr cur);
-+void xmlFreeProp (xmlAttrPtr cur);
-+xmlAttrPtr xmlCopyProp (xmlNodePtr target,
-+ xmlAttrPtr cur);
-+xmlAttrPtr xmlCopyPropList (xmlNodePtr target,
-+ xmlAttrPtr cur);
-+xmlDtdPtr xmlCopyDtd (xmlDtdPtr dtd);
-+xmlDocPtr xmlCopyDoc (xmlDocPtr doc,
-+ int recursive);
-+
-+/*
-+ * Creating new nodes
-+ */
-+xmlNodePtr xmlNewDocNode (xmlDocPtr doc,
-+ xmlNsPtr ns,
-+ const xmlChar *name,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewDocRawNode (xmlDocPtr doc,
-+ xmlNsPtr ns,
-+ const xmlChar *name,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewNode (xmlNsPtr ns,
-+ const xmlChar *name);
-+xmlNodePtr xmlNewChild (xmlNodePtr parent,
-+ xmlNsPtr ns,
-+ const xmlChar *name,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewTextChild (xmlNodePtr parent,
-+ xmlNsPtr ns,
-+ const xmlChar *name,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewDocText (xmlDocPtr doc,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewText (const xmlChar *content);
-+xmlNodePtr xmlNewPI (const xmlChar *name,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewDocTextLen (xmlDocPtr doc,
-+ const xmlChar *content,
-+ int len);
-+xmlNodePtr xmlNewTextLen (const xmlChar *content,
-+ int len);
-+xmlNodePtr xmlNewDocComment (xmlDocPtr doc,
-+ const xmlChar *content);
-+xmlNodePtr xmlNewComment (const xmlChar *content);
-+xmlNodePtr xmlNewCDataBlock (xmlDocPtr doc,
-+ const xmlChar *content,
-+ int len);
-+xmlNodePtr xmlNewCharRef (xmlDocPtr doc,
-+ const xmlChar *name);
-+xmlNodePtr xmlNewReference (xmlDocPtr doc,
-+ const xmlChar *name);
-+xmlNodePtr xmlCopyNode (xmlNodePtr node,
-+ int recursive);
-+xmlNodePtr xmlCopyNodeList (xmlNodePtr node);
-+xmlNodePtr xmlNewDocFragment (xmlDocPtr doc);
-+
-+/*
-+ * Navigating
-+ */
-+xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc);
-+xmlNodePtr xmlGetLastChild (xmlNodePtr parent);
-+int xmlNodeIsText (xmlNodePtr node);
-+int xmlIsBlankNode (xmlNodePtr node);
-+
-+/*
-+ * Changing the structure
-+ */
-+xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc,
-+ xmlNodePtr root);
-+void xmlNodeSetName (xmlNodePtr cur,
-+ const xmlChar *name);
-+xmlNodePtr xmlAddChild (xmlNodePtr parent,
-+ xmlNodePtr cur);
-+xmlNodePtr xmlAddChildList (xmlNodePtr parent,
-+ xmlNodePtr cur);
-+xmlNodePtr xmlReplaceNode (xmlNodePtr old,
-+ xmlNodePtr cur);
-+xmlNodePtr xmlAddSibling (xmlNodePtr cur,
-+ xmlNodePtr elem);
-+xmlNodePtr xmlAddPrevSibling (xmlNodePtr cur,
-+ xmlNodePtr elem);
-+xmlNodePtr xmlAddNextSibling (xmlNodePtr cur,
-+ xmlNodePtr elem);
-+void xmlUnlinkNode (xmlNodePtr cur);
-+xmlNodePtr xmlTextMerge (xmlNodePtr first,
-+ xmlNodePtr second);
-+void xmlTextConcat (xmlNodePtr node,
-+ const xmlChar *content,
-+ int len);
-+void xmlFreeNodeList (xmlNodePtr cur);
-+void xmlFreeNode (xmlNodePtr cur);
-+void xmlSetTreeDoc (xmlNodePtr tree,
-+ xmlDocPtr doc);
-+void xmlSetListDoc (xmlNodePtr list,
-+ xmlDocPtr doc);
-+
-+/*
-+ * Namespaces
-+ */
-+xmlNsPtr xmlSearchNs (xmlDocPtr doc,
-+ xmlNodePtr node,
-+ const xmlChar *nameSpace);
-+xmlNsPtr xmlSearchNsByHref (xmlDocPtr doc,
-+ xmlNodePtr node,
-+ const xmlChar *href);
-+xmlNsPtr * xmlGetNsList (xmlDocPtr doc,
-+ xmlNodePtr node);
-+void xmlSetNs (xmlNodePtr node,
-+ xmlNsPtr ns);
-+xmlNsPtr xmlCopyNamespace (xmlNsPtr cur);
-+xmlNsPtr xmlCopyNamespaceList (xmlNsPtr cur);
-+
-+/*
-+ * Changing the content.
-+ */
-+xmlAttrPtr xmlSetProp (xmlNodePtr node,
-+ const xmlChar *name,
-+ const xmlChar *value);
-+xmlChar * xmlGetProp (xmlNodePtr node,
-+ const xmlChar *name);
-+xmlAttrPtr xmlHasProp (xmlNodePtr node,
-+ const xmlChar *name);
-+xmlAttrPtr xmlSetNsProp (xmlNodePtr node,
-+ xmlNsPtr ns,
-+ const xmlChar *name,
-+ const xmlChar *value);
-+xmlChar * xmlGetNsProp (xmlNodePtr node,
-+ const xmlChar *name,
-+ const xmlChar *nameSpace);
-+xmlNodePtr xmlStringGetNodeList (xmlDocPtr doc,
-+ const xmlChar *value);
-+xmlNodePtr xmlStringLenGetNodeList (xmlDocPtr doc,
-+ const xmlChar *value,
-+ int len);
-+xmlChar * xmlNodeListGetString (xmlDocPtr doc,
-+ xmlNodePtr list,
-+ int inLine);
-+xmlChar * xmlNodeListGetRawString (xmlDocPtr doc,
-+ xmlNodePtr list,
-+ int inLine);
-+void xmlNodeSetContent (xmlNodePtr cur,
-+ const xmlChar *content);
-+void xmlNodeSetContentLen (xmlNodePtr cur,
-+ const xmlChar *content,
-+ int len);
-+void xmlNodeAddContent (xmlNodePtr cur,
-+ const xmlChar *content);
-+void xmlNodeAddContentLen (xmlNodePtr cur,
-+ const xmlChar *content,
-+ int len);
-+xmlChar * xmlNodeGetContent (xmlNodePtr cur);
-+xmlChar * xmlNodeGetLang (xmlNodePtr cur);
-+void xmlNodeSetLang (xmlNodePtr cur,
-+ const xmlChar *lang);
-+int xmlNodeGetSpacePreserve (xmlNodePtr cur);
-+void xmlNodeSetSpacePreserve (xmlNodePtr cur, int
-+ val);
-+xmlChar * xmlNodeGetBase (xmlDocPtr doc,
-+ xmlNodePtr cur);
-+void xmlNodeSetBase (xmlNodePtr cur,
-+ xmlChar *uri);
-+
-+/*
-+ * Removing content.
-+ */
-+int xmlRemoveProp (xmlAttrPtr attr);
-+int xmlRemoveNode (xmlNodePtr node); /* TODO */
-+
-+/*
-+ * Internal, don't use
-+ */
-+#ifdef VMS
-+void xmlBufferWriteXmlCHAR (xmlBufferPtr buf,
-+ const xmlChar *string);
-+#define xmlBufferWriteCHAR xmlBufferWriteXmlCHAR
-+#else
-+void xmlBufferWriteCHAR (xmlBufferPtr buf,
-+ const xmlChar *string);
-+#endif
-+void xmlBufferWriteChar (xmlBufferPtr buf,
-+ const char *string);
-+void xmlBufferWriteQuotedString(xmlBufferPtr buf,
-+ const xmlChar *string);
-+
-+/*
-+ * Namespace handling
-+ */
-+int xmlReconciliateNs (xmlDocPtr doc,
-+ xmlNodePtr tree);
-+
-+/*
-+ * Saving
-+ */
-+void xmlDocDumpFormatMemory (xmlDocPtr cur,
-+ xmlChar**mem,
-+ int *size,
-+ int format);
-+void xmlDocDumpMemory (xmlDocPtr cur,
-+ xmlChar**mem,
-+ int *size);
-+void xmlDocDumpMemoryEnc (xmlDocPtr out_doc,
-+ xmlChar **doc_txt_ptr,
-+ int * doc_txt_len,
-+ const char *txt_encoding);
-+void xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
-+ xmlChar **doc_txt_ptr,
-+ int * doc_txt_len,
-+ const char *txt_encoding,
-+ int format);
-+int xmlDocDump (FILE *f,
-+ xmlDocPtr cur);
-+void xmlElemDump (FILE *f,
-+ xmlDocPtr doc,
-+ xmlNodePtr cur);
-+int xmlSaveFile (const char *filename,
-+ xmlDocPtr cur);
-+void xmlNodeDump (xmlBufferPtr buf,
-+ xmlDocPtr doc,
-+ xmlNodePtr cur,
-+ int level,
-+ int format);
-+
-+/* This one is exported from xmlIO.h
-+
-+int xmlSaveFileTo (xmlOutputBuffer *buf,
-+ xmlDocPtr cur,
-+ const char *encoding);
-+ */
-+
-+int xmlSaveFileEnc (const char *filename,
-+ xmlDocPtr cur,
-+ const char *encoding);
-+
-+/*
-+ * Compression
-+ */
-+int xmlGetDocCompressMode (xmlDocPtr doc);
-+void xmlSetDocCompressMode (xmlDocPtr doc,
-+ int mode);
-+int xmlGetCompressMode (void);
-+void xmlSetCompressMode (int mode);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __XML_TREE_H__ */
-+
-diff -Nru libxml2-2.3.0/libxml/uri.c libxml2-2.3.0.new/libxml/uri.c
---- libxml2-2.3.0/libxml/uri.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/uri.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,1943 @@
-+/**
-+ * uri.c: set of generic URI related routines
-+ *
-+ * Reference: RFC 2396
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#define INCLUDE_WINSOCK
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/uri.h>
-+#include <libxml/xmlerror.h>
-+
-+/************************************************************************
-+ * *
-+ * Macros to differenciate various character type *
-+ * directly extracted from RFC 2396 *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * alpha = lowalpha | upalpha
-+ */
-+#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x))
-+
-+
-+/*
-+ * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" |
-+ * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" |
-+ * "u" | "v" | "w" | "x" | "y" | "z"
-+ */
-+
-+#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))
-+
-+/*
-+ * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" |
-+ * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" |
-+ * "U" | "V" | "W" | "X" | "Y" | "Z"
-+ */
-+#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z'))
-+
-+/*
-+ * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-+ */
-+
-+#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))
-+
-+/*
-+ * alphanum = alpha | digit
-+ */
-+
-+#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
-+
-+/*
-+ * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
-+ * "a" | "b" | "c" | "d" | "e" | "f"
-+ */
-+
-+#define IS_HEX(x) ((IS_DIGIT(x)) || (((x) >= 'a') && ((x) <= 'f')) || \
-+ (((x) >= 'A') && ((x) <= 'F')))
-+
-+/*
-+ * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
-+ */
-+
-+#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \
-+ ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \
-+ ((x) == '(') || ((x) == ')'))
-+
-+
-+/*
-+ * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
-+ */
-+
-+#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
-+ ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
-+ ((x) == '+') || ((x) == '$') || ((x) == ','))
-+
-+/*
-+ * unreserved = alphanum | mark
-+ */
-+
-+#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
-+
-+/*
-+ * escaped = "%" hex hex
-+ */
-+
-+#define IS_ESCAPED(p) ((*(p) == '%') && (IS_HEX((p)[1])) && \
-+ (IS_HEX((p)[2])))
-+
-+/*
-+ * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
-+ * "&" | "=" | "+" | "$" | ","
-+ */
-+#define IS_URIC_NO_SLASH(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||\
-+ ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||\
-+ ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||\
-+ ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
-+
-+/*
-+ * pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
-+ */
-+#define IS_PCHAR(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-+ ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||\
-+ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||\
-+ ((*(p) == ',')))
-+
-+/*
-+ * rel_segment = 1*( unreserved | escaped |
-+ * ";" | "@" | "&" | "=" | "+" | "$" | "," )
-+ */
-+
-+#define IS_SEGMENT(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-+ ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || \
-+ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
-+ ((*(p) == ',')))
-+
-+/*
-+ * scheme = alpha *( alpha | digit | "+" | "-" | "." )
-+ */
-+
-+#define IS_SCHEME(x) ((IS_ALPHA(x)) || (IS_DIGIT(x)) || \
-+ ((x) == '+') || ((x) == '-') || ((x) == '.'))
-+
-+/*
-+ * reg_name = 1*( unreserved | escaped | "$" | "," |
-+ * ";" | ":" | "@" | "&" | "=" | "+" )
-+ */
-+
-+#define IS_REG_NAME(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-+ ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || \
-+ ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || \
-+ ((*(p) == '=')) || ((*(p) == '+')))
-+
-+/*
-+ * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" |
-+ * "+" | "$" | "," )
-+ */
-+#define IS_USERINFO(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-+ ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) || \
-+ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
-+ ((*(p) == ',')))
-+
-+/*
-+ * uric = reserved | unreserved | escaped
-+ */
-+
-+#define IS_URIC(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-+ (IS_RESERVED(*(p))))
-+
-+/*
-+ * Skip to next pointer char, handle escaped sequences
-+ */
-+
-+#define NEXT(p) ((*p == '%')? p += 3 : p++)
-+
-+/*
-+ * Productions from the spec.
-+ *
-+ * authority = server | reg_name
-+ * reg_name = 1*( unreserved | escaped | "$" | "," |
-+ * ";" | ":" | "@" | "&" | "=" | "+" )
-+ *
-+ * path = [ abs_path | opaque_part ]
-+ */
-+
-+/************************************************************************
-+ * *
-+ * Generic URI structure functions *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlCreateURI:
-+ *
-+ * Simply creates an empty xmlURI
-+ *
-+ * Returns the new structure or NULL in case of error
-+ */
-+xmlURIPtr
-+xmlCreateURI(void) {
-+ xmlURIPtr ret;
-+
-+ ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCreateURI: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlURI));
-+ return(ret);
-+}
-+
-+/**
-+ * xmlSaveUri:
-+ * @uri: pointer to an xmlURI
-+ *
-+ * Save the URI as an escaped string
-+ *
-+ * Returns a new string (to be deallocated by caller)
-+ */
-+xmlChar *
-+xmlSaveUri(xmlURIPtr uri) {
-+ xmlChar *ret = NULL;
-+ const char *p;
-+ int len;
-+ int max;
-+
-+ if (uri == NULL) return(NULL);
-+
-+
-+ max = 80;
-+ ret = (xmlChar *) xmlMalloc((max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ len = 0;
-+
-+ if (uri->scheme != NULL) {
-+ p = uri->scheme;
-+ while (*p != 0) {
-+ if (len >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = *p++;
-+ }
-+ if (len >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = ':';
-+ }
-+ if (uri->opaque != NULL) {
-+ p = uri->opaque;
-+ while (*p != 0) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((IS_UNRESERVED(*(p))) ||
-+ ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||
-+ ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||
-+ ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
-+ ret[len++] = *p++;
-+ else {
-+ int val = *(unsigned char *)p++;
-+ int hi = val / 0x10, lo = val % 0x10;
-+ ret[len++] = '%';
-+ ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-+ ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-+ }
-+ }
-+ if (len >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = 0;
-+ } else {
-+ if (uri->server != NULL) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = '/';
-+ ret[len++] = '/';
-+ if (uri->user != NULL) {
-+ p = uri->user;
-+ while (*p != 0) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((IS_UNRESERVED(*(p))) ||
-+ ((*(p) == ';')) || ((*(p) == ':')) ||
-+ ((*(p) == '&')) || ((*(p) == '=')) ||
-+ ((*(p) == '+')) || ((*(p) == '$')) ||
-+ ((*(p) == ',')))
-+ ret[len++] = *p++;
-+ else {
-+ int val = *(unsigned char *)p++;
-+ int hi = val / 0x10, lo = val % 0x10;
-+ ret[len++] = '%';
-+ ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-+ ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-+ }
-+ }
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = '@';
-+ }
-+ p = uri->server;
-+ while (*p != 0) {
-+ if (len >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = *p++;
-+ }
-+ if (uri->port > 0) {
-+ if (len + 10 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ len += sprintf((char *) &ret[len], ":%d", uri->port);
-+ }
-+ } else if (uri->authority != NULL) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = '/';
-+ ret[len++] = '/';
-+ p = uri->authority;
-+ while (*p != 0) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((IS_UNRESERVED(*(p))) ||
-+ ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
-+ ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||
-+ ((*(p) == '=')) || ((*(p) == '+')))
-+ ret[len++] = *p++;
-+ else {
-+ int val = *(unsigned char *)p++;
-+ int hi = val / 0x10, lo = val % 0x10;
-+ ret[len++] = '%';
-+ ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-+ ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-+ }
-+ }
-+ } else if (uri->scheme != NULL) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = '/';
-+ ret[len++] = '/';
-+ }
-+ if (uri->path != NULL) {
-+ p = uri->path;
-+ while (*p != 0) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
-+ ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
-+ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||
-+ ((*(p) == ',')))
-+ ret[len++] = *p++;
-+ else {
-+ int val = *(unsigned char *)p++;
-+ int hi = val / 0x10, lo = val % 0x10;
-+ ret[len++] = '%';
-+ ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-+ ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-+ }
-+ }
-+ }
-+ if (uri->query != NULL) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = '?';
-+ p = uri->query;
-+ while (*p != 0) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
-+ ret[len++] = *p++;
-+ else {
-+ int val = *(unsigned char *)p++;
-+ int hi = val / 0x10, lo = val % 0x10;
-+ ret[len++] = '%';
-+ ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-+ ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-+ }
-+ }
-+ }
-+ if (uri->fragment != NULL) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = '#';
-+ p = uri->fragment;
-+ while (*p != 0) {
-+ if (len + 3 >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret,
-+ (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
-+ ret[len++] = *p++;
-+ else {
-+ int val = *(unsigned char *)p++;
-+ int hi = val / 0x10, lo = val % 0x10;
-+ ret[len++] = '%';
-+ ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-+ ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-+ }
-+ }
-+ }
-+ if (len >= max) {
-+ max *= 2;
-+ ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlSaveUri: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ ret[len++] = 0;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlPrintURI:
-+ * @stream: a FILE* for the output
-+ * @uri: pointer to an xmlURI
-+ *
-+ * Prints the URI in the stream @steam.
-+ */
-+void
-+xmlPrintURI(FILE *stream, xmlURIPtr uri) {
-+ xmlChar *out;
-+
-+ out = xmlSaveUri(uri);
-+ if (out != NULL) {
-+ fprintf(stream, "%s", out);
-+ xmlFree(out);
-+ }
-+}
-+
-+/**
-+ * xmlCleanURI:
-+ * @uri: pointer to an xmlURI
-+ *
-+ * Make sure the xmlURI struct is free of content
-+ */
-+void
-+xmlCleanURI(xmlURIPtr uri) {
-+ if (uri == NULL) return;
-+
-+ if (uri->scheme != NULL) xmlFree(uri->scheme);
-+ uri->scheme = NULL;
-+ if (uri->server != NULL) xmlFree(uri->server);
-+ uri->server = NULL;
-+ if (uri->user != NULL) xmlFree(uri->user);
-+ uri->user = NULL;
-+ if (uri->path != NULL) xmlFree(uri->path);
-+ uri->path = NULL;
-+ if (uri->fragment != NULL) xmlFree(uri->fragment);
-+ uri->fragment = NULL;
-+ if (uri->opaque != NULL) xmlFree(uri->opaque);
-+ uri->opaque = NULL;
-+ if (uri->authority != NULL) xmlFree(uri->authority);
-+ uri->authority = NULL;
-+ if (uri->query != NULL) xmlFree(uri->query);
-+ uri->query = NULL;
-+}
-+
-+/**
-+ * xmlFreeURI:
-+ * @uri: pointer to an xmlURI
-+ *
-+ * Free up the xmlURI struct
-+ */
-+void
-+xmlFreeURI(xmlURIPtr uri) {
-+ if (uri == NULL) return;
-+
-+ if (uri->scheme != NULL) xmlFree(uri->scheme);
-+ if (uri->server != NULL) xmlFree(uri->server);
-+ if (uri->user != NULL) xmlFree(uri->user);
-+ if (uri->path != NULL) xmlFree(uri->path);
-+ if (uri->fragment != NULL) xmlFree(uri->fragment);
-+ if (uri->opaque != NULL) xmlFree(uri->opaque);
-+ if (uri->authority != NULL) xmlFree(uri->authority);
-+ if (uri->query != NULL) xmlFree(uri->query);
-+ memset(uri, -1, sizeof(xmlURI));
-+ xmlFree(uri);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Helper functions *
-+ * *
-+ ************************************************************************/
-+
-+#if 0
-+/**
-+ * xmlNormalizeURIPath:
-+ * @path: pointer to the path string
-+ *
-+ * applies the 5 normalization steps to a path string
-+ * Normalization occurs directly on the string, no new allocation is done
-+ *
-+ * Returns 0 or an error code
-+ */
-+int
-+xmlNormalizeURIPath(char *path) {
-+ int cur, out;
-+
-+ if (path == NULL)
-+ return(-1);
-+ cur = 0;
-+ out = 0;
-+ while ((path[cur] != 0) && (path[cur] != '/')) cur++;
-+ if (path[cur] == 0)
-+ return(0);
-+
-+ /* we are positionned at the beginning of the first segment */
-+ cur++;
-+ out = cur;
-+
-+ /*
-+ * Analyze each segment in sequence.
-+ */
-+ while (path[cur] != 0) {
-+ /*
-+ * c) All occurrences of "./", where "." is a complete path segment,
-+ * are removed from the buffer string.
-+ */
-+ if ((path[cur] == '.') && (path[cur + 1] == '/')) {
-+ cur += 2;
-+ if (path[cur] == 0) {
-+ path[out++] = 0;
-+ }
-+ continue;
-+ }
-+
-+ /*
-+ * d) If the buffer string ends with "." as a complete path segment,
-+ * that "." is removed.
-+ */
-+ if ((path[cur] == '.') && (path[cur + 1] == 0)) {
-+ path[out] = 0;
-+ break;
-+ }
-+
-+ /* read the segment */
-+ while ((path[cur] != 0) && (path[cur] != '/')) {
-+ path[out++] = path[cur++];
-+ }
-+ path[out++] = path[cur];
-+ if (path[cur] != 0) {
-+ cur++;
-+ }
-+ }
-+
-+ cur = 0;
-+ out = 0;
-+ while ((path[cur] != 0) && (path[cur] != '/')) cur++;
-+ if (path[cur] == 0)
-+ return(0);
-+ /* we are positionned at the beginning of the first segment */
-+ cur++;
-+ out = cur;
-+ /*
-+ * Analyze each segment in sequence.
-+ */
-+ while (path[cur] != 0) {
-+ /*
-+ * e) All occurrences of "<segment>/../", where <segment> is a
-+ * complete path segment not equal to "..", are removed from the
-+ * buffer string. Removal of these path segments is performed
-+ * iteratively, removing the leftmost matching pattern on each
-+ * iteration, until no matching pattern remains.
-+ */
-+ if ((cur > 1) && (out > 1) &&
-+ (path[cur] == '/') && (path[cur + 1] == '.') &&
-+ (path[cur + 2] == '.') && (path[cur + 3] == '/') &&
-+ ((path[out] != '.') || (path[out - 1] != '.') ||
-+ (path[out - 2] != '/'))) {
-+ cur += 3;
-+ out --;
-+ while ((out > 0) && (path[out] != '/')) { out --; }
-+ path[out] = 0;
-+ continue;
-+ }
-+
-+ /*
-+ * f) If the buffer string ends with "<segment>/..", where <segment>
-+ * is a complete path segment not equal to "..", that
-+ * "<segment>/.." is removed.
-+ */
-+ if ((path[cur] == '/') && (path[cur + 1] == '.') &&
-+ (path[cur + 2] == '.') && (path[cur + 3] == 0) &&
-+ ((path[out] != '.') || (path[out - 1] != '.') ||
-+ (path[out - 2] != '/'))) {
-+ cur += 4;
-+ out --;
-+ while ((out > 0) && (path[out - 1] != '/')) { out --; }
-+ path[out] = 0;
-+ continue;
-+ }
-+
-+ path[out++] = path[cur++]; /* / or 0 */
-+ }
-+ path[out] = 0;
-+
-+ /*
-+ * g) If the resulting buffer string still begins with one or more
-+ * complete path segments of "..", then the reference is
-+ * considered to be in error. Implementations may handle this
-+ * error by retaining these components in the resolved path (i.e.,
-+ * treating them as part of the final URI), by removing them from
-+ * the resolved path (i.e., discarding relative levels above the
-+ * root), or by avoiding traversal of the reference.
-+ *
-+ * We discard them from the final path.
-+ */
-+ cur = 0;
-+ while ((path[cur] == '/') && (path[cur + 1] == '.') &&
-+ (path[cur + 2] == '.'))
-+ cur += 3;
-+ if (cur != 0) {
-+ out = 0;
-+ while (path[cur] != 0) path[out++] = path[cur++];
-+ path[out] = 0;
-+ }
-+ return(0);
-+}
-+#else
-+/**
-+ * xmlNormalizeURIPath:
-+ * @path: pointer to the path string
-+ *
-+ * Applies the 5 normalization steps to a path string--that is, RFC 2396
-+ * Section 5.2, steps 6.c through 6.g.
-+ *
-+ * Normalization occurs directly on the string, no new allocation is done
-+ *
-+ * Returns 0 or an error code
-+ */
-+int
-+xmlNormalizeURIPath(char *path) {
-+ char *cur, *out;
-+
-+ if (path == NULL)
-+ return(-1);
-+
-+ /* Skip all initial "/" chars. We want to get to the beginning of the
-+ * first non-empty segment.
-+ */
-+ cur = path;
-+ while (cur[0] == '/')
-+ ++cur;
-+ if (cur[0] == '\0')
-+ return(0);
-+
-+ /* Keep everything we've seen so far. */
-+ out = cur;
-+
-+ /*
-+ * Analyze each segment in sequence for cases (c) and (d).
-+ */
-+ while (cur[0] != '\0') {
-+ /*
-+ * c) All occurrences of "./", where "." is a complete path segment,
-+ * are removed from the buffer string.
-+ */
-+ if ((cur[0] == '.') && (cur[1] == '/')) {
-+ cur += 2;
-+ continue;
-+ }
-+
-+ /*
-+ * d) If the buffer string ends with "." as a complete path segment,
-+ * that "." is removed.
-+ */
-+ if ((cur[0] == '.') && (cur[1] == '\0'))
-+ break;
-+
-+ /* Otherwise keep the segment. */
-+ while (cur[0] != '/') {
-+ if (cur[0] == '\0')
-+ goto done_cd;
-+ (out++)[0] = (cur++)[0];
-+ }
-+ (out++)[0] = (cur++)[0];
-+ }
-+ done_cd:
-+ out[0] = '\0';
-+
-+ /* Reset to the beginning of the first segment for the next sequence. */
-+ cur = path;
-+ while (cur[0] == '/')
-+ ++cur;
-+ if (cur[0] == '\0')
-+ return(0);
-+
-+ /*
-+ * Analyze each segment in sequence for cases (e) and (f).
-+ *
-+ * e) All occurrences of "<segment>/../", where <segment> is a
-+ * complete path segment not equal to "..", are removed from the
-+ * buffer string. Removal of these path segments is performed
-+ * iteratively, removing the leftmost matching pattern on each
-+ * iteration, until no matching pattern remains.
-+ *
-+ * f) If the buffer string ends with "<segment>/..", where <segment>
-+ * is a complete path segment not equal to "..", that
-+ * "<segment>/.." is removed.
-+ *
-+ * To satisfy the "iterative" clause in (e), we need to collapse the
-+ * string every time we find something that needs to be removed. Thus,
-+ * we don't need to keep two pointers into the string: we only need a
-+ * "current position" pointer.
-+ */
-+ while (1) {
-+ char *segp;
-+
-+ /* At the beginning of each iteration of this loop, "cur" points to
-+ * the first character of the segment we want to examine.
-+ */
-+
-+ /* Find the end of the current segment. */
-+ segp = cur;
-+ while ((segp[0] != '/') && (segp[0] != '\0'))
-+ ++segp;
-+
-+ /* If this is the last segment, we're done (we need at least two
-+ * segments to meet the criteria for the (e) and (f) cases).
-+ */
-+ if (segp[0] == '\0')
-+ break;
-+
-+ /* If the first segment is "..", or if the next segment _isn't_ "..",
-+ * keep this segment and try the next one.
-+ */
-+ ++segp;
-+ if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
-+ || ((segp[0] != '.') || (segp[1] != '.')
-+ || ((segp[2] != '/') && (segp[2] != '\0')))) {
-+ cur = segp;
-+ continue;
-+ }
-+
-+ /* If we get here, remove this segment and the next one and back up
-+ * to the previous segment (if there is one), to implement the
-+ * "iteratively" clause. It's pretty much impossible to back up
-+ * while maintaining two pointers into the buffer, so just compact
-+ * the whole buffer now.
-+ */
-+
-+ /* If this is the end of the buffer, we're done. */
-+ if (segp[2] == '\0') {
-+ cur[0] = '\0';
-+ break;
-+ }
-+ strcpy(cur, segp + 3);
-+
-+ /* If there are no previous segments, then keep going from here. */
-+ segp = cur;
-+ while ((segp > path) && ((--segp)[0] == '/'))
-+ ;
-+ if (segp == path)
-+ continue;
-+
-+ /* "segp" is pointing to the end of a previous segment; find it's
-+ * start. We need to back up to the previous segment and start
-+ * over with that to handle things like "foo/bar/../..". If we
-+ * don't do this, then on the first pass we'll remove the "bar/..",
-+ * but be pointing at the second ".." so we won't realize we can also
-+ * remove the "foo/..".
-+ */
-+ cur = segp;
-+ while ((cur > path) && (cur[-1] != '/'))
-+ --cur;
-+ }
-+ out[0] = '\0';
-+
-+ /*
-+ * g) If the resulting buffer string still begins with one or more
-+ * complete path segments of "..", then the reference is
-+ * considered to be in error. Implementations may handle this
-+ * error by retaining these components in the resolved path (i.e.,
-+ * treating them as part of the final URI), by removing them from
-+ * the resolved path (i.e., discarding relative levels above the
-+ * root), or by avoiding traversal of the reference.
-+ *
-+ * We discard them from the final path.
-+ */
-+ if (path[0] == '/') {
-+ cur = path;
-+ while ((cur[1] == '.') && (cur[2] == '.')
-+ && ((cur[3] == '/') || (cur[3] == '\0')))
-+ cur += 3;
-+
-+ if (cur != path) {
-+ out = path;
-+ while (cur[0] != '\0')
-+ (out++)[0] = (cur++)[0];
-+ out[0] = 0;
-+ }
-+ }
-+
-+ return(0);
-+}
-+#endif
-+
-+/**
-+ * xmlURIUnescapeString:
-+ * @str: the string to unescape
-+ * @len: the lenght in bytes to unescape (or <= 0 to indicate full string)
-+ * @target: optionnal destination buffer
-+ *
-+ * Unescaping routine, does not do validity checks !
-+ * Output is direct unsigned char translation of %XX values (no encoding)
-+ *
-+ * Returns an copy of the string, but unescaped
-+ */
-+char *
-+xmlURIUnescapeString(const char *str, int len, char *target) {
-+ char *ret, *out;
-+ const char *in;
-+
-+ if (str == NULL)
-+ return(NULL);
-+ if (len <= 0) len = strlen(str);
-+ if (len <= 0) return(NULL);
-+
-+ if (target == NULL) {
-+ ret = (char *) xmlMalloc(len + 1);
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlURIUnescapeString: out of memory\n");
-+ return(NULL);
-+ }
-+ } else
-+ ret = target;
-+ in = str;
-+ out = ret;
-+ while(len > 0) {
-+ if (*in == '%') {
-+ in++;
-+ if ((*in >= '0') && (*in <= '9'))
-+ *out = (*in - '0');
-+ else if ((*in >= 'a') && (*in <= 'f'))
-+ *out = (*in - 'a') + 10;
-+ else if ((*in >= 'A') && (*in <= 'F'))
-+ *out = (*in - 'A') + 10;
-+ in++;
-+ if ((*in >= '0') && (*in <= '9'))
-+ *out = *out * 16 + (*in - '0');
-+ else if ((*in >= 'a') && (*in <= 'f'))
-+ *out = *out * 16 + (*in - 'a') + 10;
-+ else if ((*in >= 'A') && (*in <= 'F'))
-+ *out = *out * 16 + (*in - 'A') + 10;
-+ in++;
-+ len -= 3;
-+ out++;
-+ } else {
-+ *out++ = *in++;
-+ len--;
-+ }
-+ }
-+ *out = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlURIEscape:
-+ * @str: the string of the URI to escape
-+ *
-+ * Escaping routine, does not do validity checks !
-+ * It will try to escape the chars needing this, but this is heuristic
-+ * based it's impossible to be sure.
-+ *
-+ * Returns an copy of the string, but escaped
-+ */
-+xmlChar *
-+xmlURIEscape(const xmlChar *str) {
-+ xmlChar *ret;
-+ const xmlChar *in;
-+ unsigned int len, out;
-+
-+ if (str == NULL)
-+ return(NULL);
-+ len = xmlStrlen(str);
-+ if (len <= 0) return(NULL);
-+
-+ len += 20;
-+ ret = (xmlChar *) xmlMalloc(len);
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlURIEscape: out of memory\n");
-+ return(NULL);
-+ }
-+ in = (const xmlChar *) str;
-+ out = 0;
-+ while(*in != 0) {
-+ if (len - out <= 3) {
-+ len += 20;
-+ ret = (xmlChar *) xmlRealloc(ret, len);
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlURIEscape: out of memory\n");
-+ return(NULL);
-+ }
-+ }
-+ if ((!IS_UNRESERVED(*in)) && (*in != ':') && (*in != '/') &&
-+ (*in != '?') && (*in != '#')) {
-+ unsigned char val;
-+ ret[out++] = '%';
-+ val = *in >> 4;
-+ if (val <= 9)
-+ ret[out++] = '0' + val;
-+ else
-+ ret[out++] = 'A' + val - 0xA;
-+ val = *in & 0xF;
-+ if (val <= 9)
-+ ret[out++] = '0' + val;
-+ else
-+ ret[out++] = 'A' + val - 0xA;
-+ in++;
-+ } else {
-+ ret[out++] = *in++;
-+ }
-+ }
-+ ret[out] = 0;
-+ return(ret);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Escaped URI parsing *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlParseURIFragment:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an URI fragment string and fills in the appropriate fields
-+ * of the @uri structure.
-+ *
-+ * fragment = *uric
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIFragment(xmlURIPtr uri, const char **str) {
-+ const char *cur = *str;
-+
-+ if (str == NULL) return(-1);
-+
-+ while (IS_URIC(cur)) NEXT(cur);
-+ if (uri != NULL) {
-+ if (uri->fragment != NULL) xmlFree(uri->fragment);
-+ uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIQuery:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse the query part of an URI
-+ *
-+ * query = *uric
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIQuery(xmlURIPtr uri, const char **str) {
-+ const char *cur = *str;
-+
-+ if (str == NULL) return(-1);
-+
-+ while (IS_URIC(cur)) NEXT(cur);
-+ if (uri != NULL) {
-+ if (uri->query != NULL) xmlFree(uri->query);
-+ uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIScheme:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an URI scheme
-+ *
-+ * scheme = alpha *( alpha | digit | "+" | "-" | "." )
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIScheme(xmlURIPtr uri, const char **str) {
-+ const char *cur;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+ if (!IS_ALPHA(*cur))
-+ return(2);
-+ cur++;
-+ while (IS_SCHEME(*cur)) cur++;
-+ if (uri != NULL) {
-+ if (uri->scheme != NULL) xmlFree(uri->scheme);
-+ /* !!! strndup */
-+ uri->scheme = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIOpaquePart:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an URI opaque part
-+ *
-+ * opaque_part = uric_no_slash *uric
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIOpaquePart(xmlURIPtr uri, const char **str) {
-+ const char *cur;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+ if (!IS_URIC_NO_SLASH(cur)) {
-+ return(3);
-+ }
-+ NEXT(cur);
-+ while (IS_URIC(cur)) NEXT(cur);
-+ if (uri != NULL) {
-+ if (uri->opaque != NULL) xmlFree(uri->opaque);
-+ uri->opaque = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIServer:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse a server subpart of an URI, it's a finer grain analysis
-+ * of the authority part.
-+ *
-+ * server = [ [ userinfo "@" ] hostport ]
-+ * userinfo = *( unreserved | escaped |
-+ * ";" | ":" | "&" | "=" | "+" | "$" | "," )
-+ * hostport = host [ ":" port ]
-+ * host = hostname | IPv4address
-+ * hostname = *( domainlabel "." ) toplabel [ "." ]
-+ * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
-+ * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
-+ * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
-+ * port = *digit
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIServer(xmlURIPtr uri, const char **str) {
-+ const char *cur;
-+ const char *host, *tmp;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+
-+ /*
-+ * is there an userinfo ?
-+ */
-+ while (IS_USERINFO(cur)) NEXT(cur);
-+ if (*cur == '@') {
-+ if (uri != NULL) {
-+ if (uri->user != NULL) xmlFree(uri->user);
-+ uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ cur++;
-+ } else {
-+ if (uri != NULL) {
-+ if (uri->user != NULL) xmlFree(uri->user);
-+ uri->user = NULL;
-+ }
-+ cur = *str;
-+ }
-+ /*
-+ * This can be empty in the case where there is no server
-+ */
-+ host = cur;
-+ if (*cur == '/') {
-+ if (uri != NULL) {
-+ if (uri->authority != NULL) xmlFree(uri->authority);
-+ uri->authority = NULL;
-+ if (uri->server != NULL) xmlFree(uri->server);
-+ uri->server = NULL;
-+ uri->port = 0;
-+ }
-+ return(0);
-+ }
-+ /*
-+ * host part of hostport can derive either an IPV4 address
-+ * or an unresolved name. Check the IP first, it easier to detect
-+ * errors if wrong one
-+ */
-+ if (IS_DIGIT(*cur)) {
-+ while(IS_DIGIT(*cur)) cur++;
-+ if (*cur != '.')
-+ goto host_name;
-+ cur++;
-+ if (!IS_DIGIT(*cur))
-+ goto host_name;
-+ while(IS_DIGIT(*cur)) cur++;
-+ if (*cur != '.')
-+ goto host_name;
-+ cur++;
-+ if (!IS_DIGIT(*cur))
-+ goto host_name;
-+ while(IS_DIGIT(*cur)) cur++;
-+ if (*cur != '.')
-+ goto host_name;
-+ cur++;
-+ if (!IS_DIGIT(*cur))
-+ goto host_name;
-+ while(IS_DIGIT(*cur)) cur++;
-+ if (uri != NULL) {
-+ if (uri->authority != NULL) xmlFree(uri->authority);
-+ uri->authority = NULL;
-+ if (uri->server != NULL) xmlFree(uri->server);
-+ uri->server = xmlURIUnescapeString(host, cur - host, NULL);
-+ }
-+ goto host_done;
-+ }
-+host_name:
-+ /*
-+ * the hostname production as-is is a parser nightmare.
-+ * simplify it to
-+ * hostname = *( domainlabel "." ) domainlabel [ "." ]
-+ * and just make sure the last label starts with a non numeric char.
-+ */
-+ if (!IS_ALPHANUM(*cur))
-+ return(6);
-+ while (IS_ALPHANUM(*cur)) {
-+ while ((IS_ALPHANUM(*cur)) || (*cur == '-')) cur++;
-+ if (*cur == '.')
-+ cur++;
-+ }
-+ tmp = cur;
-+ tmp--;
-+ while (IS_ALPHANUM(*tmp) && (*tmp != '.') && (tmp >= host)) tmp--;
-+ tmp++;
-+ if (!IS_ALPHA(*tmp))
-+ return(7);
-+ if (uri != NULL) {
-+ if (uri->authority != NULL) xmlFree(uri->authority);
-+ uri->authority = NULL;
-+ if (uri->server != NULL) xmlFree(uri->server);
-+ uri->server = xmlURIUnescapeString(host, cur - host, NULL);
-+ }
-+
-+host_done:
-+
-+ /*
-+ * finish by checking for a port presence.
-+ */
-+ if (*cur == ':') {
-+ cur++;
-+ if (IS_DIGIT(*cur)) {
-+ if (uri != NULL)
-+ uri->port = 0;
-+ while (IS_DIGIT(*cur)) {
-+ if (uri != NULL)
-+ uri->port = uri->port * 10 + (*cur - '0');
-+ cur++;
-+ }
-+ }
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIRelSegment:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an URI relative segment
-+ *
-+ * rel_segment = 1*( unreserved | escaped | ";" | "@" | "&" | "=" |
-+ * "+" | "$" | "," )
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIRelSegment(xmlURIPtr uri, const char **str) {
-+ const char *cur;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+ if (!IS_SEGMENT(cur)) {
-+ return(3);
-+ }
-+ NEXT(cur);
-+ while (IS_SEGMENT(cur)) NEXT(cur);
-+ if (uri != NULL) {
-+ if (uri->path != NULL) xmlFree(uri->path);
-+ uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIPathSegments:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ * @slash: should we add a leading slash
-+ *
-+ * Parse an URI set of path segments
-+ *
-+ * path_segments = segment *( "/" segment )
-+ * segment = *pchar *( ";" param )
-+ * param = *pchar
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash) {
-+ const char *cur;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+
-+ do {
-+ while (IS_PCHAR(cur)) NEXT(cur);
-+ if (*cur == ';') {
-+ cur++;
-+ while (IS_PCHAR(cur)) NEXT(cur);
-+ }
-+ if (*cur != '/') break;
-+ cur++;
-+ } while (1);
-+ if (uri != NULL) {
-+ int len, len2 = 0;
-+ char *path;
-+
-+ /*
-+ * Concat the set of path segments to the current path
-+ */
-+ len = cur - *str;
-+ if (slash)
-+ len++;
-+
-+ if (uri->path != NULL) {
-+ len2 = strlen(uri->path);
-+ len += len2;
-+ }
-+ path = (char *) xmlMalloc(len + 1);
-+ if (path == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParseURIPathSegments: out of memory\n");
-+ *str = cur;
-+ return(-1);
-+ }
-+ if (uri->path != NULL)
-+ memcpy(path, uri->path, len2);
-+ if (slash) {
-+ path[len2] = '/';
-+ len2++;
-+ }
-+ path[len2] = 0;
-+ if (cur - *str > 0)
-+ xmlURIUnescapeString(*str, cur - *str, &path[len2]);
-+ if (uri->path != NULL)
-+ xmlFree(uri->path);
-+ uri->path = path;
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIAuthority:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse the authority part of an URI.
-+ *
-+ * authority = server | reg_name
-+ * server = [ [ userinfo "@" ] hostport ]
-+ * reg_name = 1*( unreserved | escaped | "$" | "," | ";" | ":" |
-+ * "@" | "&" | "=" | "+" )
-+ *
-+ * Note : this is completely ambiguous since reg_name is allowed to
-+ * use the full set of chars in use by server:
-+ *
-+ * 3.2.1. Registry-based Naming Authority
-+ *
-+ * The structure of a registry-based naming authority is specific
-+ * to the URI scheme, but constrained to the allowed characters
-+ * for an authority component.
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIAuthority(xmlURIPtr uri, const char **str) {
-+ const char *cur;
-+ int ret;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+
-+ /*
-+ * try first to parse it as a server string.
-+ */
-+ ret = xmlParseURIServer(uri, str);
-+ if (ret == 0)
-+ return(0);
-+
-+ /*
-+ * failed, fallback to reg_name
-+ */
-+ if (!IS_REG_NAME(cur)) {
-+ return(5);
-+ }
-+ NEXT(cur);
-+ while (IS_REG_NAME(cur)) NEXT(cur);
-+ if (uri != NULL) {
-+ if (uri->server != NULL) xmlFree(uri->server);
-+ uri->server = NULL;
-+ if (uri->user != NULL) xmlFree(uri->user);
-+ uri->user = NULL;
-+ if (uri->authority != NULL) xmlFree(uri->authority);
-+ uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURIHierPart:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an URI hirarchical part
-+ *
-+ * hier_part = ( net_path | abs_path ) [ "?" query ]
-+ * abs_path = "/" path_segments
-+ * net_path = "//" authority [ abs_path ]
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIHierPart(xmlURIPtr uri, const char **str) {
-+ int ret;
-+ const char *cur;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+
-+ if ((cur[0] == '/') && (cur[1] == '/')) {
-+ cur += 2;
-+ ret = xmlParseURIAuthority(uri, &cur);
-+ if (ret != 0)
-+ return(ret);
-+ if (cur[0] == '/') {
-+ cur++;
-+ ret = xmlParseURIPathSegments(uri, &cur, 1);
-+ }
-+ } else if (cur[0] == '/') {
-+ cur++;
-+ ret = xmlParseURIPathSegments(uri, &cur, 1);
-+ } else {
-+ return(4);
-+ }
-+ if (ret != 0)
-+ return(ret);
-+ if (*cur == '?') {
-+ cur++;
-+ ret = xmlParseURIQuery(uri, &cur);
-+ if (ret != 0)
-+ return(ret);
-+ }
-+ *str = cur;
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseAbsoluteURI:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an URI reference string and fills in the appropriate fields
-+ * of the @uri structure
-+ *
-+ * absoluteURI = scheme ":" ( hier_part | opaque_part )
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseAbsoluteURI(xmlURIPtr uri, const char **str) {
-+ int ret;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ ret = xmlParseURIScheme(uri, str);
-+ if (ret != 0) return(ret);
-+ if (**str != ':')
-+ return(1);
-+ (*str)++;
-+ if (**str == '/')
-+ return(xmlParseURIHierPart(uri, str));
-+ return(xmlParseURIOpaquePart(uri, str));
-+}
-+
-+/**
-+ * xmlParseRelativeURI:
-+ * @uri: pointer to an URI structure
-+ * @str: pointer to the string to analyze
-+ *
-+ * Parse an relative URI string and fills in the appropriate fields
-+ * of the @uri structure
-+ *
-+ * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
-+ * abs_path = "/" path_segments
-+ * net_path = "//" authority [ abs_path ]
-+ * rel_path = rel_segment [ abs_path ]
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseRelativeURI(xmlURIPtr uri, const char **str) {
-+ int ret = 0;
-+ const char *cur;
-+
-+ if (str == NULL)
-+ return(-1);
-+
-+ cur = *str;
-+ if ((cur[0] == '/') && (cur[1] == '/')) {
-+ cur += 2;
-+ ret = xmlParseURIAuthority(uri, &cur);
-+ if (ret != 0)
-+ return(ret);
-+ if (cur[0] == '/') {
-+ cur++;
-+ ret = xmlParseURIPathSegments(uri, &cur, 1);
-+ }
-+ } else if (cur[0] == '/') {
-+ cur++;
-+ ret = xmlParseURIPathSegments(uri, &cur, 1);
-+ } else if (cur[0] != '#' && cur[0] != '?') {
-+ ret = xmlParseURIRelSegment(uri, &cur);
-+ if (ret != 0)
-+ return(ret);
-+ if (cur[0] == '/') {
-+ cur++;
-+ ret = xmlParseURIPathSegments(uri, &cur, 1);
-+ }
-+ }
-+ if (ret != 0)
-+ return(ret);
-+ if (*cur == '?') {
-+ cur++;
-+ ret = xmlParseURIQuery(uri, &cur);
-+ if (ret != 0)
-+ return(ret);
-+ }
-+ *str = cur;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParseURIReference:
-+ * @uri: pointer to an URI structure
-+ * @str: the string to analyze
-+ *
-+ * Parse an URI reference string and fills in the appropriate fields
-+ * of the @uri structure
-+ *
-+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-+ *
-+ * Returns 0 or the error code
-+ */
-+int
-+xmlParseURIReference(xmlURIPtr uri, const char *str) {
-+ int ret;
-+ const char *tmp = str;
-+
-+ if (str == NULL)
-+ return(-1);
-+ xmlCleanURI(uri);
-+
-+ /*
-+ * Try first to parse aboslute refs, then fallback to relative if
-+ * it fails.
-+ */
-+ ret = xmlParseAbsoluteURI(uri, &str);
-+ if (ret != 0) {
-+ xmlCleanURI(uri);
-+ str = tmp;
-+ ret = xmlParseRelativeURI(uri, &str);
-+ }
-+ if (ret != 0) {
-+ xmlCleanURI(uri);
-+ return(ret);
-+ }
-+
-+ if (*str == '#') {
-+ str++;
-+ ret = xmlParseURIFragment(uri, &str);
-+ if (ret != 0) return(ret);
-+ }
-+ if (*str != 0) {
-+ xmlCleanURI(uri);
-+ return(1);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlParseURI:
-+ * @str: the URI string to analyze
-+ *
-+ * Parse an URI
-+ *
-+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-+ *
-+ * Returns a newly build xmlURIPtr or NULL in case of error
-+ */
-+xmlURIPtr
-+xmlParseURI(const char *str) {
-+ xmlURIPtr uri;
-+ int ret;
-+
-+ if (str == NULL)
-+ return(NULL);
-+ uri = xmlCreateURI();
-+ if (uri != NULL) {
-+ ret = xmlParseURIReference(uri, str);
-+ if (ret) {
-+ xmlFreeURI(uri);
-+ return(NULL);
-+ }
-+ }
-+ return(uri);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Public functions *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlBuildURI:
-+ * @URI: the URI instance found in the document
-+ * @base: the base value
-+ *
-+ * Computes he final URI of the reference done by checking that
-+ * the given URI is valid, and building the final URI using the
-+ * base URI. This is processed according to section 5.2 of the
-+ * RFC 2396
-+ *
-+ * 5.2. Resolving Relative References to Absolute Form
-+ *
-+ * Returns a new URI string (to be freed by the caller) or NULL in case
-+ * of error.
-+ */
-+xmlChar *
-+xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
-+ xmlChar *val = NULL;
-+ int ret, len, index, cur, out;
-+ xmlURIPtr ref = NULL;
-+ xmlURIPtr bas = NULL;
-+ xmlURIPtr res = NULL;
-+
-+ /*
-+ * 1) The URI reference is parsed into the potential four components and
-+ * fragment identifier, as described in Section 4.3.
-+ *
-+ * NOTE that a completely empty URI is treated by modern browsers
-+ * as a reference to "." rather than as a synonym for the current
-+ * URI. Should we do that here?
-+ */
-+ if (URI == NULL)
-+ ret = -1;
-+ else {
-+ if (*URI) {
-+ ref = xmlCreateURI();
-+ if (ref == NULL)
-+ goto done;
-+ ret = xmlParseURIReference(ref, (const char *) URI);
-+ }
-+ else
-+ ret = 0;
-+ }
-+ if (ret != 0)
-+ goto done;
-+ if (base == NULL)
-+ ret = -1;
-+ else {
-+ bas = xmlCreateURI();
-+ if (bas == NULL)
-+ goto done;
-+ ret = xmlParseURIReference(bas, (const char *) base);
-+ }
-+ if (ret != 0) {
-+ if (ref)
-+ val = xmlSaveUri(ref);
-+ goto done;
-+ }
-+ if (ref == NULL) {
-+ /*
-+ * the base fragment must be ignored
-+ */
-+ if (bas->fragment != NULL) {
-+ xmlFree(bas->fragment);
-+ bas->fragment = NULL;
-+ }
-+ val = xmlSaveUri(bas);
-+ goto done;
-+ }
-+
-+ /*
-+ * 2) If the path component is empty and the scheme, authority, and
-+ * query components are undefined, then it is a reference to the
-+ * current document and we are done. Otherwise, the reference URI's
-+ * query and fragment components are defined as found (or not found)
-+ * within the URI reference and not inherited from the base URI.
-+ *
-+ * NOTE that in modern browsers, the parsing differs from the above
-+ * in the following aspect: the query component is allowed to be
-+ * defined while still treating this as a reference to the current
-+ * document.
-+ */
-+ res = xmlCreateURI();
-+ if (res == NULL)
-+ goto done;
-+ if ((ref->scheme == NULL) && (ref->path == NULL) &&
-+ ((ref->authority == NULL) && (ref->server == NULL))) {
-+ if (bas->scheme != NULL)
-+ res->scheme = xmlMemStrdup(bas->scheme);
-+ if (bas->authority != NULL)
-+ res->authority = xmlMemStrdup(bas->authority);
-+ else if (bas->server != NULL) {
-+ res->server = xmlMemStrdup(bas->server);
-+ if (bas->user != NULL)
-+ res->user = xmlMemStrdup(bas->user);
-+ res->port = bas->port;
-+ }
-+ if (bas->path != NULL)
-+ res->path = xmlMemStrdup(bas->path);
-+ if (ref->query != NULL)
-+ res->query = xmlMemStrdup(ref->query);
-+ else if (bas->query != NULL)
-+ res->query = xmlMemStrdup(bas->query);
-+ if (ref->fragment != NULL)
-+ res->fragment = xmlMemStrdup(ref->fragment);
-+ goto step_7;
-+ }
-+
-+ if (ref->query != NULL)
-+ res->query = xmlMemStrdup(ref->query);
-+ if (ref->fragment != NULL)
-+ res->fragment = xmlMemStrdup(ref->fragment);
-+
-+ /*
-+ * 3) If the scheme component is defined, indicating that the reference
-+ * starts with a scheme name, then the reference is interpreted as an
-+ * absolute URI and we are done. Otherwise, the reference URI's
-+ * scheme is inherited from the base URI's scheme component.
-+ */
-+ if (ref->scheme != NULL) {
-+ val = xmlSaveUri(ref);
-+ goto done;
-+ }
-+ if (bas->scheme != NULL)
-+ res->scheme = xmlMemStrdup(bas->scheme);
-+
-+ /*
-+ * 4) If the authority component is defined, then the reference is a
-+ * network-path and we skip to step 7. Otherwise, the reference
-+ * URI's authority is inherited from the base URI's authority
-+ * component, which will also be undefined if the URI scheme does not
-+ * use an authority component.
-+ */
-+ if ((ref->authority != NULL) || (ref->server != NULL)) {
-+ if (ref->authority != NULL)
-+ res->authority = xmlMemStrdup(ref->authority);
-+ else {
-+ res->server = xmlMemStrdup(ref->server);
-+ if (ref->user != NULL)
-+ res->user = xmlMemStrdup(ref->user);
-+ res->port = ref->port;
-+ }
-+ if (ref->path != NULL)
-+ res->path = xmlMemStrdup(ref->path);
-+ goto step_7;
-+ }
-+ if (bas->authority != NULL)
-+ res->authority = xmlMemStrdup(bas->authority);
-+ else if (bas->server != NULL) {
-+ res->server = xmlMemStrdup(bas->server);
-+ if (bas->user != NULL)
-+ res->user = xmlMemStrdup(bas->user);
-+ res->port = bas->port;
-+ }
-+
-+ /*
-+ * 5) If the path component begins with a slash character ("/"), then
-+ * the reference is an absolute-path and we skip to step 7.
-+ */
-+ if ((ref->path != NULL) && (ref->path[0] == '/')) {
-+ res->path = xmlMemStrdup(ref->path);
-+ goto step_7;
-+ }
-+
-+
-+ /*
-+ * 6) If this step is reached, then we are resolving a relative-path
-+ * reference. The relative path needs to be merged with the base
-+ * URI's path. Although there are many ways to do this, we will
-+ * describe a simple method using a separate string buffer.
-+ *
-+ * Allocate a buffer large enough for the result string.
-+ */
-+ len = 2; /* extra / and 0 */
-+ if (ref->path != NULL)
-+ len += strlen(ref->path);
-+ if (bas->path != NULL)
-+ len += strlen(bas->path);
-+ res->path = (char *) xmlMalloc(len);
-+ if (res->path == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlBuildURI: out of memory\n");
-+ goto done;
-+ }
-+ res->path[0] = 0;
-+
-+ /*
-+ * a) All but the last segment of the base URI's path component is
-+ * copied to the buffer. In other words, any characters after the
-+ * last (right-most) slash character, if any, are excluded.
-+ */
-+ cur = 0;
-+ out = 0;
-+ if (bas->path != NULL) {
-+ while (bas->path[cur] != 0) {
-+ while ((bas->path[cur] != 0) && (bas->path[cur] != '/'))
-+ cur++;
-+ if (bas->path[cur] == 0)
-+ break;
-+
-+ cur++;
-+ while (out < cur) {
-+ res->path[out] = bas->path[out];
-+ out++;
-+ }
-+ }
-+ }
-+ res->path[out] = 0;
-+
-+ /*
-+ * b) The reference's path component is appended to the buffer
-+ * string.
-+ */
-+ if (ref->path != NULL && ref->path[0] != 0) {
-+ index = 0;
-+ /*
-+ * Ensure the path includes a '/'
-+ */
-+ if ((out == 0) && (bas->server != NULL))
-+ res->path[out++] = '/';
-+ while (ref->path[index] != 0) {
-+ res->path[out++] = ref->path[index++];
-+ }
-+ }
-+ res->path[out] = 0;
-+
-+ /*
-+ * Steps c) to h) are really path normalization steps
-+ */
-+ xmlNormalizeURIPath(res->path);
-+
-+step_7:
-+
-+ /*
-+ * 7) The resulting URI components, including any inherited from the
-+ * base URI, are recombined to give the absolute form of the URI
-+ * reference.
-+ */
-+ val = xmlSaveUri(res);
-+
-+done:
-+ if (ref != NULL)
-+ xmlFreeURI(ref);
-+ if (bas != NULL)
-+ xmlFreeURI(bas);
-+ if (res != NULL)
-+ xmlFreeURI(res);
-+ return(val);
-+}
-+
-+
-diff -Nru libxml2-2.3.0/libxml/uri.h libxml2-2.3.0.new/libxml/uri.h
---- libxml2-2.3.0/libxml/uri.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/uri.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,61 @@
-+/**
-+ * uri.c: library of generic URI related routines
-+ *
-+ * Reference: RFC 2396
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_URI_H__
-+#define __XML_URI_H__
-+
-+#include <libxml/tree.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/**
-+ *
-+ */
-+typedef struct _xmlURI xmlURI;
-+typedef xmlURI *xmlURIPtr;
-+struct _xmlURI {
-+ char *scheme;
-+ char *opaque;
-+ char *authority;
-+ char *server;
-+ char *user;
-+ int port;
-+ char *path;
-+ char *query;
-+ char *fragment;
-+};
-+
-+/*
-+ * This function is in tree.h:
-+ * xmlChar * xmlNodeGetBase (xmlDocPtr doc,
-+ * xmlNodePtr cur);
-+ */
-+xmlURIPtr xmlCreateURI (void);
-+xmlChar * xmlBuildURI (const xmlChar *URI,
-+ const xmlChar *base);
-+xmlURIPtr xmlParseURI (const char *URI);
-+int xmlParseURIReference (xmlURIPtr uri,
-+ const char *str);
-+xmlChar * xmlSaveUri (xmlURIPtr uri);
-+void xmlPrintURI (FILE *stream,
-+ xmlURIPtr uri);
-+char * xmlURIUnescapeString (const char *str,
-+ int len,
-+ char *target);
-+int xmlNormalizeURIPath (char *path);
-+xmlChar * xmlURIEscape (const xmlChar *str);
-+void xmlFreeURI (xmlURIPtr uri);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_URI_H__ */
-diff -Nru libxml2-2.3.0/libxml/valid.c libxml2-2.3.0.new/libxml/valid.c
---- libxml2-2.3.0/libxml/valid.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/valid.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,4025 @@
-+/*
-+ * valid.c : part of the code use to do the DTD handling and the validity
-+ * checking
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/hash.h>
-+#include <libxml/valid.h>
-+#include <libxml/parser.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/xmlerror.h>
-+
-+/*
-+ * Generic function for accessing stacks in the Validity Context
-+ */
-+
-+#define PUSH_AND_POP(scope, type, name) \
-+scope int name##VPush(xmlValidCtxtPtr ctxt, type value) { \
-+ if (ctxt->name##Nr >= ctxt->name##Max) { \
-+ ctxt->name##Max *= 2; \
-+ ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-+ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-+ if (ctxt->name##Tab == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "realloc failed !\n"); \
-+ return(0); \
-+ } \
-+ } \
-+ ctxt->name##Tab[ctxt->name##Nr] = value; \
-+ ctxt->name = value; \
-+ return(ctxt->name##Nr++); \
-+} \
-+scope type name##VPop(xmlValidCtxtPtr ctxt) { \
-+ type ret; \
-+ if (ctxt->name##Nr <= 0) return(0); \
-+ ctxt->name##Nr--; \
-+ if (ctxt->name##Nr > 0) \
-+ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-+ else \
-+ ctxt->name = NULL; \
-+ ret = ctxt->name##Tab[ctxt->name##Nr]; \
-+ ctxt->name##Tab[ctxt->name##Nr] = 0; \
-+ return(ret); \
-+} \
-+
-+PUSH_AND_POP(static, xmlNodePtr, node)
-+
-+/* #define DEBUG_VALID_ALGO */
-+
-+#ifdef DEBUG_VALID_ALGO
-+void xmlValidPrintNodeList(xmlNodePtr cur) {
-+ if (cur == NULL)
-+ xmlGenericError(xmlGenericErrorContext, "null ");
-+ while (cur != NULL) {
-+ switch (cur->type) {
-+ case XML_ELEMENT_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "%s ", cur->name);
-+ break;
-+ case XML_TEXT_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "text ");
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "cdata ");
-+ break;
-+ case XML_ENTITY_REF_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "&%s; ", cur->name);
-+ break;
-+ case XML_PI_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "pi(%s) ", cur->name);
-+ break;
-+ case XML_COMMENT_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "comment ");
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?attr? ");
-+ break;
-+ case XML_ENTITY_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?ent? ");
-+ break;
-+ case XML_DOCUMENT_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?doc? ");
-+ break;
-+ case XML_DOCUMENT_TYPE_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?doctype? ");
-+ break;
-+ case XML_DOCUMENT_FRAG_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?frag? ");
-+ break;
-+ case XML_NOTATION_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?nota? ");
-+ break;
-+ case XML_HTML_DOCUMENT_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?html? ");
-+ break;
-+ case XML_DTD_NODE:
-+ xmlGenericError(xmlGenericErrorContext, "?dtd? ");
-+ break;
-+ case XML_ELEMENT_DECL:
-+ xmlGenericError(xmlGenericErrorContext, "?edecl? ");
-+ break;
-+ case XML_ATTRIBUTE_DECL:
-+ xmlGenericError(xmlGenericErrorContext, "?adecl? ");
-+ break;
-+ case XML_ENTITY_DECL:
-+ xmlGenericError(xmlGenericErrorContext, "?entdecl? ");
-+ break;
-+ }
-+ cur = cur->next;
-+ }
-+}
-+
-+void xmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) {
-+ char expr[1000];
-+
-+ expr[0] = 0;
-+ xmlGenericError(xmlGenericErrorContext, "valid: ");
-+ xmlValidPrintNodeList(cur);
-+ xmlGenericError(xmlGenericErrorContext, "against ");
-+ xmlSprintfElementContent(expr, cont, 0);
-+ xmlGenericError(xmlGenericErrorContext, "%s\n", expr);
-+}
-+
-+#define DEBUG_VALID_STATE(n,c) xmlValidDebug(n,c);
-+#else
-+#define DEBUG_VALID_STATE(n,c)
-+#endif
-+
-+/* TODO: use hash table for accesses to elem and attribute dedinitions */
-+
-+#define VERROR \
-+ if ((ctxt != NULL) && (ctxt->error != NULL)) ctxt->error
-+
-+#define VWARNING \
-+ if ((ctxt != NULL) && (ctxt->warning != NULL)) ctxt->warning
-+
-+#define CHECK_DTD \
-+ if (doc == NULL) return(0); \
-+ else if ((doc->intSubset == NULL) && \
-+ (doc->extSubset == NULL)) return(0)
-+
-+xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name);
-+xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
-+
-+/************************************************************************
-+ * *
-+ * QName handling helper *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlSplitQName2:
-+ * @name: an XML parser context
-+ * @prefix: a xmlChar **
-+ *
-+ * parse an XML qualified name string
-+ *
-+ * [NS 5] QName ::= (Prefix ':')? LocalPart
-+ *
-+ * [NS 6] Prefix ::= NCName
-+ *
-+ * [NS 7] LocalPart ::= NCName
-+ *
-+ * Returns NULL if not a QName, otherwise the local part, and prefix
-+ * is updated to get the Prefix if any.
-+ */
-+
-+xmlChar *
-+xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
-+ int len = 0;
-+ xmlChar *ret = NULL;
-+
-+ *prefix = NULL;
-+
-+ /* xml: prefix is not really a namespace */
-+ if ((name[0] == 'x') && (name[1] == 'm') &&
-+ (name[2] == 'l') && (name[3] == ':'))
-+ return(NULL);
-+
-+ /* nasty but valid */
-+ if (name[0] == ':')
-+ return(NULL);
-+
-+ /*
-+ * we are not trying to validate but just to cut, and yes it will
-+ * work even if this is as set of UTF-8 encoded chars
-+ */
-+ while ((name[len] != 0) && (name[len] != ':'))
-+ len++;
-+
-+ if (name[len] == 0)
-+ return(NULL);
-+
-+ *prefix = xmlStrndup(name, len);
-+ ret = xmlStrdup(&name[len + 1]);
-+
-+ return(ret);
-+}
-+
-+/****************************************************************
-+ * *
-+ * Util functions for data allocation/deallocation *
-+ * *
-+ ****************************************************************/
-+
-+/**
-+ * xmlNewElementContent:
-+ * @name: the subelement name or NULL
-+ * @type: the type of element content decl
-+ *
-+ * Allocate an element content structure.
-+ *
-+ * Returns NULL if not, othervise the new element content structure
-+ */
-+xmlElementContentPtr
-+xmlNewElementContent(xmlChar *name, xmlElementContentType type) {
-+ xmlElementContentPtr ret;
-+
-+ switch(type) {
-+ case XML_ELEMENT_CONTENT_ELEMENT:
-+ if (name == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewElementContent : name == NULL !\n");
-+ }
-+ break;
-+ case XML_ELEMENT_CONTENT_PCDATA:
-+ case XML_ELEMENT_CONTENT_SEQ:
-+ case XML_ELEMENT_CONTENT_OR:
-+ if (name != NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewElementContent : name != NULL !\n");
-+ }
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewElementContent: unknown type %d\n", type);
-+ return(NULL);
-+ }
-+ ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlNewElementContent : out of memory!\n");
-+ return(NULL);
-+ }
-+ ret->type = type;
-+ ret->ocur = XML_ELEMENT_CONTENT_ONCE;
-+ if (name != NULL)
-+ ret->name = xmlStrdup(name);
-+ else
-+ ret->name = NULL;
-+ ret->c1 = ret->c2 = NULL;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlCopyElementContent:
-+ * @content: An element content pointer.
-+ *
-+ * Build a copy of an element content description.
-+ *
-+ * Returns the new xmlElementContentPtr or NULL in case of error.
-+ */
-+xmlElementContentPtr
-+xmlCopyElementContent(xmlElementContentPtr cur) {
-+ xmlElementContentPtr ret;
-+
-+ if (cur == NULL) return(NULL);
-+ ret = xmlNewElementContent((xmlChar *) cur->name, cur->type);
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCopyElementContent : out of memory\n");
-+ return(NULL);
-+ }
-+ ret->ocur = cur->ocur;
-+ if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1);
-+ if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeElementContent:
-+ * @cur: the element content tree to free
-+ *
-+ * Free an element content structure. This is a recursive call !
-+ */
-+void
-+xmlFreeElementContent(xmlElementContentPtr cur) {
-+ if (cur == NULL) return;
-+ switch (cur->type) {
-+ case XML_ELEMENT_CONTENT_PCDATA:
-+ case XML_ELEMENT_CONTENT_ELEMENT:
-+ case XML_ELEMENT_CONTENT_SEQ:
-+ case XML_ELEMENT_CONTENT_OR:
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFreeElementContent : type %d\n", cur->type);
-+ return;
-+ }
-+ if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
-+ if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
-+ if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-+ memset(cur, -1, sizeof(xmlElementContent));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlDumpElementContent:
-+ * @buf: An XML buffer
-+ * @content: An element table
-+ * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
-+ *
-+ * This will dump the content of the element table as an XML DTD definition
-+ */
-+void
-+xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
-+ if (content == NULL) return;
-+
-+ if (glob) xmlBufferWriteChar(buf, "(");
-+ switch (content->type) {
-+ case XML_ELEMENT_CONTENT_PCDATA:
-+ xmlBufferWriteChar(buf, "#PCDATA");
-+ break;
-+ case XML_ELEMENT_CONTENT_ELEMENT:
-+ xmlBufferWriteCHAR(buf, content->name);
-+ break;
-+ case XML_ELEMENT_CONTENT_SEQ:
-+ if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-+ (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-+ xmlDumpElementContent(buf, content->c1, 1);
-+ else
-+ xmlDumpElementContent(buf, content->c1, 0);
-+ xmlBufferWriteChar(buf, " , ");
-+ if (content->c2->type == XML_ELEMENT_CONTENT_OR)
-+ xmlDumpElementContent(buf, content->c2, 1);
-+ else
-+ xmlDumpElementContent(buf, content->c2, 0);
-+ break;
-+ case XML_ELEMENT_CONTENT_OR:
-+ if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-+ (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-+ xmlDumpElementContent(buf, content->c1, 1);
-+ else
-+ xmlDumpElementContent(buf, content->c1, 0);
-+ xmlBufferWriteChar(buf, " | ");
-+ if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
-+ xmlDumpElementContent(buf, content->c2, 1);
-+ else
-+ xmlDumpElementContent(buf, content->c2, 0);
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDumpElementContent: unknown type %d\n",
-+ content->type);
-+ }
-+ if (glob)
-+ xmlBufferWriteChar(buf, ")");
-+ switch (content->ocur) {
-+ case XML_ELEMENT_CONTENT_ONCE:
-+ break;
-+ case XML_ELEMENT_CONTENT_OPT:
-+ xmlBufferWriteChar(buf, "?");
-+ break;
-+ case XML_ELEMENT_CONTENT_MULT:
-+ xmlBufferWriteChar(buf, "*");
-+ break;
-+ case XML_ELEMENT_CONTENT_PLUS:
-+ xmlBufferWriteChar(buf, "+");
-+ break;
-+ }
-+}
-+
-+/**
-+ * xmlSprintfElementContent:
-+ * @buf: an output buffer
-+ * @content: An element table
-+ * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
-+ *
-+ * This will dump the content of the element content definition
-+ * Intended just for the debug routine
-+ */
-+void
-+xmlSprintfElementContent(char *buf, xmlElementContentPtr content, int glob) {
-+ if (content == NULL) return;
-+ if (glob) strcat(buf, "(");
-+ switch (content->type) {
-+ case XML_ELEMENT_CONTENT_PCDATA:
-+ strcat(buf, "#PCDATA");
-+ break;
-+ case XML_ELEMENT_CONTENT_ELEMENT:
-+ strcat(buf, (char *) content->name);
-+ break;
-+ case XML_ELEMENT_CONTENT_SEQ:
-+ if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-+ (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-+ xmlSprintfElementContent(buf, content->c1, 1);
-+ else
-+ xmlSprintfElementContent(buf, content->c1, 0);
-+ strcat(buf, " , ");
-+ if (content->c2->type == XML_ELEMENT_CONTENT_OR)
-+ xmlSprintfElementContent(buf, content->c2, 1);
-+ else
-+ xmlSprintfElementContent(buf, content->c2, 0);
-+ break;
-+ case XML_ELEMENT_CONTENT_OR:
-+ if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-+ (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-+ xmlSprintfElementContent(buf, content->c1, 1);
-+ else
-+ xmlSprintfElementContent(buf, content->c1, 0);
-+ strcat(buf, " | ");
-+ if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
-+ xmlSprintfElementContent(buf, content->c2, 1);
-+ else
-+ xmlSprintfElementContent(buf, content->c2, 0);
-+ break;
-+ }
-+ if (glob)
-+ strcat(buf, ")");
-+ switch (content->ocur) {
-+ case XML_ELEMENT_CONTENT_ONCE:
-+ break;
-+ case XML_ELEMENT_CONTENT_OPT:
-+ strcat(buf, "?");
-+ break;
-+ case XML_ELEMENT_CONTENT_MULT:
-+ strcat(buf, "*");
-+ break;
-+ case XML_ELEMENT_CONTENT_PLUS:
-+ strcat(buf, "+");
-+ break;
-+ }
-+}
-+
-+/****************************************************************
-+ * *
-+ * Registration of DTD declarations *
-+ * *
-+ ****************************************************************/
-+
-+/**
-+ * xmlCreateElementTable:
-+ *
-+ * create and initialize an empty element hash table.
-+ *
-+ * Returns the xmlElementTablePtr just created or NULL in case of error.
-+ */
-+xmlElementTablePtr
-+xmlCreateElementTable(void) {
-+ return(xmlHashCreate(0));
-+}
-+
-+/**
-+ * xmlFreeElement:
-+ * @elem: An element
-+ *
-+ * Deallocate the memory used by an element definition
-+ */
-+void
-+xmlFreeElement(xmlElementPtr elem) {
-+ if (elem == NULL) return;
-+ xmlUnlinkNode((xmlNodePtr) elem);
-+ xmlFreeElementContent(elem->content);
-+ if (elem->name != NULL)
-+ xmlFree((xmlChar *) elem->name);
-+ if (elem->prefix != NULL)
-+ xmlFree((xmlChar *) elem->prefix);
-+ memset(elem, -1, sizeof(xmlElement));
-+ xmlFree(elem);
-+}
-+
-+
-+/**
-+ * xmlAddElementDecl:
-+ * @ctxt: the validation context
-+ * @dtd: pointer to the DTD
-+ * @name: the entity name
-+ * @type: the element type
-+ * @content: the element content tree or NULL
-+ *
-+ * Register a new element declaration
-+ *
-+ * Returns NULL if not, othervise the entity
-+ */
-+xmlElementPtr
-+xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
-+ xmlElementTypeVal type,
-+ xmlElementContentPtr content) {
-+ xmlElementPtr ret;
-+ xmlElementTablePtr table;
-+ xmlChar *ns, *uqname;
-+
-+ if (dtd == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: dtd == NULL\n");
-+ return(NULL);
-+ }
-+ if (name == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: name == NULL\n");
-+ return(NULL);
-+ }
-+ switch (type) {
-+ case XML_ELEMENT_TYPE_EMPTY:
-+ if (content != NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: content != NULL for EMPTY\n");
-+ return(NULL);
-+ }
-+ break;
-+ case XML_ELEMENT_TYPE_ANY:
-+ if (content != NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: content != NULL for ANY\n");
-+ return(NULL);
-+ }
-+ break;
-+ case XML_ELEMENT_TYPE_MIXED:
-+ if (content == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: content == NULL for MIXED\n");
-+ return(NULL);
-+ }
-+ break;
-+ case XML_ELEMENT_TYPE_ELEMENT:
-+ if (content == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: content == NULL for ELEMENT\n");
-+ return(NULL);
-+ }
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: unknown type %d\n", type);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * check if name is a QName
-+ */
-+ uqname = xmlSplitQName2(name, &ns);
-+ if (uqname != NULL)
-+ name = uqname;
-+
-+ /*
-+ * Create the Element table if needed.
-+ */
-+ table = (xmlElementTablePtr) dtd->elements;
-+ if (table == NULL) {
-+ table = xmlCreateElementTable();
-+ dtd->elements = (void *) table;
-+ }
-+ if (table == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: Table creation failed!\n");
-+ return(NULL);
-+ }
-+
-+ ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddElementDecl: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlElement));
-+ ret->type = XML_ELEMENT_DECL;
-+
-+ /*
-+ * fill the structure.
-+ */
-+ ret->etype = type;
-+ ret->name = xmlStrdup(name);
-+ ret->prefix = ns;
-+ ret->content = xmlCopyElementContent(content);
-+ ret->attributes = xmlScanAttributeDecl(dtd, name);
-+
-+ /*
-+ * Validity Check:
-+ * Insertion must not fail
-+ */
-+ if (xmlHashAddEntry2(table, name, ns, ret)) {
-+ /*
-+ * The element is already defined in this Dtd.
-+ */
-+ VERROR(ctxt->userData, "Redefinition of element %s\n", name);
-+ xmlFreeElement(ret);
-+ if (uqname != NULL)
-+ xmlFree(uqname);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Link it to the Dtd
-+ */
-+ ret->parent = dtd;
-+ ret->doc = dtd->doc;
-+ if (dtd->last == NULL) {
-+ dtd->children = dtd->last = (xmlNodePtr) ret;
-+ } else {
-+ dtd->last->next = (xmlNodePtr) ret;
-+ ret->prev = dtd->last;
-+ dtd->last = (xmlNodePtr) ret;
-+ }
-+ if (uqname != NULL)
-+ xmlFree(uqname);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeElementTable:
-+ * @table: An element table
-+ *
-+ * Deallocate the memory used by an element hash table.
-+ */
-+void
-+xmlFreeElementTable(xmlElementTablePtr table) {
-+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeElement);
-+}
-+
-+/**
-+ * xmlCopyElement:
-+ * @elem: An element
-+ *
-+ * Build a copy of an element.
-+ *
-+ * Returns the new xmlElementPtr or NULL in case of error.
-+ */
-+xmlElementPtr
-+xmlCopyElement(xmlElementPtr elem) {
-+ xmlElementPtr cur;
-+
-+ cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCopyElement: out of memory !\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlElement));
-+ cur->type = XML_ELEMENT_DECL;
-+ cur->etype = elem->etype;
-+ if (elem->name != NULL)
-+ cur->name = xmlStrdup(elem->name);
-+ else
-+ cur->name = NULL;
-+ if (elem->prefix != NULL)
-+ cur->prefix = xmlStrdup(elem->prefix);
-+ else
-+ cur->prefix = NULL;
-+ cur->content = xmlCopyElementContent(elem->content);
-+ /* TODO : rebuild the attribute list on the copy */
-+ cur->attributes = NULL;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlCopyElementTable:
-+ * @table: An element table
-+ *
-+ * Build a copy of an element table.
-+ *
-+ * Returns the new xmlElementTablePtr or NULL in case of error.
-+ */
-+xmlElementTablePtr
-+xmlCopyElementTable(xmlElementTablePtr table) {
-+ return((xmlElementTablePtr) xmlHashCopy(table,
-+ (xmlHashCopier) xmlCopyElement));
-+}
-+
-+/**
-+ * xmlDumpElementDecl:
-+ * @buf: the XML buffer output
-+ * @elem: An element table
-+ *
-+ * This will dump the content of the element declaration as an XML
-+ * DTD definition
-+ */
-+void
-+xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
-+ switch (elem->etype) {
-+ case XML_ELEMENT_TYPE_EMPTY:
-+ xmlBufferWriteChar(buf, "<!ELEMENT ");
-+ xmlBufferWriteCHAR(buf, elem->name);
-+ xmlBufferWriteChar(buf, " EMPTY>\n");
-+ break;
-+ case XML_ELEMENT_TYPE_ANY:
-+ xmlBufferWriteChar(buf, "<!ELEMENT ");
-+ xmlBufferWriteCHAR(buf, elem->name);
-+ xmlBufferWriteChar(buf, " ANY>\n");
-+ break;
-+ case XML_ELEMENT_TYPE_MIXED:
-+ xmlBufferWriteChar(buf, "<!ELEMENT ");
-+ xmlBufferWriteCHAR(buf, elem->name);
-+ xmlBufferWriteChar(buf, " ");
-+ xmlDumpElementContent(buf, elem->content, 1);
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ case XML_ELEMENT_TYPE_ELEMENT:
-+ xmlBufferWriteChar(buf, "<!ELEMENT ");
-+ xmlBufferWriteCHAR(buf, elem->name);
-+ xmlBufferWriteChar(buf, " ");
-+ xmlDumpElementContent(buf, elem->content, 1);
-+ xmlBufferWriteChar(buf, ">\n");
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDumpElementDecl: internal: unknown type %d\n",
-+ elem->etype);
-+ }
-+}
-+
-+/**
-+ * xmlDumpElementTable:
-+ * @buf: the XML buffer output
-+ * @table: An element table
-+ *
-+ * This will dump the content of the element table as an XML DTD definition
-+ */
-+void
-+xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
-+ xmlHashScan(table, (xmlHashScanner) xmlDumpElementDecl, buf);
-+}
-+
-+/**
-+ * xmlCreateEnumeration:
-+ * @name: the enumeration name or NULL
-+ *
-+ * create and initialize an enumeration attribute node.
-+ *
-+ * Returns the xmlEnumerationPtr just created or NULL in case
-+ * of error.
-+ */
-+xmlEnumerationPtr
-+xmlCreateEnumeration(xmlChar *name) {
-+ xmlEnumerationPtr ret;
-+
-+ ret = (xmlEnumerationPtr) xmlMalloc(sizeof(xmlEnumeration));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCreateEnumeration : xmlMalloc(%ld) failed\n",
-+ (long)sizeof(xmlEnumeration));
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlEnumeration));
-+
-+ if (name != NULL)
-+ ret->name = xmlStrdup(name);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeEnumeration:
-+ * @cur: the tree to free.
-+ *
-+ * free an enumeration attribute node (recursive).
-+ */
-+void
-+xmlFreeEnumeration(xmlEnumerationPtr cur) {
-+ if (cur == NULL) return;
-+
-+ if (cur->next != NULL) xmlFreeEnumeration(cur->next);
-+
-+ if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-+ memset(cur, -1, sizeof(xmlEnumeration));
-+ xmlFree(cur);
-+}
-+
-+/**
-+ * xmlCopyEnumeration:
-+ * @cur: the tree to copy.
-+ *
-+ * Copy an enumeration attribute node (recursive).
-+ *
-+ * Returns the xmlEnumerationPtr just created or NULL in case
-+ * of error.
-+ */
-+xmlEnumerationPtr
-+xmlCopyEnumeration(xmlEnumerationPtr cur) {
-+ xmlEnumerationPtr ret;
-+
-+ if (cur == NULL) return(NULL);
-+ ret = xmlCreateEnumeration((xmlChar *) cur->name);
-+
-+ if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
-+ else ret->next = NULL;
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlDumpEnumeration:
-+ * @buf: the XML buffer output
-+ * @enum: An enumeration
-+ *
-+ * This will dump the content of the enumeration
-+ */
-+void
-+xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
-+ if (cur == NULL) return;
-+
-+ xmlBufferWriteCHAR(buf, cur->name);
-+ if (cur->next == NULL)
-+ xmlBufferWriteChar(buf, ")");
-+ else {
-+ xmlBufferWriteChar(buf, " | ");
-+ xmlDumpEnumeration(buf, cur->next);
-+ }
-+}
-+
-+/**
-+ * xmlCreateAttributeTable:
-+ *
-+ * create and initialize an empty attribute hash table.
-+ *
-+ * Returns the xmlAttributeTablePtr just created or NULL in case
-+ * of error.
-+ */
-+xmlAttributeTablePtr
-+xmlCreateAttributeTable(void) {
-+ return(xmlHashCreate(0));
-+}
-+
-+/**
-+ * xmlScanAttributeDeclCallback:
-+ * @attr: the attribute decl
-+ * @list: the list to update
-+ *
-+ * Callback called by xmlScanAttributeDecl when a new attribute
-+ * has to be entered in the list.
-+ */
-+void
-+xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
-+ const xmlChar* name) {
-+ attr->nexth = *list;
-+ *list = attr;
-+}
-+
-+/**
-+ * xmlScanAttributeDecl:
-+ * @dtd: pointer to the DTD
-+ * @elem: the element name
-+ *
-+ * When inserting a new element scan the DtD for existing attributes
-+ * for taht element and initialize the Attribute chain
-+ *
-+ * Returns the pointer to the first attribute decl in the chain,
-+ * possibly NULL.
-+ */
-+xmlAttributePtr
-+xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
-+ xmlAttributePtr ret = NULL;
-+ xmlAttributeTablePtr table;
-+
-+ if (dtd == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlScanAttributeDecl: dtd == NULL\n");
-+ return(NULL);
-+ }
-+ if (elem == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlScanAttributeDecl: elem == NULL\n");
-+ return(NULL);
-+ }
-+ table = (xmlAttributeTablePtr) dtd->attributes;
-+ if (table == NULL)
-+ return(NULL);
-+
-+ /* WRONG !!! */
-+ xmlHashScan3(table, NULL, NULL, elem,
-+ (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlScanIDAttributeDecl:
-+ * @ctxt: the validation context
-+ * @elem: the element name
-+ *
-+ * Verify that the element don't have too many ID attributes
-+ * declared.
-+ *
-+ * Returns the number of ID attributes found.
-+ */
-+int
-+xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
-+ xmlAttributePtr cur;
-+ int ret = 0;
-+
-+ if (elem == NULL) return(0);
-+ cur = elem->attributes;
-+ while (cur != NULL) {
-+ if (cur->atype == XML_ATTRIBUTE_ID) {
-+ ret ++;
-+ if (ret > 1)
-+ VERROR(ctxt->userData,
-+ "Element %s has too may ID attributes defined : %s\n",
-+ elem->name, cur->name);
-+ }
-+ cur = cur->nexth;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeAttribute:
-+ * @elem: An attribute
-+ *
-+ * Deallocate the memory used by an attribute definition
-+ */
-+void
-+xmlFreeAttribute(xmlAttributePtr attr) {
-+ if (attr == NULL) return;
-+ xmlUnlinkNode((xmlNodePtr) attr);
-+ if (attr->tree != NULL)
-+ xmlFreeEnumeration(attr->tree);
-+ if (attr->elem != NULL)
-+ xmlFree((xmlChar *) attr->elem);
-+ if (attr->name != NULL)
-+ xmlFree((xmlChar *) attr->name);
-+ if (attr->defaultValue != NULL)
-+ xmlFree((xmlChar *) attr->defaultValue);
-+ if (attr->prefix != NULL)
-+ xmlFree((xmlChar *) attr->prefix);
-+ memset(attr, -1, sizeof(xmlAttribute));
-+ xmlFree(attr);
-+}
-+
-+
-+/**
-+ * xmlAddAttributeDecl:
-+ * @ctxt: the validation context
-+ * @dtd: pointer to the DTD
-+ * @elem: the element name
-+ * @name: the attribute name
-+ * @ns: the attribute namespace prefix
-+ * @type: the attribute type
-+ * @def: the attribute default type
-+ * @defaultValue: the attribute default value
-+ * @tree: if it's an enumeration, the associated list
-+ *
-+ * Register a new attribute declaration
-+ * Note that @tree becomes the ownership of the DTD
-+ *
-+ * Returns NULL if not new, othervise the attribute decl
-+ */
-+xmlAttributePtr
-+xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
-+ const xmlChar *name, const xmlChar *ns,
-+ xmlAttributeType type, xmlAttributeDefault def,
-+ const xmlChar *defaultValue, xmlEnumerationPtr tree) {
-+ xmlAttributePtr ret;
-+ xmlAttributeTablePtr table;
-+ xmlElementPtr elemDef;
-+
-+ if (dtd == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddAttributeDecl: dtd == NULL\n");
-+ xmlFreeEnumeration(tree);
-+ return(NULL);
-+ }
-+ if (name == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddAttributeDecl: name == NULL\n");
-+ xmlFreeEnumeration(tree);
-+ return(NULL);
-+ }
-+ if (elem == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddAttributeDecl: elem == NULL\n");
-+ xmlFreeEnumeration(tree);
-+ return(NULL);
-+ }
-+ /*
-+ * Check the type and possibly the default value.
-+ */
-+ switch (type) {
-+ case XML_ATTRIBUTE_CDATA:
-+ break;
-+ case XML_ATTRIBUTE_ID:
-+ break;
-+ case XML_ATTRIBUTE_IDREF:
-+ break;
-+ case XML_ATTRIBUTE_IDREFS:
-+ break;
-+ case XML_ATTRIBUTE_ENTITY:
-+ break;
-+ case XML_ATTRIBUTE_ENTITIES:
-+ break;
-+ case XML_ATTRIBUTE_NMTOKEN:
-+ break;
-+ case XML_ATTRIBUTE_NMTOKENS:
-+ break;
-+ case XML_ATTRIBUTE_ENUMERATION:
-+ break;
-+ case XML_ATTRIBUTE_NOTATION:
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddAttributeDecl: unknown type %d\n", type);
-+ xmlFreeEnumeration(tree);
-+ return(NULL);
-+ }
-+ if ((defaultValue != NULL) &&
-+ (!xmlValidateAttributeValue(type, defaultValue))) {
-+ VERROR(ctxt->userData, "Attribute %s on %s: invalid default value\n",
-+ elem, name, defaultValue);
-+ defaultValue = NULL;
-+ }
-+
-+ /*
-+ * Create the Attribute table if needed.
-+ */
-+ table = (xmlAttributeTablePtr) dtd->attributes;
-+ if (table == NULL) {
-+ table = xmlCreateAttributeTable();
-+ dtd->attributes = (void *) table;
-+ }
-+ if (table == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddAttributeDecl: Table creation failed!\n");
-+ return(NULL);
-+ }
-+
-+
-+ ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddAttributeDecl: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlAttribute));
-+ ret->type = XML_ATTRIBUTE_DECL;
-+
-+ /*
-+ * fill the structure.
-+ */
-+ ret->atype = type;
-+ ret->name = xmlStrdup(name);
-+ ret->prefix = xmlStrdup(ns);
-+ ret->elem = xmlStrdup(elem);
-+ ret->def = def;
-+ ret->tree = tree;
-+ if (defaultValue != NULL)
-+ ret->defaultValue = xmlStrdup(defaultValue);
-+
-+ /*
-+ * Validity Check:
-+ * Search the DTD for previous declarations of the ATTLIST
-+ */
-+ if (xmlHashAddEntry3(table, name, ns, elem, ret) < 0) {
-+ /*
-+ * The attribute is already defined in this Dtd.
-+ */
-+ VWARNING(ctxt->userData,
-+ "Attribute %s on %s: already defined\n",
-+ name, elem);
-+ xmlFreeAttribute(ret);
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Validity Check:
-+ * Multiple ID per element
-+ */
-+ elemDef = xmlGetDtdElementDesc(dtd, elem);
-+ if (elemDef != NULL) {
-+ if ((type == XML_ATTRIBUTE_ID) &&
-+ (xmlScanIDAttributeDecl(NULL, elemDef) != 0))
-+ VERROR(ctxt->userData,
-+ "Element %s has too may ID attributes defined : %s\n",
-+ elem, name);
-+ ret->nexth = elemDef->attributes;
-+ elemDef->attributes = ret;
-+ }
-+
-+ /*
-+ * Link it to the Dtd
-+ */
-+ ret->parent = dtd;
-+ ret->doc = dtd->doc;
-+ if (dtd->last == NULL) {
-+ dtd->children = dtd->last = (xmlNodePtr) ret;
-+ } else {
-+ dtd->last->next = (xmlNodePtr) ret;
-+ ret->prev = dtd->last;
-+ dtd->last = (xmlNodePtr) ret;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeAttributeTable:
-+ * @table: An attribute table
-+ *
-+ * Deallocate the memory used by an entities hash table.
-+ */
-+void
-+xmlFreeAttributeTable(xmlAttributeTablePtr table) {
-+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeAttribute);
-+}
-+
-+/**
-+ * xmlCopyAttribute:
-+ * @attr: An attribute
-+ *
-+ * Build a copy of an attribute.
-+ *
-+ * Returns the new xmlAttributePtr or NULL in case of error.
-+ */
-+xmlAttributePtr
-+xmlCopyAttribute(xmlAttributePtr attr) {
-+ xmlAttributePtr cur;
-+
-+ cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCopyAttribute: out of memory !\n");
-+ return(NULL);
-+ }
-+ memset(cur, 0, sizeof(xmlAttribute));
-+ cur->atype = attr->atype;
-+ cur->def = attr->def;
-+ cur->tree = xmlCopyEnumeration(attr->tree);
-+ if (attr->elem != NULL)
-+ cur->elem = xmlStrdup(attr->elem);
-+ if (attr->name != NULL)
-+ cur->name = xmlStrdup(attr->name);
-+ if (attr->defaultValue != NULL)
-+ cur->defaultValue = xmlStrdup(attr->defaultValue);
-+ return(cur);
-+}
-+
-+/**
-+ * xmlCopyAttributeTable:
-+ * @table: An attribute table
-+ *
-+ * Build a copy of an attribute table.
-+ *
-+ * Returns the new xmlAttributeTablePtr or NULL in case of error.
-+ */
-+xmlAttributeTablePtr
-+xmlCopyAttributeTable(xmlAttributeTablePtr table) {
-+ return((xmlAttributeTablePtr) xmlHashCopy(table,
-+ (xmlHashCopier) xmlCopyAttribute));
-+}
-+
-+/**
-+ * xmlDumpAttributeDecl:
-+ * @buf: the XML buffer output
-+ * @attr: An attribute declaration
-+ *
-+ * This will dump the content of the attribute declaration as an XML
-+ * DTD definition
-+ */
-+void
-+xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
-+ xmlBufferWriteChar(buf, "<!ATTLIST ");
-+ xmlBufferWriteCHAR(buf, attr->elem);
-+ xmlBufferWriteChar(buf, " ");
-+ if (attr->prefix != NULL) {
-+ xmlBufferWriteCHAR(buf, attr->prefix);
-+ xmlBufferWriteChar(buf, ":");
-+ }
-+ xmlBufferWriteCHAR(buf, attr->name);
-+ switch (attr->atype) {
-+ case XML_ATTRIBUTE_CDATA:
-+ xmlBufferWriteChar(buf, " CDATA");
-+ break;
-+ case XML_ATTRIBUTE_ID:
-+ xmlBufferWriteChar(buf, " ID");
-+ break;
-+ case XML_ATTRIBUTE_IDREF:
-+ xmlBufferWriteChar(buf, " IDREF");
-+ break;
-+ case XML_ATTRIBUTE_IDREFS:
-+ xmlBufferWriteChar(buf, " IDREFS");
-+ break;
-+ case XML_ATTRIBUTE_ENTITY:
-+ xmlBufferWriteChar(buf, " ENTITY");
-+ break;
-+ case XML_ATTRIBUTE_ENTITIES:
-+ xmlBufferWriteChar(buf, " ENTITIES");
-+ break;
-+ case XML_ATTRIBUTE_NMTOKEN:
-+ xmlBufferWriteChar(buf, " NMTOKEN");
-+ break;
-+ case XML_ATTRIBUTE_NMTOKENS:
-+ xmlBufferWriteChar(buf, " NMTOKENS");
-+ break;
-+ case XML_ATTRIBUTE_ENUMERATION:
-+ xmlBufferWriteChar(buf, " (");
-+ xmlDumpEnumeration(buf, attr->tree);
-+ break;
-+ case XML_ATTRIBUTE_NOTATION:
-+ xmlBufferWriteChar(buf, " NOTATION (");
-+ xmlDumpEnumeration(buf, attr->tree);
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDumpAttributeTable: internal: unknown type %d\n",
-+ attr->atype);
-+ }
-+ switch (attr->def) {
-+ case XML_ATTRIBUTE_NONE:
-+ break;
-+ case XML_ATTRIBUTE_REQUIRED:
-+ xmlBufferWriteChar(buf, " #REQUIRED");
-+ break;
-+ case XML_ATTRIBUTE_IMPLIED:
-+ xmlBufferWriteChar(buf, " #IMPLIED");
-+ break;
-+ case XML_ATTRIBUTE_FIXED:
-+ xmlBufferWriteChar(buf, " #FIXED");
-+ break;
-+ default:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDumpAttributeTable: internal: unknown default %d\n",
-+ attr->def);
-+ }
-+ if (attr->defaultValue != NULL) {
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteQuotedString(buf, attr->defaultValue);
-+ }
-+ xmlBufferWriteChar(buf, ">\n");
-+}
-+
-+/**
-+ * xmlDumpAttributeTable:
-+ * @buf: the XML buffer output
-+ * @table: An attribute table
-+ *
-+ * This will dump the content of the attribute table as an XML DTD definition
-+ */
-+void
-+xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
-+ xmlHashScan(table, (xmlHashScanner) xmlDumpAttributeDecl, buf);
-+}
-+
-+/************************************************************************
-+ * *
-+ * NOTATIONs *
-+ * *
-+ ************************************************************************/
-+/**
-+ * xmlCreateNotationTable:
-+ *
-+ * create and initialize an empty notation hash table.
-+ *
-+ * Returns the xmlNotationTablePtr just created or NULL in case
-+ * of error.
-+ */
-+xmlNotationTablePtr
-+xmlCreateNotationTable(void) {
-+ return(xmlHashCreate(0));
-+}
-+
-+/**
-+ * xmlFreeNotation:
-+ * @not: A notation
-+ *
-+ * Deallocate the memory used by an notation definition
-+ */
-+void
-+xmlFreeNotation(xmlNotationPtr nota) {
-+ if (nota == NULL) return;
-+ if (nota->name != NULL)
-+ xmlFree((xmlChar *) nota->name);
-+ if (nota->PublicID != NULL)
-+ xmlFree((xmlChar *) nota->PublicID);
-+ if (nota->SystemID != NULL)
-+ xmlFree((xmlChar *) nota->SystemID);
-+ memset(nota, -1, sizeof(xmlNotation));
-+ xmlFree(nota);
-+}
-+
-+
-+/**
-+ * xmlAddNotationDecl:
-+ * @dtd: pointer to the DTD
-+ * @ctxt: the validation context
-+ * @name: the entity name
-+ * @PublicID: the public identifier or NULL
-+ * @SystemID: the system identifier or NULL
-+ *
-+ * Register a new notation declaration
-+ *
-+ * Returns NULL if not, othervise the entity
-+ */
-+xmlNotationPtr
-+xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
-+ const xmlChar *PublicID, const xmlChar *SystemID) {
-+ xmlNotationPtr ret;
-+ xmlNotationTablePtr table;
-+
-+ if (dtd == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNotationDecl: dtd == NULL\n");
-+ return(NULL);
-+ }
-+ if (name == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNotationDecl: name == NULL\n");
-+ return(NULL);
-+ }
-+ if ((PublicID == NULL) && (SystemID == NULL)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
-+ }
-+
-+ /*
-+ * Create the Notation table if needed.
-+ */
-+ table = (xmlNotationTablePtr) dtd->notations;
-+ if (table == NULL)
-+ dtd->notations = table = xmlCreateNotationTable();
-+ if (table == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNotationDecl: Table creation failed!\n");
-+ return(NULL);
-+ }
-+
-+ ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNotationDecl: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, sizeof(xmlNotation));
-+
-+ /*
-+ * fill the structure.
-+ */
-+ ret->name = xmlStrdup(name);
-+ if (SystemID != NULL)
-+ ret->SystemID = xmlStrdup(SystemID);
-+ if (PublicID != NULL)
-+ ret->PublicID = xmlStrdup(PublicID);
-+
-+ /*
-+ * Validity Check:
-+ * Check the DTD for previous declarations of the ATTLIST
-+ */
-+ if (xmlHashAddEntry(table, name, ret)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddNotationDecl: %s already defined\n", name);
-+ xmlFreeNotation(ret);
-+ return(NULL);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeNotationTable:
-+ * @table: An notation table
-+ *
-+ * Deallocate the memory used by an entities hash table.
-+ */
-+void
-+xmlFreeNotationTable(xmlNotationTablePtr table) {
-+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeNotation);
-+}
-+
-+/**
-+ * xmlCopyNotation:
-+ * @nota: A notation
-+ *
-+ * Build a copy of a notation.
-+ *
-+ * Returns the new xmlNotationPtr or NULL in case of error.
-+ */
-+xmlNotationPtr
-+xmlCopyNotation(xmlNotationPtr nota) {
-+ xmlNotationPtr cur;
-+
-+ cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
-+ if (cur == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlCopyNotation: out of memory !\n");
-+ return(NULL);
-+ }
-+ if (nota->name != NULL)
-+ cur->name = xmlStrdup(nota->name);
-+ else
-+ cur->name = NULL;
-+ if (nota->PublicID != NULL)
-+ cur->PublicID = xmlStrdup(nota->PublicID);
-+ else
-+ cur->PublicID = NULL;
-+ if (nota->SystemID != NULL)
-+ cur->SystemID = xmlStrdup(nota->SystemID);
-+ else
-+ cur->SystemID = NULL;
-+ return(cur);
-+}
-+
-+/**
-+ * xmlCopyNotationTable:
-+ * @table: A notation table
-+ *
-+ * Build a copy of a notation table.
-+ *
-+ * Returns the new xmlNotationTablePtr or NULL in case of error.
-+ */
-+xmlNotationTablePtr
-+xmlCopyNotationTable(xmlNotationTablePtr table) {
-+ return((xmlNotationTablePtr) xmlHashCopy(table,
-+ (xmlHashCopier) xmlCopyNotation));
-+}
-+
-+/**
-+ * xmlDumpNotationDecl:
-+ * @buf: the XML buffer output
-+ * @nota: A notation declaration
-+ *
-+ * This will dump the content the notation declaration as an XML DTD definition
-+ */
-+void
-+xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) {
-+ xmlBufferWriteChar(buf, "<!NOTATION ");
-+ xmlBufferWriteCHAR(buf, nota->name);
-+ if (nota->PublicID != NULL) {
-+ xmlBufferWriteChar(buf, " PUBLIC ");
-+ xmlBufferWriteQuotedString(buf, nota->PublicID);
-+ if (nota->SystemID != NULL) {
-+ xmlBufferWriteChar(buf, " ");
-+ xmlBufferWriteCHAR(buf, nota->SystemID);
-+ }
-+ } else {
-+ xmlBufferWriteChar(buf, " SYSTEM ");
-+ xmlBufferWriteCHAR(buf, nota->SystemID);
-+ }
-+ xmlBufferWriteChar(buf, " >\n");
-+}
-+
-+/**
-+ * xmlDumpNotationTable:
-+ * @buf: the XML buffer output
-+ * @table: A notation table
-+ *
-+ * This will dump the content of the notation table as an XML DTD definition
-+ */
-+void
-+xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
-+ xmlHashScan(table, (xmlHashScanner) xmlDumpNotationDecl, buf);
-+}
-+
-+/************************************************************************
-+ * *
-+ * IDs *
-+ * *
-+ ************************************************************************/
-+/**
-+ * xmlCreateIDTable:
-+ *
-+ * create and initialize an empty id hash table.
-+ *
-+ * Returns the xmlIDTablePtr just created or NULL in case
-+ * of error.
-+ */
-+xmlIDTablePtr
-+xmlCreateIDTable(void) {
-+ return(xmlHashCreate(0));
-+}
-+
-+/**
-+ * xmlFreeID:
-+ * @not: A id
-+ *
-+ * Deallocate the memory used by an id definition
-+ */
-+void
-+xmlFreeID(xmlIDPtr id) {
-+ if (id == NULL) return;
-+ if (id->value != NULL)
-+ xmlFree((xmlChar *) id->value);
-+ memset(id, -1, sizeof(xmlID));
-+ xmlFree(id);
-+}
-+
-+/**
-+ * xmlAddID:
-+ * @ctxt: the validation context
-+ * @doc: pointer to the document
-+ * @value: the value name
-+ * @attr: the attribute holding the ID
-+ *
-+ * Register a new id declaration
-+ *
-+ * Returns NULL if not, othervise the new xmlIDPtr
-+ */
-+xmlIDPtr
-+xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
-+ xmlAttrPtr attr) {
-+ xmlIDPtr ret;
-+ xmlIDTablePtr table;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddIDDecl: doc == NULL\n");
-+ return(NULL);
-+ }
-+ if (value == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddIDDecl: value == NULL\n");
-+ return(NULL);
-+ }
-+ if (attr == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddIDDecl: attr == NULL\n");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Create the ID table if needed.
-+ */
-+ table = (xmlIDTablePtr) doc->ids;
-+ if (table == NULL)
-+ doc->ids = table = xmlCreateIDTable();
-+ if (table == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddID: Table creation failed!\n");
-+ return(NULL);
-+ }
-+
-+ ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddID: out of memory\n");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * fill the structure.
-+ */
-+ ret->value = xmlStrdup(value);
-+ ret->attr = attr;
-+
-+ if (xmlHashAddEntry(table, value, ret) < 0) {
-+ /*
-+ * The id is already defined in this Dtd.
-+ */
-+ VERROR(ctxt->userData, "ID %s already defined\n", value);
-+ xmlFreeID(ret);
-+ return(NULL);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeIDTable:
-+ * @table: An id table
-+ *
-+ * Deallocate the memory used by an ID hash table.
-+ */
-+void
-+xmlFreeIDTable(xmlIDTablePtr table) {
-+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
-+}
-+
-+/**
-+ * xmlIsID:
-+ * @doc: the document
-+ * @elem: the element carrying the attribute
-+ * @attr: the attribute
-+ *
-+ * Determine whether an attribute is of type ID. In case we have Dtd(s)
-+ * then this is simple, otherwise we use an heuristic: name ID (upper
-+ * or lowercase).
-+ *
-+ * Returns 0 or 1 depending on the lookup result
-+ */
-+int
-+xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
-+ if (doc == NULL) return(0);
-+ if (attr == NULL) return(0);
-+ if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
-+ return(0);
-+ } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
-+ if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
-+ (xmlStrEqual(BAD_CAST "name", attr->name)))
-+ return(1);
-+ return(0);
-+ } else {
-+ xmlAttributePtr attrDecl;
-+
-+ if (elem == NULL) return(0);
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name,
-+ attr->name);
-+
-+ if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
-+ return(1);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlRemoveID
-+ * @doc: the document
-+ * @attr: the attribute
-+ *
-+ * Remove the given attribute from the ID table maintained internally.
-+ *
-+ * Returns -1 if the lookup failed and 0 otherwise
-+ */
-+int
-+xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
-+ xmlAttrPtr cur;
-+ xmlIDTablePtr table;
-+ xmlChar *ID;
-+
-+ if (doc == NULL) return(-1);
-+ if (attr == NULL) return(-1);
-+ table = (xmlIDTablePtr) doc->ids;
-+ if (table == NULL)
-+ return(-1);
-+
-+ if (attr == NULL)
-+ return(-1);
-+ ID = xmlNodeListGetString(doc, attr->children, 1);
-+ if (ID == NULL)
-+ return(-1);
-+ cur = xmlHashLookup(table, ID);
-+ if (cur != attr) {
-+ xmlFree(ID);
-+ return(-1);
-+ }
-+ xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeID);
-+ xmlFree(ID);
-+ return(0);
-+}
-+
-+/**
-+ * xmlGetID:
-+ * @doc: pointer to the document
-+ * @ID: the ID value
-+ *
-+ * Search the attribute declaring the given ID
-+ *
-+ * Returns NULL if not found, otherwise the xmlAttrPtr defining the ID
-+ */
-+xmlAttrPtr
-+xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
-+ xmlIDTablePtr table;
-+ xmlIDPtr id;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "xmlGetID: doc == NULL\n");
-+ return(NULL);
-+ }
-+
-+ if (ID == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "xmlGetID: ID == NULL\n");
-+ return(NULL);
-+ }
-+
-+ table = (xmlIDTablePtr) doc->ids;
-+ if (table == NULL)
-+ return(NULL);
-+
-+ id = xmlHashLookup(table, ID);
-+ if (id == NULL)
-+ return(NULL);
-+ return(id->attr);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Refs *
-+ * *
-+ ************************************************************************/
-+/**
-+ * xmlCreateRefTable:
-+ *
-+ * create and initialize an empty ref hash table.
-+ *
-+ * Returns the xmlRefTablePtr just created or NULL in case
-+ * of error.
-+ */
-+xmlRefTablePtr
-+xmlCreateRefTable(void) {
-+ return(xmlHashCreate(0));
-+}
-+
-+/**
-+ * xmlFreeRef:
-+ * @ref: A ref
-+ *
-+ * Deallocate the memory used by an ref definition
-+ */
-+void
-+xmlFreeRef(xmlRefPtr ref) {
-+ if (ref == NULL) return;
-+ if (ref->value != NULL)
-+ xmlFree((xmlChar *) ref->value);
-+ memset(ref, -1, sizeof(xmlRef));
-+ xmlFree(ref);
-+}
-+
-+/**
-+ * xmlAddRef:
-+ * @ctxt: the validation context
-+ * @doc: pointer to the document
-+ * @value: the value name
-+ * @attr: the attribute holding the Ref
-+ *
-+ * Register a new ref declaration
-+ *
-+ * Returns NULL if not, othervise the new xmlRefPtr
-+ */
-+xmlRefPtr
-+xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
-+ xmlAttrPtr attr) {
-+ xmlRefPtr ret;
-+ xmlRefTablePtr table;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddRefDecl: doc == NULL\n");
-+ return(NULL);
-+ }
-+ if (value == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddRefDecl: value == NULL\n");
-+ return(NULL);
-+ }
-+ if (attr == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddRefDecl: attr == NULL\n");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Create the Ref table if needed.
-+ */
-+ table = (xmlRefTablePtr) doc->refs;
-+ if (table == NULL)
-+ doc->refs = table = xmlCreateRefTable();
-+ if (table == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddRef: Table creation failed!\n");
-+ return(NULL);
-+ }
-+
-+ ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAddRef: out of memory\n");
-+ return(NULL);
-+ }
-+
-+ /*
-+ * fill the structure.
-+ */
-+ ret->value = xmlStrdup(value);
-+ ret->attr = attr;
-+
-+ /*
-+ * !!! Should we keep track of all refs ? and use xmlHashAddEntry2 ?
-+ */
-+ if (xmlHashAddEntry(table, value, ret) < 0) {
-+ /*
-+ * Since there is no discrimination on error returns
-+ * from xmlHashAddEntry, I'm presuming <0 means the
-+ * key already exists.
-+ */
-+ xmlHashUpdateEntry(table, value, ret, (xmlHashDeallocator) xmlFreeRef);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeRefTable:
-+ * @table: An ref table
-+ *
-+ * Deallocate the memory used by an Ref hash table.
-+ */
-+void
-+xmlFreeRefTable(xmlRefTablePtr table) {
-+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeRef);
-+}
-+
-+/**
-+ * xmlIsRef:
-+ * @doc: the document
-+ * @elem: the element carrying the attribute
-+ * @attr: the attribute
-+ *
-+ * Determine whether an attribute is of type Ref. In case we have Dtd(s)
-+ * then this is simple, otherwise we use an heuristic: name Ref (upper
-+ * or lowercase).
-+ *
-+ * Returns 0 or 1 depending on the lookup result
-+ */
-+int
-+xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
-+ if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
-+ return(0);
-+ } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
-+ /* TODO @@@ */
-+ return(0);
-+ } else {
-+ xmlAttributePtr attrDecl;
-+
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name,
-+ attr->name);
-+
-+ if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_IDREF))
-+ return(1);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlRemoveRef
-+ * @doc: the document
-+ * @attr: the attribute
-+ *
-+ * Remove the given attribute from the Ref table maintained internally.
-+ *
-+ * Returns -1 if the lookup failed and 0 otherwise
-+ */
-+int
-+xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
-+ xmlAttrPtr cur;
-+ xmlRefTablePtr table;
-+ xmlChar *ID;
-+
-+ if (doc == NULL) return(-1);
-+ if (attr == NULL) return(-1);
-+ table = (xmlRefTablePtr) doc->refs;
-+ if (table == NULL)
-+ return(-1);
-+
-+ if (attr == NULL)
-+ return(-1);
-+ ID = xmlNodeListGetString(doc, attr->children, 1);
-+ if (ID == NULL)
-+ return(-1);
-+ cur = xmlHashLookup(table, ID);
-+ if (cur != attr) {
-+ xmlFree(ID);
-+ return(-1);
-+ }
-+ xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeRef);
-+ xmlFree(ID);
-+ return(0);
-+}
-+
-+/**
-+ * xmlGetRef:
-+ * @doc: pointer to the document
-+ * @Ref: the Ref value
-+ *
-+ * Search the next attribute declaring the given Ref
-+ *
-+ * Returns NULL if not found, otherwise the xmlAttrPtr defining the Ref
-+ */
-+xmlAttrPtr
-+xmlGetRef(xmlDocPtr doc, const xmlChar *Ref) {
-+ xmlRefTablePtr table;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "xmlGetRef: doc == NULL\n");
-+ return(NULL);
-+ }
-+
-+ if (Ref == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "xmlGetRef: Ref == NULL\n");
-+ return(NULL);
-+ }
-+
-+ table = (xmlRefTablePtr) doc->refs;
-+ if (table == NULL)
-+ return(NULL);
-+
-+ return(xmlHashLookup(table, Ref));
-+}
-+
-+/************************************************************************
-+ * *
-+ * Routines for validity checking *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlGetDtdElementDesc:
-+ * @dtd: a pointer to the DtD to search
-+ * @name: the element name
-+ *
-+ * Search the Dtd for the description of this element
-+ *
-+ * returns the xmlElementPtr if found or NULL
-+ */
-+
-+xmlElementPtr
-+xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
-+ xmlElementTablePtr table;
-+ xmlElementPtr cur;
-+ xmlChar *uqname = NULL, *prefix = NULL;
-+
-+ if (dtd == NULL) return(NULL);
-+ if (dtd->elements == NULL) return(NULL);
-+ table = (xmlElementTablePtr) dtd->elements;
-+
-+ uqname = xmlSplitQName2(name, &prefix);
-+ if (uqname != NULL) {
-+ cur = xmlHashLookup2(table, uqname, prefix);
-+ if (prefix != NULL) xmlFree(prefix);
-+ if (uqname != NULL) xmlFree(uqname);
-+ } else
-+ cur = xmlHashLookup2(table, name, NULL);
-+ return(cur);
-+}
-+
-+/**
-+ * xmlGetDtdQElementDesc:
-+ * @dtd: a pointer to the DtD to search
-+ * @name: the element name
-+ * @prefix: the element namespace prefix
-+ *
-+ * Search the Dtd for the description of this element
-+ *
-+ * returns the xmlElementPtr if found or NULL
-+ */
-+
-+xmlElementPtr
-+xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
-+ const xmlChar *prefix) {
-+ xmlElementTablePtr table;
-+
-+ if (dtd == NULL) return(NULL);
-+ if (dtd->elements == NULL) return(NULL);
-+ table = (xmlElementTablePtr) dtd->elements;
-+
-+ return(xmlHashLookup2(table, name, prefix));
-+}
-+
-+/**
-+ * xmlGetDtdAttrDesc:
-+ * @dtd: a pointer to the DtD to search
-+ * @elem: the element name
-+ * @name: the attribute name
-+ *
-+ * Search the Dtd for the description of this attribute on
-+ * this element.
-+ *
-+ * returns the xmlAttributePtr if found or NULL
-+ */
-+
-+xmlAttributePtr
-+xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
-+ xmlAttributeTablePtr table;
-+ xmlAttributePtr cur;
-+ xmlChar *uqname = NULL, *prefix = NULL;
-+
-+ if (dtd == NULL) return(NULL);
-+ if (dtd->attributes == NULL) return(NULL);
-+
-+ table = (xmlAttributeTablePtr) dtd->attributes;
-+ if (table == NULL)
-+ return(NULL);
-+
-+ uqname = xmlSplitQName2(name, &prefix);
-+
-+ if (uqname != NULL) {
-+ cur = xmlHashLookup3(table, uqname, prefix, elem);
-+ if (prefix != NULL) xmlFree(prefix);
-+ if (uqname != NULL) xmlFree(uqname);
-+ } else
-+ cur = xmlHashLookup3(table, name, NULL, elem);
-+ return(cur);
-+}
-+
-+/**
-+ * xmlGetDtdQAttrDesc:
-+ * @dtd: a pointer to the DtD to search
-+ * @elem: the element name
-+ * @name: the attribute name
-+ * @prefix: the attribute namespace prefix
-+ *
-+ * Search the Dtd for the description of this qualified attribute on
-+ * this element.
-+ *
-+ * returns the xmlAttributePtr if found or NULL
-+ */
-+
-+xmlAttributePtr
-+xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
-+ const xmlChar *prefix) {
-+ xmlAttributeTablePtr table;
-+
-+ if (dtd == NULL) return(NULL);
-+ if (dtd->attributes == NULL) return(NULL);
-+ table = (xmlAttributeTablePtr) dtd->attributes;
-+
-+ return(xmlHashLookup3(table, name, prefix, elem));
-+}
-+
-+/**
-+ * xmlGetDtdNotationDesc:
-+ * @dtd: a pointer to the DtD to search
-+ * @name: the notation name
-+ *
-+ * Search the Dtd for the description of this notation
-+ *
-+ * returns the xmlNotationPtr if found or NULL
-+ */
-+
-+xmlNotationPtr
-+xmlGetDtdNotationDesc(xmlDtdPtr dtd, const xmlChar *name) {
-+ xmlNotationTablePtr table;
-+
-+ if (dtd == NULL) return(NULL);
-+ if (dtd->notations == NULL) return(NULL);
-+ table = (xmlNotationTablePtr) dtd->notations;
-+
-+ return(xmlHashLookup(table, name));
-+}
-+
-+/**
-+ * xmlValidateNotationUse:
-+ * @ctxt: the validation context
-+ * @doc: the document
-+ * @notationName: the notation name to check
-+ *
-+ * Validate that the given mame match a notation declaration.
-+ * - [ VC: Notation Declared ]
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ const xmlChar *notationName) {
-+ xmlNotationPtr notaDecl;
-+ if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
-+
-+ notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
-+ if ((notaDecl == NULL) && (doc->extSubset != NULL))
-+ notaDecl = xmlGetDtdNotationDesc(doc->extSubset, notationName);
-+
-+ if (notaDecl == NULL) {
-+ VERROR(ctxt->userData, "NOTATION %s is not declared\n",
-+ notationName);
-+ return(0);
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * xmlIsMixedElement
-+ * @doc: the document
-+ * @name: the element name
-+ *
-+ * Search in the DtDs whether an element accept Mixed content (or ANY)
-+ * basically if it is supposed to accept text childs
-+ *
-+ * returns 0 if no, 1 if yes, and -1 if no element description is available
-+ */
-+
-+int
-+xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
-+ xmlElementPtr elemDecl;
-+
-+ if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
-+
-+ elemDecl = xmlGetDtdElementDesc(doc->intSubset, name);
-+ if ((elemDecl == NULL) && (doc->extSubset != NULL))
-+ elemDecl = xmlGetDtdElementDesc(doc->extSubset, name);
-+ if (elemDecl == NULL) return(-1);
-+ switch (elemDecl->etype) {
-+ case XML_ELEMENT_TYPE_ELEMENT:
-+ return(0);
-+ case XML_ELEMENT_TYPE_EMPTY:
-+ /*
-+ * return 1 for EMPTY since we want VC error to pop up
-+ * on <empty> </empty> for example
-+ */
-+ case XML_ELEMENT_TYPE_ANY:
-+ case XML_ELEMENT_TYPE_MIXED:
-+ return(1);
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * xmlValidateNameValue:
-+ * @value: an Name value
-+ *
-+ * Validate that the given value match Name production
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateNameValue(const xmlChar *value) {
-+ const xmlChar *cur;
-+
-+ if (value == NULL) return(0);
-+ cur = value;
-+
-+ if (!IS_LETTER(*cur) && (*cur != '_') &&
-+ (*cur != ':')) {
-+ return(0);
-+ }
-+
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+
-+ if (*cur != 0) return(0);
-+
-+ return(1);
-+}
-+
-+/**
-+ * xmlValidateNamesValue:
-+ * @value: an Names value
-+ *
-+ * Validate that the given value match Names production
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateNamesValue(const xmlChar *value) {
-+ const xmlChar *cur;
-+
-+ if (value == NULL) return(0);
-+ cur = value;
-+
-+ if (!IS_LETTER(*cur) && (*cur != '_') &&
-+ (*cur != ':')) {
-+ return(0);
-+ }
-+
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+
-+ while (IS_BLANK(*cur)) {
-+ while (IS_BLANK(*cur)) cur++;
-+
-+ if (!IS_LETTER(*cur) && (*cur != '_') &&
-+ (*cur != ':')) {
-+ return(0);
-+ }
-+
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+ }
-+
-+ if (*cur != 0) return(0);
-+
-+ return(1);
-+}
-+
-+/**
-+ * xmlValidateNmtokenValue:
-+ * @value: an Mntoken value
-+ *
-+ * Validate that the given value match Nmtoken production
-+ *
-+ * [ VC: Name Token ]
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateNmtokenValue(const xmlChar *value) {
-+ const xmlChar *cur;
-+
-+ if (value == NULL) return(0);
-+ cur = value;
-+
-+ if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
-+ (*cur != '.') && (*cur != '-') &&
-+ (*cur != '_') && (*cur != ':') &&
-+ (!IS_COMBINING(*cur)) &&
-+ (!IS_EXTENDER(*cur)))
-+ return(0);
-+
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+
-+ if (*cur != 0) return(0);
-+
-+ return(1);
-+}
-+
-+/**
-+ * xmlValidateNmtokensValue:
-+ * @value: an Mntokens value
-+ *
-+ * Validate that the given value match Nmtokens production
-+ *
-+ * [ VC: Name Token ]
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateNmtokensValue(const xmlChar *value) {
-+ const xmlChar *cur;
-+
-+ if (value == NULL) return(0);
-+ cur = value;
-+
-+ while (IS_BLANK(*cur)) cur++;
-+ if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
-+ (*cur != '.') && (*cur != '-') &&
-+ (*cur != '_') && (*cur != ':') &&
-+ (!IS_COMBINING(*cur)) &&
-+ (!IS_EXTENDER(*cur)))
-+ return(0);
-+
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+
-+ while (IS_BLANK(*cur)) {
-+ while (IS_BLANK(*cur)) cur++;
-+ if (*cur == 0) return(1);
-+
-+ if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
-+ (*cur != '.') && (*cur != '-') &&
-+ (*cur != '_') && (*cur != ':') &&
-+ (!IS_COMBINING(*cur)) &&
-+ (!IS_EXTENDER(*cur)))
-+ return(0);
-+
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+ }
-+
-+ if (*cur != 0) return(0);
-+
-+ return(1);
-+}
-+
-+/**
-+ * xmlValidateNotationDecl:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @nota: a notation definition
-+ *
-+ * Try to validate a single notation definition
-+ * basically it does the following checks as described by the
-+ * XML-1.0 recommendation:
-+ * - it seems that no validity constraing exist on notation declarations
-+ * But this function get called anyway ...
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateNotationDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ xmlNotationPtr nota) {
-+ int ret = 1;
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlValidateAttributeValue:
-+ * @type: an attribute type
-+ * @value: an attribute value
-+ *
-+ * Validate that the given attribute value match the proper production
-+ *
-+ * [ VC: ID ]
-+ * Values of type ID must match the Name production....
-+ *
-+ * [ VC: IDREF ]
-+ * Values of type IDREF must match the Name production, and values
-+ * of type IDREFS must match Names ...
-+ *
-+ * [ VC: Entity Name ]
-+ * Values of type ENTITY must match the Name production, values
-+ * of type ENTITIES must match Names ...
-+ *
-+ * [ VC: Name Token ]
-+ * Values of type NMTOKEN must match the Nmtoken production; values
-+ * of type NMTOKENS must match Nmtokens.
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) {
-+ switch (type) {
-+ case XML_ATTRIBUTE_ENTITIES:
-+ case XML_ATTRIBUTE_IDREFS:
-+ return(xmlValidateNamesValue(value));
-+ case XML_ATTRIBUTE_ENTITY:
-+ case XML_ATTRIBUTE_IDREF:
-+ case XML_ATTRIBUTE_ID:
-+ case XML_ATTRIBUTE_NOTATION:
-+ return(xmlValidateNameValue(value));
-+ case XML_ATTRIBUTE_NMTOKENS:
-+ case XML_ATTRIBUTE_ENUMERATION:
-+ return(xmlValidateNmtokensValue(value));
-+ case XML_ATTRIBUTE_NMTOKEN:
-+ return(xmlValidateNmtokenValue(value));
-+ case XML_ATTRIBUTE_CDATA:
-+ break;
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * xmlValidateAttributeValue2:
-+ * @ctxt: the validation context
-+ * @doc: the document
-+ * @name: the attribute name (used for error reporting only)
-+ * @type: the attribute type
-+ * @value: the attribute value
-+ *
-+ * Validate that the given attribute value match a given type.
-+ * This typically cannot be done before having finished parsing
-+ * the subsets.
-+ *
-+ * [ VC: IDREF ]
-+ * Values of type IDREF must match one of the declared IDs
-+ * Values of type IDREFS must match a sequence of the declared IDs
-+ * each Name must match the value of an ID attribute on some element
-+ * in the XML document; i.e. IDREF values must match the value of
-+ * some ID attribute
-+ *
-+ * [ VC: Entity Name ]
-+ * Values of type ENTITY must match one declared entity
-+ * Values of type ENTITIES must match a sequence of declared entities
-+ *
-+ * [ VC: Notation Attributes ]
-+ * all notation names in the declaration must be declared.
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ const xmlChar *name, xmlAttributeType type, const xmlChar *value) {
-+ int ret = 1;
-+ switch (type) {
-+ case XML_ATTRIBUTE_IDREFS:
-+ case XML_ATTRIBUTE_IDREF:
-+ case XML_ATTRIBUTE_ID:
-+ case XML_ATTRIBUTE_NMTOKENS:
-+ case XML_ATTRIBUTE_ENUMERATION:
-+ case XML_ATTRIBUTE_NMTOKEN:
-+ case XML_ATTRIBUTE_CDATA:
-+ break;
-+ case XML_ATTRIBUTE_ENTITY: {
-+ xmlEntityPtr ent;
-+
-+ ent = xmlGetDocEntity(doc, value);
-+ if (ent == NULL) {
-+ VERROR(ctxt->userData,
-+ "ENTITY attribute %s reference an unknown entity \"%s\"\n",
-+ name, value);
-+ ret = 0;
-+ } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-+ VERROR(ctxt->userData,
-+ "ENTITY attribute %s reference an entity \"%s\" of wrong type\n",
-+ name, value);
-+ ret = 0;
-+ }
-+ break;
-+ }
-+ case XML_ATTRIBUTE_ENTITIES: {
-+ xmlChar *dup, *nam = NULL, *cur, save;
-+ xmlEntityPtr ent;
-+
-+ dup = xmlStrdup(value);
-+ if (dup == NULL)
-+ return(0);
-+ cur = dup;
-+ while (*cur != 0) {
-+ nam = cur;
-+ while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
-+ save = *cur;
-+ *cur = 0;
-+ ent = xmlGetDocEntity(doc, nam);
-+ if (ent == NULL) {
-+ VERROR(ctxt->userData,
-+ "ENTITIES attribute %s reference an unknown entity \"%s\"\n",
-+ name, nam);
-+ ret = 0;
-+ } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-+ VERROR(ctxt->userData,
-+ "ENTITIES attribute %s reference an entity \"%s\" of wrong type\n",
-+ name, nam);
-+ ret = 0;
-+ }
-+ if (save == 0)
-+ break;
-+ *cur = save;
-+ while (IS_BLANK(*cur)) cur++;
-+ }
-+ xmlFree(dup);
-+ break;
-+ }
-+ case XML_ATTRIBUTE_NOTATION: {
-+ xmlNotationPtr nota;
-+
-+ nota = xmlGetDtdNotationDesc(doc->intSubset, value);
-+ if ((nota == NULL) && (doc->extSubset != NULL))
-+ nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-+
-+ if (nota == NULL) {
-+ VERROR(ctxt->userData,
-+ "NOTATION attribute %s reference an unknown notation \"%s\"\n",
-+ name, value);
-+ ret = 0;
-+ }
-+ break;
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlValidNormalizeAttributeValue:
-+ * @doc: the document
-+ * @elem: the parent
-+ * @name: the attribute name
-+ * @value: the attribute value
-+ *
-+ * Does the validation related extra step of the normalization of attribute
-+ * values:
-+ *
-+ * If the declared value is not CDATA, then the XML processor must further
-+ * process the normalized attribute value by discarding any leading and
-+ * trailing space (#x20) characters, and by replacing sequences of space
-+ * (#x20) characters by single space (#x20) character.
-+ *
-+ * returns a new normalized string if normalization is needed, NULL otherwise
-+ * the caller must free the returned value.
-+ */
-+
-+xmlChar *
-+xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
-+ const xmlChar *name, const xmlChar *value) {
-+ xmlChar *ret, *dst;
-+ const xmlChar *src;
-+ xmlAttributePtr attrDecl = NULL;
-+
-+ if (doc == NULL) return(NULL);
-+ if (elem == NULL) return(NULL);
-+ if (name == NULL) return(NULL);
-+ if (value == NULL) return(NULL);
-+
-+ if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
-+ xmlChar qname[500];
-+#ifdef HAVE_SNPRINTF
-+ snprintf((char *) qname, sizeof(qname), "%s:%s",
-+ elem->ns->prefix, elem->name);
-+#else
-+ sprintf((char *) qname, "%s:%s", elem->ns->prefix, elem->name);
-+#endif
-+ qname[sizeof(qname) - 1] = 0;
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name);
-+ }
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
-+
-+ if (attrDecl == NULL)
-+ return(NULL);
-+ if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
-+ return(NULL);
-+
-+ ret = xmlStrdup(value);
-+ if (ret == NULL)
-+ return(NULL);
-+ src = value;
-+ dst = ret;
-+ while (*src == 0x20) src++;
-+ while (*src != 0) {
-+ if (*src == 0x20) {
-+ while (*src == 0x20) src++;
-+ if (*src != 0)
-+ *dst++ = 0x20;
-+ } else {
-+ *dst++ = *src++;
-+ }
-+ }
-+ *dst = 0;
-+ return(ret);
-+}
-+
-+void
-+xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count,
-+ const xmlChar* name) {
-+ if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
-+}
-+
-+/**
-+ * xmlValidateAttributeDecl:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @attr: an attribute definition
-+ *
-+ * Try to validate a single attribute definition
-+ * basically it does the following checks as described by the
-+ * XML-1.0 recommendation:
-+ * - [ VC: Attribute Default Legal ]
-+ * - [ VC: Enumeration ]
-+ * - [ VC: ID Attribute Default ]
-+ *
-+ * The ID/IDREF uniqueness and matching are done separately
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ xmlAttributePtr attr) {
-+ int ret = 1;
-+ int val;
-+ CHECK_DTD;
-+ if(attr == NULL) return(1);
-+
-+ /* Attribute Default Legal */
-+ /* Enumeration */
-+ if (attr->defaultValue != NULL) {
-+ val = xmlValidateAttributeValue(attr->atype, attr->defaultValue);
-+ if (val == 0) {
-+ VERROR(ctxt->userData,
-+ "Syntax of default value for attribute %s on %s is not valid\n",
-+ attr->name, attr->elem);
-+ }
-+ ret &= val;
-+ }
-+
-+ /* ID Attribute Default */
-+ if ((attr->atype == XML_ATTRIBUTE_ID)&&
-+ (attr->def != XML_ATTRIBUTE_IMPLIED) &&
-+ (attr->def != XML_ATTRIBUTE_REQUIRED)) {
-+ VERROR(ctxt->userData,
-+ "ID attribute %s on %s is not valid must be #IMPLIED or #REQUIRED\n",
-+ attr->name, attr->elem);
-+ ret = 0;
-+ }
-+
-+ /* One ID per Element Type */
-+ if (attr->atype == XML_ATTRIBUTE_ID) {
-+ int nbId;
-+
-+ /* the trick is taht we parse DtD as their own internal subset */
-+ xmlElementPtr elem = xmlGetDtdElementDesc(doc->intSubset,
-+ attr->elem);
-+ if (elem != NULL) {
-+ nbId = xmlScanIDAttributeDecl(NULL, elem);
-+ } else {
-+ xmlAttributeTablePtr table;
-+
-+ /*
-+ * The attribute may be declared in the internal subset and the
-+ * element in the external subset.
-+ */
-+ nbId = 0;
-+ table = (xmlAttributeTablePtr) doc->intSubset->attributes;
-+ xmlHashScan3(table, NULL, NULL, attr->elem, (xmlHashScanner)
-+ xmlValidateAttributeIdCallback, &nbId);
-+ }
-+ if (nbId > 1) {
-+ VERROR(ctxt->userData,
-+ "Element %s has %d ID attribute defined in the internal subset : %s\n",
-+ attr->elem, nbId, attr->name);
-+ } else if (doc->extSubset != NULL) {
-+ int extId = 0;
-+ elem = xmlGetDtdElementDesc(doc->extSubset, attr->elem);
-+ if (elem != NULL) {
-+ extId = xmlScanIDAttributeDecl(NULL, elem);
-+ }
-+ if (extId > 1) {
-+ VERROR(ctxt->userData,
-+ "Element %s has %d ID attribute defined in the external subset : %s\n",
-+ attr->elem, extId, attr->name);
-+ } else if (extId + nbId > 1) {
-+ VERROR(ctxt->userData,
-+"Element %s has ID attributes defined in the internal and external subset : %s\n",
-+ attr->elem, attr->name);
-+ }
-+ }
-+ }
-+
-+ /* Validity Constraint: Enumeration */
-+ if ((attr->defaultValue != NULL) && (attr->tree != NULL)) {
-+ xmlEnumerationPtr tree = attr->tree;
-+ while (tree != NULL) {
-+ if (xmlStrEqual(tree->name, attr->defaultValue)) break;
-+ tree = tree->next;
-+ }
-+ if (tree == NULL) {
-+ VERROR(ctxt->userData,
-+"Default value \"%s\" for attribute %s on %s is not among the enumerated set\n",
-+ attr->defaultValue, attr->name, attr->elem);
-+ ret = 0;
-+ }
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlValidateElementDecl:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @elem: an element definition
-+ *
-+ * Try to validate a single element definition
-+ * basically it does the following checks as described by the
-+ * XML-1.0 recommendation:
-+ * - [ VC: One ID per Element Type ]
-+ * - [ VC: No Duplicate Types ]
-+ * - [ VC: Unique Element Type Declaration ]
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ xmlElementPtr elem) {
-+ int ret = 1;
-+ xmlElementPtr tst;
-+
-+ CHECK_DTD;
-+
-+ if (elem == NULL) return(1);
-+
-+ /* No Duplicate Types */
-+ if (elem->etype == XML_ELEMENT_TYPE_MIXED) {
-+ xmlElementContentPtr cur, next;
-+ const xmlChar *name;
-+
-+ cur = elem->content;
-+ while (cur != NULL) {
-+ if (cur->type != XML_ELEMENT_CONTENT_OR) break;
-+ if (cur->c1 == NULL) break;
-+ if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
-+ name = cur->c1->name;
-+ next = cur->c2;
-+ while (next != NULL) {
-+ if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
-+ if (xmlStrEqual(next->name, name)) {
-+ VERROR(ctxt->userData,
-+ "Definition of %s has duplicate references of %s\n",
-+ elem->name, name);
-+ ret = 0;
-+ }
-+ break;
-+ }
-+ if (next->c1 == NULL) break;
-+ if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
-+ if (xmlStrEqual(next->c1->name, name)) {
-+ VERROR(ctxt->userData,
-+ "Definition of %s has duplicate references of %s\n",
-+ elem->name, name);
-+ ret = 0;
-+ }
-+ next = next->c2;
-+ }
-+ }
-+ cur = cur->c2;
-+ }
-+ }
-+
-+ /* VC: Unique Element Type Declaration */
-+ tst = xmlGetDtdElementDesc(doc->intSubset, elem->name);
-+ if ((tst != NULL ) && (tst != elem)) {
-+ VERROR(ctxt->userData, "Redefinition of element %s\n",
-+ elem->name);
-+ ret = 0;
-+ }
-+ tst = xmlGetDtdElementDesc(doc->extSubset, elem->name);
-+ if ((tst != NULL ) && (tst != elem)) {
-+ VERROR(ctxt->userData, "Redefinition of element %s\n",
-+ elem->name);
-+ ret = 0;
-+ }
-+
-+ /* One ID per Element Type */
-+ if (xmlScanIDAttributeDecl(ctxt, elem) > 1) {
-+ ret = 0;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlValidateOneAttribute:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @elem: an element instance
-+ * @attr: an attribute instance
-+ * @value: the attribute value (without entities processing)
-+ *
-+ * Try to validate a single attribute for an element
-+ * basically it does the following checks as described by the
-+ * XML-1.0 recommendation:
-+ * - [ VC: Attribute Value Type ]
-+ * - [ VC: Fixed Attribute Default ]
-+ * - [ VC: Entity Name ]
-+ * - [ VC: Name Token ]
-+ * - [ VC: ID ]
-+ * - [ VC: IDREF ]
-+ * - [ VC: Entity Name ]
-+ * - [ VC: Notation Attributes ]
-+ *
-+ * The ID/IDREF uniqueness and matching are done separately
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) {
-+ /* xmlElementPtr elemDecl; */
-+ xmlAttributePtr attrDecl = NULL;
-+ int val;
-+ int ret = 1;
-+
-+ CHECK_DTD;
-+ if ((elem == NULL) || (elem->name == NULL)) return(0);
-+ if ((attr == NULL) || (attr->name == NULL)) return(0);
-+
-+ if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
-+ xmlChar qname[500];
-+#ifdef HAVE_SNPRINTF
-+ snprintf((char *) qname, sizeof(qname), "%s:%s",
-+ elem->ns->prefix, elem->name);
-+#else
-+ sprintf((char *) qname, "%s:%s", elem->ns->prefix, elem->name);
-+#endif
-+ qname[sizeof(qname) - 1] = 0;
-+ if (attr->ns != NULL) {
-+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname,
-+ attr->name, attr->ns->prefix);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname,
-+ attr->name, attr->ns->prefix);
-+ } else {
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attr->name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
-+ qname, attr->name);
-+ }
-+ }
-+ if (attrDecl == NULL) {
-+ if (attr->ns != NULL) {
-+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
-+ attr->name, attr->ns->prefix);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
-+ attr->name, attr->ns->prefix);
-+ } else {
-+ attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
-+ elem->name, attr->name);
-+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
-+ attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
-+ elem->name, attr->name);
-+ }
-+ }
-+
-+
-+ /* Validity Constraint: Attribute Value Type */
-+ if (attrDecl == NULL) {
-+ VERROR(ctxt->userData,
-+ "No declaration for attribute %s on element %s\n",
-+ attr->name, elem->name);
-+ return(0);
-+ }
-+ attr->atype = attrDecl->atype;
-+
-+ val = xmlValidateAttributeValue(attrDecl->atype, value);
-+ if (val == 0) {
-+ VERROR(ctxt->userData,
-+ "Syntax of value for attribute %s on %s is not valid\n",
-+ attr->name, elem->name);
-+ ret = 0;
-+ }
-+
-+ /* Validity constraint: Fixed Attribute Default */
-+ if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
-+ if (!xmlStrEqual(value, attrDecl->defaultValue)) {
-+ VERROR(ctxt->userData,
-+ "Value for attribute %s on %s is differnt from default \"%s\"\n",
-+ attr->name, elem->name, attrDecl->defaultValue);
-+ ret = 0;
-+ }
-+ }
-+
-+ /* Validity Constraint: ID uniqueness */
-+ if (attrDecl->atype == XML_ATTRIBUTE_ID) {
-+ if (xmlAddID(ctxt, doc, value, attr) == NULL)
-+ ret = 0;
-+ }
-+
-+ if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
-+ (attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
-+ if (xmlAddRef(ctxt, doc, value, attr) == NULL)
-+ ret = 0;
-+ }
-+
-+ /* Validity Constraint: Notation Attributes */
-+ if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
-+ xmlEnumerationPtr tree = attrDecl->tree;
-+ xmlNotationPtr nota;
-+
-+ /* First check that the given NOTATION was declared */
-+ nota = xmlGetDtdNotationDesc(doc->intSubset, value);
-+ if (nota == NULL)
-+ nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-+
-+ if (nota == NULL) {
-+ VERROR(ctxt->userData,
-+ "Value \"%s\" for attribute %s on %s is not a declared Notation\n",
-+ value, attr->name, elem->name);
-+ ret = 0;
-+ }
-+
-+ /* Second, verify that it's among the list */
-+ while (tree != NULL) {
-+ if (xmlStrEqual(tree->name, value)) break;
-+ tree = tree->next;
-+ }
-+ if (tree == NULL) {
-+ VERROR(ctxt->userData,
-+"Value \"%s\" for attribute %s on %s is not among the enumerated notations\n",
-+ value, attr->name, elem->name);
-+ ret = 0;
-+ }
-+ }
-+
-+ /* Validity Constraint: Enumeration */
-+ if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
-+ xmlEnumerationPtr tree = attrDecl->tree;
-+ while (tree != NULL) {
-+ if (xmlStrEqual(tree->name, value)) break;
-+ tree = tree->next;
-+ }
-+ if (tree == NULL) {
-+ VERROR(ctxt->userData,
-+ "Value \"%s\" for attribute %s on %s is not among the enumerated set\n",
-+ value, attr->name, elem->name);
-+ ret = 0;
-+ }
-+ }
-+
-+ /* Fixed Attribute Default */
-+ if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
-+ (!xmlStrEqual(attrDecl->defaultValue, value))) {
-+ VERROR(ctxt->userData,
-+ "Value for attribute %s on %s must be \"%s\"\n",
-+ attr->name, elem->name, attrDecl->defaultValue);
-+ ret = 0;
-+ }
-+
-+ /* Extra check for the attribute value */
-+ ret &= xmlValidateAttributeValue2(ctxt, doc, attr->name,
-+ attrDecl->atype, value);
-+
-+ return(ret);
-+}
-+
-+/* Find the next XML_ELEMENT_NODE, subject to the content constraints.
-+ * Return -1 if we found something unexpected, or 1 otherwise.
-+ */
-+
-+static int
-+xmlValidateFindNextElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-+ xmlElementContentPtr cont)
-+{
-+ while (*child && (*child)->type != XML_ELEMENT_NODE) {
-+ switch ((*child)->type) {
-+ /*
-+ * If there is an entity declared and it's not empty
-+ * Push the current node on the stack and process with the
-+ * entity content.
-+ */
-+ case XML_ENTITY_REF_NODE:
-+ if (((*child)->children != NULL) &&
-+ ((*child)->children->children != NULL)) {
-+ nodeVPush(ctxt, *child);
-+ *child = (*child)->children->children;
-+ continue;
-+ }
-+ break;
-+
-+ /* These things are ignored (skipped) during validation. */
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ break;
-+
-+ case XML_TEXT_NODE:
-+ if (xmlIsBlankNode(*child)
-+ && (cont->type == XML_ELEMENT_CONTENT_ELEMENT
-+ || cont->type == XML_ELEMENT_CONTENT_SEQ
-+ || cont->type == XML_ELEMENT_CONTENT_OR))
-+ break;
-+ return -1;
-+
-+ default:
-+ return -1;
-+ }
-+ *child = (*child)->next;
-+ }
-+
-+ return 1;
-+}
-+
-+int xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-+ xmlElementContentPtr cont);
-+
-+/**
-+ * xmlValidateElementTypeExpr:
-+ * @ctxt: the validation context
-+ * @child: pointer to the child list
-+ * @cont: pointer to the content declaration
-+ *
-+ * Try to validate the content of an element of type element
-+ * but don't handle the occurence factor
-+ *
-+ * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
-+ * also update child value in-situ.
-+ */
-+
-+int
-+xmlValidateElementTypeExpr(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-+ xmlElementContentPtr cont) {
-+ xmlNodePtr cur;
-+ int ret = 1;
-+
-+ if (cont == NULL) return(-1);
-+ DEBUG_VALID_STATE(*child, cont)
-+ ret = xmlValidateFindNextElement(ctxt, child, cont);
-+ if (ret < 0)
-+ return(-1);
-+ DEBUG_VALID_STATE(*child, cont)
-+ switch (cont->type) {
-+ case XML_ELEMENT_CONTENT_PCDATA:
-+ if (*child == NULL) return(0);
-+ if ((*child)->type == XML_TEXT_NODE) return(1);
-+ return(0);
-+ case XML_ELEMENT_CONTENT_ELEMENT:
-+ if (*child == NULL) return(0);
-+ ret = (xmlStrEqual((*child)->name, cont->name));
-+ if (ret == 1) {
-+ while ((*child)->next == NULL) {
-+ if (((*child)->parent != NULL) &&
-+ ((*child)->parent->type == XML_ENTITY_DECL)) {
-+ *child = nodeVPop(ctxt);
-+ } else
-+ break;
-+ }
-+ *child = (*child)->next;
-+ }
-+ return(ret);
-+ case XML_ELEMENT_CONTENT_OR:
-+ cur = *child;
-+ ret = xmlValidateElementTypeElement(ctxt, child, cont->c1);
-+ if (ret == -1) return(-1);
-+ if (ret == 1) {
-+ return(1);
-+ }
-+ /* rollback and retry the other path */
-+ *child = cur;
-+ ret = xmlValidateElementTypeElement(ctxt, child, cont->c2);
-+ if (ret == -1) return(-1);
-+ if (ret == 0) {
-+ *child = cur;
-+ return(0);
-+ }
-+ return(1);
-+ case XML_ELEMENT_CONTENT_SEQ:
-+ cur = *child;
-+ ret = xmlValidateElementTypeElement(ctxt, child, cont->c1);
-+ if (ret == -1) return(-1);
-+ if (ret == 0) {
-+ *child = cur;
-+ return(0);
-+ }
-+ ret = xmlValidateElementTypeElement(ctxt, child, cont->c2);
-+ if (ret == -1) return(-1);
-+ if (ret == 0) {
-+ *child = cur;
-+ return(0);
-+ }
-+ return(1);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlValidateElementTypeElement:
-+ * @ctxt: the validation context
-+ * @child: pointer to the child list
-+ * @cont: pointer to the content declaration
-+ *
-+ * Try to validate the content of an element of type element
-+ * yeah, Yet Another Regexp Implementation, and recursive
-+ *
-+ * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
-+ * also update child and content values in-situ.
-+ */
-+
-+int
-+xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-+ xmlElementContentPtr cont) {
-+ xmlNodePtr cur;
-+ int ret;
-+
-+ if (cont == NULL) return(-1);
-+
-+ DEBUG_VALID_STATE(*child, cont)
-+ ret = xmlValidateFindNextElement(ctxt, child, cont);
-+ if (ret < 0)
-+ return(-1);
-+ DEBUG_VALID_STATE(*child, cont)
-+ cur = *child;
-+ ret = xmlValidateElementTypeExpr(ctxt, child, cont);
-+ if (ret == -1) return(-1);
-+ switch (cont->ocur) {
-+ case XML_ELEMENT_CONTENT_ONCE:
-+ if (ret == 1) {
-+ /* skip ignorable elems */
-+ while ((*child != NULL) &&
-+ ((*child)->type == XML_PI_NODE
-+ || (*child)->type == XML_COMMENT_NODE
-+ || (*child)->type == XML_XINCLUDE_START
-+ || (*child)->type == XML_XINCLUDE_END)) {
-+ while ((*child)->next == NULL) {
-+ if (((*child)->parent != NULL) &&
-+ ((*child)->parent->type == XML_ENTITY_REF_NODE)) {
-+ *child = (*child)->parent;
-+ } else
-+ break;
-+ }
-+ *child = (*child)->next;
-+ }
-+ return(1);
-+ }
-+ *child = cur;
-+ return(0);
-+ case XML_ELEMENT_CONTENT_OPT:
-+ if (ret == 0) {
-+ *child = cur;
-+ return(1);
-+ }
-+ break;
-+ case XML_ELEMENT_CONTENT_MULT:
-+ if (ret == 0) {
-+ *child = cur;
-+ break;
-+ }
-+ /* no break on purpose */
-+ case XML_ELEMENT_CONTENT_PLUS:
-+ if (ret == 0) {
-+ *child = cur;
-+ return(0);
-+ }
-+ if (ret == -1) return(-1);
-+ cur = *child;
-+ do {
-+ if (*child == NULL)
-+ break; /* while */
-+ if ((*child)->type == XML_TEXT_NODE
-+ && xmlIsBlankNode(*child)) {
-+ *child = (*child)->next;
-+ continue;
-+ }
-+ ret = xmlValidateElementTypeExpr(ctxt, child, cont);
-+ if (ret == 1)
-+ cur = *child;
-+ } while (ret == 1);
-+ if (ret == -1) return(-1);
-+ *child = cur;
-+ break;
-+ }
-+
-+ return xmlValidateFindNextElement(ctxt, child, cont);
-+}
-+
-+/**
-+ * xmlSprintfElementChilds:
-+ * @buf: an output buffer
-+ * @content: An element
-+ * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
-+ *
-+ * This will dump the list of childs to the buffer
-+ * Intended just for the debug routine
-+ */
-+void
-+xmlSprintfElementChilds(char *buf, xmlNodePtr node, int glob) {
-+ xmlNodePtr cur;
-+
-+ if (node == NULL) return;
-+ if (glob) strcat(buf, "(");
-+ cur = node->children;
-+ while (cur != NULL) {
-+ switch (cur->type) {
-+ case XML_ELEMENT_NODE:
-+ strcat(buf, (char *) cur->name);
-+ if (cur->next != NULL)
-+ strcat(buf, " ");
-+ break;
-+ case XML_TEXT_NODE:
-+ if (xmlIsBlankNode(cur))
-+ break;
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ strcat(buf, "CDATA");
-+ if (cur->next != NULL)
-+ strcat(buf, " ");
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ case XML_DOCUMENT_NODE:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_NAMESPACE_DECL:
-+ strcat(buf, "???");
-+ if (cur->next != NULL)
-+ strcat(buf, " ");
-+ break;
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_DTD_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ break;
-+ }
-+ cur = cur->next;
-+ }
-+ if (glob) strcat(buf, ")");
-+}
-+
-+
-+/**
-+ * xmlValidateOneElement:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @elem: an element instance
-+ *
-+ * Try to validate a single element and it's attributes,
-+ * basically it does the following checks as described by the
-+ * XML-1.0 recommendation:
-+ * - [ VC: Element Valid ]
-+ * - [ VC: Required Attribute ]
-+ * Then call xmlValidateOneAttribute() for each attribute present.
-+ *
-+ * The ID/IDREF checkings are done separately
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-+ xmlNodePtr elem) {
-+ xmlElementPtr elemDecl = NULL;
-+ xmlElementContentPtr cont;
-+ xmlAttributePtr attr;
-+ xmlNodePtr child;
-+ int ret = 1;
-+ const xmlChar *name;
-+
-+ CHECK_DTD;
-+
-+ if (elem == NULL) return(0);
-+ if (elem->type == XML_TEXT_NODE) {
-+ }
-+ switch (elem->type) {
-+ case XML_ATTRIBUTE_NODE:
-+ VERROR(ctxt->userData,
-+ "Attribute element not expected here\n");
-+ return(0);
-+ case XML_TEXT_NODE:
-+ if (elem->children != NULL) {
-+ VERROR(ctxt->userData, "Text element has childs !\n");
-+ return(0);
-+ }
-+ if (elem->properties != NULL) {
-+ VERROR(ctxt->userData, "Text element has attributes !\n");
-+ return(0);
-+ }
-+ if (elem->ns != NULL) {
-+ VERROR(ctxt->userData, "Text element has namespace !\n");
-+ return(0);
-+ }
-+ if (elem->nsDef != NULL) {
-+ VERROR(ctxt->userData,
-+ "Text element carries namespace definitions !\n");
-+ return(0);
-+ }
-+ if (elem->content == NULL) {
-+ VERROR(ctxt->userData,
-+ "Text element has no content !\n");
-+ return(0);
-+ }
-+ return(1);
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ return(1);
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ return(1);
-+ case XML_ENTITY_NODE:
-+ VERROR(ctxt->userData,
-+ "Entity element not expected here\n");
-+ return(0);
-+ case XML_NOTATION_NODE:
-+ VERROR(ctxt->userData,
-+ "Notation element not expected here\n");
-+ return(0);
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ VERROR(ctxt->userData,
-+ "Document element not expected here\n");
-+ return(0);
-+ case XML_HTML_DOCUMENT_NODE:
-+ VERROR(ctxt->userData,
-+ "\n");
-+ return(0);
-+ case XML_ELEMENT_NODE:
-+ break;
-+ default:
-+ VERROR(ctxt->userData,
-+ "unknown element type %d\n", elem->type);
-+ return(0);
-+ }
-+ if (elem->name == NULL) return(0);
-+
-+ /*
-+ * Fetch the declaration for the qualified name
-+ */
-+ if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
-+ elemDecl = xmlGetDtdQElementDesc(doc->intSubset,
-+ elem->name, elem->ns->prefix);
-+ if ((elemDecl == NULL) && (doc->extSubset != NULL))
-+ elemDecl = xmlGetDtdQElementDesc(doc->extSubset,
-+ elem->name, elem->ns->prefix);
-+ }
-+
-+ /*
-+ * Fetch the declaration for the non qualified name
-+ */
-+ if (elemDecl == NULL) {
-+ elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
-+ if ((elemDecl == NULL) && (doc->extSubset != NULL))
-+ elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
-+ }
-+ if (elemDecl == NULL) {
-+ VERROR(ctxt->userData, "No declaration for element %s\n",
-+ elem->name);
-+ return(0);
-+ }
-+
-+ /* Check taht the element content matches the definition */
-+ switch (elemDecl->etype) {
-+ case XML_ELEMENT_TYPE_EMPTY:
-+ if (elem->children != NULL) {
-+ VERROR(ctxt->userData,
-+ "Element %s was declared EMPTY this one has content\n",
-+ elem->name);
-+ ret = 0;
-+ }
-+ break;
-+ case XML_ELEMENT_TYPE_ANY:
-+ /* I don't think anything is required then */
-+ break;
-+ case XML_ELEMENT_TYPE_MIXED:
-+ /* Hum, this start to get messy */
-+ child = elem->children;
-+ while (child != NULL) {
-+ if (child->type == XML_ELEMENT_NODE) {
-+ name = child->name;
-+ if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
-+ xmlChar qname[500];
-+#ifdef HAVE_SNPRINTF
-+ snprintf((char *) qname, sizeof(qname), "%s:%s",
-+ child->ns->prefix, child->name);
-+#else
-+ sprintf((char *) qname, "%s:%s",
-+ child->ns->prefix, child->name);
-+#endif
-+ qname[sizeof(qname) - 1] = 0;
-+ cont = elemDecl->content;
-+ while (cont != NULL) {
-+ if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
-+ if (xmlStrEqual(cont->name, qname)) break;
-+ } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
-+ (cont->c1 != NULL) &&
-+ (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
-+ if (xmlStrEqual(cont->c1->name, qname)) break;
-+ } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
-+ (cont->c1 == NULL) ||
-+ (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
-+ /* Internal error !!! */
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Internal: MIXED struct bad\n");
-+ break;
-+ }
-+ cont = cont->c2;
-+ }
-+ if (cont != NULL)
-+ goto child_ok;
-+ }
-+ cont = elemDecl->content;
-+ while (cont != NULL) {
-+ if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
-+ if (xmlStrEqual(cont->name, name)) break;
-+ } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
-+ (cont->c1 != NULL) &&
-+ (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)) {
-+ if (xmlStrEqual(cont->c1->name, name)) break;
-+ } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
-+ (cont->c1 == NULL) ||
-+ (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)) {
-+ /* Internal error !!! */
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Internal: MIXED struct bad\n");
-+ break;
-+ }
-+ cont = cont->c2;
-+ }
-+ if (cont == NULL) {
-+ VERROR(ctxt->userData,
-+ "Element %s is not declared in %s list of possible childs\n",
-+ name, elem->name);
-+ ret = 0;
-+ }
-+ }
-+child_ok:
-+ child = child->next;
-+ }
-+ break;
-+ case XML_ELEMENT_TYPE_ELEMENT:
-+ child = elem->children;
-+ cont = elemDecl->content;
-+ ret = xmlValidateElementTypeElement(ctxt, &child, cont);
-+ while ((child != NULL) && (child->type == XML_TEXT_NODE) &&
-+ (xmlIsBlankNode(child))) {
-+ child = child->next;
-+ continue;
-+ }
-+ if ((ret == 0) || (child != NULL)) {
-+ char expr[1000];
-+ char list[2000];
-+
-+ expr[0] = 0;
-+ xmlSprintfElementContent(expr, cont, 1);
-+ list[0] = 0;
-+ xmlSprintfElementChilds(list, elem, 1);
-+
-+ VERROR(ctxt->userData,
-+ "Element %s content doesn't follow the Dtd\nExpecting %s, got %s\n",
-+ elem->name, expr, list);
-+ ret = 0;
-+ }
-+ break;
-+ }
-+
-+ /* [ VC: Required Attribute ] */
-+ attr = elemDecl->attributes;
-+ while (attr != NULL) {
-+ if (attr->def == XML_ATTRIBUTE_REQUIRED) {
-+ xmlAttrPtr attrib;
-+ int qualified = -1;
-+
-+ attrib = elem->properties;
-+ while (attrib != NULL) {
-+ if (xmlStrEqual(attrib->name, attr->name)) {
-+ if (attr->prefix != NULL) {
-+ xmlNsPtr nameSpace = attrib->ns;
-+
-+ if (nameSpace == NULL)
-+ nameSpace = elem->ns;
-+ /*
-+ * qualified names handling is problematic, having a
-+ * different prefix should be possible but DTDs don't
-+ * allow to define the URI instead of the prefix :-(
-+ */
-+ if (nameSpace == NULL) {
-+ if (qualified < 0)
-+ qualified = 0;
-+ } else if (!xmlStrEqual(nameSpace->prefix, attr->prefix)) {
-+ if (qualified < 1)
-+ qualified = 1;
-+ } else
-+ goto found;
-+ } else {
-+ /*
-+ * We should allow applications to define namespaces
-+ * for their application even if the DTD doesn't
-+ * carry one, otherwise, basically we would always
-+ * break.
-+ */
-+ goto found;
-+ }
-+ }
-+ attrib = attrib->next;
-+ }
-+ if (qualified == -1) {
-+ if (attr->prefix == NULL) {
-+ VERROR(ctxt->userData,
-+ "Element %s doesn't carry attribute %s\n",
-+ elem->name, attr->name);
-+ ret = 0;
-+ } else {
-+ VERROR(ctxt->userData,
-+ "Element %s doesn't carry attribute %s:%s\n",
-+ elem->name, attr->prefix,attr->name);
-+ ret = 0;
-+ }
-+ } else if (qualified == 0) {
-+ VWARNING(ctxt->userData,
-+ "Element %s required attribute %s:%s has no prefix\n",
-+ elem->name, attr->prefix,attr->name);
-+ } else if (qualified == 1) {
-+ VWARNING(ctxt->userData,
-+ "Element %s required attribute %s:%s has different prefix\n",
-+ elem->name, attr->prefix,attr->name);
-+ }
-+ }
-+found:
-+ attr = attr->nexth;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlValidateRoot:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ *
-+ * Try to validate a the root element
-+ * basically it does the following check as described by the
-+ * XML-1.0 recommendation:
-+ * - [ VC: Root Element Type ]
-+ * it doesn't try to recurse or apply other check to the element
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-+ xmlNodePtr root;
-+ if (doc == NULL) return(0);
-+
-+ root = xmlDocGetRootElement(doc);
-+ if ((root == NULL) || (root->name == NULL)) {
-+ VERROR(ctxt->userData, "Not valid: no root element\n");
-+ return(0);
-+ }
-+
-+ /*
-+ * When doing post validation against a separate DTD, those may
-+ * no internal subset has been generated
-+ */
-+ if ((doc->intSubset != NULL) &&
-+ (doc->intSubset->name != NULL)) {
-+ /*
-+ * Check first the document root against the NQName
-+ */
-+ if (!xmlStrEqual(doc->intSubset->name, root->name)) {
-+ if ((root->ns != NULL) && (root->ns->prefix != NULL)) {
-+ xmlChar qname[500];
-+#ifdef HAVE_SNPRINTF
-+ snprintf((char *) qname, sizeof(qname), "%s:%s",
-+ root->ns->prefix, root->name);
-+#else
-+ sprintf((char *) qname, "%s:%s", root->ns->prefix, root->name);
-+#endif
-+ qname[sizeof(qname) - 1] = 0;
-+ if (xmlStrEqual(doc->intSubset->name, qname))
-+ goto name_ok;
-+ }
-+ if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) &&
-+ (xmlStrEqual(root->name, BAD_CAST "html")))
-+ goto name_ok;
-+ VERROR(ctxt->userData,
-+ "Not valid: root and DtD name do not match '%s' and '%s'\n",
-+ root->name, doc->intSubset->name);
-+ return(0);
-+
-+ }
-+ }
-+name_ok:
-+ return(1);
-+}
-+
-+
-+/**
-+ * xmlValidateElement:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @elem: an element instance
-+ *
-+ * Try to validate the subtree under an element
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
-+ xmlNodePtr child;
-+ xmlAttrPtr attr;
-+ xmlChar *value;
-+ int ret = 1;
-+
-+ if (elem == NULL) return(0);
-+
-+ /*
-+ * XInclude elements were added after parsing in the infoset,
-+ * they don't really mean anything validation wise.
-+ */
-+ if ((elem->type == XML_XINCLUDE_START) ||
-+ (elem->type == XML_XINCLUDE_END))
-+ return(1);
-+
-+ CHECK_DTD;
-+
-+ ret &= xmlValidateOneElement(ctxt, doc, elem);
-+ attr = elem->properties;
-+ while(attr != NULL) {
-+ value = xmlNodeListGetString(doc, attr->children, 0);
-+ ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
-+ if (value != NULL)
-+ xmlFree(value);
-+ attr= attr->next;
-+ }
-+ child = elem->children;
-+ while (child != NULL) {
-+ ret &= xmlValidateElement(ctxt, doc, child);
-+ child = child->next;
-+ }
-+
-+ return(ret);
-+}
-+
-+
-+void
-+xmlValidateCheckRefCallback(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
-+ const xmlChar *name) {
-+ xmlAttrPtr id;
-+ xmlAttrPtr attr;
-+
-+ if (ref == NULL)
-+ return;
-+ attr = ref->attr;
-+ if (attr == NULL)
-+ return;
-+ if (attr->atype == XML_ATTRIBUTE_IDREF) {
-+ id = xmlGetID(ctxt->doc, name);
-+ if (id == NULL) {
-+ VERROR(ctxt->userData,
-+ "IDREF attribute %s reference an unknown ID \"%s\"\n",
-+ attr->name, name);
-+ ctxt->valid = 0;
-+ }
-+ } else if (attr->atype == XML_ATTRIBUTE_IDREFS) {
-+ xmlChar *dup, *str = NULL, *cur, save;
-+
-+ dup = xmlStrdup(name);
-+ if (dup == NULL) {
-+ ctxt->valid = 0;
-+ return;
-+ }
-+ cur = dup;
-+ while (*cur != 0) {
-+ str = cur;
-+ while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
-+ save = *cur;
-+ *cur = 0;
-+ id = xmlGetID(ctxt->doc, str);
-+ if (id == NULL) {
-+ VERROR(ctxt->userData,
-+ "IDREFS attribute %s reference an unknown ID \"%s\"\n",
-+ attr->name, str);
-+ ctxt->valid = 0;
-+ }
-+ if (save == 0)
-+ break;
-+ *cur = save;
-+ while (IS_BLANK(*cur)) cur++;
-+ }
-+ xmlFree(dup);
-+ }
-+}
-+
-+/**
-+ * xmlValidateDocumentFinal:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ *
-+ * Does the final step for the document validation once all the
-+ * incremental validation steps have been completed
-+ *
-+ * basically it does the following checks described by the XML Rec
-+ *
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-+ xmlRefTablePtr table;
-+
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlValidateDocumentFinal: doc == NULL\n");
-+ return(0);
-+ }
-+
-+ /*
-+ * Check all the NOTATION/NOTATIONS attributes
-+ */
-+ /*
-+ * Check all the ENTITY/ENTITIES attributes definition for validity
-+ */
-+ /*
-+ * Check all the IDREF/IDREFS attributes definition for validity
-+ */
-+ table = (xmlRefTablePtr) doc->refs;
-+ ctxt->doc = doc;
-+ ctxt->valid = 1;
-+ xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
-+ return(ctxt->valid);
-+}
-+
-+/**
-+ * xmlValidateDtd:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ * @dtd: a dtd instance
-+ *
-+ * Try to validate the document against the dtd instance
-+ *
-+ * basically it does check all the definitions in the DtD.
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
-+ int ret;
-+ xmlDtdPtr oldExt;
-+ xmlNodePtr root;
-+
-+ if (dtd == NULL) return(0);
-+ if (doc == NULL) return(0);
-+ oldExt = doc->extSubset;
-+ doc->extSubset = dtd;
-+ ret = xmlValidateRoot(ctxt, doc);
-+ if (ret == 0) {
-+ doc->extSubset = oldExt;
-+ return(ret);
-+ }
-+ if (doc->ids != NULL) {
-+ xmlFreeIDTable(doc->ids);
-+ doc->ids = NULL;
-+ }
-+ if (doc->refs != NULL) {
-+ xmlFreeRefTable(doc->refs);
-+ doc->refs = NULL;
-+ }
-+ root = xmlDocGetRootElement(doc);
-+ ret = xmlValidateElement(ctxt, doc, root);
-+ ret &= xmlValidateDocumentFinal(ctxt, doc);
-+ doc->extSubset = oldExt;
-+ return(ret);
-+}
-+
-+void
-+xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
-+ const xmlChar *name) {
-+ if (cur == NULL)
-+ return;
-+ switch (cur->atype) {
-+ case XML_ATTRIBUTE_CDATA:
-+ case XML_ATTRIBUTE_ID:
-+ case XML_ATTRIBUTE_IDREF :
-+ case XML_ATTRIBUTE_IDREFS:
-+ case XML_ATTRIBUTE_NMTOKEN:
-+ case XML_ATTRIBUTE_NMTOKENS:
-+ case XML_ATTRIBUTE_ENUMERATION:
-+ break;
-+ case XML_ATTRIBUTE_ENTITY:
-+ case XML_ATTRIBUTE_ENTITIES:
-+ case XML_ATTRIBUTE_NOTATION:
-+ if (cur->defaultValue != NULL) {
-+ ctxt->valid &= xmlValidateAttributeValue2(ctxt, ctxt->doc,
-+ cur->name, cur->atype, cur->defaultValue);
-+ }
-+ if (cur->tree != NULL) {
-+ xmlEnumerationPtr tree = cur->tree;
-+ while (tree != NULL) {
-+ ctxt->valid &= xmlValidateAttributeValue2(ctxt, ctxt->doc,
-+ cur->name, cur->atype, tree->name);
-+ tree = tree->next;
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlValidateDtdFinal:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ *
-+ * Does the final step for the dtds validation once all the
-+ * subsets have been parsed
-+ *
-+ * basically it does the following checks described by the XML Rec
-+ * - check that ENTITY and ENTITIES type attributes default or
-+ * possible values matches one of the defined entities.
-+ * - check that NOTATION type attributes default or
-+ * possible values matches one of the defined notations.
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-+ int ret = 1;
-+ xmlDtdPtr dtd;
-+ xmlAttributeTablePtr table;
-+
-+ if (doc == NULL) return(0);
-+ if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
-+ return(0);
-+ ctxt->doc = doc;
-+ ctxt->valid = ret;
-+ dtd = doc->intSubset;
-+ if ((dtd != NULL) && (dtd->attributes != NULL)) {
-+ table = (xmlAttributeTablePtr) dtd->attributes;
-+ xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
-+ }
-+ dtd = doc->extSubset;
-+ if ((dtd != NULL) && (dtd->attributes != NULL)) {
-+ table = (xmlAttributeTablePtr) dtd->attributes;
-+ xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
-+ }
-+ return(ctxt->valid);
-+}
-+
-+/**
-+ * xmlValidateDocument:
-+ * @ctxt: the validation context
-+ * @doc: a document instance
-+ *
-+ * Try to validate the document instance
-+ *
-+ * basically it does the all the checks described by the XML Rec
-+ * i.e. validates the internal and external subset (if present)
-+ * and validate the document tree.
-+ *
-+ * returns 1 if valid or 0 otherwise
-+ */
-+
-+int
-+xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-+ int ret;
-+ xmlNodePtr root;
-+
-+ if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
-+ return(0);
-+ if ((doc->intSubset != NULL) && ((doc->intSubset->SystemID != NULL) ||
-+ (doc->intSubset->ExternalID != NULL)) && (doc->extSubset == NULL)) {
-+ doc->extSubset = xmlParseDTD(doc->intSubset->ExternalID,
-+ doc->intSubset->SystemID);
-+ if (doc->extSubset == NULL) {
-+ if (doc->intSubset->SystemID != NULL) {
-+ VERROR(ctxt->userData,
-+ "Could not load the external subset \"%s\"\n",
-+ doc->intSubset->SystemID);
-+ } else {
-+ VERROR(ctxt->userData,
-+ "Could not load the external subset \"%s\"\n",
-+ doc->intSubset->ExternalID);
-+ }
-+ return(0);
-+ }
-+ }
-+
-+ if (doc->ids != NULL) {
-+ xmlFreeIDTable(doc->ids);
-+ doc->ids = NULL;
-+ }
-+ if (doc->refs != NULL) {
-+ xmlFreeRefTable(doc->refs);
-+ doc->refs = NULL;
-+ }
-+ ret = xmlValidateDtdFinal(ctxt, doc);
-+ if (!xmlValidateRoot(ctxt, doc)) return(0);
-+
-+ root = xmlDocGetRootElement(doc);
-+ ret &= xmlValidateElement(ctxt, doc, root);
-+ ret &= xmlValidateDocumentFinal(ctxt, doc);
-+ return(ret);
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Routines for dynamic validation editing *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlValidGetPotentialChildren:
-+ * @ctree: an element content tree
-+ * @list: an array to store the list of child names
-+ * @len: a pointer to the number of element in the list
-+ * @max: the size of the array
-+ *
-+ * Build/extend a list of potential children allowed by the content tree
-+ *
-+ * returns the number of element in the list, or -1 in case of error.
-+ */
-+
-+int
-+xmlValidGetPotentialChildren(xmlElementContent *ctree, const xmlChar **list,
-+ int *len, int max) {
-+ int i;
-+
-+ if ((ctree == NULL) || (list == NULL) || (len == NULL))
-+ return(-1);
-+ if (*len >= max) return(*len);
-+
-+ switch (ctree->type) {
-+ case XML_ELEMENT_CONTENT_PCDATA:
-+ for (i = 0; i < *len;i++)
-+ if (xmlStrEqual(BAD_CAST "#PCDATA", list[i])) return(*len);
-+ list[(*len)++] = BAD_CAST "#PCDATA";
-+ break;
-+ case XML_ELEMENT_CONTENT_ELEMENT:
-+ for (i = 0; i < *len;i++)
-+ if (xmlStrEqual(ctree->name, list[i])) return(*len);
-+ list[(*len)++] = ctree->name;
-+ break;
-+ case XML_ELEMENT_CONTENT_SEQ:
-+ xmlValidGetPotentialChildren(ctree->c1, list, len, max);
-+ xmlValidGetPotentialChildren(ctree->c2, list, len, max);
-+ break;
-+ case XML_ELEMENT_CONTENT_OR:
-+ xmlValidGetPotentialChildren(ctree->c1, list, len, max);
-+ xmlValidGetPotentialChildren(ctree->c2, list, len, max);
-+ break;
-+ }
-+
-+ return(*len);
-+}
-+
-+/**
-+ * xmlValidGetValidElements:
-+ * @prev: an element to insert after
-+ * @next: an element to insert next
-+ * @list: an array to store the list of child names
-+ * @max: the size of the array
-+ *
-+ * This function returns the list of authorized children to insert
-+ * within an existing tree while respecting the validity constraints
-+ * forced by the Dtd. The insertion point is defined using @prev and
-+ * @next in the following ways:
-+ * to insert before 'node': xmlValidGetValidElements(node->prev, node, ...
-+ * to insert next 'node': xmlValidGetValidElements(node, node->next, ...
-+ * to replace 'node': xmlValidGetValidElements(node->prev, node->next, ...
-+ * to prepend a child to 'node': xmlValidGetValidElements(NULL, node->childs,
-+ * to append a child to 'node': xmlValidGetValidElements(node->last, NULL, ...
-+ *
-+ * pointers to the element names are inserted at the beginning of the array
-+ * and do not need to be freed.
-+ *
-+ * returns the number of element in the list, or -1 in case of error. If
-+ * the function returns the value @max the caller is invited to grow the
-+ * receiving array and retry.
-+ */
-+
-+int
-+xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **list,
-+ int max) {
-+ int nb_valid_elements = 0;
-+ const xmlChar *elements[256];
-+ int nb_elements = 0, i;
-+
-+ xmlNode *ref_node;
-+ xmlNode *parent;
-+ xmlNode *test_node;
-+
-+ xmlNode *prev_next;
-+ xmlNode *next_prev;
-+ xmlNode *parent_childs;
-+ xmlNode *parent_last;
-+
-+ xmlElement *element_desc;
-+
-+ if (prev == NULL && next == NULL)
-+ return(-1);
-+
-+ if (list == NULL) return(-1);
-+ if (max <= 0) return(-1);
-+
-+ nb_valid_elements = 0;
-+ ref_node = prev ? prev : next;
-+ parent = ref_node->parent;
-+
-+ /*
-+ * Retrieves the parent element declaration
-+ */
-+ element_desc = xmlGetDtdElementDesc(parent->doc->intSubset,
-+ parent->name);
-+ if ((element_desc == NULL) && (parent->doc->extSubset != NULL))
-+ element_desc = xmlGetDtdElementDesc(parent->doc->extSubset,
-+ parent->name);
-+ if (element_desc == NULL) return(-1);
-+
-+ /*
-+ * Do a backup of the current tree structure
-+ */
-+ prev_next = prev ? prev->next : NULL;
-+ next_prev = next ? next->prev : NULL;
-+ parent_childs = parent->children;
-+ parent_last = parent->last;
-+
-+ /*
-+ * Creates a dummy node and insert it into the tree
-+ */
-+ test_node = xmlNewNode (NULL, BAD_CAST "<!dummy?>");
-+ test_node->doc = ref_node->doc;
-+ test_node->parent = parent;
-+ test_node->prev = prev;
-+ test_node->next = next;
-+
-+ if (prev) prev->next = test_node;
-+ else parent->children = test_node;
-+
-+ if (next) next->prev = test_node;
-+ else parent->last = test_node;
-+
-+ /*
-+ * Insert each potential child node and check if the parent is
-+ * still valid
-+ */
-+ nb_elements = xmlValidGetPotentialChildren(element_desc->content,
-+ elements, &nb_elements, 256);
-+
-+ for (i = 0;i < nb_elements;i++) {
-+ test_node->name = elements[i];
-+ if (xmlValidateOneElement(NULL, parent->doc, parent)) {
-+ int j;
-+
-+ for (j = 0; j < nb_valid_elements;j++)
-+ if (xmlStrEqual(elements[i], list[j])) break;
-+ list[nb_valid_elements++] = elements[i];
-+ if (nb_valid_elements >= max) break;
-+ }
-+ }
-+
-+ /*
-+ * Restore the tree structure
-+ */
-+ if (prev) prev->next = prev_next;
-+ if (next) next->prev = next_prev;
-+ parent->children = parent_childs;
-+ parent->last = parent_last;
-+
-+ return(nb_valid_elements);
-+}
-diff -Nru libxml2-2.3.0/libxml/valid.h libxml2-2.3.0.new/libxml/valid.h
---- libxml2-2.3.0/libxml/valid.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/valid.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,236 @@
-+/*
-+ * valid.h : interface to the DTD handling and the validity checking
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+
-+#ifndef __XML_VALID_H__
-+#define __XML_VALID_H__
-+
-+#include <libxml/tree.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/**
-+ * an xmlValidCtxt is used for error reporting when validating
-+ */
-+
-+typedef void (*xmlValidityErrorFunc) (void *ctx, const char *msg, ...);
-+typedef void (*xmlValidityWarningFunc) (void *ctx, const char *msg, ...);
-+
-+typedef struct _xmlValidCtxt xmlValidCtxt;
-+typedef xmlValidCtxt *xmlValidCtxtPtr;
-+struct _xmlValidCtxt {
-+ void *userData; /* user specific data block */
-+ xmlValidityErrorFunc error; /* the callback in case of errors */
-+ xmlValidityWarningFunc warning; /* the callback in case of warning */
-+
-+ /* Node analysis stack used when validating within entities */
-+ xmlNodePtr node; /* Current parsed Node */
-+ int nodeNr; /* Depth of the parsing stack */
-+ int nodeMax; /* Max depth of the parsing stack */
-+ xmlNodePtr *nodeTab; /* array of nodes */
-+
-+ int finishDtd; /* finished validating the Dtd ? */
-+ xmlDocPtr doc; /* the document */
-+ int valid; /* temporary validity check result */
-+};
-+
-+/*
-+ * ALl notation declarations are stored in a table
-+ * there is one table per DTD
-+ */
-+
-+typedef struct _xmlHashTable xmlNotationTable;
-+typedef xmlNotationTable *xmlNotationTablePtr;
-+
-+/*
-+ * ALl element declarations are stored in a table
-+ * there is one table per DTD
-+ */
-+
-+typedef struct _xmlHashTable xmlElementTable;
-+typedef xmlElementTable *xmlElementTablePtr;
-+
-+/*
-+ * ALl attribute declarations are stored in a table
-+ * there is one table per DTD
-+ */
-+
-+typedef struct _xmlHashTable xmlAttributeTable;
-+typedef xmlAttributeTable *xmlAttributeTablePtr;
-+
-+/*
-+ * ALl IDs attributes are stored in a table
-+ * there is one table per document
-+ */
-+
-+typedef struct _xmlHashTable xmlIDTable;
-+typedef xmlIDTable *xmlIDTablePtr;
-+
-+/*
-+ * ALl Refs attributes are stored in a table
-+ * there is one table per document
-+ */
-+
-+typedef struct _xmlHashTable xmlRefTable;
-+typedef xmlRefTable *xmlRefTablePtr;
-+
-+/* helper */
-+xmlChar * xmlSplitQName2 (const xmlChar *name,
-+ xmlChar **prefix);
-+
-+/* Notation */
-+xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
-+ xmlDtdPtr dtd,
-+ const xmlChar *name,
-+ const xmlChar *PublicID,
-+ const xmlChar *SystemID);
-+xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table);
-+void xmlFreeNotationTable(xmlNotationTablePtr table);
-+void xmlDumpNotationDecl (xmlBufferPtr buf,
-+ xmlNotationPtr nota);
-+void xmlDumpNotationTable(xmlBufferPtr buf,
-+ xmlNotationTablePtr table);
-+
-+/* Element Content */
-+xmlElementContentPtr xmlNewElementContent (xmlChar *name,
-+ xmlElementContentType type);
-+xmlElementContentPtr xmlCopyElementContent(xmlElementContentPtr content);
-+void xmlFreeElementContent(xmlElementContentPtr cur);
-+void xmlSprintfElementContent(char *buf,
-+ xmlElementContentPtr content,
-+ int glob);
-+
-+/* Element */
-+xmlElementPtr xmlAddElementDecl (xmlValidCtxtPtr ctxt,
-+ xmlDtdPtr dtd,
-+ const xmlChar *name,
-+ xmlElementTypeVal type,
-+ xmlElementContentPtr content);
-+xmlElementTablePtr xmlCopyElementTable (xmlElementTablePtr table);
-+void xmlFreeElementTable (xmlElementTablePtr table);
-+void xmlDumpElementTable (xmlBufferPtr buf,
-+ xmlElementTablePtr table);
-+void xmlDumpElementDecl (xmlBufferPtr buf,
-+ xmlElementPtr elem);
-+
-+/* Enumeration */
-+xmlEnumerationPtr xmlCreateEnumeration (xmlChar *name);
-+void xmlFreeEnumeration (xmlEnumerationPtr cur);
-+xmlEnumerationPtr xmlCopyEnumeration (xmlEnumerationPtr cur);
-+
-+/* Attribute */
-+xmlAttributePtr xmlAddAttributeDecl (xmlValidCtxtPtr ctxt,
-+ xmlDtdPtr dtd,
-+ const xmlChar *elem,
-+ const xmlChar *name,
-+ const xmlChar *ns,
-+ xmlAttributeType type,
-+ xmlAttributeDefault def,
-+ const xmlChar *defaultValue,
-+ xmlEnumerationPtr tree);
-+xmlAttributeTablePtr xmlCopyAttributeTable (xmlAttributeTablePtr table);
-+void xmlFreeAttributeTable (xmlAttributeTablePtr table);
-+void xmlDumpAttributeTable (xmlBufferPtr buf,
-+ xmlAttributeTablePtr table);
-+void xmlDumpAttributeDecl (xmlBufferPtr buf,
-+ xmlAttributePtr attr);
-+
-+/* IDs */
-+xmlIDPtr xmlAddID (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ const xmlChar *value,
-+ xmlAttrPtr attr);
-+xmlIDTablePtr xmlCopyIDTable (xmlIDTablePtr table);
-+void xmlFreeIDTable (xmlIDTablePtr table);
-+xmlAttrPtr xmlGetID (xmlDocPtr doc,
-+ const xmlChar *ID);
-+int xmlIsID (xmlDocPtr doc,
-+ xmlNodePtr elem,
-+ xmlAttrPtr attr);
-+int xmlRemoveID (xmlDocPtr doc, xmlAttrPtr attr);
-+
-+/* IDREFs */
-+xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ const xmlChar *value,
-+ xmlAttrPtr attr);
-+xmlRefTablePtr xmlCopyRefTable (xmlRefTablePtr table);
-+void xmlFreeRefTable (xmlRefTablePtr table);
-+int xmlIsRef (xmlDocPtr doc,
-+ xmlNodePtr elem,
-+ xmlAttrPtr attr);
-+int xmlRemoveRef (xmlDocPtr doc, xmlAttrPtr attr);
-+
-+/**
-+ * The public function calls related to validity checking
-+ */
-+
-+int xmlValidateRoot (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc);
-+int xmlValidateElementDecl (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlElementPtr elem);
-+xmlChar * xmlValidNormalizeAttributeValue(xmlDocPtr doc,
-+ xmlNodePtr elem,
-+ const xmlChar *name,
-+ const xmlChar *value);
-+int xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlAttributePtr attr);
-+int xmlValidateAttributeValue(xmlAttributeType type,
-+ const xmlChar *value);
-+int xmlValidateNotationDecl (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlNotationPtr nota);
-+int xmlValidateDtd (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlDtdPtr dtd);
-+int xmlValidateDtdFinal (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc);
-+int xmlValidateDocument (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc);
-+int xmlValidateElement (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlNodePtr elem);
-+int xmlValidateOneElement (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlNodePtr elem);
-+int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ xmlNodePtr elem,
-+ xmlAttrPtr attr,
-+ const xmlChar *value);
-+int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc);
-+int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
-+ xmlDocPtr doc,
-+ const xmlChar *notationName);
-+int xmlIsMixedElement (xmlDocPtr doc,
-+ const xmlChar *name);
-+xmlAttributePtr xmlGetDtdAttrDesc (xmlDtdPtr dtd,
-+ const xmlChar *elem,
-+ const xmlChar *name);
-+xmlNotationPtr xmlGetDtdNotationDesc (xmlDtdPtr dtd,
-+ const xmlChar *name);
-+xmlElementPtr xmlGetDtdElementDesc (xmlDtdPtr dtd,
-+ const xmlChar *name);
-+
-+int xmlValidGetValidElements(xmlNode *prev,
-+ xmlNode *next,
-+ const xmlChar **list,
-+ int max);
-+int xmlValidGetPotentialChildren(xmlElementContent *ctree,
-+ const xmlChar **list,
-+ int *len,
-+ int max);
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_VALID_H__ */
-diff -Nru libxml2-2.3.0/libxml/win32config.h libxml2-2.3.0.new/libxml/win32config.h
---- libxml2-2.3.0/libxml/win32config.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/win32config.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,92 @@
-+#define HAVE_CTYPE_H
-+#define HAVE_STDLIB_H
-+#define HAVE_MALLOC_H
-+#define HAVE_TIME_H
-+#define HAVE_FCNTL_H
-+
-+#include <io.h>
-+
-+#define LIBXML_DLL_IMPORT
-+#define SOCKLEN_T int
-+
-+#ifdef INCLUDE_WINSOCK
-+#include <winsock2.h>
-+
-+#define EWOULDBLOCK WSAEWOULDBLOCK
-+#define EINPROGRESS WSAEINPROGRESS
-+#define EALREADY WSAEALREADY
-+#define ENOTSOCK WSAENOTSOCK
-+#define EDESTADDRREQ WSAEDESTADDRREQ
-+#define EMSGSIZE WSAEMSGSIZE
-+#define EPROTOTYPE WSAEPROTOTYPE
-+#define ENOPROTOOPT WSAENOPROTOOPT
-+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
-+#define EOPNOTSUPP WSAEOPNOTSUPP
-+#define EPFNOSUPPORT WSAEPFNOSUPPORT
-+#define EAFNOSUPPORT WSAEAFNOSUPPORT
-+#define EADDRINUSE WSAEADDRINUSE
-+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-+#define ENETDOWN WSAENETDOWN
-+#define ENETUNREACH WSAENETUNREACH
-+#define ENETRESET WSAENETRESET
-+#define ECONNABORTED WSAECONNABORTED
-+#define ECONNRESET WSAECONNRESET
-+#define ENOBUFS WSAENOBUFS
-+#define EISCONN WSAEISCONN
-+#define ENOTCONN WSAENOTCONN
-+#define ESHUTDOWN WSAESHUTDOWN
-+#define ETOOMANYREFS WSAETOOMANYREFS
-+#define ETIMEDOUT WSAETIMEDOUT
-+#define ECONNREFUSED WSAECONNREFUSED
-+#define ELOOP WSAELOOP
-+#define ENAMETOOLONG WSAENAMETOOLONG
-+#define EHOSTDOWN WSAEHOSTDOWN
-+#define EHOSTUNREACH WSAEHOSTUNREACH
-+#define ENOTEMPTY WSAENOTEMPTY
-+#define EPROCLIM WSAEPROCLIM
-+#define EUSERS WSAEUSERS
-+#define EDQUOT WSAEDQUOT
-+#define ESTALE WSAESTALE
-+#define EREMOTE WSAEREMOTE
-+#endif /* INCLUDE_WINSOCK */
-+
-+#define HAVE_ISINF
-+#define HAVE_ISNAN
-+
-+#include <math.h>
-+static int isinf (double d) {
-+ int expon = 0;
-+ double val = frexp (d, &expon);
-+ if (expon == 1025) {
-+ if (val == 0.5) {
-+ return 1;
-+ } else if (val == -0.5) {
-+ return -1;
-+ } else {
-+ return 0;
-+ }
-+ } else {
-+ return 0;
-+ }
-+}
-+static int isnan (double d) {
-+ int expon = 0;
-+ double val = frexp (d, &expon);
-+ if (expon == 1025) {
-+ if (val == 0.5) {
-+ return 0;
-+ } else if (val == -0.5) {
-+ return 0;
-+ } else {
-+ return 1;
-+ }
-+ } else {
-+ return 0;
-+ }
-+}
-+
-+#include <direct.h>
-+
-+#define HAVE_SYS_STAT_H #define HAVE__STAT
-+
-diff -Nru libxml2-2.3.0/libxml/xinclude.c libxml2-2.3.0.new/libxml/xinclude.c
---- libxml2-2.3.0/libxml/xinclude.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xinclude.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,806 @@
-+/*
-+ * xinclude.c : Code to implement XInclude processing
-+ *
-+ * World Wide Web Consortium Working Draft 26 October 2000
-+ * http://www.w3.org/TR/2000/WD-xinclude-20001026
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+/*
-+ * TODO: compute XPointers nodesets
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/uri.h>
-+#include <libxml/xpointer.h>
-+#include <libxml/parserInternals.h>
-+#ifdef LIBXML_DEBUG_ENABLED
-+#include <libxml/debugXML.h>
-+#endif
-+#include <libxml/xmlerror.h>
-+
-+#ifdef LIBXML_XINCLUDE_ENABLED
-+#include <libxml/xinclude.h>
-+
-+#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/1999/XML/xinclude"
-+#define XINCLUDE_NODE (const xmlChar *) "include"
-+#define XINCLUDE_HREF (const xmlChar *) "href"
-+#define XINCLUDE_PARSE (const xmlChar *) "parse"
-+#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
-+#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
-+
-+/* #define DEBUG_XINCLUDE */
-+
-+/************************************************************************
-+ * *
-+ * XInclude contexts handling *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * An XInclude context
-+ */
-+typedef xmlChar *URL;
-+typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
-+typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;
-+struct _xmlXIncludeCtxt {
-+ xmlDocPtr doc; /* the source document */
-+ int incNr; /* number of includes */
-+ int incMax; /* size of includes tab */
-+ xmlNodePtr *incTab; /* array of include nodes */
-+ xmlNodePtr *repTab; /* array of replacement node lists */
-+ int docNr; /* number of parsed documents */
-+ int docMax; /* size of parsed documents tab */
-+ xmlDocPtr *docTab; /* array of parsed documents */
-+ URL *urlTab; /* array of parsed documents URLs */
-+ int txtNr; /* number of unparsed documents */
-+ int txtMax; /* size of unparsed documents tab */
-+ xmlNodePtr *txtTab; /* array of unparsed text nodes */
-+ URL *txturlTab; /* array of unparsed txtuments URLs */
-+};
-+
-+/**
-+ * xmlXIncludeAddNode:
-+ * @ctxt: the XInclude context
-+ * @node: the new node
-+ *
-+ * Add a new node to process to an XInclude context
-+ */
-+void
-+xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
-+ if (ctxt->incMax == 0) {
-+ ctxt->incMax = 4;
-+ ctxt->incTab = (xmlNodePtr *) xmlMalloc(ctxt->incMax *
-+ sizeof(ctxt->incTab[0]));
-+ if (ctxt->incTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc failed !\n");
-+ return;
-+ }
-+ ctxt->repTab = (xmlNodePtr *) xmlMalloc(ctxt->incMax *
-+ sizeof(ctxt->repTab[0]));
-+ if (ctxt->repTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc failed !\n");
-+ return;
-+ }
-+ }
-+ if (ctxt->incNr >= ctxt->incMax) {
-+ ctxt->incMax *= 2;
-+ ctxt->incTab = (xmlNodePtr *) xmlRealloc(ctxt->incTab,
-+ ctxt->incMax * sizeof(ctxt->incTab[0]));
-+ if (ctxt->incTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return;
-+ }
-+ ctxt->repTab = (xmlNodePtr *) xmlRealloc(ctxt->repTab,
-+ ctxt->incMax * sizeof(ctxt->repTab[0]));
-+ if (ctxt->repTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return;
-+ }
-+ }
-+ ctxt->incTab[ctxt->incNr] = node;
-+ ctxt->repTab[ctxt->incNr] = NULL;
-+ ctxt->incNr++;
-+}
-+
-+/**
-+ * xmlXIncludeAddDoc:
-+ * @ctxt: the XInclude context
-+ * @doc: the new document
-+ * @url: the associated URL
-+ *
-+ * Add a new document to the list
-+ */
-+void
-+xmlXIncludeAddDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, const URL url) {
-+ if (ctxt->docMax == 0) {
-+ ctxt->docMax = 4;
-+ ctxt->docTab = (xmlDocPtr *) xmlMalloc(ctxt->docMax *
-+ sizeof(ctxt->docTab[0]));
-+ if (ctxt->docTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc failed !\n");
-+ return;
-+ }
-+ ctxt->urlTab = (URL *) xmlMalloc(ctxt->docMax *
-+ sizeof(ctxt->urlTab[0]));
-+ if (ctxt->urlTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc failed !\n");
-+ return;
-+ }
-+ }
-+ if (ctxt->docNr >= ctxt->docMax) {
-+ ctxt->docMax *= 2;
-+ ctxt->docTab = (xmlDocPtr *) xmlRealloc(ctxt->docTab,
-+ ctxt->docMax * sizeof(ctxt->docTab[0]));
-+ if (ctxt->docTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return;
-+ }
-+ ctxt->urlTab = (URL *) xmlRealloc(ctxt->urlTab,
-+ ctxt->docMax * sizeof(ctxt->urlTab[0]));
-+ if (ctxt->urlTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return;
-+ }
-+ }
-+ ctxt->docTab[ctxt->docNr] = doc;
-+ ctxt->urlTab[ctxt->docNr] = xmlStrdup(url);
-+ ctxt->docNr++;
-+}
-+
-+/**
-+ * xmlXIncludeAddTxt:
-+ * @ctxt: the XInclude context
-+ * @txt: the new text node
-+ * @url: the associated URL
-+ *
-+ * Add a new txtument to the list
-+ */
-+void
-+xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const URL url) {
-+ if (ctxt->txtMax == 0) {
-+ ctxt->txtMax = 4;
-+ ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
-+ sizeof(ctxt->txtTab[0]));
-+ if (ctxt->txtTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc failed !\n");
-+ return;
-+ }
-+ ctxt->txturlTab = (URL *) xmlMalloc(ctxt->txtMax *
-+ sizeof(ctxt->txturlTab[0]));
-+ if (ctxt->txturlTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "malloc failed !\n");
-+ return;
-+ }
-+ }
-+ if (ctxt->txtNr >= ctxt->txtMax) {
-+ ctxt->txtMax *= 2;
-+ ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
-+ ctxt->txtMax * sizeof(ctxt->txtTab[0]));
-+ if (ctxt->txtTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return;
-+ }
-+ ctxt->txturlTab = (URL *) xmlRealloc(ctxt->txturlTab,
-+ ctxt->txtMax * sizeof(ctxt->urlTab[0]));
-+ if (ctxt->txturlTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "realloc failed !\n");
-+ return;
-+ }
-+ }
-+ ctxt->txtTab[ctxt->txtNr] = txt;
-+ ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url);
-+ ctxt->txtNr++;
-+}
-+
-+/**
-+ * xmlXIncludeNewContext:
-+ * @doc: an XML Document
-+ *
-+ * Creates a new XInclude context
-+ *
-+ * Returns the new set
-+ */
-+xmlXIncludeCtxtPtr
-+xmlXIncludeNewContext(xmlDocPtr doc) {
-+ xmlXIncludeCtxtPtr ret;
-+
-+ if (doc == NULL)
-+ return(NULL);
-+ ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
-+ if (ret == NULL)
-+ return(NULL);
-+ memset(ret, 0, sizeof(xmlXIncludeCtxt));
-+ ret->doc = doc;
-+ ret->incNr = 0;
-+ ret->incMax = 0;
-+ ret->incTab = NULL;
-+ ret->repTab = NULL;
-+ ret->docNr = 0;
-+ ret->docMax = 0;
-+ ret->docTab = NULL;
-+ ret->urlTab = NULL;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXIncludeFreeContext:
-+ * @ctxt: the XInclude context
-+ *
-+ * Free an XInclude context
-+ */
-+void
-+xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
-+ int i;
-+
-+ if (ctxt == NULL)
-+ return;
-+ for (i = 0;i < ctxt->docNr;i++) {
-+ xmlFreeDoc(ctxt->docTab[i]);
-+ if (ctxt->urlTab[i] != NULL)
-+ xmlFree(ctxt->urlTab[i]);
-+ }
-+ for (i = 0;i < ctxt->txtNr;i++) {
-+ if (ctxt->txturlTab[i] != NULL)
-+ xmlFree(ctxt->txturlTab[i]);
-+ }
-+ if (ctxt->incTab != NULL)
-+ xmlFree(ctxt->incTab);
-+ if (ctxt->repTab != NULL)
-+ xmlFree(ctxt->repTab);
-+ if (ctxt->urlTab != NULL)
-+ xmlFree(ctxt->urlTab);
-+ if (ctxt->docTab != NULL)
-+ xmlFree(ctxt->docTab);
-+ if (ctxt->txtTab != NULL)
-+ xmlFree(ctxt->txtTab);
-+ if (ctxt->txturlTab != NULL)
-+ xmlFree(ctxt->txturlTab);
-+ memset(ctxt, 0xeb, sizeof(xmlXIncludeCtxt));
-+ xmlFree(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * XInclude I/O handling *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXIncludeLoadDoc:
-+ * @ctxt: the XInclude context
-+ * @url: the associated URL
-+ * @nr: the xinclude node number
-+ *
-+ * Load the document, and store the result in the XInclude context
-+ */
-+void
-+xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
-+ xmlDocPtr doc;
-+ xmlURIPtr uri;
-+ xmlChar *URL;
-+ xmlChar *fragment = NULL;
-+ int i;
-+ /*
-+ * Check the URL and remove any fragment identifier
-+ */
-+ uri = xmlParseURI((const char *)url);
-+ if (uri == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: invalid value URI %s\n", url);
-+ return;
-+ }
-+ if (uri->fragment != NULL) {
-+ fragment = (xmlChar *) uri->fragment;
-+ uri->fragment = NULL;
-+ }
-+ URL = xmlSaveUri(uri);
-+ xmlFreeURI(uri);
-+ if (URL == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: invalid value URI %s\n", url);
-+ if (fragment != NULL)
-+ xmlFree(fragment);
-+ return;
-+ }
-+
-+ /*
-+ * Handling of references to the local document are done
-+ * directly through ctxt->doc.
-+ */
-+ if ((URL[0] == 0) || (URL[0] == '#')) {
-+ doc = NULL;
-+ goto loaded;
-+ }
-+
-+ /*
-+ * Prevent reloading twice the document.
-+ */
-+ for (i = 0; i < ctxt->docNr; i++) {
-+ if (xmlStrEqual(URL, ctxt->urlTab[i])) {
-+ doc = ctxt->docTab[i];
-+ goto loaded;
-+ }
-+ }
-+ /*
-+ * Load it.
-+ */
-+ doc = xmlParseFile((const char *)URL);
-+ if (doc == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: could not load %s\n", URL);
-+ xmlFree(URL);
-+ if (fragment != NULL)
-+ xmlFree(fragment);
-+ return;
-+ }
-+ xmlXIncludeAddDoc(ctxt, doc, URL);
-+
-+loaded:
-+ if (fragment == NULL) {
-+ /*
-+ * Add the top children list as the replacement copy.
-+ * ISSUE: seems we should scrap DTD info from the copied list.
-+ */
-+ if (doc == NULL)
-+ ctxt->repTab[nr] = xmlCopyNodeList(ctxt->doc->children);
-+ else
-+ ctxt->repTab[nr] = xmlCopyNodeList(doc->children);
-+ } else {
-+ /*
-+ * Computes the XPointer expression and make a copy used
-+ * as the replacement copy.
-+ */
-+ xmlXPathObjectPtr xptr;
-+ xmlXPathContextPtr xptrctxt;
-+
-+ if (doc == NULL) {
-+ xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr], NULL);
-+ } else {
-+ xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
-+ }
-+ if (xptrctxt == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: could create XPointer context\n");
-+ xmlFree(URL);
-+ xmlFree(fragment);
-+ return;
-+ }
-+ xptr = xmlXPtrEval(fragment, xptrctxt);
-+ if (xptr == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: XPointer evaluation failed: #%s\n",
-+ fragment);
-+ xmlXPathFreeContext(xptrctxt);
-+ xmlFree(URL);
-+ xmlFree(fragment);
-+ return;
-+ }
-+ ctxt->repTab[nr] = xmlXPtrBuildNodeList(xptr);
-+ xmlXPathFreeObject(xptr);
-+ xmlXPathFreeContext(xptrctxt);
-+ xmlFree(fragment);
-+ }
-+ xmlFree(URL);
-+}
-+
-+/**
-+ * xmlXIncludeLoadTxt:
-+ * @ctxt: the XInclude context
-+ * @url: the associated URL
-+ * @nr: the xinclude node number
-+ *
-+ * Load the content, and store the result in the XInclude context
-+ */
-+void
-+xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
-+ xmlParserInputBufferPtr buf;
-+ xmlNodePtr node;
-+ xmlURIPtr uri;
-+ xmlChar *URL;
-+ int i;
-+ /*
-+ * Check the URL and remove any fragment identifier
-+ */
-+ uri = xmlParseURI((const char *)url);
-+ if (uri == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: invalid value URI %s\n", url);
-+ return;
-+ }
-+ if (uri->fragment != NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: fragment identifier forbidden for text: %s\n",
-+ uri->fragment);
-+ xmlFreeURI(uri);
-+ return;
-+ }
-+ URL = xmlSaveUri(uri);
-+ xmlFreeURI(uri);
-+ if (URL == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: invalid value URI %s\n", url);
-+ return;
-+ }
-+
-+ /*
-+ * Handling of references to the local document are done
-+ * directly through ctxt->doc.
-+ */
-+ if (URL[0] == 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: text serialization of document not available\n");
-+ xmlFree(URL);
-+ return;
-+ }
-+
-+ /*
-+ * Prevent reloading twice the document.
-+ */
-+ for (i = 0; i < ctxt->txtNr; i++) {
-+ if (xmlStrEqual(URL, ctxt->txturlTab[i])) {
-+ node = xmlCopyNode(ctxt->txtTab[i], 1);
-+ goto loaded;
-+ }
-+ }
-+ /*
-+ * Load it.
-+ * Issue 62: how to detect the encoding
-+ */
-+ buf = xmlParserInputBufferCreateFilename((const char *)URL, 0);
-+ if (buf == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: could not load %s\n", URL);
-+ xmlFree(URL);
-+ return;
-+ }
-+ node = xmlNewText(NULL);
-+
-+ /*
-+ * Scan all chars from the resource and add the to the node
-+ */
-+ while (xmlParserInputBufferRead(buf, 128) > 0) {
-+ int len;
-+ const xmlChar *content;
-+
-+ content = xmlBufferContent(buf->buffer);
-+ len = xmlBufferLength(buf->buffer);
-+ for (i = 0;i < len; i++) {
-+ /*
-+ * TODO: if the encoding issue is solved, scan UTF8 chars instead
-+ */
-+ if (!IS_CHAR(content[i])) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: %s contains invalid char %d\n", URL, content[i]);
-+ } else {
-+ xmlNodeAddContentLen(node, &content[i], 1);
-+ }
-+ }
-+ xmlBufferShrink(buf->buffer, len);
-+ }
-+ xmlFreeParserInputBuffer(buf);
-+ xmlXIncludeAddTxt(ctxt, node, URL);
-+
-+loaded:
-+ /*
-+ * Add the element as the replacement copy.
-+ */
-+ ctxt->repTab[nr] = node;
-+ xmlFree(URL);
-+}
-+
-+/************************************************************************
-+ * *
-+ * XInclude Processing *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXIncludePreProcessNode:
-+ * @ctxt: an XInclude context
-+ * @node: an XInclude node
-+ *
-+ * Implement the infoset replacement lookup on the XML element @node
-+ *
-+ * Returns the result list or NULL in case of error
-+ */
-+xmlNodePtr
-+xmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
-+ xmlXIncludeAddNode(ctxt, node);
-+ return(0);
-+}
-+
-+/**
-+ * xmlXIncludeLoadNode:
-+ * @ctxt: an XInclude context
-+ * @nr: the node number
-+ *
-+ * Find and load the infoset replacement for the given node.
-+ *
-+ * Returns 0 if substition succeeded, -1 if some processing failed
-+ */
-+int
-+xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
-+ xmlNodePtr cur;
-+ xmlChar *href;
-+ xmlChar *parse;
-+ xmlChar *base;
-+ xmlChar *URI;
-+ int xml = 1; /* default Issue 64 */
-+
-+ if (ctxt == NULL)
-+ return(-1);
-+ if ((nr < 0) || (nr >= ctxt->incNr))
-+ return(-1);
-+ cur = ctxt->incTab[nr];
-+ if (cur == NULL)
-+ return(-1);
-+
-+#ifdef DEBUG_XINCLUDE
-+ xmlDebugDumpNode(stdout, cur, 0);
-+#endif
-+ /*
-+ * read the attributes
-+ */
-+ href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
-+ if (href == NULL) {
-+ href = xmlGetProp(cur, XINCLUDE_HREF);
-+ if (href == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
-+ return(-1);
-+ }
-+ }
-+ parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
-+ if (parse == NULL) {
-+ parse = xmlGetProp(cur, XINCLUDE_PARSE);
-+ }
-+ if (parse != NULL) {
-+ if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
-+ xml = 1;
-+ else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
-+ xml = 0;
-+ else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: invalid value %s for %s\n",
-+ parse, XINCLUDE_PARSE);
-+ if (href != NULL)
-+ xmlFree(href);
-+ if (parse != NULL)
-+ xmlFree(parse);
-+ return(-1);
-+ }
-+ }
-+
-+ /*
-+ * compute the URI
-+ */
-+ base = xmlNodeGetBase(ctxt->doc, cur);
-+ if (base == NULL) {
-+ URI = xmlBuildURI(href, ctxt->doc->URL);
-+ } else {
-+ URI = xmlBuildURI(href, base);
-+ }
-+ if (URI == NULL) {
-+ xmlChar *escbase;
-+ xmlChar *eschref;
-+ /*
-+ * Some escapeing may be needed
-+ */
-+ escbase = xmlURIEscape(base);
-+ eschref = xmlURIEscape(href);
-+ URI = xmlBuildURI(eschref, escbase);
-+ if (escbase != NULL)
-+ xmlFree(escbase);
-+ if (eschref != NULL)
-+ xmlFree(eschref);
-+ }
-+ if (URI == NULL) {
-+ xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
-+ if (parse != NULL)
-+ xmlFree(parse);
-+ if (href != NULL)
-+ xmlFree(href);
-+ if (base != NULL)
-+ xmlFree(base);
-+ return(-1);
-+ }
-+#ifdef DEBUG_XINCLUDE
-+ xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
-+ xml ? "xml": "text");
-+ xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
-+#endif
-+
-+ /*
-+ * Cleanup
-+ */
-+ if (xml) {
-+ xmlXIncludeLoadDoc(ctxt, URI, nr);
-+ /* xmlXIncludeGetFragment(ctxt, cur, URI); */
-+ } else {
-+ xmlXIncludeLoadTxt(ctxt, URI, nr);
-+ }
-+
-+ /*
-+ * Cleanup
-+ */
-+ if (URI != NULL)
-+ xmlFree(URI);
-+ if (parse != NULL)
-+ xmlFree(parse);
-+ if (href != NULL)
-+ xmlFree(href);
-+ if (base != NULL)
-+ xmlFree(base);
-+ return(0);
-+}
-+
-+/**
-+ * xmlXIncludeIncludeNode:
-+ * @ctxt: an XInclude context
-+ * @nr: the node number
-+ *
-+ * Inplement the infoset replacement for the given node
-+ *
-+ * Returns 0 if substition succeeded, -1 if some processing failed
-+ */
-+int
-+xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
-+ xmlNodePtr cur, end, list;
-+
-+ if (ctxt == NULL)
-+ return(-1);
-+ if ((nr < 0) || (nr >= ctxt->incNr))
-+ return(-1);
-+ cur = ctxt->incTab[nr];
-+ if (cur == NULL)
-+ return(-1);
-+
-+ /*
-+ * Change the current node as an XInclude start one, and add an
-+ * entity end one
-+ */
-+ cur->type = XML_XINCLUDE_START;
-+ end = xmlNewNode(cur->ns, cur->name);
-+ if (end == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "XInclude: failed to build node\n");
-+ return(-1);
-+ }
-+ end->type = XML_XINCLUDE_END;
-+ xmlAddNextSibling(cur, end);
-+
-+ /*
-+ * Add the list of nodes
-+ */
-+ list = ctxt->repTab[nr];
-+ ctxt->repTab[nr] = NULL;
-+ while (list != NULL) {
-+ cur = list;
-+ list = list->next;
-+
-+ xmlAddPrevSibling(end, cur);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXIncludeTestNode:
-+ * @doc: an XML document
-+ * @node: an XInclude node
-+ *
-+ * test if the node is an XInclude node
-+ *
-+ * Returns 1 true, 0 otherwise
-+ */
-+int
-+xmlXIncludeTestNode(xmlDocPtr doc, xmlNodePtr node) {
-+ if (node == NULL)
-+ return(0);
-+ if (node->ns == NULL)
-+ return(0);
-+ if ((xmlStrEqual(node->name, XINCLUDE_NODE)) &&
-+ (xmlStrEqual(node->ns->href, XINCLUDE_NS))) return(1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlXIncludeProcess:
-+ * @doc: an XML document
-+ *
-+ * Implement the XInclude substitution on the XML document @doc
-+ *
-+ * Returns 0 if no substition were done, -1 if some processing failed
-+ * or the number of substitutions done.
-+ */
-+int
-+xmlXIncludeProcess(xmlDocPtr doc) {
-+ xmlXIncludeCtxtPtr ctxt;
-+ xmlNodePtr cur;
-+ int ret = 0;
-+ int i;
-+
-+ if (doc == NULL)
-+ return(-1);
-+ ctxt = xmlXIncludeNewContext(doc);
-+ if (ctxt == NULL)
-+ return(-1);
-+
-+ /*
-+ * First phase: lookup the elements in the document
-+ */
-+ cur = xmlDocGetRootElement(doc);
-+ if (xmlXIncludeTestNode(doc, cur))
-+ xmlXIncludePreProcessNode(ctxt, cur);
-+ while (cur != NULL) {
-+ /* TODO: need to work on entities -> stack */
-+ if ((cur->children != NULL) &&
-+ (cur->children->type != XML_ENTITY_DECL)) {
-+ cur = cur->children;
-+ if (xmlXIncludeTestNode(doc, cur))
-+ xmlXIncludePreProcessNode(ctxt, cur);
-+ } else if (cur->next != NULL) {
-+ cur = cur->next;
-+ if (xmlXIncludeTestNode(doc, cur))
-+ xmlXIncludePreProcessNode(ctxt, cur);
-+ } else {
-+ do {
-+ cur = cur->parent;
-+ if (cur == NULL) break; /* do */
-+ if (cur->next != NULL) {
-+ cur = cur->next;
-+ if (xmlXIncludeTestNode(doc, cur))
-+ xmlXIncludePreProcessNode(ctxt, cur);
-+ break; /* do */
-+ }
-+ } while (cur != NULL);
-+ }
-+ }
-+
-+ /*
-+ * Second Phase : collect the infosets fragments
-+ */
-+ for (i = 0;i < ctxt->incNr; i++) {
-+ xmlXIncludeLoadNode(ctxt, i);
-+ }
-+
-+ /*
-+ * Third phase: extend the original document infoset.
-+ */
-+ for (i = 0;i < ctxt->incNr; i++) {
-+ xmlXIncludeIncludeNode(ctxt, i);
-+ }
-+
-+ /*
-+ * Cleanup
-+ */
-+ xmlXIncludeFreeContext(ctxt);
-+ return(ret);
-+}
-+
-+#else /* !LIBXML_XINCLUDE_ENABLED */
-+#endif
-diff -Nru libxml2-2.3.0/libxml/xinclude.h libxml2-2.3.0.new/libxml/xinclude.h
---- libxml2-2.3.0/libxml/xinclude.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xinclude.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,26 @@
-+/*
-+ * xinclude.c : API to handle XInclude processing
-+ *
-+ * World Wide Web Consortium Working Draft 26 October 2000
-+ * http://www.w3.org/TR/2000/WD-xinclude-20001026
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_XINCLUDE_H__
-+#define __XML_XINCLUDE_H__
-+
-+#include <libxml/tree.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+int xmlXIncludeProcess (xmlDocPtr doc);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_XINCLUDE_H__ */
-diff -Nru libxml2-2.3.0/libxml/xlink.c libxml2-2.3.0.new/libxml/xlink.c
---- libxml2-2.3.0/libxml/xlink.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xlink.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,187 @@
-+/*
-+ * xlink.c : implementation of the hyperlinks detection module
-+ * This version supports both XML XLinks and HTML simple links
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h> /* for memset() only */
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_ZLIB_H
-+#include <zlib.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/valid.h>
-+#include <libxml/xlink.h>
-+
-+#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
-+#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
-+
-+/****************************************************************
-+ * *
-+ * Default setting and related functions *
-+ * *
-+ ****************************************************************/
-+
-+xlinkHandlerPtr xlinkDefaultHandler = NULL;
-+xlinkNodeDetectFunc xlinkDefaultDetect = NULL;
-+
-+/**
-+ * xlinkGetDefaultHandler:
-+ *
-+ * Get the default xlink handler.
-+ *
-+ * Returns the current xlinkHandlerPtr value.
-+ */
-+xlinkHandlerPtr
-+xlinkGetDefaultHandler(void) {
-+ return(xlinkDefaultHandler);
-+}
-+
-+
-+/**
-+ * xlinkSetDefaultHandler:
-+ * @handler: the new value for the xlink handler block
-+ *
-+ * Set the default xlink handlers
-+ */
-+void
-+xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
-+ xlinkDefaultHandler = handler;
-+}
-+
-+/**
-+ * xlinkGetDefaultDetect:
-+ *
-+ * Get the default xlink detection routine
-+ *
-+ * Returns the current function or NULL;
-+ */
-+xlinkNodeDetectFunc
-+xlinkGetDefaultDetect (void) {
-+ return(xlinkDefaultDetect);
-+}
-+
-+/**
-+ * xlinkSetDefaultDetect:
-+ * @func: pointer to the new detction routine.
-+ *
-+ * Set the default xlink detection routine
-+ */
-+void
-+xlinkSetDefaultDetect (xlinkNodeDetectFunc func) {
-+ xlinkDefaultDetect = func;
-+}
-+
-+/****************************************************************
-+ * *
-+ * The detection routines *
-+ * *
-+ ****************************************************************/
-+
-+
-+/**
-+ * xlinkIsLink:
-+ * @doc: the document containing the node
-+ * @node: the node pointer itself
-+ *
-+ * Check whether the given node carries the attributes needed
-+ * to be a link element (or is one of the linking elements issued
-+ * from the (X)HTML DtDs).
-+ * This routine don't try to do full checking of the link validity
-+ * but tries to detect and return the appropriate link type.
-+ *
-+ * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
-+ * link detected.
-+ */
-+xlinkType
-+xlinkIsLink (xmlDocPtr doc, xmlNodePtr node) {
-+ xmlChar *type = NULL, *role = NULL;
-+ xlinkType ret = XLINK_TYPE_NONE;
-+
-+ if (node == NULL) return(XLINK_TYPE_NONE);
-+ if (doc == NULL) doc = node->doc;
-+ if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
-+ /*
-+ * This is an HTML document.
-+ */
-+ } else if ((node->ns != NULL) &&
-+ (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) {
-+ /*
-+ * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
-+ */
-+ /*
-+ * This is an XHTML element within an XML document
-+ * Check whether it's one of the element able to carry links
-+ * and in that case if it holds the attributes.
-+ */
-+ }
-+
-+ /*
-+ * We don't prevent a-priori having XML Linking constructs on
-+ * XHTML elements
-+ */
-+ type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
-+ if (type != NULL) {
-+ if (!xmlStrEqual(type, BAD_CAST "simple")) {
-+ ret = XLINK_TYPE_SIMPLE;
-+ } if (!xmlStrEqual(type, BAD_CAST "extended")) {
-+ role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
-+ if (role != NULL) {
-+ xmlNsPtr xlink;
-+ xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
-+ if (xlink == NULL) {
-+ /* Humm, fallback method */
-+ if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset"))
-+ ret = XLINK_TYPE_EXTENDED_SET;
-+ } else {
-+ xmlChar buf[200];
-+#ifdef HAVE_SNPRINTF
-+ snprintf((char *) buf, sizeof(buf), "%s:external-linkset",
-+ (char *) xlink->prefix);
-+#else
-+ sprintf((char *) buf, "%s:external-linkset",
-+ (char *) xlink->prefix);
-+#endif
-+ buf[sizeof(buf) - 1] = 0;
-+ if (xmlStrEqual(role, buf))
-+ ret = XLINK_TYPE_EXTENDED_SET;
-+
-+ }
-+
-+ }
-+ ret = XLINK_TYPE_EXTENDED;
-+ }
-+ }
-+
-+ if (type != NULL) xmlFree(type);
-+ if (role != NULL) xmlFree(role);
-+ return(ret);
-+}
-diff -Nru libxml2-2.3.0/libxml/xlink.h libxml2-2.3.0.new/libxml/xlink.h
---- libxml2-2.3.0/libxml/xlink.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xlink.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,182 @@
-+/*
-+ * xlink.h : interfaces to the hyperlinks detection module
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Related specification: http://www.w3.org/TR/xlink
-+ * http://www.w3.org/HTML/
-+ * and XBase
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_XLINK_H__
-+#define __XML_XLINK_H__
-+
-+#include <libxml/tree.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+/**
-+ * Various defines for the various Link properties.
-+ *
-+ * NOTE: the link detection layer will try to resolve QName expansion
-+ * of namespaces, if "foo" is the prefix for "http://foo.com/"
-+ * then the link detection layer will expand role="foo:myrole"
-+ * to "http://foo.com/:myrole"
-+ * NOTE: the link detection layer will expand URI-Refences found on
-+ * href attributes by using the base mechanism if found.
-+ */
-+typedef xmlChar *xlinkHRef;
-+typedef xmlChar *xlinkRole;
-+typedef xmlChar *xlinkTitle;
-+
-+typedef enum {
-+ XLINK_TYPE_NONE = 0,
-+ XLINK_TYPE_SIMPLE,
-+ XLINK_TYPE_EXTENDED,
-+ XLINK_TYPE_EXTENDED_SET
-+} xlinkType;
-+
-+typedef enum {
-+ XLINK_SHOW_NONE = 0,
-+ XLINK_SHOW_NEW,
-+ XLINK_SHOW_EMBED,
-+ XLINK_SHOW_REPLACE
-+} xlinkShow;
-+
-+typedef enum {
-+ XLINK_ACTUATE_NONE = 0,
-+ XLINK_ACTUATE_AUTO,
-+ XLINK_ACTUATE_ONREQUEST
-+} xlinkActuate;
-+
-+/**
-+ * xlinkNodeDetectFunc:
-+ * @ctx: user data pointer
-+ * @node: the node to check
-+ *
-+ * This is the prototype for the link detection routine
-+ * It calls the default link detection callbacks upon link detection.
-+ */
-+typedef void
-+(*xlinkNodeDetectFunc) (void *ctx,
-+ xmlNodePtr node);
-+
-+/**
-+ * The link detection module interract with the upper layers using
-+ * a set of callback registered at parsing time.
-+ */
-+
-+/**
-+ * xlinkSimpleLinkFunk:
-+ * @ctx: user data pointer
-+ * @node: the node carrying the link
-+ * @href: the target of the link
-+ * @role: the role string
-+ * @title: the link title
-+ *
-+ * This is the prototype for a simple link detection callback.
-+ */
-+typedef void
-+(*xlinkSimpleLinkFunk) (void *ctx,
-+ xmlNodePtr node,
-+ const xlinkHRef href,
-+ const xlinkRole role,
-+ const xlinkTitle title);
-+
-+/**
-+ * xlinkExtendedLinkFunk:
-+ * @ctx: user data pointer
-+ * @node: the node carrying the link
-+ * @nbLocators: the number of locators detected on the link
-+ * @hrefs: pointer to the array of locator hrefs
-+ * @roles: pointer to the array of locator roles
-+ * @nbArcs: the number of arcs detected on the link
-+ * @from: pointer to the array of source roles found on the arcs
-+ * @to: pointer to the array of target roles found on the arcs
-+ * @show: array of values for the show attributes found on the arcs
-+ * @actuate: array of values for the actuate attributes found on the arcs
-+ * @nbTitles: the number of titles detected on the link
-+ * @title: array of titles detected on the link
-+ * @langs: array of xml:lang values for the titles
-+ *
-+ * This is the prototype for a extended link detection callback.
-+ */
-+typedef void
-+(*xlinkExtendedLinkFunk)(void *ctx,
-+ xmlNodePtr node,
-+ int nbLocators,
-+ const xlinkHRef *hrefs,
-+ const xlinkRole *roles,
-+ int nbArcs,
-+ const xlinkRole *from,
-+ const xlinkRole *to,
-+ xlinkShow *show,
-+ xlinkActuate *actuate,
-+ int nbTitles,
-+ const xlinkTitle *titles,
-+ const xmlChar **langs);
-+
-+/**
-+ * xlinkExtendedLinkSetFunk:
-+ * @ctx: user data pointer
-+ * @node: the node carrying the link
-+ * @nbLocators: the number of locators detected on the link
-+ * @hrefs: pointer to the array of locator hrefs
-+ * @roles: pointer to the array of locator roles
-+ * @nbTitles: the number of titles detected on the link
-+ * @title: array of titles detected on the link
-+ * @langs: array of xml:lang values for the titles
-+ *
-+ * This is the prototype for a extended link set detection callback.
-+ */
-+typedef void
-+(*xlinkExtendedLinkSetFunk) (void *ctx,
-+ xmlNodePtr node,
-+ int nbLocators,
-+ const xlinkHRef *hrefs,
-+ const xlinkRole *roles,
-+ int nbTitles,
-+ const xlinkTitle *titles,
-+ const xmlChar **langs);
-+
-+/**
-+ * This is the structure containing a set of Links detection callbacks
-+ *
-+ * There is no default xlink callbacks, if one want to get link
-+ * recognition activated, those call backs must be provided before parsing.
-+ */
-+typedef struct _xlinkHandler xlinkHandler;
-+typedef xlinkHandler *xlinkHandlerPtr;
-+struct _xlinkHandler {
-+ xlinkSimpleLinkFunk simple;
-+ xlinkExtendedLinkFunk extended;
-+ xlinkExtendedLinkSetFunk set;
-+};
-+
-+/**
-+ * the default detection routine, can be overriden, they call the default
-+ * detection callbacks.
-+ */
-+
-+xlinkNodeDetectFunc xlinkGetDefaultDetect (void);
-+void xlinkSetDefaultDetect (xlinkNodeDetectFunc func);
-+
-+/**
-+ * Routines to set/get the default handlers.
-+ */
-+xlinkHandlerPtr xlinkGetDefaultHandler (void);
-+void xlinkSetDefaultHandler (xlinkHandlerPtr handler);
-+
-+/*
-+ * Link detection module itself.
-+ */
-+xlinkType xlinkIsLink (xmlDocPtr doc,
-+ xmlNodePtr node);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_XLINK_H__ */
-diff -Nru libxml2-2.3.0/libxml/xml-config.1 libxml2-2.3.0.new/libxml/xml-config.1
---- libxml2-2.3.0/libxml/xml-config.1 Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xml-config.1 Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,31 @@
-+.TH GNOME-XML 1 "3 July 1999" Version 1.1.0
-+.SH NAME
-+xml-config - script to get information about the installed version of GNOME-XML
-+.SH SYNOPSIS
-+.B xml-config
-+[\-\-prefix\fI[=DIR]\fP] [\-\-libs] [\-\-cflags] [\-\-version] [\-\-help]
-+.SH DESCRIPTION
-+\fIxml-config\fP is a tool that is used to determine the compile and
-+linker flags that should be used to compile and link programs that use
-+\fIGNOME-XML\fP.
-+.SH OPTIONS
-+.l
-+\fIxml-config\fP accepts the following options:
-+.TP 8
-+.B \-\-version
-+Print the currently installed version of \fIGNOME-XML\fP on the standard output.
-+.TP 8
-+.B \-\-libs
-+Print the linker flags that are necessary to link a \fIGNOME-XML\fP program.
-+.TP 8
-+.B \-\-cflags
-+Print the compiler flags that are necessary to compile a \fIGNOME-XML\fP program.
-+.TP 8
-+.B \-\-prefix=PREFIX
-+If specified, use PREFIX instead of the installation prefix that
-+\fIGNOME-XML\fP was built with when computing the output for the
-+\-\-cflags and \-\-libs options. This option must be specified before
-+any \-\-libs or \-\-cflags options.
-+.SH AUTHOR
-+This manual page was written by Fredrik Hallenberg <hallon@lysator.liu.se>,
-+for the Debian GNU/linux system (but may be used by others).
-diff -Nru libxml2-2.3.0/libxml/xml-config.in libxml2-2.3.0.new/libxml/xml-config.in
---- libxml2-2.3.0/libxml/xml-config.in Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xml-config.in Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,72 @@
-+#! /bin/sh
-+
-+prefix=@prefix@
-+exec_prefix=@exec_prefix@
-+includedir=@includedir@
-+libdir=@libdir@
-+
-+usage()
-+{
-+ cat <<EOF
-+Usage: xml-config [OPTION]
-+
-+Known values for OPTION are:
-+
-+ --prefix=DIR change libxml prefix [default $prefix]
-+ --libs print library linking information
-+ --cflags print pre-processor and compiler flags
-+ --help display this help and exit
-+ --version output version information
-+EOF
-+
-+ exit $1
-+}
-+
-+if test $# -eq 0; then
-+ usage 1
-+fi
-+
-+cflags=false
-+libs=false
-+
-+while test $# -gt 0; do
-+ case "$1" in
-+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
-+ *) optarg= ;;
-+ esac
-+
-+ case "$1" in
-+ --prefix=*)
-+ prefix=$optarg
-+ ;;
-+
-+ --prefix)
-+ echo $prefix
-+ ;;
-+
-+ --version)
-+ echo @VERSION@
-+ exit 0
-+ ;;
-+
-+ --help)
-+ usage 0
-+ ;;
-+
-+ --cflags)
-+ echo @XML_INCLUDEDIR@ @XML_CFLAGS@
-+ ;;
-+
-+ --libs)
-+ echo @XML_LIBDIR@ @XML_LIBS@
-+ ;;
-+
-+ *)
-+ usage
-+ exit 1
-+ ;;
-+ esac
-+ shift
-+done
-+
-+exit 0
-diff -Nru libxml2-2.3.0/libxml/xmlConf.sh.in libxml2-2.3.0.new/libxml/xmlConf.sh.in
---- libxml2-2.3.0/libxml/xmlConf.sh.in Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlConf.sh.in Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,8 @@
-+#
-+# Configuration file for using the XML library in GNOME applications
-+#
-+XML_LIBDIR="@XML_LIBDIR@"
-+XML_LIBS="@XML_LIBS@"
-+XML_INCLUDEDIR="@XML_INCLUDEDIR@"
-+MODULE_VERSION="xml-@VERSION@"
-+
-diff -Nru libxml2-2.3.0/libxml/xmlIO.c libxml2-2.3.0.new/libxml/xmlIO.c
---- libxml2-2.3.0/libxml/xmlIO.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlIO.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,1743 @@
-+/*
-+ * xmlIO.c : implementation of the I/O interfaces used by the parser
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ *
-+ * 14 Nov 2000 ht - for VMS, truncated name of long functions to under 32 char
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <errno.h>
-+
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_ZLIB_H
-+#include <zlib.h>
-+#endif
-+
-+/* Figure a portable way to know if a file is a directory. */
-+#ifndef HAVE_STAT
-+# ifdef HAVE__STAT
-+# define stat(x,y) _stat(x,y)
-+# define HAVE_STAT
-+# endif
-+#endif
-+#ifdef HAVE_STAT
-+# ifndef S_ISDIR
-+# ifdef _S_ISDIR
-+# define S_ISDIR(x) _S_ISDIR(x)
-+# else
-+# ifdef S_IFDIR
-+# ifndef S_IFMT
-+# ifdef _S_IFMT
-+# define S_IFMT _S_IFMT
-+# endif
-+# endif
-+# ifdef S_IFMT
-+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-+# endif
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/parser.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/xmlIO.h>
-+#include <libxml/nanohttp.h>
-+#include <libxml/nanoftp.h>
-+#include <libxml/xmlerror.h>
-+
-+#ifdef VMS
-+#define xmlRegisterDefaultInputCallbacks xmlRegisterDefInputCallbacks
-+#define xmlRegisterDefaultOutputCallbacks xmlRegisterDefOutputCallbacks
-+#endif
-+
-+/* #define VERBOSE_FAILURE */
-+/* #define DEBUG_EXTERNAL_ENTITIES */
-+/* #define DEBUG_INPUT */
-+
-+#ifdef DEBUG_INPUT
-+#define MINLEN 40
-+#else
-+#define MINLEN 4000
-+#endif
-+
-+/*
-+ * Input I/O callback sets
-+ */
-+typedef struct _xmlInputCallback {
-+ xmlInputMatchCallback matchcallback;
-+ xmlInputOpenCallback opencallback;
-+ xmlInputReadCallback readcallback;
-+ xmlInputCloseCallback closecallback;
-+} xmlInputCallback;
-+
-+#define MAX_INPUT_CALLBACK 15
-+
-+xmlInputCallback xmlInputCallbackTable[MAX_INPUT_CALLBACK];
-+int xmlInputCallbackNr = 0;
-+int xmlInputCallbackInitialized = 0;
-+
-+/*
-+ * Output I/O callback sets
-+ */
-+typedef struct _xmlOutputCallback {
-+ xmlOutputMatchCallback matchcallback;
-+ xmlOutputOpenCallback opencallback;
-+ xmlOutputWriteCallback writecallback;
-+ xmlOutputCloseCallback closecallback;
-+} xmlOutputCallback;
-+
-+#define MAX_OUTPUT_CALLBACK 15
-+
-+xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
-+int xmlOutputCallbackNr = 0;
-+int xmlOutputCallbackInitialized = 0;
-+
-+/************************************************************************
-+ * *
-+ * Standard I/O for file accesses *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlCheckFilename
-+ * @path: the path to check
-+ *
-+ * function checks to see if @path is a valid source
-+ * (file, socket...) for XML.
-+ *
-+ * if stat is not available on the target machine,
-+ * returns 1. if stat fails, returns 0 (if calling
-+ * stat on the filename fails, it can't be right).
-+ * if stat succeeds and the file is a directory,
-+ * sets errno to EISDIR and returns 0. otherwise
-+ * returns 1.
-+ */
-+
-+static int
-+xmlCheckFilename (const char *path)
-+{
-+#ifdef HAVE_STAT
-+#ifdef S_ISDIR
-+ struct stat stat_buffer;
-+
-+ if (stat(path, &stat_buffer) == -1)
-+ return 0;
-+
-+ if (S_ISDIR(stat_buffer.st_mode)) {
-+ errno = EISDIR;
-+ return 0;
-+ }
-+
-+#endif
-+#endif
-+ return 1;
-+}
-+
-+int
-+xmlNop(void) {
-+ return(0);
-+}
-+
-+/**
-+ * xmlFdMatch:
-+ * @filename: the URI for matching
-+ *
-+ * input from file descriptor
-+ *
-+ * Returns 1 if matches, 0 otherwise
-+ */
-+int
-+xmlFdMatch (const char *filename) {
-+ return(1);
-+}
-+
-+/**
-+ * xmlFdOpen:
-+ * @filename: the URI for matching
-+ *
-+ * input from file descriptor, supports compressed input
-+ * if @filename is " " then the standard input is used
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlFdOpen (const char *filename) {
-+ const char *path = NULL;
-+ int fd;
-+
-+ if (!strcmp(filename, "-")) {
-+ fd = 0;
-+ return((void *) fd);
-+ }
-+
-+ if (!strncmp(filename, "file://localhost", 16))
-+ path = &filename[16];
-+ else if (!strncmp(filename, "file:///", 8))
-+ path = &filename[8];
-+ else if (filename[0] == '/')
-+ path = filename;
-+ if (path == NULL)
-+ return(NULL);
-+
-+#ifdef WIN32
-+ fd = _open (path, O_RDONLY | _O_BINARY);
-+#else
-+ fd = open (path, O_RDONLY);
-+#endif
-+
-+ return((void *) fd);
-+}
-+
-+/**
-+ * xmlFdOpenW:
-+ * @filename: the URI for matching
-+ *
-+ * input from file descriptor,
-+ * if @filename is "-" then the standard output is used
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlFdOpenW (const char *filename) {
-+ const char *path = NULL;
-+ int fd;
-+
-+ if (!strcmp(filename, "-")) {
-+ fd = 1;
-+ return((void *) fd);
-+ }
-+
-+ if (!strncmp(filename, "file://localhost", 16))
-+ path = &filename[16];
-+ else if (!strncmp(filename, "file:///", 8))
-+ path = &filename[8];
-+ else if (filename[0] == '/')
-+ path = filename;
-+ if (path == NULL)
-+ return(NULL);
-+
-+ fd = open (path, O_WRONLY);
-+
-+ return((void *) fd);
-+}
-+
-+/**
-+ * xmlFdRead:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to read
-+ *
-+ * Read @len bytes to @buffer from the I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlFdRead (void * context, char * buffer, int len) {
-+ return(read((int) context, &buffer[0], len));
-+}
-+
-+/**
-+ * xmlFdWrite:
-+ * @context: the I/O context
-+ * @buffer: where to get data
-+ * @len: number of bytes to write
-+ *
-+ * Write @len bytes from @buffer to the I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlFdWrite (void * context, const char * buffer, int len) {
-+ return(write((int) context, &buffer[0], len));
-+}
-+
-+/**
-+ * xmlFdClose:
-+ * @context: the I/O context
-+ *
-+ * Close an I/O channel
-+ */
-+void
-+xmlFdClose (void * context) {
-+ close((int) context);
-+}
-+
-+/**
-+ * xmlFileMatch:
-+ * @filename: the URI for matching
-+ *
-+ * input from FILE *
-+ *
-+ * Returns 1 if matches, 0 otherwise
-+ */
-+int
-+xmlFileMatch (const char *filename) {
-+ return(1);
-+}
-+
-+/**
-+ * xmlFileOpen:
-+ * @filename: the URI for matching
-+ *
-+ * input from FILE *, supports compressed input
-+ * if @filename is " " then the standard input is used
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlFileOpen (const char *filename) {
-+ const char *path = NULL;
-+ FILE *fd;
-+
-+ if (!strcmp(filename, "-")) {
-+ fd = stdin;
-+ return((void *) fd);
-+ }
-+
-+ if (!strncmp(filename, "file://localhost", 16))
-+ path = &filename[16];
-+ else if (!strncmp(filename, "file:///", 8))
-+ path = &filename[8];
-+ else
-+ path = filename;
-+
-+ if (path == NULL)
-+ return(NULL);
-+ if (!xmlCheckFilename(path))
-+ return(NULL);
-+
-+#ifdef WIN32
-+ fd = fopen(path, "rb");
-+#else
-+ fd = fopen(path, "r");
-+#endif /* WIN32 */
-+ return((void *) fd);
-+}
-+
-+/**
-+ * xmlFileOpenW:
-+ * @filename: the URI for matching
-+ *
-+ * output to from FILE *,
-+ * if @filename is "-" then the standard output is used
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlFileOpenW (const char *filename) {
-+ const char *path = NULL;
-+ FILE *fd;
-+
-+ if (!strcmp(filename, "-")) {
-+ fd = stdout;
-+ return((void *) fd);
-+ }
-+
-+ if (!strncmp(filename, "file://localhost", 16))
-+ path = &filename[16];
-+ else if (!strncmp(filename, "file:///", 8))
-+ path = &filename[8];
-+ else
-+ path = filename;
-+
-+ if (path == NULL)
-+ return(NULL);
-+
-+ fd = fopen(path, "w");
-+ return((void *) fd);
-+}
-+
-+/**
-+ * xmlFileRead:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to write
-+ *
-+ * Read @len bytes to @buffer from the I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlFileRead (void * context, char * buffer, int len) {
-+ return(fread(&buffer[0], 1, len, (FILE *) context));
-+}
-+
-+/**
-+ * xmlFileWrite:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to write
-+ *
-+ * Write @len bytes from @buffer to the I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlFileWrite (void * context, const char * buffer, int len) {
-+ return(fwrite(&buffer[0], 1, len, (FILE *) context));
-+}
-+
-+/**
-+ * xmlFileClose:
-+ * @context: the I/O context
-+ *
-+ * Close an I/O channel
-+ */
-+void
-+xmlFileClose (void * context) {
-+ fclose((FILE *) context);
-+}
-+
-+/**
-+ * xmlFileFlush:
-+ * @context: the I/O context
-+ *
-+ * Flush an I/O channel
-+ */
-+void
-+xmlFileFlush (void * context) {
-+ fflush((FILE *) context);
-+}
-+
-+#ifdef HAVE_ZLIB_H
-+/************************************************************************
-+ * *
-+ * I/O for compressed file accesses *
-+ * *
-+ ************************************************************************/
-+/**
-+ * xmlGzfileMatch:
-+ * @filename: the URI for matching
-+ *
-+ * input from compressed file test
-+ *
-+ * Returns 1 if matches, 0 otherwise
-+ */
-+int
-+xmlGzfileMatch (const char *filename) {
-+ return(1);
-+}
-+
-+/**
-+ * xmlGzfileOpen:
-+ * @filename: the URI for matching
-+ *
-+ * input from compressed file open
-+ * if @filename is " " then the standard input is used
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlGzfileOpen (const char *filename) {
-+ const char *path = NULL;
-+ gzFile fd;
-+
-+ if (!strcmp(filename, "-")) {
-+ fd = gzdopen(fileno(stdin), "rb");
-+ return((void *) fd);
-+ }
-+
-+ if (!strncmp(filename, "file://localhost", 16))
-+ path = &filename[16];
-+ else if (!strncmp(filename, "file:///", 8))
-+ path = &filename[7];
-+ else
-+ path = filename;
-+
-+ if (path == NULL)
-+ return(NULL);
-+ if (!xmlCheckFilename(path))
-+ return(NULL);
-+
-+ fd = gzopen(path, "rb");
-+ return((void *) fd);
-+}
-+
-+/**
-+ * xmlGzfileOpenW:
-+ * @filename: the URI for matching
-+ * @compression: the compression factor (0 - 9 included)
-+ *
-+ * input from compressed file open
-+ * if @filename is " " then the standard input is used
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlGzfileOpenW (const char *filename, int compression) {
-+ const char *path = NULL;
-+ char mode[15];
-+ gzFile fd;
-+
-+ sprintf(mode, "wb%d", compression);
-+ if (!strcmp(filename, "-")) {
-+ fd = gzdopen(1, mode);
-+ return((void *) fd);
-+ }
-+
-+ if (!strncmp(filename, "file://localhost", 16))
-+ path = &filename[16];
-+ else if (!strncmp(filename, "file:///", 8))
-+ path = &filename[8];
-+ else
-+ path = filename;
-+
-+ if (path == NULL)
-+ return(NULL);
-+
-+ fd = gzopen(path, mode);
-+ return((void *) fd);
-+}
-+
-+/**
-+ * xmlGzfileRead:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to write
-+ *
-+ * Read @len bytes to @buffer from the compressed I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlGzfileRead (void * context, char * buffer, int len) {
-+ return(gzread((gzFile) context, &buffer[0], len));
-+}
-+
-+/**
-+ * xmlGzfileWrite:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to write
-+ *
-+ * Write @len bytes from @buffer to the compressed I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlGzfileWrite (void * context, const char * buffer, int len) {
-+ return(gzwrite((gzFile) context, (char *) &buffer[0], len));
-+}
-+
-+/**
-+ * xmlGzfileClose:
-+ * @context: the I/O context
-+ *
-+ * Close a compressed I/O channel
-+ */
-+void
-+xmlGzfileClose (void * context) {
-+ gzclose((gzFile) context);
-+}
-+#endif /* HAVE_ZLIB_H */
-+
-+#ifdef LIBXML_HTTP_ENABLED
-+/************************************************************************
-+ * *
-+ * I/O for HTTP file accesses *
-+ * *
-+ ************************************************************************/
-+/**
-+ * xmlIOHTTPMatch:
-+ * @filename: the URI for matching
-+ *
-+ * check if the URI matches an HTTP one
-+ *
-+ * Returns 1 if matches, 0 otherwise
-+ */
-+int
-+xmlIOHTTPMatch (const char *filename) {
-+ if (!strncmp(filename, "http://", 7))
-+ return(1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlIOHTTPOpen:
-+ * @filename: the URI for matching
-+ *
-+ * open an HTTP I/O channel
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlIOHTTPOpen (const char *filename) {
-+ return(xmlNanoHTTPOpen(filename, NULL));
-+}
-+
-+/**
-+ * xmlIOHTTPRead:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to write
-+ *
-+ * Read @len bytes to @buffer from the I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlIOHTTPRead(void * context, char * buffer, int len) {
-+ return(xmlNanoHTTPRead(context, &buffer[0], len));
-+}
-+
-+/**
-+ * xmlIOHTTPClose:
-+ * @context: the I/O context
-+ *
-+ * Close an HTTP I/O channel
-+ */
-+void
-+xmlIOHTTPClose (void * context) {
-+ xmlNanoHTTPClose(context);
-+}
-+#endif /* LIBXML_HTTP_ENABLED */
-+
-+#ifdef LIBXML_FTP_ENABLED
-+/************************************************************************
-+ * *
-+ * I/O for FTP file accesses *
-+ * *
-+ ************************************************************************/
-+/**
-+ * xmlIOFTPMatch:
-+ * @filename: the URI for matching
-+ *
-+ * check if the URI matches an FTP one
-+ *
-+ * Returns 1 if matches, 0 otherwise
-+ */
-+int
-+xmlIOFTPMatch (const char *filename) {
-+ if (!strncmp(filename, "ftp://", 6))
-+ return(1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlIOFTPOpen:
-+ * @filename: the URI for matching
-+ *
-+ * open an FTP I/O channel
-+ *
-+ * Returns an I/O context or NULL in case of error
-+ */
-+void *
-+xmlIOFTPOpen (const char *filename) {
-+ return(xmlNanoFTPOpen(filename));
-+}
-+
-+/**
-+ * xmlIOFTPRead:
-+ * @context: the I/O context
-+ * @buffer: where to drop data
-+ * @len: number of bytes to write
-+ *
-+ * Read @len bytes to @buffer from the I/O channel.
-+ *
-+ * Returns the number of bytes written
-+ */
-+int
-+xmlIOFTPRead(void * context, char * buffer, int len) {
-+ return(xmlNanoFTPRead(context, &buffer[0], len));
-+}
-+
-+/**
-+ * xmlIOFTPClose:
-+ * @context: the I/O context
-+ *
-+ * Close an FTP I/O channel
-+ */
-+void
-+xmlIOFTPClose (void * context) {
-+ xmlNanoFTPClose(context);
-+}
-+#endif /* LIBXML_FTP_ENABLED */
-+
-+
-+/**
-+ * xmlRegisterInputCallbacks:
-+ * @match: the xmlInputMatchCallback
-+ * @open: the xmlInputOpenCallback
-+ * @read: the xmlInputReadCallback
-+ * @close: the xmlInputCloseCallback
-+ *
-+ * Register a new set of I/O callback for handling parser input.
-+ *
-+ * Returns the registered handler number or -1 in case of error
-+ */
-+int
-+xmlRegisterInputCallbacks(xmlInputMatchCallback match,
-+ xmlInputOpenCallback open, xmlInputReadCallback read,
-+ xmlInputCloseCallback close) {
-+ if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) {
-+ return(-1);
-+ }
-+ xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = match;
-+ xmlInputCallbackTable[xmlInputCallbackNr].opencallback = open;
-+ xmlInputCallbackTable[xmlInputCallbackNr].readcallback = read;
-+ xmlInputCallbackTable[xmlInputCallbackNr].closecallback = close;
-+ return(xmlInputCallbackNr++);
-+}
-+
-+/**
-+ * xmlRegisterOutputCallbacks:
-+ * @match: the xmlOutputMatchCallback
-+ * @open: the xmlOutputOpenCallback
-+ * @write: the xmlOutputWriteCallback
-+ * @close: the xmlOutputCloseCallback
-+ *
-+ * Register a new set of I/O callback for handling output.
-+ *
-+ * Returns the registered handler number or -1 in case of error
-+ */
-+int
-+xmlRegisterOutputCallbacks(xmlOutputMatchCallback match,
-+ xmlOutputOpenCallback open, xmlOutputWriteCallback write,
-+ xmlOutputCloseCallback close) {
-+ if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) {
-+ return(-1);
-+ }
-+ xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = match;
-+ xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = open;
-+ xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = write;
-+ xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = close;
-+ return(xmlOutputCallbackNr++);
-+}
-+
-+/**
-+ * xmlRegisterDefaultInputCallbacks:
-+ *
-+ * Registers the default compiled-in I/O handlers.
-+ */
-+void
-+#ifdef VMS
-+xmlRegisterDefInputCallbacks
-+#else
-+xmlRegisterDefaultInputCallbacks
-+#endif
-+(void) {
-+ if (xmlInputCallbackInitialized)
-+ return;
-+
-+ xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
-+ xmlFileRead, xmlFileClose);
-+#ifdef HAVE_ZLIB_H
-+ xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
-+ xmlGzfileRead, xmlGzfileClose);
-+#endif /* HAVE_ZLIB_H */
-+
-+#ifdef LIBXML_HTTP_ENABLED
-+ xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
-+ xmlIOHTTPRead, xmlIOHTTPClose);
-+#endif /* LIBXML_HTTP_ENABLED */
-+
-+#ifdef LIBXML_FTP_ENABLED
-+ xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
-+ xmlIOFTPRead, xmlIOFTPClose);
-+#endif /* LIBXML_FTP_ENABLED */
-+ xmlInputCallbackInitialized = 1;
-+}
-+
-+/**
-+ * xmlRegisterDefaultOutputCallbacks:
-+ *
-+ * Registers the default compiled-in I/O handlers.
-+ */
-+void
-+#ifdef VMS
-+xmlRegisterDefOutputCallbacks
-+#else
-+xmlRegisterDefaultOutputCallbacks
-+#endif
-+(void) {
-+ if (xmlOutputCallbackInitialized)
-+ return;
-+
-+ xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
-+ xmlFileWrite, xmlFileClose);
-+/*********************************
-+ No way a-priori to distinguish between gzipped files from
-+ uncompressed ones except opening if existing then closing
-+ and saving with same compression ratio ... a pain.
-+
-+#ifdef HAVE_ZLIB_H
-+ xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
-+ xmlGzfileWrite, xmlGzfileClose);
-+#endif
-+ No HTTP PUT support yet, patches welcome
-+
-+#ifdef LIBXML_HTTP_ENABLED
-+ xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
-+ xmlIOHTTPWrite, xmlIOHTTPClose);
-+#endif
-+
-+ Nor FTP PUT ....
-+#ifdef LIBXML_FTP_ENABLED
-+ xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
-+ xmlIOFTPWrite, xmlIOFTPClose);
-+#endif
-+ **********************************/
-+ xmlOutputCallbackInitialized = 1;
-+}
-+
-+/**
-+ * xmlAllocParserInputBuffer:
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered parser input for progressive parsing
-+ *
-+ * Returns the new parser input or NULL
-+ */
-+xmlParserInputBufferPtr
-+xmlAllocParserInputBuffer(xmlCharEncoding enc) {
-+ xmlParserInputBufferPtr ret;
-+
-+ ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAllocParserInputBuffer : out of memory!\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
-+ ret->buffer = xmlBufferCreate();
-+ if (ret->buffer == NULL) {
-+ xmlFree(ret);
-+ return(NULL);
-+ }
-+ ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
-+ ret->encoder = xmlGetCharEncodingHandler(enc);
-+ if (ret->encoder != NULL)
-+ ret->raw = xmlBufferCreate();
-+ else
-+ ret->raw = NULL;
-+ ret->readcallback = NULL;
-+ ret->closecallback = NULL;
-+ ret->context = NULL;
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlAllocOutputBuffer:
-+ * @encoder: the encoding converter or NULL
-+ *
-+ * Create a buffered parser output
-+ *
-+ * Returns the new parser output or NULL
-+ */
-+xmlOutputBufferPtr
-+xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
-+ xmlOutputBufferPtr ret;
-+
-+ ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlAllocOutputBuffer : out of memory!\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
-+ ret->buffer = xmlBufferCreate();
-+ if (ret->buffer == NULL) {
-+ xmlFree(ret);
-+ return(NULL);
-+ }
-+ ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
-+ ret->encoder = encoder;
-+ if (encoder != NULL) {
-+ ret->conv = xmlBufferCreateSize(4000);
-+ /*
-+ * This call is designed to initiate the encoder state
-+ */
-+ xmlCharEncOutFunc(encoder, ret->conv, NULL);
-+ } else
-+ ret->conv = NULL;
-+ ret->writecallback = NULL;
-+ ret->closecallback = NULL;
-+ ret->context = NULL;
-+ ret->written = 0;
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlFreeParserInputBuffer:
-+ * @in: a buffered parser input
-+ *
-+ * Free up the memory used by a buffered parser input
-+ */
-+void
-+xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) {
-+ if (in->raw) {
-+ xmlBufferFree(in->raw);
-+ in->raw = NULL;
-+ }
-+ if (in->encoder != NULL) {
-+ xmlCharEncCloseFunc(in->encoder);
-+ }
-+ if (in->closecallback != NULL) {
-+ in->closecallback(in->context);
-+ }
-+ if (in->buffer != NULL) {
-+ xmlBufferFree(in->buffer);
-+ in->buffer = NULL;
-+ }
-+
-+ memset(in, 0xbe, (size_t) sizeof(xmlParserInputBuffer));
-+ xmlFree(in);
-+}
-+
-+/**
-+ * xmlOutputBufferClose:
-+ * @out: a buffered output
-+ *
-+ * flushes and close the output I/O channel
-+ * and free up all the associated resources
-+ *
-+ * Returns the number of byte written or -1 in case of error.
-+ */
-+int
-+xmlOutputBufferClose(xmlOutputBufferPtr out) {
-+ int written;
-+
-+ if (out == NULL)
-+ return(-1);
-+ if (out->writecallback != NULL)
-+ xmlOutputBufferFlush(out);
-+ if (out->closecallback != NULL) {
-+ out->closecallback(out->context);
-+ }
-+ written = out->written;
-+ if (out->conv) {
-+ xmlBufferFree(out->conv);
-+ out->conv = NULL;
-+ }
-+ if (out->encoder != NULL) {
-+ xmlCharEncCloseFunc(out->encoder);
-+ }
-+ if (out->buffer != NULL) {
-+ xmlBufferFree(out->buffer);
-+ out->buffer = NULL;
-+ }
-+
-+ memset(out, 0xbe, (size_t) sizeof(xmlOutputBuffer));
-+ xmlFree(out);
-+ return(written);
-+}
-+
-+/**
-+ * xmlParserInputBufferCreateFilename:
-+ * @URI: a C string containing the URI or filename
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered parser input for the progressive parsing of a file
-+ * If filename is "-' then we use stdin as the input.
-+ * Automatic support for ZLIB/Compress compressed document is provided
-+ * by default if found at compile-time.
-+ * Do an encoding check if enc == XML_CHAR_ENCODING_NONE
-+ *
-+ * Returns the new parser input or NULL
-+ */
-+xmlParserInputBufferPtr
-+#ifdef VMS
-+xmlParserInputBufferCreateFname
-+#else
-+xmlParserInputBufferCreateFilename
-+#endif
-+(const char *URI, xmlCharEncoding enc) {
-+ xmlParserInputBufferPtr ret;
-+ int i;
-+ void *context = NULL;
-+
-+ if (xmlInputCallbackInitialized == 0)
-+ xmlRegisterDefaultInputCallbacks();
-+
-+ if (URI == NULL) return(NULL);
-+
-+ /*
-+ * Try to find one of the input accept method accepting taht scheme
-+ * Go in reverse to give precedence to user defined handlers.
-+ */
-+ for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
-+ if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
-+ (xmlInputCallbackTable[i].matchcallback(URI) != 0)) {
-+ context = xmlInputCallbackTable[i].opencallback(URI);
-+ if (context != NULL)
-+ break;
-+ }
-+ }
-+ if (context == NULL) {
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate the Input buffer front-end.
-+ */
-+ ret = xmlAllocParserInputBuffer(enc);
-+ if (ret != NULL) {
-+ ret->context = context;
-+ ret->readcallback = xmlInputCallbackTable[i].readcallback;
-+ ret->closecallback = xmlInputCallbackTable[i].closecallback;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlOutputBufferCreateFilename:
-+ * @URI: a C string containing the URI or filename
-+ * @encoder: the encoding converter or NULL
-+ * @compression: the compression ration (0 none, 9 max).
-+ *
-+ * Create a buffered output for the progressive saving of a file
-+ * If filename is "-' then we use stdout as the output.
-+ * Automatic support for ZLIB/Compress compressed document is provided
-+ * by default if found at compile-time.
-+ * TODO: currently if compression is set, the library only support
-+ * writing to a local file.
-+ *
-+ * Returns the new output or NULL
-+ */
-+xmlOutputBufferPtr
-+xmlOutputBufferCreateFilename(const char *URI,
-+ xmlCharEncodingHandlerPtr encoder,
-+ int compression) {
-+ xmlOutputBufferPtr ret;
-+ int i;
-+ void *context = NULL;
-+
-+ if (xmlOutputCallbackInitialized == 0)
-+ xmlRegisterDefaultOutputCallbacks();
-+
-+ if (URI == NULL) return(NULL);
-+
-+#ifdef HAVE_ZLIB_H
-+ if ((compression > 0) && (compression <= 9)) {
-+ context = xmlGzfileOpenW(URI, compression);
-+ if (context != NULL) {
-+ ret = xmlAllocOutputBuffer(encoder);
-+ if (ret != NULL) {
-+ ret->context = context;
-+ ret->writecallback = xmlGzfileWrite;
-+ ret->closecallback = xmlGzfileClose;
-+ }
-+ return(ret);
-+ }
-+ }
-+#endif
-+
-+ /*
-+ * Try to find one of the output accept method accepting taht scheme
-+ * Go in reverse to give precedence to user defined handlers.
-+ */
-+ for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
-+ if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
-+ (xmlOutputCallbackTable[i].matchcallback(URI) != 0)) {
-+ context = xmlOutputCallbackTable[i].opencallback(URI);
-+ if (context != NULL)
-+ break;
-+ }
-+ }
-+ if (context == NULL) {
-+ return(NULL);
-+ }
-+
-+ /*
-+ * Allocate the Output buffer front-end.
-+ */
-+ ret = xmlAllocOutputBuffer(encoder);
-+ if (ret != NULL) {
-+ ret->context = context;
-+ ret->writecallback = xmlOutputCallbackTable[i].writecallback;
-+ ret->closecallback = xmlOutputCallbackTable[i].closecallback;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputBufferCreateFile:
-+ * @file: a FILE*
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered parser input for the progressive parsing of a FILE *
-+ * buffered C I/O
-+ *
-+ * Returns the new parser input or NULL
-+ */
-+xmlParserInputBufferPtr
-+xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) {
-+ xmlParserInputBufferPtr ret;
-+
-+ if (xmlInputCallbackInitialized == 0)
-+ xmlRegisterDefaultInputCallbacks();
-+
-+ if (file == NULL) return(NULL);
-+
-+ ret = xmlAllocParserInputBuffer(enc);
-+ if (ret != NULL) {
-+ ret->context = file;
-+ ret->readcallback = xmlFileRead;
-+ ret->closecallback = xmlFileFlush;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlOutputBufferCreateFile:
-+ * @file: a FILE*
-+ * @encoder: the encoding converter or NULL
-+ *
-+ * Create a buffered output for the progressive saving to a FILE *
-+ * buffered C I/O
-+ *
-+ * Returns the new parser output or NULL
-+ */
-+xmlOutputBufferPtr
-+xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
-+ xmlOutputBufferPtr ret;
-+
-+ if (xmlOutputCallbackInitialized == 0)
-+ xmlRegisterDefaultOutputCallbacks();
-+
-+ if (file == NULL) return(NULL);
-+
-+ ret = xmlAllocOutputBuffer(encoder);
-+ if (ret != NULL) {
-+ ret->context = file;
-+ ret->writecallback = xmlFileWrite;
-+ ret->closecallback = xmlFileFlush;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputBufferCreateFd:
-+ * @fd: a file descriptor number
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered parser input for the progressive parsing for the input
-+ * from a file descriptor
-+ *
-+ * Returns the new parser input or NULL
-+ */
-+xmlParserInputBufferPtr
-+xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
-+ xmlParserInputBufferPtr ret;
-+
-+ if (fd < 0) return(NULL);
-+
-+ ret = xmlAllocParserInputBuffer(enc);
-+ if (ret != NULL) {
-+ ret->context = (void *) fd;
-+ ret->readcallback = xmlFdRead;
-+ ret->closecallback = xmlFdClose;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputBufferCreateMem:
-+ * @mem: the memory input
-+ * @size: the length of the memory block
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered parser input for the progressive parsing for the input
-+ * from a memory area.
-+ *
-+ * Returns the new parser input or NULL
-+ */
-+xmlParserInputBufferPtr
-+xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
-+ xmlParserInputBufferPtr ret;
-+
-+ if (size <= 0) return(NULL);
-+ if (mem == NULL) return(NULL);
-+
-+ ret = xmlAllocParserInputBuffer(enc);
-+ if (ret != NULL) {
-+ ret->context = (void *) mem;
-+ ret->readcallback = (xmlInputReadCallback) xmlNop;
-+ ret->closecallback = NULL;
-+ xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size);
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlOutputBufferCreateFd:
-+ * @fd: a file descriptor number
-+ * @encoder: the encoding converter or NULL
-+ *
-+ * Create a buffered output for the progressive saving
-+ * to a file descriptor
-+ *
-+ * Returns the new parser output or NULL
-+ */
-+xmlOutputBufferPtr
-+xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
-+ xmlOutputBufferPtr ret;
-+
-+ if (fd < 0) return(NULL);
-+
-+ ret = xmlAllocOutputBuffer(encoder);
-+ if (ret != NULL) {
-+ ret->context = (void *) fd;
-+ ret->writecallback = xmlFdWrite;
-+ ret->closecallback = xmlFdClose;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputBufferCreateIO:
-+ * @ioread: an I/O read function
-+ * @ioclose: an I/O close function
-+ * @ioctx: an I/O handler
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered parser input for the progressive parsing for the input
-+ * from an I/O handler
-+ *
-+ * Returns the new parser input or NULL
-+ */
-+xmlParserInputBufferPtr
-+xmlParserInputBufferCreateIO(xmlInputReadCallback ioread,
-+ xmlInputCloseCallback ioclose, void *ioctx, xmlCharEncoding enc) {
-+ xmlParserInputBufferPtr ret;
-+
-+ if (ioread == NULL) return(NULL);
-+
-+ ret = xmlAllocParserInputBuffer(enc);
-+ if (ret != NULL) {
-+ ret->context = (void *) ioctx;
-+ ret->readcallback = ioread;
-+ ret->closecallback = ioclose;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlOutputBufferCreateIO:
-+ * @iowrite: an I/O write function
-+ * @ioclose: an I/O close function
-+ * @ioctx: an I/O handler
-+ * @enc: the charset encoding if known
-+ *
-+ * Create a buffered output for the progressive saving
-+ * to an I/O handler
-+ *
-+ * Returns the new parser output or NULL
-+ */
-+xmlOutputBufferPtr
-+xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite,
-+ xmlOutputCloseCallback ioclose, void *ioctx,
-+ xmlCharEncodingHandlerPtr encoder) {
-+ xmlOutputBufferPtr ret;
-+
-+ if (iowrite == NULL) return(NULL);
-+
-+ ret = xmlAllocOutputBuffer(encoder);
-+ if (ret != NULL) {
-+ ret->context = (void *) ioctx;
-+ ret->writecallback = iowrite;
-+ ret->closecallback = ioclose;
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlParserInputBufferPush:
-+ * @in: a buffered parser input
-+ * @len: the size in bytes of the array.
-+ * @buf: an char array
-+ *
-+ * Push the content of the arry in the input buffer
-+ * This routine handle the I18N transcoding to internal UTF-8
-+ * This is used when operating the parser in progressive (push) mode.
-+ *
-+ * Returns the number of chars read and stored in the buffer, or -1
-+ * in case of error.
-+ */
-+int
-+xmlParserInputBufferPush(xmlParserInputBufferPtr in,
-+ int len, const char *buf) {
-+ int nbchars = 0;
-+
-+ if (len < 0) return(0);
-+ if (in->encoder != NULL) {
-+ /*
-+ * Store the data in the incoming raw buffer
-+ */
-+ if (in->raw == NULL) {
-+ in->raw = xmlBufferCreate();
-+ }
-+ xmlBufferAdd(in->raw, (const xmlChar *) buf, len);
-+
-+ /*
-+ * convert as much as possible to the parser reading buffer.
-+ */
-+ nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-+ if (nbchars < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInputBufferPush: encoder error\n");
-+ return(-1);
-+ }
-+ } else {
-+ nbchars = len;
-+ xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
-+ }
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext,
-+ "I/O: pushed %d chars, buffer %d/%d\n",
-+ nbchars, in->buffer->use, in->buffer->size);
-+#endif
-+ return(nbchars);
-+}
-+
-+/**
-+ * xmlParserInputBufferGrow:
-+ * @in: a buffered parser input
-+ * @len: indicative value of the amount of chars to read
-+ *
-+ * Grow up the content of the input buffer, the old data are preserved
-+ * This routine handle the I18N transcoding to internal UTF-8
-+ * This routine is used when operating the parser in normal (pull) mode
-+ *
-+ * TODO: one should be able to remove one extra copy by copying directy
-+ * onto in->buffer or in->raw
-+ *
-+ * Returns the number of chars read and stored in the buffer, or -1
-+ * in case of error.
-+ */
-+int
-+xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
-+ char *buffer = NULL;
-+ int res = 0;
-+ int nbchars = 0;
-+ int buffree;
-+
-+ if ((len <= MINLEN) && (len != 4))
-+ len = MINLEN;
-+ buffree = in->buffer->size - in->buffer->use;
-+ if (buffree <= 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInputBufferGrow : buffer full !\n");
-+ return(0);
-+ }
-+ if (len > buffree)
-+ len = buffree;
-+
-+ buffer = (char *) xmlMalloc((len + 1) * sizeof(char));
-+ if (buffer == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInputBufferGrow : out of memory !\n");
-+ return(-1);
-+ }
-+
-+ /*
-+ * Call the read method for this I/O type.
-+ */
-+ if (in->readcallback != NULL) {
-+ res = in->readcallback(in->context, &buffer[0], len);
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInputBufferGrow : no input !\n");
-+ xmlFree(buffer);
-+ return(-1);
-+ }
-+ if (res < 0) {
-+ perror ("read error");
-+ xmlFree(buffer);
-+ return(-1);
-+ }
-+ len = res;
-+ if (in->encoder != NULL) {
-+ /*
-+ * Store the data in the incoming raw buffer
-+ */
-+ if (in->raw == NULL) {
-+ in->raw = xmlBufferCreate();
-+ }
-+ xmlBufferAdd(in->raw, (const xmlChar *) buffer, len);
-+
-+ /*
-+ * convert as much as possible to the parser reading buffer.
-+ */
-+ nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-+ if (nbchars < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlParserInputBufferGrow: encoder error\n");
-+ return(-1);
-+ }
-+ } else {
-+ nbchars = len;
-+ buffer[nbchars] = 0;
-+ xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars);
-+ }
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext,
-+ "I/O: read %d chars, buffer %d/%d\n",
-+ nbchars, in->buffer->use, in->buffer->size);
-+#endif
-+ xmlFree(buffer);
-+ return(nbchars);
-+}
-+
-+/**
-+ * xmlParserInputBufferRead:
-+ * @in: a buffered parser input
-+ * @len: indicative value of the amount of chars to read
-+ *
-+ * Refresh the content of the input buffer, the old data are considered
-+ * consumed
-+ * This routine handle the I18N transcoding to internal UTF-8
-+ *
-+ * Returns the number of chars read and stored in the buffer, or -1
-+ * in case of error.
-+ */
-+int
-+xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) {
-+ /* xmlBufferEmpty(in->buffer); */
-+ if (in->readcallback != NULL)
-+ return(xmlParserInputBufferGrow(in, len));
-+ else
-+ return(-1);
-+}
-+
-+/**
-+ * xmlOutputBufferWrite:
-+ * @out: a buffered parser output
-+ * @len: the size in bytes of the array.
-+ * @buf: an char array
-+ *
-+ * Write the content of the array in the output I/O buffer
-+ * This routine handle the I18N transcoding from internal UTF-8
-+ * The buffer is lossless, i.e. will store in case of partial
-+ * or delayed writes.
-+ *
-+ * Returns the number of chars immediately written, or -1
-+ * in case of error.
-+ */
-+int
-+xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
-+ int nbchars = 0; /* number of chars to output to I/O */
-+ int ret; /* return from function call */
-+ int written = 0; /* number of char written to I/O so far */
-+ int chunk; /* number of byte curreent processed from buf */
-+
-+ if (len < 0) return(0);
-+
-+ do {
-+ chunk = len;
-+ if (chunk > 4 * MINLEN)
-+ chunk = 4 * MINLEN;
-+
-+ /*
-+ * first handle encoding stuff.
-+ */
-+ if (out->encoder != NULL) {
-+ /*
-+ * Store the data in the incoming raw buffer
-+ */
-+ if (out->conv == NULL) {
-+ out->conv = xmlBufferCreate();
-+ }
-+ xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
-+
-+ if ((out->buffer->use < MINLEN) && (chunk == len))
-+ goto done;
-+
-+ /*
-+ * convert as much as possible to the parser reading buffer.
-+ */
-+ ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
-+ if (ret < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlOutputBufferWrite: encoder error\n");
-+ return(-1);
-+ }
-+ nbchars = out->conv->use;
-+ } else {
-+ xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
-+ nbchars = out->buffer->use;
-+ }
-+ buf += chunk;
-+ len -= chunk;
-+
-+ if ((nbchars < MINLEN) && (len <= 0))
-+ goto done;
-+
-+ if (out->writecallback) {
-+ /*
-+ * second write the stuff to the I/O channel
-+ */
-+ if (out->encoder != NULL) {
-+ ret = out->writecallback(out->context,
-+ (const char *)out->conv->content, nbchars);
-+ if (ret >= 0)
-+ xmlBufferShrink(out->conv, nbchars);
-+ } else {
-+ ret = out->writecallback(out->context,
-+ (const char *)out->buffer->content, nbchars);
-+ if (ret >= 0)
-+ xmlBufferShrink(out->buffer, nbchars);
-+ }
-+ if (ret < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "I/O: error %d writing %d bytes\n", ret, nbchars);
-+ return(ret);
-+ }
-+ out->written += ret;
-+ }
-+ written += nbchars;
-+ } while (len > 0);
-+
-+done:
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext,
-+ "I/O: wrote %d chars\n", written);
-+#endif
-+ return(written);
-+}
-+
-+/**
-+ * xmlOutputBufferWriteString:
-+ * @out: a buffered parser output
-+ * @str: a zero terminated C string
-+ *
-+ * Write the content of the string in the output I/O buffer
-+ * This routine handle the I18N transcoding from internal UTF-8
-+ * The buffer is lossless, i.e. will store in case of partial
-+ * or delayed writes.
-+ *
-+ * Returns the number of chars immediately written, or -1
-+ * in case of error.
-+ */
-+int
-+xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
-+ int len;
-+
-+ if (str == NULL)
-+ return(-1);
-+ len = strlen(str);
-+
-+ if (len > 0)
-+ return(xmlOutputBufferWrite(out, len, str));
-+ return(len);
-+}
-+
-+/**
-+ * xmlOutputBufferFlush:
-+ * @out: a buffered output
-+ *
-+ * flushes the output I/O channel
-+ *
-+ * Returns the number of byte written or -1 in case of error.
-+ */
-+int
-+xmlOutputBufferFlush(xmlOutputBufferPtr out) {
-+ int nbchars = 0, ret = 0;
-+
-+ /*
-+ * first handle encoding stuff.
-+ */
-+ if ((out->conv != NULL) && (out->encoder != NULL)) {
-+ /*
-+ * convert as much as possible to the parser reading buffer.
-+ */
-+ nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
-+ if (nbchars < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlOutputBufferWrite: encoder error\n");
-+ return(-1);
-+ }
-+ }
-+
-+ /*
-+ * second flush the stuff to the I/O channel
-+ */
-+ if ((out->conv != NULL) && (out->encoder != NULL) &&
-+ (out->writecallback != NULL)) {
-+ ret = out->writecallback(out->context,
-+ (const char *)out->conv->content, out->conv->use);
-+ if (ret >= 0)
-+ xmlBufferShrink(out->conv, ret);
-+ } else if (out->writecallback != NULL) {
-+ ret = out->writecallback(out->context,
-+ (const char *)out->buffer->content, out->buffer->use);
-+ if (ret >= 0)
-+ xmlBufferShrink(out->buffer, ret);
-+ }
-+ if (ret < 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "I/O: error %d flushing %d bytes\n", ret, nbchars);
-+ return(ret);
-+ }
-+ out->written += ret;
-+
-+#ifdef DEBUG_INPUT
-+ xmlGenericError(xmlGenericErrorContext,
-+ "I/O: flushed %d chars\n", ret);
-+#endif
-+ return(ret);
-+}
-+
-+/*
-+ * xmlParserGetDirectory:
-+ * @filename: the path to a file
-+ *
-+ * lookup the directory for that file
-+ *
-+ * Returns a new allocated string containing the directory, or NULL.
-+ */
-+char *
-+xmlParserGetDirectory(const char *filename) {
-+ char *ret = NULL;
-+ char dir[1024];
-+ char *cur;
-+ char sep = '/';
-+
-+ if (xmlInputCallbackInitialized == 0)
-+ xmlRegisterDefaultInputCallbacks();
-+
-+ if (filename == NULL) return(NULL);
-+#ifdef WIN32
-+ sep = '\\';
-+#endif
-+
-+ strncpy(dir, filename, 1023);
-+ dir[1023] = 0;
-+ cur = &dir[strlen(dir)];
-+ while (cur > dir) {
-+ if (*cur == sep) break;
-+ cur --;
-+ }
-+ if (*cur == sep) {
-+ if (cur == dir) dir[1] = 0;
-+ else *cur = 0;
-+ ret = xmlMemStrdup(dir);
-+ } else {
-+ if (getcwd(dir, 1024) != NULL) {
-+ dir[1023] = 0;
-+ ret = xmlMemStrdup(dir);
-+ }
-+ }
-+ return(ret);
-+}
-+
-+/****************************************************************
-+ * *
-+ * External entities loading *
-+ * *
-+ ****************************************************************/
-+
-+/*
-+ * xmlDefaultExternalEntityLoader:
-+ * @URL: the URL for the entity to load
-+ * @ID: the System ID for the entity to load
-+ * @ctxt: the context in which the entity is called or NULL
-+ *
-+ * By default we don't load external entitites, yet.
-+ *
-+ * Returns a new allocated xmlParserInputPtr, or NULL.
-+ */
-+static
-+xmlParserInputPtr
-+xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
-+ xmlParserCtxtPtr ctxt) {
-+ xmlParserInputPtr ret = NULL;
-+
-+#ifdef DEBUG_EXTERNAL_ENTITIES
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
-+#endif
-+ if (URL == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt,
-+ "failed to load external entity \"%s\"\n", ID);
-+ return(NULL);
-+ }
-+ ret = xmlNewInputFromFile(ctxt, URL);
-+ if (ret == NULL) {
-+ if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-+ ctxt->sax->warning(ctxt,
-+ "failed to load external entity \"%s\"\n", URL);
-+ }
-+ return(ret);
-+}
-+
-+static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
-+ xmlDefaultExternalEntityLoader;
-+
-+/*
-+ * xmlSetExternalEntityLoader:
-+ * @f: the new entity resolver function
-+ *
-+ * Changes the defaultexternal entity resolver function for the application
-+ */
-+void
-+xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
-+ xmlCurrentExternalEntityLoader = f;
-+}
-+
-+/*
-+ * xmlGetExternalEntityLoader:
-+ *
-+ * Get the default external entity resolver function for the application
-+ *
-+ * Returns the xmlExternalEntityLoader function pointer
-+ */
-+xmlExternalEntityLoader
-+xmlGetExternalEntityLoader(void) {
-+ return(xmlCurrentExternalEntityLoader);
-+}
-+
-+/*
-+ * xmlLoadExternalEntity:
-+ * @URL: the URL for the entity to load
-+ * @ID: the System ID for the entity to load
-+ * @ctxt: the context in which the entity is called or NULL
-+ *
-+ * Load an external entity, note that the use of this function for
-+ * unparsed entities may generate problems
-+ * TODO: a more generic External entitiy API must be designed
-+ *
-+ * Returns the xmlParserInputPtr or NULL
-+ */
-+xmlParserInputPtr
-+xmlLoadExternalEntity(const char *URL, const char *ID,
-+ xmlParserCtxtPtr ctxt) {
-+ return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));
-+}
-+
-diff -Nru libxml2-2.3.0/libxml/xmlIO.h libxml2-2.3.0.new/libxml/xmlIO.h
---- libxml2-2.3.0/libxml/xmlIO.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlIO.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,178 @@
-+/*
-+ * xmlIO.h : interface for the I/O interfaces used by the parser
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ *
-+ * 15 Nov 2000 ht - modified for VMS
-+ */
-+
-+#ifndef __XML_IO_H__
-+#define __XML_IO_H__
-+
-+#include <stdio.h>
-+#include <libxml/tree.h>
-+#include <libxml/parser.h>
-+#include <libxml/encoding.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * Those are the functions and datatypes for the parser input
-+ * I/O structures.
-+ */
-+
-+typedef int (*xmlInputMatchCallback) (char const *filename);
-+typedef void * (*xmlInputOpenCallback) (char const *filename);
-+typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
-+typedef void (*xmlInputCloseCallback) (void * context);
-+
-+typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
-+typedef xmlParserInputBuffer *xmlParserInputBufferPtr;
-+struct _xmlParserInputBuffer {
-+ void* context;
-+ xmlInputReadCallback readcallback;
-+ xmlInputCloseCallback closecallback;
-+
-+ xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
-+
-+ xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 */
-+ xmlBufferPtr raw; /* if encoder != NULL buffer for raw input */
-+};
-+
-+
-+/*
-+ * Those are the functions and datatypes for the library output
-+ * I/O structures.
-+ */
-+
-+typedef int (*xmlOutputMatchCallback) (char const *filename);
-+typedef void * (*xmlOutputOpenCallback) (char const *filename);
-+typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
-+ int len);
-+typedef void (*xmlOutputCloseCallback) (void * context);
-+
-+typedef struct _xmlOutputBuffer xmlOutputBuffer;
-+typedef xmlOutputBuffer *xmlOutputBufferPtr;
-+struct _xmlOutputBuffer {
-+ void* context;
-+ xmlOutputWriteCallback writecallback;
-+ xmlOutputCloseCallback closecallback;
-+
-+ xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
-+
-+ xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 or ISOLatin */
-+ xmlBufferPtr conv; /* if encoder != NULL buffer for output */
-+ int written; /* total number of byte written */
-+};
-+
-+/*
-+ * Interfaces for input
-+ */
-+
-+void xmlRegisterDefaultInputCallbacks (void);
-+xmlParserInputBufferPtr
-+ xmlAllocParserInputBuffer (xmlCharEncoding enc);
-+
-+#ifdef VMS
-+xmlParserInputBufferPtr
-+ xmlParserInputBufferCreateFname (const char *URI,
-+ xmlCharEncoding enc);
-+#define xmlParserInputBufferCreateFilename xmlParserInputBufferCreateFname
-+#else
-+xmlParserInputBufferPtr
-+ xmlParserInputBufferCreateFilename (const char *URI,
-+ xmlCharEncoding enc);
-+#endif
-+
-+xmlParserInputBufferPtr
-+ xmlParserInputBufferCreateFile (FILE *file,
-+ xmlCharEncoding enc);
-+xmlParserInputBufferPtr
-+ xmlParserInputBufferCreateFd (int fd,
-+ xmlCharEncoding enc);
-+xmlParserInputBufferPtr
-+ xmlParserInputBufferCreateMem (const char *mem, int size,
-+ xmlCharEncoding enc);
-+xmlParserInputBufferPtr
-+ xmlParserInputBufferCreateIO (xmlInputReadCallback ioread,
-+ xmlInputCloseCallback ioclose,
-+ void *ioctx,
-+ xmlCharEncoding enc);
-+int xmlParserInputBufferRead (xmlParserInputBufferPtr in,
-+ int len);
-+int xmlParserInputBufferGrow (xmlParserInputBufferPtr in,
-+ int len);
-+int xmlParserInputBufferPush (xmlParserInputBufferPtr in,
-+ int len,
-+ const char *buf);
-+void xmlFreeParserInputBuffer (xmlParserInputBufferPtr in);
-+char * xmlParserGetDirectory (const char *filename);
-+
-+int xmlRegisterInputCallbacks (xmlInputMatchCallback match,
-+ xmlInputOpenCallback open,
-+ xmlInputReadCallback read,
-+ xmlInputCloseCallback close);
-+/*
-+ * Interfaces for output
-+ */
-+void xmlRegisterDefaultOutputCallbacks(void);
-+xmlOutputBufferPtr
-+ xmlAllocOutputBuffer (xmlCharEncodingHandlerPtr encoder);
-+
-+xmlOutputBufferPtr
-+ xmlOutputBufferCreateFilename (const char *URI,
-+ xmlCharEncodingHandlerPtr encoder,
-+ int compression);
-+
-+xmlOutputBufferPtr
-+ xmlOutputBufferCreateFile (FILE *file,
-+ xmlCharEncodingHandlerPtr encoder);
-+
-+xmlOutputBufferPtr
-+ xmlOutputBufferCreateFd (int fd,
-+ xmlCharEncodingHandlerPtr encoder);
-+
-+xmlOutputBufferPtr
-+ xmlOutputBufferCreateIO (xmlOutputWriteCallback iowrite,
-+ xmlOutputCloseCallback ioclose,
-+ void *ioctx,
-+ xmlCharEncodingHandlerPtr encoder);
-+
-+int xmlOutputBufferWrite (xmlOutputBufferPtr out,
-+ int len,
-+ const char *buf);
-+int xmlOutputBufferWriteString (xmlOutputBufferPtr out,
-+ const char *str);
-+
-+int xmlOutputBufferFlush (xmlOutputBufferPtr out);
-+int xmlOutputBufferClose (xmlOutputBufferPtr out);
-+
-+int xmlRegisterOutputCallbacks (xmlOutputMatchCallback match,
-+ xmlOutputOpenCallback open,
-+ xmlOutputWriteCallback write,
-+ xmlOutputCloseCallback close);
-+
-+/*
-+ * This save function are part of tree.h and HTMLtree.h actually
-+ */
-+int xmlSaveFileTo (xmlOutputBuffer *buf,
-+ xmlDocPtr cur,
-+ const char *encoding);
-+void xmlNodeDumpOutput (xmlOutputBufferPtr buf,
-+ xmlDocPtr doc,
-+ xmlNodePtr cur,
-+ int level,
-+ int format,
-+ const char *encoding);
-+void htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
-+ xmlDocPtr cur,
-+ const char *encoding);
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __XML_IO_H__ */
-diff -Nru libxml2-2.3.0/libxml/xmlerror.h libxml2-2.3.0.new/libxml/xmlerror.h
---- libxml2-2.3.0/libxml/xmlerror.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlerror.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,180 @@
-+#ifndef __XML_ERROR_H__
-+#define __XML_ERROR_H__
-+
-+#include <libxml/parser.h>
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef enum {
-+ XML_ERR_OK = 0,
-+ XML_ERR_INTERNAL_ERROR,
-+ XML_ERR_NO_MEMORY,
-+
-+ XML_ERR_DOCUMENT_START, /* 3 */
-+ XML_ERR_DOCUMENT_EMPTY,
-+ XML_ERR_DOCUMENT_END,
-+
-+ XML_ERR_INVALID_HEX_CHARREF, /* 6 */
-+ XML_ERR_INVALID_DEC_CHARREF,
-+ XML_ERR_INVALID_CHARREF,
-+ XML_ERR_INVALID_CHAR,
-+
-+ XML_ERR_CHARREF_AT_EOF, /* 10 */
-+ XML_ERR_CHARREF_IN_PROLOG,
-+ XML_ERR_CHARREF_IN_EPILOG,
-+ XML_ERR_CHARREF_IN_DTD,
-+ XML_ERR_ENTITYREF_AT_EOF,
-+ XML_ERR_ENTITYREF_IN_PROLOG,
-+ XML_ERR_ENTITYREF_IN_EPILOG,
-+ XML_ERR_ENTITYREF_IN_DTD,
-+ XML_ERR_PEREF_AT_EOF,
-+ XML_ERR_PEREF_IN_PROLOG,
-+ XML_ERR_PEREF_IN_EPILOG,
-+ XML_ERR_PEREF_IN_INT_SUBSET,
-+
-+ XML_ERR_ENTITYREF_NO_NAME, /* 22 */
-+ XML_ERR_ENTITYREF_SEMICOL_MISSING,
-+
-+ XML_ERR_PEREF_NO_NAME, /* 24 */
-+ XML_ERR_PEREF_SEMICOL_MISSING,
-+
-+ XML_ERR_UNDECLARED_ENTITY, /* 26 */
-+ XML_WAR_UNDECLARED_ENTITY,
-+ XML_ERR_UNPARSED_ENTITY,
-+ XML_ERR_ENTITY_IS_EXTERNAL,
-+ XML_ERR_ENTITY_IS_PARAMETER,
-+
-+ XML_ERR_UNKNOWN_ENCODING, /* 31 */
-+ XML_ERR_UNSUPPORTED_ENCODING,
-+
-+ XML_ERR_STRING_NOT_STARTED, /* 33 */
-+ XML_ERR_STRING_NOT_CLOSED,
-+ XML_ERR_NS_DECL_ERROR,
-+
-+ XML_ERR_ENTITY_NOT_STARTED, /* 36 */
-+ XML_ERR_ENTITY_NOT_FINISHED,
-+
-+ XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
-+ XML_ERR_ATTRIBUTE_NOT_STARTED,
-+ XML_ERR_ATTRIBUTE_NOT_FINISHED,
-+ XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
-+ XML_ERR_ATTRIBUTE_REDEFINED,
-+
-+ XML_ERR_LITERAL_NOT_STARTED, /* 43 */
-+ XML_ERR_LITERAL_NOT_FINISHED,
-+
-+ XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
-+
-+ XML_ERR_PI_NOT_STARTED, /* 47 */
-+ XML_ERR_PI_NOT_FINISHED,
-+
-+ XML_ERR_NOTATION_NOT_STARTED, /* 49 */
-+ XML_ERR_NOTATION_NOT_FINISHED,
-+
-+ XML_ERR_ATTLIST_NOT_STARTED, /* 51 */
-+ XML_ERR_ATTLIST_NOT_FINISHED,
-+
-+ XML_ERR_MIXED_NOT_STARTED, /* 53 */
-+ XML_ERR_MIXED_NOT_FINISHED,
-+
-+ XML_ERR_ELEMCONTENT_NOT_STARTED, /* 55 */
-+ XML_ERR_ELEMCONTENT_NOT_FINISHED,
-+
-+ XML_ERR_XMLDECL_NOT_STARTED, /* 57 */
-+ XML_ERR_XMLDECL_NOT_FINISHED,
-+
-+ XML_ERR_CONDSEC_NOT_STARTED, /* 59 */
-+ XML_ERR_CONDSEC_NOT_FINISHED,
-+
-+ XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 61 */
-+
-+ XML_ERR_DOCTYPE_NOT_FINISHED, /* 62 */
-+
-+ XML_ERR_MISPLACED_CDATA_END, /* 63 */
-+ XML_ERR_CDATA_NOT_FINISHED,
-+
-+ XML_ERR_RESERVED_XML_NAME, /* 65 */
-+
-+ XML_ERR_SPACE_REQUIRED, /* 66 */
-+ XML_ERR_SEPARATOR_REQUIRED,
-+ XML_ERR_NMTOKEN_REQUIRED,
-+ XML_ERR_NAME_REQUIRED,
-+ XML_ERR_PCDATA_REQUIRED,
-+ XML_ERR_URI_REQUIRED,
-+ XML_ERR_PUBID_REQUIRED,
-+ XML_ERR_LT_REQUIRED,
-+ XML_ERR_GT_REQUIRED,
-+ XML_ERR_LTSLASH_REQUIRED,
-+ XML_ERR_EQUAL_REQUIRED,
-+
-+ XML_ERR_TAG_NAME_MISMATCH, /* 77 */
-+ XML_ERR_TAG_NOT_FINISED,
-+
-+ XML_ERR_STANDALONE_VALUE, /* 79 */
-+
-+ XML_ERR_ENCODING_NAME, /* 80 */
-+
-+ XML_ERR_HYPHEN_IN_COMMENT, /* 81 */
-+
-+ XML_ERR_INVALID_ENCODING, /* 82 */
-+
-+ XML_ERR_EXT_ENTITY_STANDALONE, /* 83 */
-+
-+ XML_ERR_CONDSEC_INVALID, /* 84 */
-+
-+ XML_ERR_VALUE_REQUIRED, /* 85 */
-+
-+ XML_ERR_NOT_WELL_BALANCED, /* 86 */
-+ XML_ERR_EXTRA_CONTENT, /* 87 */
-+ XML_ERR_ENTITY_CHAR_ERROR, /* 88 */
-+ XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
-+ XML_ERR_ENTITY_LOOP, /* 89 */
-+ XML_ERR_ENTITY_BOUNDARY, /* 90 */
-+ XML_ERR_INVALID_URI, /* 91 */
-+ XML_ERR_URI_FRAGMENT /* 92 */
-+}xmlParserErrors;
-+
-+/*
-+ * Signature of the function to use when there is an error and
-+ * no parsing or validity context available
-+ */
-+typedef void (*xmlGenericErrorFunc) (void *ctx, const char *msg, ...);
-+
-+/*
-+ * Those are the default error function and associated context to use
-+ * when when there is an error and no parsing or validity context available
-+ */
-+
-+LIBXML_DLL_IMPORT extern xmlGenericErrorFunc xmlGenericError;
-+LIBXML_DLL_IMPORT extern void *xmlGenericErrorContext;
-+
-+/*
-+ * Use the following function to reset the two previous global variables.
-+ */
-+void xmlSetGenericErrorFunc (void *ctx,
-+ xmlGenericErrorFunc handler);
-+
-+/*
-+ * Default message routines used by SAX and Valid context for error
-+ * and warning reporting
-+ */
-+void xmlParserError (void *ctx,
-+ const char *msg,
-+ ...);
-+void xmlParserWarning (void *ctx,
-+ const char *msg,
-+ ...);
-+void xmlParserValidityError (void *ctx,
-+ const char *msg,
-+ ...);
-+void xmlParserValidityWarning(void *ctx,
-+ const char *msg,
-+ ...);
-+void xmlParserPrintFileInfo (xmlParserInputPtr input);
-+void xmlParserPrintFileContext(xmlParserInputPtr input);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_ERROR_H__ */
-diff -Nru libxml2-2.3.0/libxml/xmlmemory.c libxml2-2.3.0.new/libxml/xmlmemory.c
---- libxml2-2.3.0/libxml/xmlmemory.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlmemory.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,707 @@
-+/*
-+ * memory.c: libxml memory allocator wrapper.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#ifdef HAVE_TIME_H
-+#include <time.h>
-+#endif
-+#ifdef HAVE_MALLOC_H
-+#include <malloc.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/xmlerror.h>
-+
-+#ifdef xmlMalloc
-+#undef xmlMalloc
-+#endif
-+#ifdef xmlRealloc
-+#undef xmlRealloc
-+#endif
-+#ifdef xmlMemStrdup
-+#undef xmlMemStrdup
-+#endif
-+
-+
-+/*
-+ * Each of the blocks allocated begin with a header containing informations
-+ */
-+
-+#define MEMTAG 0x5aa5
-+
-+#define MALLOC_TYPE 1
-+#define REALLOC_TYPE 2
-+#define STRDUP_TYPE 3
-+
-+typedef struct memnod {
-+ unsigned int mh_tag;
-+ unsigned int mh_type;
-+ unsigned long mh_number;
-+ size_t mh_size;
-+#ifdef MEM_LIST
-+ struct memnod *mh_next;
-+ struct memnod *mh_prev;
-+#endif
-+ const char *mh_file;
-+ unsigned int mh_line;
-+} MEMHDR;
-+
-+
-+#ifdef SUN4
-+#define ALIGN_SIZE 16
-+#else
-+#define ALIGN_SIZE sizeof(double)
-+#endif
-+#define HDR_SIZE sizeof(MEMHDR)
-+#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
-+ / ALIGN_SIZE ) * ALIGN_SIZE)
-+
-+
-+#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
-+#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
-+
-+
-+static unsigned long debugMemSize = 0;
-+static unsigned long debugMaxMemSize = 0;
-+static int block=0;
-+int xmlMemStopAtBlock = 0;
-+int xmlMemInitialized = 0;
-+#ifdef MEM_LIST
-+static MEMHDR *memlist = NULL;
-+#endif
-+
-+void debugmem_tag_error(void *addr);
-+#ifdef MEM_LIST
-+void debugmem_list_add(MEMHDR *);
-+void debugmem_list_delete(MEMHDR *);
-+#endif
-+#define Mem_Tag_Err(a) debugmem_tag_error(a);
-+
-+#ifndef TEST_POINT
-+#define TEST_POINT
-+#endif
-+
-+/**
-+ * xmlMallocBreakpoint:
-+ *
-+ * Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
-+ * number reaches the specified value this function is called. One need to add a breakpoint
-+ * to it to get the context in which the given block is allocated.
-+ */
-+
-+void
-+xmlMallocBreakpoint(void) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
-+}
-+
-+/**
-+ * xmlMallocLoc:
-+ * @size: an int specifying the size in byte to allocate.
-+ * @file: the file name or NULL
-+ * @line: the line number
-+ *
-+ * a malloc() equivalent, with logging of the allocation info.
-+ *
-+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
-+ */
-+
-+void *
-+xmlMallocLoc(int size, const char * file, int line)
-+{
-+ MEMHDR *p;
-+
-+ if (!xmlMemInitialized) xmlInitMemory();
-+#ifdef DEBUG_MEMORY
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Malloc(%d)\n",size);
-+#endif
-+
-+ TEST_POINT
-+
-+ p = (MEMHDR *) malloc(RESERVE_SIZE+size);
-+
-+ if (!p) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlMalloc : Out of free space\n");
-+ xmlMemoryDump();
-+ return(NULL);
-+ }
-+ p->mh_tag = MEMTAG;
-+ p->mh_number = ++block;
-+ p->mh_size = size;
-+ p->mh_type = MALLOC_TYPE;
-+ p->mh_file = file;
-+ p->mh_line = line;
-+ debugMemSize += size;
-+ if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
-+#ifdef MEM_LIST
-+ debugmem_list_add(p);
-+#endif
-+
-+#ifdef DEBUG_MEMORY
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Malloc(%d) Ok\n",size);
-+#endif
-+
-+ if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
-+
-+ TEST_POINT
-+
-+ return(HDR_2_CLIENT(p));
-+}
-+
-+/**
-+ * xmlMemMalloc:
-+ * @size: an int specifying the size in byte to allocate.
-+ *
-+ * a malloc() equivalent, with logging of the allocation info.
-+ *
-+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
-+ */
-+
-+void *
-+xmlMemMalloc(int size)
-+{
-+ return(xmlMallocLoc(size, "none", 0));
-+}
-+
-+/**
-+ * xmlReallocLoc:
-+ * @ptr: the initial memory block pointer
-+ * @size: an int specifying the size in byte to allocate.
-+ * @file: the file name or NULL
-+ * @line: the line number
-+ *
-+ * a realloc() equivalent, with logging of the allocation info.
-+ *
-+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
-+ */
-+
-+void *
-+xmlReallocLoc(void *ptr,int size, const char * file, int line)
-+{
-+ MEMHDR *p;
-+ unsigned long number;
-+
-+ if (!xmlMemInitialized) xmlInitMemory();
-+ TEST_POINT
-+
-+ p = CLIENT_2_HDR(ptr);
-+ number = p->mh_number;
-+ if (p->mh_tag != MEMTAG) {
-+ Mem_Tag_Err(p);
-+ goto error;
-+ }
-+ p->mh_tag = ~MEMTAG;
-+ debugMemSize -= p->mh_size;
-+#ifdef MEM_LIST
-+ debugmem_list_delete(p);
-+#endif
-+
-+ p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
-+ if (!p) {
-+ goto error;
-+ }
-+ p->mh_tag = MEMTAG;
-+ p->mh_number = number;
-+ p->mh_type = REALLOC_TYPE;
-+ p->mh_size = size;
-+ p->mh_file = file;
-+ p->mh_line = line;
-+ debugMemSize += size;
-+ if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
-+#ifdef MEM_LIST
-+ debugmem_list_add(p);
-+#endif
-+
-+ TEST_POINT
-+
-+ return(HDR_2_CLIENT(p));
-+
-+error:
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlMemRealloc:
-+ * @ptr: the initial memory block pointer
-+ * @size: an int specifying the size in byte to allocate.
-+ *
-+ * a realloc() equivalent, with logging of the allocation info.
-+ *
-+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
-+ */
-+
-+void *
-+xmlMemRealloc(void *ptr,int size) {
-+ return(xmlReallocLoc(ptr, size, "none", 0));
-+}
-+
-+/**
-+ * xmlMemFree:
-+ * @ptr: the memory block pointer
-+ *
-+ * a free() equivalent, with error checking.
-+ */
-+void
-+xmlMemFree(void *ptr)
-+{
-+ MEMHDR *p;
-+
-+ TEST_POINT
-+
-+ p = CLIENT_2_HDR(ptr);
-+ if (p->mh_tag != MEMTAG) {
-+ Mem_Tag_Err(p);
-+ goto error;
-+ }
-+ p->mh_tag = ~MEMTAG;
-+ debugMemSize -= p->mh_size;
-+
-+#ifdef MEM_LIST
-+ debugmem_list_delete(p);
-+#endif
-+ free(p);
-+
-+ TEST_POINT
-+
-+ return;
-+
-+error:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlFree(%X) error\n", (unsigned int) ptr);
-+ return;
-+}
-+
-+/**
-+ * xmlMemStrdupLoc:
-+ * @ptr: the initial string pointer
-+ * @file: the file name or NULL
-+ * @line: the line number
-+ *
-+ * a strdup() equivalent, with logging of the allocation info.
-+ *
-+ * Returns a pointer to the new string or NULL if allocation error occured.
-+ */
-+
-+char *
-+xmlMemStrdupLoc(const char *str, const char *file, int line)
-+{
-+ char *s;
-+ size_t size = strlen(str) + 1;
-+ MEMHDR *p;
-+
-+ if (!xmlMemInitialized) xmlInitMemory();
-+ TEST_POINT
-+
-+ p = (MEMHDR *) malloc(RESERVE_SIZE+size);
-+ if (!p) {
-+ goto error;
-+ }
-+ p->mh_tag = MEMTAG;
-+ p->mh_number = ++block;
-+ p->mh_size = size;
-+ p->mh_type = STRDUP_TYPE;
-+ p->mh_file = file;
-+ p->mh_line = line;
-+ debugMemSize += size;
-+ if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
-+#ifdef MEM_LIST
-+ debugmem_list_add(p);
-+#endif
-+ s = (char *) HDR_2_CLIENT(p);
-+
-+ if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
-+
-+ if (s != NULL)
-+ strcpy(s,str);
-+ else
-+ goto error;
-+
-+ TEST_POINT
-+
-+ return(s);
-+
-+error:
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlMemoryStrdup:
-+ * @ptr: the initial string pointer
-+ *
-+ * a strdup() equivalent, with logging of the allocation info.
-+ *
-+ * Returns a pointer to the new string or NULL if allocation error occured.
-+ */
-+
-+char *
-+xmlMemoryStrdup(const char *str) {
-+ return(xmlMemStrdupLoc(str, "none", 0));
-+}
-+
-+/**
-+ * xmlMemUsed:
-+ *
-+ * returns the amount of memory currenly allocated
-+ *
-+ * Returns an int representing the amount of memory allocated.
-+ */
-+
-+int
-+xmlMemUsed(void) {
-+ return(debugMemSize);
-+}
-+
-+#ifdef MEM_LIST
-+/**
-+ * xmlMemContentShow:
-+ * @fp: a FILE descriptor used as the output file
-+ * @p: a memory block header
-+ *
-+ * tries to show some content from the memory block
-+ */
-+
-+void
-+xmlMemContentShow(FILE *fp, MEMHDR *p)
-+{
-+ int i,j,len = p->mh_size;
-+ const char *buf = (const char *) HDR_2_CLIENT(p);
-+
-+ if (p == NULL) {
-+ fprintf(fp, " NULL");
-+ return;
-+ }
-+
-+ for (i = 0;i < len;i++) {
-+ if (buf[i] == 0) break;
-+ if (!isprint(buf[i])) break;
-+ }
-+ if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
-+ if (len >= 4) {
-+ MEMHDR *q;
-+ void *cur;
-+
-+ for (j = 0;j < len -3;j += 4) {
-+ cur = *((void **) &buf[j]);
-+ q = CLIENT_2_HDR(cur);
-+ p = memlist;
-+ while (p != NULL) {
-+ if (p == q) break;
-+ p = p->mh_next;
-+ }
-+ if ((p != NULL) && (p == q)) {
-+ fprintf(fp, " pointer to #%lu at index %d",
-+ p->mh_number, j);
-+ return;
-+ }
-+ }
-+ }
-+ } else if ((i == 0) && (buf[i] == 0)) {
-+ fprintf(fp," null");
-+ } else {
-+ if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
-+ else {
-+ fprintf(fp," [");
-+ for (j = 0;j < i;j++)
-+ fprintf(fp,"%c", buf[j]);
-+ fprintf(fp,"]");
-+ }
-+ }
-+}
-+#endif
-+
-+/**
-+ * xmlMemShow:
-+ * @fp: a FILE descriptor used as the output file
-+ * @nr: number of entries to dump
-+ *
-+ * show a show display of the memory allocated, and dump
-+ * the @nr last allocated areas which were not freed
-+ */
-+
-+void
-+xmlMemShow(FILE *fp, int nr)
-+{
-+#ifdef MEM_LIST
-+ MEMHDR *p;
-+#endif
-+
-+ if (fp != NULL)
-+ fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
-+ debugMemSize, debugMaxMemSize);
-+#ifdef MEM_LIST
-+ if (nr > 0) {
-+ fprintf(fp,"NUMBER SIZE TYPE WHERE\n");
-+ p = memlist;
-+ while ((p) && nr > 0) {
-+ fprintf(fp,"%6lu %6u ",p->mh_number,p->mh_size);
-+ switch (p->mh_type) {
-+ case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
-+ case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
-+ case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
-+ default:fprintf(fp," ??? in ");break;
-+ }
-+ if (p->mh_file != NULL)
-+ fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
-+ if (p->mh_tag != MEMTAG)
-+ fprintf(fp," INVALID");
-+ xmlMemContentShow(fp, p);
-+ fprintf(fp,"\n");
-+ nr--;
-+ p = p->mh_next;
-+ }
-+ }
-+#endif /* MEM_LIST */
-+}
-+
-+/**
-+ * xmlMemDisplay:
-+ * @fp: a FILE descriptor used as the output file, if NULL, the result is
-+ * written to the file .memorylist
-+ *
-+ * show in-extenso the memory blocks allocated
-+ */
-+
-+void
-+xmlMemDisplay(FILE *fp)
-+{
-+#ifdef MEM_LIST
-+ MEMHDR *p;
-+ int idx;
-+#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
-+ time_t currentTime;
-+ char buf[500];
-+ struct tm * tstruct;
-+
-+ currentTime = time(NULL);
-+ tstruct = localtime(¤tTime);
-+ strftime(buf, sizeof(buf) - 1, "%c", tstruct);
-+ fprintf(fp," %s\n\n", buf);
-+#endif
-+
-+
-+ fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
-+ debugMemSize, debugMaxMemSize);
-+ fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
-+ idx = 0;
-+ p = memlist;
-+ while (p) {
-+ fprintf(fp,"%-5u %6lu %6u ",idx++,p->mh_number,p->mh_size);
-+ switch (p->mh_type) {
-+ case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
-+ case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
-+ case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
-+ default:fprintf(fp," ??? in ");break;
-+ }
-+ if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
-+ if (p->mh_tag != MEMTAG)
-+ fprintf(fp," INVALID");
-+ xmlMemContentShow(fp, p);
-+ fprintf(fp,"\n");
-+ p = p->mh_next;
-+ }
-+#else
-+ fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
-+#endif
-+}
-+
-+#ifdef MEM_LIST
-+
-+void debugmem_list_add(MEMHDR *p)
-+{
-+ p->mh_next = memlist;
-+ p->mh_prev = NULL;
-+ if (memlist) memlist->mh_prev = p;
-+ memlist = p;
-+#ifdef MEM_LIST_DEBUG
-+ if (stderr)
-+ Mem_Display(stderr);
-+#endif
-+}
-+
-+void debugmem_list_delete(MEMHDR *p)
-+{
-+ if (p->mh_next)
-+ p->mh_next->mh_prev = p->mh_prev;
-+ if (p->mh_prev)
-+ p->mh_prev->mh_next = p->mh_next;
-+ else memlist = p->mh_next;
-+#ifdef MEM_LIST_DEBUG
-+ if (stderr)
-+ Mem_Display(stderr);
-+#endif
-+}
-+
-+#endif
-+
-+/*
-+ * debugmem_tag_error : internal error function.
-+ */
-+
-+void debugmem_tag_error(void *p)
-+{
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Memory tag error occurs :%p \n\t bye\n", p);
-+#ifdef MEM_LIST
-+ if (stderr)
-+ xmlMemDisplay(stderr);
-+#endif
-+}
-+
-+FILE *xmlMemoryDumpFile = NULL;
-+
-+
-+/**
-+ * xmlMemoryDump:
-+ *
-+ * Dump in-extenso the memory blocks allocated to the file .memorylist
-+ */
-+
-+void
-+xmlMemoryDump(void)
-+{
-+#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
-+ FILE *dump;
-+
-+ dump = fopen(".memdump", "w");
-+ if (dump == NULL) xmlMemoryDumpFile = stdout;
-+ else xmlMemoryDumpFile = dump;
-+
-+ xmlMemDisplay(xmlMemoryDumpFile);
-+
-+ if (dump != NULL) fclose(dump);
-+#endif
-+}
-+
-+
-+/****************************************************************
-+ * *
-+ * Initialization Routines *
-+ * *
-+ ****************************************************************/
-+
-+#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
-+xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
-+xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
-+xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
-+xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
-+#else
-+xmlFreeFunc xmlFree = (xmlFreeFunc) free;
-+xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc;
-+xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc;
-+xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) strdup;
-+#endif
-+
-+/**
-+ * xmlInitMemory:
-+ *
-+ * Initialize the memory layer.
-+ *
-+ * Returns 0 on success
-+ */
-+
-+static int xmlInitMemoryDone = 0;
-+
-+int
-+xmlInitMemory(void)
-+{
-+ int ret;
-+
-+#ifdef HAVE_STDLIB_H
-+ char *breakpoint;
-+#endif
-+
-+ if (xmlInitMemoryDone) return(-1);
-+
-+#ifdef HAVE_STDLIB_H
-+ breakpoint = getenv("XML_MEM_BREAKPOINT");
-+ if (breakpoint != NULL) {
-+ sscanf(breakpoint, "%d", &xmlMemStopAtBlock);
-+ }
-+#endif
-+
-+#ifdef DEBUG_MEMORY
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlInitMemory() Ok\n");
-+#endif
-+ ret = 0;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlMemSetup:
-+ * @freeFunc: the free() function to use
-+ * @mallocFunc: the malloc() function to use
-+ * @reallocFunc: the realloc() function to use
-+ * @strdupFunc: the strdup() function to use
-+ *
-+ * Override the default memory access functions with a new set
-+ * This has to be called before any other libxml routines !
-+ *
-+ * Should this be blocked if there was already some allocations
-+ * done ?
-+ *
-+ * Returns 0 on success
-+ */
-+int
-+xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
-+ xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
-+ if (freeFunc == NULL)
-+ return(-1);
-+ if (mallocFunc == NULL)
-+ return(-1);
-+ if (reallocFunc == NULL)
-+ return(-1);
-+ if (strdupFunc == NULL)
-+ return(-1);
-+ xmlFree = freeFunc;
-+ xmlMalloc = mallocFunc;
-+ xmlRealloc = reallocFunc;
-+ xmlMemStrdup = strdupFunc;
-+ return(0);
-+}
-+
-+/**
-+ * xmlMemGet:
-+ * @freeFunc: the free() function in use
-+ * @mallocFunc: the malloc() function in use
-+ * @reallocFunc: the realloc() function in use
-+ * @strdupFunc: the strdup() function in use
-+ *
-+ * Return the memory access functions set currently in use
-+ *
-+ * Returns 0 on success
-+ */
-+int
-+xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
-+ xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
-+ if (freeFunc != NULL) *freeFunc = xmlFree;
-+ if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
-+ if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
-+ if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
-+ return(0);
-+}
-+
-diff -Nru libxml2-2.3.0/libxml/xmlmemory.h libxml2-2.3.0.new/libxml/xmlmemory.h
---- libxml2-2.3.0/libxml/xmlmemory.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlmemory.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,91 @@
-+/*
-+ * xmlmemory.h: interface for the memory allocation debug.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+
-+#ifndef _DEBUG_MEMORY_ALLOC_
-+#define _DEBUG_MEMORY_ALLOC_
-+
-+#include <stdio.h>
-+#include <libxml/xmlversion.h>
-+
-+/*
-+ * DEBUG_MEMORY_LOCATION should be activated only done when debugging
-+ * libxml.
-+ */
-+/* #define DEBUG_MEMORY_LOCATION */
-+
-+#ifdef DEBUG
-+#ifndef DEBUG_MEMORY
-+#define DEBUG_MEMORY
-+#endif
-+#endif
-+
-+#ifdef DEBUG_MEMORY_LOCATION
-+#define MEM_LIST /* keep a list of all the allocated memory blocks */
-+#endif
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * The XML memory wrapper support 4 basic overloadable functions
-+ */
-+typedef void (*xmlFreeFunc)(void *);
-+typedef void *(*xmlMallocFunc)(int);
-+typedef void *(*xmlReallocFunc)(void *, int);
-+typedef char *(*xmlStrdupFunc)(const char *);
-+
-+/*
-+ * The 4 interfaces used for all memory handling within libxml
-+ */
-+LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
-+LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
-+LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
-+LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
-+
-+/*
-+ * The way to overload the existing functions
-+ */
-+int xmlMemSetup (xmlFreeFunc freeFunc,
-+ xmlMallocFunc mallocFunc,
-+ xmlReallocFunc reallocFunc,
-+ xmlStrdupFunc strdupFunc);
-+int xmlMemGet (xmlFreeFunc *freeFunc,
-+ xmlMallocFunc *mallocFunc,
-+ xmlReallocFunc *reallocFunc,
-+ xmlStrdupFunc *strdupFunc);
-+
-+/*
-+ * Initialization of the memory layer
-+ */
-+int xmlInitMemory (void);
-+
-+/*
-+ * Those are specific to the XML debug memory wrapper
-+ */
-+int xmlMemUsed (void);
-+void xmlMemDisplay (FILE *fp);
-+void xmlMemShow (FILE *fp, int nr);
-+void xmlMemoryDump (void);
-+int xmlInitMemory (void);
-+
-+#ifdef DEBUG_MEMORY_LOCATION
-+#define xmlMalloc(x) xmlMallocLoc((x), __FILE__, __LINE__)
-+#define xmlRealloc(p, x) xmlReallocLoc((p), (x), __FILE__, __LINE__)
-+#define xmlMemStrdup(x) xmlMemStrdupLoc((x), __FILE__, __LINE__)
-+
-+void * xmlMallocLoc(int size, const char *file, int line);
-+void * xmlReallocLoc(void *ptr,int size, const char *file, int line);
-+char * xmlMemStrdupLoc(const char *str, const char *file, int line);
-+#endif /* DEBUG_MEMORY_LOCATION */
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* _DEBUG_MEMORY_ALLOC_ */
-+
-diff -Nru libxml2-2.3.0/libxml/xmlversion.h libxml2-2.3.0.new/libxml/xmlversion.h
---- libxml2-2.3.0/libxml/xmlversion.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlversion.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,129 @@
-+/*
-+ * xmlversion.h : compile-time version informations for the XML parser.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_VERSION_H__
-+#define __XML_VERSION_H__
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * use those to be sure nothing nasty will happen if
-+ * your library and includes mismatch
-+ */
-+extern void xmlCheckVersion(int version);
-+#define LIBXML_DOTTED_VERSION "2.3.0"
-+#define LIBXML_VERSION 20300
-+#define LIBXML_VERSION_STRING "20300"
-+#define LIBXML_TEST_VERSION xmlCheckVersion(20300);
-+
-+/*
-+ * Whether the FTP support is configured in
-+ */
-+#if 1
-+#define LIBXML_FTP_ENABLED
-+#else
-+#define LIBXML_FTP_DISABLED
-+#endif
-+
-+/*
-+ * Whether the HTTP support is configured in
-+ */
-+#if 1
-+#define LIBXML_HTTP_ENABLED
-+#else
-+#define LIBXML_HTTP_DISABLED
-+#endif
-+
-+/*
-+ * Whether the HTML support is configured in
-+ */
-+#if 1
-+#define LIBXML_HTML_ENABLED
-+#else
-+#define LIBXML_HTML_DISABLED
-+#endif
-+
-+/*
-+ * Whether the Docbook support is configured in
-+#if @WITH_SGML@
-+#define LIBXML_SGML_ENABLED
-+#else
-+#define LIBXML_SGML_DISABLED
-+#endif
-+ */
-+
-+/*
-+ * Whether XPath is configured in
-+ */
-+#if 1
-+#define LIBXML_XPATH_ENABLED
-+#else
-+#define LIBXML_XPATH_DISABLED
-+#endif
-+
-+/*
-+ * Whether XPointer is configured in
-+ */
-+#if 1
-+#define LIBXML_XPTR_ENABLED
-+#else
-+#define LIBXML_XPTR_DISABLED
-+#endif
-+
-+/*
-+ * Whether XInclude is configured in
-+ */
-+#if 1
-+#define LIBXML_XINCLUDE_ENABLED
-+#else
-+#define LIBXML_XINCLUDE_DISABLED
-+#endif
-+
-+/*
-+ * Whether iconv support is available
-+ */
-+#ifndef WIN32
-+#if 1
-+#define LIBXML_ICONV_ENABLED
-+#else
-+#define LIBXML_ICONV_DISABLED
-+#endif
-+#endif
-+
-+/*
-+ * Whether Debugging module is configured in
-+ */
-+#if 1
-+#define LIBXML_DEBUG_ENABLED
-+#else
-+#define LIBXML_DEBUG_DISABLED
-+#endif
-+
-+/*
-+ * Whether the memory debugging is configured in
-+ */
-+#if 0
-+#define DEBUG_MEMORY_LOCATION
-+#endif
-+
-+#ifndef LIBXML_DLL_IMPORT
-+#if defined(WIN32) && !defined(STATIC)
-+#define LIBXML_DLL_IMPORT __declspec(dllimport)
-+#else
-+#define LIBXML_DLL_IMPORT
-+#endif
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+#endif
-+
-+
-diff -Nru libxml2-2.3.0/libxml/xmlversion.h.in libxml2-2.3.0.new/libxml/xmlversion.h.in
---- libxml2-2.3.0/libxml/xmlversion.h.in Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xmlversion.h.in Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,129 @@
-+/*
-+ * xmlversion.h : compile-time version informations for the XML parser.
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_VERSION_H__
-+#define __XML_VERSION_H__
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * use those to be sure nothing nasty will happen if
-+ * your library and includes mismatch
-+ */
-+extern void xmlCheckVersion(int version);
-+#define LIBXML_DOTTED_VERSION "@VERSION@"
-+#define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
-+#define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
-+#define LIBXML_TEST_VERSION xmlCheckVersion(@LIBXML_VERSION_NUMBER@);
-+
-+/*
-+ * Whether the FTP support is configured in
-+ */
-+#if @WITH_FTP@
-+#define LIBXML_FTP_ENABLED
-+#else
-+#define LIBXML_FTP_DISABLED
-+#endif
-+
-+/*
-+ * Whether the HTTP support is configured in
-+ */
-+#if @WITH_HTTP@
-+#define LIBXML_HTTP_ENABLED
-+#else
-+#define LIBXML_HTTP_DISABLED
-+#endif
-+
-+/*
-+ * Whether the HTML support is configured in
-+ */
-+#if @WITH_HTML@
-+#define LIBXML_HTML_ENABLED
-+#else
-+#define LIBXML_HTML_DISABLED
-+#endif
-+
-+/*
-+ * Whether the Docbook support is configured in
-+#if @WITH_SGML@
-+#define LIBXML_SGML_ENABLED
-+#else
-+#define LIBXML_SGML_DISABLED
-+#endif
-+ */
-+
-+/*
-+ * Whether XPath is configured in
-+ */
-+#if @WITH_XPATH@
-+#define LIBXML_XPATH_ENABLED
-+#else
-+#define LIBXML_XPATH_DISABLED
-+#endif
-+
-+/*
-+ * Whether XPointer is configured in
-+ */
-+#if @WITH_XPTR@
-+#define LIBXML_XPTR_ENABLED
-+#else
-+#define LIBXML_XPTR_DISABLED
-+#endif
-+
-+/*
-+ * Whether XInclude is configured in
-+ */
-+#if @WITH_XINCLUDE@
-+#define LIBXML_XINCLUDE_ENABLED
-+#else
-+#define LIBXML_XINCLUDE_DISABLED
-+#endif
-+
-+/*
-+ * Whether iconv support is available
-+ */
-+#ifndef WIN32
-+#if @WITH_ICONV@
-+#define LIBXML_ICONV_ENABLED
-+#else
-+#define LIBXML_ICONV_DISABLED
-+#endif
-+#endif
-+
-+/*
-+ * Whether Debugging module is configured in
-+ */
-+#if @WITH_DEBUG@
-+#define LIBXML_DEBUG_ENABLED
-+#else
-+#define LIBXML_DEBUG_DISABLED
-+#endif
-+
-+/*
-+ * Whether the memory debugging is configured in
-+ */
-+#if @WITH_MEM_DEBUG@
-+#define DEBUG_MEMORY_LOCATION
-+#endif
-+
-+#ifndef LIBXML_DLL_IMPORT
-+#if defined(WIN32) && !defined(STATIC)
-+#define LIBXML_DLL_IMPORT __declspec(dllimport)
-+#else
-+#define LIBXML_DLL_IMPORT
-+#endif
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+#endif
-+
-+
-diff -Nru libxml2-2.3.0/libxml/xpath.c libxml2-2.3.0.new/libxml/xpath.c
---- libxml2-2.3.0/libxml/xpath.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xpath.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,6293 @@
-+/*
-+ * xpath.c: XML Path Language implementation
-+ * XPath is a language for addressing parts of an XML document,
-+ * designed to be used by both XSLT and XPointer
-+ *
-+ * Reference: W3C Recommendation 16 November 1999
-+ * http://www.w3.org/TR/1999/REC-xpath-19991116
-+ * Public reference:
-+ * http://www.w3.org/TR/xpath
-+ *
-+ * See COPYRIGHT for the status of this software
-+ *
-+ * Author: Daniel.Veillard@w3.org
-+ *
-+ * 14 Nov 2000 ht - truncated declaration of xmlXPathEvalRelativeLocationPath
-+ * for VMS
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+#include <libxml/xmlversion.h>
-+#ifdef LIBXML_XPATH_ENABLED
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#ifdef HAVE_MATH_H
-+#include <math.h>
-+#endif
-+#ifdef HAVE_FLOAT_H
-+#include <float.h>
-+#endif
-+#ifdef HAVE_IEEEFP_H
-+#include <ieeefp.h>
-+#endif
-+#ifdef HAVE_NAN_H
-+#include <nan.h>
-+#endif
-+#ifdef HAVE_CTYPE_H
-+#include <ctype.h>
-+#endif
-+
-+#include <libxml/xmlmemory.h>
-+#include <libxml/tree.h>
-+#include <libxml/valid.h>
-+#include <libxml/xpath.h>
-+#include <libxml/xpathInternals.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/hash.h>
-+#ifdef LIBXML_XPTR_ENABLED
-+#include <libxml/xpointer.h>
-+#endif
-+#ifdef LIBXML_DEBUG_ENABLED
-+#include <libxml/debugXML.h>
-+#endif
-+#include <libxml/xmlerror.h>
-+
-+/* #define DEBUG */
-+/* #define DEBUG_STEP */
-+/* #define DEBUG_EXPR */
-+
-+void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+double xmlXPathStringEvalNumber(const xmlChar *str);
-+
-+/*
-+ * Setup stuff for floating point
-+ * The lack of portability of this section of the libc is annoying !
-+ */
-+double xmlXPathNAN = 0;
-+double xmlXPathPINF = 1;
-+double xmlXPathNINF = -1;
-+
-+#ifndef isinf
-+#ifndef HAVE_ISINF
-+
-+#if HAVE_FPCLASS
-+
-+int isinf(double d) {
-+ fpclass_t type = fpclass(d);
-+ switch (type) {
-+ case FP_NINF:
-+ return(-1);
-+ case FP_PINF:
-+ return(1);
-+ }
-+ return(0);
-+}
-+
-+#elif defined(HAVE_FP_CLASS) || defined(HAVE_FP_CLASS_D)
-+
-+#if HAVE_FP_CLASS_H
-+#include <fp_class.h>
-+#endif
-+
-+int isinf(double d) {
-+#if HAVE_FP_CLASS
-+ int fpclass = fp_class(d);
-+#else
-+ int fpclass = fp_class_d(d);
-+#endif
-+ if (fpclass == FP_POS_INF)
-+ return(1);
-+ if (fpclass == FP_NEG_INF)
-+ return(-1);
-+ return(0);
-+}
-+
-+#elif defined(HAVE_CLASS)
-+
-+int isinf(double d) {
-+ int fpclass = class(d);
-+ if (fpclass == FP_PLUS_INF)
-+ return(1);
-+ if (fpclass == FP_MINUS_INF)
-+ return(-1);
-+ return(0);
-+}
-+#elif defined(finite) || defined(HAVE_FINITE)
-+int isinf(double x) { return !finite(x) && x==x; }
-+#elif defined(HUGE_VAL)
-+int isinf(double x)
-+{
-+ if (x == HUGE_VAL)
-+ return(1);
-+ if (x == -HUGE_VAL)
-+ return(-1);
-+ return(0);
-+}
-+#endif
-+
-+#endif /* ! HAVE_ISINF */
-+#endif /* ! defined(isinf) */
-+
-+#ifndef isnan
-+#ifndef HAVE_ISNAN
-+
-+#ifdef HAVE_ISNAND
-+#define isnan(f) isnand(f)
-+#endif /* HAVE_iSNAND */
-+
-+#endif /* ! HAVE_iSNAN */
-+#endif /* ! defined(isnan) */
-+
-+/**
-+ * xmlXPathInit:
-+ *
-+ * Initialize the XPath environment
-+ */
-+void
-+xmlXPathInit(void) {
-+ static int initialized = 0;
-+
-+ if (initialized) return;
-+
-+ xmlXPathNAN = 0;
-+ xmlXPathNAN /= 0;
-+
-+ xmlXPathPINF = 1;
-+ xmlXPathPINF /= 0;
-+
-+ xmlXPathNINF = -1;
-+ xmlXPathNINF /= 0;
-+
-+ initialized = 1;
-+}
-+
-+/************************************************************************
-+ * *
-+ * Debugging related functions *
-+ * *
-+ ************************************************************************/
-+
-+#define TODO \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "Unimplemented block at %s:%d\n", \
-+ __FILE__, __LINE__);
-+
-+#define STRANGE \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "Internal error at %s:%d\n", \
-+ __FILE__, __LINE__);
-+
-+#ifdef LIBXML_DEBUG_ENABLED
-+void xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+ if (cur == NULL) {
-+ fprintf(output, shift);
-+ fprintf(output, "Node is NULL !\n");
-+ return;
-+
-+ }
-+
-+ if ((cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ fprintf(output, shift);
-+ fprintf(output, " /\n");
-+ } else if (cur->type == XML_ATTRIBUTE_NODE)
-+ xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
-+ else
-+ xmlDebugDumpOneNode(output, cur, depth);
-+}
-+
-+void xmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ if (cur == NULL) {
-+ fprintf(output, shift);
-+ fprintf(output, "NodeSet is NULL !\n");
-+ return;
-+
-+ }
-+
-+ fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
-+ for (i = 0;i < cur->nodeNr;i++) {
-+ fprintf(output, shift);
-+ fprintf(output, "%d", i + 1);
-+ xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
-+ }
-+}
-+
-+#if defined(LIBXML_XPTR_ENABLED)
-+void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
-+void xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ if (cur == NULL) {
-+ fprintf(output, shift);
-+ fprintf(output, "LocationSet is NULL !\n");
-+ return;
-+
-+ }
-+
-+ for (i = 0;i < cur->locNr;i++) {
-+ fprintf(output, shift);
-+ fprintf(output, "%d : ", i + 1);
-+ xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
-+ }
-+}
-+#endif
-+
-+void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
-+ int i;
-+ char shift[100];
-+
-+ for (i = 0;((i < depth) && (i < 25));i++)
-+ shift[2 * i] = shift[2 * i + 1] = ' ';
-+ shift[2 * i] = shift[2 * i + 1] = 0;
-+
-+ fprintf(output, shift);
-+
-+ if (cur == NULL) {
-+ fprintf(output, "Object is empty (NULL)\n");
-+ return;
-+ }
-+ switch(cur->type) {
-+ case XPATH_UNDEFINED:
-+ fprintf(output, "Object is uninitialized\n");
-+ break;
-+ case XPATH_NODESET:
-+ fprintf(output, "Object is a Node Set :\n");
-+ xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
-+ break;
-+ case XPATH_XSLT_TREE:
-+ fprintf(output, "Object is an XSLT value tree :\n");
-+ xmlXPathDebugDumpNode(output, cur->user, depth);
-+ break;
-+ case XPATH_BOOLEAN:
-+ fprintf(output, "Object is a Boolean : ");
-+ if (cur->boolval) fprintf(output, "true\n");
-+ else fprintf(output, "false\n");
-+ break;
-+ case XPATH_NUMBER:
-+ fprintf(output, "Object is a number : %0g\n", cur->floatval);
-+ break;
-+ case XPATH_STRING:
-+ fprintf(output, "Object is a string : ");
-+ xmlDebugDumpString(output, cur->stringval);
-+ fprintf(output, "\n");
-+ break;
-+ case XPATH_POINT:
-+ fprintf(output, "Object is a point : index %d in node", cur->index);
-+ xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
-+ fprintf(output, "\n");
-+ break;
-+ case XPATH_RANGE:
-+ if ((cur->user2 == NULL) ||
-+ ((cur->user2 == cur->user) && (cur->index == cur->index2))) {
-+ fprintf(output, "Object is a collapsed range :\n");
-+ fprintf(output, shift);
-+ if (cur->index >= 0)
-+ fprintf(output, "index %d in ", cur->index);
-+ fprintf(output, "node\n");
-+ xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
-+ depth + 1);
-+ } else {
-+ fprintf(output, "Object is a range :\n");
-+ fprintf(output, shift);
-+ fprintf(output, "From ");
-+ if (cur->index >= 0)
-+ fprintf(output, "index %d in ", cur->index);
-+ fprintf(output, "node\n");
-+ xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
-+ depth + 1);
-+ fprintf(output, shift);
-+ fprintf(output, "To ");
-+ if (cur->index2 >= 0)
-+ fprintf(output, "index %d in ", cur->index2);
-+ fprintf(output, "node\n");
-+ xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
-+ depth + 1);
-+ fprintf(output, "\n");
-+ }
-+ break;
-+ case XPATH_LOCATIONSET:
-+#if defined(LIBXML_XPTR_ENABLED)
-+ fprintf(output, "Object is a Location Set:\n");
-+ xmlXPathDebugDumpLocationSet(output,
-+ (xmlLocationSetPtr) cur->user, depth);
-+#endif
-+ break;
-+ case XPATH_USERS:
-+ fprintf(output, "Object is user defined\n");
-+ break;
-+ }
-+}
-+#endif
-+
-+/************************************************************************
-+ * *
-+ * Parser stacks related functions and macros *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * Generic function for accessing stacks in the Parser Context
-+ */
-+
-+#define PUSH_AND_POP(type, name) \
-+extern int name##Push(xmlXPathParserContextPtr ctxt, type value) { \
-+ if (ctxt->name##Nr >= ctxt->name##Max) { \
-+ ctxt->name##Max *= 2; \
-+ ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-+ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-+ if (ctxt->name##Tab == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "realloc failed !\n"); \
-+ return(0); \
-+ } \
-+ } \
-+ ctxt->name##Tab[ctxt->name##Nr] = value; \
-+ ctxt->name = value; \
-+ return(ctxt->name##Nr++); \
-+} \
-+extern type name##Pop(xmlXPathParserContextPtr ctxt) { \
-+ type ret; \
-+ if (ctxt->name##Nr <= 0) return(0); \
-+ ctxt->name##Nr--; \
-+ if (ctxt->name##Nr > 0) \
-+ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-+ else \
-+ ctxt->name = NULL; \
-+ ret = ctxt->name##Tab[ctxt->name##Nr]; \
-+ ctxt->name##Tab[ctxt->name##Nr] = 0; \
-+ return(ret); \
-+} \
-+
-+PUSH_AND_POP(xmlXPathObjectPtr, value)
-+
-+/*
-+ * Macros for accessing the content. Those should be used only by the parser,
-+ * and not exported.
-+ *
-+ * Dirty macros, i.e. one need to make assumption on the context to use them
-+ *
-+ * CUR_PTR return the current pointer to the xmlChar to be parsed.
-+ * CUR returns the current xmlChar value, i.e. a 8 bit value
-+ * in ISO-Latin or UTF-8.
-+ * This should be used internally by the parser
-+ * only to compare to ASCII values otherwise it would break when
-+ * running with UTF-8 encoding.
-+ * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-+ * to compare on ASCII based substring.
-+ * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-+ * strings within the parser.
-+ * CURRENT Returns the current char value, with the full decoding of
-+ * UTF-8 if we are using this mode. It returns an int.
-+ * NEXT Skip to the next character, this does the proper decoding
-+ * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-+ * It returns the pointer to the current xmlChar.
-+ */
-+
-+#define CUR (*ctxt->cur)
-+#define SKIP(val) ctxt->cur += (val)
-+#define NXT(val) ctxt->cur[(val)]
-+#define CUR_PTR ctxt->cur
-+
-+#define SKIP_BLANKS \
-+ while (IS_BLANK(*(ctxt->cur))) NEXT
-+
-+#define CURRENT (*ctxt->cur)
-+#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
-+
-+/************************************************************************
-+ * *
-+ * Error handling routines *
-+ * *
-+ ************************************************************************/
-+
-+
-+const char *xmlXPathErrorMessages[] = {
-+ "Ok",
-+ "Number encoding",
-+ "Unfinished litteral",
-+ "Start of litteral",
-+ "Expected $ for variable reference",
-+ "Undefined variable",
-+ "Invalid predicate",
-+ "Invalid expression",
-+ "Missing closing curly brace",
-+ "Unregistered function",
-+ "Invalid operand",
-+ "Invalid type",
-+ "Invalid number of arguments",
-+ "Invalid context size",
-+ "Invalid context position",
-+ "Memory allocation error",
-+ "Syntax error",
-+ "Resource error",
-+ "Sub resource error",
-+ "Undefined namespace prefix"
-+};
-+
-+/**
-+ * xmlXPathError:
-+ * @ctxt: the XPath Parser context
-+ * @file: the file name
-+ * @line: the line number
-+ * @no: the error number
-+ *
-+ * Create a new xmlNodeSetPtr of type double and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+void
-+xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file,
-+ int line, int no) {
-+ int n;
-+ const xmlChar *cur;
-+ const xmlChar *base;
-+
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Error %s:%d: %s\n", file, line,
-+ xmlXPathErrorMessages[no]);
-+
-+ cur = ctxt->cur;
-+ base = ctxt->base;
-+ while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
-+ cur--;
-+ }
-+ n = 0;
-+ while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
-+ cur--;
-+ if ((*cur == '\n') || (*cur == '\r')) cur++;
-+ base = cur;
-+ n = 0;
-+ while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
-+ xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++);
-+ n++;
-+ }
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+ cur = ctxt->cur;
-+ while ((*cur == '\n') || (*cur == '\r'))
-+ cur--;
-+ n = 0;
-+ while ((cur != base) && (n++ < 80)) {
-+ xmlGenericError(xmlGenericErrorContext, " ");
-+ base++;
-+ }
-+ xmlGenericError(xmlGenericErrorContext,"^\n");
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Routines to handle NodeSets *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPathCmpNodes:
-+ * @node1: the first node
-+ * @node2: the second node
-+ *
-+ * Compare two nodes w.r.t document order
-+ *
-+ * Returns -2 in case of error 1 if first point < second point, 0 if
-+ * that's the same node, -1 otherwise
-+ */
-+int
-+xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
-+ int depth1, depth2;
-+ xmlNodePtr cur, root;
-+
-+ if ((node1 == NULL) || (node2 == NULL))
-+ return(-2);
-+ /*
-+ * a couple of optimizations which will avoid computations in most cases
-+ */
-+ if (node1 == node2)
-+ return(0);
-+ if (node1 == node2->prev)
-+ return(1);
-+ if (node1 == node2->next)
-+ return(-1);
-+
-+ /*
-+ * compute depth to root
-+ */
-+ for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
-+ if (cur == node1)
-+ return(1);
-+ depth2++;
-+ }
-+ root = cur;
-+ for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
-+ if (cur == node2)
-+ return(-1);
-+ depth1++;
-+ }
-+ /*
-+ * Distinct document (or distinct entities :-( ) case.
-+ */
-+ if (root != cur) {
-+ return(-2);
-+ }
-+ /*
-+ * get the nearest common ancestor.
-+ */
-+ while (depth1 > depth2) {
-+ depth1--;
-+ node1 = node1->parent;
-+ }
-+ while (depth2 > depth1) {
-+ depth2--;
-+ node2 = node2->parent;
-+ }
-+ while (node1->parent != node2->parent) {
-+ node1 = node1->parent;
-+ node2 = node2->parent;
-+ /* should not happen but just in case ... */
-+ if ((node1 == NULL) || (node2 == NULL))
-+ return(-2);
-+ }
-+ /*
-+ * Find who's first.
-+ */
-+ if (node1 == node2->next)
-+ return(-1);
-+ for (cur = node1->next;cur != NULL;cur = cur->next)
-+ if (cur == node2)
-+ return(1);
-+ return(-1); /* assume there is no sibling list corruption */
-+}
-+
-+#define XML_NODESET_DEFAULT 10
-+/**
-+ * xmlXPathNodeSetCreate:
-+ * @val: an initial xmlNodePtr, or NULL
-+ *
-+ * Create a new xmlNodeSetPtr of type double and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlNodeSetPtr
-+xmlXPathNodeSetCreate(xmlNodePtr val) {
-+ xmlNodeSetPtr ret;
-+
-+ ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewNodeSet: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
-+ if (val != NULL) {
-+ ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-+ sizeof(xmlNodePtr));
-+ if (ret->nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewNodeSet: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret->nodeTab, 0 ,
-+ XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-+ ret->nodeMax = XML_NODESET_DEFAULT;
-+ ret->nodeTab[ret->nodeNr++] = val;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathNodeSetAdd:
-+ * @cur: the initial node set
-+ * @val: a new xmlNodePtr
-+ *
-+ * add a new xmlNodePtr ot an existing NodeSet
-+ */
-+void
-+xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
-+ int i;
-+
-+ if (val == NULL) return;
-+
-+ /*
-+ * check against doublons
-+ */
-+ for (i = 0;i < cur->nodeNr;i++)
-+ if (cur->nodeTab[i] == val) return;
-+
-+ /*
-+ * grow the nodeTab if needed
-+ */
-+ if (cur->nodeMax == 0) {
-+ cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-+ sizeof(xmlNodePtr));
-+ if (cur->nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetAdd: out of memory\n");
-+ return;
-+ }
-+ memset(cur->nodeTab, 0 ,
-+ XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-+ cur->nodeMax = XML_NODESET_DEFAULT;
-+ } else if (cur->nodeNr == cur->nodeMax) {
-+ xmlNodePtr *temp;
-+
-+ cur->nodeMax *= 2;
-+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
-+ sizeof(xmlNodePtr));
-+ if (temp == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetAdd: out of memory\n");
-+ return;
-+ }
-+ cur->nodeTab = temp;
-+ }
-+ cur->nodeTab[cur->nodeNr++] = val;
-+}
-+
-+/**
-+ * xmlXPathNodeSetAddUnique:
-+ * @cur: the initial node set
-+ * @val: a new xmlNodePtr
-+ *
-+ * add a new xmlNodePtr ot an existing NodeSet, optimized version
-+ * when we are sure the node is not already in the set.
-+ */
-+void
-+xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
-+ if (val == NULL) return;
-+
-+ /*
-+ * grow the nodeTab if needed
-+ */
-+ if (cur->nodeMax == 0) {
-+ cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-+ sizeof(xmlNodePtr));
-+ if (cur->nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetAddUnique: out of memory\n");
-+ return;
-+ }
-+ memset(cur->nodeTab, 0 ,
-+ XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-+ cur->nodeMax = XML_NODESET_DEFAULT;
-+ } else if (cur->nodeNr == cur->nodeMax) {
-+ xmlNodePtr *temp;
-+
-+ cur->nodeMax *= 2;
-+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
-+ sizeof(xmlNodePtr));
-+ if (temp == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetAddUnique: out of memory\n");
-+ return;
-+ }
-+ cur->nodeTab = temp;
-+ }
-+ cur->nodeTab[cur->nodeNr++] = val;
-+}
-+
-+/**
-+ * xmlXPathNodeSetMerge:
-+ * @val1: the first NodeSet or NULL
-+ * @val2: the second NodeSet
-+ *
-+ * Merges two nodesets, all nodes from @val2 are added to @val1
-+ * if @val1 is NULL, a new set is created and copied from @val2
-+ *
-+ * Returns val1 once extended or NULL in case of error.
-+ */
-+xmlNodeSetPtr
-+xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
-+ int i, j, initNr;
-+
-+ if (val2 == NULL) return(val1);
-+ if (val1 == NULL) {
-+ val1 = xmlXPathNodeSetCreate(NULL);
-+ }
-+
-+ initNr = val1->nodeNr;
-+
-+ for (i = 0;i < val2->nodeNr;i++) {
-+ /*
-+ * check against doublons
-+ */
-+ for (j = 0; j < initNr; j++)
-+ if (val1->nodeTab[j] == val2->nodeTab[i]) continue;
-+
-+ /*
-+ * grow the nodeTab if needed
-+ */
-+ if (val1->nodeMax == 0) {
-+ val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-+ sizeof(xmlNodePtr));
-+ if (val1->nodeTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetMerge: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(val1->nodeTab, 0 ,
-+ XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-+ val1->nodeMax = XML_NODESET_DEFAULT;
-+ } else if (val1->nodeNr == val1->nodeMax) {
-+ xmlNodePtr *temp;
-+
-+ val1->nodeMax *= 2;
-+ temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
-+ sizeof(xmlNodePtr));
-+ if (temp == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetMerge: out of memory\n");
-+ return(NULL);
-+ }
-+ val1->nodeTab = temp;
-+ }
-+ val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
-+ }
-+
-+ return(val1);
-+}
-+
-+/**
-+ * xmlXPathNodeSetDel:
-+ * @cur: the initial node set
-+ * @val: an xmlNodePtr
-+ *
-+ * Removes an xmlNodePtr from an existing NodeSet
-+ */
-+void
-+xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
-+ int i;
-+
-+ if (cur == NULL) return;
-+ if (val == NULL) return;
-+
-+ /*
-+ * check against doublons
-+ */
-+ for (i = 0;i < cur->nodeNr;i++)
-+ if (cur->nodeTab[i] == val) break;
-+
-+ if (i >= cur->nodeNr) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
-+ val->name);
-+#endif
-+ return;
-+ }
-+ cur->nodeNr--;
-+ for (;i < cur->nodeNr;i++)
-+ cur->nodeTab[i] = cur->nodeTab[i + 1];
-+ cur->nodeTab[cur->nodeNr] = NULL;
-+}
-+
-+/**
-+ * xmlXPathNodeSetRemove:
-+ * @cur: the initial node set
-+ * @val: the index to remove
-+ *
-+ * Removes an entry from an existing NodeSet list.
-+ */
-+void
-+xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
-+ if (cur == NULL) return;
-+ if (val >= cur->nodeNr) return;
-+ cur->nodeNr--;
-+ for (;val < cur->nodeNr;val++)
-+ cur->nodeTab[val] = cur->nodeTab[val + 1];
-+ cur->nodeTab[cur->nodeNr] = NULL;
-+}
-+
-+/**
-+ * xmlXPathFreeNodeSet:
-+ * @obj: the xmlNodeSetPtr to free
-+ *
-+ * Free the NodeSet compound (not the actual nodes !).
-+ */
-+void
-+xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
-+ if (obj == NULL) return;
-+ if (obj->nodeTab != NULL) {
-+#ifdef DEBUG
-+ memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
-+#endif
-+ xmlFree(obj->nodeTab);
-+ }
-+#ifdef DEBUG
-+ memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
-+#endif
-+ xmlFree(obj);
-+}
-+
-+/**
-+ * xmlXPathFreeValueTree:
-+ * @obj: the xmlNodeSetPtr to free
-+ *
-+ * Free the NodeSet compound and the actual tree, this is different
-+ * from xmlXPathFreeNodeSet()
-+ */
-+void
-+xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
-+ int i;
-+
-+ if (obj == NULL) return;
-+ for (i = 0;i < obj->nodeNr;i++)
-+ if (obj->nodeTab[i] != NULL)
-+ xmlFreeNode(obj->nodeTab[i]);
-+
-+ if (obj->nodeTab != NULL) {
-+#ifdef DEBUG
-+ memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
-+#endif
-+ xmlFree(obj->nodeTab);
-+ }
-+#ifdef DEBUG
-+ memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
-+#endif
-+ xmlFree(obj);
-+}
-+
-+#if defined(DEBUG) || defined(DEBUG_STEP)
-+/**
-+ * xmlGenericErrorContextNodeSet:
-+ * @output: a FILE * for the output
-+ * @obj: the xmlNodeSetPtr to free
-+ *
-+ * Quick display of a NodeSet
-+ */
-+void
-+xmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
-+ int i;
-+
-+ if (output == NULL) output = xmlGenericErrorContext;
-+ if (obj == NULL) {
-+ fprintf(output, "NodeSet == NULL !\n");
-+ return;
-+ }
-+ if (obj->nodeNr == 0) {
-+ fprintf(output, "NodeSet is empty\n");
-+ return;
-+ }
-+ if (obj->nodeTab == NULL) {
-+ fprintf(output, " nodeTab == NULL !\n");
-+ return;
-+ }
-+ for (i = 0; i < obj->nodeNr; i++) {
-+ if (obj->nodeTab[i] == NULL) {
-+ fprintf(output, " NULL !\n");
-+ return;
-+ }
-+ if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
-+ (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
-+ fprintf(output, " /");
-+ else if (obj->nodeTab[i]->name == NULL)
-+ fprintf(output, " noname!");
-+ else fprintf(output, " %s", obj->nodeTab[i]->name);
-+ }
-+ fprintf(output, "\n");
-+}
-+#endif
-+
-+/**
-+ * xmlXPathNewNodeSet:
-+ * @val: the NodePtr value
-+ *
-+ * Create a new xmlXPathObjectPtr of type NodeSet and initialize
-+ * it with the single Node @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewNodeSet(xmlNodePtr val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewNodeSet: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_NODESET;
-+ ret->nodesetval = xmlXPathNodeSetCreate(val);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathNewValueTree:
-+ * @val: the NodePtr value
-+ *
-+ * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
-+ * it with the tree root @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewValueTree(xmlNodePtr val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewNodeSet: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_XSLT_TREE;
-+ ret->nodesetval = xmlXPathNodeSetCreate(val);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathNewNodeSetList:
-+ * @val: an existing NodeSet
-+ *
-+ * Create a new xmlXPathObjectPtr of type NodeSet and initialize
-+ * it with the Nodeset @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewNodeSetList(xmlNodeSetPtr val) {
-+ xmlXPathObjectPtr ret;
-+ int i;
-+
-+ if (val == NULL)
-+ ret = NULL;
-+ else if (val->nodeTab == NULL)
-+ ret = xmlXPathNewNodeSet(NULL);
-+ else
-+ {
-+ ret = xmlXPathNewNodeSet(val->nodeTab[0]);
-+ for (i = 1; i < val->nodeNr; ++i)
-+ xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
-+ }
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathWrapNodeSet:
-+ * @val: the NodePtr value
-+ *
-+ * Wrap the Nodeset @val in a new xmlXPathObjectPtr
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathWrapNodeSet: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_NODESET;
-+ ret->nodesetval = val;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathFreeNodeSetList:
-+ * @obj: an existing NodeSetList object
-+ *
-+ * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
-+ * the list contrary to xmlXPathFreeObject().
-+ */
-+void
-+xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
-+ if (obj == NULL) return;
-+#ifdef DEBUG
-+ memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
-+#endif
-+ xmlFree(obj);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Routines to handle extra functions *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPathRegisterFunc:
-+ * @ctxt: the XPath context
-+ * @name: the function name
-+ * @f: the function implementation or NULL
-+ *
-+ * Register a new function. If @f is NULL it unregisters the function
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
-+ xmlXPathFunction f) {
-+ return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
-+}
-+
-+/**
-+ * xmlXPathRegisterFuncNS:
-+ * @ctxt: the XPath context
-+ * @name: the function name
-+ * @ns_uri: the function namespace URI
-+ * @f: the function implementation or NULL
-+ *
-+ * Register a new function. If @f is NULL it unregisters the function
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-+ const xmlChar *ns_uri, xmlXPathFunction f) {
-+ if (ctxt == NULL)
-+ return(-1);
-+ if (name == NULL)
-+ return(-1);
-+
-+ if (ctxt->funcHash == NULL)
-+ ctxt->funcHash = xmlHashCreate(0);
-+ if (ctxt->funcHash == NULL)
-+ return(-1);
-+ return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f));
-+}
-+
-+/**
-+ * xmlXPathFunctionLookup:
-+ * @ctxt: the XPath context
-+ * @name: the function name
-+ *
-+ * Search in the Function array of the context for the given
-+ * function.
-+ *
-+ * Returns the xmlXPathFunction or NULL if not found
-+ */
-+xmlXPathFunction
-+xmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
-+ return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
-+}
-+
-+/**
-+ * xmlXPathFunctionLookupNS:
-+ * @ctxt: the XPath context
-+ * @name: the function name
-+ * @ns_uri: the function namespace URI
-+ *
-+ * Search in the Function array of the context for the given
-+ * function.
-+ *
-+ * Returns the xmlXPathFunction or NULL if not found
-+ */
-+xmlXPathFunction
-+xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-+ const xmlChar *ns_uri) {
-+ if (ctxt == NULL)
-+ return(NULL);
-+ if (ctxt->funcHash == NULL)
-+ return(NULL);
-+ if (name == NULL)
-+ return(NULL);
-+
-+ return((xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri));
-+}
-+
-+/**
-+ * xmlXPathRegisteredFuncsCleanup:
-+ * @ctxt: the XPath context
-+ *
-+ * Cleanup the XPath context data associated to registered functions
-+ */
-+void
-+xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
-+ if (ctxt == NULL)
-+ return;
-+
-+ xmlHashFree(ctxt->funcHash, NULL);
-+ ctxt->funcHash = NULL;
-+}
-+
-+/************************************************************************
-+ * *
-+ * Routines to handle Variable *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPathRegisterVariable:
-+ * @ctxt: the XPath context
-+ * @name: the variable name
-+ * @value: the variable value or NULL
-+ *
-+ * Register a new variable value. If @value is NULL it unregisters
-+ * the variable
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
-+ xmlXPathObjectPtr value) {
-+ return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
-+}
-+
-+/**
-+ * xmlXPathRegisterVariableNS:
-+ * @ctxt: the XPath context
-+ * @name: the variable name
-+ * @ns_uri: the variable namespace URI
-+ * @value: the variable value or NULL
-+ *
-+ * Register a new variable value. If @value is NULL it unregisters
-+ * the variable
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-+ const xmlChar *ns_uri,
-+ xmlXPathObjectPtr value) {
-+ if (ctxt == NULL)
-+ return(-1);
-+ if (name == NULL)
-+ return(-1);
-+
-+ if (ctxt->varHash == NULL)
-+ ctxt->varHash = xmlHashCreate(0);
-+ if (ctxt->varHash == NULL)
-+ return(-1);
-+ return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
-+ (void *) value,
-+ (xmlHashDeallocator)xmlXPathFreeObject));
-+}
-+
-+/**
-+ * xmlXPathRegisterVariableLookup:
-+ * @ctxt: the XPath context
-+ * @f: the lookup function
-+ * @data: the lookup data
-+ *
-+ * register an external mechanism to do variable lookup
-+ */
-+void
-+xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
-+ xmlXPathVariableLookupFunc f, void *data) {
-+ if (ctxt == NULL)
-+ return;
-+ ctxt->varLookupFunc = (void *) f;
-+ ctxt->varLookupData = data;
-+}
-+
-+/**
-+ * xmlXPathVariableLookup:
-+ * @ctxt: the XPath context
-+ * @name: the variable name
-+ *
-+ * Search in the Variable array of the context for the given
-+ * variable value.
-+ *
-+ * Returns the value or NULL if not found
-+ */
-+xmlXPathObjectPtr
-+xmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
-+ if (ctxt == NULL)
-+ return(NULL);
-+
-+ if (ctxt->varLookupFunc != NULL) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
-+ (ctxt->varLookupData, name, NULL);
-+ if (ret != NULL) return(ret);
-+ }
-+ return(xmlXPathVariableLookupNS(ctxt, name, NULL));
-+}
-+
-+/**
-+ * xmlXPathVariableLookupNS:
-+ * @ctxt: the XPath context
-+ * @name: the variable name
-+ * @ns_uri: the variable namespace URI
-+ *
-+ * Search in the Variable array of the context for the given
-+ * variable value.
-+ *
-+ * Returns the value or NULL if not found
-+ */
-+xmlXPathObjectPtr
-+xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-+ const xmlChar *ns_uri) {
-+ if (ctxt == NULL)
-+ return(NULL);
-+
-+ if (ctxt->varLookupFunc != NULL) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
-+ (ctxt->varLookupData, name, ns_uri);
-+ if (ret != NULL) return(ret);
-+ }
-+
-+ if (ctxt->varHash == NULL)
-+ return(NULL);
-+ if (name == NULL)
-+ return(NULL);
-+
-+ return((xmlXPathObjectPtr) xmlHashLookup2(ctxt->varHash, name, ns_uri));
-+}
-+
-+/**
-+ * xmlXPathRegisteredVariablesCleanup:
-+ * @ctxt: the XPath context
-+ *
-+ * Cleanup the XPath context data associated to registered variables
-+ */
-+void
-+xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
-+ if (ctxt == NULL)
-+ return;
-+
-+ xmlHashFree(ctxt->varHash, NULL);
-+ ctxt->varHash = NULL;
-+}
-+
-+/**
-+ * xmlXPathRegisterNs:
-+ * @ctxt: the XPath context
-+ * @prefix: the namespace prefix
-+ * @ns_uri: the namespace name
-+ *
-+ * Register a new namespace. If @ns_uri is NULL it unregisters
-+ * the namespace
-+ *
-+ * Returns 0 in case of success, -1 in case of error
-+ */
-+int
-+xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
-+ const xmlChar *ns_uri) {
-+ if (ctxt == NULL)
-+ return(-1);
-+ if (prefix == NULL)
-+ return(-1);
-+
-+ if (ctxt->nsHash == NULL)
-+ ctxt->nsHash = xmlHashCreate(10);
-+ if (ctxt->nsHash == NULL)
-+ return(-1);
-+ return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) ns_uri,
-+ (xmlHashDeallocator)xmlFree));
-+}
-+
-+/**
-+ * xmlXPathNsLookup:
-+ * @ctxt: the XPath context
-+ * @prefix: the namespace prefix value
-+ *
-+ * Search in the namespace declaration array of the context for the given
-+ * namespace name associated to the given prefix
-+ *
-+ * Returns the value or NULL if not found
-+ */
-+const xmlChar *
-+xmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
-+ if (ctxt == NULL)
-+ return(NULL);
-+ if (prefix == NULL)
-+ return(NULL);
-+ if (ctxt->nsHash == NULL)
-+ return(NULL);
-+
-+ return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
-+}
-+
-+/**
-+ * xmlXPathRegisteredVariablesCleanup:
-+ * @ctxt: the XPath context
-+ *
-+ * Cleanup the XPath context data associated to registered variables
-+ */
-+void
-+xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
-+ if (ctxt == NULL)
-+ return;
-+
-+ xmlHashFree(ctxt->nsHash, NULL);
-+ ctxt->nsHash = NULL;
-+}
-+
-+/************************************************************************
-+ * *
-+ * Routines to handle Values *
-+ * *
-+ ************************************************************************/
-+
-+/* Allocations are terrible, one need to optimize all this !!! */
-+
-+/**
-+ * xmlXPathNewFloat:
-+ * @val: the double value
-+ *
-+ * Create a new xmlXPathObjectPtr of type double and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewFloat(double val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewFloat: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_NUMBER;
-+ ret->floatval = val;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathNewBoolean:
-+ * @val: the boolean value
-+ *
-+ * Create a new xmlXPathObjectPtr of type boolean and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewBoolean(int val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewBoolean: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_BOOLEAN;
-+ ret->boolval = (val != 0);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathNewString:
-+ * @val: the xmlChar * value
-+ *
-+ * Create a new xmlXPathObjectPtr of type string and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewString(const xmlChar *val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewString: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_STRING;
-+ if (val != NULL)
-+ ret->stringval = xmlStrdup(val);
-+ else
-+ ret->stringval = xmlStrdup((const xmlChar *)"");
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathNewCString:
-+ * @val: the char * value
-+ *
-+ * Create a new xmlXPathObjectPtr of type string and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathNewCString(const char *val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewCString: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_STRING;
-+ ret->stringval = xmlStrdup(BAD_CAST val);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathObjectCopy:
-+ * @val: the original object
-+ *
-+ * allocate a new copy of a given object
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathObjectCopy(xmlXPathObjectPtr val) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (val == NULL)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathObjectCopy: out of memory\n");
-+ return(NULL);
-+ }
-+ memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
-+ switch (val->type) {
-+ case XPATH_BOOLEAN:
-+ case XPATH_NUMBER:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ break;
-+ case XPATH_STRING:
-+ ret->stringval = xmlStrdup(val->stringval);
-+ break;
-+ case XPATH_XSLT_TREE:
-+ if ((val->nodesetval != NULL) &&
-+ (val->nodesetval->nodeTab != NULL))
-+ ret->nodesetval = xmlXPathNodeSetCreate(
-+ xmlCopyNode(val->nodesetval->nodeTab[0], 1));
-+ else
-+ ret->nodesetval = xmlXPathNodeSetCreate(NULL);
-+ break;
-+ case XPATH_NODESET:
-+ ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
-+ break;
-+ case XPATH_LOCATIONSET:
-+#ifdef LIBXML_XPTR_ENABLED
-+ {
-+ xmlLocationSetPtr loc = val->user;
-+ ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
-+ break;
-+ }
-+#endif
-+ case XPATH_UNDEFINED:
-+ case XPATH_USERS:
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathObjectCopy: unsupported type %d\n",
-+ val->type);
-+ break;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathFreeObject:
-+ * @obj: the object to free
-+ *
-+ * Free up an xmlXPathObjectPtr object.
-+ */
-+void
-+xmlXPathFreeObject(xmlXPathObjectPtr obj) {
-+ if (obj == NULL) return;
-+ if (obj->type == XPATH_NODESET) {
-+ if (obj->nodesetval != NULL)
-+ xmlXPathFreeNodeSet(obj->nodesetval);
-+#ifdef LIBXML_XPTR_ENABLED
-+ } else if (obj->type == XPATH_LOCATIONSET) {
-+ if (obj->user != NULL)
-+ xmlXPtrFreeLocationSet(obj->user);
-+#endif
-+ } else if (obj->type == XPATH_STRING) {
-+ if (obj->stringval != NULL)
-+ xmlFree(obj->stringval);
-+ } else if (obj->type == XPATH_XSLT_TREE) {
-+ if (obj->nodesetval != NULL)
-+ xmlXPathFreeValueTree(obj->nodesetval);
-+ }
-+
-+#ifdef DEBUG
-+ memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
-+#endif
-+ xmlFree(obj);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Routines to handle XPath contexts *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPathNewContext:
-+ * @doc: the XML document
-+ *
-+ * Create a new xmlXPathContext
-+ *
-+ * Returns the xmlXPathContext just allocated.
-+ */
-+xmlXPathContextPtr
-+xmlXPathNewContext(xmlDocPtr doc) {
-+ xmlXPathContextPtr ret;
-+
-+ ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewContext: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
-+ ret->doc = doc;
-+ ret->node = NULL;
-+
-+ ret->varHash = NULL;
-+
-+ ret->nb_types = 0;
-+ ret->max_types = 0;
-+ ret->types = NULL;
-+
-+ ret->funcHash = xmlHashCreate(0);
-+
-+ ret->nb_axis = 0;
-+ ret->max_axis = 0;
-+ ret->axis = NULL;
-+
-+ ret->nsHash = NULL;
-+ ret->user = NULL;
-+
-+ ret->contextSize = -1;
-+ ret->proximityPosition = -1;
-+
-+ xmlXPathRegisterAllFunctions(ret);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathFreeContext:
-+ * @ctxt: the context to free
-+ *
-+ * Free up an xmlXPathContext
-+ */
-+void
-+xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
-+ xmlXPathRegisteredNsCleanup(ctxt);
-+ xmlXPathRegisteredFuncsCleanup(ctxt);
-+ xmlXPathRegisteredVariablesCleanup(ctxt);
-+#ifdef DEBUG
-+ memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
-+#endif
-+ xmlFree(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Routines to handle XPath parser contexts *
-+ * *
-+ ************************************************************************/
-+
-+#define CHECK_CTXT(ctxt) \
-+ if (ctxt == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "%s:%d Internal error: ctxt == NULL\n", \
-+ __FILE__, __LINE__); \
-+ } \
-+
-+
-+#define CHECK_CONTEXT(ctxt) \
-+ if (ctxt == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "%s:%d Internal error: no context\n", \
-+ __FILE__, __LINE__); \
-+ } \
-+ else if (ctxt->doc == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "%s:%d Internal error: no document\n", \
-+ __FILE__, __LINE__); \
-+ } \
-+ else if (ctxt->doc->children == NULL) { \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "%s:%d Internal error: document without root\n", \
-+ __FILE__, __LINE__); \
-+ } \
-+
-+
-+/**
-+ * xmlXPathNewParserContext:
-+ * @str: the XPath expression
-+ * @ctxt: the XPath context
-+ *
-+ * Create a new xmlXPathParserContext
-+ *
-+ * Returns the xmlXPathParserContext just allocated.
-+ */
-+xmlXPathParserContextPtr
-+xmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
-+ xmlXPathParserContextPtr ret;
-+
-+ ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathNewParserContext: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
-+ ret->cur = ret->base = str;
-+ ret->context = ctxt;
-+
-+ /* Allocate the value stack */
-+ ret->valueTab = (xmlXPathObjectPtr *)
-+ xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
-+ ret->valueNr = 0;
-+ ret->valueMax = 10;
-+ ret->value = NULL;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathFreeParserContext:
-+ * @ctxt: the context to free
-+ *
-+ * Free up an xmlXPathParserContext
-+ */
-+void
-+xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
-+ if (ctxt->valueTab != NULL) {
-+#ifdef DEBUG
-+ memset(ctxt->valueTab, 0xB , 10 * (size_t) sizeof(xmlXPathObjectPtr));
-+#endif
-+ xmlFree(ctxt->valueTab);
-+ }
-+#ifdef DEBUG
-+ memset(ctxt, 0xB , (size_t) sizeof(xmlXPathParserContext));
-+#endif
-+ xmlFree(ctxt);
-+}
-+
-+/************************************************************************
-+ * *
-+ * The implicit core function library *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * Auto-pop and cast to a number
-+ */
-+void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+
-+
-+#define POP_FLOAT \
-+ arg = valuePop(ctxt); \
-+ if (arg == NULL) { \
-+ XP_ERROR(XPATH_INVALID_OPERAND); \
-+ } \
-+ if (arg->type != XPATH_NUMBER) { \
-+ valuePush(ctxt, arg); \
-+ xmlXPathNumberFunction(ctxt, 1); \
-+ arg = valuePop(ctxt); \
-+ }
-+
-+/**
-+ * xmlXPathCompareNodeSetFloat:
-+ * @ctxt: the XPath Parser context
-+ * @inf: less than (1) or greater than (0)
-+ * @strict: is the comparison strict
-+ * @arg: the node set
-+ * @f: the value
-+ *
-+ * Implement the compare operation between a nodeset and a number
-+ * @ns < @val (1, 1, ...
-+ * @ns <= @val (1, 0, ...
-+ * @ns > @val (0, 1, ...
-+ * @ns >= @val (0, 0, ...
-+ *
-+ * If one object to be compared is a node-set and the other is a number,
-+ * then the comparison will be true if and only if there is a node in the
-+ * node-set such that the result of performing the comparison on the number
-+ * to be compared and on the result of converting the string-value of that
-+ * node to a number using the number function is true.
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
-+ xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
-+ int i, ret = 0;
-+ xmlNodeSetPtr ns;
-+ xmlChar *str2;
-+
-+ if ((f == NULL) || (arg == NULL) ||
-+ ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
-+ xmlXPathFreeObject(arg);
-+ xmlXPathFreeObject(f);
-+ return(0);
-+ }
-+ ns = arg->nodesetval;
-+ for (i = 0;i < ns->nodeNr;i++) {
-+ str2 = xmlNodeGetContent(ns->nodeTab[i]);
-+ if (str2 != NULL) {
-+ valuePush(ctxt,
-+ xmlXPathNewString(str2));
-+ xmlFree(str2);
-+ xmlXPathNumberFunction(ctxt, 1);
-+ valuePush(ctxt, xmlXPathObjectCopy(f));
-+ ret = xmlXPathCompareValues(ctxt, inf, strict);
-+ if (ret)
-+ break;
-+ }
-+ }
-+ xmlXPathFreeObject(arg);
-+ xmlXPathFreeObject(f);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathCompareNodeSetString:
-+ * @ctxt: the XPath Parser context
-+ * @inf: less than (1) or greater than (0)
-+ * @strict: is the comparison strict
-+ * @arg: the node set
-+ * @s: the value
-+ *
-+ * Implement the compare operation between a nodeset and a string
-+ * @ns < @val (1, 1, ...
-+ * @ns <= @val (1, 0, ...
-+ * @ns > @val (0, 1, ...
-+ * @ns >= @val (0, 0, ...
-+ *
-+ * If one object to be compared is a node-set and the other is a string,
-+ * then the comparison will be true if and only if there is a node in
-+ * the node-set such that the result of performing the comparison on the
-+ * string-value of the node and the other string is true.
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
-+ xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
-+ int i, ret = 0;
-+ xmlNodeSetPtr ns;
-+ xmlChar *str2;
-+
-+ if ((s == NULL) || (arg == NULL) ||
-+ ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
-+ xmlXPathFreeObject(arg);
-+ xmlXPathFreeObject(s);
-+ return(0);
-+ }
-+ ns = arg->nodesetval;
-+ for (i = 0;i < ns->nodeNr;i++) {
-+ str2 = xmlNodeGetContent(ns->nodeTab[i]);
-+ if (str2 != NULL) {
-+ valuePush(ctxt,
-+ xmlXPathNewString(str2));
-+ xmlFree(str2);
-+ valuePush(ctxt, xmlXPathObjectCopy(s));
-+ ret = xmlXPathCompareValues(ctxt, inf, strict);
-+ if (ret)
-+ break;
-+ }
-+ }
-+ xmlXPathFreeObject(arg);
-+ xmlXPathFreeObject(s);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathCompareNodeSets:
-+ * @ctxt: the XPath Parser context
-+ * @op: less than (-1), equal (0) or greater than (1)
-+ * @strict: is the comparison strict
-+ * @ns1: the fist node set
-+ * @ns2: the second node set
-+ *
-+ * Implement the compare operation on nodesets:
-+ *
-+ * If both objects to be compared are node-sets, then the comparison will be true if
-+ * and only if there is a node in the first node-set and a node in the second node-set
-+ * such that the result of performing the comparison on the string-values of the two
-+ * nodes is true.
-+ */
-+int
-+xmlXPathCompareNodeSets(xmlXPathParserContextPtr ctxt, int inf, int strict,
-+ xmlXPathObjectPtr ns1, xmlXPathObjectPtr ns2) {
-+ TODO
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathCompareNodeSetValue:
-+ * @ctxt: the XPath Parser context
-+ * @inf: less than (1) or greater than (0)
-+ * @strict: is the comparison strict
-+ * @arg: the node set
-+ * @val: the value
-+ *
-+ * Implement the compare operation between a nodeset and a value
-+ * @ns < @val (1, 1, ...
-+ * @ns <= @val (1, 0, ...
-+ * @ns > @val (0, 1, ...
-+ * @ns >= @val (0, 0, ...
-+ *
-+ * If one object to be compared is a node-set and the other is a boolean, then the
-+ * comparison will be true if and only if the result of performing the comparison
-+ * on the boolean and on the result of converting the node-set to a boolean using
-+ * the boolean function is true.
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
-+ xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
-+ if ((val == NULL) || (arg == NULL) ||
-+ ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
-+ return(0);
-+
-+ switch(val->type) {
-+ case XPATH_NUMBER:
-+ return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
-+ case XPATH_NODESET:
-+ case XPATH_XSLT_TREE:
-+ return(xmlXPathCompareNodeSets(ctxt, inf, strict, arg, val));
-+ case XPATH_STRING:
-+ return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
-+ case XPATH_BOOLEAN:
-+ valuePush(ctxt, arg);
-+ xmlXPathBooleanFunction(ctxt, 1);
-+ valuePush(ctxt, val);
-+ return(xmlXPathCompareValues(ctxt, inf, strict));
-+ default:
-+ TODO
-+ return(0);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathEqualNodeSetString
-+ * @arg: the nodeset object argument
-+ * @str: the string to compare to.
-+ *
-+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
-+ * If one object to be compared is a node-set and the other is a string,
-+ * then the comparison will be true if and only if there is a node in
-+ * the node-set such that the result of performing the comparison on the
-+ * string-value of the node and the other string is true.
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar *str) {
-+ int i;
-+ xmlNodeSetPtr ns;
-+ xmlChar *str2;
-+
-+ if ((str == NULL) || (arg == NULL) ||
-+ ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
-+ return(0);
-+ ns = arg->nodesetval;
-+ for (i = 0;i < ns->nodeNr;i++) {
-+ str2 = xmlNodeGetContent(ns->nodeTab[i]);
-+ if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
-+ xmlFree(str2);
-+ return(1);
-+ }
-+ xmlFree(str2);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathEqualNodeSetFloat
-+ * @arg: the nodeset object argument
-+ * @f: the float to compare to
-+ *
-+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
-+ * If one object to be compared is a node-set and the other is a number,
-+ * then the comparison will be true if and only if there is a node in
-+ * the node-set such that the result of performing the comparison on the
-+ * number to be compared and on the result of converting the string-value
-+ * of that node to a number using the number function is true.
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathEqualNodeSetFloat(xmlXPathObjectPtr arg, float f) {
-+ char buf[100] = "";
-+
-+ if ((arg == NULL) ||
-+ ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
-+ return(0);
-+
-+ if (isnan(f))
-+ sprintf(buf, "NaN");
-+ else if (isinf(f) > 0)
-+ sprintf(buf, "+Infinity");
-+ else if (isinf(f) < 0)
-+ sprintf(buf, "-Infinity");
-+ else
-+ sprintf(buf, "%0g", f);
-+
-+ return(xmlXPathEqualNodeSetString(arg, BAD_CAST buf));
-+}
-+
-+
-+/**
-+ * xmlXPathEqualNodeSets
-+ * @arg1: first nodeset object argument
-+ * @arg2: second nodeset object argument
-+ *
-+ * Implement the equal operation on XPath nodesets: @arg1 == @arg2
-+ * If both objects to be compared are node-sets, then the comparison
-+ * will be true if and only if there is a node in the first node-set and
-+ * a node in the second node-set such that the result of performing the
-+ * comparison on the string-values of the two nodes is true.
-+ *
-+ * (needless to say, this is a costly operation)
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
-+ int i;
-+ xmlNodeSetPtr ns;
-+ xmlChar *str;
-+
-+ if ((arg1 == NULL) ||
-+ ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
-+ return(0);
-+ if ((arg2 == NULL) ||
-+ ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
-+ return(0);
-+
-+ ns = arg1->nodesetval;
-+ for (i = 0;i < ns->nodeNr;i++) {
-+ str = xmlNodeGetContent(ns->nodeTab[i]);
-+ if ((str != NULL) && (xmlXPathEqualNodeSetString(arg2, str))) {
-+ xmlFree(str);
-+ return(1);
-+ }
-+ xmlFree(str);
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathEqualValues:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
-+ *
-+ * Returns 0 or 1 depending on the results of the test.
-+ */
-+int
-+xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg1, arg2;
-+ int ret = 0;
-+
-+ arg1 = valuePop(ctxt);
-+ if (arg1 == NULL)
-+ XP_ERROR0(XPATH_INVALID_OPERAND);
-+
-+ arg2 = valuePop(ctxt);
-+ if (arg2 == NULL) {
-+ xmlXPathFreeObject(arg1);
-+ XP_ERROR0(XPATH_INVALID_OPERAND);
-+ }
-+
-+ if (arg1 == arg2) {
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: by pointer\n");
-+#endif
-+ return(1);
-+ }
-+
-+ switch (arg1->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: undefined\n");
-+#endif
-+ break;
-+ case XPATH_XSLT_TREE:
-+ case XPATH_NODESET:
-+ switch (arg2->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: undefined\n");
-+#endif
-+ break;
-+ case XPATH_XSLT_TREE:
-+ case XPATH_NODESET:
-+ ret = xmlXPathEqualNodeSets(arg1, arg2);
-+ break;
-+ case XPATH_BOOLEAN:
-+ if ((arg1->nodesetval == NULL) ||
-+ (arg1->nodesetval->nodeNr == 0)) ret = 0;
-+ else
-+ ret = 1;
-+ ret = (ret == arg2->boolval);
-+ break;
-+ case XPATH_NUMBER:
-+ ret = xmlXPathEqualNodeSetFloat(arg1, arg2->floatval);
-+ break;
-+ case XPATH_STRING:
-+ ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
-+ break;
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ break;
-+ }
-+ break;
-+ case XPATH_BOOLEAN:
-+ switch (arg2->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: undefined\n");
-+#endif
-+ break;
-+ case XPATH_NODESET:
-+ case XPATH_XSLT_TREE:
-+ if ((arg2->nodesetval == NULL) ||
-+ (arg2->nodesetval->nodeNr == 0)) ret = 0;
-+ else
-+ ret = 1;
-+ break;
-+ case XPATH_BOOLEAN:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: %d boolean %d \n",
-+ arg1->boolval, arg2->boolval);
-+#endif
-+ ret = (arg1->boolval == arg2->boolval);
-+ break;
-+ case XPATH_NUMBER:
-+ if (arg2->floatval) ret = 1;
-+ else ret = 0;
-+ ret = (arg1->boolval == ret);
-+ break;
-+ case XPATH_STRING:
-+ if ((arg2->stringval == NULL) ||
-+ (arg2->stringval[0] == 0)) ret = 0;
-+ else
-+ ret = 1;
-+ ret = (arg1->boolval == ret);
-+ break;
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ break;
-+ }
-+ break;
-+ case XPATH_NUMBER:
-+ switch (arg2->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: undefined\n");
-+#endif
-+ break;
-+ case XPATH_NODESET:
-+ case XPATH_XSLT_TREE:
-+ ret = xmlXPathEqualNodeSetFloat(arg2, arg1->floatval);
-+ break;
-+ case XPATH_BOOLEAN:
-+ if (arg1->floatval) ret = 1;
-+ else ret = 0;
-+ ret = (arg2->boolval == ret);
-+ break;
-+ case XPATH_STRING:
-+ valuePush(ctxt, arg2);
-+ xmlXPathNumberFunction(ctxt, 1);
-+ arg2 = valuePop(ctxt);
-+ /* no break on purpose */
-+ case XPATH_NUMBER:
-+ ret = (arg1->floatval == arg2->floatval);
-+ break;
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ break;
-+ }
-+ break;
-+ case XPATH_STRING:
-+ switch (arg2->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Equal: undefined\n");
-+#endif
-+ break;
-+ case XPATH_NODESET:
-+ case XPATH_XSLT_TREE:
-+ ret = xmlXPathEqualNodeSetString(arg2, arg1->stringval);
-+ break;
-+ case XPATH_BOOLEAN:
-+ if ((arg1->stringval == NULL) ||
-+ (arg1->stringval[0] == 0)) ret = 0;
-+ else
-+ ret = 1;
-+ ret = (arg2->boolval == ret);
-+ break;
-+ case XPATH_STRING:
-+ ret = xmlStrEqual(arg1->stringval, arg2->stringval);
-+ break;
-+ case XPATH_NUMBER:
-+ valuePush(ctxt, arg1);
-+ xmlXPathNumberFunction(ctxt, 1);
-+ arg1 = valuePop(ctxt);
-+ ret = (arg1->floatval == arg2->floatval);
-+ break;
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ break;
-+ }
-+ break;
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ break;
-+ }
-+ xmlXPathFreeObject(arg1);
-+ xmlXPathFreeObject(arg2);
-+ return(ret);
-+}
-+
-+
-+/**
-+ * xmlXPathCompareValues:
-+ * @ctxt: the XPath Parser context
-+ * @inf: less than (1) or greater than (0)
-+ * @strict: is the comparison strict
-+ *
-+ * Implement the compare operation on XPath objects:
-+ * @arg1 < @arg2 (1, 1, ...
-+ * @arg1 <= @arg2 (1, 0, ...
-+ * @arg1 > @arg2 (0, 1, ...
-+ * @arg1 >= @arg2 (0, 0, ...
-+ *
-+ * When neither object to be compared is a node-set and the operator is
-+ * <=, <, >=, >, then the objects are compared by converted both objects
-+ * to numbers and comparing the numbers according to IEEE 754. The <
-+ * comparison will be true if and only if the first number is less than the
-+ * second number. The <= comparison will be true if and only if the first
-+ * number is less than or equal to the second number. The > comparison
-+ * will be true if and only if the first number is greater than the second
-+ * number. The >= comparison will be true if and only if the first number
-+ * is greater than or equal to the second number.
-+ *
-+ * Returns 1 if the comparaison succeeded, 0 if it failed
-+ */
-+int
-+xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
-+ int ret = 0;
-+ xmlXPathObjectPtr arg1, arg2;
-+
-+ arg2 = valuePop(ctxt);
-+ if (arg2 == NULL) {
-+ XP_ERROR0(XPATH_INVALID_OPERAND);
-+ }
-+
-+ arg1 = valuePop(ctxt);
-+ if (arg1 == NULL) {
-+ xmlXPathFreeObject(arg2);
-+ XP_ERROR0(XPATH_INVALID_OPERAND);
-+ }
-+
-+ if ((arg2->type == XPATH_NODESET) || (arg1->type == XPATH_NODESET)) {
-+ if ((arg2->type == XPATH_NODESET) && (arg1->type == XPATH_NODESET)) {
-+ ret = xmlXPathCompareNodeSets(ctxt, inf, strict, arg1, arg2);
-+ } else {
-+ if (arg1->type == XPATH_NODESET) {
-+ ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, arg1, arg2);
-+ } else {
-+ ret = xmlXPathCompareNodeSetValue(ctxt, !inf, !strict, arg2, arg2);
-+ }
-+ }
-+ return(ret);
-+ }
-+
-+ if (arg1->type != XPATH_NUMBER) {
-+ valuePush(ctxt, arg1);
-+ xmlXPathNumberFunction(ctxt, 1);
-+ arg1 = valuePop(ctxt);
-+ }
-+ if (arg1->type != XPATH_NUMBER) {
-+ xmlXPathFreeObject(arg1);
-+ xmlXPathFreeObject(arg2);
-+ XP_ERROR0(XPATH_INVALID_OPERAND);
-+ }
-+ if (arg2->type != XPATH_NUMBER) {
-+ valuePush(ctxt, arg2);
-+ xmlXPathNumberFunction(ctxt, 1);
-+ arg2 = valuePop(ctxt);
-+ }
-+ if (arg2->type != XPATH_NUMBER) {
-+ xmlXPathFreeObject(arg1);
-+ xmlXPathFreeObject(arg2);
-+ XP_ERROR0(XPATH_INVALID_OPERAND);
-+ }
-+ /*
-+ * Add tests for infinity and nan
-+ * => feedback on 3.4 for Inf and NaN
-+ */
-+ if (inf && strict)
-+ ret = (arg1->floatval < arg2->floatval);
-+ else if (inf && !strict)
-+ ret = (arg1->floatval <= arg2->floatval);
-+ else if (!inf && strict)
-+ ret = (arg1->floatval > arg2->floatval);
-+ else if (!inf && !strict)
-+ ret = (arg1->floatval >= arg2->floatval);
-+ xmlXPathFreeObject(arg1);
-+ xmlXPathFreeObject(arg2);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathValueFlipSign:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the unary - operation on an XPath object
-+ * The numeric operators convert their operands to numbers as if
-+ * by calling the number function.
-+ */
-+void
-+xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg;
-+
-+ POP_FLOAT
-+ arg->floatval = -arg->floatval;
-+ valuePush(ctxt, arg);
-+}
-+
-+/**
-+ * xmlXPathAddValues:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the add operation on XPath objects:
-+ * The numeric operators convert their operands to numbers as if
-+ * by calling the number function.
-+ */
-+void
-+xmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg;
-+ double val;
-+
-+ POP_FLOAT
-+ val = arg->floatval;
-+ xmlXPathFreeObject(arg);
-+
-+ POP_FLOAT
-+ arg->floatval += val;
-+ valuePush(ctxt, arg);
-+}
-+
-+/**
-+ * xmlXPathSubValues:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the substraction operation on XPath objects:
-+ * The numeric operators convert their operands to numbers as if
-+ * by calling the number function.
-+ */
-+void
-+xmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg;
-+ double val;
-+
-+ POP_FLOAT
-+ val = arg->floatval;
-+ xmlXPathFreeObject(arg);
-+
-+ POP_FLOAT
-+ arg->floatval -= val;
-+ valuePush(ctxt, arg);
-+}
-+
-+/**
-+ * xmlXPathMultValues:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the multiply operation on XPath objects:
-+ * The numeric operators convert their operands to numbers as if
-+ * by calling the number function.
-+ */
-+void
-+xmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg;
-+ double val;
-+
-+ POP_FLOAT
-+ val = arg->floatval;
-+ xmlXPathFreeObject(arg);
-+
-+ POP_FLOAT
-+ arg->floatval *= val;
-+ valuePush(ctxt, arg);
-+}
-+
-+/**
-+ * xmlXPathDivValues:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the div operation on XPath objects @arg1 / @arg2:
-+ * The numeric operators convert their operands to numbers as if
-+ * by calling the number function.
-+ */
-+void
-+xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg;
-+ double val;
-+
-+ POP_FLOAT
-+ val = arg->floatval;
-+ xmlXPathFreeObject(arg);
-+
-+ POP_FLOAT
-+ arg->floatval /= val;
-+ valuePush(ctxt, arg);
-+}
-+
-+/**
-+ * xmlXPathModValues:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Implement the mod operation on XPath objects: @arg1 / @arg2
-+ * The numeric operators convert their operands to numbers as if
-+ * by calling the number function.
-+ */
-+void
-+xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathObjectPtr arg;
-+ int arg1, arg2;
-+
-+ POP_FLOAT
-+ arg2 = (int) arg->floatval;
-+ xmlXPathFreeObject(arg);
-+
-+ POP_FLOAT
-+ arg1 = (int) arg->floatval;
-+ arg->floatval = arg1 % arg2;
-+ valuePush(ctxt, arg);
-+}
-+
-+/************************************************************************
-+ * *
-+ * The traversal functions *
-+ * *
-+ ************************************************************************/
-+
-+typedef enum {
-+ AXIS_ANCESTOR = 1,
-+ AXIS_ANCESTOR_OR_SELF,
-+ AXIS_ATTRIBUTE,
-+ AXIS_CHILD,
-+ AXIS_DESCENDANT,
-+ AXIS_DESCENDANT_OR_SELF,
-+ AXIS_FOLLOWING,
-+ AXIS_FOLLOWING_SIBLING,
-+ AXIS_NAMESPACE,
-+ AXIS_PARENT,
-+ AXIS_PRECEDING,
-+ AXIS_PRECEDING_SIBLING,
-+ AXIS_SELF
-+} xmlXPathAxisVal;
-+
-+/*
-+ * A traversal function enumerates nodes along an axis.
-+ * Initially it must be called with NULL, and it indicates
-+ * termination on the axis by returning NULL.
-+ */
-+typedef xmlNodePtr (*xmlXPathTraversalFunction)
-+ (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
-+
-+/**
-+ * xmlXPathNextSelf:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "self" direction
-+ * The self axis contains just the context node itself
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur == NULL)
-+ return(ctxt->context->node);
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlXPathNextChild:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "child" direction
-+ * The child axis contains the children of the context node in document order.
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur == NULL) {
-+ if (ctxt->context->node == NULL) return(NULL);
-+ switch (ctxt->context->node->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_DTD_NODE:
-+ return(ctxt->context->node->children);
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return(((xmlDocPtr) ctxt->context->node)->children);
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_ATTRIBUTE_NODE:
-+ case XML_NAMESPACE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ return(NULL);
-+ }
-+ return(NULL);
-+ }
-+ if ((cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE))
-+ return(NULL);
-+ return(cur->next);
-+}
-+
-+/**
-+ * xmlXPathNextDescendant:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "descendant" direction
-+ * the descendant axis contains the descendants of the context node in document
-+ * order; a descendant is a child or a child of a child and so on.
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur == NULL) {
-+ if (ctxt->context->node == NULL)
-+ return(NULL);
-+ if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
-+ return(NULL);
-+
-+ if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
-+ return(ctxt->context->doc->children);
-+ return(ctxt->context->node->children);
-+ }
-+
-+ if (cur->children != NULL)
-+ {
-+ if (cur->children->type != XML_ENTITY_DECL)
-+ return(cur->children);
-+ }
-+ if (cur->next != NULL) return(cur->next);
-+
-+ do {
-+ cur = cur->parent;
-+ if (cur == NULL) return(NULL);
-+ if (cur == ctxt->context->node) return(NULL);
-+ if (cur->next != NULL) {
-+ cur = cur->next;
-+ return(cur);
-+ }
-+ } while (cur != NULL);
-+ return(cur);
-+}
-+
-+/**
-+ * xmlXPathNextDescendantOrSelf:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "descendant-or-self" direction
-+ * the descendant-or-self axis contains the context node and the descendants
-+ * of the context node in document order; thus the context node is the first
-+ * node on the axis, and the first child of the context node is the second node
-+ * on the axis
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur == NULL) {
-+ if (ctxt->context->node == NULL)
-+ return(NULL);
-+ if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
-+ return(NULL);
-+ return(ctxt->context->node);
-+ }
-+
-+ return(xmlXPathNextDescendant(ctxt, cur));
-+}
-+
-+/**
-+ * xmlXPathNextParent:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "parent" direction
-+ * The parent axis contains the parent of the context node, if there is one.
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ /*
-+ * the parent of an attribute or namespace node is the element
-+ * to which the attribute or namespace node is attached
-+ * Namespace handling !!!
-+ */
-+ if (cur == NULL) {
-+ if (ctxt->context->node == NULL) return(NULL);
-+ switch (ctxt->context->node->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ case XML_ENTITY_DECL:
-+ if (ctxt->context->node->parent == NULL)
-+ return((xmlNodePtr) ctxt->context->doc);
-+ return(ctxt->context->node->parent);
-+ case XML_ATTRIBUTE_NODE: {
-+ xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
-+
-+ return(att->parent);
-+ }
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return(NULL);
-+ case XML_NAMESPACE_DECL:
-+ /*
-+ * TODO !!! may require extending struct _xmlNs with
-+ * parent field
-+ * C.f. Infoset case...
-+ */
-+ return(NULL);
-+ }
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlXPathNextAncestor:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "ancestor" direction
-+ * the ancestor axis contains the ancestors of the context node; the ancestors
-+ * of the context node consist of the parent of context node and the parent's
-+ * parent and so on; the nodes are ordered in reverse document order; thus the
-+ * parent is the first node on the axis, and the parent's parent is the second
-+ * node on the axis
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ /*
-+ * the parent of an attribute or namespace node is the element
-+ * to which the attribute or namespace node is attached
-+ * !!!!!!!!!!!!!
-+ */
-+ if (cur == NULL) {
-+ if (ctxt->context->node == NULL) return(NULL);
-+ switch (ctxt->context->node->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_NOTATION_NODE:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ if (ctxt->context->node->parent == NULL)
-+ return((xmlNodePtr) ctxt->context->doc);
-+ return(ctxt->context->node->parent);
-+ case XML_ATTRIBUTE_NODE: {
-+ xmlAttrPtr cur = (xmlAttrPtr) ctxt->context->node;
-+
-+ return(cur->parent);
-+ }
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return(NULL);
-+ case XML_NAMESPACE_DECL:
-+ /*
-+ * TODO !!! may require extending struct _xmlNs with
-+ * parent field
-+ * C.f. Infoset case...
-+ */
-+ return(NULL);
-+ }
-+ return(NULL);
-+ }
-+ if (cur == ctxt->context->doc->children)
-+ return((xmlNodePtr) ctxt->context->doc);
-+ if (cur == (xmlNodePtr) ctxt->context->doc)
-+ return(NULL);
-+ switch (cur->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_ENTITY_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_DECL:
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ return(cur->parent);
-+ case XML_ATTRIBUTE_NODE: {
-+ xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
-+
-+ return(att->parent);
-+ }
-+ case XML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_TYPE_NODE:
-+ case XML_DOCUMENT_FRAG_NODE:
-+ case XML_HTML_DOCUMENT_NODE:
-+#ifdef LIBXML_SGML_ENABLED
-+ case XML_SGML_DOCUMENT_NODE:
-+#endif
-+ return(NULL);
-+ case XML_NAMESPACE_DECL:
-+ /*
-+ * TODO !!! may require extending struct _xmlNs with
-+ * parent field
-+ * C.f. Infoset case...
-+ */
-+ return(NULL);
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlXPathNextAncestorOrSelf:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "ancestor-or-self" direction
-+ * he ancestor-or-self axis contains the context node and ancestors of
-+ * the context node in reverse document order; thus the context node is
-+ * the first node on the axis, and the context node's parent the second;
-+ * parent here is defined the same as with the parent axis.
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur == NULL)
-+ return(ctxt->context->node);
-+ return(xmlXPathNextAncestor(ctxt, cur));
-+}
-+
-+/**
-+ * xmlXPathNextFollowingSibling:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "following-sibling" direction
-+ * The following-sibling axis contains the following siblings of the context
-+ * node in document order.
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
-+ return(NULL);
-+ if (cur == (xmlNodePtr) ctxt->context->doc)
-+ return(NULL);
-+ if (cur == NULL)
-+ return(ctxt->context->node->next);
-+ return(cur->next);
-+}
-+
-+/**
-+ * xmlXPathNextPrecedingSibling:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "preceding-sibling" direction
-+ * The preceding-sibling axis contains the preceding siblings of the context
-+ * node in reverse document order; the first preceding sibling is first on the
-+ * axis; the sibling preceding that node is the second on the axis and so on.
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
-+ return(NULL);
-+ if (cur == (xmlNodePtr) ctxt->context->doc)
-+ return(NULL);
-+ if (cur == NULL)
-+ return(ctxt->context->node->prev);
-+ return(cur->prev);
-+}
-+
-+/**
-+ * xmlXPathNextFollowing:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "following" direction
-+ * The following axis contains all nodes in the same document as the context
-+ * node that are after the context node in document order, excluding any
-+ * descendants and excluding attribute nodes and namespace nodes; the nodes
-+ * are ordered in document order
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur != NULL && cur->children != NULL)
-+ return cur->children ;
-+ if (cur == NULL) cur = ctxt->context->node;
-+ if (cur == NULL) return(NULL) ; /* ERROR */
-+ if (cur->next != NULL) return(cur->next) ;
-+ do {
-+ cur = cur->parent;
-+ if (cur == NULL) return(NULL);
-+ if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
-+ if (cur->next != NULL) return(cur->next);
-+ } while (cur != NULL);
-+ return(cur);
-+}
-+
-+/*
-+ * xmlXPathIsAncestor:
-+ * @ancestor: the ancestor node
-+ * @node: the current node
-+ *
-+ * Check that @ancestor is a @node's ancestor
-+ *
-+ * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
-+ */
-+static int
-+xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
-+ if ((ancestor == NULL) || (node == NULL)) return(0);
-+ /* nodes need to be in the same document */
-+ if (ancestor->doc != node->doc) return(0);
-+ /* avoid searching if ancestor or node is the root node */
-+ if (ancestor == (xmlNodePtr) node->doc) return(1);
-+ if (node == (xmlNodePtr) ancestor->doc) return(0);
-+ while (node->parent != NULL) {
-+ if (node->parent == ancestor)
-+ return(1);
-+ node = node->parent;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathNextPreceding:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current node in the traversal
-+ *
-+ * Traversal function for the "preceding" direction
-+ * the preceding axis contains all nodes in the same document as the context
-+ * node that are before the context node in document order, excluding any
-+ * ancestors and excluding attribute nodes and namespace nodes; the nodes are
-+ * ordered in reverse document order
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (cur == NULL)
-+ cur = ctxt->context->node ;
-+ do {
-+ if (cur->prev != NULL) {
-+ for (cur = cur->prev ; cur->last != NULL ; cur = cur->last)
-+ ;
-+ return(cur) ;
-+ }
-+
-+ cur = cur->parent;
-+ if (cur == NULL) return(NULL);
-+ if (cur == ctxt->context->doc->children) return(NULL);
-+ } while (xmlXPathIsAncestor(cur, ctxt->context->node));
-+ return(cur);
-+}
-+
-+/**
-+ * xmlXPathNextNamespace:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current attribute in the traversal
-+ *
-+ * Traversal function for the "namespace" direction
-+ * the namespace axis contains the namespace nodes of the context node;
-+ * the order of nodes on this axis is implementation-defined; the axis will
-+ * be empty unless the context node is an element
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
-+ if ((cur == NULL) || (ctxt->context->namespaces == NULL)) {
-+ if (ctxt->context->namespaces != NULL)
-+ xmlFree(ctxt->context->namespaces);
-+ ctxt->context->namespaces =
-+ xmlGetNsList(ctxt->context->doc, ctxt->context->node);
-+ if (ctxt->context->namespaces == NULL) return(NULL);
-+ ctxt->context->nsNr = 0;
-+ }
-+ return((xmlNodePtr)ctxt->context->namespaces[ctxt->context->nsNr++]);
-+}
-+
-+/**
-+ * xmlXPathNextAttribute:
-+ * @ctxt: the XPath Parser context
-+ * @cur: the current attribute in the traversal
-+ *
-+ * Traversal function for the "attribute" direction
-+ * TODO: support DTD inherited default attributes
-+ *
-+ * Returns the next element following that axis
-+ */
-+xmlNodePtr
-+xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-+ if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
-+ if (cur == NULL) {
-+ if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
-+ return(NULL);
-+ return((xmlNodePtr)ctxt->context->node->properties);
-+ }
-+ return((xmlNodePtr)cur->next);
-+}
-+
-+/************************************************************************
-+ * *
-+ * NodeTest Functions *
-+ * *
-+ ************************************************************************/
-+
-+typedef enum {
-+ NODE_TEST_NONE = 0,
-+ NODE_TEST_TYPE = 1,
-+ NODE_TEST_PI = 2,
-+ NODE_TEST_ALL = 3,
-+ NODE_TEST_NS = 4,
-+ NODE_TEST_NAME = 5
-+} xmlXPathTestVal;
-+
-+typedef enum {
-+ NODE_TYPE_NODE = 0,
-+ NODE_TYPE_COMMENT = XML_COMMENT_NODE,
-+ NODE_TYPE_TEXT = XML_TEXT_NODE,
-+ NODE_TYPE_PI = XML_PI_NODE
-+} xmlXPathTypeVal;
-+
-+#define IS_FUNCTION 200
-+
-+/**
-+ * xmlXPathNodeCollectAndTest:
-+ * @ctxt: the XPath Parser context
-+ * @axis: the XPath axis
-+ * @test: the XPath test
-+ * @type: the XPath type
-+ * @prefix: the namesapce prefix if any
-+ * @name: the name used in the search if any
-+ *
-+ * This is the function implementing a step: based on the current list
-+ * of nodes, it builds up a new list, looking at all nodes under that
-+ * axis and selecting them.
-+ *
-+ * Returns the new NodeSet resulting from the search.
-+ */
-+void
-+xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
-+ xmlXPathTestVal test, xmlXPathTypeVal type,
-+ const xmlChar *prefix, const xmlChar *name) {
-+#ifdef DEBUG_STEP
-+ int n = 0, t = 0;
-+#endif
-+ int i;
-+ xmlNodeSetPtr ret;
-+ xmlXPathTraversalFunction next = NULL;
-+ void (*addNode)(xmlNodeSetPtr, xmlNodePtr);
-+ xmlNodePtr cur = NULL;
-+ xmlXPathObjectPtr obj;
-+ xmlNodeSetPtr nodelist;
-+
-+ CHECK_TYPE(XPATH_NODESET);
-+ obj = valuePop(ctxt);
-+ addNode = xmlXPathNodeSetAdd;
-+
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "new step : ");
-+#endif
-+ switch (axis) {
-+ case AXIS_ANCESTOR:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'ancestors' ");
-+#endif
-+ next = xmlXPathNextAncestor; break;
-+ case AXIS_ANCESTOR_OR_SELF:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'ancestors-or-self' ");
-+#endif
-+ next = xmlXPathNextAncestorOrSelf; break;
-+ case AXIS_ATTRIBUTE:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'attributes' ");
-+#endif
-+ next = xmlXPathNextAttribute; break;
-+ break;
-+ case AXIS_CHILD:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'child' ");
-+#endif
-+ next = xmlXPathNextChild; break;
-+ case AXIS_DESCENDANT:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'descendant' ");
-+#endif
-+ next = xmlXPathNextDescendant; break;
-+ case AXIS_DESCENDANT_OR_SELF:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'descendant-or-self' ");
-+#endif
-+ next = xmlXPathNextDescendantOrSelf; break;
-+ case AXIS_FOLLOWING:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'following' ");
-+#endif
-+ next = xmlXPathNextFollowing; break;
-+ case AXIS_FOLLOWING_SIBLING:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'following-siblings' ");
-+#endif
-+ next = xmlXPathNextFollowingSibling; break;
-+ case AXIS_NAMESPACE:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'namespace' ");
-+#endif
-+ next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; break;
-+ break;
-+ case AXIS_PARENT:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'parent' ");
-+#endif
-+ next = xmlXPathNextParent; break;
-+ case AXIS_PRECEDING:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'preceding' ");
-+#endif
-+ next = xmlXPathNextPreceding; break;
-+ case AXIS_PRECEDING_SIBLING:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'preceding-sibling' ");
-+#endif
-+ next = xmlXPathNextPrecedingSibling; break;
-+ case AXIS_SELF:
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "axis 'self' ");
-+#endif
-+ next = xmlXPathNextSelf; break;
-+ }
-+ if (next == NULL)
-+ return;
-+
-+ nodelist = obj->nodesetval;
-+ if ((nodelist != NULL) &&
-+ (nodelist->nodeNr <= 1))
-+ addNode = xmlXPathNodeSetAddUnique;
-+ else
-+ addNode = xmlXPathNodeSetAdd;
-+ ret = xmlXPathNodeSetCreate(NULL);
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ " context contains %d nodes\n",
-+ nodelist->nodeNr);
-+ switch (test) {
-+ case NODE_TEST_NODE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching all nodes\n");
-+ break;
-+ case NODE_TEST_NONE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching for none !!!\n");
-+ break;
-+ case NODE_TEST_TYPE:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching for type %d\n", type);
-+ break;
-+ case NODE_TEST_PI:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching for PI !!!\n");
-+ break;
-+ case NODE_TEST_ALL:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching for *\n");
-+ break;
-+ case NODE_TEST_NS:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching for namespace %s\n",
-+ prefix);
-+ break;
-+ case NODE_TEST_NAME:
-+ xmlGenericError(xmlGenericErrorContext,
-+ " searching for name %s\n", name);
-+ if (prefix != NULL)
-+ xmlGenericError(xmlGenericErrorContext,
-+ " with namespace %s\n",
-+ prefix);
-+ break;
-+ }
-+ xmlGenericError(xmlGenericErrorContext, "Testing : ");
-+#endif
-+ /*
-+ * 2.3 Node Tests
-+ * - For the attribute axis, the principal node type is attribute.
-+ * - For the namespace axis, the principal node type is namespace.
-+ * - For other axes, the principal node type is element.
-+ *
-+ * A node test * is true for any node of the
-+ * principal node type. For example, child::* willi
-+ * select all element children of the context node
-+ */
-+ for (i = 0;i < nodelist->nodeNr; i++) {
-+ ctxt->context->node = nodelist->nodeTab[i];
-+
-+ cur = NULL;
-+ do {
-+ cur = next(ctxt, cur);
-+ if (cur == NULL) break;
-+#ifdef DEBUG_STEP
-+ t++;
-+ xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
-+#endif
-+ switch (test) {
-+ case NODE_TEST_NONE:
-+ STRANGE
-+ return;
-+ case NODE_TEST_TYPE:
-+ if ((cur->type == type) ||
-+ ((type == NODE_TYPE_NODE) &&
-+ ((cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE) ||
-+ (cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_PI_NODE) ||
-+ (cur->type == XML_COMMENT_NODE) ||
-+ (cur->type == XML_CDATA_SECTION_NODE) ||
-+ (cur->type == XML_TEXT_NODE)))) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ break;
-+ case NODE_TEST_PI:
-+ if (cur->type == XML_PI_NODE) {
-+ if ((name != NULL) &&
-+ (!xmlStrEqual(name, cur->name)))
-+ break;
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ break;
-+ case NODE_TEST_ALL:
-+ if (axis == AXIS_ATTRIBUTE) {
-+ if (cur->type == XML_ATTRIBUTE_NODE) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ } else if (axis == AXIS_NAMESPACE) {
-+ if (cur->type == XML_NAMESPACE_DECL) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ } else {
-+ if ((cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ if (prefix == NULL) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ } else if ((cur->ns != NULL) &&
-+ (xmlStrEqual(prefix,
-+ cur->ns->href))) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ }
-+ }
-+ break;
-+ case NODE_TEST_NS: {
-+ TODO;
-+ break;
-+ }
-+ case NODE_TEST_NAME:
-+ switch (cur->type) {
-+ case XML_ELEMENT_NODE:
-+ if (xmlStrEqual(name, cur->name)) {
-+ if (prefix == NULL) {
-+ if ((cur->ns == NULL) ||
-+ (cur->ns->prefix == NULL)) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ } else {
-+ if ((cur->ns != NULL) &&
-+ (xmlStrEqual(prefix,
-+ cur->ns->href))) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ }
-+ }
-+ break;
-+ case XML_ATTRIBUTE_NODE: {
-+ xmlAttrPtr attr = (xmlAttrPtr) cur;
-+ if (xmlStrEqual(name, attr->name)) {
-+#ifdef DEBUG_STEP
-+ n++;
-+#endif
-+ addNode(ret, cur);
-+ }
-+ break;
-+ }
-+ case XML_NAMESPACE_DECL: {
-+ TODO;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+ break;
-+ }
-+ } while (cur != NULL);
-+ }
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "\nExamined %d nodes, found %d nodes at that step\n", t, n);
-+#endif
-+ xmlXPathFreeObject(obj);
-+ valuePush(ctxt, xmlXPathWrapNodeSet(ret));
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * Implicit tree core function library *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPathRoot:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Initialize the context to the root of the document
-+ */
-+void
-+xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
-+ ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+}
-+
-+/************************************************************************
-+ * *
-+ * The explicit core function library *
-+ *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib *
-+ * *
-+ ************************************************************************/
-+
-+
-+/**
-+ * xmlXPathLastFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the last() XPath function
-+ * number last()
-+ * The last function returns the number of nodes in the context node list.
-+ */
-+void
-+xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ CHECK_ARITY(0);
-+ if (ctxt->context->contextSize > 0) {
-+ valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize));
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext,
-+ "last() : %d\n", ctxt->context->contextSize);
-+#endif
-+ } else {
-+ XP_ERROR(XPATH_INVALID_CTXT_SIZE);
-+ }
-+}
-+
-+/**
-+ * xmlXPathPositionFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the position() XPath function
-+ * number position()
-+ * The position function returns the position of the context node in the
-+ * context node list. The first position is 1, and so the last positionr
-+ * will be equal to last().
-+ */
-+void
-+xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ CHECK_ARITY(0);
-+ if (ctxt->context->proximityPosition >= 0) {
-+ valuePush(ctxt,
-+ xmlXPathNewFloat((double) ctxt->context->proximityPosition));
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
-+ ctxt->context->proximityPosition);
-+#endif
-+ } else {
-+ XP_ERROR(XPATH_INVALID_CTXT_POSITION);
-+ }
-+}
-+
-+/**
-+ * xmlXPathCountFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the count() XPath function
-+ * number count(node-set)
-+ */
-+void
-+xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_XSLT_TREE)))
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ cur = valuePop(ctxt);
-+
-+ valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr));
-+ xmlXPathFreeObject(cur);
-+}
-+
-+/**
-+ * xmlXPathIdFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the id() XPath function
-+ * node-set id(object)
-+ * The id function selects elements by their unique ID
-+ * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
-+ * then the result is the union of the result of applying id to the
-+ * string value of each of the nodes in the argument node-set. When the
-+ * argument to id is of any other type, the argument is converted to a
-+ * string as if by a call to the string function; the string is split
-+ * into a whitespace-separated list of tokens (whitespace is any sequence
-+ * of characters matching the production S); the result is a node-set
-+ * containing the elements in the same document as the context node that
-+ * have a unique ID equal to any of the tokens in the list.
-+ */
-+void
-+xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ const xmlChar *tokens;
-+ const xmlChar *cur;
-+ xmlChar *ID;
-+ xmlAttrPtr attr;
-+ xmlNodePtr elem = NULL;
-+ xmlXPathObjectPtr ret, obj;
-+
-+ CHECK_ARITY(1);
-+ obj = valuePop(ctxt);
-+ if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
-+ if (obj->type == XPATH_NODESET) {
-+ xmlXPathObjectPtr newobj;
-+ int i;
-+
-+ ret = xmlXPathNewNodeSet(NULL);
-+
-+ for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-+ valuePush(ctxt,
-+ xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
-+ xmlXPathStringFunction(ctxt, 1);
-+ xmlXPathIdFunction(ctxt, 1);
-+ newobj = valuePop(ctxt);
-+ ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
-+ newobj->nodesetval);
-+ xmlXPathFreeObject(newobj);
-+ }
-+
-+ xmlXPathFreeObject(obj);
-+ valuePush(ctxt, ret);
-+ return;
-+ }
-+ if (obj->type != XPATH_STRING) {
-+ valuePush(ctxt, obj);
-+ xmlXPathStringFunction(ctxt, 1);
-+ obj = valuePop(ctxt);
-+ if (obj->type != XPATH_STRING) {
-+ xmlXPathFreeObject(obj);
-+ return;
-+ }
-+ }
-+ tokens = obj->stringval;
-+
-+ ret = xmlXPathNewNodeSet(NULL);
-+ valuePush(ctxt, ret);
-+ if (tokens == NULL) {
-+ xmlXPathFreeObject(obj);
-+ return;
-+ }
-+
-+ cur = tokens;
-+
-+ while (IS_BLANK(*cur)) cur++;
-+ while (*cur != 0) {
-+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-+ (*cur == '.') || (*cur == '-') ||
-+ (*cur == '_') || (*cur == ':') ||
-+ (IS_COMBINING(*cur)) ||
-+ (IS_EXTENDER(*cur)))
-+ cur++;
-+
-+ if ((!IS_BLANK(*cur)) && (*cur != 0)) break;
-+
-+ ID = xmlStrndup(tokens, cur - tokens);
-+ attr = xmlGetID(ctxt->context->doc, ID);
-+ if (attr != NULL) {
-+ elem = attr->parent;
-+ xmlXPathNodeSetAdd(ret->nodesetval, elem);
-+ }
-+ if (ID != NULL)
-+ xmlFree(ID);
-+
-+ while (IS_BLANK(*cur)) cur++;
-+ tokens = cur;
-+ }
-+ xmlXPathFreeObject(obj);
-+ return;
-+}
-+
-+/**
-+ * xmlXPathLocalNameFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the local-name() XPath function
-+ * string local-name(node-set?)
-+ * The local-name function returns a string containing the local part
-+ * of the name of the node in the argument node-set that is first in
-+ * document order. If the node-set is empty or the first node has no
-+ * name, an empty string is returned. If the argument is omitted it
-+ * defaults to the context node.
-+ */
-+void
-+xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+
-+ if (nargs == 0) {
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+ nargs = 1;
-+ }
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_XSLT_TREE)))
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ cur = valuePop(ctxt);
-+
-+ if (cur->nodesetval->nodeNr == 0) {
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ } else {
-+ int i = 0; /* Should be first in document order !!!!! */
-+ switch (cur->nodesetval->nodeTab[i]->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ case XML_PI_NODE:
-+ valuePush(ctxt,
-+ xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
-+ break;
-+ case XML_NAMESPACE_DECL:
-+ valuePush(ctxt, xmlXPathNewString(
-+ ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
-+ break;
-+ default:
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ }
-+ }
-+ xmlXPathFreeObject(cur);
-+}
-+
-+/**
-+ * xmlXPathNamespaceURIFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the namespace-uri() XPath function
-+ * string namespace-uri(node-set?)
-+ * The namespace-uri function returns a string containing the
-+ * namespace URI of the expanded name of the node in the argument
-+ * node-set that is first in document order. If the node-set is empty,
-+ * the first node has no name, or the expanded name has no namespace
-+ * URI, an empty string is returned. If the argument is omitted it
-+ * defaults to the context node.
-+ */
-+void
-+xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+
-+ if (nargs == 0) {
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+ nargs = 1;
-+ }
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_XSLT_TREE)))
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ cur = valuePop(ctxt);
-+
-+ if (cur->nodesetval->nodeNr == 0) {
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ } else {
-+ int i = 0; /* Should be first in document order !!!!! */
-+ switch (cur->nodesetval->nodeTab[i]->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ if (cur->nodesetval->nodeTab[i]->ns == NULL)
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ else
-+ valuePush(ctxt, xmlXPathNewString(
-+ cur->nodesetval->nodeTab[i]->ns->href));
-+ break;
-+ default:
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ }
-+ }
-+ xmlXPathFreeObject(cur);
-+}
-+
-+/**
-+ * xmlXPathNameFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the name() XPath function
-+ * string name(node-set?)
-+ * The name function returns a string containing a QName representing
-+ * the name of the node in the argument node-set that is first in documenti
-+ * order. The QName must represent the name with respect to the namespace
-+ * declarations in effect on the node whose name is being represented.
-+ * Typically, this will be the form in which the name occurred in the XML
-+ * source. This need not be the case if there are namespace declarations
-+ * in effect on the node that associate multiple prefixes with the same
-+ * namespace. However, an implementation may include information about
-+ * the original prefix in its representation of nodes; in this case, an
-+ * implementation can ensure that the returned string is always the same
-+ * as the QName used in the XML source. If the argument it omitted it
-+ * defaults to the context node.
-+ * Libxml keep the original prefix so the "real qualified name" used is
-+ * returned.
-+ */
-+void
-+xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+
-+ if (nargs == 0) {
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+ nargs = 1;
-+ }
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_XSLT_TREE)))
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ cur = valuePop(ctxt);
-+
-+ if (cur->nodesetval->nodeNr == 0) {
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ } else {
-+ int i = 0; /* Should be first in document order !!!!! */
-+
-+ switch (cur->nodesetval->nodeTab[i]->type) {
-+ case XML_ELEMENT_NODE:
-+ case XML_ATTRIBUTE_NODE:
-+ if (cur->nodesetval->nodeTab[i]->ns == NULL)
-+ valuePush(ctxt, xmlXPathNewString(
-+ cur->nodesetval->nodeTab[i]->name));
-+
-+ else {
-+ char name[2000];
-+#ifdef HAVE_SNPRINTF
-+ snprintf(name, sizeof(name), "%s:%s",
-+ (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
-+ (char *) cur->nodesetval->nodeTab[i]->name);
-+#else
-+ sprintf(name, "%s:%s",
-+ (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
-+ (char *) cur->nodesetval->nodeTab[i]->name);
-+#endif
-+ name[sizeof(name) - 1] = 0;
-+ valuePush(ctxt, xmlXPathNewCString(name));
-+ }
-+ break;
-+ default:
-+ valuePush(ctxt,
-+ xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
-+ xmlXPathLocalNameFunction(ctxt, 1);
-+ }
-+ }
-+ xmlXPathFreeObject(cur);
-+}
-+
-+/**
-+ * xmlXPathStringFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the string() XPath function
-+ * string string(object?)
-+ * he string function converts an object to a string as follows:
-+ * - A node-set is converted to a string by returning the value of
-+ * the node in the node-set that is first in document order.
-+ * If the node-set is empty, an empty string is returned.
-+ * - A number is converted to a string as follows
-+ * + NaN is converted to the string NaN
-+ * + positive zero is converted to the string 0
-+ * + negative zero is converted to the string 0
-+ * + positive infinity is converted to the string Infinity
-+ * + negative infinity is converted to the string -Infinity
-+ * + if the number is an integer, the number is represented in
-+ * decimal form as a Number with no decimal point and no leading
-+ * zeros, preceded by a minus sign (-) if the number is negative
-+ * + otherwise, the number is represented in decimal form as a
-+ * Number including a decimal point with at least one digit
-+ * before the decimal point and at least one digit after the
-+ * decimal point, preceded by a minus sign (-) if the number
-+ * is negative; there must be no leading zeros before the decimal
-+ * point apart possibly from the one required digit immediatelyi
-+ * before the decimal point; beyond the one required digit
-+ * after the decimal point there must be as many, but only as
-+ * many, more digits as are needed to uniquely distinguish the
-+ * number from all other IEEE 754 numeric values.
-+ * - The boolean false value is converted to the string false.
-+ * The boolean true value is converted to the string true.
-+ *
-+ * If the argument is omitted, it defaults to a node-set with the
-+ * context node as its only member.
-+ */
-+void
-+xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+
-+ if (nargs == 0) {
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+ nargs = 1;
-+ }
-+
-+ CHECK_ARITY(1);
-+ cur = valuePop(ctxt);
-+ if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
-+ switch (cur->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
-+#endif
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ break;
-+ case XPATH_XSLT_TREE:
-+ case XPATH_NODESET:
-+ if (cur->nodesetval->nodeNr == 0) {
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ } else {
-+ xmlChar *res;
-+ int i = 0; /* Should be first in document order !!!!! */
-+ res = xmlNodeGetContent(cur->nodesetval->nodeTab[i]);
-+ valuePush(ctxt, xmlXPathNewString(res));
-+ if (res != NULL)
-+ xmlFree(res);
-+ }
-+ xmlXPathFreeObject(cur);
-+ return;
-+ case XPATH_STRING:
-+ valuePush(ctxt, cur);
-+ return;
-+ case XPATH_BOOLEAN:
-+ if (cur->boolval) valuePush(ctxt, xmlXPathNewCString("true"));
-+ else valuePush(ctxt, xmlXPathNewCString("false"));
-+ xmlXPathFreeObject(cur);
-+ return;
-+ case XPATH_NUMBER: {
-+ char buf[100];
-+
-+ if (isnan(cur->floatval))
-+ sprintf(buf, "NaN");
-+ else if (isinf(cur->floatval) > 0)
-+ sprintf(buf, "+Infinity");
-+ else if (isinf(cur->floatval) < 0)
-+ sprintf(buf, "-Infinity");
-+ else
-+ sprintf(buf, "%0g", cur->floatval);
-+ valuePush(ctxt, xmlXPathNewCString(buf));
-+ xmlXPathFreeObject(cur);
-+ return;
-+ }
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ break;
-+ }
-+ STRANGE
-+}
-+
-+/**
-+ * xmlXPathStringLengthFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the string-length() XPath function
-+ * number string-length(string?)
-+ * The string-length returns the number of characters in the string
-+ * (see [3.6 Strings]). If the argument is omitted, it defaults to
-+ * the context node converted to a string, in other words the value
-+ * of the context node.
-+ */
-+void
-+xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+
-+ if (nargs == 0) {
-+ if (ctxt->context->node == NULL) {
-+ valuePush(ctxt, xmlXPathNewFloat(0));
-+ } else {
-+ xmlChar *content;
-+
-+ content = xmlNodeGetContent(ctxt->context->node);
-+ valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(content)));
-+ xmlFree(content);
-+ }
-+ return;
-+ }
-+ CHECK_ARITY(1);
-+ CAST_TO_STRING;
-+ CHECK_TYPE(XPATH_STRING);
-+ cur = valuePop(ctxt);
-+ valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(cur->stringval)));
-+ xmlXPathFreeObject(cur);
-+}
-+
-+/**
-+ * xmlXPathConcatFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the concat() XPath function
-+ * string concat(string, string, string*)
-+ * The concat function returns the concatenation of its arguments.
-+ */
-+void
-+xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur, newobj;
-+ xmlChar *tmp;
-+
-+ if (nargs < 2) {
-+ CHECK_ARITY(2);
-+ }
-+
-+ CAST_TO_STRING;
-+ cur = valuePop(ctxt);
-+ if ((cur == NULL) || (cur->type != XPATH_STRING)) {
-+ xmlXPathFreeObject(cur);
-+ return;
-+ }
-+ nargs--;
-+
-+ while (nargs > 0) {
-+ CAST_TO_STRING;
-+ newobj = valuePop(ctxt);
-+ if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
-+ xmlXPathFreeObject(newobj);
-+ xmlXPathFreeObject(cur);
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ }
-+ tmp = xmlStrcat(newobj->stringval, cur->stringval);
-+ newobj->stringval = cur->stringval;
-+ cur->stringval = tmp;
-+
-+ xmlXPathFreeObject(newobj);
-+ nargs--;
-+ }
-+ valuePush(ctxt, cur);
-+}
-+
-+/**
-+ * xmlXPathContainsFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the contains() XPath function
-+ * boolean contains(string, string)
-+ * The contains function returns true if the first argument string
-+ * contains the second argument string, and otherwise returns false.
-+ */
-+void
-+xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr hay, needle;
-+
-+ CHECK_ARITY(2);
-+ CAST_TO_STRING;
-+ CHECK_TYPE(XPATH_STRING);
-+ needle = valuePop(ctxt);
-+ CAST_TO_STRING;
-+ hay = valuePop(ctxt);
-+ if ((hay == NULL) || (hay->type != XPATH_STRING)) {
-+ xmlXPathFreeObject(hay);
-+ xmlXPathFreeObject(needle);
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ }
-+ if (xmlStrstr(hay->stringval, needle->stringval))
-+ valuePush(ctxt, xmlXPathNewBoolean(1));
-+ else
-+ valuePush(ctxt, xmlXPathNewBoolean(0));
-+ xmlXPathFreeObject(hay);
-+ xmlXPathFreeObject(needle);
-+}
-+
-+/**
-+ * xmlXPathStartsWithFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the starts-with() XPath function
-+ * boolean starts-with(string, string)
-+ * The starts-with function returns true if the first argument string
-+ * starts with the second argument string, and otherwise returns false.
-+ */
-+void
-+xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr hay, needle;
-+ int n;
-+
-+ CHECK_ARITY(2);
-+ CAST_TO_STRING;
-+ CHECK_TYPE(XPATH_STRING);
-+ needle = valuePop(ctxt);
-+ CAST_TO_STRING;
-+ hay = valuePop(ctxt);
-+ if ((hay == NULL) || (hay->type != XPATH_STRING)) {
-+ xmlXPathFreeObject(hay);
-+ xmlXPathFreeObject(needle);
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ }
-+ n = xmlStrlen(needle->stringval);
-+ if (xmlStrncmp(hay->stringval, needle->stringval, n))
-+ valuePush(ctxt, xmlXPathNewBoolean(0));
-+ else
-+ valuePush(ctxt, xmlXPathNewBoolean(1));
-+ xmlXPathFreeObject(hay);
-+ xmlXPathFreeObject(needle);
-+}
-+
-+/**
-+ * xmlXPathSubstringFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the substring() XPath function
-+ * string substring(string, number, number?)
-+ * The substring function returns the substring of the first argument
-+ * starting at the position specified in the second argument with
-+ * length specified in the third argument. For example,
-+ * substring("12345",2,3) returns "234". If the third argument is not
-+ * specified, it returns the substring starting at the position specified
-+ * in the second argument and continuing to the end of the string. For
-+ * example, substring("12345",2) returns "2345". More precisely, each
-+ * character in the string (see [3.6 Strings]) is considered to have a
-+ * numeric position: the position of the first character is 1, the position
-+ * of the second character is 2 and so on. The returned substring contains
-+ * those characters for which the position of the character is greater than
-+ * or equal to the second argument and, if the third argument is specified,
-+ * less than the sum of the second and third arguments; the comparisons
-+ * and addition used for the above follow the standard IEEE 754 rules. Thus:
-+ * - substring("12345", 1.5, 2.6) returns "234"
-+ * - substring("12345", 0, 3) returns "12"
-+ * - substring("12345", 0 div 0, 3) returns ""
-+ * - substring("12345", 1, 0 div 0) returns ""
-+ * - substring("12345", -42, 1 div 0) returns "12345"
-+ * - substring("12345", -1 div 0, 1 div 0) returns ""
-+ */
-+void
-+xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr str, start, len;
-+ double le, in;
-+ int i, l;
-+ xmlChar *ret;
-+
-+ /*
-+ * Conformance needs to be checked !!!!!
-+ */
-+ if (nargs < 2) {
-+ CHECK_ARITY(2);
-+ }
-+ if (nargs > 3) {
-+ CHECK_ARITY(3);
-+ }
-+ if (nargs == 3) {
-+ CAST_TO_NUMBER;
-+ CHECK_TYPE(XPATH_NUMBER);
-+ len = valuePop(ctxt);
-+ le = len->floatval;
-+ xmlXPathFreeObject(len);
-+ } else {
-+ le = 2000000000;
-+ }
-+ CAST_TO_NUMBER;
-+ CHECK_TYPE(XPATH_NUMBER);
-+ start = valuePop(ctxt);
-+ in = start->floatval;
-+ xmlXPathFreeObject(start);
-+ CAST_TO_STRING;
-+ CHECK_TYPE(XPATH_STRING);
-+ str = valuePop(ctxt);
-+ le += in;
-+
-+ /* integer index of the first char */
-+ i = (int) in;
-+ if (((double)i) != in) i++;
-+
-+ /* integer index of the last char */
-+ l = (int) le;
-+ if (((double)l) != le) l++;
-+
-+ /* back to a zero based len */
-+ i--;
-+ l--;
-+
-+ /* check against the string len */
-+ if (l > 1024) {
-+ l = xmlStrlen(str->stringval);
-+ }
-+ if (i < 0) {
-+ i = 0;
-+ }
-+
-+ /* number of chars to copy */
-+ l -= i;
-+
-+ ret = xmlStrsub(str->stringval, i, l);
-+ if (ret == NULL)
-+ valuePush(ctxt, xmlXPathNewCString(""));
-+ else {
-+ valuePush(ctxt, xmlXPathNewString(ret));
-+ xmlFree(ret);
-+ }
-+ xmlXPathFreeObject(str);
-+}
-+
-+/**
-+ * xmlXPathSubstringBeforeFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the substring-before() XPath function
-+ * string substring-before(string, string)
-+ * The substring-before function returns the substring of the first
-+ * argument string that precedes the first occurrence of the second
-+ * argument string in the first argument string, or the empty string
-+ * if the first argument string does not contain the second argument
-+ * string. For example, substring-before("1999/04/01","/") returns 1999.
-+ */
-+void
-+xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr str;
-+ xmlXPathObjectPtr find;
-+ xmlBufferPtr target;
-+ const xmlChar *point;
-+ int offset;
-+
-+ CHECK_ARITY(2);
-+ CAST_TO_STRING;
-+ find = valuePop(ctxt);
-+ CAST_TO_STRING;
-+ str = valuePop(ctxt);
-+
-+ target = xmlBufferCreate();
-+ if (target) {
-+ point = xmlStrstr(str->stringval, find->stringval);
-+ if (point) {
-+ offset = (int)(point - str->stringval);
-+ xmlBufferAdd(target, str->stringval, offset);
-+ }
-+ valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-+ xmlBufferFree(target);
-+ }
-+
-+ xmlXPathFreeObject(str);
-+ xmlXPathFreeObject(find);
-+}
-+
-+/**
-+ * xmlXPathSubstringAfterFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the substring-after() XPath function
-+ * string substring-after(string, string)
-+ * The substring-after function returns the substring of the first
-+ * argument string that follows the first occurrence of the second
-+ * argument string in the first argument string, or the empty stringi
-+ * if the first argument string does not contain the second argument
-+ * string. For example, substring-after("1999/04/01","/") returns 04/01,
-+ * and substring-after("1999/04/01","19") returns 99/04/01.
-+ */
-+void
-+xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr str;
-+ xmlXPathObjectPtr find;
-+ xmlBufferPtr target;
-+ const xmlChar *point;
-+ int offset;
-+
-+ CHECK_ARITY(2);
-+ CAST_TO_STRING;
-+ find = valuePop(ctxt);
-+ CAST_TO_STRING;
-+ str = valuePop(ctxt);
-+
-+ target = xmlBufferCreate();
-+ if (target) {
-+ point = xmlStrstr(str->stringval, find->stringval);
-+ if (point) {
-+ offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
-+ xmlBufferAdd(target, &str->stringval[offset],
-+ xmlStrlen(str->stringval) - offset);
-+ }
-+ valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-+ xmlBufferFree(target);
-+ }
-+
-+ xmlXPathFreeObject(str);
-+ xmlXPathFreeObject(find);
-+}
-+
-+/**
-+ * xmlXPathNormalizeFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the normalize-space() XPath function
-+ * string normalize-space(string?)
-+ * The normalize-space function returns the argument string with white
-+ * space normalized by stripping leading and trailing whitespace
-+ * and replacing sequences of whitespace characters by a single
-+ * space. Whitespace characters are the same allowed by the S production
-+ * in XML. If the argument is omitted, it defaults to the context
-+ * node converted to a string, in other words the value of the context node.
-+ */
-+void
-+xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr obj = NULL;
-+ xmlChar *source = NULL;
-+ xmlBufferPtr target;
-+ xmlChar blank;
-+
-+ if (nargs == 0) {
-+ /* Use current context node */
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+ xmlXPathStringFunction(ctxt, 1);
-+ nargs = 1;
-+ }
-+
-+ CHECK_ARITY(1);
-+ CAST_TO_STRING;
-+ CHECK_TYPE(XPATH_STRING);
-+ obj = valuePop(ctxt);
-+ source = obj->stringval;
-+
-+ target = xmlBufferCreate();
-+ if (target && source) {
-+
-+ /* Skip leading whitespaces */
-+ while (IS_BLANK(*source))
-+ source++;
-+
-+ /* Collapse intermediate whitespaces, and skip trailing whitespaces */
-+ blank = 0;
-+ while (*source) {
-+ if (IS_BLANK(*source)) {
-+ blank = *source;
-+ } else {
-+ if (blank) {
-+ xmlBufferAdd(target, &blank, 1);
-+ blank = 0;
-+ }
-+ xmlBufferAdd(target, source, 1);
-+ }
-+ source++;
-+ }
-+
-+ valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-+ xmlBufferFree(target);
-+ }
-+ xmlXPathFreeObject(obj);
-+}
-+
-+/**
-+ * xmlXPathTranslateFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the translate() XPath function
-+ * string translate(string, string, string)
-+ * The translate function returns the first argument string with
-+ * occurrences of characters in the second argument string replaced
-+ * by the character at the corresponding position in the third argument
-+ * string. For example, translate("bar","abc","ABC") returns the string
-+ * BAr. If there is a character in the second argument string with no
-+ * character at a corresponding position in the third argument string
-+ * (because the second argument string is longer than the third argument
-+ * string), then occurrences of that character in the first argument
-+ * string are removed. For example, translate("--aaa--","abc-","ABC")
-+ * returns "AAA". If a character occurs more than once in second
-+ * argument string, then the first occurrence determines the replacement
-+ * character. If the third argument string is longer than the second
-+ * argument string, then excess characters are ignored.
-+ */
-+void
-+xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr str;
-+ xmlXPathObjectPtr from;
-+ xmlXPathObjectPtr to;
-+ xmlBufferPtr target;
-+ int i, offset, max;
-+ xmlChar ch;
-+ const xmlChar *point;
-+
-+ CHECK_ARITY(3);
-+
-+ CAST_TO_STRING;
-+ to = valuePop(ctxt);
-+ CAST_TO_STRING;
-+ from = valuePop(ctxt);
-+ CAST_TO_STRING;
-+ str = valuePop(ctxt);
-+
-+ target = xmlBufferCreate();
-+ if (target) {
-+ max = xmlStrlen(to->stringval);
-+ for (i = 0; (ch = str->stringval[i]); i++) {
-+ point = xmlStrchr(from->stringval, ch);
-+ if (point) {
-+ /* Warning: This may not work with UTF-8 */
-+ offset = (int)(point - from->stringval);
-+ if (offset < max)
-+ xmlBufferAdd(target, &to->stringval[offset], 1);
-+ } else
-+ xmlBufferAdd(target, &ch, 1);
-+ }
-+ }
-+ valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-+ xmlBufferFree(target);
-+ xmlXPathFreeObject(str);
-+ xmlXPathFreeObject(from);
-+ xmlXPathFreeObject(to);
-+}
-+
-+/**
-+ * xmlXPathBooleanFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the boolean() XPath function
-+ * boolean boolean(object)
-+ * he boolean function converts its argument to a boolean as follows:
-+ * - a number is true if and only if it is neither positive or
-+ * negative zero nor NaN
-+ * - a node-set is true if and only if it is non-empty
-+ * - a string is true if and only if its length is non-zero
-+ */
-+void
-+xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+ int res = 0;
-+
-+ CHECK_ARITY(1);
-+ cur = valuePop(ctxt);
-+ if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
-+ switch (cur->type) {
-+ case XPATH_NODESET:
-+ case XPATH_XSLT_TREE:
-+ if ((cur->nodesetval == NULL) ||
-+ (cur->nodesetval->nodeNr == 0)) res = 0;
-+ else
-+ res = 1;
-+ break;
-+ case XPATH_STRING:
-+ if ((cur->stringval == NULL) ||
-+ (cur->stringval[0] == 0)) res = 0;
-+ else
-+ res = 1;
-+ break;
-+ case XPATH_BOOLEAN:
-+ valuePush(ctxt, cur);
-+ return;
-+ case XPATH_NUMBER:
-+ if (cur->floatval) res = 1;
-+ break;
-+ default:
-+ STRANGE
-+ }
-+ xmlXPathFreeObject(cur);
-+ valuePush(ctxt, xmlXPathNewBoolean(res));
-+}
-+
-+/**
-+ * xmlXPathNotFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the not() XPath function
-+ * boolean not(boolean)
-+ * The not function returns true if its argument is false,
-+ * and false otherwise.
-+ */
-+void
-+xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ CHECK_ARITY(1);
-+ CAST_TO_BOOLEAN;
-+ CHECK_TYPE(XPATH_BOOLEAN);
-+ ctxt->value->boolval = ! ctxt->value->boolval;
-+}
-+
-+/**
-+ * xmlXPathTrueFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the true() XPath function
-+ * boolean true()
-+ */
-+void
-+xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ CHECK_ARITY(0);
-+ valuePush(ctxt, xmlXPathNewBoolean(1));
-+}
-+
-+/**
-+ * xmlXPathFalseFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the false() XPath function
-+ * boolean false()
-+ */
-+void
-+xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ CHECK_ARITY(0);
-+ valuePush(ctxt, xmlXPathNewBoolean(0));
-+}
-+
-+/**
-+ * xmlXPathLangFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the lang() XPath function
-+ * boolean lang(string)
-+ * The lang function returns true or false depending on whether the
-+ * language of the context node as specified by xml:lang attributes
-+ * is the same as or is a sublanguage of the language specified by
-+ * the argument string. The language of the context node is determined
-+ * by the value of the xml:lang attribute on the context node, or, if
-+ * the context node has no xml:lang attribute, by the value of the
-+ * xml:lang attribute on the nearest ancestor of the context node that
-+ * has an xml:lang attribute. If there is no such attribute, then lang
-+ * returns false. If there is such an attribute, then lang returns
-+ * true if the attribute value is equal to the argument ignoring case,
-+ * or if there is some suffix starting with - such that the attribute
-+ * value is equal to the argument ignoring that suffix of the attribute
-+ * value and ignoring case.
-+ */
-+void
-+xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr val;
-+ const xmlChar *theLang;
-+ const xmlChar *lang;
-+ int ret = 0;
-+ int i;
-+
-+ CHECK_ARITY(1);
-+ CAST_TO_STRING;
-+ CHECK_TYPE(XPATH_STRING);
-+ val = valuePop(ctxt);
-+ lang = val->stringval;
-+ theLang = xmlNodeGetLang(ctxt->context->node);
-+ if ((theLang != NULL) && (lang != NULL)) {
-+ for (i = 0;lang[i] != 0;i++)
-+ if (toupper(lang[i]) != toupper(theLang[i]))
-+ goto not_equal;
-+ ret = 1;
-+ }
-+not_equal:
-+ xmlXPathFreeObject(val);
-+ valuePush(ctxt, xmlXPathNewBoolean(ret));
-+}
-+
-+/**
-+ * xmlXPathNumberFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the number() XPath function
-+ * number number(object?)
-+ */
-+void
-+xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+ double res;
-+
-+ if (nargs == 0) {
-+ if (ctxt->context->node == NULL) {
-+ valuePush(ctxt, xmlXPathNewFloat(0.0));
-+ } else {
-+ xmlChar* content = xmlNodeGetContent(ctxt->context->node);
-+
-+ res = xmlXPathStringEvalNumber(content);
-+ valuePush(ctxt, xmlXPathNewFloat(res));
-+ xmlFree(content);
-+ }
-+ return;
-+ }
-+
-+ CHECK_ARITY(1);
-+ cur = valuePop(ctxt);
-+ switch (cur->type) {
-+ case XPATH_UNDEFINED:
-+#ifdef DEBUG_EXPR
-+ xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
-+#endif
-+ valuePush(ctxt, xmlXPathNewFloat(0.0));
-+ break;
-+ case XPATH_XSLT_TREE:
-+ case XPATH_NODESET:
-+ valuePush(ctxt, cur);
-+ xmlXPathStringFunction(ctxt, 1);
-+ cur = valuePop(ctxt);
-+ case XPATH_STRING:
-+ res = xmlXPathStringEvalNumber(cur->stringval);
-+ valuePush(ctxt, xmlXPathNewFloat(res));
-+ xmlXPathFreeObject(cur);
-+ return;
-+ case XPATH_BOOLEAN:
-+ if (cur->boolval) valuePush(ctxt, xmlXPathNewFloat(1.0));
-+ else valuePush(ctxt, xmlXPathNewFloat(0.0));
-+ xmlXPathFreeObject(cur);
-+ return;
-+ case XPATH_NUMBER:
-+ valuePush(ctxt, cur);
-+ return;
-+ case XPATH_USERS:
-+ case XPATH_POINT:
-+ case XPATH_RANGE:
-+ case XPATH_LOCATIONSET:
-+ TODO
-+ valuePush(ctxt, xmlXPathNewFloat(0.0));
-+ break;
-+ }
-+ STRANGE
-+}
-+
-+/**
-+ * xmlXPathSumFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the sum() XPath function
-+ * number sum(node-set)
-+ * The sum function returns the sum of the values of the nodes in
-+ * the argument node-set.
-+ */
-+void
-+xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr cur;
-+ int i;
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_XSLT_TREE)))
-+ XP_ERROR(XPATH_INVALID_TYPE);
-+ cur = valuePop(ctxt);
-+
-+ if (cur->nodesetval->nodeNr == 0) {
-+ valuePush(ctxt, xmlXPathNewFloat(0.0));
-+ } else {
-+ valuePush(ctxt,
-+ xmlXPathNewNodeSet(cur->nodesetval->nodeTab[0]));
-+ xmlXPathNumberFunction(ctxt, 1);
-+ for (i = 1; i < cur->nodesetval->nodeNr; i++) {
-+ valuePush(ctxt,
-+ xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
-+ xmlXPathAddValues(ctxt);
-+ }
-+ }
-+ xmlXPathFreeObject(cur);
-+}
-+
-+/**
-+ * xmlXPathFloorFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the floor() XPath function
-+ * number floor(number)
-+ * The floor function returns the largest (closest to positive infinity)
-+ * number that is not greater than the argument and that is an integer.
-+ */
-+void
-+xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ CHECK_ARITY(1);
-+ CAST_TO_NUMBER;
-+ CHECK_TYPE(XPATH_NUMBER);
-+#if 0
-+ ctxt->value->floatval = floor(ctxt->value->floatval);
-+#else
-+ /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
-+ ctxt->value->floatval = (double)((int) ctxt->value->floatval);
-+#endif
-+}
-+
-+/**
-+ * xmlXPathCeilingFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the ceiling() XPath function
-+ * number ceiling(number)
-+ * The ceiling function returns the smallest (closest to negative infinity)
-+ * number that is not less than the argument and that is an integer.
-+ */
-+void
-+xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ double f;
-+
-+ CHECK_ARITY(1);
-+ CAST_TO_NUMBER;
-+ CHECK_TYPE(XPATH_NUMBER);
-+
-+#if 0
-+ ctxt->value->floatval = ceil(ctxt->value->floatval);
-+#else
-+ f = (double)((int) ctxt->value->floatval);
-+ if (f != ctxt->value->floatval)
-+ ctxt->value->floatval = f + 1;
-+#endif
-+}
-+
-+/**
-+ * xmlXPathRoundFunction:
-+ * @ctxt: the XPath Parser context
-+ * @nargs: the number of arguments
-+ *
-+ * Implement the round() XPath function
-+ * number round(number)
-+ * The round function returns the number that is closest to the
-+ * argument and that is an integer. If there are two such numbers,
-+ * then the one that is even is returned.
-+ */
-+void
-+xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ double f;
-+
-+ CHECK_ARITY(1);
-+ CAST_TO_NUMBER;
-+ CHECK_TYPE(XPATH_NUMBER);
-+
-+ if ((ctxt->value->floatval == xmlXPathNAN) ||
-+ (ctxt->value->floatval == xmlXPathPINF) ||
-+ (ctxt->value->floatval == xmlXPathNINF) ||
-+ (ctxt->value->floatval == 0.0))
-+ return;
-+
-+#if 0
-+ f = floor(ctxt->value->floatval);
-+#else
-+ f = (double)((int) ctxt->value->floatval);
-+#endif
-+ if (ctxt->value->floatval < f + 0.5)
-+ ctxt->value->floatval = f;
-+ else
-+ ctxt->value->floatval = f + 1;
-+}
-+
-+/************************************************************************
-+ * *
-+ * The Parser *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * a couple of forward declarations since we use a recursive call based
-+ * implementation.
-+ */
-+void xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt);
-+void xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt);
-+void xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt);
-+#ifdef VMS
-+void xmlXPathEvalRelLocationPath(xmlXPathParserContextPtr ctxt);
-+#define xmlXPathEvalRelativeLocationPath xmlXPathEvalRelLocationPath
-+#else
-+void xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt);
-+#endif
-+
-+/**
-+ * xmlXPathParseNCName:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * parse an XML namespace non qualified name.
-+ *
-+ * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
-+ *
-+ * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
-+ * CombiningChar | Extender
-+ *
-+ * Returns the namespace name or NULL
-+ */
-+
-+xmlChar *
-+xmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
-+ const xmlChar *q;
-+ xmlChar *ret = NULL;
-+
-+ if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
-+ q = NEXT;
-+
-+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == '.') || (CUR == '-') ||
-+ (CUR == '_') ||
-+ (IS_COMBINING(CUR)) ||
-+ (IS_EXTENDER(CUR)))
-+ NEXT;
-+
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathParseQName:
-+ * @ctxt: the XPath Parser context
-+ * @prefix: a xmlChar **
-+ *
-+ * parse an XML qualified name
-+ *
-+ * [NS 5] QName ::= (Prefix ':')? LocalPart
-+ *
-+ * [NS 6] Prefix ::= NCName
-+ *
-+ * [NS 7] LocalPart ::= NCName
-+ *
-+ * Returns the function returns the local part, and prefix is updated
-+ * to get the Prefix if any.
-+ */
-+
-+xmlChar *
-+xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
-+ xmlChar *ret = NULL;
-+
-+ *prefix = NULL;
-+ ret = xmlXPathParseNCName(ctxt);
-+ if (CUR == ':') {
-+ *prefix = ret;
-+ NEXT;
-+ ret = xmlXPathParseNCName(ctxt);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathParseName:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * parse an XML name
-+ *
-+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-+ * CombiningChar | Extender
-+ *
-+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-+ *
-+ * Returns the namespace name or NULL
-+ */
-+
-+xmlChar *
-+xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
-+ const xmlChar *q;
-+ xmlChar *ret = NULL;
-+
-+ if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
-+ q = NEXT;
-+
-+ /* TODO Make this UTF8 compliant !!! */
-+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-+ (CUR == '.') || (CUR == '-') ||
-+ (CUR == '_') || (CUR == ':') ||
-+ (IS_COMBINING(CUR)) ||
-+ (IS_EXTENDER(CUR)))
-+ NEXT;
-+
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathStringEvalNumber:
-+ * @str: A string to scan
-+ *
-+ * [30] Number ::= Digits ('.' Digits?)?
-+ * | '.' Digits
-+ * [31] Digits ::= [0-9]+
-+ *
-+ * Parse and evaluate a Number in the string
-+ * In complement of the Number expression, this function also handles
-+ * negative values : '-' Number.
-+ *
-+ * Returns the double value.
-+ */
-+double
-+xmlXPathStringEvalNumber(const xmlChar *str) {
-+ const xmlChar *cur = str;
-+ double ret = 0.0;
-+ double mult = 1;
-+ int ok = 0;
-+ int isneg = 0;
-+
-+ while (*cur == ' ') cur++;
-+ if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
-+ return(xmlXPathNAN);
-+ }
-+ if (*cur == '-') {
-+ isneg = 1;
-+ cur++;
-+ }
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ ret = ret * 10 + (*cur - '0');
-+ ok = 1;
-+ cur++;
-+ }
-+ if (*cur == '.') {
-+ cur++;
-+ if (((*cur < '0') || (*cur > '9')) && (!ok)) {
-+ return(xmlXPathNAN);
-+ }
-+ while ((*cur >= '0') && (*cur <= '9')) {
-+ mult /= 10;
-+ ret = ret + (*cur - '0') * mult;
-+ cur++;
-+ }
-+ }
-+ while (*cur == ' ') cur++;
-+ if (*cur != 0) return(xmlXPathNAN);
-+ if (isneg) ret = -ret;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathEvalNumber:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [30] Number ::= Digits ('.' Digits?)?
-+ * | '.' Digits
-+ * [31] Digits ::= [0-9]+
-+ *
-+ * Parse and evaluate a Number, then push it on the stack
-+ *
-+ */
-+void
-+xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) {
-+ double ret = 0.0;
-+ double mult = 1;
-+ int ok = 0;
-+
-+ CHECK_ERROR;
-+ if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
-+ XP_ERROR(XPATH_NUMBER_ERROR);
-+ }
-+ while ((CUR >= '0') && (CUR <= '9')) {
-+ ret = ret * 10 + (CUR - '0');
-+ ok = 1;
-+ NEXT;
-+ }
-+ if (CUR == '.') {
-+ NEXT;
-+ if (((CUR < '0') || (CUR > '9')) && (!ok)) {
-+ XP_ERROR(XPATH_NUMBER_ERROR);
-+ }
-+ while ((CUR >= '0') && (CUR <= '9')) {
-+ mult /= 10;
-+ ret = ret + (CUR - '0') * mult;
-+ NEXT;
-+ }
-+ }
-+ valuePush(ctxt, xmlXPathNewFloat(ret));
-+}
-+
-+/**
-+ * xmlXPathEvalLiteral:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Parse a Literal and push it on the stack.
-+ *
-+ * [29] Literal ::= '"' [^"]* '"'
-+ * | "'" [^']* "'"
-+ *
-+ * TODO: xmlXPathEvalLiteral memory allocation could be improved.
-+ */
-+void
-+xmlXPathEvalLiteral(xmlXPathParserContextPtr ctxt) {
-+ const xmlChar *q;
-+ xmlChar *ret = NULL;
-+
-+ if (CUR == '"') {
-+ NEXT;
-+ q = CUR_PTR;
-+ while ((IS_CHAR(CUR)) && (CUR != '"'))
-+ NEXT;
-+ if (!IS_CHAR(CUR)) {
-+ XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
-+ } else {
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+ NEXT;
-+ }
-+ } else if (CUR == '\'') {
-+ NEXT;
-+ q = CUR_PTR;
-+ while ((IS_CHAR(CUR)) && (CUR != '\''))
-+ NEXT;
-+ if (!IS_CHAR(CUR)) {
-+ XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
-+ } else {
-+ ret = xmlStrndup(q, CUR_PTR - q);
-+ NEXT;
-+ }
-+ } else {
-+ XP_ERROR(XPATH_START_LITERAL_ERROR);
-+ }
-+ if (ret == NULL) return;
-+ valuePush(ctxt, xmlXPathNewString(ret));
-+ xmlFree(ret);
-+}
-+
-+/**
-+ * xmlXPathEvalVariableReference:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Parse a VariableReference, evaluate it and push it on the stack.
-+ *
-+ * The variable bindings consist of a mapping from variable names
-+ * to variable values. The value of a variable is an object, which
-+ * of any of the types that are possible for the value of an expression,
-+ * and may also be of additional types not specified here.
-+ *
-+ * Early evaluation is possible since:
-+ * The variable bindings [...] used to evaluate a subexpression are
-+ * always the same as those used to evaluate the containing expression.
-+ *
-+ * [36] VariableReference ::= '$' QName
-+ */
-+void
-+xmlXPathEvalVariableReference(xmlXPathParserContextPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *prefix;
-+ xmlXPathObjectPtr value;
-+
-+ SKIP_BLANKS;
-+ if (CUR != '$') {
-+ XP_ERROR(XPATH_VARIABLE_REF_ERROR);
-+ }
-+ NEXT;
-+ name = xmlXPathParseQName(ctxt, &prefix);
-+ if (name == NULL) {
-+ XP_ERROR(XPATH_VARIABLE_REF_ERROR);
-+ }
-+ if (prefix == NULL) {
-+ value = xmlXPathVariableLookup(ctxt->context, name);
-+ } else {
-+ TODO;
-+ value = NULL;
-+ }
-+ xmlFree(name);
-+ if (prefix != NULL) xmlFree(prefix);
-+ if (value == NULL) {
-+ XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR);
-+ }
-+ valuePush(ctxt, value);
-+ SKIP_BLANKS;
-+}
-+
-+/**
-+ * xmlXPathIsNodeType:
-+ * @ctxt: the XPath Parser context
-+ * @name: a name string
-+ *
-+ * Is the name given a NodeType one.
-+ *
-+ * [38] NodeType ::= 'comment'
-+ * | 'text'
-+ * | 'processing-instruction'
-+ * | 'node'
-+ *
-+ * Returns 1 if true 0 otherwise
-+ */
-+int
-+xmlXPathIsNodeType(const xmlChar *name) {
-+ if (name == NULL)
-+ return(0);
-+
-+ if (xmlStrEqual(name, BAD_CAST "comment"))
-+ return(1);
-+ if (xmlStrEqual(name, BAD_CAST "text"))
-+ return(1);
-+ if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
-+ return(1);
-+ if (xmlStrEqual(name, BAD_CAST "node"))
-+ return(1);
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathEvalFunctionCall:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')'
-+ * [17] Argument ::= Expr
-+ *
-+ * Parse and evaluate a function call, the evaluation of all arguments are
-+ * pushed on the stack
-+ */
-+void
-+xmlXPathEvalFunctionCall(xmlXPathParserContextPtr ctxt) {
-+ xmlChar *name;
-+ xmlChar *prefix;
-+ xmlXPathFunction func;
-+ int nbargs = 0;
-+
-+ name = xmlXPathParseQName(ctxt, &prefix);
-+ if (name == NULL) {
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ SKIP_BLANKS;
-+ if (prefix == NULL) {
-+ func = xmlXPathFunctionLookup(ctxt->context, name);
-+ } else {
-+ TODO;
-+ func = NULL;
-+ }
-+ if (func == NULL) {
-+ xmlFree(name);
-+ if (prefix != NULL) xmlFree(prefix);
-+ XP_ERROR(XPATH_UNKNOWN_FUNC_ERROR);
-+ }
-+#ifdef DEBUG_EXPR
-+ if (prefix == NULL)
-+ xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
-+ name);
-+ else
-+ xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
-+ prefix, name);
-+#endif
-+
-+ xmlFree(name);
-+ if (prefix != NULL) xmlFree(prefix);
-+
-+ if (CUR != '(') {
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ while (CUR != ')') {
-+ xmlXPathEvalExpr(ctxt);
-+ nbargs++;
-+ if (CUR == ')') break;
-+ if (CUR != ',') {
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ func(ctxt, nbargs);
-+}
-+
-+/**
-+ * xmlXPathEvalPrimaryExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [15] PrimaryExpr ::= VariableReference
-+ * | '(' Expr ')'
-+ * | Literal
-+ * | Number
-+ * | FunctionCall
-+ *
-+ * Parse and evaluate a primary expression, then push the result on the stack
-+ */
-+void
-+xmlXPathEvalPrimaryExpr(xmlXPathParserContextPtr ctxt) {
-+ SKIP_BLANKS;
-+ if (CUR == '$') xmlXPathEvalVariableReference(ctxt);
-+ else if (CUR == '(') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ xmlXPathEvalExpr(ctxt);
-+ if (CUR != ')') {
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ } else if (IS_DIGIT(CUR)) {
-+ xmlXPathEvalNumber(ctxt);
-+ } else if ((CUR == '\'') || (CUR == '"')) {
-+ xmlXPathEvalLiteral(ctxt);
-+ } else {
-+ xmlXPathEvalFunctionCall(ctxt);
-+ }
-+ SKIP_BLANKS;
-+}
-+
-+/**
-+ * xmlXPathEvalFilterExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [20] FilterExpr ::= PrimaryExpr
-+ * | FilterExpr Predicate
-+ *
-+ * Parse and evaluate a filter expression, then push the result on the stack
-+ * Square brackets are used to filter expressions in the same way that
-+ * they are used in location paths. It is an error if the expression to
-+ * be filtered does not evaluate to a node-set. The context node list
-+ * used for evaluating the expression in square brackets is the node-set
-+ * to be filtered listed in document order.
-+ */
-+
-+void
-+xmlXPathEvalFilterExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalPrimaryExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+
-+ while (CUR == '[') {
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_LOCATIONSET)))
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+ if (ctxt->value->type == XPATH_NODESET)
-+ xmlXPathEvalPredicate(ctxt);
-+ else
-+ xmlXPtrEvalRangePredicate(ctxt);
-+ SKIP_BLANKS;
-+ }
-+
-+
-+}
-+
-+/**
-+ * xmlXPathScanName:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * Trickery: parse an XML name but without consuming the input flow
-+ * Needed to avoid insanity in the parser state.
-+ *
-+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-+ * CombiningChar | Extender
-+ *
-+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-+ *
-+ * [6] Names ::= Name (S Name)*
-+ *
-+ * Returns the Name parsed or NULL
-+ */
-+
-+xmlChar *
-+xmlXPathScanName(xmlXPathParserContextPtr ctxt) {
-+ xmlChar buf[XML_MAX_NAMELEN];
-+ int len = 0;
-+
-+ SKIP_BLANKS;
-+ if (!IS_LETTER(CUR) && (CUR != '_') &&
-+ (CUR != ':')) {
-+ return(NULL);
-+ }
-+
-+ while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
-+ (NXT(len) == '.') || (NXT(len) == '-') ||
-+ (NXT(len) == '_') || (NXT(len) == ':') ||
-+ (IS_COMBINING(NXT(len))) ||
-+ (IS_EXTENDER(NXT(len)))) {
-+ buf[len] = NXT(len);
-+ len++;
-+ if (len >= XML_MAX_NAMELEN) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlScanName: reached XML_MAX_NAMELEN limit\n");
-+ while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
-+ (NXT(len) == '.') || (NXT(len) == '-') ||
-+ (NXT(len) == '_') || (NXT(len) == ':') ||
-+ (IS_COMBINING(NXT(len))) ||
-+ (IS_EXTENDER(NXT(len))))
-+ len++;
-+ break;
-+ }
-+ }
-+ return(xmlStrndup(buf, len));
-+}
-+
-+/**
-+ * xmlXPathEvalPathExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [19] PathExpr ::= LocationPath
-+ * | FilterExpr
-+ * | FilterExpr '/' RelativeLocationPath
-+ * | FilterExpr '//' RelativeLocationPath
-+ *
-+ * Parse and evaluate a path expression, then push the result on the stack
-+ * The / operator and // operators combine an arbitrary expression
-+ * and a relative location path. It is an error if the expression
-+ * does not evaluate to a node-set.
-+ * The / operator does composition in the same way as when / is
-+ * used in a location path. As in location paths, // is short for
-+ * /descendant-or-self::node()/.
-+ */
-+
-+void
-+xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
-+ int lc = 1; /* Should we branch to LocationPath ? */
-+ xmlChar *name = NULL; /* we may have to preparse a name to find out */
-+
-+ SKIP_BLANKS;
-+ if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
-+ (CUR == '\'') || (CUR == '"')) {
-+ lc = 0;
-+ } else if (CUR == '/') {
-+ /* relative or absolute location path */
-+ lc = 1;
-+ } else if (CUR == '@') {
-+ /* relative abbreviated attribute location path */
-+ lc = 1;
-+ } else if (CUR == '.') {
-+ /* relative abbreviated attribute location path */
-+ lc = 1;
-+ } else {
-+ /*
-+ * Problem is finding if we have a name here whether it's:
-+ * - a nodetype
-+ * - a function call in which case it's followed by '('
-+ * - an axis in which case it's followed by ':'
-+ * - a element name
-+ * We do an a priori analysis here rather than having to
-+ * maintain parsed token content through the recursive function
-+ * calls. This looks uglier but makes the code quite easier to
-+ * read/write/debug.
-+ */
-+ SKIP_BLANKS;
-+ name = xmlXPathScanName(ctxt);
-+ if (name != NULL) {
-+ int len =xmlStrlen(name);
-+ int blank = 0;
-+
-+ while (NXT(len) != 0) {
-+ if (NXT(len) == '/') {
-+ /* element name */
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PathExpr: AbbrRelLocation\n");
-+#endif
-+ lc = 1;
-+ break;
-+ } else if (IS_BLANK(NXT(len))) {
-+ /* skip to next */
-+ blank = 1;
-+ } else if (NXT(len) == ':') {
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PathExpr: AbbrRelLocation\n");
-+#endif
-+ lc = 1;
-+ break;
-+ } else if ((NXT(len) == '(')) {
-+ /* Note Type or Function */
-+ if (xmlXPathIsNodeType(name)) {
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PathExpr: Type search\n");
-+#endif
-+ lc = 1;
-+ } else {
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PathExpr: function call\n");
-+#endif
-+ lc = 0;
-+ }
-+ break;
-+ } else if ((NXT(len) == '[')) {
-+ /* element name */
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PathExpr: AbbrRelLocation\n");
-+#endif
-+ lc = 1;
-+ break;
-+ } else if ((NXT(len) == '<') || (NXT(len) == '>') ||
-+ (NXT(len) == '=')) {
-+ lc = 1;
-+ break;
-+ } else {
-+ lc = 1;
-+ break;
-+ }
-+ len++;
-+ }
-+ if (NXT(len) == 0) {
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "PathExpr: AbbrRelLocation\n");
-+#endif
-+ /* element name */
-+ lc = 1;
-+ }
-+ xmlFree(name);
-+ } else {
-+ /* make sure all cases are covered explicitely */
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ }
-+
-+ if (lc) {
-+ if (CUR == '/')
-+ xmlXPathRoot(ctxt);
-+ else {
-+ /* TAG:9999 */
-+ valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-+ }
-+ xmlXPathEvalLocationPath(ctxt);
-+ } else {
-+ xmlXPathEvalFilterExpr(ctxt);
-+ CHECK_ERROR;
-+ if ((CUR == '/') && (NXT(1) == '/')) {
-+ SKIP(2);
-+ SKIP_BLANKS;
-+ xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
-+ NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-+ ctxt->context->node = NULL;
-+ xmlXPathEvalRelativeLocationPath(ctxt);
-+ } else if (CUR == '/') {
-+ xmlXPathEvalRelativeLocationPath(ctxt);
-+ }
-+ }
-+ SKIP_BLANKS;
-+}
-+
-+/**
-+ * xmlXPathEvalUnionExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [18] UnionExpr ::= PathExpr
-+ * | UnionExpr '|' PathExpr
-+ *
-+ * Parse and evaluate an union expression, then push the result on the stack
-+ */
-+
-+void
-+xmlXPathEvalUnionExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalPathExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while (CUR == '|') {
-+ xmlXPathObjectPtr obj1,obj2, tmp;
-+
-+ CHECK_TYPE(XPATH_NODESET);
-+ obj1 = valuePop(ctxt);
-+ tmp = xmlXPathNewNodeSet(ctxt->context->node);
-+ valuePush(ctxt, tmp);
-+
-+ NEXT;
-+ SKIP_BLANKS;
-+ xmlXPathEvalPathExpr(ctxt);
-+
-+ CHECK_TYPE(XPATH_NODESET);
-+ obj2 = valuePop(ctxt);
-+ obj1->nodesetval = xmlXPathNodeSetMerge(obj1->nodesetval,
-+ obj2->nodesetval);
-+ if (ctxt->value == tmp) {
-+ tmp = valuePop(ctxt);
-+ xmlXPathFreeObject(tmp);
-+ }
-+ valuePush(ctxt, obj1);
-+ xmlXPathFreeObject(obj2);
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalUnaryExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [27] UnaryExpr ::= UnionExpr
-+ * | '-' UnaryExpr
-+ *
-+ * Parse and evaluate an unary expression, then push the result on the stack
-+ */
-+
-+void
-+xmlXPathEvalUnaryExpr(xmlXPathParserContextPtr ctxt) {
-+ int minus = 0;
-+
-+ SKIP_BLANKS;
-+ if (CUR == '-') {
-+ minus = 1;
-+ NEXT;
-+ SKIP_BLANKS;
-+ }
-+ xmlXPathEvalUnionExpr(ctxt);
-+ CHECK_ERROR;
-+ if (minus) {
-+ xmlXPathValueFlipSign(ctxt);
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalMultiplicativeExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [26] MultiplicativeExpr ::= UnaryExpr
-+ * | MultiplicativeExpr MultiplyOperator UnaryExpr
-+ * | MultiplicativeExpr 'div' UnaryExpr
-+ * | MultiplicativeExpr 'mod' UnaryExpr
-+ * [34] MultiplyOperator ::= '*'
-+ *
-+ * Parse and evaluate an Additive expression, then push the result on the stack
-+ */
-+
-+void
-+xmlXPathEvalMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalUnaryExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while ((CUR == '*') ||
-+ ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
-+ ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
-+ int op = -1;
-+
-+ if (CUR == '*') {
-+ op = 0;
-+ NEXT;
-+ } else if (CUR == 'd') {
-+ op = 1;
-+ SKIP(3);
-+ } else if (CUR == 'm') {
-+ op = 2;
-+ SKIP(3);
-+ }
-+ SKIP_BLANKS;
-+ xmlXPathEvalUnaryExpr(ctxt);
-+ CHECK_ERROR;
-+ switch (op) {
-+ case 0:
-+ xmlXPathMultValues(ctxt);
-+ break;
-+ case 1:
-+ xmlXPathDivValues(ctxt);
-+ break;
-+ case 2:
-+ xmlXPathModValues(ctxt);
-+ break;
-+ }
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalAdditiveExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [25] AdditiveExpr ::= MultiplicativeExpr
-+ * | AdditiveExpr '+' MultiplicativeExpr
-+ * | AdditiveExpr '-' MultiplicativeExpr
-+ *
-+ * Parse and evaluate an Additive expression, then push the result on the stack
-+ */
-+
-+void
-+xmlXPathEvalAdditiveExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalMultiplicativeExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while ((CUR == '+') || (CUR == '-')) {
-+ int plus;
-+
-+ if (CUR == '+') plus = 1;
-+ else plus = 0;
-+ NEXT;
-+ SKIP_BLANKS;
-+ xmlXPathEvalMultiplicativeExpr(ctxt);
-+ CHECK_ERROR;
-+ if (plus) xmlXPathAddValues(ctxt);
-+ else xmlXPathSubValues(ctxt);
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalRelationalExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [24] RelationalExpr ::= AdditiveExpr
-+ * | RelationalExpr '<' AdditiveExpr
-+ * | RelationalExpr '>' AdditiveExpr
-+ * | RelationalExpr '<=' AdditiveExpr
-+ * | RelationalExpr '>=' AdditiveExpr
-+ *
-+ * A <= B > C is allowed ? Answer from James, yes with
-+ * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
-+ * which is basically what got implemented.
-+ *
-+ * Parse and evaluate a Relational expression, then push the result
-+ * on the stack
-+ */
-+
-+void
-+xmlXPathEvalRelationalExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalAdditiveExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while ((CUR == '<') ||
-+ (CUR == '>') ||
-+ ((CUR == '<') && (NXT(1) == '=')) ||
-+ ((CUR == '>') && (NXT(1) == '='))) {
-+ int inf, strict, ret;
-+
-+ if (CUR == '<') inf = 1;
-+ else inf = 0;
-+ if (NXT(1) == '=') strict = 0;
-+ else strict = 1;
-+ NEXT;
-+ if (!strict) NEXT;
-+ SKIP_BLANKS;
-+ xmlXPathEvalAdditiveExpr(ctxt);
-+ CHECK_ERROR;
-+ ret = xmlXPathCompareValues(ctxt, inf, strict);
-+ valuePush(ctxt, xmlXPathNewBoolean(ret));
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalEqualityExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [23] EqualityExpr ::= RelationalExpr
-+ * | EqualityExpr '=' RelationalExpr
-+ * | EqualityExpr '!=' RelationalExpr
-+ *
-+ * A != B != C is allowed ? Answer from James, yes with
-+ * (RelationalExpr = RelationalExpr) = RelationalExpr
-+ * (RelationalExpr != RelationalExpr) != RelationalExpr
-+ * which is basically what got implemented.
-+ *
-+ * Parse and evaluate an Equality expression, then push the result on the stack
-+ *
-+ */
-+void
-+xmlXPathEvalEqualityExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalRelationalExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
-+ xmlXPathObjectPtr res;
-+ int eq, equal;
-+
-+ if (CUR == '=') eq = 1;
-+ else eq = 0;
-+ NEXT;
-+ if (!eq) NEXT;
-+ SKIP_BLANKS;
-+ xmlXPathEvalRelationalExpr(ctxt);
-+ CHECK_ERROR;
-+ equal = xmlXPathEqualValues(ctxt);
-+ if (eq) res = xmlXPathNewBoolean(equal);
-+ else res = xmlXPathNewBoolean(!equal);
-+ valuePush(ctxt, res);
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalAndExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [22] AndExpr ::= EqualityExpr
-+ * | AndExpr 'and' EqualityExpr
-+ *
-+ * Parse and evaluate an AND expression, then push the result on the stack
-+ *
-+ */
-+void
-+xmlXPathEvalAndExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalEqualityExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
-+ xmlXPathObjectPtr arg1, arg2;
-+
-+ SKIP(3);
-+ SKIP_BLANKS;
-+ xmlXPathEvalEqualityExpr(ctxt);
-+ CHECK_ERROR;
-+ xmlXPathBooleanFunction(ctxt, 1);
-+ arg2 = valuePop(ctxt);
-+ xmlXPathBooleanFunction(ctxt, 1);
-+ arg1 = valuePop(ctxt);
-+ arg1->boolval &= arg2->boolval;
-+ valuePush(ctxt, arg1);
-+ xmlXPathFreeObject(arg2);
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalExpr:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [14] Expr ::= OrExpr
-+ * [21] OrExpr ::= AndExpr
-+ * | OrExpr 'or' AndExpr
-+ *
-+ * Parse and evaluate an expression, then push the result on the stack
-+ *
-+ */
-+void
-+xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathEvalAndExpr(ctxt);
-+ CHECK_ERROR;
-+ SKIP_BLANKS;
-+ while ((CUR == 'o') && (NXT(1) == 'r')) {
-+ xmlXPathObjectPtr arg1, arg2;
-+
-+ SKIP(2);
-+ SKIP_BLANKS;
-+ xmlXPathEvalAndExpr(ctxt);
-+ CHECK_ERROR;
-+ xmlXPathBooleanFunction(ctxt, 1);
-+ arg2 = valuePop(ctxt);
-+ xmlXPathBooleanFunction(ctxt, 1);
-+ arg1 = valuePop(ctxt);
-+ arg1->boolval |= arg2->boolval;
-+ valuePush(ctxt, arg1);
-+ xmlXPathFreeObject(arg2);
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvaluatePredicateResult:
-+ * @ctxt: the XPath Parser context
-+ * @res: the Predicate Expression evaluation result
-+ *
-+ * Evaluate a predicate result for the current node.
-+ * A PredicateExpr is evaluated by evaluating the Expr and converting
-+ * the result to a boolean. If the result is a number, the result will
-+ * be converted to true if the number is equal to the position of the
-+ * context node in the context node list (as returned by the position
-+ * function) and will be converted to false otherwise; if the result
-+ * is not a number, then the result will be converted as if by a call
-+ * to the boolean function.
-+ *
-+ * Return 1 if predicate is true, 0 otherwise
-+ */
-+int
-+xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
-+ xmlXPathObjectPtr res) {
-+ if (res == NULL) return(0);
-+ switch (res->type) {
-+ case XPATH_BOOLEAN:
-+ return(res->boolval);
-+ case XPATH_NUMBER:
-+ return(res->floatval == ctxt->context->proximityPosition);
-+ case XPATH_NODESET:
-+ case XPATH_XSLT_TREE:
-+ return(res->nodesetval->nodeNr != 0);
-+ case XPATH_STRING:
-+ return((res->stringval != NULL) &&
-+ (xmlStrlen(res->stringval) != 0));
-+ default:
-+ STRANGE
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPathEvalPredicate:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [8] Predicate ::= '[' PredicateExpr ']'
-+ * [9] PredicateExpr ::= Expr
-+ *
-+ * ---------------------
-+ * For each node in the node-set to be filtered, the PredicateExpr is
-+ * evaluated with that node as the context node, with the number of nodes
-+ * in the node-set as the context size, and with the proximity position
-+ * of the node in the node-set with respect to the axis as the context
-+ * position; if PredicateExpr evaluates to true for that node, the node
-+ * is included in the new node-set; otherwise, it is not included.
-+ * ---------------------
-+ *
-+ * Parse and evaluate a predicate for all the elements of the
-+ * current node list. Then refine the list by removing all
-+ * nodes where the predicate is false.
-+ */
-+void
-+xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
-+ const xmlChar *cur;
-+ xmlXPathObjectPtr res;
-+ xmlXPathObjectPtr obj, tmp;
-+ xmlNodeSetPtr newset = NULL;
-+ xmlNodeSetPtr oldset;
-+ int i;
-+
-+ SKIP_BLANKS;
-+ if (CUR != '[') {
-+ XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Extract the old set, and then evaluate the result of the
-+ * expression for all the element in the set. use it to grow
-+ * up a new set.
-+ */
-+ CHECK_TYPE(XPATH_NODESET);
-+ obj = valuePop(ctxt);
-+ oldset = obj->nodesetval;
-+ ctxt->context->node = NULL;
-+
-+ if ((oldset == NULL) || (oldset->nodeNr == 0)) {
-+ ctxt->context->contextSize = 0;
-+ ctxt->context->proximityPosition = 0;
-+ xmlXPathEvalExpr(ctxt);
-+ res = valuePop(ctxt);
-+ if (res != NULL)
-+ xmlXPathFreeObject(res);
-+ valuePush(ctxt, obj);
-+ CHECK_ERROR;
-+ } else {
-+ /*
-+ * Save the expression pointer since we will have to evaluate
-+ * it multiple times. Initialize the new set.
-+ */
-+ cur = ctxt->cur;
-+ newset = xmlXPathNodeSetCreate(NULL);
-+
-+ for (i = 0; i < oldset->nodeNr; i++) {
-+ ctxt->cur = cur;
-+
-+ /*
-+ * Run the evaluation with a node list made of a single item
-+ * in the nodeset.
-+ */
-+ ctxt->context->node = oldset->nodeTab[i];
-+ tmp = xmlXPathNewNodeSet(ctxt->context->node);
-+ valuePush(ctxt, tmp);
-+ ctxt->context->contextSize = oldset->nodeNr;
-+ ctxt->context->proximityPosition = i + 1;
-+
-+ xmlXPathEvalExpr(ctxt);
-+ CHECK_ERROR;
-+
-+ /*
-+ * The result of the evaluation need to be tested to
-+ * decided whether the filter succeeded or not
-+ */
-+ res = valuePop(ctxt);
-+ if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-+ xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
-+ }
-+
-+ /*
-+ * Cleanup
-+ */
-+ if (res != NULL)
-+ xmlXPathFreeObject(res);
-+ if (ctxt->value == tmp) {
-+ res = valuePop(ctxt);
-+ xmlXPathFreeObject(res);
-+ }
-+
-+ ctxt->context->node = NULL;
-+ }
-+
-+ /*
-+ * The result is used as the new evaluation set.
-+ */
-+ xmlXPathFreeObject(obj);
-+ ctxt->context->node = NULL;
-+ ctxt->context->contextSize = -1;
-+ ctxt->context->proximityPosition = -1;
-+ valuePush(ctxt, xmlXPathWrapNodeSet(newset));
-+ }
-+ if (CUR != ']') {
-+ XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-+ }
-+
-+ NEXT;
-+ SKIP_BLANKS;
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext, "After predicate : ");
-+ xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
-+ ctxt->value->nodesetval);
-+#endif
-+}
-+
-+/**
-+ * xmlXPathEvalNodeTest:
-+ * @ctxt: the XPath Parser context
-+ * @test: pointer to a xmlXPathTestVal
-+ * @type: pointer to a xmlXPathTypeVal
-+ * @prefix: placeholder for a possible name prefix
-+ *
-+ * [7] NodeTest ::= NameTest
-+ * | NodeType '(' ')'
-+ * | 'processing-instruction' '(' Literal ')'
-+ *
-+ * [37] NameTest ::= '*'
-+ * | NCName ':' '*'
-+ * | QName
-+ * [38] NodeType ::= 'comment'
-+ * | 'text'
-+ * | 'processing-instruction'
-+ * | 'node'
-+ *
-+ * Returns the name found and update @test, @type and @prefix appropriately
-+ */
-+xmlChar *
-+xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
-+ xmlXPathTypeVal *type, const xmlChar **prefix, xmlChar *name) {
-+ int blanks;
-+
-+ if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
-+ STRANGE;
-+ return(NULL);
-+ }
-+ *type = 0;
-+ *test = 0;
-+ *prefix = NULL;
-+ SKIP_BLANKS;
-+
-+ if ((name == NULL) && (CUR == '*')) {
-+ /*
-+ * All elements
-+ */
-+ NEXT;
-+ *test = NODE_TEST_ALL;
-+ return(NULL);
-+ }
-+
-+ if (name == NULL)
-+ name = xmlXPathParseNCName(ctxt);
-+ if (name == NULL) {
-+ XP_ERROR0(XPATH_EXPR_ERROR);
-+ }
-+
-+ blanks = IS_BLANK(CUR);
-+ SKIP_BLANKS;
-+ if (CUR == '(') {
-+ NEXT;
-+ /*
-+ * NodeType or PI search
-+ */
-+ if (xmlStrEqual(name, BAD_CAST "comment"))
-+ *type = NODE_TYPE_COMMENT;
-+ else if (xmlStrEqual(name, BAD_CAST "node"))
-+ *type = NODE_TYPE_NODE;
-+ else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
-+ *type = NODE_TYPE_PI;
-+ else if (xmlStrEqual(name, BAD_CAST "text"))
-+ *type = NODE_TYPE_TEXT;
-+ else {
-+ if (name != NULL)
-+ xmlFree(name);
-+ XP_ERROR0(XPATH_EXPR_ERROR);
-+ }
-+
-+ *test = NODE_TEST_TYPE;
-+
-+ SKIP_BLANKS;
-+ if (*type == NODE_TYPE_PI) {
-+ /*
-+ * Specific case: search a PI by name.
-+ */
-+ xmlXPathObjectPtr cur;
-+
-+ if (name != NULL)
-+ xmlFree(name);
-+
-+ xmlXPathEvalLiteral(ctxt);
-+ CHECK_ERROR 0;
-+ xmlXPathStringFunction(ctxt, 1);
-+ CHECK_ERROR0;
-+ cur = valuePop(ctxt);
-+ name = xmlStrdup(cur->stringval);
-+ xmlXPathFreeObject(cur);
-+ SKIP_BLANKS;
-+ }
-+ if (CUR != ')') {
-+ if (name != NULL)
-+ xmlFree(name);
-+ XP_ERROR0(XPATH_UNCLOSED_ERROR);
-+ }
-+ NEXT;
-+ return(name);
-+ }
-+ *test = NODE_TEST_NAME;
-+ if ((!blanks) && (CUR == ':')) {
-+ NEXT;
-+
-+ /*
-+ * get the namespace name for this prefix
-+ */
-+ *prefix = xmlXPathNsLookup(ctxt->context, name);
-+ if (name != NULL)
-+ xmlFree(name);
-+ if (*prefix == NULL) {
-+ XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
-+ }
-+
-+ if (CUR == '*') {
-+ /*
-+ * All elements
-+ */
-+ NEXT;
-+ *test = NODE_TEST_ALL;
-+ return(NULL);
-+ }
-+
-+ name = xmlXPathParseNCName(ctxt);
-+ if (name == NULL) {
-+ XP_ERROR0(XPATH_EXPR_ERROR);
-+ }
-+ }
-+ return(name);
-+}
-+
-+/**
-+ * xmlXPathIsAxisName:
-+ * @name: a preparsed name token
-+ *
-+ * [6] AxisName ::= 'ancestor'
-+ * | 'ancestor-or-self'
-+ * | 'attribute'
-+ * | 'child'
-+ * | 'descendant'
-+ * | 'descendant-or-self'
-+ * | 'following'
-+ * | 'following-sibling'
-+ * | 'namespace'
-+ * | 'parent'
-+ * | 'preceding'
-+ * | 'preceding-sibling'
-+ * | 'self'
-+ *
-+ * Returns the axis or 0
-+ */
-+xmlXPathAxisVal
-+xmlXPathIsAxisName(const xmlChar *name) {
-+ xmlXPathAxisVal ret = 0;
-+ switch (name[0]) {
-+ case 'a':
-+ if (xmlStrEqual(name, BAD_CAST "ancestor"))
-+ ret = AXIS_ANCESTOR;
-+ if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
-+ ret = AXIS_ANCESTOR_OR_SELF;
-+ if (xmlStrEqual(name, BAD_CAST "attribute"))
-+ ret = AXIS_ATTRIBUTE;
-+ break;
-+ case 'c':
-+ if (xmlStrEqual(name, BAD_CAST "child"))
-+ ret = AXIS_CHILD;
-+ break;
-+ case 'd':
-+ if (xmlStrEqual(name, BAD_CAST "descendant"))
-+ ret = AXIS_DESCENDANT;
-+ if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
-+ ret = AXIS_DESCENDANT_OR_SELF;
-+ break;
-+ case 'f':
-+ if (xmlStrEqual(name, BAD_CAST "following"))
-+ ret = AXIS_FOLLOWING;
-+ if (xmlStrEqual(name, BAD_CAST "following-sibling"))
-+ ret = AXIS_FOLLOWING_SIBLING;
-+ break;
-+ case 'n':
-+ if (xmlStrEqual(name, BAD_CAST "namespace"))
-+ ret = AXIS_NAMESPACE;
-+ break;
-+ case 'p':
-+ if (xmlStrEqual(name, BAD_CAST "parent"))
-+ ret = AXIS_PARENT;
-+ if (xmlStrEqual(name, BAD_CAST "preceding"))
-+ ret = AXIS_PRECEDING;
-+ if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
-+ ret = AXIS_PRECEDING_SIBLING;
-+ break;
-+ case 's':
-+ if (xmlStrEqual(name, BAD_CAST "self"))
-+ ret = AXIS_SELF;
-+ break;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathEvalAxisSpecifier:
-+ * @ctxt: the XPath Parser context
-+ *
-+ *
-+ * Returns the axis found
-+ */
-+xmlXPathAxisVal
-+xmlXPathEvalAxisSpecifier(xmlXPathParserContextPtr ctxt) {
-+ xmlXPathAxisVal ret = AXIS_CHILD;
-+ int blank = 0;
-+ xmlChar *name;
-+
-+ if (CUR == '@') {
-+ NEXT;
-+ return(AXIS_ATTRIBUTE);
-+ } else {
-+ name = xmlXPathParseNCName(ctxt);
-+ if (name == NULL) {
-+ XP_ERROR0(XPATH_EXPR_ERROR);
-+ }
-+ if (IS_BLANK(CUR))
-+ blank = 1;
-+ SKIP_BLANKS;
-+ if ((CUR == ':') && (NXT(1) == ':')) {
-+ ret = xmlXPathIsAxisName(name);
-+ } else if ((blank) && (CUR == ':'))
-+ XP_ERROR0(XPATH_EXPR_ERROR);
-+
-+ xmlFree(name);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPathEvalStep:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [4] Step ::= AxisSpecifier NodeTest Predicate*
-+ * | AbbreviatedStep
-+ *
-+ * [12] AbbreviatedStep ::= '.' | '..'
-+ *
-+ * [5] AxisSpecifier ::= AxisName '::'
-+ * | AbbreviatedAxisSpecifier
-+ *
-+ * [13] AbbreviatedAxisSpecifier ::= '@'?
-+ *
-+ * Modified for XPtr range support as:
-+ *
-+ * [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
-+ * | AbbreviatedStep
-+ * | 'range-to' '(' Expr ')' Predicate*
-+ *
-+ * Evaluate one step in a Location Path
-+ * A location step of . is short for self::node(). This is
-+ * particularly useful in conjunction with //. For example, the
-+ * location path .//para is short for
-+ * self::node()/descendant-or-self::node()/child::para
-+ * and so will select all para descendant elements of the context
-+ * node.
-+ * Similarly, a location step of .. is short for parent::node().
-+ * For example, ../title is short for parent::node()/child::title
-+ * and so will select the title children of the parent of the context
-+ * node.
-+ */
-+void
-+xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
-+ SKIP_BLANKS;
-+ if ((CUR == '.') && (NXT(1) == '.')) {
-+ SKIP(2);
-+ SKIP_BLANKS;
-+ xmlXPathNodeCollectAndTest(ctxt, AXIS_PARENT,
-+ NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-+ } else if (CUR == '.') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ } else {
-+ xmlChar *name = NULL;
-+ const xmlChar *prefix = NULL;
-+ xmlXPathTestVal test;
-+ xmlXPathAxisVal axis;
-+ xmlXPathTypeVal type;
-+
-+ /*
-+ * The modification needed for XPointer change to the production
-+ */
-+#ifdef LIBXML_XPTR_ENABLED
-+ if (ctxt->context->xptr) {
-+ name = xmlXPathParseNCName(ctxt);
-+ if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
-+ xmlFree(name);
-+ SKIP_BLANKS;
-+ if (CUR != '(') {
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ xmlXPtrRangeToFunction(ctxt, 1);
-+ CHECK_ERROR;
-+
-+ SKIP_BLANKS;
-+ if (CUR != ')') {
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ }
-+ NEXT;
-+ goto eval_predicates;
-+ }
-+ }
-+#endif
-+ if (name == NULL)
-+ name = xmlXPathParseNCName(ctxt);
-+ if (name != NULL) {
-+ axis = xmlXPathIsAxisName(name);
-+ if (axis != 0) {
-+ SKIP_BLANKS;
-+ if ((CUR == ':') && (NXT(1) == ':')) {
-+ SKIP(2);
-+ xmlFree(name);
-+ name = NULL;
-+ } else {
-+ /* an element name can conflict with an axis one :-\ */
-+ axis = AXIS_CHILD;
-+ }
-+ } else {
-+ axis = AXIS_CHILD;
-+ }
-+ } else if (CUR == '@') {
-+ NEXT;
-+ axis = AXIS_ATTRIBUTE;
-+ } else {
-+ axis = AXIS_CHILD;
-+ }
-+
-+ CHECK_ERROR;
-+
-+ name = xmlXPathEvalNodeTest(ctxt, &test, &type, &prefix, name);
-+ if (test == 0)
-+ return;
-+
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext,
-+ "Basis : computing new set\n");
-+#endif
-+ xmlXPathNodeCollectAndTest(ctxt, axis, test, type, prefix, name);
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext, "Basis : ");
-+ xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
-+#endif
-+ if (name != NULL)
-+ xmlFree(name);
-+
-+eval_predicates:
-+ SKIP_BLANKS;
-+ while (CUR == '[') {
-+ xmlXPathEvalPredicate(ctxt);
-+ }
-+ }
-+#ifdef DEBUG_STEP
-+ xmlGenericError(xmlGenericErrorContext, "Step : ");
-+ xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
-+ ctxt->value->nodesetval);
-+#endif
-+}
-+
-+/**
-+ * xmlXPathEvalRelativeLocationPath:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [3] RelativeLocationPath ::= Step
-+ * | RelativeLocationPath '/' Step
-+ * | AbbreviatedRelativeLocationPath
-+ * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step
-+ *
-+ */
-+void
-+#ifdef VMS
-+xmlXPathEvalRelLocationPath
-+#else
-+xmlXPathEvalRelativeLocationPath
-+#endif
-+(xmlXPathParserContextPtr ctxt) {
-+ SKIP_BLANKS;
-+ if ((CUR == '/') && (NXT(1) == '/')) {
-+ SKIP(2);
-+ SKIP_BLANKS;
-+ xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
-+ NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-+ } else if (CUR == '/') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ }
-+ xmlXPathEvalStep(ctxt);
-+ SKIP_BLANKS;
-+ while (CUR == '/') {
-+ if ((CUR == '/') && (NXT(1) == '/')) {
-+ SKIP(2);
-+ SKIP_BLANKS;
-+ xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
-+ NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-+ xmlXPathEvalStep(ctxt);
-+ } else if (CUR == '/') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ xmlXPathEvalStep(ctxt);
-+ }
-+ SKIP_BLANKS;
-+ }
-+}
-+
-+/**
-+ * xmlXPathEvalLocationPath:
-+ * @ctxt: the XPath Parser context
-+ *
-+ * [1] LocationPath ::= RelativeLocationPath
-+ * | AbsoluteLocationPath
-+ * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath?
-+ * | AbbreviatedAbsoluteLocationPath
-+ * [10] AbbreviatedAbsoluteLocationPath ::=
-+ * '//' RelativeLocationPath
-+ *
-+ * // is short for /descendant-or-self::node()/. For example,
-+ * //para is short for /descendant-or-self::node()/child::para and
-+ * so will select any para element in the document (even a para element
-+ * that is a document element will be selected by //para since the
-+ * document element node is a child of the root node); div//para is
-+ * short for div/descendant-or-self::node()/child::para and so will
-+ * select all para descendants of div children.
-+ */
-+void
-+xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
-+ SKIP_BLANKS;
-+ if (CUR != '/') {
-+ xmlXPathEvalRelativeLocationPath(ctxt);
-+ } else {
-+ while (CUR == '/') {
-+ if ((CUR == '/') && (NXT(1) == '/')) {
-+ SKIP(2);
-+ SKIP_BLANKS;
-+ xmlXPathNodeCollectAndTest(ctxt,
-+ AXIS_DESCENDANT_OR_SELF, NODE_TEST_TYPE,
-+ NODE_TYPE_NODE, NULL, NULL);
-+ xmlXPathEvalRelativeLocationPath(ctxt);
-+ } else if (CUR == '/') {
-+ NEXT;
-+ SKIP_BLANKS;
-+ if (CUR != 0)
-+ xmlXPathEvalRelativeLocationPath(ctxt);
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * xmlXPathEval:
-+ * @str: the XPath expression
-+ * @ctx: the XPath context
-+ *
-+ * Evaluate the XPath Location Path in the given context.
-+ *
-+ * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
-+ * the caller has to free the object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
-+ xmlXPathParserContextPtr ctxt;
-+ xmlXPathObjectPtr res = NULL, tmp, init = NULL;
-+ int stack = 0;
-+
-+ xmlXPathInit();
-+
-+ CHECK_CONTEXT(ctx)
-+
-+ ctxt = xmlXPathNewParserContext(str, ctx);
-+ /**** TAG:9999
-+ if (ctx->node != NULL) {
-+ init = xmlXPathNewNodeSet(ctx->node);
-+ valuePush(ctxt, init);
-+ }
-+ ****/
-+ xmlXPathEvalExpr(ctxt);
-+
-+ if (ctxt->value == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathEval: evaluation failed\n");
-+ } else {
-+ res = valuePop(ctxt);
-+ }
-+
-+ do {
-+ tmp = valuePop(ctxt);
-+ if (tmp != NULL) {
-+ if (tmp != init)
-+ stack++;
-+ xmlXPathFreeObject(tmp);
-+ }
-+ } while (tmp != NULL);
-+ if (stack != 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathEval: %d object left on the stack\n",
-+ stack);
-+ }
-+ if (ctxt->error != XPATH_EXPRESSION_OK) {
-+ xmlXPathFreeObject(res);
-+ res = NULL;
-+ }
-+
-+ xmlXPathFreeParserContext(ctxt);
-+ return(res);
-+}
-+
-+/**
-+ * xmlXPathEvalExpression:
-+ * @str: the XPath expression
-+ * @ctxt: the XPath context
-+ *
-+ * Evaluate the XPath expression in the given context.
-+ *
-+ * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
-+ * the caller has to free the object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
-+ xmlXPathParserContextPtr pctxt;
-+ xmlXPathObjectPtr res, tmp;
-+ int stack = 0;
-+
-+ xmlXPathInit();
-+
-+ CHECK_CONTEXT(ctxt)
-+
-+ pctxt = xmlXPathNewParserContext(str, ctxt);
-+ xmlXPathEvalExpr(pctxt);
-+
-+ res = valuePop(pctxt);
-+ do {
-+ tmp = valuePop(pctxt);
-+ if (tmp != NULL) {
-+ xmlXPathFreeObject(tmp);
-+ stack++;
-+ }
-+ } while (tmp != NULL);
-+ if (stack != 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPathEvalExpression: %d object left on the stack\n",
-+ stack);
-+ }
-+ xmlXPathFreeParserContext(pctxt);
-+ return(res);
-+}
-+
-+/**
-+ * xmlXPathRegisterAllFunctions:
-+ * @ctxt: the XPath context
-+ *
-+ * Registers all default XPath functions in this context
-+ */
-+void
-+xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
-+{
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
-+ xmlXPathBooleanFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
-+ xmlXPathCeilingFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
-+ xmlXPathCountFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
-+ xmlXPathConcatFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
-+ xmlXPathContainsFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
-+ xmlXPathIdFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
-+ xmlXPathFalseFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
-+ xmlXPathFloorFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
-+ xmlXPathLastFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
-+ xmlXPathLangFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
-+ xmlXPathLocalNameFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
-+ xmlXPathNotFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
-+ xmlXPathNameFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
-+ xmlXPathNamespaceURIFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
-+ xmlXPathNormalizeFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
-+ xmlXPathNumberFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
-+ xmlXPathPositionFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
-+ xmlXPathRoundFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
-+ xmlXPathStringFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
-+ xmlXPathStringLengthFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
-+ xmlXPathStartsWithFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
-+ xmlXPathSubstringFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
-+ xmlXPathSubstringBeforeFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
-+ xmlXPathSubstringAfterFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
-+ xmlXPathSumFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
-+ xmlXPathTrueFunction);
-+ xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
-+ xmlXPathTranslateFunction);
-+}
-+
-+#endif /* LIBXML_XPATH_ENABLED */
-diff -Nru libxml2-2.3.0/libxml/xpath.h libxml2-2.3.0.new/libxml/xpath.h
---- libxml2-2.3.0/libxml/xpath.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xpath.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,278 @@
-+/*
-+ * xpath.c: interface for XML Path Language implementation
-+ *
-+ * Reference: W3C Working Draft 5 July 1999
-+ * http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
-+ *
-+ * See COPYRIGHT for the status of this software
-+ *
-+ * Author: Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_XPATH_H__
-+#define __XML_XPATH_H__
-+
-+#include <libxml/tree.h>
-+#include <libxml/hash.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef struct _xmlXPathContext xmlXPathContext;
-+typedef xmlXPathContext *xmlXPathContextPtr;
-+typedef struct _xmlXPathParserContext xmlXPathParserContext;
-+typedef xmlXPathParserContext *xmlXPathParserContextPtr;
-+
-+/**
-+ * The set of XPath error codes
-+ */
-+
-+typedef enum {
-+ XPATH_EXPRESSION_OK = 0,
-+ XPATH_NUMBER_ERROR,
-+ XPATH_UNFINISHED_LITERAL_ERROR,
-+ XPATH_START_LITERAL_ERROR,
-+ XPATH_VARIABLE_REF_ERROR,
-+ XPATH_UNDEF_VARIABLE_ERROR,
-+ XPATH_INVALID_PREDICATE_ERROR,
-+ XPATH_EXPR_ERROR,
-+ XPATH_UNCLOSED_ERROR,
-+ XPATH_UNKNOWN_FUNC_ERROR,
-+ XPATH_INVALID_OPERAND,
-+ XPATH_INVALID_TYPE,
-+ XPATH_INVALID_ARITY,
-+ XPATH_INVALID_CTXT_SIZE,
-+ XPATH_INVALID_CTXT_POSITION,
-+ XPATH_MEMORY_ERROR,
-+ XPTR_SYNTAX_ERROR,
-+ XPTR_RESOURCE_ERROR,
-+ XPTR_SUB_RESOURCE_ERROR,
-+ XPATH_UNDEF_PREFIX_ERROR
-+} xmlXPathError;
-+
-+/*
-+ * A node-set (an unordered collection of nodes without duplicates)
-+ */
-+typedef struct _xmlNodeSet xmlNodeSet;
-+typedef xmlNodeSet *xmlNodeSetPtr;
-+struct _xmlNodeSet {
-+ int nodeNr; /* number of nodes in the set */
-+ int nodeMax; /* size of the array as allocated */
-+ xmlNodePtr *nodeTab; /* array of nodes in no particular order */
-+};
-+
-+/*
-+ * An expression is evaluated to yield an object, which
-+ * has one of the following four basic types:
-+ * - node-set
-+ * - boolean
-+ * - number
-+ * - string
-+ *
-+ * @@ XPointer will add more types !
-+ */
-+
-+typedef enum {
-+ XPATH_UNDEFINED = 0,
-+ XPATH_NODESET = 1,
-+ XPATH_BOOLEAN = 2,
-+ XPATH_NUMBER = 3,
-+ XPATH_STRING = 4,
-+ XPATH_POINT = 5,
-+ XPATH_RANGE = 6,
-+ XPATH_LOCATIONSET = 7,
-+ XPATH_USERS = 8,
-+ XPATH_XSLT_TREE = 9 /* An XSLT value tree, non modifiable */
-+} xmlXPathObjectType;
-+
-+typedef struct _xmlXPathObject xmlXPathObject;
-+typedef xmlXPathObject *xmlXPathObjectPtr;
-+struct _xmlXPathObject {
-+ xmlXPathObjectType type;
-+ xmlNodeSetPtr nodesetval;
-+ int boolval;
-+ double floatval;
-+ xmlChar *stringval;
-+ void *user;
-+ int index;
-+ void *user2;
-+ int index2;
-+};
-+
-+/*
-+ * A conversion function is associated to a type and used to cast
-+ * the new type to primitive values.
-+ */
-+typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
-+
-+/*
-+ * Extra type: a name and a conversion function.
-+ */
-+
-+typedef struct _xmlXPathType xmlXPathType;
-+typedef xmlXPathType *xmlXPathTypePtr;
-+struct _xmlXPathType {
-+ const xmlChar *name; /* the type name */
-+ xmlXPathConvertFunc func; /* the conversion function */
-+};
-+
-+/*
-+ * Extra variable: a name and a value.
-+ */
-+
-+typedef struct _xmlXPathVariable xmlXPathVariable;
-+typedef xmlXPathVariable *xmlXPathVariablePtr;
-+struct _xmlXPathVariable {
-+ const xmlChar *name; /* the variable name */
-+ xmlXPathObjectPtr value; /* the value */
-+};
-+
-+/*
-+ * an evaluation function, the parameters are on the context stack
-+ */
-+
-+typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, int nargs);
-+
-+/*
-+ * Extra function: a name and a evaluation function.
-+ */
-+
-+typedef struct _xmlXPathFunct xmlXPathFunct;
-+typedef xmlXPathFunct *xmlXPathFuncPtr;
-+struct _xmlXPathFunct {
-+ const xmlChar *name; /* the function name */
-+ xmlXPathEvalFunc func; /* the evaluation function */
-+};
-+
-+/*
-+ * An axis traversal function. To traverse an axis, the engine calls
-+ * the first time with cur == NULL and repeat until the function returns
-+ * NULL indicating the end of the axis traversal.
-+ */
-+
-+typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
-+ xmlXPathObjectPtr cur);
-+
-+/*
-+ * Extra axis: a name and an axis function.
-+ */
-+
-+typedef struct _xmlXPathAxis xmlXPathAxis;
-+typedef xmlXPathAxis *xmlXPathAxisPtr;
-+struct _xmlXPathAxis {
-+ const xmlChar *name; /* the axis name */
-+ xmlXPathAxisFunc func; /* the search function */
-+};
-+
-+/*
-+ * Expression evaluation occurs with respect to a context.
-+ * he context consists of:
-+ * - a node (the context node)
-+ * - a node list (the context node list)
-+ * - a set of variable bindings
-+ * - a function library
-+ * - the set of namespace declarations in scope for the expression
-+ * Following the switch to hash tables, this need to be trimmed up at
-+ * the next binary incompatible release.
-+ */
-+
-+struct _xmlXPathContext {
-+ xmlDocPtr doc; /* The current document */
-+ xmlNodePtr node; /* The current node */
-+
-+ int nb_variables_unused; /* unused (hash table) */
-+ int max_variables_unused; /* unused (hash table) */
-+ xmlHashTablePtr varHash; /* Hash table of defined variables */
-+
-+ int nb_types; /* number of defined types */
-+ int max_types; /* max number of types */
-+ xmlXPathTypePtr types; /* Array of defined types */
-+
-+ int nb_funcs_unused; /* unused (hash table) */
-+ int max_funcs_unused; /* unused (hash table) */
-+ xmlHashTablePtr funcHash; /* Hash table of defined funcs */
-+
-+ int nb_axis; /* number of defined axis */
-+ int max_axis; /* max number of axis */
-+ xmlXPathAxisPtr axis; /* Array of defined axis */
-+
-+ /* the namespace nodes of the context node */
-+ xmlNsPtr *namespaces; /* Array of namespaces */
-+ int nsNr; /* number of namespace in scope */
-+ void *user; /* function to free */
-+
-+ /* extra variables */
-+ int contextSize; /* the context size */
-+ int proximityPosition; /* the proximity position */
-+
-+ /* extra stuff for XPointer */
-+ int xptr; /* it this an XPointer context */
-+ xmlNodePtr here; /* for here() */
-+ xmlNodePtr origin; /* for origin() */
-+
-+ /* the set of namespace declarations in scope for the expression */
-+ xmlHashTablePtr nsHash; /* The namespaces hash table */
-+ void *varLookupFunc; /* variable lookup func */
-+ void *varLookupData; /* variable lookup data */
-+
-+ /* Possibility to link in an extra item */
-+ void *extra; /* needed for XSLT */
-+};
-+
-+/*
-+ * An XPath parser context, it contains pure parsing informations,
-+ * an xmlXPathContext, and the stack of objects.
-+ */
-+struct _xmlXPathParserContext {
-+ const xmlChar *cur; /* the current char being parsed */
-+ const xmlChar *base; /* the full expression */
-+
-+ int error; /* error code */
-+
-+ xmlXPathContextPtr context; /* the evaluation context */
-+ xmlXPathObjectPtr value; /* the current value */
-+ int valueNr; /* number of values stacked */
-+ int valueMax; /* max number of values stacked */
-+ xmlXPathObjectPtr *valueTab; /* stack of values */
-+};
-+
-+/*
-+ * An XPath function
-+ * The arguments (if any) are popped out of the context stack
-+ * and the result is pushed on the stack.
-+ */
-+
-+typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
-+
-+/************************************************************************
-+ * *
-+ * Public API *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * Evaluation functions.
-+ */
-+void xmlXPathInit (void);
-+xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
-+void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
-+xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
-+ xmlXPathContextPtr ctxt);
-+xmlXPathObjectPtr xmlXPathEvalXPtrExpr (const xmlChar *str,
-+ xmlXPathContextPtr ctxt);
-+void xmlXPathFreeObject (xmlXPathObjectPtr obj);
-+xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
-+ xmlXPathContextPtr ctxt);
-+xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
-+void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
-+void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
-+xmlXPathObjectPtr xmlXPathObjectCopy (xmlXPathObjectPtr val);
-+int xmlXPathCmpNodes (xmlNodePtr node1,
-+ xmlNodePtr node2);
-+
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* ! __XML_XPATH_H__ */
-diff -Nru libxml2-2.3.0/libxml/xpathInternals.h libxml2-2.3.0.new/libxml/xpathInternals.h
---- libxml2-2.3.0/libxml/xpathInternals.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xpathInternals.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,229 @@
-+/*
-+ * xpath.c: internal interfaces for XML Path Language implementation
-+ * used to build new modules on top of XPath
-+ *
-+ * See COPYRIGHT for the status of this software
-+ *
-+ * Author: Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_XPATH_INTERNALS_H__
-+#define __XML_XPATH_INTERNALS_H__
-+
-+#include <libxml/xpath.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/************************************************************************
-+ * *
-+ * Helpers *
-+ * *
-+ ************************************************************************/
-+
-+#define CHECK_ERROR \
-+ if (ctxt->error != XPATH_EXPRESSION_OK) return
-+
-+#define CHECK_ERROR0 \
-+ if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
-+
-+#define XP_ERROR(X) \
-+ { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
-+ ctxt->error = (X); return; }
-+
-+#define XP_ERROR0(X) \
-+ { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
-+ ctxt->error = (X); return(0); }
-+
-+#define CHECK_TYPE(typeval) \
-+ if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+#define CHECK_ARITY(x) \
-+ if (nargs != (x)) \
-+ XP_ERROR(XPATH_INVALID_ARITY);
-+
-+#define CAST_TO_STRING \
-+ if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING)) \
-+ xmlXPathStringFunction(ctxt, 1);
-+
-+#define CAST_TO_NUMBER \
-+ if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER)) \
-+ xmlXPathNumberFunction(ctxt, 1);
-+
-+#define CAST_TO_BOOLEAN \
-+ if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN)) \
-+ xmlXPathBooleanFunction(ctxt, 1);
-+
-+/*
-+ * Varibale Lookup forwarding
-+ */
-+typedef xmlXPathObjectPtr
-+ (*xmlXPathVariableLookupFunc) (void *ctxt,
-+ const xmlChar *name,
-+ const xmlChar *ns_uri);
-+
-+void xmlXPathRegisterVariableLookup (xmlXPathContextPtr ctxt,
-+ xmlXPathVariableLookupFunc f,
-+ void *varCtxt);
-+
-+/*
-+ * Error reporting
-+ */
-+void xmlXPatherror (xmlXPathParserContextPtr ctxt,
-+ const char *file,
-+ int line,
-+ int no);
-+
-+void xmlXPathDebugDumpObject (FILE *output,
-+ xmlXPathObjectPtr cur,
-+ int depth);
-+
-+/**
-+ * Extending a context
-+ */
-+
-+int xmlXPathRegisterNs (xmlXPathContextPtr ctxt,
-+ const xmlChar *prefix,
-+ const xmlChar *ns_uri);
-+const xmlChar * xmlXPathNsLookup (xmlXPathContextPtr ctxt,
-+ const xmlChar *ns_uri);
-+void xmlXPathRegisteredNsCleanup (xmlXPathContextPtr ctxt);
-+
-+int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
-+ const xmlChar *name,
-+ xmlXPathFunction f);
-+int xmlXPathRegisterFuncNS (xmlXPathContextPtr ctxt,
-+ const xmlChar *name,
-+ const xmlChar *ns_uri,
-+ xmlXPathFunction f);
-+int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
-+ const xmlChar *name,
-+ xmlXPathObjectPtr value);
-+int xmlXPathRegisterVariableNS (xmlXPathContextPtr ctxt,
-+ const xmlChar *name,
-+ const xmlChar *ns_uri,
-+ xmlXPathObjectPtr value);
-+xmlXPathFunction xmlXPathFunctionLookup (xmlXPathContextPtr ctxt,
-+ const xmlChar *name);
-+xmlXPathFunction xmlXPathFunctionLookupNS (xmlXPathContextPtr ctxt,
-+ const xmlChar *name,
-+ const xmlChar *ns_uri);
-+void xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt);
-+xmlXPathObjectPtr xmlXPathVariableLookup (xmlXPathContextPtr ctxt,
-+ const xmlChar *name);
-+xmlXPathObjectPtr xmlXPathVariableLookupNS (xmlXPathContextPtr ctxt,
-+ const xmlChar *name,
-+ const xmlChar *ns_uri);
-+void xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt);
-+
-+/**
-+ * Utilities to extend XPath
-+ */
-+xmlXPathParserContextPtr
-+ xmlXPathNewParserContext (const xmlChar *str,
-+ xmlXPathContextPtr ctxt);
-+void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
-+
-+/* TODO: remap to xmlXPathValuePop and Push */
-+xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
-+int valuePush (xmlXPathParserContextPtr ctxt,
-+ xmlXPathObjectPtr value);
-+
-+xmlXPathObjectPtr xmlXPathNewString (const xmlChar *val);
-+xmlXPathObjectPtr xmlXPathNewCString (const char *val);
-+xmlXPathObjectPtr xmlXPathNewFloat (double val);
-+xmlXPathObjectPtr xmlXPathNewBoolean (int val);
-+xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
-+xmlXPathObjectPtr xmlXPathNewValueTree (xmlNodePtr val);
-+void xmlXPathNodeSetAdd (xmlNodeSetPtr cur,
-+ xmlNodePtr val);
-+
-+
-+void xmlXPathIdFunction (xmlXPathParserContextPtr ctxt,
-+ int nargs);
-+void xmlXPathRoot (xmlXPathParserContextPtr ctxt);
-+void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt);
-+xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt);
-+xmlChar * xmlXPathParseNCName (xmlXPathParserContextPtr ctxt);
-+
-+/*
-+ * Debug
-+ */
-+#ifdef LIBXML_DEBUG_ENABLED
-+double xmlXPathStringEvalNumber(const xmlChar *str);
-+void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
-+#endif
-+/*
-+ * Existing functions
-+ */
-+
-+int xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
-+ xmlXPathObjectPtr res);
-+void xmlXPathInit(void);
-+void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt);
-+xmlNodeSetPtr xmlXPathNodeSetCreate(xmlNodePtr val);
-+void xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val);
-+xmlNodeSetPtr xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2);
-+void xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val);
-+void xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val);
-+void xmlXPathFreeNodeSet(xmlNodeSetPtr obj);
-+xmlXPathObjectPtr xmlXPathNewNodeSet(xmlNodePtr val);
-+xmlXPathObjectPtr xmlXPathNewNodeSetList(xmlNodeSetPtr val);
-+xmlXPathObjectPtr xmlXPathWrapNodeSet(xmlNodeSetPtr val);
-+void xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj);
-+
-+
-+xmlXPathObjectPtr xmlXPathNewFloat(double val);
-+xmlXPathObjectPtr xmlXPathNewBoolean(int val);
-+xmlXPathObjectPtr xmlXPathNewString(const xmlChar *val);
-+xmlXPathObjectPtr xmlXPathNewCString(const char *val);
-+void xmlXPathFreeObject(xmlXPathObjectPtr obj);
-+xmlXPathContextPtr xmlXPathNewContext(xmlDocPtr doc);
-+void xmlXPathFreeContext(xmlXPathContextPtr ctxt);
-+
-+int xmlXPathEqualValues(xmlXPathParserContextPtr ctxt);
-+int xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict);
-+void xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt);
-+void xmlXPathAddValues(xmlXPathParserContextPtr ctxt);
-+void xmlXPathSubValues(xmlXPathParserContextPtr ctxt);
-+void xmlXPathMultValues(xmlXPathParserContextPtr ctxt);
-+void xmlXPathDivValues(xmlXPathParserContextPtr ctxt);
-+void xmlXPathModValues(xmlXPathParserContextPtr ctxt);
-+
-+/*
-+ * The official core of XPath functions
-+ */
-+void xmlXPathRoot(xmlXPathParserContextPtr ctxt);
-+void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* ! __XML_XPATH_INTERNALS_H__ */
-diff -Nru libxml2-2.3.0/libxml/xpointer.c libxml2-2.3.0.new/libxml/xpointer.c
---- libxml2-2.3.0/libxml/xpointer.c Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xpointer.c Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,2903 @@
-+/*
-+ * xpointer.c : Code to handle XML Pointer
-+ *
-+ * World Wide Web Consortium Working Draft 03-March-1998
-+ * http://www.w3.org/TR/2000/CR-xptr-20000607
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifdef WIN32
-+#include "win32config.h"
-+#else
-+#include "config.h"
-+#endif
-+
-+/**
-+ * TODO: better handling of error cases, the full expression should
-+ * be parsed beforehand instead of a progressive evaluation
-+ * TODO: Access into entities references are not supported now ...
-+ * need a start to be able to pop out of entities refs since
-+ * parent is the endity declaration, not the ref.
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <libxml/xpointer.h>
-+#include <libxml/xmlmemory.h>
-+#include <libxml/parserInternals.h>
-+#include <libxml/uri.h>
-+#include <libxml/xpath.h>
-+#include <libxml/xpathInternals.h>
-+#ifdef LIBXML_DEBUG_ENABLED
-+#include <libxml/debugXML.h>
-+#endif
-+#include <libxml/xmlerror.h>
-+
-+#ifdef LIBXML_XPTR_ENABLED
-+
-+/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
-+#define XPTR_XMLNS_SCHEME
-+
-+/* #define DEBUG_RANGES */
-+
-+#define TODO \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "Unimplemented block at %s:%d\n", \
-+ __FILE__, __LINE__);
-+
-+#define STRANGE \
-+ xmlGenericError(xmlGenericErrorContext, \
-+ "Internal error at %s:%d\n", \
-+ __FILE__, __LINE__);
-+
-+/************************************************************************
-+ * *
-+ * A few helper functions for child sequences *
-+ * *
-+ ************************************************************************/
-+
-+xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
-+/**
-+ * xmlXPtrGetArity:
-+ * @cur: the node
-+ *
-+ * Returns the number of child for an element, -1 in case of error
-+ */
-+int
-+xmlXPtrGetArity(xmlNodePtr cur) {
-+ int i;
-+ if (cur == NULL)
-+ return(-1);
-+ cur = cur->children;
-+ for (i = 0;cur != NULL;cur = cur->next) {
-+ if ((cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ i++;
-+ }
-+ }
-+ return(i);
-+}
-+
-+/**
-+ * xmlXPtrGetIndex:
-+ * @cur: the node
-+ *
-+ * Returns the index of the node in its parent children list, -1
-+ * in case of error
-+ */
-+int
-+xmlXPtrGetIndex(xmlNodePtr cur) {
-+ int i;
-+ if (cur == NULL)
-+ return(-1);
-+ for (i = 1;cur != NULL;cur = cur->prev) {
-+ if ((cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ i++;
-+ }
-+ }
-+ return(i);
-+}
-+
-+/**
-+ * xmlXPtrGetNthChild:
-+ * @cur: the node
-+ * @no: the child number
-+ *
-+ * Returns the @no'th element child of @cur or NULL
-+ */
-+xmlNodePtr
-+xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
-+ int i;
-+ if (cur == NULL)
-+ return(cur);
-+ cur = cur->children;
-+ for (i = 0;i <= no;cur = cur->next) {
-+ if (cur == NULL)
-+ return(cur);
-+ if ((cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ i++;
-+ if (i == no)
-+ break;
-+ }
-+ }
-+ return(cur);
-+}
-+
-+/************************************************************************
-+ * *
-+ * Handling of XPointer specific types *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPtrCmpPoints:
-+ * @node1: the first node
-+ * @index1: the first index
-+ * @node2: the second node
-+ * @index2: the second index
-+ *
-+ * Compare two points w.r.t document order
-+ *
-+ * Returns -2 in case of error 1 if first point < second point, 0 if
-+ * that's the same point, -1 otherwise
-+ */
-+int
-+xmlXPtrCmpPoints(xmlNodePtr node1, int index1, xmlNodePtr node2, int index2) {
-+ if ((node1 == NULL) || (node2 == NULL))
-+ return(-2);
-+ /*
-+ * a couple of optimizations which will avoid computations in most cases
-+ */
-+ if (node1 == node2) {
-+ if (index1 < index2)
-+ return(1);
-+ if (index1 > index2)
-+ return(-1);
-+ return(0);
-+ }
-+ return(xmlXPathCmpNodes(node1, node2));
-+}
-+
-+/**
-+ * xmlXPtrNewPoint:
-+ * @node: the xmlNodePtr
-+ * @index: the index within the node
-+ *
-+ * Create a new xmlXPathObjectPtr of type point
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewPoint(xmlNodePtr node, int index) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (node == NULL)
-+ return(NULL);
-+ if (index < 0)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewPoint: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_POINT;
-+ ret->user = (void *) node;
-+ ret->index = index;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrRangeCheckOrder:
-+ * @range: an object range
-+ *
-+ * Make sure the points in the range are in the right order
-+ */
-+void
-+xmlXPtrRangeCheckOrder(xmlXPathObjectPtr range) {
-+ int tmp;
-+ xmlNodePtr tmp2;
-+ if (range == NULL)
-+ return;
-+ if (range->type != XPATH_RANGE)
-+ return;
-+ if (range->user2 == NULL)
-+ return;
-+ tmp = xmlXPtrCmpPoints(range->user, range->index,
-+ range->user2, range->index2);
-+ if (tmp == -1) {
-+ tmp2 = range->user;
-+ range->user = range->user2;
-+ range->user2 = tmp2;
-+ tmp = range->index;
-+ range->index = range->index2;
-+ range->index2 = tmp;
-+ }
-+}
-+
-+/**
-+ * xmlXPtrRangesEqual:
-+ * @range1: the first range
-+ * @range2: the second range
-+ *
-+ * Compare two ranges
-+ *
-+ * Return 1 if equal, 0 otherwise
-+ */
-+int
-+xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
-+ if (range1 == range2)
-+ return(1);
-+ if ((range1 == NULL) || (range2 == NULL))
-+ return(0);
-+ if (range1->type != range2->type)
-+ return(0);
-+ if (range1->type != XPATH_RANGE)
-+ return(0);
-+ if (range1->user != range2->user)
-+ return(0);
-+ if (range1->index != range2->index)
-+ return(0);
-+ if (range1->user2 != range2->user2)
-+ return(0);
-+ if (range1->index2 != range2->index2)
-+ return(0);
-+ return(1);
-+}
-+
-+/**
-+ * xmlXPtrNewRange:
-+ * @start: the starting node
-+ * @startindex: the start index
-+ * @end: the ending point
-+ * @endindex: the ending index
-+ *
-+ * Create a new xmlXPathObjectPtr of type range
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewRange(xmlNodePtr start, int startindex,
-+ xmlNodePtr end, int endindex) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ if (end == NULL)
-+ return(NULL);
-+ if (startindex < 0)
-+ return(NULL);
-+ if (endindex < 0)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangePoints: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start;
-+ ret->index = startindex;
-+ ret->user2 = end;
-+ ret->index2 = endindex;
-+ xmlXPtrRangeCheckOrder(ret);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewRangePoints:
-+ * @start: the starting point
-+ * @end: the ending point
-+ *
-+ * Create a new xmlXPathObjectPtr of type range using 2 Points
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ if (end == NULL)
-+ return(NULL);
-+ if (start->type != XPATH_POINT)
-+ return(NULL);
-+ if (end->type != XPATH_POINT)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangePoints: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start->user;
-+ ret->index = start->index;
-+ ret->user2 = end->user;
-+ ret->index2 = end->index;
-+ xmlXPtrRangeCheckOrder(ret);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewRangePointNode:
-+ * @start: the starting point
-+ * @end: the ending node
-+ *
-+ * Create a new xmlXPathObjectPtr of type range from a point to a node
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ if (end == NULL)
-+ return(NULL);
-+ if (start->type != XPATH_POINT)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangePointNode: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start->user;
-+ ret->index = start->index;
-+ ret->user2 = end;
-+ ret->index2 = -1;
-+ xmlXPtrRangeCheckOrder(ret);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewRangeNodePoint:
-+ * @start: the starting node
-+ * @end: the ending point
-+ *
-+ * Create a new xmlXPathObjectPtr of type range from a node to a point
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ if (end == NULL)
-+ return(NULL);
-+ if (start->type != XPATH_POINT)
-+ return(NULL);
-+ if (end->type != XPATH_POINT)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangeNodePoint: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start;
-+ ret->index = -1;
-+ ret->user2 = end->user;
-+ ret->index2 = end->index;
-+ xmlXPtrRangeCheckOrder(ret);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewRangeNodes:
-+ * @start: the starting node
-+ * @end: the ending node
-+ *
-+ * Create a new xmlXPathObjectPtr of type range using 2 nodes
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ if (end == NULL)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangeNodes: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start;
-+ ret->index = -1;
-+ ret->user2 = end;
-+ ret->index2 = -1;
-+ xmlXPtrRangeCheckOrder(ret);
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewCollapsedRange:
-+ * @start: the starting and ending node
-+ *
-+ * Create a new xmlXPathObjectPtr of type range using a single nodes
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewCollapsedRange(xmlNodePtr start) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangeNodes: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start;
-+ ret->index = -1;
-+ ret->user2 = NULL;
-+ ret->index2 = -1;
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewRangeNodeObject:
-+ * @start: the starting node
-+ * @end: the ending object
-+ *
-+ * Create a new xmlXPathObjectPtr of type range from a not to an object
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
-+ xmlXPathObjectPtr ret;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ if (end == NULL)
-+ return(NULL);
-+ switch (end->type) {
-+ case XPATH_POINT:
-+ break;
-+ case XPATH_NODESET:
-+ /*
-+ * Empty set ...
-+ */
-+ if (end->nodesetval->nodeNr <= 0)
-+ return(NULL);
-+ break;
-+ default:
-+ TODO
-+ return(NULL);
-+ }
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewRangeNodeObject: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_RANGE;
-+ ret->user = start;
-+ ret->index = -1;
-+ switch (end->type) {
-+ case XPATH_POINT:
-+ ret->user2 = end->user;
-+ ret->index2 = end->index;
-+ case XPATH_NODESET: {
-+ ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
-+ ret->index2 = -1;
-+ break;
-+ }
-+ default:
-+ STRANGE
-+ return(NULL);
-+ }
-+ xmlXPtrRangeCheckOrder(ret);
-+ return(ret);
-+}
-+
-+#define XML_RANGESET_DEFAULT 10
-+
-+/**
-+ * xmlXPtrLocationSetCreate:
-+ * @val: an initial xmlXPathObjectPtr, or NULL
-+ *
-+ * Create a new xmlLocationSetPtr of type double and of value @val
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlLocationSetPtr
-+xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) {
-+ xmlLocationSetPtr ret;
-+
-+ ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrLocationSetCreate: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlLocationSet));
-+ if (val != NULL) {
-+ ret->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
-+ sizeof(xmlXPathObjectPtr));
-+ if (ret->locTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrLocationSetCreate: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret->locTab, 0 ,
-+ XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
-+ ret->locMax = XML_RANGESET_DEFAULT;
-+ ret->locTab[ret->locNr++] = val;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrLocationSetAdd:
-+ * @cur: the initial range set
-+ * @val: a new xmlXPathObjectPtr
-+ *
-+ * add a new xmlXPathObjectPtr ot an existing LocationSet
-+ * If the location already exist in the set @val is freed.
-+ */
-+void
-+xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
-+ int i;
-+
-+ if (val == NULL) return;
-+
-+ /*
-+ * check against doublons
-+ */
-+ for (i = 0;i < cur->locNr;i++) {
-+ if (xmlXPtrRangesEqual(cur->locTab[i], val)) {
-+ xmlXPathFreeObject(val);
-+ return;
-+ }
-+ }
-+
-+ /*
-+ * grow the locTab if needed
-+ */
-+ if (cur->locMax == 0) {
-+ cur->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
-+ sizeof(xmlXPathObjectPtr));
-+ if (cur->locTab == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrLocationSetAdd: out of memory\n");
-+ return;
-+ }
-+ memset(cur->locTab, 0 ,
-+ XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
-+ cur->locMax = XML_RANGESET_DEFAULT;
-+ } else if (cur->locNr == cur->locMax) {
-+ xmlXPathObjectPtr *temp;
-+
-+ cur->locMax *= 2;
-+ temp = (xmlXPathObjectPtr *) xmlRealloc(cur->locTab, cur->locMax *
-+ sizeof(xmlXPathObjectPtr));
-+ if (temp == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrLocationSetAdd: out of memory\n");
-+ return;
-+ }
-+ cur->locTab = temp;
-+ }
-+ cur->locTab[cur->locNr++] = val;
-+}
-+
-+/**
-+ * xmlXPtrLocationSetMerge:
-+ * @val1: the first LocationSet
-+ * @val2: the second LocationSet
-+ *
-+ * Merges two rangesets, all ranges from @val2 are added to @val1
-+ *
-+ * Returns val1 once extended or NULL in case of error.
-+ */
-+xmlLocationSetPtr
-+xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) {
-+ int i;
-+
-+ if (val1 == NULL) return(NULL);
-+ if (val2 == NULL) return(val1);
-+
-+ /*
-+ * !!!!! this can be optimized a lot, knowing that both
-+ * val1 and val2 already have unicity of their values.
-+ */
-+
-+ for (i = 0;i < val2->locNr;i++)
-+ xmlXPtrLocationSetAdd(val1, val2->locTab[i]);
-+
-+ return(val1);
-+}
-+
-+/**
-+ * xmlXPtrLocationSetDel:
-+ * @cur: the initial range set
-+ * @val: an xmlXPathObjectPtr
-+ *
-+ * Removes an xmlXPathObjectPtr from an existing LocationSet
-+ */
-+void
-+xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
-+ int i;
-+
-+ if (cur == NULL) return;
-+ if (val == NULL) return;
-+
-+ /*
-+ * check against doublons
-+ */
-+ for (i = 0;i < cur->locNr;i++)
-+ if (cur->locTab[i] == val) break;
-+
-+ if (i >= cur->locNr) {
-+#ifdef DEBUG
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrLocationSetDel: Range %s wasn't found in RangeList\n",
-+ val->name);
-+#endif
-+ return;
-+ }
-+ cur->locNr--;
-+ for (;i < cur->locNr;i++)
-+ cur->locTab[i] = cur->locTab[i + 1];
-+ cur->locTab[cur->locNr] = NULL;
-+}
-+
-+/**
-+ * xmlXPtrLocationSetRemove:
-+ * @cur: the initial range set
-+ * @val: the index to remove
-+ *
-+ * Removes an entry from an existing LocationSet list.
-+ */
-+void
-+xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) {
-+ if (cur == NULL) return;
-+ if (val >= cur->locNr) return;
-+ cur->locNr--;
-+ for (;val < cur->locNr;val++)
-+ cur->locTab[val] = cur->locTab[val + 1];
-+ cur->locTab[cur->locNr] = NULL;
-+}
-+
-+/**
-+ * xmlXPtrFreeLocationSet:
-+ * @obj: the xmlLocationSetPtr to free
-+ *
-+ * Free the LocationSet compound (not the actual ranges !).
-+ */
-+void
-+xmlXPtrFreeLocationSet(xmlLocationSetPtr obj) {
-+ int i;
-+
-+ if (obj == NULL) return;
-+ if (obj->locTab != NULL) {
-+ for (i = 0;i < obj->locNr; i++) {
-+ xmlXPathFreeObject(obj->locTab[i]);
-+ }
-+#ifdef DEBUG
-+ memset(obj->locTab, 0xB ,
-+ (size_t) sizeof(xmlXPathObjectPtr) * obj->locMax);
-+#endif
-+ xmlFree(obj->locTab);
-+ }
-+#ifdef DEBUG
-+ memset(obj, 0xB , (size_t) sizeof(xmlLocationSet));
-+#endif
-+ xmlFree(obj);
-+}
-+
-+/**
-+ * xmlXPtrNewLocationSetNodes:
-+ * @start: the start NodePtr value
-+ * @end: the end NodePtr value or NULL
-+ *
-+ * Create a new xmlXPathObjectPtr of type LocationSet and initialize
-+ * it with the single range made of the two nodes @start and @end
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewLocationSetNodes: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_LOCATIONSET;
-+ if (end == NULL)
-+ ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewCollapsedRange(start));
-+ else
-+ ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewRangeNodes(start,end));
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrNewLocationSetNodeSet:
-+ * @set: a node set
-+ *
-+ * Create a new xmlXPathObjectPtr of type LocationSet and initialize
-+ * it with all the nodes from @set
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrNewLocationSetNodes: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_LOCATIONSET;
-+ if (set != NULL) {
-+ int i;
-+ xmlLocationSetPtr newset;
-+
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+ if (newset == NULL)
-+ return(ret);
-+
-+ for (i = 0;i < set->nodeNr;i++)
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrNewCollapsedRange(set->nodeTab[i]));
-+
-+ ret->user = (void *) newset;
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrWrapLocationSet:
-+ * @val: the LocationSet value
-+ *
-+ * Wrap the LocationSet @val in a new xmlXPathObjectPtr
-+ *
-+ * Returns the newly created object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrWrapLocationSet(xmlLocationSetPtr val) {
-+ xmlXPathObjectPtr ret;
-+
-+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-+ if (ret == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrWrapLocationSet: out of memory\n");
-+ return(NULL);
-+ }
-+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-+ ret->type = XPATH_LOCATIONSET;
-+ ret->user = (void *) val;
-+ return(ret);
-+}
-+
-+/************************************************************************
-+ * *
-+ * The parser *
-+ * *
-+ ************************************************************************/
-+
-+/*
-+ * Macros for accessing the content. Those should be used only by the parser,
-+ * and not exported.
-+ *
-+ * Dirty macros, i.e. one need to make assumption on the context to use them
-+ *
-+ * CUR_PTR return the current pointer to the xmlChar to be parsed.
-+ * CUR returns the current xmlChar value, i.e. a 8 bit value
-+ * in ISO-Latin or UTF-8.
-+ * This should be used internally by the parser
-+ * only to compare to ASCII values otherwise it would break when
-+ * running with UTF-8 encoding.
-+ * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-+ * to compare on ASCII based substring.
-+ * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-+ * strings within the parser.
-+ * CURRENT Returns the current char value, with the full decoding of
-+ * UTF-8 if we are using this mode. It returns an int.
-+ * NEXT Skip to the next character, this does the proper decoding
-+ * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-+ * It returns the pointer to the current xmlChar.
-+ */
-+
-+#define CUR (*ctxt->cur)
-+#define SKIP(val) ctxt->cur += (val)
-+#define NXT(val) ctxt->cur[(val)]
-+#define CUR_PTR ctxt->cur
-+
-+#define SKIP_BLANKS \
-+ while (IS_BLANK(*(ctxt->cur))) NEXT
-+
-+#define CURRENT (*ctxt->cur)
-+#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
-+
-+/*
-+ * xmlXPtrGetChildNo:
-+ * @ctxt: the XPointer Parser context
-+ * @index: the child number
-+ *
-+ * Move the current node of the nodeset on the stack to the
-+ * given child if found
-+ */
-+void
-+xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int index) {
-+ xmlNodePtr cur = NULL;
-+ xmlXPathObjectPtr obj;
-+ xmlNodeSetPtr oldset;
-+
-+ CHECK_TYPE(XPATH_NODESET);
-+ obj = valuePop(ctxt);
-+ oldset = obj->nodesetval;
-+ if ((index <= 0) || (oldset == NULL) || (oldset->nodeNr != 1)) {
-+ xmlXPathFreeObject(obj);
-+ valuePush(ctxt, xmlXPathNewNodeSet(NULL));
-+ return;
-+ }
-+ cur = xmlXPtrGetNthChild(oldset->nodeTab[0], index);
-+ if (cur == NULL) {
-+ xmlXPathFreeObject(obj);
-+ valuePush(ctxt, xmlXPathNewNodeSet(NULL));
-+ return;
-+ }
-+ oldset->nodeTab[0] = cur;
-+ valuePush(ctxt, obj);
-+}
-+
-+/**
-+ * xmlXPtrEvalXPtrPart:
-+ * @ctxt: the XPointer Parser context
-+ * @name: the preparsed Scheme for the XPtrPart
-+ *
-+ * XPtrPart ::= 'xpointer' '(' XPtrExpr ')'
-+ * | Scheme '(' SchemeSpecificExpr ')'
-+ *
-+ * Scheme ::= NCName - 'xpointer' [VC: Non-XPointer schemes]
-+ *
-+ * SchemeSpecificExpr ::= StringWithBalancedParens
-+ *
-+ * StringWithBalancedParens ::=
-+ * [^()]* ('(' StringWithBalancedParens ')' [^()]*)*
-+ * [VC: Parenthesis escaping]
-+ *
-+ * XPtrExpr ::= Expr [VC: Parenthesis escaping]
-+ *
-+ * VC: Parenthesis escaping:
-+ * The end of an XPointer part is signaled by the right parenthesis ")"
-+ * character that is balanced with the left parenthesis "(" character
-+ * that began the part. Any unbalanced parenthesis character inside the
-+ * expression, even within literals, must be escaped with a circumflex (^)
-+ * character preceding it. If the expression contains any literal
-+ * occurrences of the circumflex, each must be escaped with an additional
-+ * circumflex (that is, ^^). If the unescaped parentheses in the expression
-+ * are not balanced, a syntax error results.
-+ *
-+ * Parse and evaluate an XPtrPart. Basically it generates the unescaped
-+ * string and if the scheme is 'xpointer' it will call the XPath interprter.
-+ *
-+ * TODO: there is no new scheme registration mechanism
-+ */
-+
-+void
-+xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
-+ xmlChar *buffer, *cur;
-+ int len;
-+ int level;
-+
-+ if (name == NULL)
-+ name = xmlXPathParseName(ctxt);
-+ if (name == NULL)
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+
-+ if (CUR != '(')
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ NEXT;
-+ level = 1;
-+
-+ len = xmlStrlen(ctxt->cur);
-+ len++;
-+ buffer = (xmlChar *) xmlMalloc(len * sizeof (xmlChar));
-+ if (buffer == NULL) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrEvalXPtrPart: out of memory\n");
-+ return;
-+ }
-+
-+ cur = buffer;
-+ while (CUR != 0) {
-+ if (CUR == ')') {
-+ level--;
-+ if (level == 0) {
-+ NEXT;
-+ break;
-+ }
-+ *cur++ = CUR;
-+ } else if (CUR == '(') {
-+ level++;
-+ *cur++ = CUR;
-+ } else if (CUR == '^') {
-+ NEXT;
-+ if ((CUR == ')') || (CUR == '(') || (CUR == '^')) {
-+ *cur++ = CUR;
-+ } else {
-+ *cur++ = '^';
-+ *cur++ = CUR;
-+ }
-+ } else {
-+ *cur++ = CUR;
-+ }
-+ NEXT;
-+ }
-+ *cur = 0;
-+
-+ if ((level != 0) && (CUR == 0)) {
-+ xmlFree(buffer);
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+ }
-+
-+ if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
-+ const xmlChar *left = CUR_PTR;
-+
-+ CUR_PTR = buffer;
-+ xmlXPathRoot(ctxt);
-+ xmlXPathEvalExpr(ctxt);
-+ CUR_PTR=left;
-+#ifdef XPTR_XMLNS_SCHEME
-+ } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
-+ const xmlChar *left = CUR_PTR;
-+ xmlChar *prefix;
-+ xmlChar *URI;
-+ xmlURIPtr value;
-+
-+ CUR_PTR = buffer;
-+ prefix = xmlXPathParseNCName(ctxt);
-+ if (prefix == NULL) {
-+ xmlFree(buffer);
-+ xmlFree(name);
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+ }
-+ SKIP_BLANKS;
-+ if (CUR != '=') {
-+ xmlFree(prefix);
-+ xmlFree(buffer);
-+ xmlFree(name);
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+ /* @@ check escaping in the XPointer WD */
-+
-+ value = xmlParseURI((const char *)ctxt->cur);
-+ if (value == NULL) {
-+ xmlFree(prefix);
-+ xmlFree(buffer);
-+ xmlFree(name);
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+ }
-+ URI = xmlSaveUri(value);
-+ xmlFreeURI(value);
-+ if (URI == NULL) {
-+ xmlFree(prefix);
-+ xmlFree(buffer);
-+ xmlFree(name);
-+ XP_ERROR(XPATH_MEMORY_ERROR);
-+ }
-+
-+ xmlXPathRegisterNs(ctxt->context, prefix, URI);
-+ CUR_PTR = left;
-+#endif /* XPTR_XMLNS_SCHEME */
-+ } else {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "unsupported scheme '%s'\n", name);
-+ }
-+ xmlFree(buffer);
-+ xmlFree(name);
-+}
-+
-+/**
-+ * xmlXPtrEvalFullXPtr:
-+ * @ctxt: the XPointer Parser context
-+ * @name: the preparsed Scheme for the first XPtrPart
-+ *
-+ * FullXPtr ::= XPtrPart (S? XPtrPart)*
-+ *
-+ * As the specs says:
-+ * -----------
-+ * When multiple XPtrParts are provided, they must be evaluated in
-+ * left-to-right order. If evaluation of one part fails, the nexti
-+ * is evaluated. The following conditions cause XPointer part failure:
-+ *
-+ * - An unknown scheme
-+ * - A scheme that does not locate any sub-resource present in the resource
-+ * - A scheme that is not applicable to the media type of the resource
-+ *
-+ * The XPointer application must consume a failed XPointer part and
-+ * attempt to evaluate the next one, if any. The result of the first
-+ * XPointer part whose evaluation succeeds is taken to be the fragment
-+ * located by the XPointer as a whole. If all the parts fail, the result
-+ * for the XPointer as a whole is a sub-resource error.
-+ * -----------
-+ *
-+ * Parse and evaluate a Full XPtr i.e. possibly a cascade of XPath based
-+ * expressions or other shemes.
-+ */
-+void
-+xmlXPtrEvalFullXPtr(xmlXPathParserContextPtr ctxt, xmlChar *name) {
-+ if (name == NULL)
-+ name = xmlXPathParseName(ctxt);
-+ if (name == NULL)
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ while (name != NULL) {
-+ xmlXPtrEvalXPtrPart(ctxt, name);
-+
-+ /* in case of syntax error, break here */
-+ if (ctxt->error != XPATH_EXPRESSION_OK)
-+ return;
-+
-+ /*
-+ * If the returned value is a non-empty nodeset
-+ * or location set, return here.
-+ */
-+ if (ctxt->value != NULL) {
-+ xmlXPathObjectPtr obj = ctxt->value;
-+
-+ switch (obj->type) {
-+ case XPATH_LOCATIONSET: {
-+ xmlLocationSetPtr loc = ctxt->value->user;
-+ if ((loc != NULL) && (loc->locNr > 0))
-+ return;
-+ break;
-+ }
-+ case XPATH_NODESET: {
-+ xmlNodeSetPtr loc = ctxt->value->nodesetval;
-+ if ((loc != NULL) && (loc->nodeNr > 0))
-+ return;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ /*
-+ * Evaluating to improper values is equivalent to
-+ * a sub-resource error, clean-up the stack
-+ */
-+ do {
-+ obj = valuePop(ctxt);
-+ if (obj != NULL) {
-+ xmlXPathFreeObject(obj);
-+ }
-+ } while (obj != NULL);
-+ }
-+
-+ /*
-+ * Is there another XPoointer part.
-+ */
-+ SKIP_BLANKS;
-+ name = xmlXPathParseName(ctxt);
-+ }
-+}
-+
-+/**
-+ * xmlXPtrEvalChildSeq:
-+ * @ctxt: the XPointer Parser context
-+ * @name: a possible ID name of the child sequence
-+ *
-+ * ChildSeq ::= '/1' ('/' [0-9]*)*
-+ * | Name ('/' [0-9]*)+
-+ *
-+ * Parse and evaluate a Child Sequence. This routine also handle the
-+ * case of a Bare Name used to get a document ID.
-+ */
-+void
-+xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
-+ /*
-+ * XPointer don't allow by syntax to adress in mutirooted trees
-+ * this might prove useful in some cases, warn about it.
-+ */
-+ if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "warning: ChildSeq not starting by /1\n");
-+ }
-+
-+ if (name != NULL) {
-+ valuePush(ctxt, xmlXPathNewString(name));
-+ xmlFree(name);
-+ xmlXPathIdFunction(ctxt, 1);
-+ CHECK_ERROR;
-+ }
-+
-+ while (CUR == '/') {
-+ int child = 0;
-+ NEXT;
-+
-+ while ((CUR >= '0') && (CUR <= '9')) {
-+ child = child * 10 + (CUR - '0');
-+ NEXT;
-+ }
-+ xmlXPtrGetChildNo(ctxt, child);
-+ }
-+}
-+
-+
-+/**
-+ * xmlXPtrEvalXPointer:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * XPointer ::= Name
-+ * | ChildSeq
-+ * | FullXPtr
-+ *
-+ * Parse and evaluate an XPointer
-+ */
-+void
-+xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
-+ SKIP_BLANKS;
-+ if (CUR == '/') {
-+ xmlXPathRoot(ctxt);
-+ xmlXPtrEvalChildSeq(ctxt, NULL);
-+ } else {
-+ xmlChar *name;
-+
-+ name = xmlXPathParseName(ctxt);
-+ if (name == NULL)
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+ if (CUR == '(') {
-+ xmlXPtrEvalFullXPtr(ctxt, name);
-+ /* Short evaluation */
-+ return;
-+ } else {
-+ /* this handle both Bare Names and Child Sequences */
-+ xmlXPtrEvalChildSeq(ctxt, name);
-+ }
-+ }
-+ SKIP_BLANKS;
-+ if (CUR != 0)
-+ XP_ERROR(XPATH_EXPR_ERROR);
-+}
-+
-+
-+/************************************************************************
-+ * *
-+ * General routines *
-+ * *
-+ ************************************************************************/
-+
-+void xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-+
-+/**
-+ * xmlXPtrNewContext:
-+ * @doc: the XML document
-+ * @here: the node that directly contains the XPointer being evaluated or NULL
-+ * @origin: the element from which a user or program initiated traversal of
-+ * the link, or NULL.
-+ *
-+ * Create a new XPointer context
-+ *
-+ * Returns the xmlXPathContext just allocated.
-+ */
-+xmlXPathContextPtr
-+xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
-+ xmlXPathContextPtr ret;
-+
-+ ret = xmlXPathNewContext(doc);
-+ if (ret == NULL)
-+ return(ret);
-+ ret->xptr = 1;
-+ ret->here = here;
-+ ret->origin = origin;
-+
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
-+ xmlXPtrRangeToFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"range",
-+ xmlXPtrRangeFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
-+ xmlXPtrRangeInsideFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"string-range",
-+ xmlXPtrStringRangeFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"start-point",
-+ xmlXPtrStartPointFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"end-point",
-+ xmlXPtrEndPointFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)"here",
-+ xmlXPtrHereFunction);
-+ xmlXPathRegisterFunc(ret, (xmlChar *)" origin",
-+ xmlXPtrOriginFunction);
-+
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrEval:
-+ * @str: the XPointer expression
-+ * @ctx: the XPointer context
-+ *
-+ * Evaluate the XPath Location Path in the given context.
-+ *
-+ * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
-+ * the caller has to free the object.
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
-+ xmlXPathParserContextPtr ctxt;
-+ xmlXPathObjectPtr res = NULL, tmp;
-+ xmlXPathObjectPtr init = NULL;
-+ int stack = 0;
-+
-+ xmlXPathInit();
-+
-+ if ((ctx == NULL) || (str == NULL))
-+ return(NULL);
-+
-+ ctxt = xmlXPathNewParserContext(str, ctx);
-+ /* TAG:9999
-+ if (ctx->node != NULL) {
-+ init = xmlXPathNewNodeSet(ctx->node);
-+ valuePush(ctxt, init);
-+ }
-+ */
-+ xmlXPtrEvalXPointer(ctxt);
-+
-+ if ((ctxt->value != NULL) &&
-+ (ctxt->value->type != XPATH_NODESET) &&
-+ (ctxt->value->type != XPATH_LOCATIONSET)) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrEval: evaluation failed to return a node set\n");
-+ } else {
-+ res = valuePop(ctxt);
-+ }
-+
-+ do {
-+ tmp = valuePop(ctxt);
-+ if (tmp != NULL) {
-+ if (tmp != init) {
-+ if (tmp->type == XPATH_NODESET) {
-+ /*
-+ * Evaluation may push a root nodeset which is unused
-+ */
-+ xmlNodeSetPtr set;
-+ set = tmp->nodesetval;
-+ if ((set->nodeNr != 1) ||
-+ (set->nodeTab[0] != (xmlNodePtr) ctx->doc))
-+ stack++;
-+ } else
-+ stack++;
-+ }
-+ xmlXPathFreeObject(tmp);
-+ }
-+ } while (tmp != NULL);
-+ if (stack != 0) {
-+ xmlGenericError(xmlGenericErrorContext,
-+ "xmlXPtrEval: %d object left on the stack\n",
-+ stack);
-+ }
-+ if (ctxt->error != XPATH_EXPRESSION_OK) {
-+ xmlXPathFreeObject(res);
-+ res = NULL;
-+ }
-+
-+ xmlXPathFreeParserContext(ctxt);
-+ return(res);
-+}
-+
-+/**
-+ * xmlXPtrBuildRangeNodeList:
-+ * @range: a range object
-+ *
-+ * Build a node list tree copy of the range
-+ *
-+ * Returns an xmlNodePtr list or NULL.
-+ * the caller has to free the node tree.
-+ */
-+xmlNodePtr
-+xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
-+ /* pointers to generated nodes */
-+ xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;
-+ /* pointers to traversal nodes */
-+ xmlNodePtr start, cur, end;
-+ int index, index2;
-+
-+ if (range == NULL)
-+ return(NULL);
-+ if (range->type != XPATH_RANGE)
-+ return(NULL);
-+ start = (xmlNodePtr) range->user;
-+
-+ if (start == NULL)
-+ return(NULL);
-+ end = range->user2;
-+ if (end == NULL)
-+ return(xmlCopyNode(start, 1));
-+
-+ cur = start;
-+ index = range->index;
-+ index2 = range->index2;
-+ while (cur != NULL) {
-+ if (cur == end) {
-+ if (cur->type == XML_TEXT_NODE) {
-+ const xmlChar *content = cur->content;
-+ int len;
-+
-+ if (content == NULL) {
-+ tmp = xmlNewTextLen(NULL, 0);
-+ } else {
-+ len = index2;
-+ if ((cur == start) && (index > 1)) {
-+ content += (index - 1);
-+ len -= (index - 1);
-+ index = 0;
-+ } else {
-+ len = index2;
-+ }
-+ tmp = xmlNewTextLen(content, len);
-+ }
-+ /* single sub text node selection */
-+ if (list == NULL)
-+ return(tmp);
-+ /* prune and return full set */
-+ if (last != NULL)
-+ xmlAddNextSibling(last, tmp);
-+ else
-+ xmlAddChild(parent, tmp);
-+ return(list);
-+ } else {
-+ tmp = xmlCopyNode(cur, 0);
-+ if (list == NULL)
-+ list = tmp;
-+ else {
-+ if (last != NULL)
-+ xmlAddNextSibling(last, tmp);
-+ else
-+ xmlAddChild(parent, tmp);
-+ }
-+ last = NULL;
-+ parent = tmp;
-+
-+ if (index2 > 1) {
-+ end = xmlXPtrGetNthChild(cur, index2 - 1);
-+ index2 = 0;
-+ }
-+ if ((cur == start) && (index > 1)) {
-+ cur = xmlXPtrGetNthChild(cur, index - 1);
-+ index = 0;
-+ } else {
-+ cur = cur->children;
-+ }
-+ /*
-+ * Now gather the remaining nodes from cur to end
-+ */
-+ continue; /* while */
-+ }
-+ } else if ((cur == start) &&
-+ (list == NULL) /* looks superfluous but ... */ ) {
-+ if (cur->type == XML_TEXT_NODE) {
-+ const xmlChar *content = cur->content;
-+
-+ if (content == NULL) {
-+ tmp = xmlNewTextLen(NULL, 0);
-+ } else {
-+ if (index > 1) {
-+ content += (index - 1);
-+ }
-+ tmp = xmlNewText(content);
-+ }
-+ last = list = tmp;
-+ } else {
-+ if ((cur == start) && (index > 1)) {
-+ tmp = xmlCopyNode(cur, 0);
-+ list = tmp;
-+ parent = tmp;
-+ last = NULL;
-+ cur = xmlXPtrGetNthChild(cur, index - 1);
-+ index = 0;
-+ /*
-+ * Now gather the remaining nodes from cur to end
-+ */
-+ continue; /* while */
-+ }
-+ tmp = xmlCopyNode(cur, 1);
-+ list = tmp;
-+ parent = NULL;
-+ last = tmp;
-+ }
-+ } else {
-+ tmp = NULL;
-+ switch (cur->type) {
-+ case XML_DTD_NODE:
-+ case XML_ELEMENT_DECL:
-+ case XML_ATTRIBUTE_DECL:
-+ case XML_ENTITY_NODE:
-+ /* Do not copy DTD informations */
-+ break;
-+ case XML_ENTITY_DECL:
-+ TODO /* handle csossing entities -> stack needed */
-+ break;
-+ case XML_XINCLUDE_START:
-+ case XML_XINCLUDE_END:
-+ /* don't consider it part of the tree content */
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ /* Humm, should not happen ! */
-+ STRANGE
-+ break;
-+ default:
-+ tmp = xmlCopyNode(cur, 1);
-+ break;
-+ }
-+ if (tmp != NULL) {
-+ if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
-+ STRANGE
-+ return(NULL);
-+ }
-+ if (last != NULL)
-+ xmlAddNextSibling(last, tmp);
-+ else {
-+ xmlAddChild(parent, tmp);
-+ last = tmp;
-+ }
-+ }
-+ }
-+ /*
-+ * Skip to next node in document order
-+ */
-+ if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
-+ STRANGE
-+ return(NULL);
-+ }
-+ cur = xmlXPtrAdvanceNode(cur);
-+ }
-+ return(list);
-+}
-+
-+/**
-+ * xmlXPtrBuildNodeList:
-+ * @obj: the XPointer result from the evaluation.
-+ *
-+ * Build a node list tree copy of the XPointer result.
-+ *
-+ * Returns an xmlNodePtr list or NULL.
-+ * the caller has to free the node tree.
-+ */
-+xmlNodePtr
-+xmlXPtrBuildNodeList(xmlXPathObjectPtr obj) {
-+ xmlNodePtr list = NULL, last = NULL;
-+ int i;
-+
-+ if (obj == NULL)
-+ return(NULL);
-+ switch (obj->type) {
-+ case XPATH_NODESET: {
-+ xmlNodeSetPtr set = obj->nodesetval;
-+ if (set == NULL)
-+ return(NULL);
-+ for (i = 0;i < set->nodeNr;i++) {
-+ if (last == NULL)
-+ list = last = xmlCopyNode(set->nodeTab[i], 1);
-+ else {
-+ xmlAddNextSibling(last, xmlCopyNode(set->nodeTab[i], 1));
-+ if (last->next != NULL)
-+ last = last->next;
-+ }
-+ }
-+ break;
-+ }
-+ case XPATH_LOCATIONSET: {
-+ xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
-+ if (set == NULL)
-+ return(NULL);
-+ for (i = 0;i < set->locNr;i++) {
-+ if (last == NULL)
-+ list = last = xmlXPtrBuildNodeList(set->locTab[i]);
-+ else
-+ xmlAddNextSibling(last,
-+ xmlXPtrBuildNodeList(set->locTab[i]));
-+ if (last != NULL) {
-+ while (last->next != NULL)
-+ last = last->next;
-+ }
-+ }
-+ break;
-+ }
-+ case XPATH_RANGE:
-+ return(xmlXPtrBuildRangeNodeList(obj));
-+ case XPATH_POINT:
-+ return(xmlCopyNode(obj->user, 0));
-+ default:
-+ break;
-+ }
-+ return(list);
-+}
-+
-+/************************************************************************
-+ * *
-+ * XPointer functions *
-+ * *
-+ ************************************************************************/
-+
-+/**
-+ * xmlXPtrNbLocChildren:
-+ * @node: an xmlNodePtr
-+ *
-+ * Count the number of location children of @node or the lenght of the
-+ * string value in case of text/PI/Comments nodes
-+ *
-+ * Returns the number of location children
-+ */
-+int
-+xmlXPtrNbLocChildren(xmlNodePtr node) {
-+ int ret = 0;
-+ if (node == NULL)
-+ return(-1);
-+ switch (node->type) {
-+ case XML_HTML_DOCUMENT_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_ELEMENT_NODE:
-+ node = node->children;
-+ while (node != NULL) {
-+ if (node->type == XML_ELEMENT_NODE)
-+ ret++;
-+ node = node->next;
-+ }
-+ break;
-+ case XML_ATTRIBUTE_NODE:
-+ return(-1);
-+
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+#ifndef XML_USE_BUFFER_CONTENT
-+ ret = xmlStrlen(node->content);
-+#else
-+ ret = xmlBufferLength(node->content);
-+#endif
-+ break;
-+ default:
-+ return(-1);
-+ }
-+ return(ret);
-+}
-+
-+/**
-+ * xmlXPtrHereFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing here() operation
-+ * as described in 5.4.3
-+ */
-+void
-+xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ if (ctxt->context->here == NULL)
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+
-+ valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));
-+}
-+
-+/**
-+ * xmlXPtrOriginFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing origin() operation
-+ * as described in 5.4.3
-+ */
-+void
-+xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ if (ctxt->context->origin == NULL)
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+
-+ valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));
-+}
-+
-+/**
-+ * xmlXPtrStartPointFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing start-point() operation
-+ * as described in 5.4.3
-+ * ----------------
-+ * location-set start-point(location-set)
-+ *
-+ * For each location x in the argument location-set, start-point adds a
-+ * location of type point to the result location-set. That point represents
-+ * the start point of location x and is determined by the following rules:
-+ *
-+ * - If x is of type point, the start point is x.
-+ * - If x is of type range, the start point is the start point of x.
-+ * - If x is of type root, element, text, comment, or processing instruction,
-+ * - the container node of the start point is x and the index is 0.
-+ * - If x is of type attribute or namespace, the function must signal a
-+ * syntax error.
-+ * ----------------
-+ *
-+ */
-+void
-+xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr tmp, obj, point;
-+ xmlLocationSetPtr newset = NULL;
-+ xmlLocationSetPtr oldset = NULL;
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_LOCATIONSET) &&
-+ (ctxt->value->type != XPATH_NODESET)))
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+ obj = valuePop(ctxt);
-+ if (obj->type == XPATH_NODESET) {
-+ /*
-+ * First convert to a location set
-+ */
-+ tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
-+ xmlXPathFreeObject(obj);
-+ obj = tmp;
-+ }
-+
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+ if (newset == NULL) {
-+ xmlXPathFreeObject(obj);
-+ XP_ERROR(XPATH_MEMORY_ERROR);
-+ }
-+ oldset = (xmlLocationSetPtr) obj->user;
-+ if (oldset != NULL) {
-+ int i;
-+
-+ for (i = 0; i < oldset->locNr; i++) {
-+ tmp = oldset->locTab[i];
-+ if (tmp == NULL)
-+ continue;
-+ point = NULL;
-+ switch (tmp->type) {
-+ case XPATH_POINT:
-+ point = xmlXPtrNewPoint(tmp->user, tmp->index);
-+ break;
-+ case XPATH_RANGE: {
-+ xmlNodePtr node = tmp->user;
-+ if (node != NULL) {
-+ if (node->type == XML_ATTRIBUTE_NODE) {
-+ /* TODO: Namespace Nodes ??? */
-+ xmlXPathFreeObject(obj);
-+ xmlXPtrFreeLocationSet(newset);
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+ }
-+ point = xmlXPtrNewPoint(node, tmp->index);
-+ }
-+ break;
-+ }
-+ default:
-+ /*** Should we raise an error ?
-+ xmlXPathFreeObject(obj);
-+ xmlXPathFreeObject(newset);
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+ ***/
-+ break;
-+ }
-+ if (point != NULL)
-+ xmlXPtrLocationSetAdd(newset, point);
-+ }
-+ }
-+ xmlXPathFreeObject(obj);
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+}
-+
-+/**
-+ * xmlXPtrEndPointFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing end-point() operation
-+ * as described in 5.4.3
-+ * ----------------------------
-+ * location-set end-point(location-set)
-+ *
-+ * For each location x in the argument location-set, end-point adds a
-+ * location of type point to the result location-set. That point representsi
-+ * the end point of location x and is determined by the following rules:
-+ *
-+ * - If x is of type point, the resulting point is x.
-+ * - If x is of type range, the resulting point is the end point of x.
-+ * - If x is of type root or element, the container node of the resulting
-+ * point is x and the index is the number of location children of x.
-+ * - If x is of type text, comment, or processing instruction, the container
-+ * node of the resulting point is x and the index is the length of thei
-+ * string-value of x.
-+ * - If x is of type attribute or namespace, the function must signal a
-+ * syntax error.
-+ * ----------------------------
-+ */
-+void
-+xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr tmp, obj, point;
-+ xmlLocationSetPtr newset = NULL;
-+ xmlLocationSetPtr oldset = NULL;
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_LOCATIONSET) &&
-+ (ctxt->value->type != XPATH_NODESET)))
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+ obj = valuePop(ctxt);
-+ if (obj->type == XPATH_NODESET) {
-+ /*
-+ * First convert to a location set
-+ */
-+ tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
-+ xmlXPathFreeObject(obj);
-+ obj = tmp;
-+ }
-+
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+ oldset = (xmlLocationSetPtr) obj->user;
-+ if (oldset != NULL) {
-+ int i;
-+
-+ for (i = 0; i < oldset->locNr; i++) {
-+ tmp = oldset->locTab[i];
-+ if (tmp == NULL)
-+ continue;
-+ point = NULL;
-+ switch (tmp->type) {
-+ case XPATH_POINT:
-+ point = xmlXPtrNewPoint(tmp->user, tmp->index);
-+ break;
-+ case XPATH_RANGE: {
-+ xmlNodePtr node = tmp->user2;
-+ if (node != NULL) {
-+ if (node->type == XML_ATTRIBUTE_NODE) {
-+ /* TODO: Namespace Nodes ??? */
-+ xmlXPathFreeObject(obj);
-+ xmlXPtrFreeLocationSet(newset);
-+ XP_ERROR(XPTR_SYNTAX_ERROR);
-+ }
-+ point = xmlXPtrNewPoint(node, tmp->index2);
-+ } else if (tmp->user == NULL) {
-+ point = xmlXPtrNewPoint(node,
-+ xmlXPtrNbLocChildren(node));
-+ }
-+ break;
-+ }
-+ default:
-+ /*** Should we raise an error ?
-+ xmlXPathFreeObject(obj);
-+ xmlXPathFreeObject(newset);
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+ ***/
-+ break;
-+ }
-+ if (point != NULL)
-+ xmlXPtrLocationSetAdd(newset, point);
-+ }
-+ }
-+ xmlXPathFreeObject(obj);
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+}
-+
-+
-+/**
-+ * xmlXPtrCoveringRange:
-+ * @ctxt: the XPointer Parser context
-+ * @loc: the location for which the covering range must be computed
-+ *
-+ * A covering range is a range that wholly encompasses a location
-+ * Section 5.3.3. Covering Ranges for All Location Types
-+ * http://www.w3.org/TR/xptr#N2267
-+ *
-+ * Returns a new location or NULL in case of error
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
-+ if (loc == NULL)
-+ return(NULL);
-+ if ((ctxt == NULL) || (ctxt->context == NULL) ||
-+ (ctxt->context->doc == NULL))
-+ return(NULL);
-+ switch (loc->type) {
-+ case XPATH_POINT:
-+ return(xmlXPtrNewRange(loc->user, loc->index,
-+ loc->user, loc->index));
-+ case XPATH_RANGE:
-+ if (loc->user2 != NULL) {
-+ return(xmlXPtrNewRange(loc->user, loc->index,
-+ loc->user2, loc->index2));
-+ } else {
-+ xmlNodePtr node = (xmlNodePtr) loc->user;
-+ if (node == (xmlNodePtr) ctxt->context->doc) {
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlXPtrGetArity(node)));
-+ } else {
-+ switch (node->type) {
-+ case XML_ATTRIBUTE_NODE:
-+ /* !!! our model is slightly different than XPath */
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlXPtrGetArity(node)));
-+ case XML_ELEMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE: {
-+ int index = xmlXPtrGetIndex(node);
-+
-+ node = node->parent;
-+ return(xmlXPtrNewRange(node, index - 1,
-+ node, index + 1));
-+ }
-+ default:
-+ return(NULL);
-+ }
-+ }
-+ }
-+ default:
-+ TODO /* missed one case ??? */
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlXPtrRangeFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing the range() function 5.4.3
-+ * location-set range(location-set )
-+ *
-+ * The range function returns ranges covering the locations in
-+ * the argument location-set. For each location x in the argument
-+ * location-set, a range location representing the covering range of
-+ * x is added to the result location-set.
-+ */
-+void
-+xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ int i;
-+ xmlXPathObjectPtr set;
-+ xmlLocationSetPtr oldset;
-+ xmlLocationSetPtr newset;
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_LOCATIONSET) &&
-+ (ctxt->value->type != XPATH_NODESET)))
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+ set = valuePop(ctxt);
-+ if (set->type == XPATH_NODESET) {
-+ xmlXPathObjectPtr tmp;
-+
-+ /*
-+ * First convert to a location set
-+ */
-+ tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
-+ xmlXPathFreeObject(set);
-+ set = tmp;
-+ }
-+ oldset = (xmlLocationSetPtr) set->user;
-+
-+ /*
-+ * The loop is to compute the covering range for each item and add it
-+ */
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+ for (i = 0;i < oldset->locNr;i++) {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
-+ }
-+
-+ /*
-+ * Save the new value and cleanup
-+ */
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+ xmlXPathFreeObject(set);
-+}
-+
-+/**
-+ * xmlXPtrInsideRange:
-+ * @ctxt: the XPointer Parser context
-+ * @loc: the location for which the inside range must be computed
-+ *
-+ * A inside range is a range described in the range-inside() description
-+ *
-+ * Returns a new location or NULL in case of error
-+ */
-+xmlXPathObjectPtr
-+xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
-+ if (loc == NULL)
-+ return(NULL);
-+ if ((ctxt == NULL) || (ctxt->context == NULL) ||
-+ (ctxt->context->doc == NULL))
-+ return(NULL);
-+ switch (loc->type) {
-+ case XPATH_POINT: {
-+ xmlNodePtr node = (xmlNodePtr) loc->user;
-+ switch (node->type) {
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE: {
-+ if (node->content == NULL) {
-+ return(xmlXPtrNewRange(node, 0, node, 0));
-+ } else {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlStrlen(node->content)));
-+#else
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlBufferLength(node->content)));
-+#endif
-+ }
-+ }
-+ case XML_ATTRIBUTE_NODE:
-+ case XML_ELEMENT_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE: {
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlXPtrGetArity(node)));
-+ }
-+ default:
-+ return(NULL);
-+ }
-+ return(NULL);
-+ }
-+ case XPATH_RANGE: {
-+ xmlNodePtr node = (xmlNodePtr) loc->user;
-+ if (loc->user2 != NULL) {
-+ return(xmlXPtrNewRange(node, loc->index,
-+ loc->user2, loc->index2));
-+ } else {
-+ switch (node->type) {
-+ case XML_PI_NODE:
-+ case XML_COMMENT_NODE:
-+ case XML_TEXT_NODE:
-+ case XML_CDATA_SECTION_NODE: {
-+ if (node->content == NULL) {
-+ return(xmlXPtrNewRange(node, 0, node, 0));
-+ } else {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlStrlen(node->content)));
-+#else
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlBufferLength(node->content)));
-+#endif
-+ }
-+ }
-+ case XML_ATTRIBUTE_NODE:
-+ case XML_ELEMENT_NODE:
-+ case XML_ENTITY_REF_NODE:
-+ case XML_DOCUMENT_NODE:
-+ case XML_NOTATION_NODE:
-+ case XML_HTML_DOCUMENT_NODE: {
-+ return(xmlXPtrNewRange(node, 0, node,
-+ xmlXPtrGetArity(node)));
-+ }
-+ default:
-+ return(NULL);
-+ }
-+ return(NULL);
-+ }
-+ }
-+ default:
-+ TODO /* missed one case ??? */
-+ }
-+ return(NULL);
-+}
-+
-+/**
-+ * xmlXPtrRangeInsideFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing the range-inside() function 5.4.3
-+ * location-set range-inside(location-set )
-+ *
-+ * The range-inside function returns ranges covering the contents of
-+ * the locations in the argument location-set. For each location x in
-+ * the argument location-set, a range location is added to the result
-+ * location-set. If x is a range location, then x is added to the
-+ * result location-set. If x is not a range location, then x is used
-+ * as the container location of the start and end points of the range
-+ * location to be added; the index of the start point of the range is
-+ * zero; if the end point is a character point then its index is the
-+ * length of the string-value of x, and otherwise is the number of
-+ * location children of x.
-+ *
-+ */
-+void
-+xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ int i;
-+ xmlXPathObjectPtr set;
-+ xmlLocationSetPtr oldset;
-+ xmlLocationSetPtr newset;
-+
-+ CHECK_ARITY(1);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_LOCATIONSET) &&
-+ (ctxt->value->type != XPATH_NODESET)))
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+ set = valuePop(ctxt);
-+ if (set->type == XPATH_NODESET) {
-+ xmlXPathObjectPtr tmp;
-+
-+ /*
-+ * First convert to a location set
-+ */
-+ tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
-+ xmlXPathFreeObject(set);
-+ set = tmp;
-+ }
-+ oldset = (xmlLocationSetPtr) set->user;
-+
-+ /*
-+ * The loop is to compute the covering range for each item and add it
-+ */
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+ for (i = 0;i < oldset->locNr;i++) {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
-+ }
-+
-+ /*
-+ * Save the new value and cleanup
-+ */
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+ xmlXPathFreeObject(set);
-+}
-+
-+/**
-+ * xmlXPtrRangeToFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Implement the range-to() XPointer function
-+ */
-+void
-+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ xmlXPathObjectPtr range;
-+ const xmlChar *cur;
-+ xmlXPathObjectPtr res, obj;
-+ xmlXPathObjectPtr tmp;
-+ xmlLocationSetPtr newset = NULL;
-+ xmlNodeSetPtr oldset;
-+ int i;
-+
-+ CHECK_ARITY(1);
-+ /*
-+ * Save the expression pointer since we will have to evaluate
-+ * it multiple times. Initialize the new set.
-+ */
-+ CHECK_TYPE(XPATH_NODESET);
-+ obj = valuePop(ctxt);
-+ oldset = obj->nodesetval;
-+ ctxt->context->node = NULL;
-+
-+ cur = ctxt->cur;
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+
-+ for (i = 0; i < oldset->nodeNr; i++) {
-+ ctxt->cur = cur;
-+
-+ /*
-+ * Run the evaluation with a node list made of a single item
-+ * in the nodeset.
-+ */
-+ ctxt->context->node = oldset->nodeTab[i];
-+ tmp = xmlXPathNewNodeSet(ctxt->context->node);
-+ valuePush(ctxt, tmp);
-+
-+ xmlXPathEvalExpr(ctxt);
-+ CHECK_ERROR;
-+
-+ /*
-+ * The result of the evaluation need to be tested to
-+ * decided whether the filter succeeded or not
-+ */
-+ res = valuePop(ctxt);
-+ range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
-+ if (range != NULL) {
-+ xmlXPtrLocationSetAdd(newset, range);
-+ }
-+
-+ /*
-+ * Cleanup
-+ */
-+ if (res != NULL)
-+ xmlXPathFreeObject(res);
-+ if (ctxt->value == tmp) {
-+ res = valuePop(ctxt);
-+ xmlXPathFreeObject(res);
-+ }
-+
-+ ctxt->context->node = NULL;
-+ }
-+
-+ /*
-+ * The result is used as the new evaluation set.
-+ */
-+ xmlXPathFreeObject(obj);
-+ ctxt->context->node = NULL;
-+ ctxt->context->contextSize = -1;
-+ ctxt->context->proximityPosition = -1;
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+}
-+
-+/**
-+ * xmlXPtrAdvanceNode:
-+ * @cur: the node
-+ *
-+ * Advance to the next element or text node in document order
-+ * TODO: add a stack for entering/exiting entities
-+ *
-+ * Returns -1 in case of failure, 0 otherwise
-+ */
-+xmlNodePtr
-+xmlXPtrAdvanceNode(xmlNodePtr cur) {
-+next:
-+ if (cur == NULL)
-+ return(NULL);
-+ if (cur->children != NULL) {
-+ cur = cur->children ;
-+ goto found;
-+ }
-+ if (cur->next != NULL) {
-+ cur = cur->next;
-+ goto found;
-+ }
-+ do {
-+ cur = cur->parent;
-+ if (cur == NULL) return(NULL);
-+ if (cur->next != NULL) {
-+ cur = cur->next;
-+ goto found;
-+ }
-+ } while (cur != NULL);
-+
-+found:
-+ if ((cur->type != XML_ELEMENT_NODE) &&
-+ (cur->type != XML_TEXT_NODE) &&
-+ (cur->type != XML_DOCUMENT_NODE) &&
-+ (cur->type != XML_HTML_DOCUMENT_NODE) &&
-+ (cur->type != XML_CDATA_SECTION_NODE))
-+ goto next;
-+ if (cur->type == XML_ENTITY_REF_NODE) {
-+ TODO
-+ }
-+ return(cur);
-+}
-+
-+/**
-+ * xmlXPtrAdvanceChar:
-+ * @node: the node
-+ * @index: the index
-+ * @bytes: the number of bytes
-+ *
-+ * Advance a point of the associated number of bytes (not UTF8 chars)
-+ *
-+ * Returns -1 in case of failure, 0 otherwise
-+ */
-+int
-+xmlXPtrAdvanceChar(xmlNodePtr *node, int *index, int bytes) {
-+ xmlNodePtr cur;
-+ int pos;
-+ int len;
-+
-+ if ((node == NULL) || (index == NULL))
-+ return(-1);
-+ cur = *node;
-+ if (cur == NULL)
-+ return(-1);
-+ pos = *index;
-+
-+ while (bytes >= 0) {
-+ /*
-+ * First position to the beginning of the first text node
-+ * corresponding to this point
-+ */
-+ while ((cur != NULL) &&
-+ ((cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE))) {
-+ if (pos > 0) {
-+ cur = xmlXPtrGetNthChild(cur, pos);
-+ pos = 0;
-+ } else {
-+ cur = xmlXPtrAdvanceNode(cur);
-+ pos = 0;
-+ }
-+ }
-+
-+ if (cur == NULL) {
-+ *node = NULL;
-+ *index = 0;
-+ return(-1);
-+ }
-+
-+ /*
-+ * if there is no move needed return the current value.
-+ */
-+ if (pos == 0) pos = 1;
-+ if (bytes == 0) {
-+ *node = cur;
-+ *index = pos;
-+ return(0);
-+ }
-+ /*
-+ * We should have a text (or cdata) node ...
-+ */
-+ len = 0;
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ len = xmlStrlen(cur->content);
-+#else
-+ len = xmlBufferLength(cur->content);
-+#endif
-+ }
-+ if (pos > len) {
-+ /* Strange, the index in the text node is greater than it's len */
-+ STRANGE
-+ pos = len;
-+ }
-+ if (pos + bytes >= len) {
-+ bytes -= (len - pos);
-+ cur = xmlXPtrAdvanceNode(cur);
-+ cur = 0;
-+ } else if (pos + bytes < len) {
-+ pos += bytes;
-+ *node = cur;
-+ *index = pos;
-+ return(0);
-+ }
-+ }
-+ return(-1);
-+}
-+
-+/**
-+ * xmlXPtrMatchString:
-+ * @string: the string to search
-+ * @start: the start textnode
-+ * @startindex: the start index
-+ * @end: the end textnode IN/OUT
-+ * @endindex: the end index IN/OUT
-+ *
-+ * Check whether the document contains @string at the position
-+ * (@start, @startindex) and limited by the (@end, @endindex) point
-+ *
-+ * Returns -1 in case of failure, 0 if not found, 1 if found in which case
-+ * (@start, @startindex) will indicate the position of the beginning
-+ * of the range and (@end, @endindex) will endicate the end
-+ * of the range
-+ */
-+int
-+xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
-+ xmlNodePtr *end, int *endindex) {
-+ xmlNodePtr cur;
-+ int pos; /* 0 based */
-+ int len; /* in bytes */
-+ int stringlen; /* in bytes */
-+ int match;
-+
-+ if (string == NULL)
-+ return(-1);
-+ if (start == NULL)
-+ return(-1);
-+ if ((end == NULL) || (endindex == NULL))
-+ return(-1);
-+ cur = start;
-+ if (cur == NULL)
-+ return(-1);
-+ pos = startindex - 1;
-+ stringlen = xmlStrlen(string);
-+
-+ while (stringlen > 0) {
-+ if ((cur == *end) && (pos + stringlen > *endindex))
-+ return(0);
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ len = xmlStrlen(cur->content);
-+#else
-+ len = xmlBufferLength(cur->content);
-+#endif
-+ if (len >= pos + stringlen) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
-+#else
-+ len = (!xmlStrncmp(&xmlBufferContent(cur->content)[pos],
-+ string, stringlen));
-+#endif
-+ if (match) {
-+#ifdef DEBUG_RANGES
-+ xmlGenericError(xmlGenericErrorContext,
-+ "found range %d bytes at index %d of ->",
-+ stringlen, pos + 1);
-+ xmlDebugDumpString(stdout, cur->content);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+#endif
-+ *end = cur;
-+ *endindex = pos + stringlen;
-+ return(1);
-+ } else {
-+ return(0);
-+ }
-+ } else {
-+ int sub = len - pos;
-+#ifndef XML_USE_BUFFER_CONTENT
-+ match = (!xmlStrncmp(&cur->content[pos], string, sub));
-+#else
-+ len = (!xmlStrncmp(&xmlBufferContent(cur->content)[pos],
-+ string, sub));
-+#endif
-+ if (match) {
-+#ifdef DEBUG_RANGES
-+ xmlGenericError(xmlGenericErrorContext,
-+ "found subrange %d bytes at index %d of ->",
-+ sub, pos + 1);
-+ xmlDebugDumpString(stdout, cur->content);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+#endif
-+ string = &string[sub];
-+ stringlen -= sub;
-+ } else {
-+ return(0);
-+ }
-+ }
-+ }
-+ cur = xmlXPtrAdvanceNode(cur);
-+ if (cur == NULL)
-+ return(0);
-+ pos = 0;
-+ }
-+ return(1);
-+}
-+
-+/**
-+ * xmlXPtrSearchString:
-+ * @string: the string to search
-+ * @start: the start textnode IN/OUT
-+ * @startindex: the start index IN/OUT
-+ * @end: the end textnode
-+ * @endindex: the end index
-+ *
-+ * Search the next occurence of @string within the document content
-+ * until the (@end, @endindex) point is reached
-+ *
-+ * Returns -1 in case of failure, 0 if not found, 1 if found in which case
-+ * (@start, @startindex) will indicate the position of the beginning
-+ * of the range and (@end, @endindex) will endicate the end
-+ * of the range
-+ */
-+int
-+xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
-+ xmlNodePtr *end, int *endindex) {
-+ xmlNodePtr cur;
-+ const xmlChar *str;
-+ int pos; /* 0 based */
-+ int len; /* in bytes */
-+ int stringlen; /* in bytes */
-+ xmlChar first;
-+
-+ if (string == NULL)
-+ return(-1);
-+ if ((start == NULL) || (startindex == NULL))
-+ return(-1);
-+ if ((end == NULL) || (endindex == NULL))
-+ return(-1);
-+ cur = *start;
-+ if (cur == NULL)
-+ return(-1);
-+ pos = *startindex - 1;
-+ first = string[0];
-+ stringlen = xmlStrlen(string);
-+
-+ while (cur != NULL) {
-+ if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ len = xmlStrlen(cur->content);
-+#else
-+ len = xmlBufferLength(cur->content);
-+#endif
-+ while (pos <= len) {
-+ if (first != 0) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ str = xmlStrchr(&cur->content[pos], first);
-+#else
-+ str = xmlStrchr(&xmlBufferContent(cur->content)[pos],
-+ first);
-+#endif
-+ if (str != NULL) {
-+ pos = (str - (xmlChar *)(cur->content));
-+#ifdef DEBUG_RANGES
-+ xmlGenericError(xmlGenericErrorContext,
-+ "found '%c' at index %d of ->",
-+ first, pos + 1);
-+ xmlDebugDumpString(stdout, cur->content);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+#endif
-+ if (xmlXPtrMatchString(string, cur, pos + 1,
-+ end, endindex)) {
-+ *start = cur;
-+ *startindex = pos + 1;
-+ return(1);
-+ }
-+ pos++;
-+ } else {
-+ pos = len + 1;
-+ }
-+ } else {
-+ /*
-+ * An empty string is considered to match before each
-+ * character of the string-value and after the final
-+ * character.
-+ */
-+#ifdef DEBUG_RANGES
-+ xmlGenericError(xmlGenericErrorContext,
-+ "found '' at index %d of ->",
-+ pos + 1);
-+ xmlDebugDumpString(stdout, cur->content);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+#endif
-+ *start = cur;
-+ *startindex = pos + 1;
-+ *end = cur;
-+ *endindex = pos + 1;
-+ return(1);
-+ }
-+ }
-+ }
-+ if ((cur == *end) && (pos >= *endindex))
-+ return(0);
-+ cur = xmlXPtrAdvanceNode(cur);
-+ if (cur == NULL)
-+ return(0);
-+ pos = 1;
-+ }
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPtrGetLastChar:
-+ * @node: the node
-+ * @index: the index
-+ *
-+ * Computes the point coordinates of the last char of this point
-+ *
-+ * Returns -1 in case of failure, 0 otherwise
-+ */
-+int
-+xmlXPtrGetLastChar(xmlNodePtr *node, int *index) {
-+ xmlNodePtr cur;
-+ int pos, len = 0;
-+
-+ if ((node == NULL) || (index == NULL))
-+ return(-1);
-+ cur = *node;
-+ pos = *index;
-+
-+ if (cur == NULL)
-+ return(-1);
-+
-+ if ((cur->type == XML_ELEMENT_NODE) ||
-+ (cur->type == XML_DOCUMENT_NODE) ||
-+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
-+ if (pos > 0) {
-+ cur = xmlXPtrGetNthChild(cur, pos);
-+ pos = 0;
-+ }
-+ }
-+ while (cur != NULL) {
-+ if (cur->last != NULL)
-+ cur = cur->last;
-+ else if (cur->content != NULL) {
-+#ifndef XML_USE_BUFFER_CONTENT
-+ len = xmlStrlen(cur->content);
-+#else
-+ len = xmlBufferLength(cur->content);
-+#endif
-+ break;
-+ } else {
-+ return(-1);
-+ }
-+ }
-+ if (cur == NULL)
-+ return(-1);
-+ *node = cur;
-+ *index = len;
-+ return(0);
-+}
-+
-+/**
-+ * xmlXPtrGetStartPoint:
-+ * @obj: an range
-+ * @node: the resulting node
-+ * @index: the resulting index
-+ *
-+ * read the object and return the start point coordinates.
-+ *
-+ * Returns -1 in case of failure, 0 otherwise
-+ */
-+int
-+xmlXPtrGetStartPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *index) {
-+ if ((obj == NULL) || (node == NULL) || (index == NULL))
-+ return(-1);
-+
-+ switch (obj->type) {
-+ case XPATH_POINT:
-+ *node = obj->user;
-+ if (obj->index <= 0)
-+ *index = 0;
-+ else
-+ *index = obj->index;
-+ return(0);
-+ case XPATH_RANGE:
-+ *node = obj->user;
-+ if (obj->index <= 0)
-+ *index = 0;
-+ else
-+ *index = obj->index;
-+ return(0);
-+ default:
-+ return(-1);
-+ }
-+ return(-1);
-+}
-+
-+/**
-+ * xmlXPtrGetEndPoint:
-+ * @obj: an range
-+ * @node: the resulting node
-+ * @index: the resulting index
-+ *
-+ * read the object and return the end point coordinates.
-+ *
-+ * Returns -1 in case of failure, 0 otherwise
-+ */
-+int
-+xmlXPtrGetEndPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *index) {
-+ if ((obj == NULL) || (node == NULL) || (index == NULL))
-+ return(-1);
-+
-+ switch (obj->type) {
-+ case XPATH_POINT:
-+ *node = obj->user;
-+ if (obj->index <= 0)
-+ *index = 0;
-+ else
-+ *index = obj->index;
-+ return(0);
-+ case XPATH_RANGE:
-+ *node = obj->user;
-+ if (obj->index <= 0)
-+ *index = 0;
-+ else
-+ *index = obj->index;
-+ return(0);
-+ default:
-+ return(-1);
-+ }
-+ return(-1);
-+}
-+
-+/**
-+ * xmlXPtrStringRangeFunction:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * Function implementing the string-range() function
-+ * range as described in 5.4.2
-+ *
-+ * ------------------------------
-+ * [Definition: For each location in the location-set argument,
-+ * string-range returns a set of string ranges, a set of substrings in a
-+ * string. Specifically, the string-value of the location is searched for
-+ * substrings that match the string argument, and the resulting location-set
-+ * will contain a range location for each non-overlapping match.]
-+ * An empty string is considered to match before each character of the
-+ * string-value and after the final character. Whitespace in a string
-+ * is matched literally, with no normalization except that provided by
-+ * XML for line ends. The third argument gives the position of the first
-+ * character to be in the resulting range, relative to the start of the
-+ * match. The default value is 1, which makes the range start immediately
-+ * before the first character of the matched string. The fourth argument
-+ * gives the number of characters in the range; the default is that the
-+ * range extends to the end of the matched string.
-+ *
-+ * Element boundaries, as well as entire embedded nodes such as processing
-+ * instructions and comments, are ignored as defined in [XPath].
-+ *
-+ * If the string in the second argument is not found in the string-value
-+ * of the location, or if a value in the third or fourth argument indicates
-+ * a string that is beyond the beginning or end of the document, the
-+ * expression fails.
-+ *
-+ * The points of the range-locations in the returned location-set will
-+ * all be character points.
-+ * ------------------------------
-+ */
-+void
-+xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-+ int i, startindex, endindex, fendindex;
-+ xmlNodePtr start, end, fend;
-+ xmlXPathObjectPtr set;
-+ xmlLocationSetPtr oldset;
-+ xmlLocationSetPtr newset;
-+ xmlXPathObjectPtr string;
-+ xmlXPathObjectPtr position = NULL;
-+ xmlXPathObjectPtr number = NULL;
-+ int found, pos, num;
-+
-+ /*
-+ * Grab the arguments
-+ */
-+ if ((nargs < 2) || (nargs > 4))
-+ XP_ERROR(XPATH_INVALID_ARITY);
-+
-+ if (nargs >= 4) {
-+ CHECK_TYPE(XPATH_NUMBER);
-+ number = valuePop(ctxt);
-+ if (number != NULL)
-+ num = number->floatval;
-+ }
-+ if (nargs >= 3) {
-+ CHECK_TYPE(XPATH_NUMBER);
-+ position = valuePop(ctxt);
-+ if (position != NULL)
-+ pos = position->floatval;
-+ }
-+ CHECK_TYPE(XPATH_STRING);
-+ string = valuePop(ctxt);
-+ if ((ctxt->value == NULL) ||
-+ ((ctxt->value->type != XPATH_LOCATIONSET) &&
-+ (ctxt->value->type != XPATH_NODESET)))
-+ XP_ERROR(XPATH_INVALID_TYPE)
-+
-+ set = valuePop(ctxt);
-+ if (set->type == XPATH_NODESET) {
-+ xmlXPathObjectPtr tmp;
-+
-+ /*
-+ * First convert to a location set
-+ */
-+ tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
-+ xmlXPathFreeObject(set);
-+ set = tmp;
-+ }
-+ oldset = (xmlLocationSetPtr) set->user;
-+
-+ /*
-+ * The loop is to search for each element in the location set
-+ * the list of location set corresponding to that search
-+ */
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+ for (i = 0;i < oldset->locNr;i++) {
-+#ifdef DEBUG_RANGES
-+ xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
-+#endif
-+
-+ xmlXPtrGetStartPoint(oldset->locTab[i], &start, &startindex);
-+ xmlXPtrGetEndPoint(oldset->locTab[i], &end, &endindex);
-+ xmlXPtrAdvanceChar(&start, &startindex, 0);
-+ xmlXPtrGetLastChar(&end, &endindex);
-+
-+#ifdef DEBUG_RANGES
-+ xmlGenericError(xmlGenericErrorContext,
-+ "from index %d of ->", startindex);
-+ xmlDebugDumpString(stdout, start->content);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+ xmlGenericError(xmlGenericErrorContext,
-+ "to index %d of ->", endindex);
-+ xmlDebugDumpString(stdout, end->content);
-+ xmlGenericError(xmlGenericErrorContext, "\n");
-+#endif
-+ do {
-+ fend = end;
-+ fendindex = endindex;
-+ found = xmlXPtrSearchString(string->stringval, &start, &startindex,
-+ &fend, &fendindex);
-+ if (found == 1) {
-+ if (position == NULL) {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrNewRange(start, startindex, fend, fendindex));
-+ } else if (xmlXPtrAdvanceChar(&start, &startindex,
-+ pos - 1) == 0) {
-+ if ((number != NULL) && (num > 0)) {
-+ int rindex;
-+ xmlNodePtr rend;
-+ rend = start;
-+ rindex = startindex - 1;
-+ if (xmlXPtrAdvanceChar(&rend, &rindex,
-+ num) == 0) {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrNewRange(start, startindex,
-+ rend, rindex));
-+ }
-+ } else if ((number != NULL) && (num <= 0)) {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrNewRange(start, startindex,
-+ start, startindex));
-+ } else {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPtrNewRange(start, startindex,
-+ fend, fendindex));
-+ }
-+ }
-+ start = fend;
-+ startindex = fendindex;
-+ if (string->stringval[0] == 0)
-+ startindex++;
-+ }
-+ } while (found == 1);
-+ }
-+
-+ /*
-+ * Save the new value and cleanup
-+ */
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+ xmlXPathFreeObject(set);
-+ xmlXPathFreeObject(string);
-+ if (position) xmlXPathFreeObject(position);
-+ if (number) xmlXPathFreeObject(number);
-+}
-+
-+/**
-+ * xmlXPtrEvalRangePredicate:
-+ * @ctxt: the XPointer Parser context
-+ *
-+ * [8] Predicate ::= '[' PredicateExpr ']'
-+ * [9] PredicateExpr ::= Expr
-+ *
-+ * Evaluate a predicate as in xmlXPathEvalPredicate() but for
-+ * a Location Set instead of a node set
-+ */
-+void
-+xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
-+ const xmlChar *cur;
-+ xmlXPathObjectPtr res;
-+ xmlXPathObjectPtr obj, tmp;
-+ xmlLocationSetPtr newset = NULL;
-+ xmlLocationSetPtr oldset;
-+ int i;
-+
-+ SKIP_BLANKS;
-+ if (CUR != '[') {
-+ XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-+ }
-+ NEXT;
-+ SKIP_BLANKS;
-+
-+ /*
-+ * Extract the old set, and then evaluate the result of the
-+ * expression for all the element in the set. use it to grow
-+ * up a new set.
-+ */
-+ CHECK_TYPE(XPATH_LOCATIONSET);
-+ obj = valuePop(ctxt);
-+ oldset = obj->user;
-+ ctxt->context->node = NULL;
-+
-+ if ((oldset == NULL) || (oldset->locNr == 0)) {
-+ ctxt->context->contextSize = 0;
-+ ctxt->context->proximityPosition = 0;
-+ xmlXPathEvalExpr(ctxt);
-+ res = valuePop(ctxt);
-+ if (res != NULL)
-+ xmlXPathFreeObject(res);
-+ valuePush(ctxt, obj);
-+ CHECK_ERROR;
-+ } else {
-+ /*
-+ * Save the expression pointer since we will have to evaluate
-+ * it multiple times. Initialize the new set.
-+ */
-+ cur = ctxt->cur;
-+ newset = xmlXPtrLocationSetCreate(NULL);
-+
-+ for (i = 0; i < oldset->locNr; i++) {
-+ ctxt->cur = cur;
-+
-+ /*
-+ * Run the evaluation with a node list made of a single item
-+ * in the nodeset.
-+ */
-+ ctxt->context->node = oldset->locTab[i]->user;
-+ tmp = xmlXPathNewNodeSet(ctxt->context->node);
-+ valuePush(ctxt, tmp);
-+ ctxt->context->contextSize = oldset->locNr;
-+ ctxt->context->proximityPosition = i + 1;
-+
-+ xmlXPathEvalExpr(ctxt);
-+ CHECK_ERROR;
-+
-+ /*
-+ * The result of the evaluation need to be tested to
-+ * decided whether the filter succeeded or not
-+ */
-+ res = valuePop(ctxt);
-+ if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-+ xmlXPtrLocationSetAdd(newset,
-+ xmlXPathObjectCopy(oldset->locTab[i]));
-+ }
-+
-+ /*
-+ * Cleanup
-+ */
-+ if (res != NULL)
-+ xmlXPathFreeObject(res);
-+ if (ctxt->value == tmp) {
-+ res = valuePop(ctxt);
-+ xmlXPathFreeObject(res);
-+ }
-+
-+ ctxt->context->node = NULL;
-+ }
-+
-+ /*
-+ * The result is used as the new evaluation set.
-+ */
-+ xmlXPathFreeObject(obj);
-+ ctxt->context->node = NULL;
-+ ctxt->context->contextSize = -1;
-+ ctxt->context->proximityPosition = -1;
-+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-+ }
-+ if (CUR != ']') {
-+ XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-+ }
-+
-+ NEXT;
-+ SKIP_BLANKS;
-+}
-+
-+#else
-+#endif
-+
-diff -Nru libxml2-2.3.0/libxml/xpointer.h libxml2-2.3.0.new/libxml/xpointer.h
---- libxml2-2.3.0/libxml/xpointer.h Thu Jan 1 01:00:00 1970
-+++ libxml2-2.3.0.new/libxml/xpointer.h Mon Feb 12 04:07:28 2001
-@@ -0,0 +1,57 @@
-+/*
-+ * xpointer.h : API to handle XML Pointers
-+ *
-+ * World Wide Web Consortium Working Draft 03-March-1998
-+ * http://www.w3.org/TR/1998/WD-xptr-19980303
-+ *
-+ * See Copyright for the status of this software.
-+ *
-+ * Daniel.Veillard@w3.org
-+ */
-+
-+#ifndef __XML_XPTR_H__
-+#define __XML_XPTR_H__
-+
-+#include <libxml/tree.h>
-+#include <libxml/xpath.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * A Location Set
-+ */
-+typedef struct _xmlLocationSet xmlLocationSet;
-+typedef xmlLocationSet *xmlLocationSetPtr;
-+struct _xmlLocationSet {
-+ int locNr; /* number of locations in the set */
-+ int locMax; /* size of the array as allocated */
-+ xmlXPathObjectPtr *locTab;/* array of locations */
-+};
-+
-+/*
-+ * Handling of location sets
-+ */
-+
-+void xmlXPtrFreeLocationSet (xmlLocationSetPtr obj);
-+xmlLocationSetPtr xmlXPtrLocationSetMerge (xmlLocationSetPtr val1,
-+ xmlLocationSetPtr val2);
-+
-+/*
-+ * Functions
-+ */
-+xmlXPathContextPtr xmlXPtrNewContext (xmlDocPtr doc,
-+ xmlNodePtr here,
-+ xmlNodePtr origin);
-+xmlXPathObjectPtr xmlXPtrEval (const xmlChar *str,
-+ xmlXPathContextPtr ctx);
-+void xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt,
-+ int nargs);
-+xmlNodePtr xmlXPtrBuildNodeList (xmlXPathObjectPtr obj);
-+void xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* __XML_XPTR_H__ */
-diff -Nru libxml2-2.3.0/libxml-2.0.pc.in libxml2-2.3.0.new/libxml-2.0.pc.in
---- libxml2-2.3.0/libxml-2.0.pc.in Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/libxml-2.0.pc.in Thu Jan 1 01:00:00 1970
-@@ -1,12 +0,0 @@
--prefix=@prefix@
--exec_prefix=@exec_prefix@
--libdir=@libdir@
--includedir=@includedir@
--
--
--Name: libXML
--Version: @VERSION@
--Description: libXML library.
--Requires:
--Libs: -L${libdir} -lxml2 @Z_LIBS@ @M_LIBS@ @LIBS@
--Cflags: @XML_INCLUDEDIR@ @XML_CFLAGS@
-diff -Nru libxml2-2.3.0/libxml.4 libxml2-2.3.0.new/libxml.4
---- libxml2-2.3.0/libxml.4 Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/libxml.4 Thu Jan 1 01:00:00 1970
-@@ -1,66 +0,0 @@
--.TH libxml 4 "12 April 2000"
--.SH NAME
--libxml \- library used to parse XML files
--.SH DESCRIPTION
--The
--.I libxml
--library is used to parse XML files.
--Its internal document repesentation is as close as possible to the
--.I DOM
--(Document Object Model) interface,
--an API for accessing XML or HTML structured documents.
--.LP
--The
--.I libxml
--library also has a
--.IR SAX -like
--interface,
--which is designed to be compatible with
--.IR expat (1).
--NOTE:
--.IR SAX ,
--the Simple API for XML,
--is a standard interface for event-based XML parsing,
--developed collaboratively by the members of the XML-DEV mailing list,
--currently hosted by OASIS.
--The
--.I expat
--library is a XML 1.0 parser written in C,
--which aims to be fully conforming.
--It is currently not a validating XML processor.
--.LP
--The
--.I libxml
--library now includes a nearly complete
--.I XPath
--implementation.
--The
--.I XPath
--(XML Path Language) is a language for addressing parts of an
--XML document,
--designed to be used by both
--.I XSLT
--and
--.IR XPointer .
--.LP
--The
--.I libxml
--library exports Push and Pull type parser interfaces for both XML and
--.IR html .
--.SH FILES
--.TP 2.2i
--.B /depot/lib/libxml_2.0.0/libxml.a
--static library
--.TP
--.B /depot/lib/libxml_2.0.0/libxml.so
--shareable library
--.TP
--.B /depot/package/libxml_2.0.0/bin/xmllint
--binary application for parsing XML files
--.SH AUTHORS
--Daniel Veillard (Daniel.Veillard@w3.org).
--If you download and install this package please send the author email.
--Manual page by Ziying Sherwin (sherwin@nlm.nih.gov),
--Lister Hill National Center for Biomedical Communications,
--U.S. National Library of Medicine.
--.\" end of manual page
-diff -Nru libxml2-2.3.0/libxml.m4 libxml2-2.3.0.new/libxml.m4
---- libxml2-2.3.0/libxml.m4 Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/libxml.m4 Thu Jan 1 01:00:00 1970
-@@ -1,148 +0,0 @@
--dnl Code shamelessly stolen from glib-config by Sebastian Rittau
--dnl AM_PATH_XML([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
--AC_DEFUN(AM_PATH_XML,[
--AC_ARG_WITH(xml-prefix,
-- [ --with-xml-prefix=PFX Prefix where libxml is installed (optional)],
-- xml_config_prefix="$withval", xml_config_prefix="")
--AC_ARG_ENABLE(xmltest,
-- [ --disable-xmltest Do not try to compile and run a test XML program],,
-- enable_xmltest=yes)
--
-- if test x$xml_config_prefix != x ; then
-- xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
-- if test x${XML_CONFIG+set} != xset ; then
-- XML_CONFIG=$xml_config_prefix/bin/xml-config
-- fi
-- fi
--
-- AC_PATH_PROG(XML_CONFIG, xml-config, no)
-- min_xml_version=ifelse([$1], ,2.0.0, [$1])
-- AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
-- no_xml=""
-- if test "$XML_CONFIG" = "no" ; then
-- no_xml=yes
-- else
-- XML_CFLAGS=`$XML_CONFIG $xml_config_args --cflags`
-- XML_LIBS=`$XML_CONFIG $xml_config_args --libs`
-- xml_config_major_version=`$XML_CONFIG $xml_config_args --version | \
-- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
-- xml_config_minor_version=`$XML_CONFIG $xml_config_args --version | \
-- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
-- xml_config_micro_version=`$XML_CONFIG $xml_config_args --version | \
-- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
-- if test "x$enable_xmltest" = "xyes" ; then
-- ac_save_CFLAGS="$CFLAGS"
-- ac_save_LIBS="$LIBS"
-- CFLAGS="$CFLAGS $XML_CFLAGS"
-- LIBS="$XML_LIBS $LIBS"
--dnl
--dnl Now check if the installed libxml is sufficiently new.
--dnl
-- rm -f conf.xmltest
-- AC_TRY_RUN([
--#include <stdlib.h>
--#include <stdio.h>
--#include <xmlversion.h>
--#include <parser.h>
--
--int
--main()
--{
-- int xml_major_version, xml_minor_version, xml_micro_version;
-- int major, minor, micro;
-- char *tmp_version;
--
-- system("touch conf.xmltest");
--
-- tmp_version = xmlStrdup("$min_xml_version");
-- if(sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
-- printf("%s, bad version string\n", "$min_xml_version");
-- exit(1);
-- }
--
-- tmp_version = xmlStrdup(LIBXML_DOTTED_VERSION);
-- if(sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
-- printf("%s, bad version string\n", "$min_xml_version");
-- exit(1);
-- }
--
-- if((xml_major_version != $xml_config_major_version) ||
-- (xml_minor_version != $xml_config_minor_version) ||
-- (xml_micro_version != $xml_config_micro_version))
-- {
-- printf("\n*** 'xml-config --version' returned %d.%d.%d, but libxml (%d.%d.%d)\n",
-- $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version,
-- xml_major_version, xml_minor_version, xml_micro_version);
-- printf("*** was found! If xml-config was correct, then it is best\n");
-- printf("*** to remove the old version of libxml. You may also be able to fix the error\n");
-- printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
-- printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
-- printf("*** required on your system.\n");
-- printf("*** If xml-config was wrong, set the environment variable XML_CONFIG\n");
-- printf("*** to point to the correct copy of xml-config, and remove the file config.cache\n");
-- printf("*** before re-running configure\n");
-- }
-- else
-- {
-- if ((xml_major_version > major) ||
-- ((xml_major_version == major) && (xml_minor_version > minor)) ||
-- ((xml_major_version == major) && (xml_minor_version == minor) &&
-- (xml_micro_version >= micro)))
-- {
-- return 0;
-- }
-- else
-- {
-- printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
-- xml_major_version, xml_minor_version, xml_micro_version);
-- printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
-- major, minor, micro);
-- printf("*** libxml is always available from ftp://ftp.gnome.org.\n");
-- printf("***\n");
-- printf("*** If you have already installed a sufficiently new version, this error\n");
-- printf("*** probably means that the wrong copy of the xml-config shell script is\n");
-- printf("*** being found. The easiest way to fix this is to remove the old version\n");
-- printf("*** of libxml, but you can also set the XML_CONFIG environment to point to the\n");
-- printf("*** correct copy of xml-config. (In this case, you will have to\n");
-- printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
-- printf("*** so that the correct libraries are found at run-time))\n");
-- }
-- }
-- return 1;
--}
--],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
--
-- CFLAGS="$ac_save_CFLAGS"
-- LIBS="$ac_save_LIBS"
-- fi
-- fi
--
-- if test "x$no_xml" = x ; then
-- AC_MSG_RESULT(yes)
-- ifelse([$2], , :, [$2])
-- else
-- AC_MSG_RESULT(no)
-- if test "$XML_CONFIG" = "no" ; then
-- echo "*** The xml-config script installed by libxml could not be found"
-- echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
-- echo "*** your path, or set the XML_CONFIG environment variable to the"
-- echo "*** full path to xml-config."
-- else
-- if test -f conf.xmltest ; then
-- :
-- else
-- echo "*** Could not run libxml test program, checking why..."
-- CFLAGS="$CFLAGS $XML_CFLAGS"
-- LIBS="$LIBS $XML_LIBS"
-- dnl FIXME: AC_TRY_LINK
-- fi
-- fi
--
-- XML_CFLAGS=""
-- XML_LIBS=""
-- ifelse([$3], , :, [$3])
-- fi
-- AC_SUBST(XML_CFLAGS)
-- AC_SUBST(XML_LIBS)
-- rm -f conf.xmltest
--])
-diff -Nru libxml2-2.3.0/nanoftp.c libxml2-2.3.0.new/nanoftp.c
---- libxml2-2.3.0/nanoftp.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/nanoftp.c Thu Jan 1 01:00:00 1970
-@@ -1,1964 +0,0 @@
--/*
-- * nanoftp.c: basic FTP client support
-- *
-- * Reference: RFC 959
-- */
--
--#ifdef TESTING
--#define STANDALONE
--#define HAVE_STDLIB_H
--#define HAVE_UNISTD_H
--#define HAVE_SYS_SOCKET_H
--#define HAVE_NETINET_IN_H
--#define HAVE_NETDB_H
--#define HAVE_SYS_TIME_H
--#else /* STANDALONE */
--#ifdef WIN32
--#define INCLUDE_WINSOCK
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--#endif /* STANDALONE */
--
--#include <libxml/xmlversion.h>
--
--#ifdef LIBXML_FTP_ENABLED
--#include <stdio.h>
--#include <string.h>
--
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_SYS_SOCKET_H
--#include <sys/socket.h>
--#endif
--#ifdef HAVE_NETINET_IN_H
--#include <netinet/in.h>
--#endif
--#ifdef HAVE_ARPA_INET_H
--#include <arpa/inet.h>
--#endif
--#ifdef HAVE_NETDB_H
--#include <netdb.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_ERRNO_H
--#include <errno.h>
--#endif
--#ifdef HAVE_SYS_TIME_H
--#include <sys/time.h>
--#endif
--#ifdef HAVE_SYS_SELECT_H
--#include <sys/select.h>
--#endif
--#ifdef HAVE_STRINGS_H
--#include <strings.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/nanoftp.h>
--#include <libxml/xmlerror.h>
--
--/* #define DEBUG_FTP 1 */
--#ifdef STANDALONE
--#ifndef DEBUG_FTP
--#define DEBUG_FTP 1
--#endif
--#endif
--
--/**
-- * A couple portability macros
-- */
--#ifndef _WINSOCKAPI_
--#define closesocket(s) close(s)
--#define SOCKET int
--#endif
--
--static char hostname[100];
--
--#define FTP_COMMAND_OK 200
--#define FTP_SYNTAX_ERROR 500
--#define FTP_GET_PASSWD 331
--#define FTP_BUF_SIZE 512
--
--typedef struct xmlNanoFTPCtxt {
-- char *protocol; /* the protocol name */
-- char *hostname; /* the host name */
-- int port; /* the port */
-- char *path; /* the path within the URL */
-- char *user; /* user string */
-- char *passwd; /* passwd string */
-- struct sockaddr_in ftpAddr; /* the socket address struct */
-- int passive; /* currently we support only passive !!! */
-- SOCKET controlFd; /* the file descriptor for the control socket */
-- SOCKET dataFd; /* the file descriptor for the data socket */
-- int state; /* WRITE / READ / CLOSED */
-- int returnValue; /* the protocol return value */
-- /* buffer for data received from the control connection */
-- char controlBuf[FTP_BUF_SIZE + 1];
-- int controlBufIndex;
-- int controlBufUsed;
-- int controlBufAnswer;
--} xmlNanoFTPCtxt, *xmlNanoFTPCtxtPtr;
--
--static int initialized = 0;
--static char *proxy = NULL; /* the proxy name if any */
--static int proxyPort = 0; /* the proxy port if any */
--static char *proxyUser = NULL; /* user for proxy authentication */
--static char *proxyPasswd = NULL;/* passwd for proxy authentication */
--static int proxyType = 0; /* uses TYPE or a@b ? */
--
--/**
-- * xmlNanoFTPInit:
-- *
-- * Initialize the FTP protocol layer.
-- * Currently it just checks for proxy informations,
-- * and get the hostname
-- */
--
--void
--xmlNanoFTPInit(void) {
-- const char *env;
--#ifdef _WINSOCKAPI_
-- WSADATA wsaData;
--#endif
--
-- if (initialized)
-- return;
--
--#ifdef _WINSOCKAPI_
-- if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
-- return;
--#endif
--
-- gethostname(hostname, sizeof(hostname));
--
-- proxyPort = 21;
-- env = getenv("no_proxy");
-- if (env != NULL)
-- return;
-- env = getenv("ftp_proxy");
-- if (env != NULL) {
-- xmlNanoFTPScanProxy(env);
-- } else {
-- env = getenv("FTP_PROXY");
-- if (env != NULL) {
-- xmlNanoFTPScanProxy(env);
-- }
-- }
-- env = getenv("ftp_proxy_user");
-- if (env != NULL) {
-- proxyUser = xmlMemStrdup(env);
-- }
-- env = getenv("ftp_proxy_password");
-- if (env != NULL) {
-- proxyPasswd = xmlMemStrdup(env);
-- }
-- initialized = 1;
--}
--
--/**
-- * xmlNanoFTPClenup:
-- *
-- * Cleanup the FTP protocol layer. This cleanup proxy informations.
-- */
--
--void
--xmlNanoFTPCleanup(void) {
-- if (proxy != NULL) {
-- xmlFree(proxy);
-- proxy = NULL;
-- }
-- if (proxyUser != NULL) {
-- xmlFree(proxyUser);
-- proxyUser = NULL;
-- }
-- if (proxyPasswd != NULL) {
-- xmlFree(proxyPasswd);
-- proxyPasswd = NULL;
-- }
-- hostname[0] = 0;
--#ifdef _WINSOCKAPI_
-- if (initialized)
-- WSACleanup();
--#endif
-- initialized = 0;
-- return;
--}
--
--/**
-- * xmlNanoFTPProxy:
-- * @host: the proxy host name
-- * @port: the proxy port
-- * @user: the proxy user name
-- * @passwd: the proxy password
-- * @type: the type of proxy 1 for using SITE, 2 for USER a@b
-- *
-- * Setup the FTP proxy informations.
-- * This can also be done by using ftp_proxy ftp_proxy_user and
-- * ftp_proxy_password environment variables.
-- */
--
--void
--xmlNanoFTPProxy(const char *host, int port, const char *user,
-- const char *passwd, int type) {
-- if (proxy != NULL)
-- xmlFree(proxy);
-- if (proxyUser != NULL)
-- xmlFree(proxyUser);
-- if (proxyPasswd != NULL)
-- xmlFree(proxyPasswd);
-- if (host)
-- proxy = xmlMemStrdup(host);
-- if (user)
-- proxyUser = xmlMemStrdup(user);
-- if (passwd)
-- proxyPasswd = xmlMemStrdup(passwd);
-- proxyPort = port;
-- proxyType = type;
--}
--
--/**
-- * xmlNanoFTPScanURL:
-- * @ctx: an FTP context
-- * @URL: The URL used to initialize the context
-- *
-- * (Re)Initialize an FTP context by parsing the URL and finding
-- * the protocol host port and path it indicates.
-- */
--
--static void
--xmlNanoFTPScanURL(void *ctx, const char *URL) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- const char *cur = URL;
-- char buf[4096];
-- int index = 0;
-- int port = 0;
--
-- if (ctxt->protocol != NULL) {
-- xmlFree(ctxt->protocol);
-- ctxt->protocol = NULL;
-- }
-- if (ctxt->hostname != NULL) {
-- xmlFree(ctxt->hostname);
-- ctxt->hostname = NULL;
-- }
-- if (ctxt->path != NULL) {
-- xmlFree(ctxt->path);
-- ctxt->path = NULL;
-- }
-- if (URL == NULL) return;
-- buf[index] = 0;
-- while (*cur != 0) {
-- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-- buf[index] = 0;
-- ctxt->protocol = xmlMemStrdup(buf);
-- index = 0;
-- cur += 3;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0) return;
--
-- buf[index] = 0;
-- while (1) {
-- if (cur[0] == ':') {
-- buf[index] = 0;
-- ctxt->hostname = xmlMemStrdup(buf);
-- index = 0;
-- cur += 1;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- port *= 10;
-- port += *cur - '0';
-- cur++;
-- }
-- if (port != 0) ctxt->port = port;
-- while ((cur[0] != '/') && (*cur != 0))
-- cur++;
-- break;
-- }
-- if ((*cur == '/') || (*cur == 0)) {
-- buf[index] = 0;
-- ctxt->hostname = xmlMemStrdup(buf);
-- index = 0;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0)
-- ctxt->path = xmlMemStrdup("/");
-- else {
-- index = 0;
-- buf[index] = 0;
-- while (*cur != 0)
-- buf[index++] = *cur++;
-- buf[index] = 0;
-- ctxt->path = xmlMemStrdup(buf);
-- }
--}
--
--/**
-- * xmlNanoFTPUpdateURL:
-- * @ctx: an FTP context
-- * @URL: The URL used to update the context
-- *
-- * Update an FTP context by parsing the URL and finding
-- * new path it indicates. If there is an error in the
-- * protocol, hostname, port or other information, the
-- * error is raised. It indicates a new connection has to
-- * be established.
-- *
-- * Returns 0 if Ok, -1 in case of error (other host).
-- */
--
--int
--xmlNanoFTPUpdateURL(void *ctx, const char *URL) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- const char *cur = URL;
-- char buf[4096];
-- int index = 0;
-- int port = 0;
--
-- if (URL == NULL)
-- return(-1);
-- if (ctxt == NULL)
-- return(-1);
-- if (ctxt->protocol == NULL)
-- return(-1);
-- if (ctxt->hostname == NULL)
-- return(-1);
-- buf[index] = 0;
-- while (*cur != 0) {
-- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-- buf[index] = 0;
-- if (strcmp(ctxt->protocol, buf))
-- return(-1);
-- index = 0;
-- cur += 3;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0)
-- return(-1);
--
-- buf[index] = 0;
-- while (1) {
-- if (cur[0] == ':') {
-- buf[index] = 0;
-- if (strcmp(ctxt->hostname, buf))
-- return(-1);
-- index = 0;
-- cur += 1;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- port *= 10;
-- port += *cur - '0';
-- cur++;
-- }
-- if (port != ctxt->port)
-- return(-1);
-- while ((cur[0] != '/') && (*cur != 0))
-- cur++;
-- break;
-- }
-- if ((*cur == '/') || (*cur == 0)) {
-- buf[index] = 0;
-- if (strcmp(ctxt->hostname, buf))
-- return(-1);
-- index = 0;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (ctxt->path != NULL) {
-- xmlFree(ctxt->path);
-- ctxt->path = NULL;
-- }
--
-- if (*cur == 0)
-- ctxt->path = xmlMemStrdup("/");
-- else {
-- index = 0;
-- buf[index] = 0;
-- while (*cur != 0)
-- buf[index++] = *cur++;
-- buf[index] = 0;
-- ctxt->path = xmlMemStrdup(buf);
-- }
-- return(0);
--}
--
--/**
-- * xmlNanoFTPScanProxy:
-- * @URL: The proxy URL used to initialize the proxy context
-- *
-- * (Re)Initialize the FTP Proxy context by parsing the URL and finding
-- * the protocol host port it indicates.
-- * Should be like ftp://myproxy/ or ftp://myproxy:3128/
-- * A NULL URL cleans up proxy informations.
-- */
--
--void
--xmlNanoFTPScanProxy(const char *URL) {
-- const char *cur = URL;
-- char buf[4096];
-- int index = 0;
-- int port = 0;
--
-- if (proxy != NULL) {
-- xmlFree(proxy);
-- proxy = NULL;
-- }
-- if (proxyPort != 0) {
-- proxyPort = 0;
-- }
--#ifdef DEBUG_FTP
-- if (URL == NULL)
-- xmlGenericError(xmlGenericErrorContext, "Removing FTP proxy info\n");
-- else
-- xmlGenericError(xmlGenericErrorContext, "Using FTP proxy %s\n", URL);
--#endif
-- if (URL == NULL) return;
-- buf[index] = 0;
-- while (*cur != 0) {
-- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-- buf[index] = 0;
-- index = 0;
-- cur += 3;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0) return;
--
-- buf[index] = 0;
-- while (1) {
-- if (cur[0] == ':') {
-- buf[index] = 0;
-- proxy = xmlMemStrdup(buf);
-- index = 0;
-- cur += 1;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- port *= 10;
-- port += *cur - '0';
-- cur++;
-- }
-- if (port != 0) proxyPort = port;
-- while ((cur[0] != '/') && (*cur != 0))
-- cur++;
-- break;
-- }
-- if ((*cur == '/') || (*cur == 0)) {
-- buf[index] = 0;
-- proxy = xmlMemStrdup(buf);
-- index = 0;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
--}
--
--/**
-- * xmlNanoFTPNewCtxt:
-- * @URL: The URL used to initialize the context
-- *
-- * Allocate and initialize a new FTP context.
-- *
-- * Returns an FTP context or NULL in case of error.
-- */
--
--void*
--xmlNanoFTPNewCtxt(const char *URL) {
-- xmlNanoFTPCtxtPtr ret;
--
-- ret = (xmlNanoFTPCtxtPtr) xmlMalloc(sizeof(xmlNanoFTPCtxt));
-- if (ret == NULL) return(NULL);
--
-- memset(ret, 0, sizeof(xmlNanoFTPCtxt));
-- ret->port = 21;
-- ret->passive = 1;
-- ret->returnValue = 0;
-- ret->controlBufIndex = 0;
-- ret->controlBufUsed = 0;
--
-- if (URL != NULL)
-- xmlNanoFTPScanURL(ret, URL);
--
-- return(ret);
--}
--
--/**
-- * xmlNanoFTPFreeCtxt:
-- * @ctx: an FTP context
-- *
-- * Frees the context after closing the connection.
-- */
--
--void
--xmlNanoFTPFreeCtxt(void * ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- if (ctxt == NULL) return;
-- if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
-- if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
-- if (ctxt->path != NULL) xmlFree(ctxt->path);
-- ctxt->passive = 1;
-- if (ctxt->controlFd >= 0) closesocket(ctxt->controlFd);
-- ctxt->controlFd = -1;
-- ctxt->controlBufIndex = -1;
-- ctxt->controlBufUsed = -1;
-- xmlFree(ctxt);
--}
--
--/**
-- * xmlNanoFTPParseResponse:
-- * @ctx: the FTP connection context
-- * @buf: the buffer containing the response
-- * @len: the buffer length
-- *
-- * Parsing of the server answer, we just extract the code.
-- *
-- * returns 0 for errors
-- * +XXX for last line of response
-- * -XXX for response to be continued
-- */
--static int
--xmlNanoFTPParseResponse(void *ctx, char *buf, int len) {
-- int val = 0;
--
-- if (len < 3) return(-1);
-- if ((*buf >= '0') && (*buf <= '9'))
-- val = val * 10 + (*buf - '0');
-- else
-- return(0);
-- buf++;
-- if ((*buf >= '0') && (*buf <= '9'))
-- val = val * 10 + (*buf - '0');
-- else
-- return(0);
-- buf++;
-- if ((*buf >= '0') && (*buf <= '9'))
-- val = val * 10 + (*buf - '0');
-- else
-- return(0);
-- buf++;
-- if (*buf == '-')
-- return(-val);
-- return(val);
--}
--
--/**
-- * xmlNanoFTPGetMore:
-- * @ctx: an FTP context
-- *
-- * Read more information from the FTP control connection
-- * Returns the number of bytes read, < 0 indicates an error
-- */
--static int
--xmlNanoFTPGetMore(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- int len;
-- int size;
--
-- if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPGetMore : controlBufIndex = %d\n",
-- ctxt->controlBufIndex);
--#endif
-- return(-1);
-- }
--
-- if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPGetMore : controlBufUsed = %d\n",
-- ctxt->controlBufUsed);
--#endif
-- return(-1);
-- }
-- if (ctxt->controlBufIndex > ctxt->controlBufUsed) {
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",
-- ctxt->controlBufIndex, ctxt->controlBufUsed);
--#endif
-- return(-1);
-- }
--
-- /*
-- * First pack the control buffer
-- */
-- if (ctxt->controlBufIndex > 0) {
-- memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],
-- ctxt->controlBufUsed - ctxt->controlBufIndex);
-- ctxt->controlBufUsed -= ctxt->controlBufIndex;
-- ctxt->controlBufIndex = 0;
-- }
-- size = FTP_BUF_SIZE - ctxt->controlBufUsed;
-- if (size == 0) {
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);
--#endif
-- return(0);
-- }
--
-- /*
-- * Read the amount left on teh control connection
-- */
-- if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
-- size, 0)) < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPGetMore : read %d [%d - %d]\n", len,
-- ctxt->controlBufUsed, ctxt->controlBufUsed + len);
--#endif
-- ctxt->controlBufUsed += len;
-- ctxt->controlBuf[ctxt->controlBufUsed] = 0;
--
-- return(len);
--}
--
--/**
-- * xmlNanoFTPReadResponse:
-- * @ctx: an FTP context
-- *
-- * Read the response from the FTP server after a command.
-- * Returns the code number
-- */
--static int
--xmlNanoFTPReadResponse(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char *ptr, *end;
-- int len;
-- int res = -1, cur = -1;
--
--get_more:
-- /*
-- * Assumes everything up to controlBuf[controlBufIndex] has been read
-- * and analyzed.
-- */
-- len = xmlNanoFTPGetMore(ctx);
-- if (len < 0) {
-- return(-1);
-- }
-- if ((ctxt->controlBufUsed == 0) && (len == 0)) {
-- return(-1);
-- }
-- ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
-- end = &ctxt->controlBuf[ctxt->controlBufUsed];
--
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "\n<<<\n%s\n--\n", ptr);
--#endif
-- while (ptr < end) {
-- cur = xmlNanoFTPParseResponse(ctxt, ptr, end - ptr);
-- if (cur > 0) {
-- /*
-- * Successfully scanned the control code, scratch
-- * till the end of the line, but keep the index to be
-- * able to analyze the result if needed.
-- */
-- res = cur;
-- ptr += 3;
-- ctxt->controlBufAnswer = ptr - ctxt->controlBuf;
-- while ((ptr < end) && (*ptr != '\n')) ptr++;
-- if (*ptr == '\n') ptr++;
-- if (*ptr == '\r') ptr++;
-- break;
-- }
-- while ((ptr < end) && (*ptr != '\n')) ptr++;
-- if (ptr >= end) {
-- ctxt->controlBufIndex = ctxt->controlBufUsed;
-- goto get_more;
-- }
-- if (*ptr != '\r') ptr++;
-- }
--
-- if (res < 0) goto get_more;
-- ctxt->controlBufIndex = ptr - ctxt->controlBuf;
--#ifdef DEBUG_FTP
-- ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
-- xmlGenericError(xmlGenericErrorContext, "\n---\n%s\n--\n", ptr);
--#endif
--
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, "Got %d\n", res);
--#endif
-- return(res / 100);
--}
--
--/**
-- * xmlNanoFTPGetResponse:
-- * @ctx: an FTP context
-- *
-- * Get the response from the FTP server after a command.
-- * Returns the code number
-- */
--
--int
--xmlNanoFTPGetResponse(void *ctx) {
-- int res;
--
-- res = xmlNanoFTPReadResponse(ctx);
--
-- return(res);
--}
--
--/**
-- * xmlNanoFTPCheckResponse:
-- * @ctx: an FTP context
-- *
-- * Check if there is a response from the FTP server after a command.
-- * Returns the code number, or 0
-- */
--
--int
--xmlNanoFTPCheckResponse(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- fd_set rfd;
-- struct timeval tv;
--
-- tv.tv_sec = 0;
-- tv.tv_usec = 0;
-- FD_ZERO(&rfd);
-- FD_SET(ctxt->controlFd, &rfd);
-- switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) {
-- case 0:
-- return(0);
-- case -1:
--#ifdef DEBUG_FTP
-- perror("select");
--#endif
-- return(-1);
--
-- }
--
-- return(xmlNanoFTPReadResponse(ctx));
--}
--
--/**
-- * Send the user authentification
-- */
--
--static int
--xmlNanoFTPSendUser(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[200];
-- int len;
-- int res;
--
-- if (ctxt->user == NULL)
-- sprintf(buf, "USER anonymous\r\n");
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
--#else
-- sprintf(buf, "USER %s\r\n", ctxt->user);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) return(res);
-- return(0);
--}
--
--/**
-- * Send the password authentification
-- */
--
--static int
--xmlNanoFTPSendPasswd(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[200];
-- int len;
-- int res;
--
-- if (ctxt->passwd == NULL)
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
--#else
-- sprintf(buf, "PASS libxml@%s\r\n", hostname);
--#endif
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
--#else
-- sprintf(buf, "PASS %s\r\n", ctxt->passwd);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) return(res);
-- return(0);
--}
--
--/**
-- * xmlNanoFTPQuit:
-- * @ctx: an FTP context
-- *
-- * Send a QUIT command to the server
-- *
-- * Returns -1 in case of error, 0 otherwise
-- */
--
--
--int
--xmlNanoFTPQuit(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[200];
-- int len;
-- int res;
--
-- sprintf(buf, "QUIT\r\n");
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- return(0);
--}
--
--/**
-- * xmlNanoFTPConnect:
-- * @ctx: an FTP context
-- *
-- * Tries to open a control connection
-- *
-- * Returns -1 in case of error, 0 otherwise
-- */
--
--int
--xmlNanoFTPConnect(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- struct hostent *hp;
-- int port;
-- int res;
--
-- if (ctxt == NULL)
-- return(-1);
-- if (ctxt->hostname == NULL)
-- return(-1);
--
-- /*
-- * do the blocking DNS query.
-- */
-- if (proxy)
-- hp = gethostbyname(proxy);
-- else
-- hp = gethostbyname(ctxt->hostname);
-- if (hp == NULL)
-- return(-1);
--
-- /*
-- * Prepare the socket
-- */
-- memset(&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
-- ctxt->ftpAddr.sin_family = AF_INET;
-- memcpy(&ctxt->ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
-- if (proxy) {
-- port = proxyPort;
-- } else {
-- port = ctxt->port;
-- }
-- if (port == 0)
-- port = 21;
-- ctxt->ftpAddr.sin_port = htons(port);
-- ctxt->controlFd = socket(AF_INET, SOCK_STREAM, 0);
-- if (ctxt->controlFd < 0)
-- return(-1);
--
-- /*
-- * Do the connect.
-- */
-- if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
-- sizeof(struct sockaddr_in)) < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
--
-- /*
-- * Wait for the HELLO from the server.
-- */
-- res = xmlNanoFTPGetResponse(ctxt);
-- if (res != 2) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
--
-- /*
-- * State diagram for the login operation on the FTP server
-- *
-- * Reference: RFC 959
-- *
-- * 1
-- * +---+ USER +---+------------->+---+
-- * | B |---------->| W | 2 ---->| E |
-- * +---+ +---+------ | -->+---+
-- * | | | | |
-- * 3 | | 4,5 | | |
-- * -------------- ----- | | |
-- * | | | | |
-- * | | | | |
-- * | --------- |
-- * | 1| | | |
-- * V | | | |
-- * +---+ PASS +---+ 2 | ------>+---+
-- * | |---------->| W |------------->| S |
-- * +---+ +---+ ---------->+---+
-- * | | | | |
-- * 3 | |4,5| | |
-- * -------------- -------- |
-- * | | | | |
-- * | | | | |
-- * | -----------
-- * | 1,3| | | |
-- * V | 2| | |
-- * +---+ ACCT +---+-- | ----->+---+
-- * | |---------->| W | 4,5 -------->| F |
-- * +---+ +---+------------->+---+
-- *
-- * Of course in case of using a proxy this get really nasty and is not
-- * standardized at all :-(
-- */
-- if (proxy) {
-- int len;
-- char buf[400];
--
-- if (proxyUser != NULL) {
-- /*
-- * We need proxy auth
-- */
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
--#else
-- sprintf(buf, "USER %s\r\n", proxyUser);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->controlFd);
-- ctxt->controlFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- switch (res) {
-- case 2:
-- if (proxyPasswd == NULL)
-- break;
-- case 3:
-- if (proxyPasswd != NULL)
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
--#else
-- sprintf(buf, "PASS %s\r\n", proxyPasswd);
--#endif
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n",
-- hostname);
--#else
-- sprintf(buf, "PASS libxml@%s\r\n", hostname);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->controlFd);
-- ctxt->controlFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- if (res > 3) {
-- closesocket(ctxt->controlFd);
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- break;
-- case 1:
-- break;
-- case 4:
-- case 5:
-- case -1:
-- default:
-- closesocket(ctxt->controlFd);
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- }
--
-- /*
-- * We assume we don't need more authentication to the proxy
-- * and that it succeeded :-\
-- */
-- switch (proxyType) {
-- case 0:
-- /* we will try in seqence */
-- case 1:
-- /* Using SITE command */
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
--#else
-- sprintf(buf, "SITE %s\r\n", ctxt->hostname);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- if (res == 2) {
-- /* we assume it worked :-\ 1 is error for SITE command */
-- proxyType = 1;
-- break;
-- }
-- if (proxyType == 1) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- case 2:
-- /* USER user@host command */
-- if (ctxt->user == NULL)
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
-- ctxt->hostname);
--#else
-- sprintf(buf, "USER anonymous@%s\r\n", ctxt->hostname);
--#endif
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
-- ctxt->user, ctxt->hostname);
--#else
-- sprintf(buf, "USER %s@%s\r\n",
-- ctxt->user, ctxt->hostname);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- if ((res == 1) || (res == 2)) {
-- /* we assume it worked :-\ */
-- proxyType = 2;
-- return(0);
-- }
-- if (ctxt->passwd == NULL)
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
--#else
-- sprintf(buf, "PASS libxml@%s\r\n", hostname);
--#endif
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
--#else
-- sprintf(buf, "PASS %s\r\n", ctxt->passwd);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- if ((res == 1) || (res == 2)) {
-- /* we assume it worked :-\ */
-- proxyType = 2;
-- return(0);
-- }
-- if (proxyType == 2) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- case 3:
-- /*
-- * If you need support for other Proxy authentication scheme
-- * send the code or at least the sequence in use.
-- */
-- default:
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- }
-- /*
-- * Non-proxy handling.
-- */
-- res = xmlNanoFTPSendUser(ctxt);
-- if (res < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- switch (res) {
-- case 2:
-- return(0);
-- case 3:
-- break;
-- case 1:
-- case 4:
-- case 5:
-- case -1:
-- default:
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- res = xmlNanoFTPSendPasswd(ctxt);
-- if (res < 0) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- switch (res) {
-- case 2:
-- break;
-- case 3:
-- xmlGenericError(xmlGenericErrorContext,
-- "FTP server asking for ACCNT on anonymous\n");
-- case 1:
-- case 4:
-- case 5:
-- case -1:
-- default:
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- ctxt->controlFd = -1;
-- return(-1);
-- }
--
-- return(0);
--}
--
--/**
-- * xmlNanoFTPConnectTo:
-- * @server: an FTP server name
-- * @port: the port (use 21 if 0)
-- *
-- * Tries to open a control connection to the given server/port
-- *
-- * Returns an fTP context or NULL if it failed
-- */
--
--void*
--xmlNanoFTPConnectTo(const char *server, int port) {
-- xmlNanoFTPCtxtPtr ctxt;
-- int res;
--
-- xmlNanoFTPInit();
-- if (server == NULL)
-- return(NULL);
-- ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
-- ctxt->hostname = xmlMemStrdup(server);
-- if (port != 0)
-- ctxt->port = port;
-- res = xmlNanoFTPConnect(ctxt);
-- if (res < 0) {
-- xmlNanoFTPFreeCtxt(ctxt);
-- return(NULL);
-- }
-- return(ctxt);
--}
--
--/**
-- * xmlNanoFTPCwd:
-- * @ctx: an FTP context
-- * @directory: a directory on the server
-- *
-- * Tries to change the remote directory
-- *
-- * Returns -1 incase of error, 1 if CWD worked, 0 if it failed
-- */
--
--int
--xmlNanoFTPCwd(void *ctx, char *directory) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[400];
-- int len;
-- int res;
--
-- /*
-- * Expected response code for CWD:
-- *
-- * CWD
-- * 250
-- * 500, 501, 502, 421, 530, 550
-- */
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
--#else
-- sprintf(buf, "CWD %s\r\n", directory);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) return(res);
-- res = xmlNanoFTPGetResponse(ctxt);
-- if (res == 4) {
-- return(-1);
-- }
-- if (res == 2) return(1);
-- if (res == 5) {
-- return(0);
-- }
-- return(0);
--}
--
--/**
-- * xmlNanoFTPGetConnection:
-- * @ctx: an FTP context
-- *
-- * Try to open a data connection to the server. Currently only
-- * passive mode is supported.
-- *
-- * Returns -1 incase of error, 0 otherwise
-- */
--
--int
--xmlNanoFTPGetConnection(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[200], *cur;
-- int len, i;
-- int res;
-- unsigned char ad[6], *adp, *portp;
-- unsigned int temp[6];
-- struct sockaddr_in dataAddr;
-- SOCKLEN_T dataAddrLen;
--
-- ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
-- if (ctxt->dataFd < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPGetConnection: failed to create socket\n");
-- return(-1);
-- }
-- dataAddrLen = sizeof(dataAddr);
-- memset(&dataAddr, 0, dataAddrLen);
-- dataAddr.sin_family = AF_INET;
--
-- if (ctxt->passive) {
-- sprintf(buf, "PASV\r\n");
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPReadResponse(ctx);
-- if (res != 2) {
-- if (res == 5) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-1);
-- } else {
-- /*
-- * retry with an active connection
-- */
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- ctxt->passive = 0;
-- }
-- }
-- cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
-- while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
-- if (sscanf(cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
-- &temp[3], &temp[4], &temp[5]) != 6) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Invalid answer to PASV\n");
-- if (ctxt->dataFd != -1) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- }
-- return(-1);
-- }
-- for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
-- memcpy(&dataAddr.sin_addr, &ad[0], 4);
-- memcpy(&dataAddr.sin_port, &ad[4], 2);
-- if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to create a data connection\n");
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return (-1);
-- }
-- } else {
-- getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
-- dataAddr.sin_port = 0;
-- if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to bind a port\n");
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return (-1);
-- }
-- getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
--
-- if (listen(ctxt->dataFd, 1) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Could not listen on port %d\n",
-- ntohs(dataAddr.sin_port));
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return (-1);
-- }
-- adp = (unsigned char *) &dataAddr.sin_addr;
-- portp = (unsigned char *) &dataAddr.sin_port;
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
-- adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
-- portp[0] & 0xff, portp[1] & 0xff);
--#else
-- sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",
-- adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
-- portp[0] & 0xff, portp[1] & 0xff);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
--
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPGetResponse(ctxt);
-- if (res != 2) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-1);
-- }
-- }
-- return(ctxt->dataFd);
--
--}
--
--/**
-- * xmlNanoFTPCloseConnection:
-- * @ctx: an FTP context
-- *
-- * Close the data connection from the server
-- *
-- * Returns -1 incase of error, 0 otherwise
-- */
--
--int
--xmlNanoFTPCloseConnection(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- int res;
-- fd_set rfd, efd;
-- struct timeval tv;
--
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- tv.tv_sec = 15;
-- tv.tv_usec = 0;
-- FD_ZERO(&rfd);
-- FD_SET(ctxt->controlFd, &rfd);
-- FD_ZERO(&efd);
-- FD_SET(ctxt->controlFd, &efd);
-- res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);
-- if (res < 0) {
--#ifdef DEBUG_FTP
-- perror("select");
--#endif
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- return(-1);
-- }
-- if (res == 0) {
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNanoFTPCloseConnection: timeout\n");
--#endif
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- } else {
-- res = xmlNanoFTPGetResponse(ctxt);
-- if (res != 2) {
-- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-- return(-1);
-- }
-- }
-- return(0);
--}
--
--/**
-- * xmlNanoFTPParseList:
-- * @list: some data listing received from the server
-- * @callback: the user callback
-- * @userData: the user callback data
-- *
-- * Parse at most one entry from the listing.
-- *
-- * Returns -1 incase of error, the lenght of data parsed otherwise
-- */
--
--static int
--xmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) {
-- const char *cur = list;
-- char filename[151];
-- char attrib[11];
-- char owner[11];
-- char group[11];
-- char month[4];
-- int year = 0;
-- int minute = 0;
-- int hour = 0;
-- int day = 0;
-- unsigned long size = 0;
-- int links = 0;
-- int i;
--
-- if (!strncmp(cur, "total", 5)) {
-- cur += 5;
-- while (*cur == ' ') cur++;
-- while ((*cur >= '0') && (*cur <= '9'))
-- links = (links * 10) + (*cur++ - '0');
-- while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
-- cur++;
-- return(cur - list);
-- } else if (*list == '+') {
-- return(0);
-- } else {
-- while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
-- cur++;
-- if (*cur == 0) return(0);
-- i = 0;
-- while (*cur != ' ') {
-- if (i < 10)
-- attrib[i++] = *cur;
-- cur++;
-- if (*cur == 0) return(0);
-- }
-- attrib[10] = 0;
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- while ((*cur >= '0') && (*cur <= '9'))
-- links = (links * 10) + (*cur++ - '0');
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- i = 0;
-- while (*cur != ' ') {
-- if (i < 10)
-- owner[i++] = *cur;
-- cur++;
-- if (*cur == 0) return(0);
-- }
-- owner[i] = 0;
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- i = 0;
-- while (*cur != ' ') {
-- if (i < 10)
-- group[i++] = *cur;
-- cur++;
-- if (*cur == 0) return(0);
-- }
-- group[i] = 0;
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- while ((*cur >= '0') && (*cur <= '9'))
-- size = (size * 10) + (*cur++ - '0');
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- i = 0;
-- while (*cur != ' ') {
-- if (i < 3)
-- month[i++] = *cur;
-- cur++;
-- if (*cur == 0) return(0);
-- }
-- month[i] = 0;
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- while ((*cur >= '0') && (*cur <= '9'))
-- day = (day * 10) + (*cur++ - '0');
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- if ((cur[1] == 0) || (cur[2] == 0)) return(0);
-- if ((cur[1] == ':') || (cur[2] == ':')) {
-- while ((*cur >= '0') && (*cur <= '9'))
-- hour = (hour * 10) + (*cur++ - '0');
-- if (*cur == ':') cur++;
-- while ((*cur >= '0') && (*cur <= '9'))
-- minute = (minute * 10) + (*cur++ - '0');
-- } else {
-- while ((*cur >= '0') && (*cur <= '9'))
-- year = (year * 10) + (*cur++ - '0');
-- }
-- while (*cur == ' ') cur++;
-- if (*cur == 0) return(0);
-- i = 0;
-- while ((*cur != '\n') && (*cur != '\r')) {
-- if (i < 150)
-- filename[i++] = *cur;
-- cur++;
-- if (*cur == 0) return(0);
-- }
-- filename[i] = 0;
-- if ((*cur != '\n') && (*cur != '\r'))
-- return(0);
-- while ((*cur == '\n') || (*cur == '\r'))
-- cur++;
-- }
-- if (callback != NULL) {
-- callback(userData, filename, attrib, owner, group, size, links,
-- year, month, day, hour, minute);
-- }
-- return(cur - list);
--}
--
--/**
-- * xmlNanoFTPList:
-- * @ctx: an FTP context
-- * @callback: the user callback
-- * @userData: the user callback data
-- * @filename: optional files to list
-- *
-- * Do a listing on the server. All files info are passed back
-- * in the callbacks.
-- *
-- * Returns -1 incase of error, 0 otherwise
-- */
--
--int
--xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
-- char *filename) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[4096 + 1];
-- int len, res;
-- int index = 0, base;
-- fd_set rfd, efd;
-- struct timeval tv;
--
-- if (filename == NULL) {
-- if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
-- return(-1);
-- ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-- if (ctxt->dataFd == -1)
-- return(-1);
-- sprintf(buf, "LIST -L\r\n");
-- } else {
-- if (filename[0] != '/') {
-- if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
-- return(-1);
-- }
-- ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-- if (ctxt->dataFd == -1)
-- return(-1);
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
--#else
-- sprintf(buf, "LIST -L %s\r\n", filename);
--#endif
-- }
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPReadResponse(ctxt);
-- if (res != 1) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-res);
-- }
--
-- do {
-- tv.tv_sec = 1;
-- tv.tv_usec = 0;
-- FD_ZERO(&rfd);
-- FD_SET(ctxt->dataFd, &rfd);
-- FD_ZERO(&efd);
-- FD_SET(ctxt->dataFd, &efd);
-- res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv);
-- if (res < 0) {
--#ifdef DEBUG_FTP
-- perror("select");
--#endif
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-1);
-- }
-- if (res == 0) {
-- res = xmlNanoFTPCheckResponse(ctxt);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- ctxt->dataFd = -1;
-- return(-1);
-- }
-- if (res == 2) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(0);
-- }
--
-- continue;
-- }
--
-- if ((len = recv(ctxt->dataFd, &buf[index], sizeof(buf) - (index + 1), 0)) < 0) {
--#ifdef DEBUG_FTP
-- perror("recv");
--#endif
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- ctxt->dataFd = -1;
-- return(-1);
-- }
--#ifdef DEBUG_FTP
-- write(1, &buf[index], len);
--#endif
-- index += len;
-- buf[index] = 0;
-- base = 0;
-- do {
-- res = xmlNanoFTPParseList(&buf[base], callback, userData);
-- base += res;
-- } while (res > 0);
--
-- memmove(&buf[0], &buf[base], index - base);
-- index -= base;
-- } while (len != 0);
-- xmlNanoFTPCloseConnection(ctxt);
-- return(0);
--}
--
--/**
-- * xmlNanoFTPGetSocket:
-- * @ctx: an FTP context
-- * @filename: the file to retrieve (or NULL if path is in context).
-- *
-- * Initiate fetch of the given file from the server.
-- *
-- * Returns the socket for the data connection, or <0 in case of error
-- */
--
--
--int
--xmlNanoFTPGetSocket(void *ctx, const char *filename) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[300];
-- int res, len;
-- if ((filename == NULL) && (ctxt->path == NULL))
-- return(-1);
-- ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-- if (ctxt->dataFd == -1)
-- return(-1);
--
-- sprintf(buf, "TYPE I\r\n");
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPReadResponse(ctxt);
-- if (res != 2) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-res);
-- }
-- if (filename == NULL)
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
--#else
-- sprintf(buf, "RETR %s\r\n", ctxt->path);
--#endif
-- else
--#ifdef HAVE_SNPRINTF
-- snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
--#else
-- sprintf(buf, "RETR %s\r\n", filename);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- len = strlen(buf);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, buf);
--#endif
-- res = send(ctxt->controlFd, buf, len, 0);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(res);
-- }
-- res = xmlNanoFTPReadResponse(ctxt);
-- if (res != 1) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-res);
-- }
-- return(ctxt->dataFd);
--}
--
--/**
-- * xmlNanoFTPGet:
-- * @ctx: an FTP context
-- * @callback: the user callback
-- * @userData: the user callback data
-- * @filename: the file to retrieve
-- *
-- * Fetch the given file from the server. All data are passed back
-- * in the callbacks. The last callback has a size of 0 block.
-- *
-- * Returns -1 incase of error, 0 otherwise
-- */
--
--int
--xmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
-- const char *filename) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-- char buf[4096];
-- int len = 0, res;
-- fd_set rfd;
-- struct timeval tv;
--
-- if ((filename == NULL) && (ctxt->path == NULL))
-- return(-1);
-- if (callback == NULL)
-- return(-1);
-- if (xmlNanoFTPGetSocket(ctxt, filename) < 0)
-- return(-1);
--
-- do {
-- tv.tv_sec = 1;
-- tv.tv_usec = 0;
-- FD_ZERO(&rfd);
-- FD_SET(ctxt->dataFd, &rfd);
-- res = select(ctxt->dataFd + 1, &rfd, NULL, NULL, &tv);
-- if (res < 0) {
--#ifdef DEBUG_FTP
-- perror("select");
--#endif
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-1);
-- }
-- if (res == 0) {
-- res = xmlNanoFTPCheckResponse(ctxt);
-- if (res < 0) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- ctxt->dataFd = -1;
-- return(-1);
-- }
-- if (res == 2) {
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(0);
-- }
--
-- continue;
-- }
-- if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
-- callback(userData, buf, len);
-- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-- return(-1);
-- }
-- callback(userData, buf, len);
-- } while (len != 0);
--
-- return(xmlNanoFTPCloseConnection(ctxt));
--}
--
--/**
-- * xmlNanoFTPRead:
-- * @ctx: the FTP context
-- * @dest: a buffer
-- * @len: the buffer length
-- *
-- * This function tries to read @len bytes from the existing FTP connection
-- * and saves them in @dest. This is a blocking call.
-- *
-- * Returns the number of byte read. 0 is an indication of an end of connection.
-- * -1 indicates a parameter error.
-- */
--int
--xmlNanoFTPRead(void *ctx, void *dest, int len) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
--
-- if (ctx == NULL) return(-1);
-- if (ctxt->dataFd < 0) return(0);
-- if (dest == NULL) return(-1);
-- if (len <= 0) return(0);
--
-- len = recv(ctxt->dataFd, dest, len, 0);
--#ifdef DEBUG_FTP
-- xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
--#endif
-- if (len <= 0) {
-- xmlNanoFTPCloseConnection(ctxt);
-- }
-- return(len);
--}
--
--/**
-- * xmlNanoFTPOpen:
-- * @URL: the URL to the resource
-- *
-- * Start to fetch the given ftp:// resource
-- *
-- * Returns an FTP context, or NULL
-- */
--
--void*
--xmlNanoFTPOpen(const char *URL) {
-- xmlNanoFTPCtxtPtr ctxt;
-- int sock;
--
-- xmlNanoFTPInit();
-- if (URL == NULL) return(NULL);
-- if (strncmp("ftp://", URL, 6)) return(NULL);
--
-- ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(URL);
-- if (ctxt == NULL) return(NULL);
-- if (xmlNanoFTPConnect(ctxt) < 0) {
-- xmlNanoFTPFreeCtxt(ctxt);
-- return(NULL);
-- }
-- sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
-- if (sock < 0) {
-- xmlNanoFTPFreeCtxt(ctxt);
-- return(NULL);
-- }
-- return(ctxt);
--}
--
--/**
-- * xmlNanoFTPClose:
-- * @ctx: an FTP context
-- *
-- * Close the connection and both control and transport
-- *
-- * Returns -1 incase of error, 0 otherwise
-- */
--
--int
--xmlNanoFTPClose(void *ctx) {
-- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
--
-- if (ctxt == NULL)
-- return(-1);
--
-- if (ctxt->dataFd >= 0) {
-- closesocket(ctxt->dataFd);
-- ctxt->dataFd = -1;
-- }
-- if (ctxt->controlFd >= 0) {
-- xmlNanoFTPQuit(ctxt);
-- closesocket(ctxt->controlFd);
-- ctxt->controlFd = -1;
-- }
-- xmlNanoFTPFreeCtxt(ctxt);
-- return(0);
--}
--
--#ifdef STANDALONE
--/************************************************************************
-- * *
-- * Basic test in Standalone mode *
-- * *
-- ************************************************************************/
--void ftpList(void *userData, const char *filename, const char* attrib,
-- const char *owner, const char *group, unsigned long size, int links,
-- int year, const char *month, int day, int hour, int minute) {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s %s %s %ld %s\n", attrib, owner, group, size, filename);
--}
--void ftpData(void *userData, const char *data, int len) {
-- if (userData == NULL) return;
-- if (len <= 0) {
-- fclose(userData);
-- return;
-- }
-- fwrite(data, len, 1, userData);
--}
--
--int main(int argc, char **argv) {
-- void *ctxt;
-- FILE *output;
-- char *tstfile = NULL;
--
-- xmlNanoFTPInit();
-- if (argc > 1) {
-- ctxt = xmlNanoFTPNewCtxt(argv[1]);
-- if (xmlNanoFTPConnect(ctxt) < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Couldn't connect to %s\n", argv[1]);
-- exit(1);
-- }
-- if (argc > 2)
-- tstfile = argv[2];
-- } else
-- ctxt = xmlNanoFTPConnectTo("localhost", 0);
-- if (ctxt == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Couldn't connect to localhost\n");
-- exit(1);
-- }
-- xmlNanoFTPList(ctxt, ftpList, NULL, tstfile);
-- output = fopen("/tmp/tstdata", "w");
-- if (output != NULL) {
-- if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "Failed to get file\n");
--
-- }
-- xmlNanoFTPClose(ctxt);
-- xmlMemoryDump();
-- exit(0);
--}
--#endif /* STANDALONE */
--#else /* !LIBXML_FTP_ENABLED */
--#ifdef STANDALONE
--#include <stdio.h>
--int main(int argc, char **argv) {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s : FTP support not compiled in\n", argv[0]);
-- return(0);
--}
--#endif /* STANDALONE */
--#endif /* LIBXML_FTP_ENABLED */
-diff -Nru libxml2-2.3.0/nanohttp.c libxml2-2.3.0.new/nanohttp.c
---- libxml2-2.3.0/nanohttp.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/nanohttp.c Thu Jan 1 01:00:00 1970
-@@ -1,1202 +0,0 @@
--/*
-- * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets.
-- * focuses on size, streamability, reentrancy and portability
-- *
-- * This is clearly not a general purpose HTTP implementation
-- * If you look for one, check:
-- * http://www.w3.org/Library/
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--/* TODO add compression support, Send the Accept- , and decompress on the
-- fly with ZLIB if found at compile-time */
--
--#ifdef WIN32
--#define INCLUDE_WINSOCK
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <libxml/xmlversion.h>
--
--#ifdef LIBXML_HTTP_ENABLED
--#include <stdio.h>
--#include <string.h>
--
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_SYS_SOCKET_H
--#include <sys/socket.h>
--#endif
--#ifdef HAVE_NETINET_IN_H
--#include <netinet/in.h>
--#endif
--#ifdef HAVE_ARPA_INET_H
--#include <arpa/inet.h>
--#endif
--#ifdef HAVE_NETDB_H
--#include <netdb.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_ERRNO_H
--#include <errno.h>
--#endif
--#ifdef HAVE_SYS_TIME_H
--#include <sys/time.h>
--#endif
--#ifdef HAVE_SYS_SELECT_H
--#include <sys/select.h>
--#endif
--#ifdef HAVE_STRINGS_H
--#include <strings.h>
--#endif
--#ifdef SUPPORT_IP6
--#include <resolv.h>
--#endif
--
--#ifdef VMS
--#include <stropts>
--#define SOCKLEN_T unsigned int
--#define SOCKET int
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/parser.h> /* for xmlStr(n)casecmp() */
--#include <libxml/nanohttp.h>
--
--/**
-- * A couple portability macros
-- */
--#ifndef _WINSOCKAPI_
--#define closesocket(s) close(s)
--#define SOCKET int
--#endif
--
--#ifdef STANDALONE
--#define DEBUG_HTTP
--#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n)
--#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b)
--#endif
--
--#define XML_NANO_HTTP_MAX_REDIR 10
--
--#define XML_NANO_HTTP_CHUNK 4096
--
--#define XML_NANO_HTTP_CLOSED 0
--#define XML_NANO_HTTP_WRITE 1
--#define XML_NANO_HTTP_READ 2
--#define XML_NANO_HTTP_NONE 4
--
--typedef struct xmlNanoHTTPCtxt {
-- char *protocol; /* the protocol name */
-- char *hostname; /* the host name */
-- int port; /* the port */
-- char *path; /* the path within the URL */
-- SOCKET fd; /* the file descriptor for the socket */
-- int state; /* WRITE / READ / CLOSED */
-- char *out; /* buffer sent (zero terminated) */
-- char *outptr; /* index within the buffer sent */
-- char *in; /* the receiving buffer */
-- char *content; /* the start of the content */
-- char *inptr; /* the next byte to read from network */
-- char *inrptr; /* the next byte to give back to the client */
-- int inlen; /* len of the input buffer */
-- int last; /* return code for last operation */
-- int returnValue; /* the protocol return value */
-- char *contentType; /* the MIME type for the input */
-- char *location; /* the new URL in case of redirect */
-- char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */
--} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr;
--
--static int initialized = 0;
--static char *proxy = NULL; /* the proxy name if any */
--static int proxyPort; /* the proxy port if any */
--static unsigned int timeout = 60;/* the select() timeout in seconds */
--
--/**
-- * A portability function
-- */
--int socket_errno(void) {
--#ifdef _WINSOCKAPI_
-- return(WSAGetLastError());
--#else
-- return(errno);
--#endif
--}
--
--/**
-- * xmlNanoHTTPInit:
-- *
-- * Initialize the HTTP protocol layer.
-- * Currently it just checks for proxy informations
-- */
--
--void
--xmlNanoHTTPInit(void) {
-- const char *env;
--#ifdef _WINSOCKAPI_
-- WSADATA wsaData;
--#endif
--
-- if (initialized)
-- return;
--
--#ifdef _WINSOCKAPI_
-- if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
-- return;
--#endif
--
-- if (proxy == NULL) {
-- proxyPort = 80;
-- env = getenv("no_proxy");
-- if (env != NULL)
-- goto done;
-- env = getenv("http_proxy");
-- if (env != NULL) {
-- xmlNanoHTTPScanProxy(env);
-- goto done;
-- }
-- env = getenv("HTTP_PROXY");
-- if (env != NULL) {
-- xmlNanoHTTPScanProxy(env);
-- goto done;
-- }
-- }
--done:
-- initialized = 1;
--}
--
--/**
-- * xmlNanoHTTPClenup:
-- *
-- * Cleanup the HTTP protocol layer.
-- */
--
--void
--xmlNanoHTTPCleanup(void) {
-- if (proxy != NULL)
-- xmlFree(proxy);
--#ifdef _WINSOCKAPI_
-- if (initialized)
-- WSACleanup();
--#endif
-- initialized = 0;
-- return;
--}
--
--/**
-- * xmlNanoHTTPTimeout:
-- * @delay: the delay in seconds
-- *
-- * Set the HTTP timeout, (default is 60secs). 0 means immediate
-- * return, while -1 infinite.
-- */
--
--void
--xmlNanoHTTPTimeout(int delay) {
-- timeout = (unsigned int) delay;
--}
--
--/**
-- * xmlNanoHTTPScanURL:
-- * @ctxt: an HTTP context
-- * @URL: The URL used to initialize the context
-- *
-- * (Re)Initialize an HTTP context by parsing the URL and finding
-- * the protocol host port and path it indicates.
-- */
--
--static void
--xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) {
-- const char *cur = URL;
-- char buf[4096];
-- int index = 0;
-- int port = 0;
--
-- if (ctxt->protocol != NULL) {
-- xmlFree(ctxt->protocol);
-- ctxt->protocol = NULL;
-- }
-- if (ctxt->hostname != NULL) {
-- xmlFree(ctxt->hostname);
-- ctxt->hostname = NULL;
-- }
-- if (ctxt->path != NULL) {
-- xmlFree(ctxt->path);
-- ctxt->path = NULL;
-- }
-- if (URL == NULL) return;
-- buf[index] = 0;
-- while (*cur != 0) {
-- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-- buf[index] = 0;
-- ctxt->protocol = xmlMemStrdup(buf);
-- index = 0;
-- cur += 3;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0) return;
--
-- buf[index] = 0;
-- while (1) {
-- if (cur[0] == ':') {
-- buf[index] = 0;
-- ctxt->hostname = xmlMemStrdup(buf);
-- index = 0;
-- cur += 1;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- port *= 10;
-- port += *cur - '0';
-- cur++;
-- }
-- if (port != 0) ctxt->port = port;
-- while ((cur[0] != '/') && (*cur != 0))
-- cur++;
-- break;
-- }
-- if ((*cur == '/') || (*cur == 0)) {
-- buf[index] = 0;
-- ctxt->hostname = xmlMemStrdup(buf);
-- index = 0;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0)
-- ctxt->path = xmlMemStrdup("/");
-- else {
-- index = 0;
-- buf[index] = 0;
-- while (*cur != 0)
-- buf[index++] = *cur++;
-- buf[index] = 0;
-- ctxt->path = xmlMemStrdup(buf);
-- }
--}
--
--/**
-- * xmlNanoHTTPScanProxy:
-- * @URL: The proxy URL used to initialize the proxy context
-- *
-- * (Re)Initialize the HTTP Proxy context by parsing the URL and finding
-- * the protocol host port it indicates.
-- * Should be like http://myproxy/ or http://myproxy:3128/
-- * A NULL URL cleans up proxy informations.
-- */
--
--void
--xmlNanoHTTPScanProxy(const char *URL) {
-- const char *cur = URL;
-- char buf[4096];
-- int index = 0;
-- int port = 0;
--
-- if (proxy != NULL) {
-- xmlFree(proxy);
-- proxy = NULL;
-- }
-- if (proxyPort != 0) {
-- proxyPort = 0;
-- }
--#ifdef DEBUG_HTTP
-- if (URL == NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "Removing HTTP proxy info\n");
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "Using HTTP proxy %s\n", URL);
--#endif
-- if (URL == NULL) return;
-- buf[index] = 0;
-- while (*cur != 0) {
-- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
-- buf[index] = 0;
-- index = 0;
-- cur += 3;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
-- if (*cur == 0) return;
--
-- buf[index] = 0;
-- while (1) {
-- if (cur[0] == ':') {
-- buf[index] = 0;
-- proxy = xmlMemStrdup(buf);
-- index = 0;
-- cur += 1;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- port *= 10;
-- port += *cur - '0';
-- cur++;
-- }
-- if (port != 0) proxyPort = port;
-- while ((cur[0] != '/') && (*cur != 0))
-- cur++;
-- break;
-- }
-- if ((*cur == '/') || (*cur == 0)) {
-- buf[index] = 0;
-- proxy = xmlMemStrdup(buf);
-- index = 0;
-- break;
-- }
-- buf[index++] = *cur++;
-- }
--}
--
--/**
-- * xmlNanoHTTPNewCtxt:
-- * @URL: The URL used to initialize the context
-- *
-- * Allocate and initialize a new HTTP context.
-- *
-- * Returns an HTTP context or NULL in case of error.
-- */
--
--static xmlNanoHTTPCtxtPtr
--xmlNanoHTTPNewCtxt(const char *URL) {
-- xmlNanoHTTPCtxtPtr ret;
--
-- ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt));
-- if (ret == NULL) return(NULL);
--
-- memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
-- ret->port = 80;
-- ret->returnValue = 0;
-- ret->fd = -1;
--
-- xmlNanoHTTPScanURL(ret, URL);
--
-- return(ret);
--}
--
--/**
-- * xmlNanoHTTPFreeCtxt:
-- * @ctxt: an HTTP context
-- *
-- * Frees the context after closing the connection.
-- */
--
--static void
--xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) {
-- if (ctxt == NULL) return;
-- if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
-- if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
-- if (ctxt->path != NULL) xmlFree(ctxt->path);
-- if (ctxt->out != NULL) xmlFree(ctxt->out);
-- if (ctxt->in != NULL) xmlFree(ctxt->in);
-- if (ctxt->contentType != NULL) xmlFree(ctxt->contentType);
-- if (ctxt->location != NULL) xmlFree(ctxt->location);
-- if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader);
-- ctxt->state = XML_NANO_HTTP_NONE;
-- if (ctxt->fd >= 0) closesocket(ctxt->fd);
-- ctxt->fd = -1;
-- xmlFree(ctxt);
--}
--
--/**
-- * xmlNanoHTTPSend:
-- * @ctxt: an HTTP context
-- *
-- * Send the input needed to initiate the processing on the server side
-- */
--
--static void
--xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt) {
-- if (ctxt->state & XML_NANO_HTTP_WRITE) {
-- int total_sent = 0;
-- while (total_sent <strlen(ctxt->outptr)) {
-- int nsent = send(ctxt->fd, ctxt->outptr+total_sent,
-- strlen(ctxt->outptr)-total_sent, 0);
-- if (nsent>0)
-- total_sent += nsent;
--}
--
-- ctxt->last = total_sent;
-- }
--}
--
--/**
-- * xmlNanoHTTPRecv:
-- * @ctxt: an HTTP context
-- *
-- * Read information coming from the HTTP connection.
-- * This is a blocking call (but it blocks in select(), not read()).
-- *
-- * Returns the number of byte read or -1 in case of error.
-- */
--
--static int
--xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) {
-- fd_set rfd;
-- struct timeval tv;
--
--
-- while (ctxt->state & XML_NANO_HTTP_READ) {
-- if (ctxt->in == NULL) {
-- ctxt->in = (char *) xmlMalloc(65000 * sizeof(char));
-- if (ctxt->in == NULL) {
-- ctxt->last = -1;
-- return(-1);
-- }
-- ctxt->inlen = 65000;
-- ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
-- }
-- if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
-- int delta = ctxt->inrptr - ctxt->in;
-- int len = ctxt->inptr - ctxt->inrptr;
--
-- memmove(ctxt->in, ctxt->inrptr, len);
-- ctxt->inrptr -= delta;
-- ctxt->content -= delta;
-- ctxt->inptr -= delta;
-- }
-- if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
-- int d_inptr = ctxt->inptr - ctxt->in;
-- int d_content = ctxt->content - ctxt->in;
-- int d_inrptr = ctxt->inrptr - ctxt->in;
--
-- ctxt->inlen *= 2;
-- ctxt->in = (char *) xmlRealloc(ctxt->in, ctxt->inlen);
-- if (ctxt->in == NULL) {
-- ctxt->last = -1;
-- return(-1);
-- }
-- ctxt->inptr = ctxt->in + d_inptr;
-- ctxt->content = ctxt->in + d_content;
-- ctxt->inrptr = ctxt->in + d_inrptr;
-- }
-- ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
-- if (ctxt->last > 0) {
-- ctxt->inptr += ctxt->last;
-- return(ctxt->last);
-- }
-- if (ctxt->last == 0) {
-- return(0);
-- }
-- if (ctxt->last == -1) {
-- switch (socket_errno()) {
-- case EINPROGRESS:
-- case EWOULDBLOCK:
--#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
-- case EAGAIN:
--#endif
-- break;
-- default:
-- return(0);
-- }
-- }
--
-- tv.tv_sec = timeout;
-- tv.tv_usec = 0;
-- FD_ZERO(&rfd);
-- FD_SET(ctxt->fd, &rfd);
--
-- if (select(ctxt->fd+1, &rfd, NULL, NULL, &tv)<1)
-- return(0);
-- }
-- return(0);
--}
--
--/**
-- * xmlNanoHTTPReadLine:
-- * @ctxt: an HTTP context
-- *
-- * Read one line in the HTTP server output, usually for extracting
-- * the HTTP protocol informations from the answer header.
-- *
-- * Returns a newly allocated string with a copy of the line, or NULL
-- * which indicate the end of the input.
-- */
--
--static char *
--xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) {
-- char buf[4096];
-- char *bp = buf;
--
-- while (bp - buf < 4095) {
-- if (ctxt->inrptr == ctxt->inptr) {
-- if (xmlNanoHTTPRecv(ctxt) == 0) {
-- if (bp == buf)
-- return(NULL);
-- else
-- *bp = 0;
-- return(xmlMemStrdup(buf));
-- }
-- }
-- *bp = *ctxt->inrptr++;
-- if (*bp == '\n') {
-- *bp = 0;
-- return(xmlMemStrdup(buf));
-- }
-- if (*bp != '\r')
-- bp++;
-- }
-- buf[4095] = 0;
-- return(xmlMemStrdup(buf));
--}
--
--
--/**
-- * xmlNanoHTTPScanAnswer:
-- * @ctxt: an HTTP context
-- * @line: an HTTP header line
-- *
-- * Try to extract useful informations from the server answer.
-- * We currently parse and process:
-- * - The HTTP revision/ return code
-- * - The Content-Type
-- * - The Location for redirrect processing.
-- *
-- * Returns -1 in case of failure, the file descriptor number otherwise
-- */
--
--static void
--xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) {
-- const char *cur = line;
--
-- if (line == NULL) return;
--
-- if (!strncmp(line, "HTTP/", 5)) {
-- int version = 0;
-- int ret = 0;
--
-- cur += 5;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- version *= 10;
-- version += *cur - '0';
-- cur++;
-- }
-- if (*cur == '.') {
-- cur++;
-- if ((*cur >= '0') && (*cur <= '9')) {
-- version *= 10;
-- version += *cur - '0';
-- cur++;
-- }
-- while ((*cur >= '0') && (*cur <= '9'))
-- cur++;
-- } else
-- version *= 10;
-- if ((*cur != ' ') && (*cur != '\t')) return;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- if ((*cur < '0') || (*cur > '9')) return;
-- while ((*cur >= '0') && (*cur <= '9')) {
-- ret *= 10;
-- ret += *cur - '0';
-- cur++;
-- }
-- if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;
-- ctxt->returnValue = ret;
-- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {
-- cur += 13;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- if (ctxt->contentType != NULL)
-- xmlFree(ctxt->contentType);
-- ctxt->contentType = xmlMemStrdup(cur);
-- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) {
-- cur += 12;
-- if (ctxt->contentType != NULL) return;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- ctxt->contentType = xmlMemStrdup(cur);
-- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) {
-- cur += 9;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- if (ctxt->location != NULL)
-- xmlFree(ctxt->location);
-- ctxt->location = xmlMemStrdup(cur);
-- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) {
-- cur += 17;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- if (ctxt->authHeader != NULL)
-- xmlFree(ctxt->authHeader);
-- ctxt->authHeader = xmlMemStrdup(cur);
-- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) {
-- cur += 19;
-- while ((*cur == ' ') || (*cur == '\t')) cur++;
-- if (ctxt->authHeader != NULL)
-- xmlFree(ctxt->authHeader);
-- ctxt->authHeader = xmlMemStrdup(cur);
-- }
--}
--
--/**
-- * xmlNanoHTTPConnectAttempt:
-- * @ia: an internet adress structure
-- * @port: the port number
-- *
-- * Attempt a connection to the given IP:port endpoint. It forces
-- * non-blocking semantic on the socket, and allow 60 seconds for
-- * the host to answer.
-- *
-- * Returns -1 in case of failure, the file descriptor number otherwise
-- */
--
--static int
--xmlNanoHTTPConnectAttempt(struct sockaddr *addr, int port)
--{
-- SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-- fd_set wfd;
-- struct timeval tv;
-- int status;
--
-- if (s==-1) {
--#ifdef DEBUG_HTTP
-- perror("socket");
--#endif
-- return(-1);
-- }
--
--#ifdef _WINSOCKAPI_
-- {
-- u_long one = 1;
--
-- status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
-- }
--#else /* _WINSOCKAPI_ */
--#if defined(VMS)
-- {
-- int enable = 1;
-- status = ioctl(s, FIONBIO, &enable);
-- }
--#else /* VMS */
-- if ((status = fcntl(s, F_GETFL, 0)) != -1) {
--#ifdef O_NONBLOCK
-- status |= O_NONBLOCK;
--#else /* O_NONBLOCK */
--#ifdef F_NDELAY
-- status |= F_NDELAY;
--#endif /* F_NDELAY */
--#endif /* !O_NONBLOCK */
-- status = fcntl(s, F_SETFL, status);
-- }
-- if (status < 0) {
--#ifdef DEBUG_HTTP
-- perror("nonblocking");
--#endif
-- closesocket(s);
-- return(-1);
-- }
--#endif /* !VMS */
--#endif /* !_WINSOCKAPI_ */
--
--
-- if ((connect(s, addr, sizeof(*addr))==-1)) {
-- switch (socket_errno()) {
-- case EINPROGRESS:
-- case EWOULDBLOCK:
-- break;
-- default:
-- perror("connect");
-- closesocket(s);
-- return(-1);
-- }
-- }
--
-- tv.tv_sec = timeout;
-- tv.tv_usec = 0;
--
-- FD_ZERO(&wfd);
-- FD_SET(s, &wfd);
--
-- switch(select(s+1, NULL, &wfd, NULL, &tv))
-- {
-- case 0:
-- /* Time out */
-- closesocket(s);
-- return(-1);
-- case -1:
-- /* Ermm.. ?? */
--#ifdef DEBUG_HTTP
-- perror("select");
--#endif
-- closesocket(s);
-- return(-1);
-- }
--
-- if ( FD_ISSET(s, &wfd) ) {
-- SOCKLEN_T len;
-- len = sizeof(status);
-- if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {
-- /* Solaris error code */
-- return (-1);
-- }
-- if ( status ) {
-- closesocket(s);
-- errno = status;
-- return (-1);
-- }
-- } else {
-- /* pbm */
-- return (-1);
-- }
--
-- return(s);
--}
--
--/**
-- * xmlNanoHTTPConnectHost:
-- * @host: the host name
-- * @port: the port number
-- *
-- * Attempt a connection to the given host:port endpoint. It tries
-- * the multiple IP provided by the DNS if available.
-- *
-- * Returns -1 in case of failure, the file descriptor number otherwise
-- */
--
--static int
--xmlNanoHTTPConnectHost(const char *host, int port)
--{
-- struct hostent *h;
-- struct sockaddr *addr;
-- struct in_addr ia;
-- struct sockaddr_in sin;
--#ifdef SUPPORT_IP6
-- struct in6_addr ia6;
-- struct sockaddr_in6 sin6;
--#endif
-- int i;
-- int s;
--
--#if defined(SUPPORT_IP6) && defined(RES_USE_INET6)
-- if (!(_res.options & RES_INIT))
-- res_init();
-- _res.options |= RES_USE_INET6;
--#endif
-- h=gethostbyname(host);
-- if (h==NULL)
-- {
--#ifdef DEBUG_HTTP
-- xmlGenericError(xmlGenericErrorContext,"unable to resolve '%s'.\n", host);
--#endif
-- return(-1);
-- }
--
-- for(i=0; h->h_addr_list[i]; i++)
-- {
-- if (h->h_addrtype == AF_INET) {
-- /* A records (IPv4) */
-- memcpy(&ia, h->h_addr_list[i], h->h_length);
-- sin.sin_family = h->h_addrtype;
-- sin.sin_addr = ia;
-- sin.sin_port = htons(port);
-- addr = (struct sockaddr *)&sin;
--#ifdef SUPPORT_IP6
-- } else if (h->h_addrtype == AF_INET6) {
-- /* AAAA records (IPv6) */
-- memcpy(&ia6, h->h_addr_list[i], h->h_length);
-- sin6.sin_family = h->h_addrtype;
-- sin6.sin_addr = ia6;
-- sin6.sin_port = htons(port);
-- addr = (struct sockaddr *)&sin6;
--#endif
-- } else
-- break; /* for */
--
-- s = xmlNanoHTTPConnectAttempt(addr, port);
-- if (s != -1)
-- return(s);
-- }
--
--#ifdef DEBUG_HTTP
-- xmlGenericError(xmlGenericErrorContext,
-- "unable to connect to '%s'.\n", host);
--#endif
-- return(-1);
--}
--
--
--/**
-- * xmlNanoHTTPOpen:
-- * @URL: The URL to load
-- * @contentType: if available the Content-Type information will be
-- * returned at that location
-- *
-- * This function try to open a connection to the indicated resource
-- * via HTTP GET.
-- *
-- * Returns NULL in case of failure, otherwise a request handler.
-- * The contentType, if provided must be freed by the caller
-- */
--
--void*
--xmlNanoHTTPOpen(const char *URL, char **contentType) {
-- if (contentType != NULL) *contentType = NULL;
-- return xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL);
--}
--
--/**
-- * xmlNanoHTTPRead:
-- * @ctx: the HTTP context
-- * @dest: a buffer
-- * @len: the buffer length
-- *
-- * This function tries to read @len bytes from the existing HTTP connection
-- * and saves them in @dest. This is a blocking call.
-- *
-- * Returns the number of byte read. 0 is an indication of an end of connection.
-- * -1 indicates a parameter error.
-- */
--int
--xmlNanoHTTPRead(void *ctx, void *dest, int len) {
-- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
--
-- if (ctx == NULL) return(-1);
-- if (dest == NULL) return(-1);
-- if (len <= 0) return(0);
--
-- while (ctxt->inptr - ctxt->inrptr < len) {
-- if (xmlNanoHTTPRecv(ctxt) == 0) break;
-- }
-- if (ctxt->inptr - ctxt->inrptr < len)
-- len = ctxt->inptr - ctxt->inrptr;
-- memcpy(dest, ctxt->inrptr, len);
-- ctxt->inrptr += len;
-- return(len);
--}
--
--/**
-- * xmlNanoHTTPClose:
-- * @ctx: the HTTP context
-- *
-- * This function closes an HTTP context, it ends up the connection and
-- * free all data related to it.
-- */
--void
--xmlNanoHTTPClose(void *ctx) {
-- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
--
-- if (ctx == NULL) return;
--
-- xmlNanoHTTPFreeCtxt(ctxt);
--}
--
--/**
-- * xmlNanoHTTPMethod:
-- * @URL: The URL to load
-- * @method: the HTTP method to use
-- * @input: the input string if any
-- * @contentType: the Content-Type information IN and OUT
-- * @headers: the extra headers
-- *
-- * This function try to open a connection to the indicated resource
-- * via HTTP using the given @method, adding the given extra headers
-- * and the input buffer for the request content.
-- *
-- * Returns NULL in case of failure, otherwise a request handler.
-- * The contentType, if provided must be freed by the caller
-- */
--
--void*
--xmlNanoHTTPMethod(const char *URL, const char *method, const char *input,
-- char **contentType, const char *headers) {
-- xmlNanoHTTPCtxtPtr ctxt;
-- char *bp, *p;
-- int blen, ilen, ret;
-- int head;
-- int nbRedirects = 0;
-- char *redirURL = NULL;
--
-- if (URL == NULL) return(NULL);
-- if (method == NULL) method = "GET";
-- xmlNanoHTTPInit();
--
--retry:
-- if (redirURL == NULL)
-- ctxt = xmlNanoHTTPNewCtxt(URL);
-- else {
-- ctxt = xmlNanoHTTPNewCtxt(redirURL);
-- xmlFree(redirURL);
-- redirURL = NULL;
-- }
--
-- if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
-- xmlNanoHTTPFreeCtxt(ctxt);
-- if (redirURL != NULL) xmlFree(redirURL);
-- return(NULL);
-- }
-- if (ctxt->hostname == NULL) {
-- xmlNanoHTTPFreeCtxt(ctxt);
-- return(NULL);
-- }
-- if (proxy) {
-- blen = strlen(ctxt->hostname) * 2 + 16;
-- ret = xmlNanoHTTPConnectHost(proxy, proxyPort);
-- }
-- else {
-- blen = strlen(ctxt->hostname);
-- ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
-- }
-- if (ret < 0) {
-- xmlNanoHTTPFreeCtxt(ctxt);
-- return(NULL);
-- }
-- ctxt->fd = ret;
--
-- if (input != NULL) {
-- ilen = strlen(input);
-- blen += ilen + 32;
-- }
-- else
-- ilen = 0;
-- if (headers != NULL)
-- blen += strlen(headers);
-- if (contentType && *contentType)
-- blen += strlen(*contentType) + 16;
-- blen += strlen(method) + strlen(ctxt->path) + 23;
-- bp = xmlMalloc(blen);
-- if (proxy) {
-- if (ctxt->port != 80) {
-- sprintf(bp, "%s http://%s:%d%s", method, ctxt->hostname,
-- ctxt->port, ctxt->path);
-- }
-- else
-- sprintf(bp, "%s http://%s%s", method, ctxt->hostname, ctxt->path);
-- }
-- else
-- sprintf(bp, "%s %s", method, ctxt->path);
-- p = bp + strlen(bp);
-- sprintf(p, " HTTP/1.0\r\nHost: %s\r\n", ctxt->hostname);
-- p += strlen(p);
-- if (contentType != NULL && *contentType) {
-- sprintf(p, "Content-Type: %s\r\n", *contentType);
-- p += strlen(p);
-- }
-- if (headers != NULL) {
-- strcpy(p, headers);
-- p += strlen(p);
-- }
-- if (input != NULL)
-- sprintf(p, "Content-Length: %d\r\n\r\n%s", ilen, input);
-- else
-- strcpy(p, "\r\n");
--#ifdef DEBUG_HTTP
-- xmlGenericError(xmlGenericErrorContext,
-- "-> %s%s", proxy? "(Proxy) " : "", bp);
-- if ((blen -= strlen(bp)+1) < 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "ERROR: overflowed buffer by %d bytes\n", -blen);
--#endif
-- ctxt->outptr = ctxt->out = bp;
-- ctxt->state = XML_NANO_HTTP_WRITE;
-- xmlNanoHTTPSend(ctxt);
-- ctxt->state = XML_NANO_HTTP_READ;
-- head = 1;
--
-- while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
-- if (head && (*p == 0)) {
-- head = 0;
-- ctxt->content = ctxt->inrptr;
-- xmlFree(p);
-- break;
-- }
-- xmlNanoHTTPScanAnswer(ctxt, p);
--
--#ifdef DEBUG_HTTP
-- xmlGenericError(xmlGenericErrorContext, "<- %s\n", p);
--#endif
-- xmlFree(p);
-- }
--
-- if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) &&
-- (ctxt->returnValue < 400)) {
--#ifdef DEBUG_HTTP
-- xmlGenericError(xmlGenericErrorContext,
-- "\nRedirect to: %s\n", ctxt->location);
--#endif
-- while (xmlNanoHTTPRecv(ctxt)) ;
-- if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
-- nbRedirects++;
-- redirURL = xmlMemStrdup(ctxt->location);
-- xmlNanoHTTPFreeCtxt(ctxt);
-- goto retry;
-- }
-- xmlNanoHTTPFreeCtxt(ctxt);
--#ifdef DEBUG_HTTP
-- xmlGenericError(xmlGenericErrorContext,
-- "Too many redirects, aborting ...\n");
--#endif
-- return(NULL);
--
-- }
--
-- if (contentType != NULL) {
-- if (ctxt->contentType != NULL)
-- *contentType = xmlMemStrdup(ctxt->contentType);
-- else
-- *contentType = NULL;
-- }
--
--#ifdef DEBUG_HTTP
-- if (ctxt->contentType != NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- "\nCode %d, content-type '%s'\n\n",
-- ctxt->returnValue, ctxt->contentType);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "\nCode %d, no content-type\n\n",
-- ctxt->returnValue);
--#endif
--
-- return((void *) ctxt);
--}
--
--/**
-- * xmlNanoHTTPFetch:
-- * @URL: The URL to load
-- * @filename: the filename where the content should be saved
-- * @contentType: if available the Content-Type information will be
-- * returned at that location
-- *
-- * This function try to fetch the indicated resource via HTTP GET
-- * and save it's content in the file.
-- *
-- * Returns -1 in case of failure, 0 incase of success. The contentType,
-- * if provided must be freed by the caller
-- */
--int
--xmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) {
-- void *ctxt;
-- char buf[4096];
-- int fd;
-- int len;
--
-- ctxt = xmlNanoHTTPOpen(URL, contentType);
-- if (ctxt == NULL) return(-1);
--
-- if (!strcmp(filename, "-"))
-- fd = 0;
-- else {
-- fd = open(filename, O_CREAT | O_WRONLY, 00644);
-- if (fd < 0) {
-- xmlNanoHTTPClose(ctxt);
-- if ((contentType != NULL) && (*contentType != NULL)) {
-- xmlFree(*contentType);
-- *contentType = NULL;
-- }
-- return(-1);
-- }
-- }
--
-- while ((len = xmlNanoHTTPRead(ctxt, buf, sizeof(buf))) > 0) {
-- write(fd, buf, len);
-- }
--
-- xmlNanoHTTPClose(ctxt);
-- close(fd);
-- return(0);
--}
--
--/**
-- * xmlNanoHTTPSave:
-- * @ctxt: the HTTP context
-- * @filename: the filename where the content should be saved
-- *
-- * This function saves the output of the HTTP transaction to a file
-- * It closes and free the context at the end
-- *
-- * Returns -1 in case of failure, 0 incase of success.
-- */
--int
--xmlNanoHTTPSave(void *ctxt, const char *filename) {
-- char buf[4096];
-- int fd;
-- int len;
--
-- if (ctxt == NULL) return(-1);
--
-- if (!strcmp(filename, "-"))
-- fd = 0;
-- else {
-- fd = open(filename, O_CREAT | O_WRONLY);
-- if (fd < 0) {
-- xmlNanoHTTPClose(ctxt);
-- return(-1);
-- }
-- }
--
-- while ((len = xmlNanoHTTPRead(ctxt, buf, sizeof(buf))) > 0) {
-- write(fd, buf, len);
-- }
--
-- xmlNanoHTTPClose(ctxt);
-- return(0);
--}
--
--/**
-- * xmlNanoHTTPReturnCode:
-- * @ctx: the HTTP context
-- *
-- * Returns the HTTP return code for the request.
-- */
--int
--xmlNanoHTTPReturnCode(void *ctx) {
-- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
--
-- if (ctxt == NULL) return(-1);
--
-- return(ctxt->returnValue);
--}
--
--/**
-- * xmlNanoHTTPAuthHeader:
-- * @ctx: the HTTP context
-- *
-- * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate
-- * header.
-- */
--const char *
--xmlNanoHTTPAuthHeader(void *ctx) {
-- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
--
-- if (ctxt == NULL) return(NULL);
--
-- return(ctxt->authHeader);
--}
--
--#ifdef STANDALONE
--int main(int argc, char **argv) {
-- char *contentType = NULL;
--
-- if (argv[1] != NULL) {
-- if (argv[2] != NULL)
-- xmlNanoHTTPFetch(argv[1], argv[2], &contentType);
-- else
-- xmlNanoHTTPFetch(argv[1], "-", &contentType);
-- if (contentType != NULL) xmlFree(contentType);
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: minimal HTTP GET implementation\n", argv[0]);
-- xmlGenericError(xmlGenericErrorContext,
-- "\tusage %s [ URL [ filename ] ]\n", argv[0]);
-- }
-- xmlNanoHTTPCleanup();
-- xmlMemoryDump();
-- return(0);
--}
--#endif /* STANDALONE */
--#else /* !LIBXML_HTTP_ENABLED */
--#ifdef STANDALONE
--#include <stdio.h>
--int main(int argc, char **argv) {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s : HTTP support not compiled in\n", argv[0]);
-- return(0);
--}
--#endif /* STANDALONE */
--#endif /* LIBXML_HTTP_ENABLED */
-diff -Nru libxml2-2.3.0/parser.c libxml2-2.3.0.new/parser.c
---- libxml2-2.3.0/parser.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/parser.c Thu Jan 1 01:00:00 1970
-@@ -1,9863 +0,0 @@
--/*
-- * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
-- * implemented on top of the SAX interfaces
-- *
-- * References:
-- * The XML specification:
-- * http://www.w3.org/TR/REC-xml
-- * Original 1.0 version:
-- * http://www.w3.org/TR/1998/REC-xml-19980210
-- * XML second edition working draft
-- * http://www.w3.org/TR/2000/WD-xml-2e-20000814
-- *
-- * Okay this is a big file, the parser core is around 7000 lines, then it
-- * is followed by the progressive parser top routines, then the various
-- * high level APIs to call the parser and a few miscelaneous functions.
-- * A number of helper functions and deprecated ones have been moved to
-- * parserInternals.c to reduce this file size.
-- * As much as possible the functions are associated with their relative
-- * production in the XML specification. A few productions defining the
-- * different ranges of character are actually implanted either in
-- * parserInternals.h or parserInternals.c
-- * The DOM tree build is realized from the default SAX callbacks in
-- * the module SAX.c.
-- * The routines doing the validation checks are in valid.c and called either
-- * from the SAx callbacks or as standalones functions using a preparsed
-- * document.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- *
-- * 14 Nov 2000 ht - truncated definitions of xmlSubstituteEntitiesDefaultValue
-- * and xmlDoValidityCheckingDefaultValue for VMS
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#define XML_DIR_SEP '\\'
--#else
--#include "config.h"
--#define XML_DIR_SEP '/'
--#endif
--
--#include <stdio.h>
--#include <stdlib.h>
--#include <string.h>
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/parserInternals.h>
--#include <libxml/valid.h>
--#include <libxml/entities.h>
--#include <libxml/xmlerror.h>
--#include <libxml/encoding.h>
--#include <libxml/xmlIO.h>
--#include <libxml/uri.h>
--
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_SYS_STAT_H
--#include <sys/stat.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_ZLIB_H
--#include <zlib.h>
--#endif
--
--
--#define XML_PARSER_BIG_BUFFER_SIZE 1000
--#define XML_PARSER_BUFFER_SIZE 100
--
--/*
-- * Various global defaults for parsing
-- */
--int xmlGetWarningsDefaultValue = 1;
--int xmlParserDebugEntities = 0;
--#ifdef VMS
--int xmlSubstituteEntitiesDefaultVal = 0;
--#define xmlSubstituteEntitiesDefaultValue xmlSubstituteEntitiesDefaultVal
--int xmlDoValidityCheckingDefaultVal = 0;
--#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
--#else
--int xmlSubstituteEntitiesDefaultValue = 0;
--int xmlDoValidityCheckingDefaultValue = 0;
--#endif
--int xmlLoadExtDtdDefaultValue = 0;
--int xmlPedanticParserDefaultValue = 0;
--int xmlKeepBlanksDefaultValue = 1;
--
--/*
-- * List of XML prefixed PI allowed by W3C specs
-- */
--
--const char *xmlW3CPIs[] = {
-- "xml-stylesheet",
-- NULL
--};
--
--/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
--void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
--xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
-- const xmlChar **str);
--
--
--/************************************************************************
-- * *
-- * Parser stacks related functions and macros *
-- * *
-- ************************************************************************/
--
--xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
-- const xmlChar ** str);
--
--/*
-- * Generic function for accessing stacks in the Parser Context
-- */
--
--#define PUSH_AND_POP(scope, type, name) \
--scope int name##Push(xmlParserCtxtPtr ctxt, type value) { \
-- if (ctxt->name##Nr >= ctxt->name##Max) { \
-- ctxt->name##Max *= 2; \
-- ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-- ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-- if (ctxt->name##Tab == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "realloc failed !\n"); \
-- return(0); \
-- } \
-- } \
-- ctxt->name##Tab[ctxt->name##Nr] = value; \
-- ctxt->name = value; \
-- return(ctxt->name##Nr++); \
--} \
--scope type name##Pop(xmlParserCtxtPtr ctxt) { \
-- type ret; \
-- if (ctxt->name##Nr <= 0) return(0); \
-- ctxt->name##Nr--; \
-- if (ctxt->name##Nr > 0) \
-- ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-- else \
-- ctxt->name = NULL; \
-- ret = ctxt->name##Tab[ctxt->name##Nr]; \
-- ctxt->name##Tab[ctxt->name##Nr] = 0; \
-- return(ret); \
--} \
--
--/*
-- * Those macros actually generate the functions
-- */
--PUSH_AND_POP(extern, xmlParserInputPtr, input)
--PUSH_AND_POP(extern, xmlNodePtr, node)
--PUSH_AND_POP(extern, xmlChar*, name)
--
--int spacePush(xmlParserCtxtPtr ctxt, int val) {
-- if (ctxt->spaceNr >= ctxt->spaceMax) {
-- ctxt->spaceMax *= 2;
-- ctxt->spaceTab = (int *) xmlRealloc(ctxt->spaceTab,
-- ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
-- if (ctxt->spaceTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return(0);
-- }
-- }
-- ctxt->spaceTab[ctxt->spaceNr] = val;
-- ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
-- return(ctxt->spaceNr++);
--}
--
--int spacePop(xmlParserCtxtPtr ctxt) {
-- int ret;
-- if (ctxt->spaceNr <= 0) return(0);
-- ctxt->spaceNr--;
-- if (ctxt->spaceNr > 0)
-- ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
-- else
-- ctxt->space = NULL;
-- ret = ctxt->spaceTab[ctxt->spaceNr];
-- ctxt->spaceTab[ctxt->spaceNr] = -1;
-- return(ret);
--}
--
--/*
-- * Macros for accessing the content. Those should be used only by the parser,
-- * and not exported.
-- *
-- * Dirty macros, i.e. one often need to make assumption on the context to
-- * use them
-- *
-- * CUR_PTR return the current pointer to the xmlChar to be parsed.
-- * To be used with extreme caution since operations consuming
-- * characters may move the input buffer to a different location !
-- * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
-- * This should be used internally by the parser
-- * only to compare to ASCII values otherwise it would break when
-- * running with UTF-8 encoding.
-- * RAW same as CUR but in the input buffer, bypass any token
-- * extraction that may have been done
-- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-- * to compare on ASCII based substring.
-- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-- * strings within the parser.
-- *
-- * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
-- *
-- * NEXT Skip to the next character, this does the proper decoding
-- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-- * NEXTL(l) Skip l xmlChars in the input buffer
-- * CUR_CHAR(l) returns the current unicode character (int), set l
-- * to the number of xmlChars used for the encoding [0-5].
-- * CUR_SCHAR same but operate on a string instead of the context
-- * COPY_BUF copy the current unicode char to the target buffer, increment
-- * the index
-- * GROW, SHRINK handling of input buffers
-- */
--
--#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
--#define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
--#define NXT(val) ctxt->input->cur[(val)]
--#define CUR_PTR ctxt->input->cur
--
--#define SKIP(val) do { \
-- ctxt->nbChars += (val),ctxt->input->cur += (val); \
-- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
-- /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
-- if ((*ctxt->input->cur == 0) && \
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
-- xmlPopInput(ctxt); \
-- } while (0)
--
--#define SHRINK do { \
-- xmlParserInputShrink(ctxt->input); \
-- if ((*ctxt->input->cur == 0) && \
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
-- xmlPopInput(ctxt); \
-- } while (0)
--
--#define GROW do { \
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \
-- if ((*ctxt->input->cur == 0) && \
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
-- xmlPopInput(ctxt); \
-- } while (0)
--
--#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
--
--#define NEXT xmlNextChar(ctxt)
--
--#define NEXTL(l) do { \
-- if (*(ctxt->input->cur) == '\n') { \
-- ctxt->input->line++; ctxt->input->col = 1; \
-- } else ctxt->input->col++; \
-- ctxt->token = 0; ctxt->input->cur += l; \
-- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
-- /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
-- } while (0)
--
--#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
--#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
--
--#define COPY_BUF(l,b,i,v) \
-- if (l == 1) b[i++] = (xmlChar) v; \
-- else i += xmlCopyChar(l,&b[i],v)
--
--/**
-- * xmlSkipBlankChars:
-- * @ctxt: the XML parser context
-- *
-- * skip all blanks character found at that point in the input streams.
-- * It pops up finished entities in the process if allowable at that point.
-- *
-- * Returns the number of space chars skipped
-- */
--
--int
--xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
-- int cur, res = 0;
--
-- /*
-- * It's Okay to use CUR/NEXT here since all the blanks are on
-- * the ASCII range.
-- */
-- do {
-- cur = CUR;
-- while (IS_BLANK(cur)) { /* CHECKED tstblanks.xml */
-- NEXT;
-- cur = CUR;
-- res++;
-- }
-- while ((cur == 0) && (ctxt->inputNr > 1) &&
-- (ctxt->instate != XML_PARSER_COMMENT)) {
-- xmlPopInput(ctxt);
-- cur = CUR;
-- }
-- /*
-- * Need to handle support of entities branching here
-- */
-- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
-- /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */
-- } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
-- return(res);
--}
--
--/************************************************************************
-- * *
-- * Commodity functions to handle entities *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlPopInput:
-- * @ctxt: an XML parser context
-- *
-- * xmlPopInput: the current input pointed by ctxt->input came to an end
-- * pop it and return the next char.
-- *
-- * Returns the current xmlChar in the parser context
-- */
--xmlChar
--xmlPopInput(xmlParserCtxtPtr ctxt) {
-- if (ctxt->inputNr == 1) return(0); /* End of main Input */
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "Popping input %d\n", ctxt->inputNr);
-- xmlFreeInputStream(inputPop(ctxt));
-- if ((*ctxt->input->cur == 0) &&
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-- return(xmlPopInput(ctxt));
-- return(CUR);
--}
--
--/**
-- * xmlPushInput:
-- * @ctxt: an XML parser context
-- * @input: an XML parser input fragment (entity, XML fragment ...).
-- *
-- * xmlPushInput: switch to a new input stream which is stacked on top
-- * of the previous one(s).
-- */
--void
--xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
-- if (input == NULL) return;
--
-- if (xmlParserDebugEntities) {
-- if ((ctxt->input != NULL) && (ctxt->input->filename))
-- xmlGenericError(xmlGenericErrorContext,
-- "%s(%d): ", ctxt->input->filename,
-- ctxt->input->line);
-- xmlGenericError(xmlGenericErrorContext,
-- "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
-- }
-- inputPush(ctxt, input);
-- GROW;
--}
--
--/**
-- * xmlParseCharRef:
-- * @ctxt: an XML parser context
-- *
-- * parse Reference declarations
-- *
-- * [66] CharRef ::= '&#' [0-9]+ ';' |
-- * '&#x' [0-9a-fA-F]+ ';'
-- *
-- * [ WFC: Legal Character ]
-- * Characters referred to using character references must match the
-- * production for Char.
-- *
-- * Returns the value parsed (as an int), 0 in case of error
-- */
--int
--xmlParseCharRef(xmlParserCtxtPtr ctxt) {
-- int val = 0;
-- int count = 0;
--
-- if (ctxt->token != 0) {
-- val = ctxt->token;
-- ctxt->token = 0;
-- return(val);
-- }
-- /*
-- * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
-- */
-- if ((RAW == '&') && (NXT(1) == '#') &&
-- (NXT(2) == 'x')) {
-- SKIP(3);
-- GROW;
-- while (RAW != ';') { /* loop blocked by count */
-- if ((RAW >= '0') && (RAW <= '9') && (count < 20))
-- val = val * 16 + (CUR - '0');
-- else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
-- val = val * 16 + (CUR - 'a') + 10;
-- else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
-- val = val * 16 + (CUR - 'A') + 10;
-- else {
-- ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseCharRef: invalid hexadecimal value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- val = 0;
-- break;
-- }
-- NEXT;
-- count++;
-- }
-- if (RAW == ';') {
-- /* on purpose to avoid reentrancy problems with NEXT and SKIP */
-- ctxt->nbChars ++;
-- ctxt->input->cur++;
-- }
-- } else if ((RAW == '&') && (NXT(1) == '#')) {
-- SKIP(2);
-- GROW;
-- while (RAW != ';') { /* loop blocked by count */
-- if ((RAW >= '0') && (RAW <= '9') && (count < 20))
-- val = val * 10 + (CUR - '0');
-- else {
-- ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseCharRef: invalid decimal value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- val = 0;
-- break;
-- }
-- NEXT;
-- count++;
-- }
-- if (RAW == ';') {
-- /* on purpose to avoid reentrancy problems with NEXT and SKIP */
-- ctxt->nbChars ++;
-- ctxt->input->cur++;
-- }
-- } else {
-- ctxt->errNo = XML_ERR_INVALID_CHARREF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseCharRef: invalid value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * [ WFC: Legal Character ]
-- * Characters referred to using character references must match the
-- * production for Char.
-- */
-- if (IS_CHAR(val)) {
-- return(val);
-- } else {
-- ctxt->errNo = XML_ERR_INVALID_CHAR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "CharRef: invalid xmlChar value %d\n",
-- val);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(0);
--}
--
--/**
-- * xmlParseStringCharRef:
-- * @ctxt: an XML parser context
-- * @str: a pointer to an index in the string
-- *
-- * parse Reference declarations, variant parsing from a string rather
-- * than an an input flow.
-- *
-- * [66] CharRef ::= '&#' [0-9]+ ';' |
-- * '&#x' [0-9a-fA-F]+ ';'
-- *
-- * [ WFC: Legal Character ]
-- * Characters referred to using character references must match the
-- * production for Char.
-- *
-- * Returns the value parsed (as an int), 0 in case of error, str will be
-- * updated to the current value of the index
-- */
--int
--xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
-- const xmlChar *ptr;
-- xmlChar cur;
-- int val = 0;
--
-- if ((str == NULL) || (*str == NULL)) return(0);
-- ptr = *str;
-- cur = *ptr;
-- if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
-- ptr += 3;
-- cur = *ptr;
-- while (cur != ';') { /* Non input consuming loop */
-- if ((cur >= '0') && (cur <= '9'))
-- val = val * 16 + (cur - '0');
-- else if ((cur >= 'a') && (cur <= 'f'))
-- val = val * 16 + (cur - 'a') + 10;
-- else if ((cur >= 'A') && (cur <= 'F'))
-- val = val * 16 + (cur - 'A') + 10;
-- else {
-- ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStringCharRef: invalid hexadecimal value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- val = 0;
-- break;
-- }
-- ptr++;
-- cur = *ptr;
-- }
-- if (cur == ';')
-- ptr++;
-- } else if ((cur == '&') && (ptr[1] == '#')){
-- ptr += 2;
-- cur = *ptr;
-- while (cur != ';') { /* Non input consuming loops */
-- if ((cur >= '0') && (cur <= '9'))
-- val = val * 10 + (cur - '0');
-- else {
-- ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStringCharRef: invalid decimal value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- val = 0;
-- break;
-- }
-- ptr++;
-- cur = *ptr;
-- }
-- if (cur == ';')
-- ptr++;
-- } else {
-- ctxt->errNo = XML_ERR_INVALID_CHARREF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseCharRef: invalid value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(0);
-- }
-- *str = ptr;
--
-- /*
-- * [ WFC: Legal Character ]
-- * Characters referred to using character references must match the
-- * production for Char.
-- */
-- if (IS_CHAR(val)) {
-- return(val);
-- } else {
-- ctxt->errNo = XML_ERR_INVALID_CHAR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "CharRef: invalid xmlChar value %d\n", val);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(0);
--}
--
--/**
-- * xmlParserHandlePEReference:
-- * @ctxt: the parser context
-- *
-- * [69] PEReference ::= '%' Name ';'
-- *
-- * [ WFC: No Recursion ]
-- * A parsed entity must not contain a recursive
-- * reference to itself, either directly or indirectly.
-- *
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an internal DTD
-- * subset which contains no parameter entity references, or a document
-- * with "standalone='yes'", ... ... The declaration of a parameter
-- * entity must precede any reference to it...
-- *
-- * [ VC: Entity Declared ]
-- * In a document with an external subset or external parameter entities
-- * with "standalone='no'", ... ... The declaration of a parameter entity
-- * must precede any reference to it...
-- *
-- * [ WFC: In DTD ]
-- * Parameter-entity references may only appear in the DTD.
-- * NOTE: misleading but this is handled.
-- *
-- * A PEReference may have been detected in the current input stream
-- * the handling is done accordingly to
-- * http://www.w3.org/TR/REC-xml#entproc
-- * i.e.
-- * - Included in literal in entity values
-- * - Included as Paraemeter Entity reference within DTDs
-- */
--void
--xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlEntityPtr entity = NULL;
-- xmlParserInputPtr input;
--
-- if (ctxt->token != 0) {
-- return;
-- }
-- if (RAW != '%') return;
-- switch(ctxt->instate) {
-- case XML_PARSER_CDATA_SECTION:
-- return;
-- case XML_PARSER_COMMENT:
-- return;
-- case XML_PARSER_START_TAG:
-- return;
-- case XML_PARSER_END_TAG:
-- return;
-- case XML_PARSER_EOF:
-- ctxt->errNo = XML_ERR_PEREF_AT_EOF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "PEReference at EOF\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_PROLOG:
-- case XML_PARSER_START:
-- case XML_PARSER_MISC:
-- ctxt->errNo = XML_ERR_PEREF_IN_PROLOG;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "PEReference in prolog!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_ENTITY_DECL:
-- case XML_PARSER_CONTENT:
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- case XML_PARSER_PI:
-- case XML_PARSER_SYSTEM_LITERAL:
-- /* we just ignore it there */
-- return;
-- case XML_PARSER_EPILOG:
-- ctxt->errNo = XML_ERR_PEREF_IN_EPILOG;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "PEReference in epilog!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_ENTITY_VALUE:
-- /*
-- * NOTE: in the case of entity values, we don't do the
-- * substitution here since we need the literal
-- * entity value to be able to save the internal
-- * subset of the document.
-- * This will be handled by xmlStringDecodeEntities
-- */
-- return;
-- case XML_PARSER_DTD:
-- /*
-- * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
-- * In the internal DTD subset, parameter-entity references
-- * can occur only where markup declarations can occur, not
-- * within markup declarations.
-- * In that case this is handled in xmlParseMarkupDecl
-- */
-- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
-- return;
-- break;
-- case XML_PARSER_IGNORE:
-- return;
-- }
--
-- NEXT;
-- name = xmlParseName(ctxt);
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "PE Reference: %s\n", name);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_PEREF_NO_NAME;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "xmlHandlePEReference: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (RAW == ';') {
-- NEXT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
-- entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
-- if (entity == NULL) {
--
-- /*
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an
-- * internal DTD subset which contains no parameter entity
-- * references, or a document with "standalone='yes'", ...
-- * ... The declaration of a parameter entity must precede
-- * any reference to it...
-- */
-- if ((ctxt->standalone == 1) ||
-- ((ctxt->hasExternalSubset == 0) &&
-- (ctxt->hasPErefs == 0))) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "PEReference: %%%s; not found\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- /*
-- * [ VC: Entity Declared ]
-- * In a document with an external subset or external
-- * parameter entities with "standalone='no'", ...
-- * ... The declaration of a parameter entity must precede
-- * any reference to it...
-- */
-- if ((!ctxt->disableSAX) &&
-- (ctxt->validate) && (ctxt->vctxt.error != NULL)) {
-- ctxt->vctxt.error(ctxt->vctxt.userData,
-- "PEReference: %%%s; not found\n", name);
-- } else if ((!ctxt->disableSAX) &&
-- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "PEReference: %%%s; not found\n", name);
-- ctxt->valid = 0;
-- }
-- } else {
-- if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
-- (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
-- /*
-- * handle the extra spaces added before and after
-- * c.f. http://www.w3.org/TR/REC-xml#as-PE
-- * this is done independantly.
-- */
-- input = xmlNewEntityInputStream(ctxt, entity);
-- xmlPushInput(ctxt, input);
-- if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-- (RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-- xmlParseTextDecl(ctxt);
-- }
-- if (ctxt->token == 0)
-- ctxt->token = ' ';
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlHandlePEReference: %s is not a parameter entity\n",
-- name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
-- } else {
-- ctxt->errNo = XML_ERR_PEREF_SEMICOL_MISSING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlHandlePEReference: expecting ';'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlFree(name);
-- }
--}
--
--/*
-- * Macro used to grow the current buffer.
-- */
--#define growBuffer(buffer) { \
-- buffer##_size *= 2; \
-- buffer = (xmlChar *) \
-- xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
-- if (buffer == NULL) { \
-- perror("realloc failed"); \
-- return(NULL); \
-- } \
--}
--
--/**
-- * xmlStringDecodeEntities:
-- * @ctxt: the parser context
-- * @str: the input string
-- * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
-- * @end: an end marker xmlChar, 0 if none
-- * @end2: an end marker xmlChar, 0 if none
-- * @end3: an end marker xmlChar, 0 if none
-- *
-- * Takes a entity string content and process to do the adequate subtitutions.
-- *
-- * [67] Reference ::= EntityRef | CharRef
-- *
-- * [69] PEReference ::= '%' Name ';'
-- *
-- * Returns A newly allocated string with the substitution done. The caller
-- * must deallocate it !
-- */
--xmlChar *
--xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
-- xmlChar end, xmlChar end2, xmlChar end3) {
-- xmlChar *buffer = NULL;
-- int buffer_size = 0;
--
-- xmlChar *current = NULL;
-- xmlEntityPtr ent;
-- int c,l;
-- int nbchars = 0;
--
-- if (str == NULL)
-- return(NULL);
--
-- if (ctxt->depth > 40) {
-- ctxt->errNo = XML_ERR_ENTITY_LOOP;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Detected entity reference loop\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- /*
-- * allocate a translation buffer.
-- */
-- buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("xmlDecodeEntities: malloc failed");
-- return(NULL);
-- }
--
-- /*
-- * Ok loop until we reach one of the ending char or a size limit.
-- * we are operating on already parsed values.
-- */
-- c = CUR_SCHAR(str, l);
-- while ((c != 0) && (c != end) && /* non input consuming loop */
-- (c != end2) && (c != end3)) {
--
-- if (c == 0) break;
-- if ((c == '&') && (str[1] == '#')) {
-- int val = xmlParseStringCharRef(ctxt, &str);
-- if (val != 0) {
-- COPY_BUF(0,buffer,nbchars,val);
-- }
-- } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "String decoding Entity Reference: %.30s\n",
-- str);
-- ent = xmlParseStringEntityRef(ctxt, &str);
-- if ((ent != NULL) &&
-- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-- if (ent->content != NULL) {
-- COPY_BUF(0,buffer,nbchars,ent->content[0]);
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "internal error entity has no content\n");
-- }
-- } else if ((ent != NULL) && (ent->content != NULL)) {
-- xmlChar *rep;
--
-- ctxt->depth++;
-- rep = xmlStringDecodeEntities(ctxt, ent->content, what,
-- 0, 0, 0);
-- ctxt->depth--;
-- if (rep != NULL) {
-- current = rep;
-- while (*current != 0) { /* non input consuming loop */
-- buffer[nbchars++] = *current++;
-- if (nbchars >
-- buffer_size - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- }
-- xmlFree(rep);
-- }
-- } else if (ent != NULL) {
-- int i = xmlStrlen(ent->name);
-- const xmlChar *cur = ent->name;
--
-- buffer[nbchars++] = '&';
-- if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- for (;i > 0;i--)
-- buffer[nbchars++] = *cur++;
-- buffer[nbchars++] = ';';
-- }
-- } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "String decoding PE Reference: %.30s\n", str);
-- ent = xmlParseStringPEReference(ctxt, &str);
-- if (ent != NULL) {
-- xmlChar *rep;
--
-- ctxt->depth++;
-- rep = xmlStringDecodeEntities(ctxt, ent->content, what,
-- 0, 0, 0);
-- ctxt->depth--;
-- if (rep != NULL) {
-- current = rep;
-- while (*current != 0) { /* non input consuming loop */
-- buffer[nbchars++] = *current++;
-- if (nbchars >
-- buffer_size - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- }
-- xmlFree(rep);
-- }
-- }
-- } else {
-- COPY_BUF(l,buffer,nbchars,c);
-- str += l;
-- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- }
-- c = CUR_SCHAR(str, l);
-- }
-- buffer[nbchars++] = 0;
-- return(buffer);
--}
--
--
--/************************************************************************
-- * *
-- * Commodity functions to handle xmlChars *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlStrndup:
-- * @cur: the input xmlChar *
-- * @len: the len of @cur
-- *
-- * a strndup for array of xmlChar's
-- *
-- * Returns a new xmlChar * or NULL
-- */
--xmlChar *
--xmlStrndup(const xmlChar *cur, int len) {
-- xmlChar *ret;
--
-- if ((cur == NULL) || (len < 0)) return(NULL);
-- ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %ld byte failed\n",
-- (len + 1) * (long)sizeof(xmlChar));
-- return(NULL);
-- }
-- memcpy(ret, cur, len * sizeof(xmlChar));
-- ret[len] = 0;
-- return(ret);
--}
--
--/**
-- * xmlStrdup:
-- * @cur: the input xmlChar *
-- *
-- * a strdup for array of xmlChar's. Since they are supposed to be
-- * encoded in UTF-8 or an encoding with 8bit based chars, we assume
-- * a termination mark of '0'.
-- *
-- * Returns a new xmlChar * or NULL
-- */
--xmlChar *
--xmlStrdup(const xmlChar *cur) {
-- const xmlChar *p = cur;
--
-- if (cur == NULL) return(NULL);
-- while (*p != 0) p++; /* non input consuming */
-- return(xmlStrndup(cur, p - cur));
--}
--
--/**
-- * xmlCharStrndup:
-- * @cur: the input char *
-- * @len: the len of @cur
-- *
-- * a strndup for char's to xmlChar's
-- *
-- * Returns a new xmlChar * or NULL
-- */
--
--xmlChar *
--xmlCharStrndup(const char *cur, int len) {
-- int i;
-- xmlChar *ret;
--
-- if ((cur == NULL) || (len < 0)) return(NULL);
-- ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n",
-- (len + 1) * (long)sizeof(xmlChar));
-- return(NULL);
-- }
-- for (i = 0;i < len;i++)
-- ret[i] = (xmlChar) cur[i];
-- ret[len] = 0;
-- return(ret);
--}
--
--/**
-- * xmlCharStrdup:
-- * @cur: the input char *
-- * @len: the len of @cur
-- *
-- * a strdup for char's to xmlChar's
-- *
-- * Returns a new xmlChar * or NULL
-- */
--
--xmlChar *
--xmlCharStrdup(const char *cur) {
-- const char *p = cur;
--
-- if (cur == NULL) return(NULL);
-- while (*p != '\0') p++; /* non input consuming */
-- return(xmlCharStrndup(cur, p - cur));
--}
--
--/**
-- * xmlStrcmp:
-- * @str1: the first xmlChar *
-- * @str2: the second xmlChar *
-- *
-- * a strcmp for xmlChar's
-- *
-- * Returns the integer result of the comparison
-- */
--
--int
--xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
-- register int tmp;
--
-- if (str1 == str2) return(0);
-- if (str1 == NULL) return(-1);
-- if (str2 == NULL) return(1);
-- do {
-- tmp = *str1++ - *str2;
-- if (tmp != 0) return(tmp);
-- } while (*str2++ != 0);
-- return 0;
--}
--
--/**
-- * xmlStrEqual:
-- * @str1: the first xmlChar *
-- * @str2: the second xmlChar *
-- *
-- * Check if both string are equal of have same content
-- * Should be a bit more readable and faster than xmlStrEqual()
-- *
-- * Returns 1 if they are equal, 0 if they are different
-- */
--
--int
--xmlStrEqual(const xmlChar *str1, const xmlChar *str2) {
-- if (str1 == str2) return(1);
-- if (str1 == NULL) return(0);
-- if (str2 == NULL) return(0);
-- do {
-- if (*str1++ != *str2) return(0);
-- } while (*str2++);
-- return(1);
--}
--
--/**
-- * xmlStrncmp:
-- * @str1: the first xmlChar *
-- * @str2: the second xmlChar *
-- * @len: the max comparison length
-- *
-- * a strncmp for xmlChar's
-- *
-- * Returns the integer result of the comparison
-- */
--
--int
--xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
-- register int tmp;
--
-- if (len <= 0) return(0);
-- if (str1 == str2) return(0);
-- if (str1 == NULL) return(-1);
-- if (str2 == NULL) return(1);
-- do {
-- tmp = *str1++ - *str2;
-- if (tmp != 0 || --len == 0) return(tmp);
-- } while (*str2++ != 0);
-- return 0;
--}
--
--static xmlChar casemap[256] = {
-- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-- 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
-- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-- 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
-- 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
-- 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
-- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
-- 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
-- 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
-- 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
-- 0x78,0x79,0x7A,0x7B,0x5C,0x5D,0x5E,0x5F,
-- 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
-- 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
-- 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
-- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
-- 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
-- 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
-- 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
-- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
-- 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
-- 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
-- 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
-- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
-- 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
-- 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
-- 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
-- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
-- 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
-- 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
-- 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
--};
--
--/**
-- * xmlStrcasecmp:
-- * @str1: the first xmlChar *
-- * @str2: the second xmlChar *
-- *
-- * a strcasecmp for xmlChar's
-- *
-- * Returns the integer result of the comparison
-- */
--
--int
--xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) {
-- register int tmp;
--
-- if (str1 == str2) return(0);
-- if (str1 == NULL) return(-1);
-- if (str2 == NULL) return(1);
-- do {
-- tmp = casemap[*str1++] - casemap[*str2];
-- if (tmp != 0) return(tmp);
-- } while (*str2++ != 0);
-- return 0;
--}
--
--/**
-- * xmlStrncasecmp:
-- * @str1: the first xmlChar *
-- * @str2: the second xmlChar *
-- * @len: the max comparison length
-- *
-- * a strncasecmp for xmlChar's
-- *
-- * Returns the integer result of the comparison
-- */
--
--int
--xmlStrncasecmp(const xmlChar *str1, const xmlChar *str2, int len) {
-- register int tmp;
--
-- if (len <= 0) return(0);
-- if (str1 == str2) return(0);
-- if (str1 == NULL) return(-1);
-- if (str2 == NULL) return(1);
-- do {
-- tmp = casemap[*str1++] - casemap[*str2];
-- if (tmp != 0 || --len == 0) return(tmp);
-- } while (*str2++ != 0);
-- return 0;
--}
--
--/**
-- * xmlStrchr:
-- * @str: the xmlChar * array
-- * @val: the xmlChar to search
-- *
-- * a strchr for xmlChar's
-- *
-- * Returns the xmlChar * for the first occurence or NULL.
-- */
--
--const xmlChar *
--xmlStrchr(const xmlChar *str, xmlChar val) {
-- if (str == NULL) return(NULL);
-- while (*str != 0) { /* non input consuming */
-- if (*str == val) return((xmlChar *) str);
-- str++;
-- }
-- return(NULL);
--}
--
--/**
-- * xmlStrstr:
-- * @str: the xmlChar * array (haystack)
-- * @val: the xmlChar to search (needle)
-- *
-- * a strstr for xmlChar's
-- *
-- * Returns the xmlChar * for the first occurence or NULL.
-- */
--
--const xmlChar *
--xmlStrstr(const xmlChar *str, xmlChar *val) {
-- int n;
--
-- if (str == NULL) return(NULL);
-- if (val == NULL) return(NULL);
-- n = xmlStrlen(val);
--
-- if (n == 0) return(str);
-- while (*str != 0) { /* non input consuming */
-- if (*str == *val) {
-- if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
-- }
-- str++;
-- }
-- return(NULL);
--}
--
--/**
-- * xmlStrcasestr:
-- * @str: the xmlChar * array (haystack)
-- * @val: the xmlChar to search (needle)
-- *
-- * a case-ignoring strstr for xmlChar's
-- *
-- * Returns the xmlChar * for the first occurence or NULL.
-- */
--
--const xmlChar *
--xmlStrcasestr(const xmlChar *str, xmlChar *val) {
-- int n;
--
-- if (str == NULL) return(NULL);
-- if (val == NULL) return(NULL);
-- n = xmlStrlen(val);
--
-- if (n == 0) return(str);
-- while (*str != 0) { /* non input consuming */
-- if (casemap[*str] == casemap[*val])
-- if (!xmlStrncasecmp(str, val, n)) return(str);
-- str++;
-- }
-- return(NULL);
--}
--
--/**
-- * xmlStrsub:
-- * @str: the xmlChar * array (haystack)
-- * @start: the index of the first char (zero based)
-- * @len: the length of the substring
-- *
-- * Extract a substring of a given string
-- *
-- * Returns the xmlChar * for the first occurence or NULL.
-- */
--
--xmlChar *
--xmlStrsub(const xmlChar *str, int start, int len) {
-- int i;
--
-- if (str == NULL) return(NULL);
-- if (start < 0) return(NULL);
-- if (len < 0) return(NULL);
--
-- for (i = 0;i < start;i++) {
-- if (*str == 0) return(NULL);
-- str++;
-- }
-- if (*str == 0) return(NULL);
-- return(xmlStrndup(str, len));
--}
--
--/**
-- * xmlStrlen:
-- * @str: the xmlChar * array
-- *
-- * length of a xmlChar's string
-- *
-- * Returns the number of xmlChar contained in the ARRAY.
-- */
--
--int
--xmlStrlen(const xmlChar *str) {
-- int len = 0;
--
-- if (str == NULL) return(0);
-- while (*str != 0) { /* non input consuming */
-- str++;
-- len++;
-- }
-- return(len);
--}
--
--/**
-- * xmlStrncat:
-- * @cur: the original xmlChar * array
-- * @add: the xmlChar * array added
-- * @len: the length of @add
-- *
-- * a strncat for array of xmlChar's, it will extend cur with the len
-- * first bytes of @add.
-- *
-- * Returns a new xmlChar *, the original @cur is reallocated if needed
-- * and should not be freed
-- */
--
--xmlChar *
--xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
-- int size;
-- xmlChar *ret;
--
-- if ((add == NULL) || (len == 0))
-- return(cur);
-- if (cur == NULL)
-- return(xmlStrndup(add, len));
--
-- size = xmlStrlen(cur);
-- ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlStrncat: realloc of %ld byte failed\n",
-- (size + len + 1) * (long)sizeof(xmlChar));
-- return(cur);
-- }
-- memcpy(&ret[size], add, len * sizeof(xmlChar));
-- ret[size + len] = 0;
-- return(ret);
--}
--
--/**
-- * xmlStrcat:
-- * @cur: the original xmlChar * array
-- * @add: the xmlChar * array added
-- *
-- * a strcat for array of xmlChar's. Since they are supposed to be
-- * encoded in UTF-8 or an encoding with 8bit based chars, we assume
-- * a termination mark of '0'.
-- *
-- * Returns a new xmlChar * containing the concatenated string.
-- */
--xmlChar *
--xmlStrcat(xmlChar *cur, const xmlChar *add) {
-- const xmlChar *p = add;
--
-- if (add == NULL) return(cur);
-- if (cur == NULL)
-- return(xmlStrdup(add));
--
-- while (*p != 0) p++; /* non input consuming */
-- return(xmlStrncat(cur, add, p - add));
--}
--
--/************************************************************************
-- * *
-- * Commodity functions, cleanup needed ? *
-- * *
-- ************************************************************************/
--
--/**
-- * areBlanks:
-- * @ctxt: an XML parser context
-- * @str: a xmlChar *
-- * @len: the size of @str
-- *
-- * Is this a sequence of blank chars that one can ignore ?
-- *
-- * Returns 1 if ignorable 0 otherwise.
-- */
--
--static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
-- int i, ret;
-- xmlNodePtr lastChild;
--
-- /*
-- * Check for xml:space value.
-- */
-- if (*(ctxt->space) == 1)
-- return(0);
--
-- /*
-- * Check that the string is made of blanks
-- */
-- for (i = 0;i < len;i++)
-- if (!(IS_BLANK(str[i]))) return(0);
--
-- /*
-- * Look if the element is mixed content in the Dtd if available
-- */
-- if (ctxt->myDoc != NULL) {
-- ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
-- if (ret == 0) return(1);
-- if (ret == 1) return(0);
-- }
--
-- /*
-- * Otherwise, heuristic :-\
-- */
-- if (ctxt->keepBlanks)
-- return(0);
-- if (RAW != '<') return(0);
-- if (ctxt->node == NULL) return(0);
-- if ((ctxt->node->children == NULL) &&
-- (RAW == '<') && (NXT(1) == '/')) return(0);
--
-- lastChild = xmlGetLastChild(ctxt->node);
-- if (lastChild == NULL) {
-- if (ctxt->node->content != NULL) return(0);
-- } else if (xmlNodeIsText(lastChild))
-- return(0);
-- else if ((ctxt->node->children != NULL) &&
-- (xmlNodeIsText(ctxt->node->children)))
-- return(0);
-- return(1);
--}
--
--/*
-- * Forward definition for recusive behaviour.
-- */
--void xmlParsePEReference(xmlParserCtxtPtr ctxt);
--void xmlParseReference(xmlParserCtxtPtr ctxt);
--
--/************************************************************************
-- * *
-- * Extra stuff for namespace support *
-- * Relates to http://www.w3.org/TR/WD-xml-names *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlSplitQName:
-- * @ctxt: an XML parser context
-- * @name: an XML parser context
-- * @prefix: a xmlChar **
-- *
-- * parse an UTF8 encoded XML qualified name string
-- *
-- * [NS 5] QName ::= (Prefix ':')? LocalPart
-- *
-- * [NS 6] Prefix ::= NCName
-- *
-- * [NS 7] LocalPart ::= NCName
-- *
-- * Returns the local part, and prefix is updated
-- * to get the Prefix if any.
-- */
--
--xmlChar *
--xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
-- xmlChar buf[XML_MAX_NAMELEN + 5];
-- xmlChar *buffer = NULL;
-- int len = 0;
-- int max = XML_MAX_NAMELEN;
-- xmlChar *ret = NULL;
-- const xmlChar *cur = name;
-- int c;
--
-- *prefix = NULL;
--
-- /* xml: prefix is not really a namespace */
-- if ((cur[0] == 'x') && (cur[1] == 'm') &&
-- (cur[2] == 'l') && (cur[3] == ':'))
-- return(xmlStrdup(name));
--
-- /* nasty but valid */
-- if (cur[0] == ':')
-- return(xmlStrdup(name));
--
-- c = *cur++;
-- while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
-- buf[len++] = c;
-- c = *cur++;
-- }
-- if (len >= max) {
-- /*
-- * Okay someone managed to make a huge name, so he's ready to pay
-- * for the processing speed.
-- */
-- max = len * 2;
--
-- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlSplitQName: out of memory\n");
-- return(NULL);
-- }
-- memcpy(buffer, buf, len);
-- while ((c != 0) && (c != ':')) { /* tested bigname.xml */
-- if (len + 10 > max) {
-- max *= 2;
-- buffer = (xmlChar *) xmlRealloc(buffer,
-- max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlSplitQName: out of memory\n");
-- return(NULL);
-- }
-- }
-- buffer[len++] = c;
-- c = *cur++;
-- }
-- buffer[len] = 0;
-- }
--
-- if (buffer == NULL)
-- ret = xmlStrndup(buf, len);
-- else {
-- ret = buffer;
-- buffer = NULL;
-- max = XML_MAX_NAMELEN;
-- }
--
--
-- if (c == ':') {
-- c = *cur++;
-- if (c == 0) return(ret);
-- *prefix = ret;
-- len = 0;
--
-- while ((c != 0) && (len < max)) { /* tested bigname2.xml */
-- buf[len++] = c;
-- c = *cur++;
-- }
-- if (len >= max) {
-- /*
-- * Okay someone managed to make a huge name, so he's ready to pay
-- * for the processing speed.
-- */
-- max = len * 2;
--
-- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlSplitQName: out of memory\n");
-- return(NULL);
-- }
-- memcpy(buffer, buf, len);
-- while (c != 0) { /* tested bigname2.xml */
-- if (len + 10 > max) {
-- max *= 2;
-- buffer = (xmlChar *) xmlRealloc(buffer,
-- max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlSplitQName: out of memory\n");
-- return(NULL);
-- }
-- }
-- buffer[len++] = c;
-- c = *cur++;
-- }
-- buffer[len] = 0;
-- }
--
-- if (buffer == NULL)
-- ret = xmlStrndup(buf, len);
-- else {
-- ret = buffer;
-- }
-- }
--
-- return(ret);
--}
--
--/************************************************************************
-- * *
-- * The parser itself *
-- * Relates to http://www.w3.org/TR/REC-xml *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlParseName:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML name.
-- *
-- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-- * CombiningChar | Extender
-- *
-- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-- *
-- * [6] Names ::= Name (S Name)*
-- *
-- * Returns the Name parsed or NULL
-- */
--
--xmlChar *
--xmlParseName(xmlParserCtxtPtr ctxt) {
-- xmlChar buf[XML_MAX_NAMELEN + 5];
-- int len = 0, l;
-- int c;
-- int count = 0;
--
-- GROW;
-- c = CUR_CHAR(l);
-- if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
-- (!IS_LETTER(c) && (c != '_') &&
-- (c != ':'))) {
-- return(NULL);
-- }
--
-- while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
-- ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
-- (c == '.') || (c == '-') ||
-- (c == '_') || (c == ':') ||
-- (IS_COMBINING(c)) ||
-- (IS_EXTENDER(c)))) {
-- if (count++ > 100) {
-- count = 0;
-- GROW;
-- }
-- COPY_BUF(l,buf,len,c);
-- NEXTL(l);
-- c = CUR_CHAR(l);
-- if (len >= XML_MAX_NAMELEN) {
-- /*
-- * Okay someone managed to make a huge name, so he's ready to pay
-- * for the processing speed.
-- */
-- xmlChar *buffer;
-- int max = len * 2;
--
-- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseName: out of memory\n");
-- return(NULL);
-- }
-- memcpy(buffer, buf, len);
-- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
-- (c == '.') || (c == '-') ||
-- (c == '_') || (c == ':') ||
-- (IS_COMBINING(c)) ||
-- (IS_EXTENDER(c))) {
-- if (count++ > 100) {
-- count = 0;
-- GROW;
-- }
-- if (len + 10 > max) {
-- max *= 2;
-- buffer = (xmlChar *) xmlRealloc(buffer,
-- max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseName: out of memory\n");
-- return(NULL);
-- }
-- }
-- COPY_BUF(l,buffer,len,c);
-- NEXTL(l);
-- c = CUR_CHAR(l);
-- }
-- buffer[len] = 0;
-- return(buffer);
-- }
-- }
-- return(xmlStrndup(buf, len));
--}
--
--/**
-- * xmlParseStringName:
-- * @ctxt: an XML parser context
-- * @str: a pointer to the string pointer (IN/OUT)
-- *
-- * parse an XML name.
-- *
-- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-- * CombiningChar | Extender
-- *
-- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-- *
-- * [6] Names ::= Name (S Name)*
-- *
-- * Returns the Name parsed or NULL. The str pointer
-- * is updated to the current location in the string.
-- */
--
--xmlChar *
--xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
-- xmlChar buf[XML_MAX_NAMELEN + 5];
-- const xmlChar *cur = *str;
-- int len = 0, l;
-- int c;
--
-- c = CUR_SCHAR(cur, l);
-- if (!IS_LETTER(c) && (c != '_') &&
-- (c != ':')) {
-- return(NULL);
-- }
--
-- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
-- (c == '.') || (c == '-') ||
-- (c == '_') || (c == ':') ||
-- (IS_COMBINING(c)) ||
-- (IS_EXTENDER(c))) {
-- COPY_BUF(l,buf,len,c);
-- cur += l;
-- c = CUR_SCHAR(cur, l);
-- if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
-- /*
-- * Okay someone managed to make a huge name, so he's ready to pay
-- * for the processing speed.
-- */
-- xmlChar *buffer;
-- int max = len * 2;
--
-- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStringName: out of memory\n");
-- return(NULL);
-- }
-- memcpy(buffer, buf, len);
-- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
-- (c == '.') || (c == '-') ||
-- (c == '_') || (c == ':') ||
-- (IS_COMBINING(c)) ||
-- (IS_EXTENDER(c))) {
-- if (len + 10 > max) {
-- max *= 2;
-- buffer = (xmlChar *) xmlRealloc(buffer,
-- max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStringName: out of memory\n");
-- return(NULL);
-- }
-- }
-- COPY_BUF(l,buffer,len,c);
-- cur += l;
-- c = CUR_SCHAR(cur, l);
-- }
-- buffer[len] = 0;
-- *str = cur;
-- return(buffer);
-- }
-- }
-- *str = cur;
-- return(xmlStrndup(buf, len));
--}
--
--/**
-- * xmlParseNmtoken:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML Nmtoken.
-- *
-- * [7] Nmtoken ::= (NameChar)+
-- *
-- * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
-- *
-- * Returns the Nmtoken parsed or NULL
-- */
--
--xmlChar *
--xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
-- xmlChar buf[XML_MAX_NAMELEN + 5];
-- int len = 0, l;
-- int c;
-- int count = 0;
--
-- GROW;
-- c = CUR_CHAR(l);
--
-- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
-- (c == '.') || (c == '-') ||
-- (c == '_') || (c == ':') ||
-- (IS_COMBINING(c)) ||
-- (IS_EXTENDER(c))) {
-- if (count++ > 100) {
-- count = 0;
-- GROW;
-- }
-- COPY_BUF(l,buf,len,c);
-- NEXTL(l);
-- c = CUR_CHAR(l);
-- if (len >= XML_MAX_NAMELEN) {
-- /*
-- * Okay someone managed to make a huge token, so he's ready to pay
-- * for the processing speed.
-- */
-- xmlChar *buffer;
-- int max = len * 2;
--
-- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseNmtoken: out of memory\n");
-- return(NULL);
-- }
-- memcpy(buffer, buf, len);
-- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
-- (c == '.') || (c == '-') ||
-- (c == '_') || (c == ':') ||
-- (IS_COMBINING(c)) ||
-- (IS_EXTENDER(c))) {
-- if (count++ > 100) {
-- count = 0;
-- GROW;
-- }
-- if (len + 10 > max) {
-- max *= 2;
-- buffer = (xmlChar *) xmlRealloc(buffer,
-- max * sizeof(xmlChar));
-- if (buffer == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseName: out of memory\n");
-- return(NULL);
-- }
-- }
-- COPY_BUF(l,buffer,len,c);
-- NEXTL(l);
-- c = CUR_CHAR(l);
-- }
-- buffer[len] = 0;
-- return(buffer);
-- }
-- }
-- if (len == 0)
-- return(NULL);
-- return(xmlStrndup(buf, len));
--}
--
--/**
-- * xmlParseEntityValue:
-- * @ctxt: an XML parser context
-- * @orig: if non-NULL store a copy of the original entity value
-- *
-- * parse a value for ENTITY declarations
-- *
-- * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
-- * "'" ([^%&'] | PEReference | Reference)* "'"
-- *
-- * Returns the EntityValue parsed with reference substitued or NULL
-- */
--
--xmlChar *
--xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = XML_PARSER_BUFFER_SIZE;
-- int c, l;
-- xmlChar stop;
-- xmlChar *ret = NULL;
-- const xmlChar *cur = NULL;
-- xmlParserInputPtr input;
--
-- if (RAW == '"') stop = '"';
-- else if (RAW == '\'') stop = '\'';
-- else {
-- ctxt->errNo = XML_ERR_ENTITY_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "EntityValue: \" or ' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return(NULL);
-- }
--
-- /*
-- * The content of the entity definition is copied in a buffer.
-- */
--
-- ctxt->instate = XML_PARSER_ENTITY_VALUE;
-- input = ctxt->input;
-- GROW;
-- NEXT;
-- c = CUR_CHAR(l);
-- /*
-- * NOTE: 4.4.5 Included in Literal
-- * When a parameter entity reference appears in a literal entity
-- * value, ... a single or double quote character in the replacement
-- * text is always treated as a normal data character and will not
-- * terminate the literal.
-- * In practice it means we stop the loop only when back at parsing
-- * the initial entity and the quote is found
-- */
-- while ((IS_CHAR(c)) && ((c != stop) || /* checked */
-- (ctxt->input != input))) {
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- }
-- COPY_BUF(l,buf,len,c);
-- NEXTL(l);
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
-- xmlPopInput(ctxt);
--
-- GROW;
-- c = CUR_CHAR(l);
-- if (c == 0) {
-- GROW;
-- c = CUR_CHAR(l);
-- }
-- }
-- buf[len] = 0;
--
-- /*
-- * Raise problem w.r.t. '&' and '%' being used in non-entities
-- * reference constructs. Note Charref will be handled in
-- * xmlStringDecodeEntities()
-- */
-- cur = buf;
-- while (*cur != 0) { /* non input consuming */
-- if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
-- xmlChar *name;
-- xmlChar tmp = *cur;
--
-- cur++;
-- name = xmlParseStringName(ctxt, &cur);
-- if ((name == NULL) || (*cur != ';')) {
-- ctxt->errNo = XML_ERR_ENTITY_CHAR_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "EntityValue: '%c' forbidden except for entities references\n",
-- tmp);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if ((ctxt->inSubset == 1) && (tmp == '%')) {
-- ctxt->errNo = XML_ERR_ENTITY_PE_INTERNAL;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "EntityValue: PEReferences forbidden in internal subset\n",
-- tmp);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (name != NULL)
-- xmlFree(name);
-- }
-- cur++;
-- }
--
-- /*
-- * Then PEReference entities are substituted.
-- */
-- if (c != stop) {
-- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "EntityValue: \" expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFree(buf);
-- } else {
-- NEXT;
-- /*
-- * NOTE: 4.4.7 Bypassed
-- * When a general entity reference appears in the EntityValue in
-- * an entity declaration, it is bypassed and left as is.
-- * so XML_SUBSTITUTE_REF is not set here.
-- */
-- ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
-- 0, 0, 0);
-- if (orig != NULL)
-- *orig = buf;
-- else
-- xmlFree(buf);
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlParseAttValue:
-- * @ctxt: an XML parser context
-- *
-- * parse a value for an attribute
-- * Note: the parser won't do substitution of entities here, this
-- * will be handled later in xmlStringGetNodeList
-- *
-- * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
-- * "'" ([^<&'] | Reference)* "'"
-- *
-- * 3.3.3 Attribute-Value Normalization:
-- * Before the value of an attribute is passed to the application or
-- * checked for validity, the XML processor must normalize it as follows:
-- * - a character reference is processed by appending the referenced
-- * character to the attribute value
-- * - an entity reference is processed by recursively processing the
-- * replacement text of the entity
-- * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
-- * appending #x20 to the normalized value, except that only a single
-- * #x20 is appended for a "#xD#xA" sequence that is part of an external
-- * parsed entity or the literal entity value of an internal parsed entity
-- * - other characters are processed by appending them to the normalized value
-- * If the declared value is not CDATA, then the XML processor must further
-- * process the normalized attribute value by discarding any leading and
-- * trailing space (#x20) characters, and by replacing sequences of space
-- * (#x20) characters by a single space (#x20) character.
-- * All attributes for which no declaration has been read should be treated
-- * by a non-validating parser as if declared CDATA.
-- *
-- * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
-- */
--
--xmlChar *
--xmlParseAttValue(xmlParserCtxtPtr ctxt) {
-- xmlChar limit = 0;
-- xmlChar *buf = NULL;
-- int len = 0;
-- int buf_size = 0;
-- int c, l;
-- xmlChar *current = NULL;
-- xmlEntityPtr ent;
--
--
-- SHRINK;
-- if (NXT(0) == '"') {
-- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
-- limit = '"';
-- NEXT;
-- } else if (NXT(0) == '\'') {
-- limit = '\'';
-- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "AttValue: \" or ' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- /*
-- * allocate a translation buffer.
-- */
-- buf_size = XML_PARSER_BUFFER_SIZE;
-- buf = (xmlChar *) xmlMalloc(buf_size * sizeof(xmlChar));
-- if (buf == NULL) {
-- perror("xmlParseAttValue: malloc failed");
-- return(NULL);
-- }
--
-- /*
-- * Ok loop until we reach one of the ending char or a size limit.
-- */
-- c = CUR_CHAR(l);
-- while (((NXT(0) != limit) && /* checked */
-- (c != '<')) || (ctxt->token != 0)) {
-- if (c == 0) break;
-- if (ctxt->token == '&') {
-- /*
-- * The reparsing will be done in xmlStringGetNodeList()
-- * called by the attribute() function in SAX.c
-- */
-- static xmlChar buffer[6] = "&";
--
-- if (len > buf_size - 10) {
-- growBuffer(buf);
-- }
-- current = &buffer[0];
-- while (*current != 0) { /* non input consuming */
-- buf[len++] = *current++;
-- }
-- ctxt->token = 0;
-- } else if (c == '&') {
-- if (NXT(1) == '#') {
-- int val = xmlParseCharRef(ctxt);
-- if (val == '&') {
-- /*
-- * The reparsing will be done in xmlStringGetNodeList()
-- * called by the attribute() function in SAX.c
-- */
-- static xmlChar buffer[6] = "&";
--
-- if (len > buf_size - 10) {
-- growBuffer(buf);
-- }
-- current = &buffer[0];
-- while (*current != 0) { /* non input consuming */
-- buf[len++] = *current++;
-- }
-- } else {
-- len += xmlCopyChar(0, &buf[len], val);
-- }
-- } else {
-- ent = xmlParseEntityRef(ctxt);
-- if ((ent != NULL) &&
-- (ctxt->replaceEntities != 0)) {
-- xmlChar *rep;
--
-- if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
-- rep = xmlStringDecodeEntities(ctxt, ent->content,
-- XML_SUBSTITUTE_REF, 0, 0, 0);
-- if (rep != NULL) {
-- current = rep;
-- while (*current != 0) { /* non input consuming */
-- buf[len++] = *current++;
-- if (len > buf_size - 10) {
-- growBuffer(buf);
-- }
-- }
-- xmlFree(rep);
-- }
-- } else {
-- if (ent->content != NULL)
-- buf[len++] = ent->content[0];
-- }
-- } else if (ent != NULL) {
-- int i = xmlStrlen(ent->name);
-- const xmlChar *cur = ent->name;
--
-- /*
-- * This may look absurd but is needed to detect
-- * entities problems
-- */
-- if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
-- (ent->content != NULL)) {
-- xmlChar *rep;
-- rep = xmlStringDecodeEntities(ctxt, ent->content,
-- XML_SUBSTITUTE_REF, 0, 0, 0);
-- if (rep != NULL)
-- xmlFree(rep);
-- }
--
-- /*
-- * Just output the reference
-- */
-- buf[len++] = '&';
-- if (len > buf_size - i - 10) {
-- growBuffer(buf);
-- }
-- for (;i > 0;i--)
-- buf[len++] = *cur++;
-- buf[len++] = ';';
-- }
-- }
-- } else {
-- if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
-- COPY_BUF(l,buf,len,0x20);
-- if (len > buf_size - 10) {
-- growBuffer(buf);
-- }
-- } else {
-- COPY_BUF(l,buf,len,c);
-- if (len > buf_size - 10) {
-- growBuffer(buf);
-- }
-- }
-- NEXTL(l);
-- }
-- GROW;
-- c = CUR_CHAR(l);
-- }
-- buf[len++] = 0;
-- if (RAW == '<') {
-- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Unescaped '<' not allowed in attributes values\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if (RAW != limit) {
-- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- return(buf);
--}
--
--/**
-- * xmlParseSystemLiteral:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML Literal
-- *
-- * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
-- *
-- * Returns the SystemLiteral parsed or NULL
-- */
--
--xmlChar *
--xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = XML_PARSER_BUFFER_SIZE;
-- int cur, l;
-- xmlChar stop;
-- int state = ctxt->instate;
-- int count = 0;
--
-- SHRINK;
-- if (RAW == '"') {
-- NEXT;
-- stop = '"';
-- } else if (RAW == '\'') {
-- NEXT;
-- stop = '\'';
-- } else {
-- ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "SystemLiteral \" or ' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
-- cur = CUR_CHAR(l);
-- while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- ctxt->instate = (xmlParserInputState) state;
-- return(NULL);
-- }
-- }
-- count++;
-- if (count > 50) {
-- GROW;
-- count = 0;
-- }
-- COPY_BUF(l,buf,len,cur);
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- if (cur == 0) {
-- GROW;
-- SHRINK;
-- cur = CUR_CHAR(l);
-- }
-- }
-- buf[len] = 0;
-- ctxt->instate = (xmlParserInputState) state;
-- if (!IS_CHAR(cur)) {
-- ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- NEXT;
-- }
-- return(buf);
--}
--
--/**
-- * xmlParsePubidLiteral:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML public literal
-- *
-- * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
-- *
-- * Returns the PubidLiteral parsed or NULL.
-- */
--
--xmlChar *
--xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = XML_PARSER_BUFFER_SIZE;
-- xmlChar cur;
-- xmlChar stop;
-- int count = 0;
--
-- SHRINK;
-- if (RAW == '"') {
-- NEXT;
-- stop = '"';
-- } else if (RAW == '\'') {
-- NEXT;
-- stop = '\'';
-- } else {
-- ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "SystemLiteral \" or ' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- cur = CUR;
-- while ((IS_PUBIDCHAR(cur)) && (cur != stop)) { /* checked */
-- if (len + 1 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- }
-- buf[len++] = cur;
-- count++;
-- if (count > 50) {
-- GROW;
-- count = 0;
-- }
-- NEXT;
-- cur = CUR;
-- if (cur == 0) {
-- GROW;
-- SHRINK;
-- cur = CUR;
-- }
-- }
-- buf[len] = 0;
-- if (cur != stop) {
-- ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- NEXT;
-- }
-- return(buf);
--}
--
--/**
-- * xmlParseCharData:
-- * @ctxt: an XML parser context
-- * @cdata: int indicating whether we are within a CDATA section
-- *
-- * parse a CharData section.
-- * if we are within a CDATA section ']]>' marks an end of section.
-- *
-- * The right angle bracket (>) may be represented using the string ">",
-- * and must, for compatibility, be escaped using ">" or a character
-- * reference when it appears in the string "]]>" in content, when that
-- * string is not marking the end of a CDATA section.
-- *
-- * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-- */
--
--void
--xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
-- xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
-- int nbchar = 0;
-- int cur, l;
-- int count = 0;
--
-- SHRINK;
-- GROW;
-- cur = CUR_CHAR(l);
-- while (((cur != '<') || (ctxt->token == '<')) && /* checked */
-- ((cur != '&') || (ctxt->token == '&')) &&
-- (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
-- if ((cur == ']') && (NXT(1) == ']') &&
-- (NXT(2) == '>')) {
-- if (cdata) break;
-- else {
-- ctxt->errNo = XML_ERR_MISPLACED_CDATA_END;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Sequence ']]>' not allowed in content\n");
-- /* Should this be relaxed ??? I see a "must here */
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
-- COPY_BUF(l,buf,nbchar,cur);
-- if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
-- /*
-- * Ok the segment is to be consumed as chars.
-- */
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (areBlanks(ctxt, buf, nbchar)) {
-- if (ctxt->sax->ignorableWhitespace != NULL)
-- ctxt->sax->ignorableWhitespace(ctxt->userData,
-- buf, nbchar);
-- } else {
-- if (ctxt->sax->characters != NULL)
-- ctxt->sax->characters(ctxt->userData, buf, nbchar);
-- }
-- }
-- nbchar = 0;
-- }
-- count++;
-- if (count > 50) {
-- GROW;
-- count = 0;
-- }
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- }
-- if (nbchar != 0) {
-- /*
-- * Ok the segment is to be consumed as chars.
-- */
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (areBlanks(ctxt, buf, nbchar)) {
-- if (ctxt->sax->ignorableWhitespace != NULL)
-- ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
-- } else {
-- if (ctxt->sax->characters != NULL)
-- ctxt->sax->characters(ctxt->userData, buf, nbchar);
-- }
-- }
-- }
--}
--
--/**
-- * xmlParseExternalID:
-- * @ctxt: an XML parser context
-- * @publicID: a xmlChar** receiving PubidLiteral
-- * @strict: indicate whether we should restrict parsing to only
-- * production [75], see NOTE below
-- *
-- * Parse an External ID or a Public ID
-- *
-- * NOTE: Productions [75] and [83] interract badly since [75] can generate
-- * 'PUBLIC' S PubidLiteral S SystemLiteral
-- *
-- * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-- * | 'PUBLIC' S PubidLiteral S SystemLiteral
-- *
-- * [83] PublicID ::= 'PUBLIC' S PubidLiteral
-- *
-- * Returns the function returns SystemLiteral and in the second
-- * case publicID receives PubidLiteral, is strict is off
-- * it is possible to return NULL and have publicID set.
-- */
--
--xmlChar *
--xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
-- xmlChar *URI = NULL;
--
-- SHRINK;
-- if ((RAW == 'S') && (NXT(1) == 'Y') &&
-- (NXT(2) == 'S') && (NXT(3) == 'T') &&
-- (NXT(4) == 'E') && (NXT(5) == 'M')) {
-- SKIP(6);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'SYSTEM'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- URI = xmlParseSystemLiteral(ctxt);
-- if (URI == NULL) {
-- ctxt->errNo = XML_ERR_URI_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseExternalID: SYSTEM, no URI\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- } else if ((RAW == 'P') && (NXT(1) == 'U') &&
-- (NXT(2) == 'B') && (NXT(3) == 'L') &&
-- (NXT(4) == 'I') && (NXT(5) == 'C')) {
-- SKIP(6);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'PUBLIC'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- *publicID = xmlParsePubidLiteral(ctxt);
-- if (*publicID == NULL) {
-- ctxt->errNo = XML_ERR_PUBID_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseExternalID: PUBLIC, no Public Identifier\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (strict) {
-- /*
-- * We don't handle [83] so "S SystemLiteral" is required.
-- */
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the Public Identifier\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- } else {
-- /*
-- * We handle [83] so we return immediately, if
-- * "S SystemLiteral" is not detected. From a purely parsing
-- * point of view that's a nice mess.
-- */
-- const xmlChar *ptr;
-- GROW;
--
-- ptr = CUR_PTR;
-- if (!IS_BLANK(*ptr)) return(NULL);
--
-- while (IS_BLANK(*ptr)) ptr++; /* TODO: dangerous, fix ! */
-- if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
-- }
-- SKIP_BLANKS;
-- URI = xmlParseSystemLiteral(ctxt);
-- if (URI == NULL) {
-- ctxt->errNo = XML_ERR_URI_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseExternalID: PUBLIC, no URI\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
-- return(URI);
--}
--
--/**
-- * xmlParseComment:
-- * @ctxt: an XML parser context
-- *
-- * Skip an XML (SGML) comment <!-- .... -->
-- * The spec says that "For compatibility, the string "--" (double-hyphen)
-- * must not occur within comments. "
-- *
-- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-- */
--void
--xmlParseComment(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len;
-- int size = XML_PARSER_BUFFER_SIZE;
-- int q, ql;
-- int r, rl;
-- int cur, l;
-- xmlParserInputState state;
-- xmlParserInputPtr input = ctxt->input;
-- int count = 0;
--
-- /*
-- * Check that there is a comment right here.
-- */
-- if ((RAW != '<') || (NXT(1) != '!') ||
-- (NXT(2) != '-') || (NXT(3) != '-')) return;
--
-- state = ctxt->instate;
-- ctxt->instate = XML_PARSER_COMMENT;
-- SHRINK;
-- SKIP(4);
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- ctxt->instate = state;
-- return;
-- }
-- q = CUR_CHAR(ql);
-- NEXTL(ql);
-- r = CUR_CHAR(rl);
-- NEXTL(rl);
-- cur = CUR_CHAR(l);
-- len = 0;
-- while (IS_CHAR(cur) && /* checked */
-- ((cur != '>') ||
-- (r != '-') || (q != '-'))) {
-- if ((r == '-') && (q == '-') && (len > 1)) {
-- ctxt->errNo = XML_ERR_HYPHEN_IN_COMMENT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Comment must not contain '--' (double-hyphen)`\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- ctxt->instate = state;
-- return;
-- }
-- }
-- COPY_BUF(ql,buf,len,q);
-- q = r;
-- ql = rl;
-- r = cur;
-- rl = l;
--
-- count++;
-- if (count > 50) {
-- GROW;
-- count = 0;
-- }
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- if (cur == 0) {
-- SHRINK;
-- GROW;
-- cur = CUR_CHAR(l);
-- }
-- }
-- buf[len] = 0;
-- if (!IS_CHAR(cur)) {
-- ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Comment not terminated \n<!--%.50s\n", buf);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFree(buf);
-- } else {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Comment doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- NEXT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->comment(ctxt->userData, buf);
-- xmlFree(buf);
-- }
-- ctxt->instate = state;
--}
--
--/**
-- * xmlParsePITarget:
-- * @ctxt: an XML parser context
-- *
-- * parse the name of a PI
-- *
-- * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
-- *
-- * Returns the PITarget name or NULL
-- */
--
--xmlChar *
--xmlParsePITarget(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
--
-- name = xmlParseName(ctxt);
-- if ((name != NULL) &&
-- ((name[0] == 'x') || (name[0] == 'X')) &&
-- ((name[1] == 'm') || (name[1] == 'M')) &&
-- ((name[2] == 'l') || (name[2] == 'L'))) {
-- int i;
-- if ((name[0] == 'x') && (name[1] == 'm') &&
-- (name[2] == 'l') && (name[3] == 0)) {
-- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML declaration allowed only at the start of the document\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(name);
-- } else if (name[3] == 0) {
-- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Invalid PI name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(name);
-- }
-- for (i = 0;;i++) {
-- if (xmlW3CPIs[i] == NULL) break;
-- if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
-- return(name);
-- }
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) {
-- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
-- ctxt->sax->warning(ctxt->userData,
-- "xmlParsePItarget: invalid name prefix 'xml'\n");
-- }
-- }
-- return(name);
--}
--
--/**
-- * xmlParsePI:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML Processing Instruction.
-- *
-- * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
-- *
-- * The processing is transfered to SAX once parsed.
-- */
--
--void
--xmlParsePI(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = XML_PARSER_BUFFER_SIZE;
-- int cur, l;
-- xmlChar *target;
-- xmlParserInputState state;
-- int count = 0;
--
-- if ((RAW == '<') && (NXT(1) == '?')) {
-- xmlParserInputPtr input = ctxt->input;
-- state = ctxt->instate;
-- ctxt->instate = XML_PARSER_PI;
-- /*
-- * this is a Processing Instruction.
-- */
-- SKIP(2);
-- SHRINK;
--
-- /*
-- * Parse the target name and check for special support like
-- * namespace.
-- */
-- target = xmlParsePITarget(ctxt);
-- if (target != NULL) {
-- if ((RAW == '?') && (NXT(1) == '>')) {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "PI declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP(2);
--
-- /*
-- * SAX: PI detected.
-- */
-- if ((ctxt->sax) && (!ctxt->disableSAX) &&
-- (ctxt->sax->processingInstruction != NULL))
-- ctxt->sax->processingInstruction(ctxt->userData,
-- target, NULL);
-- ctxt->instate = state;
-- xmlFree(target);
-- return;
-- }
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- ctxt->instate = state;
-- return;
-- }
-- cur = CUR;
-- if (!IS_BLANK(cur)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParsePI: PI %s space expected\n", target);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- cur = CUR_CHAR(l);
-- while (IS_CHAR(cur) && /* checked */
-- ((cur != '?') || (NXT(1) != '>'))) {
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- ctxt->instate = state;
-- return;
-- }
-- }
-- count++;
-- if (count > 50) {
-- GROW;
-- count = 0;
-- }
-- COPY_BUF(l,buf,len,cur);
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- if (cur == 0) {
-- SHRINK;
-- GROW;
-- cur = CUR_CHAR(l);
-- }
-- }
-- buf[len] = 0;
-- if (cur != '?') {
-- ctxt->errNo = XML_ERR_PI_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParsePI: PI %s never end ...\n", target);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "PI declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP(2);
--
-- /*
-- * SAX: PI detected.
-- */
-- if ((ctxt->sax) && (!ctxt->disableSAX) &&
-- (ctxt->sax->processingInstruction != NULL))
-- ctxt->sax->processingInstruction(ctxt->userData,
-- target, buf);
-- }
-- xmlFree(buf);
-- xmlFree(target);
-- } else {
-- ctxt->errNo = XML_ERR_PI_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParsePI : no target name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- ctxt->instate = state;
-- }
--}
--
--/**
-- * xmlParseNotationDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse a notation declaration
-- *
-- * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
-- *
-- * Hence there is actually 3 choices:
-- * 'PUBLIC' S PubidLiteral
-- * 'PUBLIC' S PubidLiteral S SystemLiteral
-- * and 'SYSTEM' S SystemLiteral
-- *
-- * See the NOTE on xmlParseExternalID().
-- */
--
--void
--xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *Pubid;
-- xmlChar *Systemid;
--
-- if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == 'N') && (NXT(3) == 'O') &&
-- (NXT(4) == 'T') && (NXT(5) == 'A') &&
-- (NXT(6) == 'T') && (NXT(7) == 'I') &&
-- (NXT(8) == 'O') && (NXT(9) == 'N')) {
-- xmlParserInputPtr input = ctxt->input;
-- SHRINK;
-- SKIP(10);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after '<!NOTATION'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- SKIP_BLANKS;
--
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "NOTATION: Name expected here\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the NOTATION name'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- SKIP_BLANKS;
--
-- /*
-- * Parse the IDs.
-- */
-- Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
-- SKIP_BLANKS;
--
-- if (RAW == '>') {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Notation declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- NEXT;
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->notationDecl != NULL))
-- ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
-- } else {
-- ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "'>' required to close NOTATION declaration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlFree(name);
-- if (Systemid != NULL) xmlFree(Systemid);
-- if (Pubid != NULL) xmlFree(Pubid);
-- }
--}
--
--/**
-- * xmlParseEntityDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse <!ENTITY declarations
-- *
-- * [70] EntityDecl ::= GEDecl | PEDecl
-- *
-- * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
-- *
-- * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
-- *
-- * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
-- *
-- * [74] PEDef ::= EntityValue | ExternalID
-- *
-- * [76] NDataDecl ::= S 'NDATA' S Name
-- *
-- * [ VC: Notation Declared ]
-- * The Name must match the declared name of a notation.
-- */
--
--void
--xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *name = NULL;
-- xmlChar *value = NULL;
-- xmlChar *URI = NULL, *literal = NULL;
-- xmlChar *ndata = NULL;
-- int isParameter = 0;
-- xmlChar *orig = NULL;
--
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == 'E') && (NXT(3) == 'N') &&
-- (NXT(4) == 'T') && (NXT(5) == 'I') &&
-- (NXT(6) == 'T') && (NXT(7) == 'Y')) {
-- xmlParserInputPtr input = ctxt->input;
-- ctxt->instate = XML_PARSER_ENTITY_DECL;
-- SHRINK;
-- SKIP(8);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after '<!ENTITY'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
--
-- if (RAW == '%') {
-- NEXT;
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after '%'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- isParameter = 1;
-- }
--
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "xmlParseEntityDecl: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the entity name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
--
-- /*
-- * handle the various case of definitions...
-- */
-- if (isParameter) {
-- if ((RAW == '"') || (RAW == '\'')) {
-- value = xmlParseEntityValue(ctxt, &orig);
-- if (value) {
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
-- ctxt->sax->entityDecl(ctxt->userData, name,
-- XML_INTERNAL_PARAMETER_ENTITY,
-- NULL, NULL, value);
-- }
-- } else {
-- URI = xmlParseExternalID(ctxt, &literal, 1);
-- if ((URI == NULL) && (literal == NULL)) {
-- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity value required\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (URI) {
-- xmlURIPtr uri;
--
-- uri = xmlParseURI((const char *) URI);
-- if (uri == NULL) {
-- ctxt->errNo = XML_ERR_INVALID_URI;
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Invalid URI: %s\n", URI);
-- ctxt->wellFormed = 0;
-- } else {
-- if (uri->fragment != NULL) {
-- ctxt->errNo = XML_ERR_URI_FRAGMENT;
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Fragment not allowed: %s\n", URI);
-- ctxt->wellFormed = 0;
-- } else {
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) &&
-- (ctxt->sax->entityDecl != NULL))
-- ctxt->sax->entityDecl(ctxt->userData, name,
-- XML_EXTERNAL_PARAMETER_ENTITY,
-- literal, URI, NULL);
-- }
-- xmlFreeURI(uri);
-- }
-- }
-- }
-- } else {
-- if ((RAW == '"') || (RAW == '\'')) {
-- value = xmlParseEntityValue(ctxt, &orig);
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
-- ctxt->sax->entityDecl(ctxt->userData, name,
-- XML_INTERNAL_GENERAL_ENTITY,
-- NULL, NULL, value);
-- } else {
-- URI = xmlParseExternalID(ctxt, &literal, 1);
-- if ((URI == NULL) && (literal == NULL)) {
-- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity value required\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (URI) {
-- xmlURIPtr uri;
--
-- uri = xmlParseURI((const char *)URI);
-- if (uri == NULL) {
-- ctxt->errNo = XML_ERR_INVALID_URI;
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Invalid URI: %s\n", URI);
-- ctxt->wellFormed = 0;
-- } else {
-- if (uri->fragment != NULL) {
-- ctxt->errNo = XML_ERR_URI_FRAGMENT;
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Fragment not allowed: %s\n", URI);
-- ctxt->wellFormed = 0;
-- }
-- xmlFreeURI(uri);
-- }
-- }
-- if ((RAW != '>') && (!IS_BLANK(CUR))) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required before 'NDATA'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- if ((RAW == 'N') && (NXT(1) == 'D') &&
-- (NXT(2) == 'A') && (NXT(3) == 'T') &&
-- (NXT(4) == 'A')) {
-- SKIP(5);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'NDATA'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- ndata = xmlParseName(ctxt);
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->unparsedEntityDecl != NULL))
-- ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
-- literal, URI, ndata);
-- } else {
-- if ((ctxt->sax != NULL) &&
-- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
-- ctxt->sax->entityDecl(ctxt->userData, name,
-- XML_EXTERNAL_GENERAL_PARSED_ENTITY,
-- literal, URI, NULL);
-- }
-- }
-- }
-- SKIP_BLANKS;
-- if (RAW != '>') {
-- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEntityDecl: entity %s not terminated\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Entity declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- NEXT;
-- }
-- if (orig != NULL) {
-- /*
-- * Ugly mechanism to save the raw entity value.
-- */
-- xmlEntityPtr cur = NULL;
--
-- if (isParameter) {
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->getParameterEntity != NULL))
-- cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
-- } else {
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->getEntity != NULL))
-- cur = ctxt->sax->getEntity(ctxt->userData, name);
-- }
-- if (cur != NULL) {
-- if (cur->orig != NULL)
-- xmlFree(orig);
-- else
-- cur->orig = orig;
-- } else
-- xmlFree(orig);
-- }
-- if (name != NULL) xmlFree(name);
-- if (value != NULL) xmlFree(value);
-- if (URI != NULL) xmlFree(URI);
-- if (literal != NULL) xmlFree(literal);
-- if (ndata != NULL) xmlFree(ndata);
-- }
--}
--
--/**
-- * xmlParseDefaultDecl:
-- * @ctxt: an XML parser context
-- * @value: Receive a possible fixed default value for the attribute
-- *
-- * Parse an attribute default declaration
-- *
-- * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
-- *
-- * [ VC: Required Attribute ]
-- * if the default declaration is the keyword #REQUIRED, then the
-- * attribute must be specified for all elements of the type in the
-- * attribute-list declaration.
-- *
-- * [ VC: Attribute Default Legal ]
-- * The declared default value must meet the lexical constraints of
-- * the declared attribute type c.f. xmlValidateAttributeDecl()
-- *
-- * [ VC: Fixed Attribute Default ]
-- * if an attribute has a default value declared with the #FIXED
-- * keyword, instances of that attribute must match the default value.
-- *
-- * [ WFC: No < in Attribute Values ]
-- * handled in xmlParseAttValue()
-- *
-- * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
-- * or XML_ATTRIBUTE_FIXED.
-- */
--
--int
--xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
-- int val;
-- xmlChar *ret;
--
-- *value = NULL;
-- if ((RAW == '#') && (NXT(1) == 'R') &&
-- (NXT(2) == 'E') && (NXT(3) == 'Q') &&
-- (NXT(4) == 'U') && (NXT(5) == 'I') &&
-- (NXT(6) == 'R') && (NXT(7) == 'E') &&
-- (NXT(8) == 'D')) {
-- SKIP(9);
-- return(XML_ATTRIBUTE_REQUIRED);
-- }
-- if ((RAW == '#') && (NXT(1) == 'I') &&
-- (NXT(2) == 'M') && (NXT(3) == 'P') &&
-- (NXT(4) == 'L') && (NXT(5) == 'I') &&
-- (NXT(6) == 'E') && (NXT(7) == 'D')) {
-- SKIP(8);
-- return(XML_ATTRIBUTE_IMPLIED);
-- }
-- val = XML_ATTRIBUTE_NONE;
-- if ((RAW == '#') && (NXT(1) == 'F') &&
-- (NXT(2) == 'I') && (NXT(3) == 'X') &&
-- (NXT(4) == 'E') && (NXT(5) == 'D')) {
-- SKIP(6);
-- val = XML_ATTRIBUTE_FIXED;
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after '#FIXED'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- }
-- ret = xmlParseAttValue(ctxt);
-- ctxt->instate = XML_PARSER_DTD;
-- if (ret == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attribute default value declaration error\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- *value = ret;
-- return(val);
--}
--
--/**
-- * xmlParseNotationType:
-- * @ctxt: an XML parser context
-- *
-- * parse an Notation attribute type.
-- *
-- * Note: the leading 'NOTATION' S part has already being parsed...
-- *
-- * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
-- *
-- * [ VC: Notation Attributes ]
-- * Values of this type must match one of the notation names included
-- * in the declaration; all notation names in the declaration must be declared.
-- *
-- * Returns: the notation attribute tree built while parsing
-- */
--
--xmlEnumerationPtr
--xmlParseNotationType(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlEnumerationPtr ret = NULL, last = NULL, cur;
--
-- if (RAW != '(') {
-- ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "'(' required to start 'NOTATION'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- SHRINK;
-- do {
-- NEXT;
-- SKIP_BLANKS;
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Name expected in NOTATION declaration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(ret);
-- }
-- cur = xmlCreateEnumeration(name);
-- xmlFree(name);
-- if (cur == NULL) return(ret);
-- if (last == NULL) ret = last = cur;
-- else {
-- last->next = cur;
-- last = cur;
-- }
-- SKIP_BLANKS;
-- } while (RAW == '|');
-- if (RAW != ')') {
-- ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "')' required to finish NOTATION declaration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if ((last != NULL) && (last != ret))
-- xmlFreeEnumeration(last);
-- return(ret);
-- }
-- NEXT;
-- return(ret);
--}
--
--/**
-- * xmlParseEnumerationType:
-- * @ctxt: an XML parser context
-- *
-- * parse an Enumeration attribute type.
-- *
-- * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
-- *
-- * [ VC: Enumeration ]
-- * Values of this type must match one of the Nmtoken tokens in
-- * the declaration
-- *
-- * Returns: the enumeration attribute tree built while parsing
-- */
--
--xmlEnumerationPtr
--xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlEnumerationPtr ret = NULL, last = NULL, cur;
--
-- if (RAW != '(') {
-- ctxt->errNo = XML_ERR_ATTLIST_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "'(' required to start ATTLIST enumeration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- SHRINK;
-- do {
-- NEXT;
-- SKIP_BLANKS;
-- name = xmlParseNmtoken(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NMTOKEN_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "NmToken expected in ATTLIST enumeration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(ret);
-- }
-- cur = xmlCreateEnumeration(name);
-- xmlFree(name);
-- if (cur == NULL) return(ret);
-- if (last == NULL) ret = last = cur;
-- else {
-- last->next = cur;
-- last = cur;
-- }
-- SKIP_BLANKS;
-- } while (RAW == '|');
-- if (RAW != ')') {
-- ctxt->errNo = XML_ERR_ATTLIST_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "')' required to finish ATTLIST enumeration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(ret);
-- }
-- NEXT;
-- return(ret);
--}
--
--/**
-- * xmlParseEnumeratedType:
-- * @ctxt: an XML parser context
-- * @tree: the enumeration tree built while parsing
-- *
-- * parse an Enumerated attribute type.
-- *
-- * [57] EnumeratedType ::= NotationType | Enumeration
-- *
-- * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
-- *
-- *
-- * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
-- */
--
--int
--xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
-- if ((RAW == 'N') && (NXT(1) == 'O') &&
-- (NXT(2) == 'T') && (NXT(3) == 'A') &&
-- (NXT(4) == 'T') && (NXT(5) == 'I') &&
-- (NXT(6) == 'O') && (NXT(7) == 'N')) {
-- SKIP(8);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'NOTATION'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(0);
-- }
-- SKIP_BLANKS;
-- *tree = xmlParseNotationType(ctxt);
-- if (*tree == NULL) return(0);
-- return(XML_ATTRIBUTE_NOTATION);
-- }
-- *tree = xmlParseEnumerationType(ctxt);
-- if (*tree == NULL) return(0);
-- return(XML_ATTRIBUTE_ENUMERATION);
--}
--
--/**
-- * xmlParseAttributeType:
-- * @ctxt: an XML parser context
-- * @tree: the enumeration tree built while parsing
-- *
-- * parse the Attribute list def for an element
-- *
-- * [54] AttType ::= StringType | TokenizedType | EnumeratedType
-- *
-- * [55] StringType ::= 'CDATA'
-- *
-- * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
-- * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
-- *
-- * Validity constraints for attribute values syntax are checked in
-- * xmlValidateAttributeValue()
-- *
-- * [ VC: ID ]
-- * Values of type ID must match the Name production. A name must not
-- * appear more than once in an XML document as a value of this type;
-- * i.e., ID values must uniquely identify the elements which bear them.
-- *
-- * [ VC: One ID per Element Type ]
-- * No element type may have more than one ID attribute specified.
-- *
-- * [ VC: ID Attribute Default ]
-- * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
-- *
-- * [ VC: IDREF ]
-- * Values of type IDREF must match the Name production, and values
-- * of type IDREFS must match Names; each IDREF Name must match the value
-- * of an ID attribute on some element in the XML document; i.e. IDREF
-- * values must match the value of some ID attribute.
-- *
-- * [ VC: Entity Name ]
-- * Values of type ENTITY must match the Name production, values
-- * of type ENTITIES must match Names; each Entity Name must match the
-- * name of an unparsed entity declared in the DTD.
-- *
-- * [ VC: Name Token ]
-- * Values of type NMTOKEN must match the Nmtoken production; values
-- * of type NMTOKENS must match Nmtokens.
-- *
-- * Returns the attribute type
-- */
--int
--xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
-- SHRINK;
-- if ((RAW == 'C') && (NXT(1) == 'D') &&
-- (NXT(2) == 'A') && (NXT(3) == 'T') &&
-- (NXT(4) == 'A')) {
-- SKIP(5);
-- return(XML_ATTRIBUTE_CDATA);
-- } else if ((RAW == 'I') && (NXT(1) == 'D') &&
-- (NXT(2) == 'R') && (NXT(3) == 'E') &&
-- (NXT(4) == 'F') && (NXT(5) == 'S')) {
-- SKIP(6);
-- return(XML_ATTRIBUTE_IDREFS);
-- } else if ((RAW == 'I') && (NXT(1) == 'D') &&
-- (NXT(2) == 'R') && (NXT(3) == 'E') &&
-- (NXT(4) == 'F')) {
-- SKIP(5);
-- return(XML_ATTRIBUTE_IDREF);
-- } else if ((RAW == 'I') && (NXT(1) == 'D')) {
-- SKIP(2);
-- return(XML_ATTRIBUTE_ID);
-- } else if ((RAW == 'E') && (NXT(1) == 'N') &&
-- (NXT(2) == 'T') && (NXT(3) == 'I') &&
-- (NXT(4) == 'T') && (NXT(5) == 'Y')) {
-- SKIP(6);
-- return(XML_ATTRIBUTE_ENTITY);
-- } else if ((RAW == 'E') && (NXT(1) == 'N') &&
-- (NXT(2) == 'T') && (NXT(3) == 'I') &&
-- (NXT(4) == 'T') && (NXT(5) == 'I') &&
-- (NXT(6) == 'E') && (NXT(7) == 'S')) {
-- SKIP(8);
-- return(XML_ATTRIBUTE_ENTITIES);
-- } else if ((RAW == 'N') && (NXT(1) == 'M') &&
-- (NXT(2) == 'T') && (NXT(3) == 'O') &&
-- (NXT(4) == 'K') && (NXT(5) == 'E') &&
-- (NXT(6) == 'N') && (NXT(7) == 'S')) {
-- SKIP(8);
-- return(XML_ATTRIBUTE_NMTOKENS);
-- } else if ((RAW == 'N') && (NXT(1) == 'M') &&
-- (NXT(2) == 'T') && (NXT(3) == 'O') &&
-- (NXT(4) == 'K') && (NXT(5) == 'E') &&
-- (NXT(6) == 'N')) {
-- SKIP(7);
-- return(XML_ATTRIBUTE_NMTOKEN);
-- }
-- return(xmlParseEnumeratedType(ctxt, tree));
--}
--
--/**
-- * xmlParseAttributeListDecl:
-- * @ctxt: an XML parser context
-- *
-- * : parse the Attribute list def for an element
-- *
-- * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
-- *
-- * [53] AttDef ::= S Name S AttType S DefaultDecl
-- *
-- */
--void
--xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *elemName;
-- xmlChar *attrName;
-- xmlEnumerationPtr tree;
--
-- if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == 'A') && (NXT(3) == 'T') &&
-- (NXT(4) == 'T') && (NXT(5) == 'L') &&
-- (NXT(6) == 'I') && (NXT(7) == 'S') &&
-- (NXT(8) == 'T')) {
-- xmlParserInputPtr input = ctxt->input;
--
-- SKIP(9);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after '<!ATTLIST'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- elemName = xmlParseName(ctxt);
-- if (elemName == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "ATTLIST: no name for Element\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- SKIP_BLANKS;
-- GROW;
-- while (RAW != '>') {
-- const xmlChar *check = CUR_PTR;
-- int type;
-- int def;
-- xmlChar *defaultValue = NULL;
--
-- GROW;
-- tree = NULL;
-- attrName = xmlParseName(ctxt);
-- if (attrName == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "ATTLIST: no name for Attribute\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- }
-- GROW;
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the attribute name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- break;
-- }
-- SKIP_BLANKS;
--
-- type = xmlParseAttributeType(ctxt, &tree);
-- if (type <= 0) {
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- break;
-- }
--
-- GROW;
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the attribute type\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- if (tree != NULL)
-- xmlFreeEnumeration(tree);
-- break;
-- }
-- SKIP_BLANKS;
--
-- def = xmlParseDefaultDecl(ctxt, &defaultValue);
-- if (def <= 0) {
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- if (tree != NULL)
-- xmlFreeEnumeration(tree);
-- break;
-- }
--
-- GROW;
-- if (RAW != '>') {
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the attribute default value\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- if (tree != NULL)
-- xmlFreeEnumeration(tree);
-- break;
-- }
-- SKIP_BLANKS;
-- }
-- if (check == CUR_PTR) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseAttributeListDecl: detected internal error\n");
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- if (tree != NULL)
-- xmlFreeEnumeration(tree);
-- break;
-- }
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->attributeDecl != NULL))
-- ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
-- type, def, defaultValue, tree);
-- if (attrName != NULL)
-- xmlFree(attrName);
-- if (defaultValue != NULL)
-- xmlFree(defaultValue);
-- GROW;
-- }
-- if (RAW == '>') {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Attribute list declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- NEXT;
-- }
--
-- xmlFree(elemName);
-- }
--}
--
--/**
-- * xmlParseElementMixedContentDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse the declaration for a Mixed Element content
-- * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
-- *
-- * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
-- * '(' S? '#PCDATA' S? ')'
-- *
-- * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
-- *
-- * [ VC: No Duplicate Types ]
-- * The same name must not appear more than once in a single
-- * mixed-content declaration.
-- *
-- * returns: the list of the xmlElementContentPtr describing the element choices
-- */
--xmlElementContentPtr
--xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt) {
-- xmlElementContentPtr ret = NULL, cur = NULL, n;
-- xmlChar *elem = NULL;
--
-- GROW;
-- if ((RAW == '#') && (NXT(1) == 'P') &&
-- (NXT(2) == 'C') && (NXT(3) == 'D') &&
-- (NXT(4) == 'A') && (NXT(5) == 'T') &&
-- (NXT(6) == 'A')) {
-- SKIP(7);
-- SKIP_BLANKS;
-- SHRINK;
-- if (RAW == ')') {
-- ctxt->entity = ctxt->input;
-- NEXT;
-- ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
-- if (RAW == '*') {
-- ret->ocur = XML_ELEMENT_CONTENT_MULT;
-- NEXT;
-- }
-- return(ret);
-- }
-- if ((RAW == '(') || (RAW == '|')) {
-- ret = cur = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
-- if (ret == NULL) return(NULL);
-- }
-- while (RAW == '|') {
-- NEXT;
-- if (elem == NULL) {
-- ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
-- if (ret == NULL) return(NULL);
-- ret->c1 = cur;
-- cur = ret;
-- } else {
-- n = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
-- if (n == NULL) return(NULL);
-- n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
-- cur->c2 = n;
-- cur = n;
-- xmlFree(elem);
-- }
-- SKIP_BLANKS;
-- elem = xmlParseName(ctxt);
-- if (elem == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementMixedContentDecl : Name expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFreeElementContent(cur);
-- return(NULL);
-- }
-- SKIP_BLANKS;
-- GROW;
-- }
-- if ((RAW == ')') && (NXT(1) == '*')) {
-- if (elem != NULL) {
-- cur->c2 = xmlNewElementContent(elem,
-- XML_ELEMENT_CONTENT_ELEMENT);
-- xmlFree(elem);
-- }
-- ret->ocur = XML_ELEMENT_CONTENT_MULT;
-- ctxt->entity = ctxt->input;
-- SKIP(2);
-- } else {
-- if (elem != NULL) xmlFree(elem);
-- xmlFreeElementContent(ret);
-- ctxt->errNo = XML_ERR_MIXED_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementMixedContentDecl : '|' or ')*' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- } else {
-- ctxt->errNo = XML_ERR_PCDATA_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementMixedContentDecl : '#PCDATA' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(ret);
--}
--
--/**
-- * xmlParseElementChildrenContentDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse the declaration for a Mixed Element content
-- * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
-- *
-- *
-- * [47] children ::= (choice | seq) ('?' | '*' | '+')?
-- *
-- * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
-- *
-- * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
-- *
-- * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
-- *
-- * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
-- * TODO Parameter-entity replacement text must be properly nested
-- * with parenthetized groups. That is to say, if either of the
-- * opening or closing parentheses in a choice, seq, or Mixed
-- * construct is contained in the replacement text for a parameter
-- * entity, both must be contained in the same replacement text. For
-- * interoperability, if a parameter-entity reference appears in a
-- * choice, seq, or Mixed construct, its replacement text should not
-- * be empty, and neither the first nor last non-blank character of
-- * the replacement text should be a connector (| or ,).
-- *
-- * returns: the tree of xmlElementContentPtr describing the element
-- * hierarchy.
-- */
--xmlElementContentPtr
--#ifdef VMS
--xmlParseElementChildrenContentD
--#else
--xmlParseElementChildrenContentDecl
--#endif
--(xmlParserCtxtPtr ctxt) {
-- xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
-- xmlChar *elem;
-- xmlChar type = 0;
--
-- SKIP_BLANKS;
-- GROW;
-- if (RAW == '(') {
-- /* Recurse on first child */
-- NEXT;
-- SKIP_BLANKS;
-- cur = ret = xmlParseElementChildrenContentDecl(ctxt);
-- SKIP_BLANKS;
-- GROW;
-- } else {
-- elem = xmlParseName(ctxt);
-- if (elem == NULL) {
-- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
-- GROW;
-- if (RAW == '?') {
-- cur->ocur = XML_ELEMENT_CONTENT_OPT;
-- NEXT;
-- } else if (RAW == '*') {
-- cur->ocur = XML_ELEMENT_CONTENT_MULT;
-- NEXT;
-- } else if (RAW == '+') {
-- cur->ocur = XML_ELEMENT_CONTENT_PLUS;
-- NEXT;
-- } else {
-- cur->ocur = XML_ELEMENT_CONTENT_ONCE;
-- }
-- xmlFree(elem);
-- GROW;
-- }
-- SKIP_BLANKS;
-- SHRINK;
-- while (RAW != ')') {
-- /*
-- * Each loop we parse one separator and one element.
-- */
-- if (RAW == ',') {
-- if (type == 0) type = CUR;
--
-- /*
-- * Detect "Name | Name , Name" error
-- */
-- else if (type != CUR) {
-- ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementChildrenContentDecl : '%c' expected\n",
-- type);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if ((op != NULL) && (op != ret))
-- xmlFreeElementContent(op);
-- if ((last != NULL) && (last != ret) &&
-- (last != ret->c1) && (last != ret->c2))
-- xmlFreeElementContent(last);
-- if (ret != NULL)
-- xmlFreeElementContent(ret);
-- return(NULL);
-- }
-- NEXT;
--
-- op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_SEQ);
-- if (op == NULL) {
-- xmlFreeElementContent(ret);
-- return(NULL);
-- }
-- if (last == NULL) {
-- op->c1 = ret;
-- ret = cur = op;
-- } else {
-- cur->c2 = op;
-- op->c1 = last;
-- cur =op;
-- last = NULL;
-- }
-- } else if (RAW == '|') {
-- if (type == 0) type = CUR;
--
-- /*
-- * Detect "Name , Name | Name" error
-- */
-- else if (type != CUR) {
-- ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementChildrenContentDecl : '%c' expected\n",
-- type);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if ((op != NULL) && (op != ret) && (op != last))
-- xmlFreeElementContent(op);
-- if ((last != NULL) && (last != ret) &&
-- (last != ret->c1) && (last != ret->c2))
-- xmlFreeElementContent(last);
-- if (ret != NULL)
-- xmlFreeElementContent(ret);
-- return(NULL);
-- }
-- NEXT;
--
-- op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
-- if (op == NULL) {
-- if ((op != NULL) && (op != ret))
-- xmlFreeElementContent(op);
-- if ((last != NULL) && (last != ret) &&
-- (last != ret->c1) && (last != ret->c2))
-- xmlFreeElementContent(last);
-- if (ret != NULL)
-- xmlFreeElementContent(ret);
-- return(NULL);
-- }
-- if (last == NULL) {
-- op->c1 = ret;
-- ret = cur = op;
-- } else {
-- cur->c2 = op;
-- op->c1 = last;
-- cur =op;
-- last = NULL;
-- }
-- } else {
-- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementChildrenContentDecl : ',' '|' or ')' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if ((op != NULL) && (op != ret))
-- xmlFreeElementContent(op);
-- if ((last != NULL) && (last != ret) &&
-- (last != ret->c1) && (last != ret->c2))
-- xmlFreeElementContent(last);
-- if (ret != NULL)
-- xmlFreeElementContent(ret);
-- return(NULL);
-- }
-- GROW;
-- SKIP_BLANKS;
-- GROW;
-- if (RAW == '(') {
-- /* Recurse on second child */
-- NEXT;
-- SKIP_BLANKS;
-- last = xmlParseElementChildrenContentDecl(ctxt);
-- SKIP_BLANKS;
-- } else {
-- elem = xmlParseName(ctxt);
-- if (elem == NULL) {
-- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if ((op != NULL) && (op != ret))
-- xmlFreeElementContent(op);
-- if ((last != NULL) && (last != ret) &&
-- (last != ret->c1) && (last != ret->c2))
-- xmlFreeElementContent(last);
-- if (ret != NULL)
-- xmlFreeElementContent(ret);
-- return(NULL);
-- }
-- last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
-- xmlFree(elem);
-- if (RAW == '?') {
-- last->ocur = XML_ELEMENT_CONTENT_OPT;
-- NEXT;
-- } else if (RAW == '*') {
-- last->ocur = XML_ELEMENT_CONTENT_MULT;
-- NEXT;
-- } else if (RAW == '+') {
-- last->ocur = XML_ELEMENT_CONTENT_PLUS;
-- NEXT;
-- } else {
-- last->ocur = XML_ELEMENT_CONTENT_ONCE;
-- }
-- }
-- SKIP_BLANKS;
-- GROW;
-- }
-- if ((cur != NULL) && (last != NULL)) {
-- cur->c2 = last;
-- }
-- ctxt->entity = ctxt->input;
-- NEXT;
-- if (RAW == '?') {
-- ret->ocur = XML_ELEMENT_CONTENT_OPT;
-- NEXT;
-- } else if (RAW == '*') {
-- ret->ocur = XML_ELEMENT_CONTENT_MULT;
-- NEXT;
-- } else if (RAW == '+') {
-- ret->ocur = XML_ELEMENT_CONTENT_PLUS;
-- NEXT;
-- }
-- return(ret);
--}
--
--/**
-- * xmlParseElementContentDecl:
-- * @ctxt: an XML parser context
-- * @name: the name of the element being defined.
-- * @result: the Element Content pointer will be stored here if any
-- *
-- * parse the declaration for an Element content either Mixed or Children,
-- * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
-- *
-- * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
-- *
-- * returns: the type of element content XML_ELEMENT_TYPE_xxx
-- */
--
--int
--xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, xmlChar *name,
-- xmlElementContentPtr *result) {
--
-- xmlElementContentPtr tree = NULL;
-- xmlParserInputPtr input = ctxt->input;
-- int res;
--
-- *result = NULL;
--
-- if (RAW != '(') {
-- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementContentDecl : '(' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(-1);
-- }
-- NEXT;
-- GROW;
-- SKIP_BLANKS;
-- if ((RAW == '#') && (NXT(1) == 'P') &&
-- (NXT(2) == 'C') && (NXT(3) == 'D') &&
-- (NXT(4) == 'A') && (NXT(5) == 'T') &&
-- (NXT(6) == 'A')) {
-- tree = xmlParseElementMixedContentDecl(ctxt);
-- res = XML_ELEMENT_TYPE_MIXED;
-- } else {
-- tree = xmlParseElementChildrenContentDecl(ctxt);
-- res = XML_ELEMENT_TYPE_ELEMENT;
-- }
-- if ((ctxt->entity != NULL) && (input != ctxt->entity)) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Element content declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- *result = tree;
-- return(res);
--}
--
--/**
-- * xmlParseElementDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse an Element declaration.
-- *
-- * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
-- *
-- * [ VC: Unique Element Type Declaration ]
-- * No element type may be declared more than once
-- *
-- * Returns the type of the element, or -1 in case of error
-- */
--int
--xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- int ret = -1;
-- xmlElementContentPtr content = NULL;
--
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == 'E') && (NXT(3) == 'L') &&
-- (NXT(4) == 'E') && (NXT(5) == 'M') &&
-- (NXT(6) == 'E') && (NXT(7) == 'N') &&
-- (NXT(8) == 'T')) {
-- xmlParserInputPtr input = ctxt->input;
--
-- SKIP(9);
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after 'ELEMENT'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementDecl: no name for Element\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(-1);
-- }
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space required after the element name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- if ((RAW == 'E') && (NXT(1) == 'M') &&
-- (NXT(2) == 'P') && (NXT(3) == 'T') &&
-- (NXT(4) == 'Y')) {
-- SKIP(5);
-- /*
-- * Element must always be empty.
-- */
-- ret = XML_ELEMENT_TYPE_EMPTY;
-- } else if ((RAW == 'A') && (NXT(1) == 'N') &&
-- (NXT(2) == 'Y')) {
-- SKIP(3);
-- /*
-- * Element is a generic container.
-- */
-- ret = XML_ELEMENT_TYPE_ANY;
-- } else if (RAW == '(') {
-- ret = xmlParseElementContentDecl(ctxt, name, &content);
-- } else {
-- /*
-- * [ WFC: PEs in Internal Subset ] error handling.
-- */
-- if ((RAW == '%') && (ctxt->external == 0) &&
-- (ctxt->inputNr == 1)) {
-- ctxt->errNo = XML_ERR_PEREF_IN_INT_SUBSET;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "PEReference: forbidden within markup decl in internal subset\n");
-- } else {
-- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
-- }
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- if (name != NULL) xmlFree(name);
-- return(-1);
-- }
--
-- SKIP_BLANKS;
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
-- SKIP_BLANKS;
--
-- if (RAW != '>') {
-- ctxt->errNo = XML_ERR_GT_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseElementDecl: expected '>' at the end\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (input != ctxt->input) {
-- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Element declaration doesn't start and stop in the same entity\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- NEXT;
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->elementDecl != NULL))
-- ctxt->sax->elementDecl(ctxt->userData, name, ret,
-- content);
-- }
-- if (content != NULL) {
-- xmlFreeElementContent(content);
-- }
-- if (name != NULL) {
-- xmlFree(name);
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlParseMarkupDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse Markup declarations
-- *
-- * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
-- * NotationDecl | PI | Comment
-- *
-- * [ VC: Proper Declaration/PE Nesting ]
-- * Parameter-entity replacement text must be properly nested with
-- * markup declarations. That is to say, if either the first character
-- * or the last character of a markup declaration (markupdecl above) is
-- * contained in the replacement text for a parameter-entity reference,
-- * both must be contained in the same replacement text.
-- *
-- * [ WFC: PEs in Internal Subset ]
-- * In the internal DTD subset, parameter-entity references can occur
-- * only where markup declarations can occur, not within markup declarations.
-- * (This does not apply to references that occur in external parameter
-- * entities or to the external subset.)
-- */
--void
--xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
-- GROW;
-- xmlParseElementDecl(ctxt);
-- xmlParseAttributeListDecl(ctxt);
-- xmlParseEntityDecl(ctxt);
-- xmlParseNotationDecl(ctxt);
-- xmlParsePI(ctxt);
-- xmlParseComment(ctxt);
-- /*
-- * This is only for internal subset. On external entities,
-- * the replacement is done before parsing stage
-- */
-- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
-- xmlParsePEReference(ctxt);
-- ctxt->instate = XML_PARSER_DTD;
--}
--
--/**
-- * xmlParseTextDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML declaration header for external entities
-- *
-- * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-- *
-- * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
-- */
--
--void
--xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *version;
--
-- /*
-- * We know that '<?xml' is here.
-- */
-- if ((RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-- SKIP(5);
-- } else {
-- ctxt->errNo = XML_ERR_XMLDECL_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Text declaration '<?xml' required\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
--
-- return;
-- }
--
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Space needed after '<?xml'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
--
-- /*
-- * We may have the VersionInfo here.
-- */
-- version = xmlParseVersionInfo(ctxt);
-- if (version == NULL)
-- version = xmlCharStrdup(XML_DEFAULT_VERSION);
-- ctxt->input->version = version;
--
-- /*
-- * We must have the encoding declaration
-- */
-- if (!IS_BLANK(CUR)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Space needed here\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlParseEncodingDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right here
-- */
-- return;
-- }
--
-- SKIP_BLANKS;
-- if ((RAW == '?') && (NXT(1) == '>')) {
-- SKIP(2);
-- } else if (RAW == '>') {
-- /* Deprecated old WD ... */
-- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML declaration must end-up with '?>'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "parsing XML declaration: '?>' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- MOVETO_ENDTAG(CUR_PTR);
-- NEXT;
-- }
--}
--
--/*
-- * xmlParseConditionalSections
-- * @ctxt: an XML parser context
-- *
-- * [61] conditionalSect ::= includeSect | ignoreSect
-- * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
-- * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
-- * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
-- * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
-- */
--
--void
--xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
-- SKIP(3);
-- SKIP_BLANKS;
-- if ((RAW == 'I') && (NXT(1) == 'N') && (NXT(2) == 'C') &&
-- (NXT(3) == 'L') && (NXT(4) == 'U') && (NXT(5) == 'D') &&
-- (NXT(6) == 'E')) {
-- SKIP(7);
-- SKIP_BLANKS;
-- if (RAW != '[') {
-- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML conditional section '[' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- NEXT;
-- }
-- if (xmlParserDebugEntities) {
-- if ((ctxt->input != NULL) && (ctxt->input->filename))
-- xmlGenericError(xmlGenericErrorContext,
-- "%s(%d): ", ctxt->input->filename,
-- ctxt->input->line);
-- xmlGenericError(xmlGenericErrorContext,
-- "Entering INCLUDE Conditional Section\n");
-- }
--
-- while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
-- (NXT(2) != '>'))) {
-- const xmlChar *check = CUR_PTR;
-- int cons = ctxt->input->consumed;
-- int tok = ctxt->token;
--
-- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-- xmlParseConditionalSections(ctxt);
-- } else if (IS_BLANK(CUR)) {
-- NEXT;
-- } else if (RAW == '%') {
-- xmlParsePEReference(ctxt);
-- } else
-- xmlParseMarkupDecl(ctxt);
--
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
--
-- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
-- (tok == ctxt->token)) {
-- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Content error in the external subset\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- }
-- }
-- if (xmlParserDebugEntities) {
-- if ((ctxt->input != NULL) && (ctxt->input->filename))
-- xmlGenericError(xmlGenericErrorContext,
-- "%s(%d): ", ctxt->input->filename,
-- ctxt->input->line);
-- xmlGenericError(xmlGenericErrorContext,
-- "Leaving INCLUDE Conditional Section\n");
-- }
--
-- } else if ((RAW == 'I') && (NXT(1) == 'G') && (NXT(2) == 'N') &&
-- (NXT(3) == 'O') && (NXT(4) == 'R') && (NXT(5) == 'E')) {
-- int state;
-- int instate;
-- int depth = 0;
--
-- SKIP(6);
-- SKIP_BLANKS;
-- if (RAW != '[') {
-- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML conditional section '[' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- NEXT;
-- }
-- if (xmlParserDebugEntities) {
-- if ((ctxt->input != NULL) && (ctxt->input->filename))
-- xmlGenericError(xmlGenericErrorContext,
-- "%s(%d): ", ctxt->input->filename,
-- ctxt->input->line);
-- xmlGenericError(xmlGenericErrorContext,
-- "Entering IGNORE Conditional Section\n");
-- }
--
-- /*
-- * Parse up to the end of the conditionnal section
-- * But disable SAX event generating DTD building in the meantime
-- */
-- state = ctxt->disableSAX;
-- instate = ctxt->instate;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_IGNORE;
--
-- while (depth >= 0) {
-- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-- depth++;
-- SKIP(3);
-- continue;
-- }
-- if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
-- if (--depth >= 0) SKIP(3);
-- continue;
-- }
-- NEXT;
-- continue;
-- }
--
-- ctxt->disableSAX = state;
-- ctxt->instate = instate;
--
-- if (xmlParserDebugEntities) {
-- if ((ctxt->input != NULL) && (ctxt->input->filename))
-- xmlGenericError(xmlGenericErrorContext,
-- "%s(%d): ", ctxt->input->filename,
-- ctxt->input->line);
-- xmlGenericError(xmlGenericErrorContext,
-- "Leaving IGNORE Conditional Section\n");
-- }
--
-- } else {
-- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML conditional section INCLUDE or IGNORE keyword expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- if (RAW == 0)
-- SHRINK;
--
-- if (RAW == 0) {
-- ctxt->errNo = XML_ERR_CONDSEC_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML conditional section not closed\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- SKIP(3);
-- }
--}
--
--/**
-- * xmlParseExternalSubset:
-- * @ctxt: an XML parser context
-- * @ExternalID: the external identifier
-- * @SystemID: the system identifier (or URL)
-- *
-- * parse Markup declarations from an external subset
-- *
-- * [30] extSubset ::= textDecl? extSubsetDecl
-- *
-- * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
-- */
--void
--xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
-- const xmlChar *SystemID) {
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l')) {
-- xmlParseTextDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right here
-- */
-- ctxt->instate = XML_PARSER_EOF;
-- return;
-- }
-- }
-- if (ctxt->myDoc == NULL) {
-- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-- }
-- if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
-- xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
--
-- ctxt->instate = XML_PARSER_DTD;
-- ctxt->external = 1;
-- while (((RAW == '<') && (NXT(1) == '?')) ||
-- ((RAW == '<') && (NXT(1) == '!')) ||
-- IS_BLANK(CUR)) {
-- const xmlChar *check = CUR_PTR;
-- int cons = ctxt->input->consumed;
-- int tok = ctxt->token;
--
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-- xmlParseConditionalSections(ctxt);
-- } else if (IS_BLANK(CUR)) {
-- NEXT;
-- } else if (RAW == '%') {
-- xmlParsePEReference(ctxt);
-- } else
-- xmlParseMarkupDecl(ctxt);
--
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
--
-- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
-- (tok == ctxt->token)) {
-- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Content error in the external subset\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- }
-- }
--
-- if (RAW != 0) {
-- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra content at the end of the document\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
--}
--
--/**
-- * xmlParseReference:
-- * @ctxt: an XML parser context
-- *
-- * parse and handle entity references in content, depending on the SAX
-- * interface, this may end-up in a call to character() if this is a
-- * CharRef, a predefined entity, if there is no reference() callback.
-- * or if the parser was asked to switch to that mode.
-- *
-- * [67] Reference ::= EntityRef | CharRef
-- */
--void
--xmlParseReference(xmlParserCtxtPtr ctxt) {
-- xmlEntityPtr ent;
-- xmlChar *val;
-- if (RAW != '&') return;
--
-- if (NXT(1) == '#') {
-- int i = 0;
-- xmlChar out[10];
-- int hex = NXT(2);
-- int val = xmlParseCharRef(ctxt);
--
-- if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
-- /*
-- * So we are using non-UTF-8 buffers
-- * Check that the char fit on 8bits, if not
-- * generate a CharRef.
-- */
-- if (val <= 0xFF) {
-- out[0] = val;
-- out[1] = 0;
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->characters(ctxt->userData, out, 1);
-- } else {
-- if ((hex == 'x') || (hex == 'X'))
-- sprintf((char *)out, "#x%X", val);
-- else
-- sprintf((char *)out, "#%d", val);
-- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->reference(ctxt->userData, out);
-- }
-- } else {
-- /*
-- * Just encode the value in UTF-8
-- */
-- COPY_BUF(0 ,out, i, val);
-- out[i] = 0;
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->characters(ctxt->userData, out, i);
-- }
-- } else {
-- ent = xmlParseEntityRef(ctxt);
-- if (ent == NULL) return;
-- if ((ent->name != NULL) &&
-- (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
-- xmlNodePtr list = NULL;
-- int ret;
--
--
-- /*
-- * The first reference to the entity trigger a parsing phase
-- * where the ent->children is filled with the result from
-- * the parsing.
-- */
-- if (ent->children == NULL) {
-- xmlChar *value;
-- value = ent->content;
--
-- /*
-- * Check that this entity is well formed
-- */
-- if ((value != NULL) &&
-- (value[1] == 0) && (value[0] == '<') &&
-- (xmlStrEqual(ent->name, BAD_CAST "lt"))) {
-- /*
-- * DONE: get definite answer on this !!!
-- * Lots of entity decls are used to declare a single
-- * char
-- * <!ENTITY lt "<">
-- * Which seems to be valid since
-- * 2.4: The ampersand character (&) and the left angle
-- * bracket (<) may appear in their literal form only
-- * when used ... They are also legal within the literal
-- * entity value of an internal entity declaration;i
-- * see "4.3.2 Well-Formed Parsed Entities".
-- * IMHO 2.4 and 4.3.2 are directly in contradiction.
-- * Looking at the OASIS test suite and James Clark
-- * tests, this is broken. However the XML REC uses
-- * it. Is the XML REC not well-formed ????
-- * This is a hack to avoid this problem
-- *
-- * ANSWER: since lt gt amp .. are already defined,
-- * this is a redefinition and hence the fact that the
-- * contentis not well balanced is not a Wf error, this
-- * is lousy but acceptable.
-- */
-- list = xmlNewDocText(ctxt->myDoc, value);
-- if (list != NULL) {
-- if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
-- (ent->children == NULL)) {
-- ent->children = list;
-- ent->last = list;
-- list->parent = (xmlNodePtr) ent;
-- } else {
-- xmlFreeNodeList(list);
-- }
-- } else if (list != NULL) {
-- xmlFreeNodeList(list);
-- }
-- } else {
-- /*
-- * 4.3.2: An internal general parsed entity is well-formed
-- * if its replacement text matches the production labeled
-- * content.
-- */
-- if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
-- ctxt->depth++;
-- ret = xmlParseBalancedChunkMemory(ctxt->myDoc,
-- ctxt->sax, NULL, ctxt->depth,
-- value, &list);
-- ctxt->depth--;
-- } else if (ent->etype ==
-- XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
-- ctxt->depth++;
-- ret = xmlParseExternalEntity(ctxt->myDoc,
-- ctxt->sax, NULL, ctxt->depth,
-- ent->URI, ent->ExternalID, &list);
-- ctxt->depth--;
-- } else {
-- ret = -1;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Internal: invalid entity type\n");
-- }
-- if (ret == XML_ERR_ENTITY_LOOP) {
-- ctxt->errNo = XML_ERR_ENTITY_LOOP;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Detected entity reference loop\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if ((ret == 0) && (list != NULL)) {
-- if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
-- (ent->children == NULL)) {
-- ent->children = list;
-- while (list != NULL) {
-- list->parent = (xmlNodePtr) ent;
-- if (list->next == NULL)
-- ent->last = list;
-- list = list->next;
-- }
-- } else {
-- xmlFreeNodeList(list);
-- }
-- } else if (ret > 0) {
-- ctxt->errNo = ret;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity value required\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if (list != NULL) {
-- xmlFreeNodeList(list);
-- }
-- }
-- }
-- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
-- (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
-- /*
-- * Create a node.
-- */
-- ctxt->sax->reference(ctxt->userData, ent->name);
-- return;
-- } else if (ctxt->replaceEntities) {
-- if ((ctxt->node != NULL) && (ent->children != NULL)) {
-- /*
-- * Seems we are generating the DOM content, do
-- * a simple tree copy
-- */
-- xmlNodePtr new;
-- new = xmlCopyNodeList(ent->children);
--
-- xmlAddChildList(ctxt->node, new);
-- /*
-- * This is to avoid a nasty side effect, see
-- * characters() in SAX.c
-- */
-- ctxt->nodemem = 0;
-- ctxt->nodelen = 0;
-- return;
-- } else {
-- /*
-- * Probably running in SAX mode
-- */
-- xmlParserInputPtr input;
--
-- input = xmlNewEntityInputStream(ctxt, ent);
-- xmlPushInput(ctxt, input);
-- if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) &&
-- (RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-- xmlParseTextDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right here
-- */
-- ctxt->instate = XML_PARSER_EOF;
-- return;
-- }
-- if (input->standalone == 1) {
-- ctxt->errNo = XML_ERR_EXT_ENTITY_STANDALONE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "external parsed entities cannot be standalone\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
-- return;
-- }
-- }
-- } else {
-- val = ent->content;
-- if (val == NULL) return;
-- /*
-- * inline the entity.
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
-- }
-- }
--}
--
--/**
-- * xmlParseEntityRef:
-- * @ctxt: an XML parser context
-- *
-- * parse ENTITY references declarations
-- *
-- * [68] EntityRef ::= '&' Name ';'
-- *
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an internal DTD
-- * subset which contains no parameter entity references, or a document
-- * with "standalone='yes'", the Name given in the entity reference
-- * must match that in an entity declaration, except that well-formed
-- * documents need not declare any of the following entities: amp, lt,
-- * gt, apos, quot. The declaration of a parameter entity must precede
-- * any reference to it. Similarly, the declaration of a general entity
-- * must precede any reference to it which appears in a default value in an
-- * attribute-list declaration. Note that if entities are declared in the
-- * external subset or in external parameter entities, a non-validating
-- * processor is not obligated to read and process their declarations;
-- * for such documents, the rule that an entity must be declared is a
-- * well-formedness constraint only if standalone='yes'.
-- *
-- * [ WFC: Parsed Entity ]
-- * An entity reference must not contain the name of an unparsed entity
-- *
-- * Returns the xmlEntityPtr if found, or NULL otherwise.
-- */
--xmlEntityPtr
--xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlEntityPtr ent = NULL;
--
-- GROW;
--
-- if (RAW == '&') {
-- NEXT;
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEntityRef: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (RAW == ';') {
-- NEXT;
-- /*
-- * Ask first SAX for entity resolution, otherwise try the
-- * predefined set.
-- */
-- if (ctxt->sax != NULL) {
-- if (ctxt->sax->getEntity != NULL)
-- ent = ctxt->sax->getEntity(ctxt->userData, name);
-- if (ent == NULL)
-- ent = xmlGetPredefinedEntity(name);
-- }
-- /*
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an
-- * internal DTD subset which contains no parameter entity
-- * references, or a document with "standalone='yes'", the
-- * Name given in the entity reference must match that in an
-- * entity declaration, except that well-formed documents
-- * need not declare any of the following entities: amp, lt,
-- * gt, apos, quot.
-- * The declaration of a parameter entity must precede any
-- * reference to it.
-- * Similarly, the declaration of a general entity must
-- * precede any reference to it which appears in a default
-- * value in an attribute-list declaration. Note that if
-- * entities are declared in the external subset or in
-- * external parameter entities, a non-validating processor
-- * is not obligated to read and process their declarations;
-- * for such documents, the rule that an entity must be
-- * declared is a well-formedness constraint only if
-- * standalone='yes'.
-- */
-- if (ent == NULL) {
-- if ((ctxt->standalone == 1) ||
-- ((ctxt->hasExternalSubset == 0) &&
-- (ctxt->hasPErefs == 0))) {
-- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity '%s' not defined\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Entity '%s' not defined\n", name);
-- }
-- }
--
-- /*
-- * [ WFC: Parsed Entity ]
-- * An entity reference must not contain the name of an
-- * unparsed entity
-- */
-- else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity reference to unparsed entity %s\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * [ WFC: No External Entity References ]
-- * Attribute values cannot contain direct or indirect
-- * entity references to external entities.
-- */
-- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-- ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attribute references external entity '%s'\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- /*
-- * [ WFC: No < in Attribute Values ]
-- * The replacement text of any entity referred to directly or
-- * indirectly in an attribute value (other than "<") must
-- * not contain a <.
-- */
-- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-- (ent != NULL) &&
-- (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
-- (ent->content != NULL) &&
-- (xmlStrchr(ent->content, '<'))) {
-- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "'<' in entity '%s' is not allowed in attributes values\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * Internal check, no parameter entities here ...
-- */
-- else {
-- switch (ent->etype) {
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attempt to reference the parameter entity '%s'\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- default:
-- break;
-- }
-- }
--
-- /*
-- * [ WFC: No Recursion ]
-- * A parsed entity must not contain a recursive reference
-- * to itself, either directly or indirectly.
-- * Done somewhere else
-- */
--
-- } else {
-- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEntityRef: expecting ';'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlFree(name);
-- }
-- }
-- return(ent);
--}
--
--/**
-- * xmlParseStringEntityRef:
-- * @ctxt: an XML parser context
-- * @str: a pointer to an index in the string
-- *
-- * parse ENTITY references declarations, but this version parses it from
-- * a string value.
-- *
-- * [68] EntityRef ::= '&' Name ';'
-- *
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an internal DTD
-- * subset which contains no parameter entity references, or a document
-- * with "standalone='yes'", the Name given in the entity reference
-- * must match that in an entity declaration, except that well-formed
-- * documents need not declare any of the following entities: amp, lt,
-- * gt, apos, quot. The declaration of a parameter entity must precede
-- * any reference to it. Similarly, the declaration of a general entity
-- * must precede any reference to it which appears in a default value in an
-- * attribute-list declaration. Note that if entities are declared in the
-- * external subset or in external parameter entities, a non-validating
-- * processor is not obligated to read and process their declarations;
-- * for such documents, the rule that an entity must be declared is a
-- * well-formedness constraint only if standalone='yes'.
-- *
-- * [ WFC: Parsed Entity ]
-- * An entity reference must not contain the name of an unparsed entity
-- *
-- * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
-- * is updated to the current location in the string.
-- */
--xmlEntityPtr
--xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
-- xmlChar *name;
-- const xmlChar *ptr;
-- xmlChar cur;
-- xmlEntityPtr ent = NULL;
--
-- if ((str == NULL) || (*str == NULL))
-- return(NULL);
-- ptr = *str;
-- cur = *ptr;
-- if (cur == '&') {
-- ptr++;
-- cur = *ptr;
-- name = xmlParseStringName(ctxt, &ptr);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEntityRef: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (*ptr == ';') {
-- ptr++;
-- /*
-- * Ask first SAX for entity resolution, otherwise try the
-- * predefined set.
-- */
-- if (ctxt->sax != NULL) {
-- if (ctxt->sax->getEntity != NULL)
-- ent = ctxt->sax->getEntity(ctxt->userData, name);
-- if (ent == NULL)
-- ent = xmlGetPredefinedEntity(name);
-- }
-- /*
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an
-- * internal DTD subset which contains no parameter entity
-- * references, or a document with "standalone='yes'", the
-- * Name given in the entity reference must match that in an
-- * entity declaration, except that well-formed documents
-- * need not declare any of the following entities: amp, lt,
-- * gt, apos, quot.
-- * The declaration of a parameter entity must precede any
-- * reference to it.
-- * Similarly, the declaration of a general entity must
-- * precede any reference to it which appears in a default
-- * value in an attribute-list declaration. Note that if
-- * entities are declared in the external subset or in
-- * external parameter entities, a non-validating processor
-- * is not obligated to read and process their declarations;
-- * for such documents, the rule that an entity must be
-- * declared is a well-formedness constraint only if
-- * standalone='yes'.
-- */
-- if (ent == NULL) {
-- if ((ctxt->standalone == 1) ||
-- ((ctxt->hasExternalSubset == 0) &&
-- (ctxt->hasPErefs == 0))) {
-- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity '%s' not defined\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Entity '%s' not defined\n", name);
-- }
-- }
--
-- /*
-- * [ WFC: Parsed Entity ]
-- * An entity reference must not contain the name of an
-- * unparsed entity
-- */
-- else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity reference to unparsed entity %s\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * [ WFC: No External Entity References ]
-- * Attribute values cannot contain direct or indirect
-- * entity references to external entities.
-- */
-- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-- ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attribute references external entity '%s'\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- /*
-- * [ WFC: No < in Attribute Values ]
-- * The replacement text of any entity referred to directly or
-- * indirectly in an attribute value (other than "<") must
-- * not contain a <.
-- */
-- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-- (ent != NULL) &&
-- (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
-- (ent->content != NULL) &&
-- (xmlStrchr(ent->content, '<'))) {
-- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "'<' in entity '%s' is not allowed in attributes values\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * Internal check, no parameter entities here ...
-- */
-- else {
-- switch (ent->etype) {
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attempt to reference the parameter entity '%s'\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- default:
-- break;
-- }
-- }
--
-- /*
-- * [ WFC: No Recursion ]
-- * A parsed entity must not contain a recursive reference
-- * to itself, either directly or indirectly.
-- * Done somewhwere else
-- */
--
-- } else {
-- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEntityRef: expecting ';'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlFree(name);
-- }
-- }
-- *str = ptr;
-- return(ent);
--}
--
--/**
-- * xmlParsePEReference:
-- * @ctxt: an XML parser context
-- *
-- * parse PEReference declarations
-- * The entity content is handled directly by pushing it's content as
-- * a new input stream.
-- *
-- * [69] PEReference ::= '%' Name ';'
-- *
-- * [ WFC: No Recursion ]
-- * A parsed entity must not contain a recursive
-- * reference to itself, either directly or indirectly.
-- *
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an internal DTD
-- * subset which contains no parameter entity references, or a document
-- * with "standalone='yes'", ... ... The declaration of a parameter
-- * entity must precede any reference to it...
-- *
-- * [ VC: Entity Declared ]
-- * In a document with an external subset or external parameter entities
-- * with "standalone='no'", ... ... The declaration of a parameter entity
-- * must precede any reference to it...
-- *
-- * [ WFC: In DTD ]
-- * Parameter-entity references may only appear in the DTD.
-- * NOTE: misleading but this is handled.
-- */
--void
--xmlParsePEReference(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlEntityPtr entity = NULL;
-- xmlParserInputPtr input;
--
-- if (RAW == '%') {
-- NEXT;
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParsePEReference: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- if (RAW == ';') {
-- NEXT;
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->getParameterEntity != NULL))
-- entity = ctxt->sax->getParameterEntity(ctxt->userData,
-- name);
-- if (entity == NULL) {
-- /*
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an
-- * internal DTD subset which contains no parameter entity
-- * references, or a document with "standalone='yes'", ...
-- * ... The declaration of a parameter entity must precede
-- * any reference to it...
-- */
-- if ((ctxt->standalone == 1) ||
-- ((ctxt->hasExternalSubset == 0) &&
-- (ctxt->hasPErefs == 0))) {
-- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-- if ((!ctxt->disableSAX) &&
-- (ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "PEReference: %%%s; not found\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- /*
-- * [ VC: Entity Declared ]
-- * In a document with an external subset or external
-- * parameter entities with "standalone='no'", ...
-- * ... The declaration of a parameter entity must precede
-- * any reference to it...
-- */
-- if ((!ctxt->disableSAX) &&
-- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "PEReference: %%%s; not found\n", name);
-- ctxt->valid = 0;
-- }
-- } else {
-- /*
-- * Internal checking in case the entity quest barfed
-- */
-- if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
-- (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Internal: %%%s; is not a parameter entity\n", name);
-- } else {
-- /*
-- * TODO !!!
-- * handle the extra spaces added before and after
-- * c.f. http://www.w3.org/TR/REC-xml#as-PE
-- */
-- input = xmlNewEntityInputStream(ctxt, entity);
-- xmlPushInput(ctxt, input);
-- if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-- (RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-- xmlParseTextDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing
-- * right here
-- */
-- ctxt->instate = XML_PARSER_EOF;
-- xmlFree(name);
-- return;
-- }
-- }
-- if (ctxt->token == 0)
-- ctxt->token = ' ';
-- }
-- }
-- ctxt->hasPErefs = 1;
-- } else {
-- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParsePEReference: expecting ';'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlFree(name);
-- }
-- }
--}
--
--/**
-- * xmlParseStringPEReference:
-- * @ctxt: an XML parser context
-- * @str: a pointer to an index in the string
-- *
-- * parse PEReference declarations
-- *
-- * [69] PEReference ::= '%' Name ';'
-- *
-- * [ WFC: No Recursion ]
-- * A parsed entity must not contain a recursive
-- * reference to itself, either directly or indirectly.
-- *
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an internal DTD
-- * subset which contains no parameter entity references, or a document
-- * with "standalone='yes'", ... ... The declaration of a parameter
-- * entity must precede any reference to it...
-- *
-- * [ VC: Entity Declared ]
-- * In a document with an external subset or external parameter entities
-- * with "standalone='no'", ... ... The declaration of a parameter entity
-- * must precede any reference to it...
-- *
-- * [ WFC: In DTD ]
-- * Parameter-entity references may only appear in the DTD.
-- * NOTE: misleading but this is handled.
-- *
-- * Returns the string of the entity content.
-- * str is updated to the current value of the index
-- */
--xmlEntityPtr
--xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
-- const xmlChar *ptr;
-- xmlChar cur;
-- xmlChar *name;
-- xmlEntityPtr entity = NULL;
--
-- if ((str == NULL) || (*str == NULL)) return(NULL);
-- ptr = *str;
-- cur = *ptr;
-- if (cur == '%') {
-- ptr++;
-- cur = *ptr;
-- name = xmlParseStringName(ctxt, &ptr);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStringPEReference: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- cur = *ptr;
-- if (cur == ';') {
-- ptr++;
-- cur = *ptr;
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->getParameterEntity != NULL))
-- entity = ctxt->sax->getParameterEntity(ctxt->userData,
-- name);
-- if (entity == NULL) {
-- /*
-- * [ WFC: Entity Declared ]
-- * In a document without any DTD, a document with only an
-- * internal DTD subset which contains no parameter entity
-- * references, or a document with "standalone='yes'", ...
-- * ... The declaration of a parameter entity must precede
-- * any reference to it...
-- */
-- if ((ctxt->standalone == 1) ||
-- ((ctxt->hasExternalSubset == 0) &&
-- (ctxt->hasPErefs == 0))) {
-- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "PEReference: %%%s; not found\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- /*
-- * [ VC: Entity Declared ]
-- * In a document with an external subset or external
-- * parameter entities with "standalone='no'", ...
-- * ... The declaration of a parameter entity must
-- * precede any reference to it...
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "PEReference: %%%s; not found\n", name);
-- ctxt->valid = 0;
-- }
-- } else {
-- /*
-- * Internal checking in case the entity quest barfed
-- */
-- if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
-- (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Internal: %%%s; is not a parameter entity\n", name);
-- }
-- }
-- ctxt->hasPErefs = 1;
-- } else {
-- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStringPEReference: expecting ';'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlFree(name);
-- }
-- }
-- *str = ptr;
-- return(entity);
--}
--
--/**
-- * xmlParseDocTypeDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse a DOCTYPE declaration
-- *
-- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-- * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-- *
-- * [ VC: Root Element Type ]
-- * The Name in the document type declaration must match the element
-- * type of the root element.
-- */
--
--void
--xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *name = NULL;
-- xmlChar *ExternalID = NULL;
-- xmlChar *URI = NULL;
--
-- /*
-- * We know that '<!DOCTYPE' has been detected.
-- */
-- SKIP(9);
--
-- SKIP_BLANKS;
--
-- /*
-- * Parse the DOCTYPE name.
-- */
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseDocTypeDecl : no DOCTYPE name !\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- ctxt->intSubName = name;
--
-- SKIP_BLANKS;
--
-- /*
-- * Check for SystemID and ExternalID
-- */
-- URI = xmlParseExternalID(ctxt, &ExternalID, 1);
--
-- if ((URI != NULL) || (ExternalID != NULL)) {
-- ctxt->hasExternalSubset = 1;
-- }
-- ctxt->extSubURI = URI;
-- ctxt->extSubSystem = ExternalID;
--
-- SKIP_BLANKS;
--
-- /*
-- * Create and update the internal subset.
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
--
-- /*
-- * Is there any internal subset declarations ?
-- * they are handled separately in xmlParseInternalSubset()
-- */
-- if (RAW == '[')
-- return;
--
-- /*
-- * We should be at the end of the DOCTYPE declaration.
-- */
-- if (RAW != '>') {
-- ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- NEXT;
--}
--
--/**
-- * xmlParseInternalsubset:
-- * @ctxt: an XML parser context
-- *
-- * parse the internal subset declaration
-- *
-- * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-- */
--
--void
--xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
-- /*
-- * Is there any DTD definition ?
-- */
-- if (RAW == '[') {
-- ctxt->instate = XML_PARSER_DTD;
-- NEXT;
-- /*
-- * Parse the succession of Markup declarations and
-- * PEReferences.
-- * Subsequence (markupdecl | PEReference | S)*
-- */
-- while (RAW != ']') {
-- const xmlChar *check = CUR_PTR;
-- int cons = ctxt->input->consumed;
--
-- SKIP_BLANKS;
-- xmlParseMarkupDecl(ctxt);
-- xmlParsePEReference(ctxt);
--
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
--
-- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseInternalSubset: error detected in Markup declaration\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- }
-- }
-- if (RAW == ']') {
-- NEXT;
-- SKIP_BLANKS;
-- }
-- }
--
-- /*
-- * We should be at the end of the DOCTYPE declaration.
-- */
-- if (RAW != '>') {
-- ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- NEXT;
--}
--
--/**
-- * xmlParseAttribute:
-- * @ctxt: an XML parser context
-- * @value: a xmlChar ** used to store the value of the attribute
-- *
-- * parse an attribute
-- *
-- * [41] Attribute ::= Name Eq AttValue
-- *
-- * [ WFC: No External Entity References ]
-- * Attribute values cannot contain direct or indirect entity references
-- * to external entities.
-- *
-- * [ WFC: No < in Attribute Values ]
-- * The replacement text of any entity referred to directly or indirectly in
-- * an attribute value (other than "<") must not contain a <.
-- *
-- * [ VC: Attribute Value Type ]
-- * The attribute must have been declared; the value must be of the type
-- * declared for it.
-- *
-- * [25] Eq ::= S? '=' S?
-- *
-- * With namespace:
-- *
-- * [NS 11] Attribute ::= QName Eq AttValue
-- *
-- * Also the case QName == xmlns:??? is handled independently as a namespace
-- * definition.
-- *
-- * Returns the attribute name, and the value in *value.
-- */
--
--xmlChar *
--xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
-- xmlChar *name, *val;
--
-- *value = NULL;
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- /*
-- * read the value
-- */
-- SKIP_BLANKS;
-- if (RAW == '=') {
-- NEXT;
-- SKIP_BLANKS;
-- val = xmlParseAttValue(ctxt);
-- ctxt->instate = XML_PARSER_CONTENT;
-- } else {
-- ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Specification mandate value for attribute %s\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFree(name);
-- return(NULL);
-- }
--
-- /*
-- * Check that xml:lang conforms to the specification
-- * No more registered as an error, just generate a warning now
-- * since this was deprecated in XML second edition
-- */
-- if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
-- if (!xmlCheckLanguageID(val)) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt->userData,
-- "Malformed value for xml:lang : %s\n", val);
-- }
-- }
--
-- /*
-- * Check that xml:space conforms to the specification
-- */
-- if (xmlStrEqual(name, BAD_CAST "xml:space")) {
-- if (xmlStrEqual(val, BAD_CAST "default"))
-- *(ctxt->space) = 0;
-- else if (xmlStrEqual(val, BAD_CAST "preserve"))
-- *(ctxt->space) = 1;
-- else {
-- ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
--"Invalid value for xml:space : \"%s\", \"default\" or \"preserve\" expected\n",
-- val);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
--
-- *value = val;
-- return(name);
--}
--
--/**
-- * xmlParseStartTag:
-- * @ctxt: an XML parser context
-- *
-- * parse a start of tag either for rule element or
-- * EmptyElement. In both case we don't parse the tag closing chars.
-- *
-- * [40] STag ::= '<' Name (S Attribute)* S? '>'
-- *
-- * [ WFC: Unique Att Spec ]
-- * No attribute name may appear more than once in the same start-tag or
-- * empty-element tag.
-- *
-- * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
-- *
-- * [ WFC: Unique Att Spec ]
-- * No attribute name may appear more than once in the same start-tag or
-- * empty-element tag.
-- *
-- * With namespace:
-- *
-- * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
-- *
-- * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
-- *
-- * Returns the element name parsed
-- */
--
--xmlChar *
--xmlParseStartTag(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *attname;
-- xmlChar *attvalue;
-- const xmlChar **atts = NULL;
-- int nbatts = 0;
-- int maxatts = 0;
-- int i;
--
-- if (RAW != '<') return(NULL);
-- NEXT;
--
-- name = xmlParseName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_NAME_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStartTag: invalid element name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
--
-- /*
-- * Now parse the attributes, it ends up with the ending
-- *
-- * (S Attribute)* S?
-- */
-- SKIP_BLANKS;
-- GROW;
--
-- while ((IS_CHAR(RAW)) &&
-- (RAW != '>') &&
-- ((RAW != '/') || (NXT(1) != '>'))) {
-- const xmlChar *q = CUR_PTR;
-- int cons = ctxt->input->consumed;
--
-- attname = xmlParseAttribute(ctxt, &attvalue);
-- if ((attname != NULL) && (attvalue != NULL)) {
-- /*
-- * [ WFC: Unique Att Spec ]
-- * No attribute name may appear more than once in the same
-- * start-tag or empty-element tag.
-- */
-- for (i = 0; i < nbatts;i += 2) {
-- if (xmlStrEqual(atts[i], attname)) {
-- ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Attribute %s redefined\n",
-- attname);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFree(attname);
-- xmlFree(attvalue);
-- goto failed;
-- }
-- }
--
-- /*
-- * Add the pair to atts
-- */
-- if (atts == NULL) {
-- maxatts = 10;
-- atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
-- if (atts == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %ld byte failed\n",
-- maxatts * (long)sizeof(xmlChar *));
-- return(NULL);
-- }
-- } else if (nbatts + 4 > maxatts) {
-- maxatts *= 2;
-- atts = (const xmlChar **) xmlRealloc((void *) atts,
-- maxatts * sizeof(xmlChar *));
-- if (atts == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %ld byte failed\n",
-- maxatts * (long)sizeof(xmlChar *));
-- return(NULL);
-- }
-- }
-- atts[nbatts++] = attname;
-- atts[nbatts++] = attvalue;
-- atts[nbatts] = NULL;
-- atts[nbatts + 1] = NULL;
-- } else {
-- if (attname != NULL)
-- xmlFree(attname);
-- if (attvalue != NULL)
-- xmlFree(attvalue);
-- }
--
--failed:
--
-- if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
-- break;
-- if (!IS_BLANK(RAW)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "attributes construct error\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- if ((cons == ctxt->input->consumed) && (q == CUR_PTR)) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseStartTag: problem parsing attributes\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- }
-- GROW;
-- }
--
-- /*
-- * SAX: Start of Element !
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->startElement(ctxt->userData, name, atts);
--
-- if (atts != NULL) {
-- for (i = 0;i < nbatts;i++) xmlFree((xmlChar *) atts[i]);
-- xmlFree((void *) atts);
-- }
-- return(name);
--}
--
--/**
-- * xmlParseEndTag:
-- * @ctxt: an XML parser context
-- *
-- * parse an end of tag
-- *
-- * [42] ETag ::= '</' Name S? '>'
-- *
-- * With namespace
-- *
-- * [NS 9] ETag ::= '</' QName S? '>'
-- */
--
--void
--xmlParseEndTag(xmlParserCtxtPtr ctxt) {
-- xmlChar *name;
-- xmlChar *oldname;
--
-- GROW;
-- if ((RAW != '<') || (NXT(1) != '/')) {
-- ctxt->errNo = XML_ERR_LTSLASH_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "xmlParseEndTag: '</' not found\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- SKIP(2);
--
-- name = xmlParseName(ctxt);
--
-- /*
-- * We should definitely be at the ending "S? '>'" part
-- */
-- GROW;
-- SKIP_BLANKS;
-- if ((!IS_CHAR(RAW)) || (RAW != '>')) {
-- ctxt->errNo = XML_ERR_GT_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
--
-- /*
-- * [ WFC: Element Type Match ]
-- * The Name in an element's end-tag must match the element type in the
-- * start-tag.
-- *
-- */
-- if ((name == NULL) || (ctxt->name == NULL) ||
-- (!xmlStrEqual(name, ctxt->name))) {
-- ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-- if ((name != NULL) && (ctxt->name != NULL)) {
-- ctxt->sax->error(ctxt->userData,
-- "Opening and ending tag mismatch: %s and %s\n",
-- ctxt->name, name);
-- } else if (ctxt->name != NULL) {
-- ctxt->sax->error(ctxt->userData,
-- "Ending tag eror for: %s\n", ctxt->name);
-- } else {
-- ctxt->sax->error(ctxt->userData,
-- "Ending tag error: internal error ???\n");
-- }
--
-- }
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * SAX: End of Tag
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endElement(ctxt->userData, name);
--
-- if (name != NULL)
-- xmlFree(name);
-- oldname = namePop(ctxt);
-- spacePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG_STACK
-- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- return;
--}
--
--/**
-- * xmlParseCDSect:
-- * @ctxt: an XML parser context
-- *
-- * Parse escaped pure raw content.
-- *
-- * [18] CDSect ::= CDStart CData CDEnd
-- *
-- * [19] CDStart ::= '<![CDATA['
-- *
-- * [20] Data ::= (Char* - (Char* ']]>' Char*))
-- *
-- * [21] CDEnd ::= ']]>'
-- */
--void
--xmlParseCDSect(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = XML_PARSER_BUFFER_SIZE;
-- int r, rl;
-- int s, sl;
-- int cur, l;
-- int count = 0;
--
-- if ((NXT(0) == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '[') && (NXT(3) == 'C') &&
-- (NXT(4) == 'D') && (NXT(5) == 'A') &&
-- (NXT(6) == 'T') && (NXT(7) == 'A') &&
-- (NXT(8) == '[')) {
-- SKIP(9);
-- } else
-- return;
--
-- ctxt->instate = XML_PARSER_CDATA_SECTION;
-- r = CUR_CHAR(rl);
-- if (!IS_CHAR(r)) {
-- ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "CData section not finished\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_CONTENT;
-- return;
-- }
-- NEXTL(rl);
-- s = CUR_CHAR(sl);
-- if (!IS_CHAR(s)) {
-- ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "CData section not finished\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_CONTENT;
-- return;
-- }
-- NEXTL(sl);
-- cur = CUR_CHAR(l);
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return;
-- }
-- while (IS_CHAR(cur) &&
-- ((r != ']') || (s != ']') || (cur != '>'))) {
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return;
-- }
-- }
-- COPY_BUF(rl,buf,len,r);
-- r = s;
-- rl = sl;
-- s = cur;
-- sl = l;
-- count++;
-- if (count > 50) {
-- GROW;
-- count = 0;
-- }
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- }
-- buf[len] = 0;
-- ctxt->instate = XML_PARSER_CONTENT;
-- if (cur != '>') {
-- ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "CData section not finished\n%.50s\n", buf);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFree(buf);
-- return;
-- }
-- NEXTL(l);
--
-- /*
-- * Ok the buffer is to be consumed as cdata.
-- */
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (ctxt->sax->cdataBlock != NULL)
-- ctxt->sax->cdataBlock(ctxt->userData, buf, len);
-- }
-- xmlFree(buf);
--}
--
--/**
-- * xmlParseContent:
-- * @ctxt: an XML parser context
-- *
-- * Parse a content:
-- *
-- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-- */
--
--void
--xmlParseContent(xmlParserCtxtPtr ctxt) {
-- GROW;
-- while (((RAW != 0) || (ctxt->token != 0)) &&
-- ((RAW != '<') || (NXT(1) != '/'))) {
-- const xmlChar *test = CUR_PTR;
-- int cons = ctxt->input->consumed;
-- xmlChar tok = ctxt->token;
--
-- /*
-- * Handle possible processed charrefs.
-- */
-- if (ctxt->token != 0) {
-- xmlParseCharData(ctxt, 0);
-- }
-- /*
-- * First case : a Processing Instruction.
-- */
-- else if ((RAW == '<') && (NXT(1) == '?')) {
-- xmlParsePI(ctxt);
-- }
--
-- /*
-- * Second case : a CDSection
-- */
-- else if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '[') && (NXT(3) == 'C') &&
-- (NXT(4) == 'D') && (NXT(5) == 'A') &&
-- (NXT(6) == 'T') && (NXT(7) == 'A') &&
-- (NXT(8) == '[')) {
-- xmlParseCDSect(ctxt);
-- }
--
-- /*
-- * Third case : a comment
-- */
-- else if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '-') && (NXT(3) == '-')) {
-- xmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_CONTENT;
-- }
--
-- /*
-- * Fourth case : a sub-element.
-- */
-- else if (RAW == '<') {
-- xmlParseElement(ctxt);
-- }
--
-- /*
-- * Fifth case : a reference. If if has not been resolved,
-- * parsing returns it's Name, create the node
-- */
--
-- else if (RAW == '&') {
-- xmlParseReference(ctxt);
-- }
--
-- /*
-- * Last case, text. Note that References are handled directly.
-- */
-- else {
-- xmlParseCharData(ctxt, 0);
-- }
--
-- GROW;
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
-- SHRINK;
--
-- if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
-- (tok == ctxt->token)) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "detected an error in element content\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_EOF;
-- break;
-- }
-- }
--}
--
--/**
-- * xmlParseElement:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML element, this is highly recursive
-- *
-- * [39] element ::= EmptyElemTag | STag content ETag
-- *
-- * [ WFC: Element Type Match ]
-- * The Name in an element's end-tag must match the element type in the
-- * start-tag.
-- *
-- * [ VC: Element Valid ]
-- * An element is valid if there is a declaration matching elementdecl
-- * where the Name matches the element type and one of the following holds:
-- * - The declaration matches EMPTY and the element has no content.
-- * - The declaration matches children and the sequence of child elements
-- * belongs to the language generated by the regular expression in the
-- * content model, with optional white space (characters matching the
-- * nonterminal S) between each pair of child elements.
-- * - The declaration matches Mixed and the content consists of character
-- * data and child elements whose types match names in the content model.
-- * - The declaration matches ANY, and the types of any child elements have
-- * been declared.
-- */
--
--void
--xmlParseElement(xmlParserCtxtPtr ctxt) {
-- const xmlChar *openTag = CUR_PTR;
-- xmlChar *name;
-- xmlChar *oldname;
-- xmlParserNodeInfo node_info;
-- xmlNodePtr ret;
--
-- /* Capture start position */
-- if (ctxt->record_info) {
-- node_info.begin_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.begin_line = ctxt->input->line;
-- }
--
-- if (ctxt->spaceNr == 0)
-- spacePush(ctxt, -1);
-- else
-- spacePush(ctxt, *ctxt->space);
--
-- name = xmlParseStartTag(ctxt);
-- if (name == NULL) {
-- spacePop(ctxt);
-- return;
-- }
-- namePush(ctxt, name);
-- ret = ctxt->node;
--
-- /*
-- * [ VC: Root Element Type ]
-- * The Name in the document type declaration must match the element
-- * type of the root element.
-- */
-- if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
-- ctxt->node && (ctxt->node == ctxt->myDoc->children))
-- ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
--
-- /*
-- * Check for an Empty Element.
-- */
-- if ((RAW == '/') && (NXT(1) == '>')) {
-- SKIP(2);
-- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endElement(ctxt->userData, name);
-- oldname = namePop(ctxt);
-- spacePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG_STACK
-- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- if ( ret != NULL && ctxt->record_info ) {
-- node_info.end_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.end_line = ctxt->input->line;
-- node_info.node = ret;
-- xmlParserAddNodeInfo(ctxt, &node_info);
-- }
-- return;
-- }
-- if (RAW == '>') {
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_GT_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Couldn't find end of Start Tag\n%.30s\n",
-- openTag);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
--
-- /*
-- * end of parsing of this node.
-- */
-- nodePop(ctxt);
-- oldname = namePop(ctxt);
-- spacePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG_STACK
-- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
--
-- /*
-- * Capture end position and add node
-- */
-- if ( ret != NULL && ctxt->record_info ) {
-- node_info.end_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.end_line = ctxt->input->line;
-- node_info.node = ret;
-- xmlParserAddNodeInfo(ctxt, &node_info);
-- }
-- return;
-- }
--
-- /*
-- * Parse the content of the element:
-- */
-- xmlParseContent(ctxt);
-- if (!IS_CHAR(RAW)) {
-- ctxt->errNo = XML_ERR_TAG_NOT_FINISED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Premature end of data in tag %.30s\n", openTag);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
--
-- /*
-- * end of parsing of this node.
-- */
-- nodePop(ctxt);
-- oldname = namePop(ctxt);
-- spacePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG_STACK
-- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- return;
-- }
--
-- /*
-- * parse the end of tag: '</' should be here.
-- */
-- xmlParseEndTag(ctxt);
--
-- /*
-- * Capture end position and add node
-- */
-- if ( ret != NULL && ctxt->record_info ) {
-- node_info.end_pos = ctxt->input->consumed +
-- (CUR_PTR - ctxt->input->base);
-- node_info.end_line = ctxt->input->line;
-- node_info.node = ret;
-- xmlParserAddNodeInfo(ctxt, &node_info);
-- }
--}
--
--/**
-- * xmlParseVersionNum:
-- * @ctxt: an XML parser context
-- *
-- * parse the XML version value.
-- *
-- * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
-- *
-- * Returns the string giving the XML version number, or NULL
-- */
--xmlChar *
--xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = 10;
-- xmlChar cur;
--
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- cur = CUR;
-- while (((cur >= 'a') && (cur <= 'z')) ||
-- ((cur >= 'A') && (cur <= 'Z')) ||
-- ((cur >= '0') && (cur <= '9')) ||
-- (cur == '_') || (cur == '.') ||
-- (cur == ':') || (cur == '-')) {
-- if (len + 1 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- }
-- buf[len++] = cur;
-- NEXT;
-- cur=CUR;
-- }
-- buf[len] = 0;
-- return(buf);
--}
--
--/**
-- * xmlParseVersionInfo:
-- * @ctxt: an XML parser context
-- *
-- * parse the XML version.
-- *
-- * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-- *
-- * [25] Eq ::= S? '=' S?
-- *
-- * Returns the version string, e.g. "1.0"
-- */
--
--xmlChar *
--xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
-- xmlChar *version = NULL;
-- const xmlChar *q;
--
-- if ((RAW == 'v') && (NXT(1) == 'e') &&
-- (NXT(2) == 'r') && (NXT(3) == 's') &&
-- (NXT(4) == 'i') && (NXT(5) == 'o') &&
-- (NXT(6) == 'n')) {
-- SKIP(7);
-- SKIP_BLANKS;
-- if (RAW != '=') {
-- ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseVersionInfo : expected '='\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- NEXT;
-- SKIP_BLANKS;
-- if (RAW == '"') {
-- NEXT;
-- q = CUR_PTR;
-- version = xmlParseVersionNum(ctxt);
-- if (RAW != '"') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "String not closed\n%.50s\n", q);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- } else if (RAW == '\''){
-- NEXT;
-- q = CUR_PTR;
-- version = xmlParseVersionNum(ctxt);
-- if (RAW != '\'') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "String not closed\n%.50s\n", q);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseVersionInfo : expected ' or \"\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
-- return(version);
--}
--
--/**
-- * xmlParseEncName:
-- * @ctxt: an XML parser context
-- *
-- * parse the XML encoding name
-- *
-- * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-- *
-- * Returns the encoding name value or NULL
-- */
--xmlChar *
--xmlParseEncName(xmlParserCtxtPtr ctxt) {
-- xmlChar *buf = NULL;
-- int len = 0;
-- int size = 10;
-- xmlChar cur;
--
-- cur = CUR;
-- if (((cur >= 'a') && (cur <= 'z')) ||
-- ((cur >= 'A') && (cur <= 'Z'))) {
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return(NULL);
-- }
--
-- buf[len++] = cur;
-- NEXT;
-- cur = CUR;
-- while (((cur >= 'a') && (cur <= 'z')) ||
-- ((cur >= 'A') && (cur <= 'Z')) ||
-- ((cur >= '0') && (cur <= '9')) ||
-- (cur == '.') || (cur == '_') ||
-- (cur == '-')) {
-- if (len + 1 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- }
-- buf[len++] = cur;
-- NEXT;
-- cur = CUR;
-- if (cur == 0) {
-- SHRINK;
-- GROW;
-- cur = CUR;
-- }
-- }
-- buf[len] = 0;
-- } else {
-- ctxt->errNo = XML_ERR_ENCODING_NAME;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Invalid XML encoding name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(buf);
--}
--
--/**
-- * xmlParseEncodingDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse the XML encoding declaration
-- *
-- * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'")
-- *
-- * this setups the conversion filters.
-- *
-- * Returns the encoding value or NULL
-- */
--
--xmlChar *
--xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *encoding = NULL;
-- const xmlChar *q;
--
-- SKIP_BLANKS;
-- if ((RAW == 'e') && (NXT(1) == 'n') &&
-- (NXT(2) == 'c') && (NXT(3) == 'o') &&
-- (NXT(4) == 'd') && (NXT(5) == 'i') &&
-- (NXT(6) == 'n') && (NXT(7) == 'g')) {
-- SKIP(8);
-- SKIP_BLANKS;
-- if (RAW != '=') {
-- ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEncodingDecl : expected '='\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(NULL);
-- }
-- NEXT;
-- SKIP_BLANKS;
-- if (RAW == '"') {
-- NEXT;
-- q = CUR_PTR;
-- encoding = xmlParseEncName(ctxt);
-- if (RAW != '"') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "String not closed\n%.50s\n", q);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- } else if (RAW == '\''){
-- NEXT;
-- q = CUR_PTR;
-- encoding = xmlParseEncName(ctxt);
-- if (RAW != '\'') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "String not closed\n%.50s\n", q);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- } else if (RAW == '"'){
-- ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseEncodingDecl : expected ' or \"\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
-- xmlCharEncodingHandlerPtr handler;
--
-- if (ctxt->input->encoding != NULL)
-- xmlFree((xmlChar *) ctxt->input->encoding);
-- ctxt->input->encoding = encoding;
--
-- enc = xmlParseCharEncoding((const char *) encoding);
-- /*
-- * registered set of known encodings
-- */
-- if (enc != XML_CHAR_ENCODING_ERROR) {
-- xmlSwitchEncoding(ctxt, enc);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- xmlFree(encoding);
-- return(NULL);
-- }
-- } else {
-- /*
-- * fallback for unknown encodings
-- */
-- handler = xmlFindCharEncodingHandler((const char *) encoding);
-- if (handler != NULL) {
-- xmlSwitchToEncoding(ctxt, handler);
-- } else {
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Unsupported encoding %s\n", encoding);
-- return(NULL);
-- }
-- }
-- }
-- }
-- return(encoding);
--}
--
--/**
-- * xmlParseSDDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse the XML standalone declaration
-- *
-- * [32] SDDecl ::= S 'standalone' Eq
-- * (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
-- *
-- * [ VC: Standalone Document Declaration ]
-- * TODO The standalone document declaration must have the value "no"
-- * if any external markup declarations contain declarations of:
-- * - attributes with default values, if elements to which these
-- * attributes apply appear in the document without specifications
-- * of values for these attributes, or
-- * - entities (other than amp, lt, gt, apos, quot), if references
-- * to those entities appear in the document, or
-- * - attributes with values subject to normalization, where the
-- * attribute appears in the document with a value which will change
-- * as a result of normalization, or
-- * - element types with element content, if white space occurs directly
-- * within any instance of those types.
-- *
-- * Returns 1 if standalone, 0 otherwise
-- */
--
--int
--xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
-- int standalone = -1;
--
-- SKIP_BLANKS;
-- if ((RAW == 's') && (NXT(1) == 't') &&
-- (NXT(2) == 'a') && (NXT(3) == 'n') &&
-- (NXT(4) == 'd') && (NXT(5) == 'a') &&
-- (NXT(6) == 'l') && (NXT(7) == 'o') &&
-- (NXT(8) == 'n') && (NXT(9) == 'e')) {
-- SKIP(10);
-- SKIP_BLANKS;
-- if (RAW != '=') {
-- ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML standalone declaration : expected '='\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return(standalone);
-- }
-- NEXT;
-- SKIP_BLANKS;
-- if (RAW == '\''){
-- NEXT;
-- if ((RAW == 'n') && (NXT(1) == 'o')) {
-- standalone = 0;
-- SKIP(2);
-- } else if ((RAW == 'y') && (NXT(1) == 'e') &&
-- (NXT(2) == 's')) {
-- standalone = 1;
-- SKIP(3);
-- } else {
-- ctxt->errNo = XML_ERR_STANDALONE_VALUE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "standalone accepts only 'yes' or 'no'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (RAW != '\'') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "String not closed\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- } else if (RAW == '"'){
-- NEXT;
-- if ((RAW == 'n') && (NXT(1) == 'o')) {
-- standalone = 0;
-- SKIP(2);
-- } else if ((RAW == 'y') && (NXT(1) == 'e') &&
-- (NXT(2) == 's')) {
-- standalone = 1;
-- SKIP(3);
-- } else {
-- ctxt->errNo = XML_ERR_STANDALONE_VALUE;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "standalone accepts only 'yes' or 'no'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (RAW != '"') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "String not closed\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Standalone value not found\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- }
-- return(standalone);
--}
--
--/**
-- * xmlParseXMLDecl:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML declaration header
-- *
-- * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-- */
--
--void
--xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
-- xmlChar *version;
--
-- /*
-- * We know that '<?xml' is here.
-- */
-- SKIP(5);
--
-- if (!IS_BLANK(RAW)) {
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Blank needed after '<?xml'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
--
-- /*
-- * We should have the VersionInfo here.
-- */
-- version = xmlParseVersionInfo(ctxt);
-- if (version == NULL)
-- version = xmlCharStrdup(XML_DEFAULT_VERSION);
-- ctxt->version = xmlStrdup(version);
-- xmlFree(version);
--
-- /*
-- * We may have the encoding declaration
-- */
-- if (!IS_BLANK(RAW)) {
-- if ((RAW == '?') && (NXT(1) == '>')) {
-- SKIP(2);
-- return;
-- }
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Blank needed here\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- xmlParseEncodingDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right here
-- */
-- return;
-- }
--
-- /*
-- * We may have the standalone status.
-- */
-- if ((ctxt->input->encoding != NULL) && (!IS_BLANK(RAW))) {
-- if ((RAW == '?') && (NXT(1) == '>')) {
-- SKIP(2);
-- return;
-- }
-- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Blank needed here\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- SKIP_BLANKS;
-- ctxt->input->standalone = xmlParseSDDecl(ctxt);
--
-- SKIP_BLANKS;
-- if ((RAW == '?') && (NXT(1) == '>')) {
-- SKIP(2);
-- } else if (RAW == '>') {
-- /* Deprecated old WD ... */
-- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "XML declaration must end-up with '?>'\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "parsing XML declaration: '?>' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- MOVETO_ENDTAG(CUR_PTR);
-- NEXT;
-- }
--}
--
--/**
-- * xmlParseMisc:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML Misc* optionnal field.
-- *
-- * [27] Misc ::= Comment | PI | S
-- */
--
--void
--xmlParseMisc(xmlParserCtxtPtr ctxt) {
-- while (((RAW == '<') && (NXT(1) == '?')) ||
-- ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == '-') && (NXT(3) == '-')) ||
-- IS_BLANK(CUR)) {
-- if ((RAW == '<') && (NXT(1) == '?')) {
-- xmlParsePI(ctxt);
-- } else if (IS_BLANK(CUR)) {
-- NEXT;
-- } else
-- xmlParseComment(ctxt);
-- }
--}
--
--/**
-- * xmlParseDocument:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML document (and build a tree if using the standard SAX
-- * interface).
-- *
-- * [1] document ::= prolog element Misc*
-- *
-- * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
-- *
-- * Returns 0, -1 in case of error. the parser context is augmented
-- * as a result of the parsing.
-- */
--
--int
--xmlParseDocument(xmlParserCtxtPtr ctxt) {
-- xmlChar start[4];
-- xmlCharEncoding enc;
--
-- xmlInitParser();
--
-- GROW;
--
-- /*
-- * SAX: beginning of the document processing.
-- */
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
--
-- /*
-- * Get the 4 first bytes and decode the charset
-- * if enc != XML_CHAR_ENCODING_NONE
-- * plug some encoding conversion routines.
-- */
-- start[0] = RAW;
-- start[1] = NXT(1);
-- start[2] = NXT(2);
-- start[3] = NXT(3);
-- enc = xmlDetectCharEncoding(start, 4);
-- if (enc != XML_CHAR_ENCODING_NONE) {
-- xmlSwitchEncoding(ctxt, enc);
-- }
--
--
-- if (CUR == 0) {
-- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Document is empty\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * Check for the XMLDecl in the Prolog.
-- */
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
--
-- /*
-- * Note that we will switch encoding on the fly.
-- */
-- xmlParseXMLDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right here
-- */
-- return(-1);
-- }
-- ctxt->standalone = ctxt->input->standalone;
-- SKIP_BLANKS;
-- } else {
-- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-- }
-- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
--
-- /*
-- * The Misc part of the Prolog
-- */
-- GROW;
-- xmlParseMisc(ctxt);
--
-- /*
-- * Then possibly doc type declaration(s) and more Misc
-- * (doctypedecl Misc*)?
-- */
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '!') &&
-- (NXT(2) == 'D') && (NXT(3) == 'O') &&
-- (NXT(4) == 'C') && (NXT(5) == 'T') &&
-- (NXT(6) == 'Y') && (NXT(7) == 'P') &&
-- (NXT(8) == 'E')) {
--
-- ctxt->inSubset = 1;
-- xmlParseDocTypeDecl(ctxt);
-- if (RAW == '[') {
-- ctxt->instate = XML_PARSER_DTD;
-- xmlParseInternalSubset(ctxt);
-- }
--
-- /*
-- * Create and update the external subset.
-- */
-- ctxt->inSubset = 2;
-- if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
-- ctxt->extSubSystem, ctxt->extSubURI);
-- ctxt->inSubset = 0;
--
--
-- ctxt->instate = XML_PARSER_PROLOG;
-- xmlParseMisc(ctxt);
-- }
--
-- /*
-- * Time to start parsing the tree itself
-- */
-- GROW;
-- if (RAW != '<') {
-- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Start tag expected, '<' not found\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_EOF;
-- } else {
-- ctxt->instate = XML_PARSER_CONTENT;
-- xmlParseElement(ctxt);
-- ctxt->instate = XML_PARSER_EPILOG;
--
--
-- /*
-- * The Misc part at the end
-- */
-- xmlParseMisc(ctxt);
--
-- if (RAW != 0) {
-- ctxt->errNo = XML_ERR_DOCUMENT_END;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra content at the end of the document\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- ctxt->instate = XML_PARSER_EOF;
-- }
--
-- /*
-- * SAX: end of the document processing.
-- */
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endDocument(ctxt->userData);
--
-- if (! ctxt->wellFormed) return(-1);
-- return(0);
--}
--
--/**
-- * xmlParseExtParsedEnt:
-- * @ctxt: an XML parser context
-- *
-- * parse a genreral parsed entity
-- * An external general parsed entity is well-formed if it matches the
-- * production labeled extParsedEnt.
-- *
-- * [78] extParsedEnt ::= TextDecl? content
-- *
-- * Returns 0, -1 in case of error. the parser context is augmented
-- * as a result of the parsing.
-- */
--
--int
--xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
-- xmlChar start[4];
-- xmlCharEncoding enc;
--
-- xmlDefaultSAXHandlerInit();
--
-- GROW;
--
-- /*
-- * SAX: beginning of the document processing.
-- */
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
--
-- /*
-- * Get the 4 first bytes and decode the charset
-- * if enc != XML_CHAR_ENCODING_NONE
-- * plug some encoding conversion routines.
-- */
-- start[0] = RAW;
-- start[1] = NXT(1);
-- start[2] = NXT(2);
-- start[3] = NXT(3);
-- enc = xmlDetectCharEncoding(start, 4);
-- if (enc != XML_CHAR_ENCODING_NONE) {
-- xmlSwitchEncoding(ctxt, enc);
-- }
--
--
-- if (CUR == 0) {
-- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Document is empty\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * Check for the XMLDecl in the Prolog.
-- */
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
--
-- /*
-- * Note that we will switch encoding on the fly.
-- */
-- xmlParseXMLDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right here
-- */
-- return(-1);
-- }
-- SKIP_BLANKS;
-- } else {
-- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-- }
-- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
--
-- /*
-- * Doing validity checking on chunk doesn't make sense
-- */
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->validate = 0;
-- ctxt->loadsubset = 0;
-- ctxt->depth = 0;
--
-- xmlParseContent(ctxt);
--
-- if ((RAW == '<') && (NXT(1) == '/')) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if (RAW != 0) {
-- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "extra content at the end of well balanced chunk\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- /*
-- * SAX: end of the document processing.
-- */
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endDocument(ctxt->userData);
--
-- if (! ctxt->wellFormed) return(-1);
-- return(0);
--}
--
--/************************************************************************
-- * *
-- * Progressive parsing interfaces *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlParseLookupSequence:
-- * @ctxt: an XML parser context
-- * @first: the first char to lookup
-- * @next: the next char to lookup or zero
-- * @third: the next char to lookup or zero
-- *
-- * Try to find if a sequence (first, next, third) or just (first next) or
-- * (first) is available in the input stream.
-- * This function has a side effect of (possibly) incrementing ctxt->checkIndex
-- * to avoid rescanning sequences of bytes, it DOES change the state of the
-- * parser, do not use liberally.
-- *
-- * Returns the index to the current parsing point if the full sequence
-- * is available, -1 otherwise.
-- */
--int
--xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
-- xmlChar next, xmlChar third) {
-- int base, len;
-- xmlParserInputPtr in;
-- const xmlChar *buf;
--
-- in = ctxt->input;
-- if (in == NULL) return(-1);
-- base = in->cur - in->base;
-- if (base < 0) return(-1);
-- if (ctxt->checkIndex > base)
-- base = ctxt->checkIndex;
-- if (in->buf == NULL) {
-- buf = in->base;
-- len = in->length;
-- } else {
-- buf = in->buf->buffer->content;
-- len = in->buf->buffer->use;
-- }
-- /* take into account the sequence length */
-- if (third) len -= 2;
-- else if (next) len --;
-- for (;base < len;base++) {
-- if (buf[base] == first) {
-- if (third != 0) {
-- if ((buf[base + 1] != next) ||
-- (buf[base + 2] != third)) continue;
-- } else if (next != 0) {
-- if (buf[base + 1] != next) continue;
-- }
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- if (next == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup '%c' found at %d\n",
-- first, base);
-- else if (third == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup '%c%c' found at %d\n",
-- first, next, base);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup '%c%c%c' found at %d\n",
-- first, next, third, base);
--#endif
-- return(base - (in->cur - in->base));
-- }
-- }
-- ctxt->checkIndex = base;
--#ifdef DEBUG_PUSH
-- if (next == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup '%c' failed\n", first);
-- else if (third == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup '%c%c' failed\n", first, next);
-- else
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup '%c%c%c' failed\n", first, next, third);
--#endif
-- return(-1);
--}
--
--/**
-- * xmlParseTryOrFinish:
-- * @ctxt: an XML parser context
-- * @terminate: last chunk indicator
-- *
-- * Try to progress on parsing
-- *
-- * Returns zero if no parsing was possible
-- */
--int
--xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
-- int ret = 0;
-- int avail;
-- xmlChar cur, next;
--
--#ifdef DEBUG_PUSH
-- switch (ctxt->instate) {
-- case XML_PARSER_EOF:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try EOF\n"); break;
-- case XML_PARSER_START:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try START\n"); break;
-- case XML_PARSER_MISC:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try MISC\n");break;
-- case XML_PARSER_COMMENT:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try COMMENT\n");break;
-- case XML_PARSER_PROLOG:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try PROLOG\n");break;
-- case XML_PARSER_START_TAG:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try START_TAG\n");break;
-- case XML_PARSER_CONTENT:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try CONTENT\n");break;
-- case XML_PARSER_CDATA_SECTION:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try CDATA_SECTION\n");break;
-- case XML_PARSER_END_TAG:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try END_TAG\n");break;
-- case XML_PARSER_ENTITY_DECL:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try ENTITY_DECL\n");break;
-- case XML_PARSER_ENTITY_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try ENTITY_VALUE\n");break;
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try ATTRIBUTE_VALUE\n");break;
-- case XML_PARSER_DTD:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try DTD\n");break;
-- case XML_PARSER_EPILOG:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try EPILOG\n");break;
-- case XML_PARSER_PI:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try PI\n");break;
-- case XML_PARSER_IGNORE:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: try IGNORE\n");break;
-- }
--#endif
--
-- while (1) {
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
--
-- if (ctxt->input ==NULL) break;
-- if (ctxt->input->buf == NULL)
-- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-- else
-- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-- if (avail < 1)
-- goto done;
-- switch (ctxt->instate) {
-- case XML_PARSER_EOF:
-- /*
-- * Document parsing is done !
-- */
-- goto done;
-- case XML_PARSER_START:
-- /*
-- * Very first chars read from the document flow.
-- */
-- cur = ctxt->input->cur[0];
-- if (IS_BLANK(cur)) {
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData,
-- &xmlDefaultSAXLocator);
-- ctxt->errNo = XML_ERR_DOCUMENT_START;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra spaces at the beginning of the document are not allowed\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- SKIP_BLANKS;
-- ret++;
-- if (ctxt->input->buf == NULL)
-- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-- else
-- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-- }
-- if (avail < 2)
-- goto done;
--
-- cur = ctxt->input->cur[0];
-- next = ctxt->input->cur[1];
-- if (cur == 0) {
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData,
-- &xmlDefaultSAXLocator);
-- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Document is empty\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_EOF;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering EOF\n");
--#endif
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-- ctxt->sax->endDocument(ctxt->userData);
-- goto done;
-- }
-- if ((cur == '<') && (next == '?')) {
-- /* PI or XML decl */
-- if (avail < 5) return(ret);
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-- return(ret);
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData,
-- &xmlDefaultSAXLocator);
-- if ((ctxt->input->cur[2] == 'x') &&
-- (ctxt->input->cur[3] == 'm') &&
-- (ctxt->input->cur[4] == 'l') &&
-- (IS_BLANK(ctxt->input->cur[5]))) {
-- ret += 5;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing XML Decl\n");
--#endif
-- xmlParseXMLDecl(ctxt);
-- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
-- /*
-- * The XML REC instructs us to stop parsing right
-- * here
-- */
-- ctxt->instate = XML_PARSER_EOF;
-- return(0);
-- }
-- ctxt->standalone = ctxt->input->standalone;
-- if ((ctxt->encoding == NULL) &&
-- (ctxt->input->encoding != NULL))
-- ctxt->encoding = xmlStrdup(ctxt->input->encoding);
-- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
-- ctxt->instate = XML_PARSER_MISC;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering MISC\n");
--#endif
-- } else {
-- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
-- ctxt->instate = XML_PARSER_MISC;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering MISC\n");
--#endif
-- }
-- } else {
-- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
-- ctxt->sax->setDocumentLocator(ctxt->userData,
-- &xmlDefaultSAXLocator);
-- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
-- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->startDocument(ctxt->userData);
-- ctxt->instate = XML_PARSER_MISC;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering MISC\n");
--#endif
-- }
-- break;
-- case XML_PARSER_MISC:
-- SKIP_BLANKS;
-- if (ctxt->input->buf == NULL)
-- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-- else
-- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-- if (avail < 2)
-- goto done;
-- cur = ctxt->input->cur[0];
-- next = ctxt->input->cur[1];
-- if ((cur == '<') && (next == '?')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing PI\n");
--#endif
-- xmlParsePI(ctxt);
-- } else if ((cur == '<') && (next == '!') &&
-- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing Comment\n");
--#endif
-- xmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_MISC;
-- } else if ((cur == '<') && (next == '!') &&
-- (ctxt->input->cur[2] == 'D') && (ctxt->input->cur[3] == 'O') &&
-- (ctxt->input->cur[4] == 'C') && (ctxt->input->cur[5] == 'T') &&
-- (ctxt->input->cur[6] == 'Y') && (ctxt->input->cur[7] == 'P') &&
-- (ctxt->input->cur[8] == 'E')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing internal subset\n");
--#endif
-- ctxt->inSubset = 1;
-- xmlParseDocTypeDecl(ctxt);
-- if (RAW == '[') {
-- ctxt->instate = XML_PARSER_DTD;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering DTD\n");
--#endif
-- } else {
-- /*
-- * Create and update the external subset.
-- */
-- ctxt->inSubset = 2;
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->externalSubset != NULL))
-- ctxt->sax->externalSubset(ctxt->userData,
-- ctxt->intSubName, ctxt->extSubSystem,
-- ctxt->extSubURI);
-- ctxt->inSubset = 0;
-- ctxt->instate = XML_PARSER_PROLOG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering PROLOG\n");
--#endif
-- }
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 9)) {
-- goto done;
-- } else {
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering START_TAG\n");
--#endif
-- }
-- break;
-- case XML_PARSER_IGNORE:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == IGNORE");
-- ctxt->instate = XML_PARSER_DTD;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering DTD\n");
--#endif
-- break;
-- case XML_PARSER_PROLOG:
-- SKIP_BLANKS;
-- if (ctxt->input->buf == NULL)
-- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-- else
-- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-- if (avail < 2)
-- goto done;
-- cur = ctxt->input->cur[0];
-- next = ctxt->input->cur[1];
-- if ((cur == '<') && (next == '?')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing PI\n");
--#endif
-- xmlParsePI(ctxt);
-- } else if ((cur == '<') && (next == '!') &&
-- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing Comment\n");
--#endif
-- xmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_PROLOG;
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 4)) {
-- goto done;
-- } else {
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering START_TAG\n");
--#endif
-- }
-- break;
-- case XML_PARSER_EPILOG:
-- SKIP_BLANKS;
-- if (ctxt->input->buf == NULL)
-- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
-- else
-- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
-- if (avail < 2)
-- goto done;
-- cur = ctxt->input->cur[0];
-- next = ctxt->input->cur[1];
-- if ((cur == '<') && (next == '?')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing PI\n");
--#endif
-- xmlParsePI(ctxt);
-- ctxt->instate = XML_PARSER_EPILOG;
-- } else if ((cur == '<') && (next == '!') &&
-- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing Comment\n");
--#endif
-- xmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_EPILOG;
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 4)) {
-- goto done;
-- } else {
-- ctxt->errNo = XML_ERR_DOCUMENT_END;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra content at the end of the document\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_EOF;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering EOF\n");
--#endif
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endDocument(ctxt->userData);
-- goto done;
-- }
-- break;
-- case XML_PARSER_START_TAG: {
-- xmlChar *name, *oldname;
--
-- if ((avail < 2) && (ctxt->inputNr == 1))
-- goto done;
-- cur = ctxt->input->cur[0];
-- if (cur != '<') {
-- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Start tag expect, '<' not found\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_EOF;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering EOF\n");
--#endif
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endDocument(ctxt->userData);
-- goto done;
-- }
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
-- if (ctxt->spaceNr == 0)
-- spacePush(ctxt, -1);
-- else
-- spacePush(ctxt, *ctxt->space);
-- name = xmlParseStartTag(ctxt);
-- if (name == NULL) {
-- spacePop(ctxt);
-- ctxt->instate = XML_PARSER_EOF;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering EOF\n");
--#endif
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endDocument(ctxt->userData);
-- goto done;
-- }
-- namePush(ctxt, xmlStrdup(name));
--
-- /*
-- * [ VC: Root Element Type ]
-- * The Name in the document type declaration must match
-- * the element type of the root element.
-- */
-- if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
-- ctxt->node && (ctxt->node == ctxt->myDoc->children))
-- ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
--
-- /*
-- * Check for an Empty Element.
-- */
-- if ((RAW == '/') && (NXT(1) == '>')) {
-- SKIP(2);
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->endElement != NULL) && (!ctxt->disableSAX))
-- ctxt->sax->endElement(ctxt->userData, name);
-- xmlFree(name);
-- oldname = namePop(ctxt);
-- spacePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG_STACK
-- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- if (ctxt->name == NULL) {
-- ctxt->instate = XML_PARSER_EPILOG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering EPILOG\n");
--#endif
-- } else {
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CONTENT\n");
--#endif
-- }
-- break;
-- }
-- if (RAW == '>') {
-- NEXT;
-- } else {
-- ctxt->errNo = XML_ERR_GT_REQUIRED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Couldn't find end of Start Tag %s\n",
-- name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
--
-- /*
-- * end of parsing of this node.
-- */
-- nodePop(ctxt);
-- oldname = namePop(ctxt);
-- spacePop(ctxt);
-- if (oldname != NULL) {
--#ifdef DEBUG_STACK
-- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
--#endif
-- xmlFree(oldname);
-- }
-- }
-- xmlFree(name);
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CONTENT\n");
--#endif
-- break;
-- }
-- case XML_PARSER_CONTENT: {
-- const xmlChar *test;
-- int cons;
-- xmlChar tok;
--
-- /*
-- * Handle preparsed entities and charRef
-- */
-- if (ctxt->token != 0) {
-- xmlChar cur[2] = { 0 , 0 } ;
--
-- cur[0] = (xmlChar) ctxt->token;
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, cur, 1);
-- ctxt->token = 0;
-- }
-- if ((avail < 2) && (ctxt->inputNr == 1))
-- goto done;
-- cur = ctxt->input->cur[0];
-- next = ctxt->input->cur[1];
--
-- test = CUR_PTR;
-- cons = ctxt->input->consumed;
-- tok = ctxt->token;
-- if ((cur == '<') && (next == '?')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing PI\n");
--#endif
-- xmlParsePI(ctxt);
-- } else if ((cur == '<') && (next == '!') &&
-- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing Comment\n");
--#endif
-- xmlParseComment(ctxt);
-- ctxt->instate = XML_PARSER_CONTENT;
-- } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
-- (ctxt->input->cur[2] == '[') && (NXT(3) == 'C') &&
-- (ctxt->input->cur[4] == 'D') && (NXT(5) == 'A') &&
-- (ctxt->input->cur[6] == 'T') && (NXT(7) == 'A') &&
-- (ctxt->input->cur[8] == '[')) {
-- SKIP(9);
-- ctxt->instate = XML_PARSER_CDATA_SECTION;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CDATA_SECTION\n");
--#endif
-- break;
-- } else if ((cur == '<') && (next == '!') &&
-- (avail < 9)) {
-- goto done;
-- } else if ((cur == '<') && (next == '/')) {
-- ctxt->instate = XML_PARSER_END_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering END_TAG\n");
--#endif
-- break;
-- } else if (cur == '<') {
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering START_TAG\n");
--#endif
-- break;
-- } else if (cur == '&') {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
-- goto done;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing Reference\n");
--#endif
-- xmlParseReference(ctxt);
-- } else {
-- /* TODO Avoid the extra copy, handle directly !!! */
-- /*
-- * Goal of the following test is:
-- * - minimize calls to the SAX 'character' callback
-- * when they are mergeable
-- * - handle an problem for isBlank when we only parse
-- * a sequence of blank chars and the next one is
-- * not available to check against '<' presence.
-- * - tries to homogenize the differences in SAX
-- * callbacks beween the push and pull versions
-- * of the parser.
-- */
-- if ((ctxt->inputNr == 1) &&
-- (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
-- goto done;
-- }
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: Parsing char data\n");
--#endif
-- xmlParseCharData(ctxt, 0);
-- }
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1))
-- xmlPopInput(ctxt);
-- if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
-- (tok == ctxt->token)) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "detected an error in element content\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->instate = XML_PARSER_EOF;
-- break;
-- }
-- break;
-- }
-- case XML_PARSER_CDATA_SECTION: {
-- /*
-- * The Push mode need to have the SAX callback for
-- * cdataBlock merge back contiguous callbacks.
-- */
-- int base;
--
-- base = xmlParseLookupSequence(ctxt, ']', ']', '>');
-- if (base < 0) {
-- if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
-- if (ctxt->sax->cdataBlock != NULL)
-- ctxt->sax->cdataBlock(ctxt->userData, ctxt->input->cur,
-- XML_PARSER_BIG_BUFFER_SIZE);
-- }
-- SKIP(XML_PARSER_BIG_BUFFER_SIZE);
-- ctxt->checkIndex = 0;
-- }
-- goto done;
-- } else {
-- if ((ctxt->sax != NULL) && (base > 0) &&
-- (!ctxt->disableSAX)) {
-- if (ctxt->sax->cdataBlock != NULL)
-- ctxt->sax->cdataBlock(ctxt->userData,
-- ctxt->input->cur, base);
-- }
-- SKIP(base + 3);
-- ctxt->checkIndex = 0;
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CONTENT\n");
--#endif
-- }
-- break;
-- }
-- case XML_PARSER_END_TAG:
-- if (avail < 2)
-- goto done;
-- if ((!terminate) &&
-- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
-- goto done;
-- xmlParseEndTag(ctxt);
-- if (ctxt->name == NULL) {
-- ctxt->instate = XML_PARSER_EPILOG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering EPILOG\n");
--#endif
-- } else {
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CONTENT\n");
--#endif
-- }
-- break;
-- case XML_PARSER_DTD: {
-- /*
-- * Sorry but progressive parsing of the internal subset
-- * is not expected to be supported. We first check that
-- * the full content of the internal subset is available and
-- * the parsing is launched only at that point.
-- * Internal subset ends up with "']' S? '>'" in an unescaped
-- * section and not in a ']]>' sequence which are conditional
-- * sections (whoever argued to keep that crap in XML deserve
-- * a place in hell !).
-- */
-- int base, i;
-- xmlChar *buf;
-- xmlChar quote = 0;
--
-- base = ctxt->input->cur - ctxt->input->base;
-- if (base < 0) return(0);
-- if (ctxt->checkIndex > base)
-- base = ctxt->checkIndex;
-- buf = ctxt->input->buf->buffer->content;
-- for (;(unsigned int) base < ctxt->input->buf->buffer->use;
-- base++) {
-- if (quote != 0) {
-- if (buf[base] == quote)
-- quote = 0;
-- continue;
-- }
-- if (buf[base] == '"') {
-- quote = '"';
-- continue;
-- }
-- if (buf[base] == '\'') {
-- quote = '\'';
-- continue;
-- }
-- if (buf[base] == ']') {
-- if ((unsigned int) base +1 >=
-- ctxt->input->buf->buffer->use)
-- break;
-- if (buf[base + 1] == ']') {
-- /* conditional crap, skip both ']' ! */
-- base++;
-- continue;
-- }
-- for (i = 0;
-- (unsigned int) base + i < ctxt->input->buf->buffer->use;
-- i++) {
-- if (buf[base + i] == '>')
-- goto found_end_int_subset;
-- }
-- break;
-- }
-- }
-- /*
-- * We didn't found the end of the Internal subset
-- */
-- if (quote == 0)
-- ctxt->checkIndex = base;
--#ifdef DEBUG_PUSH
-- if (next == 0)
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: lookup of int subset end filed\n");
--#endif
-- goto done;
--
--found_end_int_subset:
-- xmlParseInternalSubset(ctxt);
-- ctxt->inSubset = 2;
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->externalSubset != NULL))
-- ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
-- ctxt->extSubSystem, ctxt->extSubURI);
-- ctxt->inSubset = 0;
-- ctxt->instate = XML_PARSER_PROLOG;
-- ctxt->checkIndex = 0;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering PROLOG\n");
--#endif
-- break;
-- }
-- case XML_PARSER_COMMENT:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == COMMENT\n");
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_PI:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == PI\n");
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering CONTENT\n");
--#endif
-- break;
-- case XML_PARSER_ENTITY_DECL:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == ENTITY_DECL\n");
-- ctxt->instate = XML_PARSER_DTD;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering DTD\n");
--#endif
-- break;
-- case XML_PARSER_ENTITY_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == ENTITY_VALUE\n");
-- ctxt->instate = XML_PARSER_CONTENT;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering DTD\n");
--#endif
-- break;
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == ATTRIBUTE_VALUE\n");
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering START_TAG\n");
--#endif
-- break;
-- case XML_PARSER_SYSTEM_LITERAL:
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: internal error, state == SYSTEM_LITERAL\n");
-- ctxt->instate = XML_PARSER_START_TAG;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext,
-- "PP: entering START_TAG\n");
--#endif
-- break;
-- }
-- }
--done:
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
--#endif
-- return(ret);
--}
--
--/**
-- * xmlParseTry:
-- * @ctxt: an XML parser context
-- *
-- * Try to progress on parsing
-- *
-- * Returns zero if no parsing was possible
-- */
--int
--xmlParseTry(xmlParserCtxtPtr ctxt) {
-- return(xmlParseTryOrFinish(ctxt, 0));
--}
--
--/**
-- * xmlParseChunk:
-- * @ctxt: an XML parser context
-- * @chunk: an char array
-- * @size: the size in byte of the chunk
-- * @terminate: last chunk indicator
-- *
-- * Parse a Chunk of memory
-- *
-- * Returns zero if no error, the xmlParserErrors otherwise.
-- */
--int
--xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
-- int terminate) {
-- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
-- int base = ctxt->input->base - ctxt->input->buf->buffer->content;
-- int cur = ctxt->input->cur - ctxt->input->base;
--
-- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-- ctxt->input->base = ctxt->input->buf->buffer->content + base;
-- ctxt->input->cur = ctxt->input->base + cur;
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
--#endif
--
-- if ((terminate) || (ctxt->input->buf->buffer->use > 80))
-- xmlParseTryOrFinish(ctxt, terminate);
-- } else if (ctxt->instate != XML_PARSER_EOF) {
-- if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
-- xmlParserInputBufferPtr in = ctxt->input->buf;
-- if ((in->encoder != NULL) && (in->buffer != NULL) &&
-- (in->raw != NULL)) {
-- int nbchars;
--
-- nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-- if (nbchars < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParseChunk: encoder error\n");
-- return(XML_ERR_INVALID_ENCODING);
-- }
-- }
-- }
-- }
-- xmlParseTryOrFinish(ctxt, terminate);
-- if (terminate) {
-- /*
-- * Check for termination
-- */
-- if ((ctxt->instate != XML_PARSER_EOF) &&
-- (ctxt->instate != XML_PARSER_EPILOG)) {
-- ctxt->errNo = XML_ERR_DOCUMENT_END;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Extra content at the end of the document\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (ctxt->instate != XML_PARSER_EOF) {
-- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL) &&
-- (!ctxt->disableSAX))
-- ctxt->sax->endDocument(ctxt->userData);
-- }
-- ctxt->instate = XML_PARSER_EOF;
-- }
-- return((xmlParserErrors) ctxt->errNo);
--}
--
--/************************************************************************
-- * *
-- * I/O front end functions to the parser *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlStopParser:
-- * @ctxt: an XML parser context
-- *
-- * Blocks further parser processing
-- */
--void
--xmlStopParser(xmlParserCtxtPtr ctxt) {
-- ctxt->instate = XML_PARSER_EOF;
-- if (ctxt->input != NULL)
-- ctxt->input->cur = BAD_CAST"";
--}
--
--/**
-- * xmlCreatePushParserCtxt:
-- * @sax: a SAX handler
-- * @user_data: The user data returned on SAX callbacks
-- * @chunk: a pointer to an array of chars
-- * @size: number of chars in the array
-- * @filename: an optional file name or URI
-- *
-- * Create a parser context for using the XML parser in push mode
-- * To allow content encoding detection, @size should be >= 4
-- * The value of @filename is used for fetching external entities
-- * and error/warning reports.
-- *
-- * Returns the new parser context or NULL
-- */
--xmlParserCtxtPtr
--xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
-- const char *chunk, int size, const char *filename) {
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr inputStream;
-- xmlParserInputBufferPtr buf;
-- xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
--
-- /*
-- * plug some encoding conversion routines
-- */
-- if ((chunk != NULL) && (size >= 4))
-- enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
--
-- buf = xmlAllocParserInputBuffer(enc);
-- if (buf == NULL) return(NULL);
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL) {
-- xmlFree(buf);
-- return(NULL);
-- }
-- if (sax != NULL) {
-- if (ctxt->sax != &xmlDefaultSAXHandler)
-- xmlFree(ctxt->sax);
-- ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
-- if (ctxt->sax == NULL) {
-- xmlFree(buf);
-- xmlFree(ctxt);
-- return(NULL);
-- }
-- memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
-- if (user_data != NULL)
-- ctxt->userData = user_data;
-- }
-- if (filename == NULL) {
-- ctxt->directory = NULL;
-- } else {
-- ctxt->directory = xmlParserGetDirectory(filename);
-- }
--
-- inputStream = xmlNewInputStream(ctxt);
-- if (inputStream == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- if (filename == NULL)
-- inputStream->filename = NULL;
-- else
-- inputStream->filename = xmlMemStrdup(filename);
-- inputStream->buf = buf;
-- inputStream->base = inputStream->buf->buffer->content;
-- inputStream->cur = inputStream->buf->buffer->content;
-- if (enc != XML_CHAR_ENCODING_NONE) {
-- xmlSwitchEncoding(ctxt, enc);
-- }
--
-- inputPush(ctxt, inputStream);
--
-- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-- (ctxt->input->buf != NULL)) {
-- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
--#ifdef DEBUG_PUSH
-- xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
--#endif
-- }
--
-- return(ctxt);
--}
--
--/**
-- * xmlCreateIOParserCtxt:
-- * @sax: a SAX handler
-- * @user_data: The user data returned on SAX callbacks
-- * @ioread: an I/O read function
-- * @ioclose: an I/O close function
-- * @ioctx: an I/O handler
-- * @enc: the charset encoding if known
-- *
-- * Create a parser context for using the XML parser with an existing
-- * I/O stream
-- *
-- * Returns the new parser context or NULL
-- */
--xmlParserCtxtPtr
--xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
-- xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
-- void *ioctx, xmlCharEncoding enc) {
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr inputStream;
-- xmlParserInputBufferPtr buf;
--
-- buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
-- if (buf == NULL) return(NULL);
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL) {
-- xmlFree(buf);
-- return(NULL);
-- }
-- if (sax != NULL) {
-- if (ctxt->sax != &xmlDefaultSAXHandler)
-- xmlFree(ctxt->sax);
-- ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
-- if (ctxt->sax == NULL) {
-- xmlFree(buf);
-- xmlFree(ctxt);
-- return(NULL);
-- }
-- memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
-- if (user_data != NULL)
-- ctxt->userData = user_data;
-- }
--
-- inputStream = xmlNewIOInputStream(ctxt, buf, enc);
-- if (inputStream == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
-- inputPush(ctxt, inputStream);
--
-- return(ctxt);
--}
--
--/************************************************************************
-- * *
-- * Front ends when parsing a Dtd *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlIOParseDTD:
-- * @sax: the SAX handler block or NULL
-- * @input: an Input Buffer
-- * @enc: the charset encoding if known
-- *
-- * Load and parse a DTD
-- *
-- * Returns the resulting xmlDtdPtr or NULL in case of error.
-- * @input will be freed at parsing end.
-- */
--
--xmlDtdPtr
--xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
-- xmlCharEncoding enc) {
-- xmlDtdPtr ret = NULL;
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr pinput = NULL;
--
-- if (input == NULL)
-- return(NULL);
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL) {
-- return(NULL);
-- }
--
-- /*
-- * Set-up the SAX context
-- */
-- if (sax != NULL) {
-- if (ctxt->sax != NULL)
-- xmlFree(ctxt->sax);
-- ctxt->sax = sax;
-- ctxt->userData = NULL;
-- }
--
-- /*
-- * generate a parser input from the I/O handler
-- */
--
-- pinput = xmlNewIOInputStream(ctxt, input, enc);
-- if (pinput == NULL) {
-- if (sax != NULL) ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- /*
-- * plug some encoding conversion routines here.
-- */
-- xmlPushInput(ctxt, pinput);
--
-- pinput->filename = NULL;
-- pinput->line = 1;
-- pinput->col = 1;
-- pinput->base = ctxt->input->cur;
-- pinput->cur = ctxt->input->cur;
-- pinput->free = NULL;
--
-- /*
-- * let's parse that entity knowing it's an external subset.
-- */
-- ctxt->inSubset = 2;
-- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-- ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
-- BAD_CAST "none", BAD_CAST "none");
-- xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
--
-- if (ctxt->myDoc != NULL) {
-- if (ctxt->wellFormed) {
-- ret = ctxt->myDoc->extSubset;
-- ctxt->myDoc->extSubset = NULL;
-- } else {
-- ret = NULL;
-- }
-- xmlFreeDoc(ctxt->myDoc);
-- ctxt->myDoc = NULL;
-- }
-- if (sax != NULL) ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * xmlSAXParseDTD:
-- * @sax: the SAX handler block
-- * @ExternalID: a NAME* containing the External ID of the DTD
-- * @SystemID: a NAME* containing the URL to the DTD
-- *
-- * Load and parse an external subset.
-- *
-- * Returns the resulting xmlDtdPtr or NULL in case of error.
-- */
--
--xmlDtdPtr
--xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
-- const xmlChar *SystemID) {
-- xmlDtdPtr ret = NULL;
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr input = NULL;
-- xmlCharEncoding enc;
--
-- if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL) {
-- return(NULL);
-- }
--
-- /*
-- * Set-up the SAX context
-- */
-- if (sax != NULL) {
-- if (ctxt->sax != NULL)
-- xmlFree(ctxt->sax);
-- ctxt->sax = sax;
-- ctxt->userData = NULL;
-- }
--
-- /*
-- * Ask the Entity resolver to load the damn thing
-- */
--
-- if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
-- input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, SystemID);
-- if (input == NULL) {
-- if (sax != NULL) ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- /*
-- * plug some encoding conversion routines here.
-- */
-- xmlPushInput(ctxt, input);
-- enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
-- xmlSwitchEncoding(ctxt, enc);
--
-- if (input->filename == NULL)
-- input->filename = (char *) xmlStrdup(SystemID);
-- input->line = 1;
-- input->col = 1;
-- input->base = ctxt->input->cur;
-- input->cur = ctxt->input->cur;
-- input->free = NULL;
--
-- /*
-- * let's parse that entity knowing it's an external subset.
-- */
-- ctxt->inSubset = 2;
-- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-- ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
-- ExternalID, SystemID);
-- xmlParseExternalSubset(ctxt, ExternalID, SystemID);
--
-- if (ctxt->myDoc != NULL) {
-- if (ctxt->wellFormed) {
-- ret = ctxt->myDoc->extSubset;
-- ctxt->myDoc->extSubset = NULL;
-- } else {
-- ret = NULL;
-- }
-- xmlFreeDoc(ctxt->myDoc);
-- ctxt->myDoc = NULL;
-- }
-- if (sax != NULL) ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * xmlParseDTD:
-- * @ExternalID: a NAME* containing the External ID of the DTD
-- * @SystemID: a NAME* containing the URL to the DTD
-- *
-- * Load and parse an external subset.
-- *
-- * Returns the resulting xmlDtdPtr or NULL in case of error.
-- */
--
--xmlDtdPtr
--xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
-- return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
--}
--
--/************************************************************************
-- * *
-- * Front ends when parsing an Entity *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlSAXParseBalancedChunk:
-- * @ctx: an XML parser context (possibly NULL)
-- * @sax: the SAX handler bloc (possibly NULL)
-- * @user_data: The user data returned on SAX callbacks (possibly NULL)
-- * @input: a parser input stream
-- * @enc: the encoding
-- *
-- * Parse a well-balanced chunk of an XML document
-- * The user has to provide SAX callback block whose routines will be
-- * called by the parser
-- * The allowed sequence for the Well Balanced Chunk is the one defined by
-- * the content production in the XML grammar:
-- *
-- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-- *
-- * Returns 0 if the chunk is well balanced, -1 in case of args problem and
-- * the error code otherwise
-- */
--
--int
--xmlSAXParseBalancedChunk(xmlParserCtxtPtr ctx, xmlSAXHandlerPtr sax,
-- void *user_data, xmlParserInputPtr input,
-- xmlCharEncoding enc) {
-- xmlParserCtxtPtr ctxt;
-- int ret;
--
-- if (input == NULL) return(-1);
--
-- if (ctx != NULL)
-- ctxt = ctx;
-- else {
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL)
-- return(-1);
-- if (sax == NULL)
-- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
-- }
--
-- /*
-- * Set-up the SAX context
-- */
-- if (sax != NULL) {
-- if (ctxt->sax != NULL)
-- xmlFree(ctxt->sax);
-- ctxt->sax = sax;
-- ctxt->userData = user_data;
-- }
--
-- /*
-- * plug some encoding conversion routines here.
-- */
-- xmlPushInput(ctxt, input);
-- if (enc != XML_CHAR_ENCODING_NONE)
-- xmlSwitchEncoding(ctxt, enc);
--
-- /*
-- * let's parse that entity knowing it's an external subset.
-- */
-- xmlParseContent(ctxt);
-- ret = ctxt->errNo;
--
-- if (ctx == NULL) {
-- if (sax != NULL)
-- ctxt->sax = NULL;
-- else
-- xmlFreeDoc(ctxt->myDoc);
-- xmlFreeParserCtxt(ctxt);
-- }
-- return(ret);
--}
--
--/**
-- * xmlParseCtxtExternalEntity:
-- * @ctx: the existing parsing context
-- * @URL: the URL for the entity to load
-- * @ID: the System ID for the entity to load
-- * @list: the return value for the set of parsed nodes
-- *
-- * Parse an external general entity within an existing parsing context
-- * An external general parsed entity is well-formed if it matches the
-- * production labeled extParsedEnt.
-- *
-- * [78] extParsedEnt ::= TextDecl? content
-- *
-- * Returns 0 if the entity is well formed, -1 in case of args problem and
-- * the parser error code otherwise
-- */
--
--int
--xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
-- const xmlChar *ID, xmlNodePtr *list) {
-- xmlParserCtxtPtr ctxt;
-- xmlDocPtr newDoc;
-- xmlSAXHandlerPtr oldsax = NULL;
-- int ret = 0;
--
-- if (ctx->depth > 40) {
-- return(XML_ERR_ENTITY_LOOP);
-- }
--
-- if (list != NULL)
-- *list = NULL;
-- if ((URL == NULL) && (ID == NULL))
-- return(-1);
-- if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
-- return(-1);
--
--
-- ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
-- if (ctxt == NULL) return(-1);
-- ctxt->userData = ctxt;
-- oldsax = ctxt->sax;
-- ctxt->sax = ctx->sax;
-- newDoc = xmlNewDoc(BAD_CAST "1.0");
-- if (newDoc == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(-1);
-- }
-- if (ctx->myDoc != NULL) {
-- newDoc->intSubset = ctx->myDoc->intSubset;
-- newDoc->extSubset = ctx->myDoc->extSubset;
-- }
-- if (ctx->myDoc->URL != NULL) {
-- newDoc->URL = xmlStrdup(ctx->myDoc->URL);
-- }
-- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-- if (newDoc->children == NULL) {
-- ctxt->sax = oldsax;
-- xmlFreeParserCtxt(ctxt);
-- newDoc->intSubset = NULL;
-- newDoc->extSubset = NULL;
-- xmlFreeDoc(newDoc);
-- return(-1);
-- }
-- nodePush(ctxt, newDoc->children);
-- if (ctx->myDoc == NULL) {
-- ctxt->myDoc = newDoc;
-- } else {
-- ctxt->myDoc = ctx->myDoc;
-- newDoc->children->doc = ctx->myDoc;
-- }
--
-- /*
-- * Parse a possible text declaration first
-- */
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-- xmlParseTextDecl(ctxt);
-- }
--
-- /*
-- * Doing validity checking on chunk doesn't make sense
-- */
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->validate = ctx->validate;
-- ctxt->loadsubset = ctx->loadsubset;
-- ctxt->depth = ctx->depth + 1;
-- ctxt->replaceEntities = ctx->replaceEntities;
-- if (ctxt->validate) {
-- ctxt->vctxt.error = ctx->vctxt.error;
-- ctxt->vctxt.warning = ctx->vctxt.warning;
-- /* Allocate the Node stack */
-- ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
-- if (ctxt->vctxt.nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParseCtxtExternalEntity: out of memory\n");
-- ctxt->validate = 0;
-- ctxt->vctxt.error = NULL;
-- ctxt->vctxt.warning = NULL;
-- } else {
-- ctxt->vctxt.nodeNr = 0;
-- ctxt->vctxt.nodeMax = 4;
-- ctxt->vctxt.node = NULL;
-- }
-- } else {
-- ctxt->vctxt.error = NULL;
-- ctxt->vctxt.warning = NULL;
-- }
--
-- xmlParseContent(ctxt);
--
-- if ((RAW == '<') && (NXT(1) == '/')) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if (RAW != 0) {
-- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "extra content at the end of well balanced chunk\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (ctxt->node != newDoc->children) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- if (!ctxt->wellFormed) {
-- if (ctxt->errNo == 0)
-- ret = 1;
-- else
-- ret = ctxt->errNo;
-- } else {
-- if (list != NULL) {
-- xmlNodePtr cur;
--
-- /*
-- * Return the newly created nodeset after unlinking it from
-- * they pseudo parent.
-- */
-- cur = newDoc->children->children;
-- *list = cur;
-- while (cur != NULL) {
-- cur->parent = NULL;
-- cur = cur->next;
-- }
-- newDoc->children->children = NULL;
-- }
-- ret = 0;
-- }
-- ctxt->sax = oldsax;
-- xmlFreeParserCtxt(ctxt);
-- newDoc->intSubset = NULL;
-- newDoc->extSubset = NULL;
-- xmlFreeDoc(newDoc);
--
-- return(ret);
--}
--
--/**
-- * xmlParseExternalEntity:
-- * @doc: the document the chunk pertains to
-- * @sax: the SAX handler bloc (possibly NULL)
-- * @user_data: The user data returned on SAX callbacks (possibly NULL)
-- * @depth: Used for loop detection, use 0
-- * @URL: the URL for the entity to load
-- * @ID: the System ID for the entity to load
-- * @list: the return value for the set of parsed nodes
-- *
-- * Parse an external general entity
-- * An external general parsed entity is well-formed if it matches the
-- * production labeled extParsedEnt.
-- *
-- * [78] extParsedEnt ::= TextDecl? content
-- *
-- * Returns 0 if the entity is well formed, -1 in case of args problem and
-- * the parser error code otherwise
-- */
--
--int
--xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
-- int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *list) {
-- xmlParserCtxtPtr ctxt;
-- xmlDocPtr newDoc;
-- xmlSAXHandlerPtr oldsax = NULL;
-- int ret = 0;
--
-- if (depth > 40) {
-- return(XML_ERR_ENTITY_LOOP);
-- }
--
--
--
-- if (list != NULL)
-- *list = NULL;
-- if ((URL == NULL) && (ID == NULL))
-- return(-1);
-- if (doc == NULL) /* @@ relax but check for dereferences */
-- return(-1);
--
--
-- ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
-- if (ctxt == NULL) return(-1);
-- ctxt->userData = ctxt;
-- if (sax != NULL) {
-- oldsax = ctxt->sax;
-- ctxt->sax = sax;
-- if (user_data != NULL)
-- ctxt->userData = user_data;
-- }
-- newDoc = xmlNewDoc(BAD_CAST "1.0");
-- if (newDoc == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(-1);
-- }
-- if (doc != NULL) {
-- newDoc->intSubset = doc->intSubset;
-- newDoc->extSubset = doc->extSubset;
-- }
-- if (doc->URL != NULL) {
-- newDoc->URL = xmlStrdup(doc->URL);
-- }
-- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-- if (newDoc->children == NULL) {
-- if (sax != NULL)
-- ctxt->sax = oldsax;
-- xmlFreeParserCtxt(ctxt);
-- newDoc->intSubset = NULL;
-- newDoc->extSubset = NULL;
-- xmlFreeDoc(newDoc);
-- return(-1);
-- }
-- nodePush(ctxt, newDoc->children);
-- if (doc == NULL) {
-- ctxt->myDoc = newDoc;
-- } else {
-- ctxt->myDoc = doc;
-- newDoc->children->doc = doc;
-- }
--
-- /*
-- * Parse a possible text declaration first
-- */
-- GROW;
-- if ((RAW == '<') && (NXT(1) == '?') &&
-- (NXT(2) == 'x') && (NXT(3) == 'm') &&
-- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-- xmlParseTextDecl(ctxt);
-- }
--
-- /*
-- * Doing validity checking on chunk doesn't make sense
-- */
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->validate = 0;
-- ctxt->loadsubset = 0;
-- ctxt->depth = depth;
--
-- xmlParseContent(ctxt);
--
-- if ((RAW == '<') && (NXT(1) == '/')) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if (RAW != 0) {
-- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "extra content at the end of well balanced chunk\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (ctxt->node != newDoc->children) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- if (!ctxt->wellFormed) {
-- if (ctxt->errNo == 0)
-- ret = 1;
-- else
-- ret = ctxt->errNo;
-- } else {
-- if (list != NULL) {
-- xmlNodePtr cur;
--
-- /*
-- * Return the newly created nodeset after unlinking it from
-- * they pseudo parent.
-- */
-- cur = newDoc->children->children;
-- *list = cur;
-- while (cur != NULL) {
-- cur->parent = NULL;
-- cur = cur->next;
-- }
-- newDoc->children->children = NULL;
-- }
-- ret = 0;
-- }
-- if (sax != NULL)
-- ctxt->sax = oldsax;
-- xmlFreeParserCtxt(ctxt);
-- newDoc->intSubset = NULL;
-- newDoc->extSubset = NULL;
-- xmlFreeDoc(newDoc);
--
-- return(ret);
--}
--
--/**
-- * xmlParseBalancedChunk:
-- * @doc: the document the chunk pertains to
-- * @sax: the SAX handler bloc (possibly NULL)
-- * @user_data: The user data returned on SAX callbacks (possibly NULL)
-- * @depth: Used for loop detection, use 0
-- * @string: the input string in UTF8 or ISO-Latin (zero terminated)
-- * @list: the return value for the set of parsed nodes
-- *
-- * Parse a well-balanced chunk of an XML document
-- * called by the parser
-- * The allowed sequence for the Well Balanced Chunk is the one defined by
-- * the content production in the XML grammar:
-- *
-- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-- *
-- * Returns 0 if the chunk is well balanced, -1 in case of args problem and
-- * the parser error code otherwise
-- */
--
--int
--xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
-- void *user_data, int depth, const xmlChar *string, xmlNodePtr *list) {
-- xmlParserCtxtPtr ctxt;
-- xmlDocPtr newDoc;
-- xmlSAXHandlerPtr oldsax = NULL;
-- int size;
-- int ret = 0;
--
-- if (depth > 40) {
-- return(XML_ERR_ENTITY_LOOP);
-- }
--
--
-- if (list != NULL)
-- *list = NULL;
-- if (string == NULL)
-- return(-1);
--
-- size = xmlStrlen(string);
--
-- ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
-- if (ctxt == NULL) return(-1);
-- ctxt->userData = ctxt;
-- if (sax != NULL) {
-- oldsax = ctxt->sax;
-- ctxt->sax = sax;
-- if (user_data != NULL)
-- ctxt->userData = user_data;
-- }
-- newDoc = xmlNewDoc(BAD_CAST "1.0");
-- if (newDoc == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(-1);
-- }
-- if (doc != NULL) {
-- newDoc->intSubset = doc->intSubset;
-- newDoc->extSubset = doc->extSubset;
-- }
-- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-- if (newDoc->children == NULL) {
-- if (sax != NULL)
-- ctxt->sax = oldsax;
-- xmlFreeParserCtxt(ctxt);
-- newDoc->intSubset = NULL;
-- newDoc->extSubset = NULL;
-- xmlFreeDoc(newDoc);
-- return(-1);
-- }
-- nodePush(ctxt, newDoc->children);
-- if (doc == NULL) {
-- ctxt->myDoc = newDoc;
-- } else {
-- ctxt->myDoc = doc;
-- newDoc->children->doc = doc;
-- }
-- ctxt->instate = XML_PARSER_CONTENT;
-- ctxt->depth = depth;
--
-- /*
-- * Doing validity checking on chunk doesn't make sense
-- */
-- ctxt->validate = 0;
-- ctxt->loadsubset = 0;
--
-- xmlParseContent(ctxt);
--
-- if ((RAW == '<') && (NXT(1) == '/')) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else if (RAW != 0) {
-- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "extra content at the end of well balanced chunk\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- if (ctxt->node != newDoc->children) {
-- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "chunk is not well balanced\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- if (!ctxt->wellFormed) {
-- if (ctxt->errNo == 0)
-- ret = 1;
-- else
-- ret = ctxt->errNo;
-- } else {
-- if (list != NULL) {
-- xmlNodePtr cur;
--
-- /*
-- * Return the newly created nodeset after unlinking it from
-- * they pseudo parent.
-- */
-- cur = newDoc->children->children;
-- *list = cur;
-- while (cur != NULL) {
-- cur->parent = NULL;
-- cur = cur->next;
-- }
-- newDoc->children->children = NULL;
-- }
-- ret = 0;
-- }
-- if (sax != NULL)
-- ctxt->sax = oldsax;
-- xmlFreeParserCtxt(ctxt);
-- newDoc->intSubset = NULL;
-- newDoc->extSubset = NULL;
-- xmlFreeDoc(newDoc);
--
-- return(ret);
--}
--
--/**
-- * xmlSAXParseEntity:
-- * @sax: the SAX handler block
-- * @filename: the filename
-- *
-- * parse an XML external entity out of context and build a tree.
-- * It use the given SAX function block to handle the parsing callback.
-- * If sax is NULL, fallback to the default DOM tree building routines.
-- *
-- * [78] extParsedEnt ::= TextDecl? content
-- *
-- * This correspond to a "Well Balanced" chunk
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
-- xmlDocPtr ret;
-- xmlParserCtxtPtr ctxt;
-- char *directory = NULL;
--
-- ctxt = xmlCreateFileParserCtxt(filename);
-- if (ctxt == NULL) {
-- return(NULL);
-- }
-- if (sax != NULL) {
-- if (ctxt->sax != NULL)
-- xmlFree(ctxt->sax);
-- ctxt->sax = sax;
-- ctxt->userData = NULL;
-- }
--
-- if ((ctxt->directory == NULL) && (directory == NULL))
-- directory = xmlParserGetDirectory(filename);
--
-- xmlParseExtParsedEnt(ctxt);
--
-- if (ctxt->wellFormed)
-- ret = ctxt->myDoc;
-- else {
-- ret = NULL;
-- xmlFreeDoc(ctxt->myDoc);
-- ctxt->myDoc = NULL;
-- }
-- if (sax != NULL)
-- ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * xmlParseEntity:
-- * @filename: the filename
-- *
-- * parse an XML external entity out of context and build a tree.
-- *
-- * [78] extParsedEnt ::= TextDecl? content
-- *
-- * This correspond to a "Well Balanced" chunk
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlParseEntity(const char *filename) {
-- return(xmlSAXParseEntity(NULL, filename));
--}
--
--/**
-- * xmlCreateEntityParserCtxt:
-- * @URL: the entity URL
-- * @ID: the entity PUBLIC ID
-- * @base: a posible base for the target URI
-- *
-- * Create a parser context for an external entity
-- * Automatic support for ZLIB/Compress compressed document is provided
-- * by default if found at compile-time.
-- *
-- * Returns the new parser context or NULL
-- */
--xmlParserCtxtPtr
--xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
-- const xmlChar *base) {
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr inputStream;
-- char *directory = NULL;
-- xmlChar *uri;
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL) {
-- return(NULL);
-- }
--
-- uri = xmlBuildURI(URL, base);
--
-- if (uri == NULL) {
-- inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
-- if (inputStream == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- inputPush(ctxt, inputStream);
--
-- if ((ctxt->directory == NULL) && (directory == NULL))
-- directory = xmlParserGetDirectory((char *)URL);
-- if ((ctxt->directory == NULL) && (directory != NULL))
-- ctxt->directory = directory;
-- } else {
-- inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
-- if (inputStream == NULL) {
-- xmlFree(uri);
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- inputPush(ctxt, inputStream);
--
-- if ((ctxt->directory == NULL) && (directory == NULL))
-- directory = xmlParserGetDirectory((char *)uri);
-- if ((ctxt->directory == NULL) && (directory != NULL))
-- ctxt->directory = directory;
-- xmlFree(uri);
-- }
--
-- return(ctxt);
--}
--
--/************************************************************************
-- * *
-- * Front ends when parsing from a file *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlCreateFileParserCtxt:
-- * @filename: the filename
-- *
-- * Create a parser context for a file content.
-- * Automatic support for ZLIB/Compress compressed document is provided
-- * by default if found at compile-time.
-- *
-- * Returns the new parser context or NULL
-- */
--xmlParserCtxtPtr
--xmlCreateFileParserCtxt(const char *filename)
--{
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr inputStream;
-- xmlParserInputBufferPtr buf;
-- char *directory = NULL;
--
-- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-- if (buf == NULL) {
-- return(NULL);
-- }
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL) {
-- if (xmlDefaultSAXHandler.error != NULL) {
-- xmlDefaultSAXHandler.error(NULL, "out of memory\n");
-- }
-- return(NULL);
-- }
--
-- inputStream = xmlNewInputStream(ctxt);
-- if (inputStream == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- inputStream->filename = xmlMemStrdup(filename);
-- inputStream->buf = buf;
-- inputStream->base = inputStream->buf->buffer->content;
-- inputStream->cur = inputStream->buf->buffer->content;
--
-- inputPush(ctxt, inputStream);
-- if ((ctxt->directory == NULL) && (directory == NULL))
-- directory = xmlParserGetDirectory(filename);
-- if ((ctxt->directory == NULL) && (directory != NULL))
-- ctxt->directory = directory;
--
-- return(ctxt);
--}
--
--/**
-- * xmlSAXParseFile:
-- * @sax: the SAX handler block
-- * @filename: the filename
-- * @recovery: work in recovery mode, i.e. tries to read no Well Formed
-- * documents
-- *
-- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
-- * compressed document is provided by default if found at compile-time.
-- * It use the given SAX function block to handle the parsing callback.
-- * If sax is NULL, fallback to the default DOM tree building routines.
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
-- int recovery) {
-- xmlDocPtr ret;
-- xmlParserCtxtPtr ctxt;
-- char *directory = NULL;
--
-- ctxt = xmlCreateFileParserCtxt(filename);
-- if (ctxt == NULL) {
-- return(NULL);
-- }
-- if (sax != NULL) {
-- if (ctxt->sax != NULL)
-- xmlFree(ctxt->sax);
-- ctxt->sax = sax;
-- ctxt->userData = NULL;
-- }
--
-- if ((ctxt->directory == NULL) && (directory == NULL))
-- directory = xmlParserGetDirectory(filename);
-- if ((ctxt->directory == NULL) && (directory != NULL))
-- ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
--
-- xmlParseDocument(ctxt);
--
-- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
-- else {
-- ret = NULL;
-- xmlFreeDoc(ctxt->myDoc);
-- ctxt->myDoc = NULL;
-- }
-- if (sax != NULL)
-- ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * xmlRecoverDoc:
-- * @cur: a pointer to an array of xmlChar
-- *
-- * parse an XML in-memory document and build a tree.
-- * In the case the document is not Well Formed, a tree is built anyway
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlRecoverDoc(xmlChar *cur) {
-- return(xmlSAXParseDoc(NULL, cur, 1));
--}
--
--/**
-- * xmlParseFile:
-- * @filename: the filename
-- *
-- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
-- * compressed document is provided by default if found at compile-time.
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlParseFile(const char *filename) {
-- return(xmlSAXParseFile(NULL, filename, 0));
--}
--
--/**
-- * xmlRecoverFile:
-- * @filename: the filename
-- *
-- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
-- * compressed document is provided by default if found at compile-time.
-- * In the case the document is not Well Formed, a tree is built anyway
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlRecoverFile(const char *filename) {
-- return(xmlSAXParseFile(NULL, filename, 1));
--}
--
--
--/**
-- * xmlSetupParserForBuffer:
-- * @ctxt: an XML parser context
-- * @buffer: a xmlChar * buffer
-- * @filename: a file name
-- *
-- * Setup the parser context to parse a new buffer; Clears any prior
-- * contents from the parser context. The buffer parameter must not be
-- * NULL, but the filename parameter can be
-- */
--void
--xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
-- const char* filename)
--{
-- xmlParserInputPtr input;
--
-- input = xmlNewInputStream(ctxt);
-- if (input == NULL) {
-- perror("malloc");
-- xmlFree(ctxt);
-- return;
-- }
--
-- xmlClearParserCtxt(ctxt);
-- if (filename != NULL)
-- input->filename = xmlMemStrdup(filename);
-- input->base = buffer;
-- input->cur = buffer;
-- inputPush(ctxt, input);
--}
--
--/**
-- * xmlSAXUserParseFile:
-- * @sax: a SAX handler
-- * @user_data: The user data returned on SAX callbacks
-- * @filename: a file name
-- *
-- * parse an XML file and call the given SAX handler routines.
-- * Automatic support for ZLIB/Compress compressed document is provided
-- *
-- * Returns 0 in case of success or a error number otherwise
-- */
--int
--xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
-- const char *filename) {
-- int ret = 0;
-- xmlParserCtxtPtr ctxt;
--
-- ctxt = xmlCreateFileParserCtxt(filename);
-- if (ctxt == NULL) return -1;
-- if (ctxt->sax != &xmlDefaultSAXHandler)
-- xmlFree(ctxt->sax);
-- ctxt->sax = sax;
-- if (user_data != NULL)
-- ctxt->userData = user_data;
--
-- xmlParseDocument(ctxt);
--
-- if (ctxt->wellFormed)
-- ret = 0;
-- else {
-- if (ctxt->errNo != 0)
-- ret = ctxt->errNo;
-- else
-- ret = -1;
-- }
-- if (sax != NULL)
-- ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return ret;
--}
--
--/************************************************************************
-- * *
-- * Front ends when parsing from memory *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlCreateMemoryParserCtxt:
-- * @buffer: a pointer to a char array
-- * @size: the size of the array
-- *
-- * Create a parser context for an XML in-memory document.
-- *
-- * Returns the new parser context or NULL
-- */
--xmlParserCtxtPtr
--xmlCreateMemoryParserCtxt(char *buffer, int size) {
-- xmlParserCtxtPtr ctxt;
-- xmlParserInputPtr input;
-- xmlParserInputBufferPtr buf;
--
-- if (buffer == NULL)
-- return(NULL);
-- if (size <= 0)
-- return(NULL);
--
-- ctxt = xmlNewParserCtxt();
-- if (ctxt == NULL)
-- return(NULL);
--
-- buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
-- if (buf == NULL) return(NULL);
--
-- input = xmlNewInputStream(ctxt);
-- if (input == NULL) {
-- xmlFreeParserCtxt(ctxt);
-- return(NULL);
-- }
--
-- input->filename = NULL;
-- input->buf = buf;
-- input->base = input->buf->buffer->content;
-- input->cur = input->buf->buffer->content;
--
-- inputPush(ctxt, input);
-- return(ctxt);
--}
--
--/**
-- * xmlSAXParseMemory:
-- * @sax: the SAX handler block
-- * @buffer: an pointer to a char array
-- * @size: the size of the array
-- * @recovery: work in recovery mode, i.e. tries to read not Well Formed
-- * documents
-- *
-- * parse an XML in-memory block and use the given SAX function block
-- * to handle the parsing callback. If sax is NULL, fallback to the default
-- * DOM tree building routines.
-- *
-- * Returns the resulting document tree
-- */
--xmlDocPtr
--xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer, int size, int recovery) {
-- xmlDocPtr ret;
-- xmlParserCtxtPtr ctxt;
--
-- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
-- if (ctxt == NULL) return(NULL);
-- if (sax != NULL) {
-- ctxt->sax = sax;
-- ctxt->userData = NULL;
-- }
--
-- xmlParseDocument(ctxt);
--
-- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
-- else {
-- ret = NULL;
-- xmlFreeDoc(ctxt->myDoc);
-- ctxt->myDoc = NULL;
-- }
-- if (sax != NULL)
-- ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * xmlParseMemory:
-- * @buffer: an pointer to a char array
-- * @size: the size of the array
-- *
-- * parse an XML in-memory block and build a tree.
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr xmlParseMemory(char *buffer, int size) {
-- return(xmlSAXParseMemory(NULL, buffer, size, 0));
--}
--
--/**
-- * xmlRecoverMemory:
-- * @buffer: an pointer to a char array
-- * @size: the size of the array
-- *
-- * parse an XML in-memory block and build a tree.
-- * In the case the document is not Well Formed, a tree is built anyway
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr xmlRecoverMemory(char *buffer, int size) {
-- return(xmlSAXParseMemory(NULL, buffer, size, 1));
--}
--
--/**
-- * xmlSAXUserParseMemory:
-- * @sax: a SAX handler
-- * @user_data: The user data returned on SAX callbacks
-- * @buffer: an in-memory XML document input
-- * @size: the length of the XML document in bytes
-- *
-- * A better SAX parsing routine.
-- * parse an XML in-memory buffer and call the given SAX handler routines.
-- *
-- * Returns 0 in case of success or a error number otherwise
-- */
--int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
-- char *buffer, int size) {
-- int ret = 0;
-- xmlParserCtxtPtr ctxt;
-- xmlSAXHandlerPtr oldsax = NULL;
--
-- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
-- if (ctxt == NULL) return -1;
-- if (sax != NULL) {
-- oldsax = ctxt->sax;
-- ctxt->sax = sax;
-- }
-- ctxt->userData = user_data;
--
-- xmlParseDocument(ctxt);
--
-- if (ctxt->wellFormed)
-- ret = 0;
-- else {
-- if (ctxt->errNo != 0)
-- ret = ctxt->errNo;
-- else
-- ret = -1;
-- }
-- if (sax != NULL) {
-- ctxt->sax = oldsax;
-- }
-- xmlFreeParserCtxt(ctxt);
--
-- return ret;
--}
--
--/**
-- * xmlCreateDocParserCtxt:
-- * @cur: a pointer to an array of xmlChar
-- *
-- * Creates a parser context for an XML in-memory document.
-- *
-- * Returns the new parser context or NULL
-- */
--xmlParserCtxtPtr
--xmlCreateDocParserCtxt(xmlChar *cur) {
-- int len;
--
-- if (cur == NULL)
-- return(NULL);
-- len = xmlStrlen(cur);
-- return(xmlCreateMemoryParserCtxt((char *)cur, len));
--}
--
--/**
-- * xmlSAXParseDoc:
-- * @sax: the SAX handler block
-- * @cur: a pointer to an array of xmlChar
-- * @recovery: work in recovery mode, i.e. tries to read no Well Formed
-- * documents
-- *
-- * parse an XML in-memory document and build a tree.
-- * It use the given SAX function block to handle the parsing callback.
-- * If sax is NULL, fallback to the default DOM tree building routines.
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
-- xmlDocPtr ret;
-- xmlParserCtxtPtr ctxt;
--
-- if (cur == NULL) return(NULL);
--
--
-- ctxt = xmlCreateDocParserCtxt(cur);
-- if (ctxt == NULL) return(NULL);
-- if (sax != NULL) {
-- ctxt->sax = sax;
-- ctxt->userData = NULL;
-- }
--
-- xmlParseDocument(ctxt);
-- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
-- else {
-- ret = NULL;
-- xmlFreeDoc(ctxt->myDoc);
-- ctxt->myDoc = NULL;
-- }
-- if (sax != NULL)
-- ctxt->sax = NULL;
-- xmlFreeParserCtxt(ctxt);
--
-- return(ret);
--}
--
--/**
-- * xmlParseDoc:
-- * @cur: a pointer to an array of xmlChar
-- *
-- * parse an XML in-memory document and build a tree.
-- *
-- * Returns the resulting document tree
-- */
--
--xmlDocPtr
--xmlParseDoc(xmlChar *cur) {
-- return(xmlSAXParseDoc(NULL, cur, 0));
--}
--
--
--/************************************************************************
-- * *
-- * Miscellaneous *
-- * *
-- ************************************************************************/
--
--#ifdef LIBXML_XPATH_ENABLED
--#include <libxml/xpath.h>
--#endif
--
--static int xmlParserInitialized = 0;
--
--/**
-- * xmlInitParser:
-- *
-- * Initialization function for the XML parser.
-- * This is not reentrant. Call once before processing in case of
-- * use in multithreaded programs.
-- */
--
--void
--xmlInitParser(void) {
-- if (xmlParserInitialized) return;
--
-- xmlInitCharEncodingHandlers();
-- xmlInitializePredefinedEntities();
-- xmlDefaultSAXHandlerInit();
-- xmlRegisterDefaultInputCallbacks();
-- xmlRegisterDefaultOutputCallbacks();
--#ifdef LIBXML_HTML_ENABLED
-- htmlInitAutoClose();
-- htmlDefaultSAXHandlerInit();
--#endif
--#ifdef LIBXML_XPATH_ENABLED
-- xmlXPathInit();
--#endif
-- xmlParserInitialized = 1;
--}
--
--/**
-- * xmlCleanupParser:
-- *
-- * Cleanup function for the XML parser. It tries to reclaim all
-- * parsing related global memory allocated for the parser processing.
-- * It doesn't deallocate any document related memory. Calling this
-- * function should not prevent reusing the parser.
-- */
--
--void
--xmlCleanupParser(void) {
-- xmlParserInitialized = 0;
-- xmlCleanupCharEncodingHandlers();
-- xmlCleanupPredefinedEntities();
--}
--
--/**
-- * xmlPedanticParserDefault:
-- * @val: int 0 or 1
-- *
-- * Set and return the previous value for enabling pedantic warnings.
-- *
-- * Returns the last value for 0 for no substitution, 1 for substitution.
-- */
--
--int
--xmlPedanticParserDefault(int val) {
-- int old = xmlPedanticParserDefaultValue;
--
-- xmlPedanticParserDefaultValue = val;
-- return(old);
--}
--
--/**
-- * xmlSubstituteEntitiesDefault:
-- * @val: int 0 or 1
-- *
-- * Set and return the previous value for default entity support.
-- * Initially the parser always keep entity references instead of substituting
-- * entity values in the output. This function has to be used to change the
-- * default parser behaviour
-- * SAX::subtituteEntities() has to be used for changing that on a file by
-- * file basis.
-- *
-- * Returns the last value for 0 for no substitution, 1 for substitution.
-- */
--
--int
--xmlSubstituteEntitiesDefault(int val) {
-- int old = xmlSubstituteEntitiesDefaultValue;
--
-- xmlSubstituteEntitiesDefaultValue = val;
-- return(old);
--}
--
--/**
-- * xmlKeepBlanksDefault:
-- * @val: int 0 or 1
-- *
-- * Set and return the previous value for default blanks text nodes support.
-- * The 1.x version of the parser used an heuristic to try to detect
-- * ignorable white spaces. As a result the SAX callback was generating
-- * ignorableWhitespace() callbacks instead of characters() one, and when
-- * using the DOM output text nodes containing those blanks were not generated.
-- * The 2.x and later version will switch to the XML standard way and
-- * ignorableWhitespace() are only generated when running the parser in
-- * validating mode and when the current element doesn't allow CDATA or
-- * mixed content.
-- * This function is provided as a way to force the standard behaviour
-- * on 1.X libs and to switch back to the old mode for compatibility when
-- * running 1.X client code on 2.X . Upgrade of 1.X code should be done
-- * by using xmlIsBlankNode() commodity function to detect the "empty"
-- * nodes generated.
-- * This value also affect autogeneration of indentation when saving code
-- * if blanks sections are kept, indentation is not generated.
-- *
-- * Returns the last value for 0 for no substitution, 1 for substitution.
-- */
--
--int
--xmlKeepBlanksDefault(int val) {
-- int old = xmlKeepBlanksDefaultValue;
--
-- xmlKeepBlanksDefaultValue = val;
-- xmlIndentTreeOutput = !val;
-- return(old);
--}
--
-diff -Nru libxml2-2.3.0/parserInternals.c libxml2-2.3.0.new/parserInternals.c
---- libxml2-2.3.0/parserInternals.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/parserInternals.c Thu Jan 1 01:00:00 1970
-@@ -1,3533 +0,0 @@
--/*
-- * parser.c : Internal routines (and obsolete ones) needed for the
-- * XML and HTML parsers.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#define XML_DIR_SEP '\\'
--#else
--#include "config.h"
--#define XML_DIR_SEP '/'
--#endif
--
--#include <stdio.h>
--#include <string.h>
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_SYS_STAT_H
--#include <sys/stat.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_ZLIB_H
--#include <zlib.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/parserInternals.h>
--#include <libxml/valid.h>
--#include <libxml/entities.h>
--#include <libxml/xmlerror.h>
--#include <libxml/encoding.h>
--#include <libxml/valid.h>
--#include <libxml/xmlIO.h>
--#include <libxml/uri.h>
--
--
--/************************************************************************
-- * *
-- * Version and Features handling *
-- * *
-- ************************************************************************/
--const char *xmlParserVersion = LIBXML_VERSION_STRING;
--
--/*
-- * xmlCheckVersion:
-- * @version: the include version number
-- *
-- * check the compiled lib version against the include one.
-- * This can warn or immediately kill the application
-- */
--void
--xmlCheckVersion(int version) {
-- int myversion = (int) LIBXML_VERSION;
--
-- if ((myversion / 10000) != (version / 10000)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Fatal: program compiled against libxml %d using libxml %d\n",
-- (version / 10000), (myversion / 10000));
-- exit(1);
-- }
-- if ((myversion / 100) < (version / 100)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Warning: program compiled against libxml %d using older %d\n",
-- (version / 100), (myversion / 100));
-- }
--}
--
--
--const char *xmlFeaturesList[] = {
-- "validate",
-- "load subset",
-- "keep blanks",
-- "disable SAX",
-- "fetch external entities",
-- "substitute entities",
-- "gather line info",
-- "user data",
-- "is html",
-- "is standalone",
-- "stop parser",
-- "document",
-- "is well formed",
-- "is valid",
-- "SAX block",
-- "SAX function internalSubset",
-- "SAX function isStandalone",
-- "SAX function hasInternalSubset",
-- "SAX function hasExternalSubset",
-- "SAX function resolveEntity",
-- "SAX function getEntity",
-- "SAX function entityDecl",
-- "SAX function notationDecl",
-- "SAX function attributeDecl",
-- "SAX function elementDecl",
-- "SAX function unparsedEntityDecl",
-- "SAX function setDocumentLocator",
-- "SAX function startDocument",
-- "SAX function endDocument",
-- "SAX function startElement",
-- "SAX function endElement",
-- "SAX function reference",
-- "SAX function characters",
-- "SAX function ignorableWhitespace",
-- "SAX function processingInstruction",
-- "SAX function comment",
-- "SAX function warning",
-- "SAX function error",
-- "SAX function fatalError",
-- "SAX function getParameterEntity",
-- "SAX function cdataBlock",
-- "SAX function externalSubset",
--};
--
--/*
-- * xmlGetFeaturesList:
-- * @len: the length of the features name array (input/output)
-- * @result: an array of string to be filled with the features name.
-- *
-- * Copy at most *@len feature names into the @result array
-- *
-- * Returns -1 in case or error, or the total number of features,
-- * len is updated with the number of strings copied,
-- * strings must not be deallocated
-- */
--int
--xmlGetFeaturesList(int *len, const char **result) {
-- int ret, i;
--
-- ret = sizeof(xmlFeaturesList)/sizeof(xmlFeaturesList[0]);
-- if ((len == NULL) || (result == NULL))
-- return(ret);
-- if ((*len < 0) || (*len >= 1000))
-- return(-1);
-- if (*len > ret)
-- *len = ret;
-- for (i = 0;i < *len;i++)
-- result[i] = xmlFeaturesList[i];
-- return(ret);
--}
--
--/*
-- * xmlGetFeature:
-- * @ctxt: an XML/HTML parser context
-- * @name: the feature name
-- * @result: location to store the result
-- *
-- * Read the current value of one feature of this parser instance
-- *
-- * Returns -1 in case or error, 0 otherwise
-- */
--int
--xmlGetFeature(xmlParserCtxtPtr ctxt, const char *name, void *result) {
-- if ((ctxt == NULL) || (name == NULL) || (result == NULL))
-- return(-1);
--
-- if (!strcmp(name, "validate")) {
-- *((int *) result) = ctxt->validate;
-- } else if (!strcmp(name, "keep blanks")) {
-- *((int *) result) = ctxt->keepBlanks;
-- } else if (!strcmp(name, "disable SAX")) {
-- *((int *) result) = ctxt->disableSAX;
-- } else if (!strcmp(name, "fetch external entities")) {
-- *((int *) result) = ctxt->loadsubset;
-- } else if (!strcmp(name, "substitute entities")) {
-- *((int *) result) = ctxt->replaceEntities;
-- } else if (!strcmp(name, "gather line info")) {
-- *((int *) result) = ctxt->record_info;
-- } else if (!strcmp(name, "user data")) {
-- *((void **)result) = ctxt->userData;
-- } else if (!strcmp(name, "is html")) {
-- *((int *) result) = ctxt->html;
-- } else if (!strcmp(name, "is standalone")) {
-- *((int *) result) = ctxt->standalone;
-- } else if (!strcmp(name, "document")) {
-- *((xmlDocPtr *) result) = ctxt->myDoc;
-- } else if (!strcmp(name, "is well formed")) {
-- *((int *) result) = ctxt->wellFormed;
-- } else if (!strcmp(name, "is valid")) {
-- *((int *) result) = ctxt->valid;
-- } else if (!strcmp(name, "SAX block")) {
-- *((xmlSAXHandlerPtr *) result) = ctxt->sax;
-- } else if (!strcmp(name, "SAX function internalSubset")) {
-- *((internalSubsetSAXFunc *) result) = ctxt->sax->internalSubset;
-- } else if (!strcmp(name, "SAX function isStandalone")) {
-- *((isStandaloneSAXFunc *) result) = ctxt->sax->isStandalone;
-- } else if (!strcmp(name, "SAX function hasInternalSubset")) {
-- *((hasInternalSubsetSAXFunc *) result) = ctxt->sax->hasInternalSubset;
-- } else if (!strcmp(name, "SAX function hasExternalSubset")) {
-- *((hasExternalSubsetSAXFunc *) result) = ctxt->sax->hasExternalSubset;
-- } else if (!strcmp(name, "SAX function resolveEntity")) {
-- *((resolveEntitySAXFunc *) result) = ctxt->sax->resolveEntity;
-- } else if (!strcmp(name, "SAX function getEntity")) {
-- *((getEntitySAXFunc *) result) = ctxt->sax->getEntity;
-- } else if (!strcmp(name, "SAX function entityDecl")) {
-- *((entityDeclSAXFunc *) result) = ctxt->sax->entityDecl;
-- } else if (!strcmp(name, "SAX function notationDecl")) {
-- *((notationDeclSAXFunc *) result) = ctxt->sax->notationDecl;
-- } else if (!strcmp(name, "SAX function attributeDecl")) {
-- *((attributeDeclSAXFunc *) result) = ctxt->sax->attributeDecl;
-- } else if (!strcmp(name, "SAX function elementDecl")) {
-- *((elementDeclSAXFunc *) result) = ctxt->sax->elementDecl;
-- } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
-- *((unparsedEntityDeclSAXFunc *) result) = ctxt->sax->unparsedEntityDecl;
-- } else if (!strcmp(name, "SAX function setDocumentLocator")) {
-- *((setDocumentLocatorSAXFunc *) result) = ctxt->sax->setDocumentLocator;
-- } else if (!strcmp(name, "SAX function startDocument")) {
-- *((startDocumentSAXFunc *) result) = ctxt->sax->startDocument;
-- } else if (!strcmp(name, "SAX function endDocument")) {
-- *((endDocumentSAXFunc *) result) = ctxt->sax->endDocument;
-- } else if (!strcmp(name, "SAX function startElement")) {
-- *((startElementSAXFunc *) result) = ctxt->sax->startElement;
-- } else if (!strcmp(name, "SAX function endElement")) {
-- *((endElementSAXFunc *) result) = ctxt->sax->endElement;
-- } else if (!strcmp(name, "SAX function reference")) {
-- *((referenceSAXFunc *) result) = ctxt->sax->reference;
-- } else if (!strcmp(name, "SAX function characters")) {
-- *((charactersSAXFunc *) result) = ctxt->sax->characters;
-- } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
-- *((ignorableWhitespaceSAXFunc *) result) = ctxt->sax->ignorableWhitespace;
-- } else if (!strcmp(name, "SAX function processingInstruction")) {
-- *((processingInstructionSAXFunc *) result) = ctxt->sax->processingInstruction;
-- } else if (!strcmp(name, "SAX function comment")) {
-- *((commentSAXFunc *) result) = ctxt->sax->comment;
-- } else if (!strcmp(name, "SAX function warning")) {
-- *((warningSAXFunc *) result) = ctxt->sax->warning;
-- } else if (!strcmp(name, "SAX function error")) {
-- *((errorSAXFunc *) result) = ctxt->sax->error;
-- } else if (!strcmp(name, "SAX function fatalError")) {
-- *((fatalErrorSAXFunc *) result) = ctxt->sax->fatalError;
-- } else if (!strcmp(name, "SAX function getParameterEntity")) {
-- *((getParameterEntitySAXFunc *) result) = ctxt->sax->getParameterEntity;
-- } else if (!strcmp(name, "SAX function cdataBlock")) {
-- *((cdataBlockSAXFunc *) result) = ctxt->sax->cdataBlock;
-- } else if (!strcmp(name, "SAX function externalSubset")) {
-- *((externalSubsetSAXFunc *) result) = ctxt->sax->externalSubset;
-- } else {
-- return(-1);
-- }
-- return(0);
--}
--
--/*
-- * xmlSetFeature:
-- * @ctxt: an XML/HTML parser context
-- * @name: the feature name
-- * @value: pointer to the location of the new value
-- *
-- * Change the current value of one feature of this parser instance
-- *
-- * Returns -1 in case or error, 0 otherwise
-- */
--int
--xmlSetFeature(xmlParserCtxtPtr ctxt, const char *name, void *value) {
-- if ((ctxt == NULL) || (name == NULL) || (value == NULL))
-- return(-1);
--
-- if (!strcmp(name, "validate")) {
-- int newvalidate = *((int *) value);
-- if ((!ctxt->validate) && (newvalidate != 0)) {
-- if (ctxt->vctxt.warning == NULL)
-- ctxt->vctxt.warning = xmlParserValidityWarning;
-- if (ctxt->vctxt.error == NULL)
-- ctxt->vctxt.error = xmlParserValidityError;
-- /* Allocate the Node stack */
-- ctxt->vctxt.nodeTab = (xmlNodePtr *)
-- xmlMalloc(4 * sizeof(xmlNodePtr));
-- if (ctxt->vctxt.nodeTab == NULL) {
-- ctxt->vctxt.nodeMax = 0;
-- ctxt->validate = 0;
-- return(-1);
-- }
-- ctxt->vctxt.nodeNr = 0;
-- ctxt->vctxt.nodeMax = 4;
-- ctxt->vctxt.node = NULL;
-- }
-- ctxt->validate = newvalidate;
-- } else if (!strcmp(name, "keep blanks")) {
-- ctxt->keepBlanks = *((int *) value);
-- } else if (!strcmp(name, "disable SAX")) {
-- ctxt->disableSAX = *((int *) value);
-- } else if (!strcmp(name, "fetch external entities")) {
-- ctxt->loadsubset = *((int *) value);
-- } else if (!strcmp(name, "substitute entities")) {
-- ctxt->replaceEntities = *((int *) value);
-- } else if (!strcmp(name, "gather line info")) {
-- ctxt->record_info = *((int *) value);
-- } else if (!strcmp(name, "user data")) {
-- ctxt->userData = *((void **)value);
-- } else if (!strcmp(name, "is html")) {
-- ctxt->html = *((int *) value);
-- } else if (!strcmp(name, "is standalone")) {
-- ctxt->standalone = *((int *) value);
-- } else if (!strcmp(name, "document")) {
-- ctxt->myDoc = *((xmlDocPtr *) value);
-- } else if (!strcmp(name, "is well formed")) {
-- ctxt->wellFormed = *((int *) value);
-- } else if (!strcmp(name, "is valid")) {
-- ctxt->valid = *((int *) value);
-- } else if (!strcmp(name, "SAX block")) {
-- ctxt->sax = *((xmlSAXHandlerPtr *) value);
-- } else if (!strcmp(name, "SAX function internalSubset")) {
-- ctxt->sax->internalSubset = *((internalSubsetSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function isStandalone")) {
-- ctxt->sax->isStandalone = *((isStandaloneSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function hasInternalSubset")) {
-- ctxt->sax->hasInternalSubset = *((hasInternalSubsetSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function hasExternalSubset")) {
-- ctxt->sax->hasExternalSubset = *((hasExternalSubsetSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function resolveEntity")) {
-- ctxt->sax->resolveEntity = *((resolveEntitySAXFunc *) value);
-- } else if (!strcmp(name, "SAX function getEntity")) {
-- ctxt->sax->getEntity = *((getEntitySAXFunc *) value);
-- } else if (!strcmp(name, "SAX function entityDecl")) {
-- ctxt->sax->entityDecl = *((entityDeclSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function notationDecl")) {
-- ctxt->sax->notationDecl = *((notationDeclSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function attributeDecl")) {
-- ctxt->sax->attributeDecl = *((attributeDeclSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function elementDecl")) {
-- ctxt->sax->elementDecl = *((elementDeclSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
-- ctxt->sax->unparsedEntityDecl = *((unparsedEntityDeclSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function setDocumentLocator")) {
-- ctxt->sax->setDocumentLocator = *((setDocumentLocatorSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function startDocument")) {
-- ctxt->sax->startDocument = *((startDocumentSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function endDocument")) {
-- ctxt->sax->endDocument = *((endDocumentSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function startElement")) {
-- ctxt->sax->startElement = *((startElementSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function endElement")) {
-- ctxt->sax->endElement = *((endElementSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function reference")) {
-- ctxt->sax->reference = *((referenceSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function characters")) {
-- ctxt->sax->characters = *((charactersSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
-- ctxt->sax->ignorableWhitespace = *((ignorableWhitespaceSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function processingInstruction")) {
-- ctxt->sax->processingInstruction = *((processingInstructionSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function comment")) {
-- ctxt->sax->comment = *((commentSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function warning")) {
-- ctxt->sax->warning = *((warningSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function error")) {
-- ctxt->sax->error = *((errorSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function fatalError")) {
-- ctxt->sax->fatalError = *((fatalErrorSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function getParameterEntity")) {
-- ctxt->sax->getParameterEntity = *((getParameterEntitySAXFunc *) value);
-- } else if (!strcmp(name, "SAX function cdataBlock")) {
-- ctxt->sax->cdataBlock = *((cdataBlockSAXFunc *) value);
-- } else if (!strcmp(name, "SAX function externalSubset")) {
-- ctxt->sax->externalSubset = *((externalSubsetSAXFunc *) value);
-- } else {
-- return(-1);
-- }
-- return(0);
--}
--
--/************************************************************************
-- * *
-- * Some functions to avoid too large macros *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlIsChar:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-- * | [#x10000-#x10FFFF]
-- * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
-- * Also available as a macro IS_CHAR()
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsChar(int c) {
-- return(
-- ((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) ||
-- (((c) >= 0x20) && ((c) <= 0xD7FF)) ||
-- (((c) >= 0xE000) && ((c) <= 0xFFFD)) ||
-- (((c) >= 0x10000) && ((c) <= 0x10FFFF)));
--}
--
--/**
-- * xmlIsBlank:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [3] S ::= (#x20 | #x9 | #xD | #xA)+
-- * Also available as a macro IS_BLANK()
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsBlank(int c) {
-- return(((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || ((c) == 0x0D));
--}
--
--/**
-- * xmlIsBaseChar:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [85] BaseChar ::= ... long list see REC ...
-- *
-- * VI is your friend !
-- * :1,$ s/\[#x\([0-9A-Z]*\)-#x\([0-9A-Z]*\)\]/ (((c) >= 0x\1) \&\& ((c) <= 0x\2)) ||/
-- * and
-- * :1,$ s/#x\([0-9A-Z]*\)/ ((c) == 0x\1) ||/
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--static int xmlBaseArray[] = {
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0000 - 0x000F */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0010 - 0x001F */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0020 - 0x002F */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0030 - 0x003F */
-- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0040 - 0x004F */
-- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x0050 - 0x005F */
-- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0060 - 0x006F */
-- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x0070 - 0x007F */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0080 - 0x008F */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0090 - 0x009F */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00A0 - 0x00AF */
-- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00B0 - 0x00BF */
-- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00C0 - 0x00CF */
-- 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00D0 - 0x00DF */
-- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00E0 - 0x00EF */
-- 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00F0 - 0x00FF */
--};
--
--int
--xmlIsBaseChar(int c) {
-- return(
-- (((c) < 0x0100) ? xmlBaseArray[c] :
-- ( /* accelerator */
-- (((c) >= 0x0100) && ((c) <= 0x0131)) ||
-- (((c) >= 0x0134) && ((c) <= 0x013E)) ||
-- (((c) >= 0x0141) && ((c) <= 0x0148)) ||
-- (((c) >= 0x014A) && ((c) <= 0x017E)) ||
-- (((c) >= 0x0180) && ((c) <= 0x01C3)) ||
-- (((c) >= 0x01CD) && ((c) <= 0x01F0)) ||
-- (((c) >= 0x01F4) && ((c) <= 0x01F5)) ||
-- (((c) >= 0x01FA) && ((c) <= 0x0217)) ||
-- (((c) >= 0x0250) && ((c) <= 0x02A8)) ||
-- (((c) >= 0x02BB) && ((c) <= 0x02C1)) ||
-- ((c) == 0x0386) ||
-- (((c) >= 0x0388) && ((c) <= 0x038A)) ||
-- ((c) == 0x038C) ||
-- (((c) >= 0x038E) && ((c) <= 0x03A1)) ||
-- (((c) >= 0x03A3) && ((c) <= 0x03CE)) ||
-- (((c) >= 0x03D0) && ((c) <= 0x03D6)) ||
-- ((c) == 0x03DA) ||
-- ((c) == 0x03DC) ||
-- ((c) == 0x03DE) ||
-- ((c) == 0x03E0) ||
-- (((c) >= 0x03E2) && ((c) <= 0x03F3)) ||
-- (((c) >= 0x0401) && ((c) <= 0x040C)) ||
-- (((c) >= 0x040E) && ((c) <= 0x044F)) ||
-- (((c) >= 0x0451) && ((c) <= 0x045C)) ||
-- (((c) >= 0x045E) && ((c) <= 0x0481)) ||
-- (((c) >= 0x0490) && ((c) <= 0x04C4)) ||
-- (((c) >= 0x04C7) && ((c) <= 0x04C8)) ||
-- (((c) >= 0x04CB) && ((c) <= 0x04CC)) ||
-- (((c) >= 0x04D0) && ((c) <= 0x04EB)) ||
-- (((c) >= 0x04EE) && ((c) <= 0x04F5)) ||
-- (((c) >= 0x04F8) && ((c) <= 0x04F9)) ||
-- (((c) >= 0x0531) && ((c) <= 0x0556)) ||
-- ((c) == 0x0559) ||
-- (((c) >= 0x0561) && ((c) <= 0x0586)) ||
-- (((c) >= 0x05D0) && ((c) <= 0x05EA)) ||
-- (((c) >= 0x05F0) && ((c) <= 0x05F2)) ||
-- (((c) >= 0x0621) && ((c) <= 0x063A)) ||
-- (((c) >= 0x0641) && ((c) <= 0x064A)) ||
-- (((c) >= 0x0671) && ((c) <= 0x06B7)) ||
-- (((c) >= 0x06BA) && ((c) <= 0x06BE)) ||
-- (((c) >= 0x06C0) && ((c) <= 0x06CE)) ||
-- (((c) >= 0x06D0) && ((c) <= 0x06D3)) ||
-- ((c) == 0x06D5) ||
-- (((c) >= 0x06E5) && ((c) <= 0x06E6)) ||
-- (((c) >= 0x905) && ( /* accelerator */
-- (((c) >= 0x0905) && ((c) <= 0x0939)) ||
-- ((c) == 0x093D) ||
-- (((c) >= 0x0958) && ((c) <= 0x0961)) ||
-- (((c) >= 0x0985) && ((c) <= 0x098C)) ||
-- (((c) >= 0x098F) && ((c) <= 0x0990)) ||
-- (((c) >= 0x0993) && ((c) <= 0x09A8)) ||
-- (((c) >= 0x09AA) && ((c) <= 0x09B0)) ||
-- ((c) == 0x09B2) ||
-- (((c) >= 0x09B6) && ((c) <= 0x09B9)) ||
-- (((c) >= 0x09DC) && ((c) <= 0x09DD)) ||
-- (((c) >= 0x09DF) && ((c) <= 0x09E1)) ||
-- (((c) >= 0x09F0) && ((c) <= 0x09F1)) ||
-- (((c) >= 0x0A05) && ((c) <= 0x0A0A)) ||
-- (((c) >= 0x0A0F) && ((c) <= 0x0A10)) ||
-- (((c) >= 0x0A13) && ((c) <= 0x0A28)) ||
-- (((c) >= 0x0A2A) && ((c) <= 0x0A30)) ||
-- (((c) >= 0x0A32) && ((c) <= 0x0A33)) ||
-- (((c) >= 0x0A35) && ((c) <= 0x0A36)) ||
-- (((c) >= 0x0A38) && ((c) <= 0x0A39)) ||
-- (((c) >= 0x0A59) && ((c) <= 0x0A5C)) ||
-- ((c) == 0x0A5E) ||
-- (((c) >= 0x0A72) && ((c) <= 0x0A74)) ||
-- (((c) >= 0x0A85) && ((c) <= 0x0A8B)) ||
-- ((c) == 0x0A8D) ||
-- (((c) >= 0x0A8F) && ((c) <= 0x0A91)) ||
-- (((c) >= 0x0A93) && ((c) <= 0x0AA8)) ||
-- (((c) >= 0x0AAA) && ((c) <= 0x0AB0)) ||
-- (((c) >= 0x0AB2) && ((c) <= 0x0AB3)) ||
-- (((c) >= 0x0AB5) && ((c) <= 0x0AB9)) ||
-- ((c) == 0x0ABD) ||
-- ((c) == 0x0AE0) ||
-- (((c) >= 0x0B05) && ((c) <= 0x0B0C)) ||
-- (((c) >= 0x0B0F) && ((c) <= 0x0B10)) ||
-- (((c) >= 0x0B13) && ((c) <= 0x0B28)) ||
-- (((c) >= 0x0B2A) && ((c) <= 0x0B30)) ||
-- (((c) >= 0x0B32) && ((c) <= 0x0B33)) ||
-- (((c) >= 0x0B36) && ((c) <= 0x0B39)) ||
-- ((c) == 0x0B3D) ||
-- (((c) >= 0x0B5C) && ((c) <= 0x0B5D)) ||
-- (((c) >= 0x0B5F) && ((c) <= 0x0B61)) ||
-- (((c) >= 0x0B85) && ((c) <= 0x0B8A)) ||
-- (((c) >= 0x0B8E) && ((c) <= 0x0B90)) ||
-- (((c) >= 0x0B92) && ((c) <= 0x0B95)) ||
-- (((c) >= 0x0B99) && ((c) <= 0x0B9A)) ||
-- ((c) == 0x0B9C) ||
-- (((c) >= 0x0B9E) && ((c) <= 0x0B9F)) ||
-- (((c) >= 0x0BA3) && ((c) <= 0x0BA4)) ||
-- (((c) >= 0x0BA8) && ((c) <= 0x0BAA)) ||
-- (((c) >= 0x0BAE) && ((c) <= 0x0BB5)) ||
-- (((c) >= 0x0BB7) && ((c) <= 0x0BB9)) ||
-- (((c) >= 0x0C05) && ((c) <= 0x0C0C)) ||
-- (((c) >= 0x0C0E) && ((c) <= 0x0C10)) ||
-- (((c) >= 0x0C12) && ((c) <= 0x0C28)) ||
-- (((c) >= 0x0C2A) && ((c) <= 0x0C33)) ||
-- (((c) >= 0x0C35) && ((c) <= 0x0C39)) ||
-- (((c) >= 0x0C60) && ((c) <= 0x0C61)) ||
-- (((c) >= 0x0C85) && ((c) <= 0x0C8C)) ||
-- (((c) >= 0x0C8E) && ((c) <= 0x0C90)) ||
-- (((c) >= 0x0C92) && ((c) <= 0x0CA8)) ||
-- (((c) >= 0x0CAA) && ((c) <= 0x0CB3)) ||
-- (((c) >= 0x0CB5) && ((c) <= 0x0CB9)) ||
-- ((c) == 0x0CDE) ||
-- (((c) >= 0x0CE0) && ((c) <= 0x0CE1)) ||
-- (((c) >= 0x0D05) && ((c) <= 0x0D0C)) ||
-- (((c) >= 0x0D0E) && ((c) <= 0x0D10)) ||
-- (((c) >= 0x0D12) && ((c) <= 0x0D28)) ||
-- (((c) >= 0x0D2A) && ((c) <= 0x0D39)) ||
-- (((c) >= 0x0D60) && ((c) <= 0x0D61)) ||
-- (((c) >= 0x0E01) && ((c) <= 0x0E2E)) ||
-- ((c) == 0x0E30) ||
-- (((c) >= 0x0E32) && ((c) <= 0x0E33)) ||
-- (((c) >= 0x0E40) && ((c) <= 0x0E45)) ||
-- (((c) >= 0x0E81) && ((c) <= 0x0E82)) ||
-- ((c) == 0x0E84) ||
-- (((c) >= 0x0E87) && ((c) <= 0x0E88)) ||
-- ((c) == 0x0E8A) ||
-- ((c) == 0x0E8D) ||
-- (((c) >= 0x0E94) && ((c) <= 0x0E97)) ||
-- (((c) >= 0x0E99) && ((c) <= 0x0E9F)) ||
-- (((c) >= 0x0EA1) && ((c) <= 0x0EA3)) ||
-- ((c) == 0x0EA5) ||
-- ((c) == 0x0EA7) ||
-- (((c) >= 0x0EAA) && ((c) <= 0x0EAB)) ||
-- (((c) >= 0x0EAD) && ((c) <= 0x0EAE)) ||
-- ((c) == 0x0EB0) ||
-- (((c) >= 0x0EB2) && ((c) <= 0x0EB3)) ||
-- ((c) == 0x0EBD) ||
-- (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) ||
-- (((c) >= 0x0F40) && ((c) <= 0x0F47)) ||
-- (((c) >= 0x0F49) && ((c) <= 0x0F69)) ||
-- (((c) >= 0x10A0) && ( /* accelerator */
-- (((c) >= 0x10A0) && ((c) <= 0x10C5)) ||
-- (((c) >= 0x10D0) && ((c) <= 0x10F6)) ||
-- ((c) == 0x1100) ||
-- (((c) >= 0x1102) && ((c) <= 0x1103)) ||
-- (((c) >= 0x1105) && ((c) <= 0x1107)) ||
-- ((c) == 0x1109) ||
-- (((c) >= 0x110B) && ((c) <= 0x110C)) ||
-- (((c) >= 0x110E) && ((c) <= 0x1112)) ||
-- ((c) == 0x113C) ||
-- ((c) == 0x113E) ||
-- ((c) == 0x1140) ||
-- ((c) == 0x114C) ||
-- ((c) == 0x114E) ||
-- ((c) == 0x1150) ||
-- (((c) >= 0x1154) && ((c) <= 0x1155)) ||
-- ((c) == 0x1159) ||
-- (((c) >= 0x115F) && ((c) <= 0x1161)) ||
-- ((c) == 0x1163) ||
-- ((c) == 0x1165) ||
-- ((c) == 0x1167) ||
-- ((c) == 0x1169) ||
-- (((c) >= 0x116D) && ((c) <= 0x116E)) ||
-- (((c) >= 0x1172) && ((c) <= 0x1173)) ||
-- ((c) == 0x1175) ||
-- ((c) == 0x119E) ||
-- ((c) == 0x11A8) ||
-- ((c) == 0x11AB) ||
-- (((c) >= 0x11AE) && ((c) <= 0x11AF)) ||
-- (((c) >= 0x11B7) && ((c) <= 0x11B8)) ||
-- ((c) == 0x11BA) ||
-- (((c) >= 0x11BC) && ((c) <= 0x11C2)) ||
-- ((c) == 0x11EB) ||
-- ((c) == 0x11F0) ||
-- ((c) == 0x11F9) ||
-- (((c) >= 0x1E00) && ((c) <= 0x1E9B)) ||
-- (((c) >= 0x1EA0) && ((c) <= 0x1EF9)) ||
-- (((c) >= 0x1F00) && ((c) <= 0x1F15)) ||
-- (((c) >= 0x1F18) && ((c) <= 0x1F1D)) ||
-- (((c) >= 0x1F20) && ((c) <= 0x1F45)) ||
-- (((c) >= 0x1F48) && ((c) <= 0x1F4D)) ||
-- (((c) >= 0x1F50) && ((c) <= 0x1F57)) ||
-- ((c) == 0x1F59) ||
-- ((c) == 0x1F5B) ||
-- ((c) == 0x1F5D) ||
-- (((c) >= 0x1F5F) && ((c) <= 0x1F7D)) ||
-- (((c) >= 0x1F80) && ((c) <= 0x1FB4)) ||
-- (((c) >= 0x1FB6) && ((c) <= 0x1FBC)) ||
-- ((c) == 0x1FBE) ||
-- (((c) >= 0x1FC2) && ((c) <= 0x1FC4)) ||
-- (((c) >= 0x1FC6) && ((c) <= 0x1FCC)) ||
-- (((c) >= 0x1FD0) && ((c) <= 0x1FD3)) ||
-- (((c) >= 0x1FD6) && ((c) <= 0x1FDB)) ||
-- (((c) >= 0x1FE0) && ((c) <= 0x1FEC)) ||
-- (((c) >= 0x1FF2) && ((c) <= 0x1FF4)) ||
-- (((c) >= 0x1FF6) && ((c) <= 0x1FFC)) ||
-- ((c) == 0x2126) ||
-- (((c) >= 0x212A) && ((c) <= 0x212B)) ||
-- ((c) == 0x212E) ||
-- (((c) >= 0x2180) && ((c) <= 0x2182)) ||
-- (((c) >= 0x3041) && ((c) <= 0x3094)) ||
-- (((c) >= 0x30A1) && ((c) <= 0x30FA)) ||
-- (((c) >= 0x3105) && ((c) <= 0x312C)) ||
-- (((c) >= 0xAC00) && ((c) <= 0xD7A3))) /* accelerators */ ))))));
--}
--
--/**
-- * xmlIsDigit:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [88] Digit ::= ... long list see REC ...
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsDigit(int c) {
-- return(
-- (((c) >= 0x0030) && ((c) <= 0x0039)) ||
-- (((c) >= 0x660) && ( /* accelerator */
-- (((c) >= 0x0660) && ((c) <= 0x0669)) ||
-- (((c) >= 0x06F0) && ((c) <= 0x06F9)) ||
-- (((c) >= 0x0966) && ((c) <= 0x096F)) ||
-- (((c) >= 0x09E6) && ((c) <= 0x09EF)) ||
-- (((c) >= 0x0A66) && ((c) <= 0x0A6F)) ||
-- (((c) >= 0x0AE6) && ((c) <= 0x0AEF)) ||
-- (((c) >= 0x0B66) && ((c) <= 0x0B6F)) ||
-- (((c) >= 0x0BE7) && ((c) <= 0x0BEF)) ||
-- (((c) >= 0x0C66) && ((c) <= 0x0C6F)) ||
-- (((c) >= 0x0CE6) && ((c) <= 0x0CEF)) ||
-- (((c) >= 0x0D66) && ((c) <= 0x0D6F)) ||
-- (((c) >= 0x0E50) && ((c) <= 0x0E59)) ||
-- (((c) >= 0x0ED0) && ((c) <= 0x0ED9)) ||
-- (((c) >= 0x0F20) && ((c) <= 0x0F29))) /* accelerator */ ));
--}
--
--/**
-- * xmlIsCombining:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [87] CombiningChar ::= ... long list see REC ...
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsCombining(int c) {
-- return(
-- (((c) >= 0x300) && ( /* accelerator */
-- (((c) >= 0x0300) && ((c) <= 0x0345)) ||
-- (((c) >= 0x0360) && ((c) <= 0x0361)) ||
-- (((c) >= 0x0483) && ((c) <= 0x0486)) ||
-- (((c) >= 0x0591) && ((c) <= 0x05A1)) ||
-- (((c) >= 0x05A3) && ((c) <= 0x05B9)) ||
-- (((c) >= 0x05BB) && ((c) <= 0x05BD)) ||
-- ((c) == 0x05BF) ||
-- (((c) >= 0x05C1) && ((c) <= 0x05C2)) ||
-- ((c) == 0x05C4) ||
-- (((c) >= 0x064B) && ((c) <= 0x0652)) ||
-- ((c) == 0x0670) ||
-- (((c) >= 0x06D6) && ((c) <= 0x06DC)) ||
-- (((c) >= 0x06DD) && ((c) <= 0x06DF)) ||
-- (((c) >= 0x06E0) && ((c) <= 0x06E4)) ||
-- (((c) >= 0x06E7) && ((c) <= 0x06E8)) ||
-- (((c) >= 0x06EA) && ((c) <= 0x06ED)) ||
-- (((c) >= 0x0901) && ( /* accelerator */
-- (((c) >= 0x0901) && ((c) <= 0x0903)) ||
-- ((c) == 0x093C) ||
-- (((c) >= 0x093E) && ((c) <= 0x094C)) ||
-- ((c) == 0x094D) ||
-- (((c) >= 0x0951) && ((c) <= 0x0954)) ||
-- (((c) >= 0x0962) && ((c) <= 0x0963)) ||
-- (((c) >= 0x0981) && ((c) <= 0x0983)) ||
-- ((c) == 0x09BC) ||
-- ((c) == 0x09BE) ||
-- ((c) == 0x09BF) ||
-- (((c) >= 0x09C0) && ((c) <= 0x09C4)) ||
-- (((c) >= 0x09C7) && ((c) <= 0x09C8)) ||
-- (((c) >= 0x09CB) && ((c) <= 0x09CD)) ||
-- ((c) == 0x09D7) ||
-- (((c) >= 0x09E2) && ((c) <= 0x09E3)) ||
-- (((c) >= 0x0A02) && ( /* accelerator */
-- ((c) == 0x0A02) ||
-- ((c) == 0x0A3C) ||
-- ((c) == 0x0A3E) ||
-- ((c) == 0x0A3F) ||
-- (((c) >= 0x0A40) && ((c) <= 0x0A42)) ||
-- (((c) >= 0x0A47) && ((c) <= 0x0A48)) ||
-- (((c) >= 0x0A4B) && ((c) <= 0x0A4D)) ||
-- (((c) >= 0x0A70) && ((c) <= 0x0A71)) ||
-- (((c) >= 0x0A81) && ((c) <= 0x0A83)) ||
-- ((c) == 0x0ABC) ||
-- (((c) >= 0x0ABE) && ((c) <= 0x0AC5)) ||
-- (((c) >= 0x0AC7) && ((c) <= 0x0AC9)) ||
-- (((c) >= 0x0ACB) && ((c) <= 0x0ACD)) ||
-- (((c) >= 0x0B01) && ((c) <= 0x0B03)) ||
-- ((c) == 0x0B3C) ||
-- (((c) >= 0x0B3E) && ((c) <= 0x0B43)) ||
-- (((c) >= 0x0B47) && ((c) <= 0x0B48)) ||
-- (((c) >= 0x0B4B) && ((c) <= 0x0B4D)) ||
-- (((c) >= 0x0B56) && ((c) <= 0x0B57)) ||
-- (((c) >= 0x0B82) && ((c) <= 0x0B83)) ||
-- (((c) >= 0x0BBE) && ((c) <= 0x0BC2)) ||
-- (((c) >= 0x0BC6) && ((c) <= 0x0BC8)) ||
-- (((c) >= 0x0BCA) && ((c) <= 0x0BCD)) ||
-- ((c) == 0x0BD7) ||
-- (((c) >= 0x0C01) && ((c) <= 0x0C03)) ||
-- (((c) >= 0x0C3E) && ((c) <= 0x0C44)) ||
-- (((c) >= 0x0C46) && ((c) <= 0x0C48)) ||
-- (((c) >= 0x0C4A) && ((c) <= 0x0C4D)) ||
-- (((c) >= 0x0C55) && ((c) <= 0x0C56)) ||
-- (((c) >= 0x0C82) && ((c) <= 0x0C83)) ||
-- (((c) >= 0x0CBE) && ((c) <= 0x0CC4)) ||
-- (((c) >= 0x0CC6) && ((c) <= 0x0CC8)) ||
-- (((c) >= 0x0CCA) && ((c) <= 0x0CCD)) ||
-- (((c) >= 0x0CD5) && ((c) <= 0x0CD6)) ||
-- (((c) >= 0x0D02) && ((c) <= 0x0D03)) ||
-- (((c) >= 0x0D3E) && ((c) <= 0x0D43)) ||
-- (((c) >= 0x0D46) && ((c) <= 0x0D48)) ||
-- (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) ||
-- ((c) == 0x0D57) ||
-- (((c) >= 0x0E31) && ( /* accelerator */
-- ((c) == 0x0E31) ||
-- (((c) >= 0x0E34) && ((c) <= 0x0E3A)) ||
-- (((c) >= 0x0E47) && ((c) <= 0x0E4E)) ||
-- ((c) == 0x0EB1) ||
-- (((c) >= 0x0EB4) && ((c) <= 0x0EB9)) ||
-- (((c) >= 0x0EBB) && ((c) <= 0x0EBC)) ||
-- (((c) >= 0x0EC8) && ((c) <= 0x0ECD)) ||
-- (((c) >= 0x0F18) && ((c) <= 0x0F19)) ||
-- ((c) == 0x0F35) ||
-- ((c) == 0x0F37) ||
-- ((c) == 0x0F39) ||
-- ((c) == 0x0F3E) ||
-- ((c) == 0x0F3F) ||
-- (((c) >= 0x0F71) && ((c) <= 0x0F84)) ||
-- (((c) >= 0x0F86) && ((c) <= 0x0F8B)) ||
-- (((c) >= 0x0F90) && ((c) <= 0x0F95)) ||
-- ((c) == 0x0F97) ||
-- (((c) >= 0x0F99) && ((c) <= 0x0FAD)) ||
-- (((c) >= 0x0FB1) && ((c) <= 0x0FB7)) ||
-- ((c) == 0x0FB9) ||
-- (((c) >= 0x20D0) && ((c) <= 0x20DC)) ||
-- ((c) == 0x20E1) ||
-- (((c) >= 0x302A) && ((c) <= 0x302F)) ||
-- ((c) == 0x3099) ||
-- ((c) == 0x309A))))))))));
--}
--
--/**
-- * xmlIsExtender:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
-- * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
-- * [#x309D-#x309E] | [#x30FC-#x30FE]
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsExtender(int c) {
-- switch (c) {
-- case 0x00B7: case 0x02D0: case 0x02D1: case 0x0387:
-- case 0x0640: case 0x0E46: case 0x0EC6: case 0x3005:
-- case 0x3031: case 0x3032: case 0x3033: case 0x3034:
-- case 0x3035: case 0x309D: case 0x309E: case 0x30FC:
-- case 0x30FE:
-- return 1;
-- default:
-- return 0;
-- }
--}
--
--/**
-- * xmlIsIdeographic:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsIdeographic(int c) {
-- return(((c) < 0x0100) ? 0 :
-- (((c) >= 0x4e00) && ((c) <= 0x9fa5)) ||
-- (((c) >= 0xf900) && ((c) <= 0xfa2d)) ||
-- (((c) >= 0x3021) && ((c) <= 0x3029)) ||
-- ((c) == 0x3007));
--}
--
--/**
-- * xmlIsLetter:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [84] Letter ::= BaseChar | Ideographic
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsLetter(int c) {
-- return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
--}
--
--/**
-- * xmlIsPubidChar:
-- * @c: an unicode character (int)
-- *
-- * Check whether the character is allowed by the production
-- * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-- *
-- * Returns 0 if not, non-zero otherwise
-- */
--int
--xmlIsPubidChar(int c) {
-- return(
-- ((c) == 0x20) || ((c) == 0x0D) || ((c) == 0x0A) ||
-- (((c) >= 'a') && ((c) <= 'z')) ||
-- (((c) >= 'A') && ((c) <= 'Z')) ||
-- (((c) >= '0') && ((c) <= '9')) ||
-- ((c) == '-') || ((c) == '\'') || ((c) == '(') || ((c) == ')') ||
-- ((c) == '+') || ((c) == ',') || ((c) == '.') || ((c) == '/') ||
-- ((c) == ':') || ((c) == '=') || ((c) == '?') || ((c) == ';') ||
-- ((c) == '!') || ((c) == '*') || ((c) == '#') || ((c) == '@') ||
-- ((c) == '$') || ((c) == '_') || ((c) == '%'));
--}
--
--/************************************************************************
-- * *
-- * Input handling functions for progressive parsing *
-- * *
-- ************************************************************************/
--
--/* #define DEBUG_INPUT */
--/* #define DEBUG_STACK */
--/* #define DEBUG_PUSH */
--
--
--/* we need to keep enough input to show errors in context */
--#define LINE_LEN 80
--
--#ifdef DEBUG_INPUT
--#define CHECK_BUFFER(in) check_buffer(in)
--
--void check_buffer(xmlParserInputPtr in) {
-- if (in->base != in->buf->buffer->content) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInput: base mismatch problem\n");
-- }
-- if (in->cur < in->base) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInput: cur < base problem\n");
-- }
-- if (in->cur > in->base + in->buf->buffer->use) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInput: cur > base + use problem\n");
-- }
-- xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d, size %d\n",
-- (int) in, (int) in->buf->buffer->content, in->cur - in->base,
-- in->buf->buffer->use, in->buf->buffer->size);
--}
--
--#else
--#define CHECK_BUFFER(in)
--#endif
--
--
--/**
-- * xmlParserInputRead:
-- * @in: an XML parser input
-- * @len: an indicative size for the lookahead
-- *
-- * This function refresh the input for the parser. It doesn't try to
-- * preserve pointers to the input buffer, and discard already read data
-- *
-- * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
-- * end of this entity
-- */
--int
--xmlParserInputRead(xmlParserInputPtr in, int len) {
-- int ret;
-- int used;
-- int index;
--
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext, "Read\n");
--#endif
-- if (in->buf == NULL) return(-1);
-- if (in->base == NULL) return(-1);
-- if (in->cur == NULL) return(-1);
-- if (in->buf->buffer == NULL) return(-1);
-- if (in->buf->readcallback == NULL) return(-1);
--
-- CHECK_BUFFER(in);
--
-- used = in->cur - in->buf->buffer->content;
-- ret = xmlBufferShrink(in->buf->buffer, used);
-- if (ret > 0) {
-- in->cur -= ret;
-- in->consumed += ret;
-- }
-- ret = xmlParserInputBufferRead(in->buf, len);
-- if (in->base != in->buf->buffer->content) {
-- /*
-- * the buffer has been realloced
-- */
-- index = in->cur - in->base;
-- in->base = in->buf->buffer->content;
-- in->cur = &in->buf->buffer->content[index];
-- }
--
-- CHECK_BUFFER(in);
--
-- return(ret);
--}
--
--/**
-- * xmlParserInputGrow:
-- * @in: an XML parser input
-- * @len: an indicative size for the lookahead
-- *
-- * This function increase the input for the parser. It tries to
-- * preserve pointers to the input buffer, and keep already read data
-- *
-- * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
-- * end of this entity
-- */
--int
--xmlParserInputGrow(xmlParserInputPtr in, int len) {
-- int ret;
-- int index;
--
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext, "Grow\n");
--#endif
-- if (in->buf == NULL) return(-1);
-- if (in->base == NULL) return(-1);
-- if (in->cur == NULL) return(-1);
-- if (in->buf->buffer == NULL) return(-1);
--
-- CHECK_BUFFER(in);
--
-- index = in->cur - in->base;
-- if (in->buf->buffer->use > (unsigned int) index + INPUT_CHUNK) {
--
-- CHECK_BUFFER(in);
--
-- return(0);
-- }
-- if (in->buf->readcallback != NULL)
-- ret = xmlParserInputBufferGrow(in->buf, len);
-- else
-- return(0);
--
-- /*
-- * NOTE : in->base may be a "dandling" i.e. freed pointer in this
-- * block, but we use it really as an integer to do some
-- * pointer arithmetic. Insure will raise it as a bug but in
-- * that specific case, that's not !
-- */
-- if (in->base != in->buf->buffer->content) {
-- /*
-- * the buffer has been realloced
-- */
-- index = in->cur - in->base;
-- in->base = in->buf->buffer->content;
-- in->cur = &in->buf->buffer->content[index];
-- }
--
-- CHECK_BUFFER(in);
--
-- return(ret);
--}
--
--/**
-- * xmlParserInputShrink:
-- * @in: an XML parser input
-- *
-- * This function removes used input for the parser.
-- */
--void
--xmlParserInputShrink(xmlParserInputPtr in) {
-- int used;
-- int ret;
-- int index;
--
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext, "Shrink\n");
--#endif
-- if (in->buf == NULL) return;
-- if (in->base == NULL) return;
-- if (in->cur == NULL) return;
-- if (in->buf->buffer == NULL) return;
--
-- CHECK_BUFFER(in);
--
-- used = in->cur - in->buf->buffer->content;
-- /*
-- * Do not shrink on large buffers whose only a tiny fraction
-- * was consumned
-- */
-- if (in->buf->buffer->use > used + 2 * INPUT_CHUNK)
-- return;
-- if (used > INPUT_CHUNK) {
-- ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
-- if (ret > 0) {
-- in->cur -= ret;
-- in->consumed += ret;
-- }
-- }
--
-- CHECK_BUFFER(in);
--
-- if (in->buf->buffer->use > INPUT_CHUNK) {
-- return;
-- }
-- xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
-- if (in->base != in->buf->buffer->content) {
-- /*
-- * the buffer has been realloced
-- */
-- index = in->cur - in->base;
-- in->base = in->buf->buffer->content;
-- in->cur = &in->buf->buffer->content[index];
-- }
--
-- CHECK_BUFFER(in);
--}
--
--/************************************************************************
-- * *
-- * UTF8 character input and related functions *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlNextChar:
-- * @ctxt: the XML parser context
-- *
-- * Skip to the next char input char.
-- */
--
--void
--xmlNextChar(xmlParserCtxtPtr ctxt) {
-- if (ctxt->instate == XML_PARSER_EOF)
-- return;
--
-- /*
-- * 2.11 End-of-Line Handling
-- * the literal two-character sequence "#xD#xA" or a standalone
-- * literal #xD, an XML processor must pass to the application
-- * the single character #xA.
-- */
-- if (ctxt->token != 0) ctxt->token = 0;
-- else if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-- if ((*ctxt->input->cur == 0) &&
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
-- (ctxt->instate != XML_PARSER_COMMENT)) {
-- /*
-- * If we are at the end of the current entity and
-- * the context allows it, we pop consumed entities
-- * automatically.
-- * the auto closing should be blocked in other cases
-- */
-- xmlPopInput(ctxt);
-- } else {
-- if (*(ctxt->input->cur) == '\n') {
-- ctxt->input->line++; ctxt->input->col = 1;
-- } else ctxt->input->col++;
-- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-- /*
-- * We are supposed to handle UTF8, check it's valid
-- * From rfc2044: encoding of the Unicode values on UTF-8:
-- *
-- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-- * 0000 0000-0000 007F 0xxxxxxx
-- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- *
-- * Check for the 0x110000 limit too
-- */
-- const unsigned char *cur = ctxt->input->cur;
-- unsigned char c;
--
-- c = *cur;
-- if (c & 0x80) {
-- if (cur[1] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if ((cur[1] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xe0) == 0xe0) {
-- unsigned int val;
--
-- if (cur[2] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if ((cur[2] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xf0) == 0xf0) {
-- if (cur[3] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if (((c & 0xf8) != 0xf0) ||
-- ((cur[3] & 0xc0) != 0x80))
-- goto encoding_error;
-- /* 4-byte code */
-- ctxt->input->cur += 4;
-- val = (cur[0] & 0x7) << 18;
-- val |= (cur[1] & 0x3f) << 12;
-- val |= (cur[2] & 0x3f) << 6;
-- val |= cur[3] & 0x3f;
-- } else {
-- /* 3-byte code */
-- ctxt->input->cur += 3;
-- val = (cur[0] & 0xf) << 12;
-- val |= (cur[1] & 0x3f) << 6;
-- val |= cur[2] & 0x3f;
-- }
-- if (((val > 0xd7ff) && (val < 0xe000)) ||
-- ((val > 0xfffd) && (val < 0x10000)) ||
-- (val >= 0x110000)) {
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Char 0x%X out of allowed range\n", val);
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- } else
-- /* 2-byte code */
-- ctxt->input->cur += 2;
-- } else
-- /* 1-byte code */
-- ctxt->input->cur++;
-- } else {
-- /*
-- * Assume it's a fixed lenght encoding (1) with
-- * a compatibke encoding for the ASCII set, since
-- * XML constructs only use < 128 chars
-- */
-- ctxt->input->cur++;
-- }
-- ctxt->nbChars++;
-- if (*ctxt->input->cur == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- }
-- } else {
-- ctxt->input->cur++;
-- ctxt->nbChars++;
-- if (*ctxt->input->cur == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- }
-- if ((*ctxt->input->cur == '%') && (!ctxt->html))
-- xmlParserHandlePEReference(ctxt);
-- if ((*ctxt->input->cur == 0) &&
-- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-- xmlPopInput(ctxt);
-- return;
--encoding_error:
-- /*
-- * If we detect an UTF8 error that probably mean that the
-- * input encoding didn't get properly advertized in the
-- * declaration header. Report the error and switch the encoding
-- * to ISO-Latin-1 (if you don't like this policy, just declare the
-- * encoding !)
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-- ctxt->sax->error(ctxt->userData,
-- "Input is not proper UTF-8, indicate encoding !\n");
-- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- ctxt->input->cur[0], ctxt->input->cur[1],
-- ctxt->input->cur[2], ctxt->input->cur[3]);
-- }
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
--
-- ctxt->charset = XML_CHAR_ENCODING_8859_1;
-- ctxt->input->cur++;
-- return;
--}
--
--/**
-- * xmlCurrentChar:
-- * @ctxt: the XML parser context
-- * @len: pointer to the length of the char read
-- *
-- * The current char value, if using UTF-8 this may actaully span multiple
-- * bytes in the input buffer. Implement the end of line normalization:
-- * 2.11 End-of-Line Handling
-- * Wherever an external parsed entity or the literal entity value
-- * of an internal parsed entity contains either the literal two-character
-- * sequence "#xD#xA" or a standalone literal #xD, an XML processor
-- * must pass to the application the single character #xA.
-- * This behavior can conveniently be produced by normalizing all
-- * line breaks to #xA on input, before parsing.)
-- *
-- * Returns the current char value and its lenght
-- */
--
--int
--xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
-- if (ctxt->instate == XML_PARSER_EOF)
-- return(0);
--
-- if (ctxt->token != 0) {
-- *len = 0;
-- return(ctxt->token);
-- }
-- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-- /*
-- * We are supposed to handle UTF8, check it's valid
-- * From rfc2044: encoding of the Unicode values on UTF-8:
-- *
-- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-- * 0000 0000-0000 007F 0xxxxxxx
-- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- *
-- * Check for the 0x110000 limit too
-- */
-- const unsigned char *cur = ctxt->input->cur;
-- unsigned char c;
-- unsigned int val;
--
-- c = *cur;
-- if (c & 0x80) {
-- if (cur[1] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if ((cur[1] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xe0) == 0xe0) {
--
-- if (cur[2] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if ((cur[2] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xf0) == 0xf0) {
-- if (cur[3] == 0)
-- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-- if (((c & 0xf8) != 0xf0) ||
-- ((cur[3] & 0xc0) != 0x80))
-- goto encoding_error;
-- /* 4-byte code */
-- *len = 4;
-- val = (cur[0] & 0x7) << 18;
-- val |= (cur[1] & 0x3f) << 12;
-- val |= (cur[2] & 0x3f) << 6;
-- val |= cur[3] & 0x3f;
-- } else {
-- /* 3-byte code */
-- *len = 3;
-- val = (cur[0] & 0xf) << 12;
-- val |= (cur[1] & 0x3f) << 6;
-- val |= cur[2] & 0x3f;
-- }
-- } else {
-- /* 2-byte code */
-- *len = 2;
-- val = (cur[0] & 0x1f) << 6;
-- val |= cur[1] & 0x3f;
-- }
-- if (!IS_CHAR(val)) {
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Char 0x%X out of allowed range\n", val);
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(val);
-- } else {
-- /* 1-byte code */
-- *len = 1;
-- if (*ctxt->input->cur == 0xD) {
-- if (ctxt->input->cur[1] == 0xA) {
-- ctxt->nbChars++;
-- ctxt->input->cur++;
-- }
-- return(0xA);
-- }
-- return((int) *ctxt->input->cur);
-- }
-- }
-- /*
-- * Assume it's a fixed lenght encoding (1) with
-- * a compatibke encoding for the ASCII set, since
-- * XML constructs only use < 128 chars
-- */
-- *len = 1;
-- if (*ctxt->input->cur == 0xD) {
-- if (ctxt->input->cur[1] == 0xA) {
-- ctxt->nbChars++;
-- ctxt->input->cur++;
-- }
-- return(0xA);
-- }
-- return((int) *ctxt->input->cur);
--encoding_error:
-- /*
-- * If we detect an UTF8 error that probably mean that the
-- * input encoding didn't get properly advertized in the
-- * declaration header. Report the error and switch the encoding
-- * to ISO-Latin-1 (if you don't like this policy, just declare the
-- * encoding !)
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-- ctxt->sax->error(ctxt->userData,
-- "Input is not proper UTF-8, indicate encoding !\n");
-- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- ctxt->input->cur[0], ctxt->input->cur[1],
-- ctxt->input->cur[2], ctxt->input->cur[3]);
-- }
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
--
-- ctxt->charset = XML_CHAR_ENCODING_8859_1;
-- *len = 1;
-- return((int) *ctxt->input->cur);
--}
--
--/**
-- * xmlStringCurrentChar:
-- * @ctxt: the XML parser context
-- * @cur: pointer to the beginning of the char
-- * @len: pointer to the length of the char read
-- *
-- * The current char value, if using UTF-8 this may actaully span multiple
-- * bytes in the input buffer.
-- *
-- * Returns the current char value and its lenght
-- */
--
--int
--xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len) {
-- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-- /*
-- * We are supposed to handle UTF8, check it's valid
-- * From rfc2044: encoding of the Unicode values on UTF-8:
-- *
-- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-- * 0000 0000-0000 007F 0xxxxxxx
-- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- *
-- * Check for the 0x110000 limit too
-- */
-- unsigned char c;
-- unsigned int val;
--
-- c = *cur;
-- if (c & 0x80) {
-- if ((cur[1] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xe0) == 0xe0) {
--
-- if ((cur[2] & 0xc0) != 0x80)
-- goto encoding_error;
-- if ((c & 0xf0) == 0xf0) {
-- if (((c & 0xf8) != 0xf0) ||
-- ((cur[3] & 0xc0) != 0x80))
-- goto encoding_error;
-- /* 4-byte code */
-- *len = 4;
-- val = (cur[0] & 0x7) << 18;
-- val |= (cur[1] & 0x3f) << 12;
-- val |= (cur[2] & 0x3f) << 6;
-- val |= cur[3] & 0x3f;
-- } else {
-- /* 3-byte code */
-- *len = 3;
-- val = (cur[0] & 0xf) << 12;
-- val |= (cur[1] & 0x3f) << 6;
-- val |= cur[2] & 0x3f;
-- }
-- } else {
-- /* 2-byte code */
-- *len = 2;
-- val = (cur[0] & 0x1f) << 6;
-- val |= cur[2] & 0x3f;
-- }
-- if (!IS_CHAR(val)) {
-- if ((ctxt->sax != NULL) &&
-- (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Char 0x%X out of allowed range\n", val);
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
-- return(val);
-- } else {
-- /* 1-byte code */
-- *len = 1;
-- return((int) *cur);
-- }
-- }
-- /*
-- * Assume it's a fixed lenght encoding (1) with
-- * a compatibke encoding for the ASCII set, since
-- * XML constructs only use < 128 chars
-- */
-- *len = 1;
-- return((int) *cur);
--encoding_error:
-- /*
-- * If we detect an UTF8 error that probably mean that the
-- * input encoding didn't get properly advertized in the
-- * declaration header. Report the error and switch the encoding
-- * to ISO-Latin-1 (if you don't like this policy, just declare the
-- * encoding !)
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
-- ctxt->sax->error(ctxt->userData,
-- "Input is not proper UTF-8, indicate encoding !\n");
-- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-- ctxt->input->cur[0], ctxt->input->cur[1],
-- ctxt->input->cur[2], ctxt->input->cur[3]);
-- }
-- ctxt->errNo = XML_ERR_INVALID_ENCODING;
--
-- *len = 1;
-- return((int) *cur);
--}
--
--/**
-- * xmlCopyChar:
-- * @len: pointer to the length of the char read (or zero)
-- * @array: pointer to an arry of xmlChar
-- * @val: the char value
-- *
-- * append the char value in the array
-- *
-- * Returns the number of xmlChar written
-- */
--
--int
--xmlCopyChar(int len, xmlChar *out, int val) {
-- /*
-- * We are supposed to handle UTF8, check it's valid
-- * From rfc2044: encoding of the Unicode values on UTF-8:
-- *
-- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
-- * 0000 0000-0000 007F 0xxxxxxx
-- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
-- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- */
-- if (len == 0) {
-- if (val < 0) len = 0;
-- else if (val < 0x80) len = 1;
-- else if (val < 0x800) len = 2;
-- else if (val < 0x10000) len = 3;
-- else if (val < 0x110000) len = 4;
-- if (len == 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "Internal error, xmlCopyChar 0x%X out of bound\n",
-- val);
-- return(0);
-- }
-- }
-- if (len > 1) {
-- int bits;
--
-- if (val < 0x80) { *out++= val; bits= -6; }
-- else if (val < 0x800) { *out++= (val >> 6) | 0xC0; bits= 0; }
-- else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6; }
-- else { *out++= (val >> 18) | 0xF0; bits= 12; }
--
-- for ( ; bits >= 0; bits-= 6)
-- *out++= ((val >> bits) & 0x3F) | 0x80 ;
--
-- return(len);
-- }
-- *out = (xmlChar) val;
-- return(1);
--}
--
--/************************************************************************
-- * *
-- * Commodity functions to switch encodings *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlSwitchEncoding:
-- * @ctxt: the parser context
-- * @enc: the encoding value (number)
-- *
-- * change the input functions when discovering the character encoding
-- * of a given entity.
-- *
-- * Returns 0 in case of success, -1 otherwise
-- */
--int
--xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
--{
-- xmlCharEncodingHandlerPtr handler;
--
-- switch (enc) {
-- case XML_CHAR_ENCODING_ERROR:
-- ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "encoding unknown\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- break;
-- case XML_CHAR_ENCODING_NONE:
-- /* let's assume it's UTF-8 without the XML decl */
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- return(0);
-- case XML_CHAR_ENCODING_UTF8:
-- /* default encoding, no conversion should be needed */
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- return(0);
-- default:
-- break;
-- }
-- handler = xmlGetCharEncodingHandler(enc);
-- if (handler == NULL) {
-- /*
-- * Default handlers.
-- */
-- switch (enc) {
-- case XML_CHAR_ENCODING_ERROR:
-- ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "encoding unknown\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- break;
-- case XML_CHAR_ENCODING_NONE:
-- /* let's assume it's UTF-8 without the XML decl */
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- return(0);
-- case XML_CHAR_ENCODING_UTF8:
-- case XML_CHAR_ENCODING_ASCII:
-- /* default encoding, no conversion should be needed */
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- return(0);
-- case XML_CHAR_ENCODING_UTF16LE:
-- break;
-- case XML_CHAR_ENCODING_UTF16BE:
-- break;
-- case XML_CHAR_ENCODING_UCS4LE:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding USC4 little endian not supported\n");
-- break;
-- case XML_CHAR_ENCODING_UCS4BE:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding USC4 big endian not supported\n");
-- break;
-- case XML_CHAR_ENCODING_EBCDIC:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding EBCDIC not supported\n");
-- break;
-- case XML_CHAR_ENCODING_UCS4_2143:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding UCS4 2143 not supported\n");
-- break;
-- case XML_CHAR_ENCODING_UCS4_3412:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding UCS4 3412 not supported\n");
-- break;
-- case XML_CHAR_ENCODING_UCS2:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding UCS2 not supported\n");
-- break;
-- case XML_CHAR_ENCODING_8859_1:
-- case XML_CHAR_ENCODING_8859_2:
-- case XML_CHAR_ENCODING_8859_3:
-- case XML_CHAR_ENCODING_8859_4:
-- case XML_CHAR_ENCODING_8859_5:
-- case XML_CHAR_ENCODING_8859_6:
-- case XML_CHAR_ENCODING_8859_7:
-- case XML_CHAR_ENCODING_8859_8:
-- case XML_CHAR_ENCODING_8859_9:
-- /*
-- * We used to keep the internal content in the
-- * document encoding however this turns being unmaintainable
-- * So xmlGetCharEncodingHandler() will return non-null
-- * values for this now.
-- */
-- if ((ctxt->inputNr == 1) &&
-- (ctxt->encoding == NULL) &&
-- (ctxt->input->encoding != NULL)) {
-- ctxt->encoding = xmlStrdup(ctxt->input->encoding);
-- }
-- ctxt->charset = enc;
-- return(0);
-- case XML_CHAR_ENCODING_2022_JP:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding ISO-2022-JPnot supported\n");
-- break;
-- case XML_CHAR_ENCODING_SHIFT_JIS:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding Shift_JIS not supported\n");
-- break;
-- case XML_CHAR_ENCODING_EUC_JP:
-- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "char encoding EUC-JPnot supported\n");
-- break;
-- }
-- }
-- if (handler == NULL)
-- return(-1);
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- return(xmlSwitchToEncoding(ctxt, handler));
--}
--
--/**
-- * xmlSwitchToEncoding:
-- * @ctxt: the parser context
-- * @handler: the encoding handler
-- *
-- * change the input functions when discovering the character encoding
-- * of a given entity.
-- *
-- * Returns 0 in case of success, -1 otherwise
-- */
--int
--xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
--{
-- int nbchars;
--
-- if (handler != NULL) {
-- if (ctxt->input != NULL) {
-- if (ctxt->input->buf != NULL) {
-- if (ctxt->input->buf->encoder != NULL) {
-- if (ctxt->input->buf->encoder == handler)
-- return(0);
-- /*
-- * Note: this is a bit dangerous, but that's what it
-- * takes to use nearly compatible signature for different
-- * encodings.
-- */
-- xmlCharEncCloseFunc(ctxt->input->buf->encoder);
-- ctxt->input->buf->encoder = handler;
-- return(0);
-- }
-- ctxt->input->buf->encoder = handler;
--
-- /*
-- * Is there already some content down the pipe to convert ?
-- */
-- if ((ctxt->input->buf->buffer != NULL) &&
-- (ctxt->input->buf->buffer->use > 0)) {
-- int processed;
--
-- /*
-- * Specific handling of the Byte Order Mark for
-- * UTF-16
-- */
-- if ((handler->name != NULL) &&
-- (!strcmp(handler->name, "UTF-16LE")) &&
-- (ctxt->input->cur[0] == 0xFF) &&
-- (ctxt->input->cur[1] == 0xFE)) {
-- ctxt->input->cur += 2;
-- }
-- if ((handler->name != NULL) &&
-- (!strcmp(handler->name, "UTF-16BE")) &&
-- (ctxt->input->cur[0] == 0xFE) &&
-- (ctxt->input->cur[1] == 0xFF)) {
-- ctxt->input->cur += 2;
-- }
--
-- /*
-- * Shring the current input buffer.
-- * Move it as the raw buffer and create a new input buffer
-- */
-- processed = ctxt->input->cur - ctxt->input->base;
-- xmlBufferShrink(ctxt->input->buf->buffer, processed);
-- ctxt->input->buf->raw = ctxt->input->buf->buffer;
-- ctxt->input->buf->buffer = xmlBufferCreate();
--
-- if (ctxt->html) {
-- /*
-- * converst as much as possbile of the buffer
-- */
-- nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-- ctxt->input->buf->buffer,
-- ctxt->input->buf->raw);
-- } else {
-- /*
-- * convert just enough to get
-- * '<?xml version="1.0" encoding="xxx"?>'
-- * parsed with the autodetected encoding
-- * into the parser reading buffer.
-- */
-- nbchars = xmlCharEncFirstLine(ctxt->input->buf->encoder,
-- ctxt->input->buf->buffer,
-- ctxt->input->buf->raw);
-- }
-- if (nbchars < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSwitchToEncoding: encoder error\n");
-- return(-1);
-- }
-- ctxt->input->base =
-- ctxt->input->cur = ctxt->input->buf->buffer->content;
--
-- }
-- return(0);
-- } else {
-- if ((ctxt->input->length == 0) || (ctxt->input->buf == NULL)) {
-- /*
-- * When parsing a static memory array one must know the
-- * size to be able to convert the buffer.
-- */
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlSwitchEncoding : no input\n");
-- return(-1);
-- } else {
-- int processed;
--
-- /*
-- * Shring the current input buffer.
-- * Move it as the raw buffer and create a new input buffer
-- */
-- processed = ctxt->input->cur - ctxt->input->base;
--
-- ctxt->input->buf->raw = xmlBufferCreate();
-- xmlBufferAdd(ctxt->input->buf->raw, ctxt->input->cur,
-- ctxt->input->length - processed);
-- ctxt->input->buf->buffer = xmlBufferCreate();
--
-- /*
-- * convert as much as possible of the raw input
-- * to the parser reading buffer.
-- */
-- nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-- ctxt->input->buf->buffer,
-- ctxt->input->buf->raw);
-- if (nbchars < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSwitchToEncoding: encoder error\n");
-- return(-1);
-- }
--
-- /*
-- * Conversion succeeded, get rid of the old buffer
-- */
-- if ((ctxt->input->free != NULL) &&
-- (ctxt->input->base != NULL))
-- ctxt->input->free((xmlChar *) ctxt->input->base);
-- ctxt->input->base =
-- ctxt->input->cur = ctxt->input->buf->buffer->content;
-- }
-- }
-- } else {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlSwitchEncoding : no input\n");
-- return(-1);
-- }
-- /*
-- * The parsing is now done in UTF8 natively
-- */
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- } else
-- return(-1);
-- return(0);
--
--}
--
--/************************************************************************
-- * *
-- * Commodity functions to handle entities processing *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlFreeInputStream:
-- * @input: an xmlParserInputPtr
-- *
-- * Free up an input stream.
-- */
--void
--xmlFreeInputStream(xmlParserInputPtr input) {
-- if (input == NULL) return;
--
-- if (input->filename != NULL) xmlFree((char *) input->filename);
-- if (input->directory != NULL) xmlFree((char *) input->directory);
-- if (input->encoding != NULL) xmlFree((char *) input->encoding);
-- if (input->version != NULL) xmlFree((char *) input->version);
-- if ((input->free != NULL) && (input->base != NULL))
-- input->free((xmlChar *) input->base);
-- if (input->buf != NULL)
-- xmlFreeParserInputBuffer(input->buf);
-- memset(input, -1, sizeof(xmlParserInput));
-- xmlFree(input);
--}
--
--/**
-- * xmlNewInputStream:
-- * @ctxt: an XML parser context
-- *
-- * Create a new input stream structure
-- * Returns the new input stream or NULL
-- */
--xmlParserInputPtr
--xmlNewInputStream(xmlParserCtxtPtr ctxt) {
-- xmlParserInputPtr input;
--
-- input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
-- if (input == NULL) {
-- if (ctxt != NULL) {
-- ctxt->errNo = XML_ERR_NO_MEMORY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "malloc: couldn't allocate a new input stream\n");
-- ctxt->errNo = XML_ERR_NO_MEMORY;
-- }
-- return(NULL);
-- }
-- memset(input, 0, sizeof(xmlParserInput));
-- input->line = 1;
-- input->col = 1;
-- input->standalone = -1;
-- return(input);
--}
--
--/**
-- * xmlNewIOInputStream:
-- * @ctxt: an XML parser context
-- * @input: an I/O Input
-- * @enc: the charset encoding if known
-- *
-- * Create a new input stream structure encapsulating the @input into
-- * a stream suitable for the parser.
-- *
-- * Returns the new input stream or NULL
-- */
--xmlParserInputPtr
--xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
-- xmlCharEncoding enc) {
-- xmlParserInputPtr inputStream;
--
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
-- inputStream = xmlNewInputStream(ctxt);
-- if (inputStream == NULL) {
-- return(NULL);
-- }
-- inputStream->filename = NULL;
-- inputStream->buf = input;
-- inputStream->base = inputStream->buf->buffer->content;
-- inputStream->cur = inputStream->buf->buffer->content;
-- if (enc != XML_CHAR_ENCODING_NONE) {
-- xmlSwitchEncoding(ctxt, enc);
-- }
--
-- return(inputStream);
--}
--
--/**
-- * xmlNewEntityInputStream:
-- * @ctxt: an XML parser context
-- * @entity: an Entity pointer
-- *
-- * Create a new input stream based on an xmlEntityPtr
-- *
-- * Returns the new input stream or NULL
-- */
--xmlParserInputPtr
--xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-- xmlParserInputPtr input;
--
-- if (entity == NULL) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "internal: xmlNewEntityInputStream entity = NULL\n");
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- return(NULL);
-- }
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "new input from entity: %s\n", entity->name);
-- if (entity->content == NULL) {
-- switch (entity->etype) {
-- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlNewEntityInputStream unparsed entity !\n");
-- break;
-- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-- case XML_EXTERNAL_PARAMETER_ENTITY:
-- return(xmlLoadExternalEntity((char *) entity->URI,
-- (char *) entity->ExternalID, ctxt));
-- case XML_INTERNAL_GENERAL_ENTITY:
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Internal entity %s without content !\n", entity->name);
-- break;
-- case XML_INTERNAL_PARAMETER_ENTITY:
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Internal parameter entity %s without content !\n", entity->name);
-- break;
-- case XML_INTERNAL_PREDEFINED_ENTITY:
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Predefined entity %s without content !\n", entity->name);
-- break;
-- }
-- return(NULL);
-- }
-- input = xmlNewInputStream(ctxt);
-- if (input == NULL) {
-- return(NULL);
-- }
-- input->filename = (char *) entity->URI;
-- input->base = entity->content;
-- input->cur = entity->content;
-- input->length = entity->length;
-- return(input);
--}
--
--/**
-- * xmlNewStringInputStream:
-- * @ctxt: an XML parser context
-- * @buffer: an memory buffer
-- *
-- * Create a new input stream based on a memory buffer.
-- * Returns the new input stream
-- */
--xmlParserInputPtr
--xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
-- xmlParserInputPtr input;
--
-- if (buffer == NULL) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "internal: xmlNewStringInputStream string = NULL\n");
-- return(NULL);
-- }
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "new fixed input: %.30s\n", buffer);
-- input = xmlNewInputStream(ctxt);
-- if (input == NULL) {
-- return(NULL);
-- }
-- input->base = buffer;
-- input->cur = buffer;
-- input->length = xmlStrlen(buffer);
-- return(input);
--}
--
--/**
-- * xmlNewInputFromFile:
-- * @ctxt: an XML parser context
-- * @filename: the filename to use as entity
-- *
-- * Create a new input stream based on a file.
-- *
-- * Returns the new input stream or NULL in case of error
-- */
--xmlParserInputPtr
--xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
-- xmlParserInputBufferPtr buf;
-- xmlParserInputPtr inputStream;
-- char *directory = NULL;
-- xmlChar *URI = NULL;
--
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "new input from file: %s\n", filename);
-- if (ctxt == NULL) return(NULL);
-- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-- if (buf == NULL)
-- return(NULL);
--
-- URI = xmlStrdup((xmlChar *) filename);
-- directory = xmlParserGetDirectory((const char *) URI);
--
-- inputStream = xmlNewInputStream(ctxt);
-- if (inputStream == NULL) {
-- if (directory != NULL) xmlFree((char *) directory);
-- if (URI != NULL) xmlFree((char *) URI);
-- return(NULL);
-- }
--
-- inputStream->filename = (const char *) URI;
-- inputStream->directory = directory;
-- inputStream->buf = buf;
--
-- inputStream->base = inputStream->buf->buffer->content;
-- inputStream->cur = inputStream->buf->buffer->content;
-- if ((ctxt->directory == NULL) && (directory != NULL))
-- ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
-- return(inputStream);
--}
--
--/************************************************************************
-- * *
-- * Commodity functions to handle parser contexts *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlInitParserCtxt:
-- * @ctxt: an XML parser context
-- *
-- * Initialize a parser context
-- */
--
--void
--xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
--{
-- xmlSAXHandler *sax;
--
-- xmlDefaultSAXHandlerInit();
--
-- sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
-- if (sax == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitParserCtxt: out of memory\n");
-- }
-- else
-- memset(sax, 0, sizeof(xmlSAXHandler));
--
-- /* Allocate the Input stack */
-- ctxt->inputTab = (xmlParserInputPtr *)
-- xmlMalloc(5 * sizeof(xmlParserInputPtr));
-- if (ctxt->inputTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitParserCtxt: out of memory\n");
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- return;
-- }
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 5;
-- ctxt->input = NULL;
--
-- ctxt->version = NULL;
-- ctxt->encoding = NULL;
-- ctxt->standalone = -1;
-- ctxt->hasExternalSubset = 0;
-- ctxt->hasPErefs = 0;
-- ctxt->html = 0;
-- ctxt->external = 0;
-- ctxt->instate = XML_PARSER_START;
-- ctxt->token = 0;
-- ctxt->directory = NULL;
--
-- /* Allocate the Node stack */
-- ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
-- if (ctxt->nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitParserCtxt: out of memory\n");
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 0;
-- ctxt->node = NULL;
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- return;
-- }
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 10;
-- ctxt->node = NULL;
--
-- /* Allocate the Name stack */
-- ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
-- if (ctxt->nameTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitParserCtxt: out of memory\n");
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 0;
-- ctxt->node = NULL;
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- ctxt->nameNr = 0;
-- ctxt->nameMax = 0;
-- ctxt->name = NULL;
-- return;
-- }
-- ctxt->nameNr = 0;
-- ctxt->nameMax = 10;
-- ctxt->name = NULL;
--
-- /* Allocate the space stack */
-- ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
-- if (ctxt->spaceTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitParserCtxt: out of memory\n");
-- ctxt->nodeNr = 0;
-- ctxt->nodeMax = 0;
-- ctxt->node = NULL;
-- ctxt->inputNr = 0;
-- ctxt->inputMax = 0;
-- ctxt->input = NULL;
-- ctxt->nameNr = 0;
-- ctxt->nameMax = 0;
-- ctxt->name = NULL;
-- ctxt->spaceNr = 0;
-- ctxt->spaceMax = 0;
-- ctxt->space = NULL;
-- return;
-- }
-- ctxt->spaceNr = 1;
-- ctxt->spaceMax = 10;
-- ctxt->spaceTab[0] = -1;
-- ctxt->space = &ctxt->spaceTab[0];
--
-- if (sax == NULL) {
-- ctxt->sax = &xmlDefaultSAXHandler;
-- } else {
-- ctxt->sax = sax;
-- memcpy(sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
-- }
-- ctxt->userData = ctxt;
-- ctxt->myDoc = NULL;
-- ctxt->wellFormed = 1;
-- ctxt->valid = 1;
-- ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
-- ctxt->validate = xmlDoValidityCheckingDefaultValue;
-- ctxt->pedantic = xmlPedanticParserDefaultValue;
-- ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
-- ctxt->vctxt.userData = ctxt;
-- if (ctxt->validate) {
-- ctxt->vctxt.error = xmlParserValidityError;
-- if (xmlGetWarningsDefaultValue == 0)
-- ctxt->vctxt.warning = NULL;
-- else
-- ctxt->vctxt.warning = xmlParserValidityWarning;
-- /* Allocate the Node stack */
-- ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
-- if (ctxt->vctxt.nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitParserCtxt: out of memory\n");
-- ctxt->vctxt.nodeMax = 0;
-- ctxt->validate = 0;
-- ctxt->vctxt.error = NULL;
-- ctxt->vctxt.warning = NULL;
-- } else {
-- ctxt->vctxt.nodeNr = 0;
-- ctxt->vctxt.nodeMax = 4;
-- ctxt->vctxt.node = NULL;
-- }
-- } else {
-- ctxt->vctxt.error = NULL;
-- ctxt->vctxt.warning = NULL;
-- }
-- ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
-- ctxt->record_info = 0;
-- ctxt->nbChars = 0;
-- ctxt->checkIndex = 0;
-- ctxt->inSubset = 0;
-- ctxt->errNo = XML_ERR_OK;
-- ctxt->depth = 0;
-- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-- xmlInitNodeInfoSeq(&ctxt->node_seq);
--}
--
--/**
-- * xmlFreeParserCtxt:
-- * @ctxt: an XML parser context
-- *
-- * Free all the memory used by a parser context. However the parsed
-- * document in ctxt->myDoc is not freed.
-- */
--
--void
--xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
--{
-- xmlParserInputPtr input;
-- xmlChar *oldname;
--
-- if (ctxt == NULL) return;
--
-- while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
-- xmlFreeInputStream(input);
-- }
-- while ((oldname = namePop(ctxt)) != NULL) { /* Non consuming */
-- xmlFree(oldname);
-- }
-- if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
-- if (ctxt->nameTab != NULL) xmlFree(ctxt->nameTab);
-- if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
-- if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
-- if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
-- if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
-- if (ctxt->intSubName != NULL) xmlFree((char *) ctxt->intSubName);
-- if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
-- if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
-- if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
-- if ((ctxt->sax != NULL) && (ctxt->sax != &xmlDefaultSAXHandler))
-- xmlFree(ctxt->sax);
-- if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
-- xmlFree(ctxt);
--}
--
--/**
-- * xmlNewParserCtxt:
-- *
-- * Allocate and initialize a new parser context.
-- *
-- * Returns the xmlParserCtxtPtr or NULL
-- */
--
--xmlParserCtxtPtr
--xmlNewParserCtxt()
--{
-- xmlParserCtxtPtr ctxt;
--
-- ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
-- if (ctxt == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewParserCtxt : cannot allocate context\n");
-- perror("malloc");
-- return(NULL);
-- }
-- memset(ctxt, 0, sizeof(xmlParserCtxt));
-- xmlInitParserCtxt(ctxt);
-- return(ctxt);
--}
--
--/************************************************************************
-- * *
-- * Handling of node informations *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlClearParserCtxt:
-- * @ctxt: an XML parser context
-- *
-- * Clear (release owned resources) and reinitialize a parser context
-- */
--
--void
--xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
--{
-- xmlClearNodeInfoSeq(&ctxt->node_seq);
-- xmlInitParserCtxt(ctxt);
--}
--
--/**
-- * xmlParserFindNodeInfo:
-- * @ctxt: an XML parser context
-- * @node: an XML node within the tree
-- *
-- * Find the parser node info struct for a given node
-- *
-- * Returns an xmlParserNodeInfo block pointer or NULL
-- */
--const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* ctx,
-- const xmlNode* node)
--{
-- unsigned long pos;
--
-- /* Find position where node should be at */
-- pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
-- if ( ctx->node_seq.buffer[pos].node == node )
-- return &ctx->node_seq.buffer[pos];
-- else
-- return NULL;
--}
--
--
--/**
-- * xmlInitNodeInfoSeq:
-- * @seq: a node info sequence pointer
-- *
-- * -- Initialize (set to initial state) node info sequence
-- */
--void
--xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
--{
-- seq->length = 0;
-- seq->maximum = 0;
-- seq->buffer = NULL;
--}
--
--/**
-- * xmlClearNodeInfoSeq:
-- * @seq: a node info sequence pointer
-- *
-- * -- Clear (release memory and reinitialize) node
-- * info sequence
-- */
--void
--xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
--{
-- if ( seq->buffer != NULL )
-- xmlFree(seq->buffer);
-- xmlInitNodeInfoSeq(seq);
--}
--
--
--/**
-- * xmlParserFindNodeInfoIndex:
-- * @seq: a node info sequence pointer
-- * @node: an XML node pointer
-- *
-- *
-- * xmlParserFindNodeInfoIndex : Find the index that the info record for
-- * the given node is or should be at in a sorted sequence
-- *
-- * Returns a long indicating the position of the record
-- */
--unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
-- const xmlNode* node)
--{
-- unsigned long upper, lower, middle;
-- int found = 0;
--
-- /* Do a binary search for the key */
-- lower = 1;
-- upper = seq->length;
-- middle = 0;
-- while ( lower <= upper && !found) {
-- middle = lower + (upper - lower) / 2;
-- if ( node == seq->buffer[middle - 1].node )
-- found = 1;
-- else if ( node < seq->buffer[middle - 1].node )
-- upper = middle - 1;
-- else
-- lower = middle + 1;
-- }
--
-- /* Return position */
-- if ( middle == 0 || seq->buffer[middle - 1].node < node )
-- return middle;
-- else
-- return middle - 1;
--}
--
--
--/**
-- * xmlParserAddNodeInfo:
-- * @ctxt: an XML parser context
-- * @info: a node info sequence pointer
-- *
-- * Insert node info record into the sorted sequence
-- */
--void
--xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
-- const xmlParserNodeInfo* info)
--{
-- unsigned long pos;
-- static unsigned int block_size = 5;
--
-- /* Find pos and check to see if node is already in the sequence */
-- pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, info->node);
-- if ( pos < ctxt->node_seq.length
-- && ctxt->node_seq.buffer[pos].node == info->node ) {
-- ctxt->node_seq.buffer[pos] = *info;
-- }
--
-- /* Otherwise, we need to add new node to buffer */
-- else {
-- /* Expand buffer by 5 if needed */
-- if ( ctxt->node_seq.length + 1 > ctxt->node_seq.maximum ) {
-- xmlParserNodeInfo* tmp_buffer;
-- unsigned int byte_size = (sizeof(*ctxt->node_seq.buffer)
-- *(ctxt->node_seq.maximum + block_size));
--
-- if ( ctxt->node_seq.buffer == NULL )
-- tmp_buffer = (xmlParserNodeInfo*) xmlMalloc(byte_size);
-- else
-- tmp_buffer = (xmlParserNodeInfo*) xmlRealloc(ctxt->node_seq.buffer, byte_size);
--
-- if ( tmp_buffer == NULL ) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Out of memory\n");
-- ctxt->errNo = XML_ERR_NO_MEMORY;
-- return;
-- }
-- ctxt->node_seq.buffer = tmp_buffer;
-- ctxt->node_seq.maximum += block_size;
-- }
--
-- /* If position is not at end, move elements out of the way */
-- if ( pos != ctxt->node_seq.length ) {
-- unsigned long i;
--
-- for ( i = ctxt->node_seq.length; i > pos; i-- )
-- ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
-- }
--
-- /* Copy element and increase length */
-- ctxt->node_seq.buffer[pos] = *info;
-- ctxt->node_seq.length++;
-- }
--}
--
--/************************************************************************
-- * *
-- * Deprecated functions kept for compatibility *
-- * *
-- ************************************************************************/
--
--/*
-- * xmlCheckLanguageID
-- * @lang: pointer to the string value
-- *
-- * Checks that the value conforms to the LanguageID production:
-- *
-- * NOTE: this is somewhat deprecated, those productions were removed from
-- * the XML Second edition.
-- *
-- * [33] LanguageID ::= Langcode ('-' Subcode)*
-- * [34] Langcode ::= ISO639Code | IanaCode | UserCode
-- * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
-- * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
-- * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
-- * [38] Subcode ::= ([a-z] | [A-Z])+
-- *
-- * Returns 1 if correct 0 otherwise
-- **/
--int
--xmlCheckLanguageID(const xmlChar *lang) {
-- const xmlChar *cur = lang;
--
-- if (cur == NULL)
-- return(0);
-- if (((cur[0] == 'i') && (cur[1] == '-')) ||
-- ((cur[0] == 'I') && (cur[1] == '-'))) {
-- /*
-- * IANA code
-- */
-- cur += 2;
-- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
-- ((cur[0] >= 'a') && (cur[0] <= 'z')))
-- cur++;
-- } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
-- ((cur[0] == 'X') && (cur[1] == '-'))) {
-- /*
-- * User code
-- */
-- cur += 2;
-- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
-- ((cur[0] >= 'a') && (cur[0] <= 'z')))
-- cur++;
-- } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-- ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
-- /*
-- * ISO639
-- */
-- cur++;
-- if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-- ((cur[0] >= 'a') && (cur[0] <= 'z')))
-- cur++;
-- else
-- return(0);
-- } else
-- return(0);
-- while (cur[0] != 0) { /* non input consuming */
-- if (cur[0] != '-')
-- return(0);
-- cur++;
-- if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-- ((cur[0] >= 'a') && (cur[0] <= 'z')))
-- cur++;
-- else
-- return(0);
-- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
-- ((cur[0] >= 'a') && (cur[0] <= 'z')))
-- cur++;
-- }
-- return(1);
--}
--
--/**
-- * xmlDecodeEntities:
-- * @ctxt: the parser context
-- * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
-- * @len: the len to decode (in bytes !), -1 for no size limit
-- * @end: an end marker xmlChar, 0 if none
-- * @end2: an end marker xmlChar, 0 if none
-- * @end3: an end marker xmlChar, 0 if none
-- *
-- * This function is deprecated, we now always process entities content
-- * through xmlStringDecodeEntities
-- *
-- * TODO: remove it in next major release.
-- *
-- * [67] Reference ::= EntityRef | CharRef
-- *
-- * [69] PEReference ::= '%' Name ';'
-- *
-- * Returns A newly allocated string with the substitution done. The caller
-- * must deallocate it !
-- */
--xmlChar *
--xmlDecodeEntities(xmlParserCtxtPtr ctxt, int len, int what,
-- xmlChar end, xmlChar end2, xmlChar end3) {
--#if 0
-- xmlChar *buffer = NULL;
-- unsigned int buffer_size = 0;
-- unsigned int nbchars = 0;
--
-- xmlChar *current = NULL;
-- xmlEntityPtr ent;
-- unsigned int max = (unsigned int) len;
-- int c,l;
--#endif
--
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDecodeEntities() deprecated function reached\n");
-- deprecated = 1;
-- }
--
--#if 0
-- if (ctxt->depth > 40) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Detected entity reference loop\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->errNo = XML_ERR_ENTITY_LOOP;
-- return(NULL);
-- }
--
-- /*
-- * allocate a translation buffer.
-- */
-- buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
-- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-- if (buffer == NULL) {
-- perror("xmlDecodeEntities: malloc failed");
-- return(NULL);
-- }
--
-- /*
-- * Ok loop until we reach one of the ending char or a size limit.
-- */
-- GROW;
-- c = CUR_CHAR(l);
-- while ((nbchars < max) && (c != end) && /* NOTUSED */
-- (c != end2) && (c != end3)) {
-- GROW;
-- if (c == 0) break;
-- if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
-- int val = xmlParseCharRef(ctxt);
-- COPY_BUF(0,buffer,nbchars,val);
-- NEXTL(l);
-- } else if ((c == '&') && (ctxt->token != '&') &&
-- (what & XML_SUBSTITUTE_REF)) {
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "decoding Entity Reference\n");
-- ent = xmlParseEntityRef(ctxt);
-- if ((ent != NULL) &&
-- (ctxt->replaceEntities != 0)) {
-- current = ent->content;
-- while (*current != 0) { /* non input consuming loop */
-- buffer[nbchars++] = *current++;
-- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- }
-- } else if (ent != NULL) {
-- const xmlChar *cur = ent->name;
--
-- buffer[nbchars++] = '&';
-- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- while (*cur != 0) { /* non input consuming loop */
-- buffer[nbchars++] = *cur++;
-- }
-- buffer[nbchars++] = ';';
-- }
-- } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
-- /*
-- * a PEReference induce to switch the entity flow,
-- * we break here to flush the current set of chars
-- * parsed if any. We will be called back later.
-- */
-- if (xmlParserDebugEntities)
-- xmlGenericError(xmlGenericErrorContext,
-- "decoding PE Reference\n");
-- if (nbchars != 0) break;
--
-- xmlParsePEReference(ctxt);
--
-- /*
-- * Pop-up of finished entities.
-- */
-- while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
-- xmlPopInput(ctxt);
--
-- break;
-- } else {
-- COPY_BUF(l,buffer,nbchars,c);
-- NEXTL(l);
-- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
-- growBuffer(buffer);
-- }
-- }
-- c = CUR_CHAR(l);
-- }
-- buffer[nbchars++] = 0;
-- return(buffer);
--#endif
-- return(NULL);
--}
--
--/**
-- * xmlNamespaceParseNCName:
-- * @ctxt: an XML parser context
-- *
-- * parse an XML namespace name.
-- *
-- * TODO: this seems not in use anymore, the namespace handling is done on
-- * top of the SAX interfaces, i.e. not on raw input.
-- *
-- * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
-- *
-- * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
-- * CombiningChar | Extender
-- *
-- * Returns the namespace name or NULL
-- */
--
--xmlChar *
--xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt) {
--#if 0
-- xmlChar buf[XML_MAX_NAMELEN + 5];
-- int len = 0, l;
-- int cur = CUR_CHAR(l);
--#endif
--
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNamespaceParseNCName() deprecated function reached\n");
-- deprecated = 1;
-- }
--
--#if 0
-- /* load first the value of the char !!! */
-- GROW;
-- if (!IS_LETTER(cur) && (cur != '_')) return(NULL);
--
--xmlGenericError(xmlGenericErrorContext,
-- "xmlNamespaceParseNCName: reached loop 3\n");
-- while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) || /* NOT REACHED */
-- (cur == '.') || (cur == '-') ||
-- (cur == '_') ||
-- (IS_COMBINING(cur)) ||
-- (IS_EXTENDER(cur))) {
-- COPY_BUF(l,buf,len,cur);
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- if (len >= XML_MAX_NAMELEN) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNamespaceParseNCName: reached XML_MAX_NAMELEN limit\n");
-- while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||/* NOT REACHED */
-- (cur == '.') || (cur == '-') ||
-- (cur == '_') ||
-- (IS_COMBINING(cur)) ||
-- (IS_EXTENDER(cur))) {
-- NEXTL(l);
-- cur = CUR_CHAR(l);
-- }
-- break;
-- }
-- }
-- return(xmlStrndup(buf, len));
--#endif
-- return(NULL);
--}
--
--/**
-- * xmlNamespaceParseQName:
-- * @ctxt: an XML parser context
-- * @prefix: a xmlChar **
-- *
-- * TODO: this seems not in use anymore, the namespace handling is done on
-- * top of the SAX interfaces, i.e. not on raw input.
-- *
-- * parse an XML qualified name
-- *
-- * [NS 5] QName ::= (Prefix ':')? LocalPart
-- *
-- * [NS 6] Prefix ::= NCName
-- *
-- * [NS 7] LocalPart ::= NCName
-- *
-- * Returns the local part, and prefix is updated
-- * to get the Prefix if any.
-- */
--
--xmlChar *
--xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, xmlChar **prefix) {
--
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNamespaceParseQName() deprecated function reached\n");
-- deprecated = 1;
-- }
--
--#if 0
-- xmlChar *ret = NULL;
--
-- *prefix = NULL;
-- ret = xmlNamespaceParseNCName(ctxt);
-- if (RAW == ':') {
-- *prefix = ret;
-- NEXT;
-- ret = xmlNamespaceParseNCName(ctxt);
-- }
--
-- return(ret);
--#endif
-- return(NULL);
--}
--
--/**
-- * xmlNamespaceParseNSDef:
-- * @ctxt: an XML parser context
-- *
-- * parse a namespace prefix declaration
-- *
-- * TODO: this seems not in use anymore, the namespace handling is done on
-- * top of the SAX interfaces, i.e. not on raw input.
-- *
-- * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
-- *
-- * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
-- *
-- * Returns the namespace name
-- */
--
--xmlChar *
--xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNamespaceParseNSDef() deprecated function reached\n");
-- deprecated = 1;
-- }
-- return(NULL);
--#if 0
-- xmlChar *name = NULL;
--
-- if ((RAW == 'x') && (NXT(1) == 'm') &&
-- (NXT(2) == 'l') && (NXT(3) == 'n') &&
-- (NXT(4) == 's')) {
-- SKIP(5);
-- if (RAW == ':') {
-- NEXT;
-- name = xmlNamespaceParseNCName(ctxt);
-- }
-- }
-- return(name);
--#endif
--}
--
--/**
-- * xmlParseQuotedString:
-- * @ctxt: an XML parser context
-- *
-- * Parse and return a string between quotes or doublequotes
-- *
-- * TODO: Deprecated, to be removed at next drop of binary compatibility
-- *
-- * Returns the string parser or NULL.
-- */
--xmlChar *
--xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParseQuotedString() deprecated function reached\n");
-- deprecated = 1;
-- }
-- return(NULL);
--
--#if 0
-- xmlChar *buf = NULL;
-- int len = 0,l;
-- int size = XML_PARSER_BUFFER_SIZE;
-- int c;
--
-- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc of %d byte failed\n", size);
-- return(NULL);
-- }
--xmlGenericError(xmlGenericErrorContext,
-- "xmlParseQuotedString: reached loop 4\n");
-- if (RAW == '"') {
-- NEXT;
-- c = CUR_CHAR(l);
-- while (IS_CHAR(c) && (c != '"')) { /* NOTUSED */
-- if (len + 5 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- }
-- COPY_BUF(l,buf,len,c);
-- NEXTL(l);
-- c = CUR_CHAR(l);
-- }
-- if (c != '"') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "String not closed \"%.50s\"\n", buf);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- NEXT;
-- }
-- } else if (RAW == '\''){
-- NEXT;
-- c = CUR;
-- while (IS_CHAR(c) && (c != '\'')) { /* NOTUSED */
-- if (len + 1 >= size) {
-- size *= 2;
-- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc of %d byte failed\n", size);
-- return(NULL);
-- }
-- }
-- buf[len++] = c;
-- NEXT;
-- c = CUR;
-- }
-- if (RAW != '\'') {
-- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "String not closed \"%.50s\"\n", buf);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- } else {
-- NEXT;
-- }
-- }
-- return(buf);
--#endif
--}
--
--/**
-- * xmlParseNamespace:
-- * @ctxt: an XML parser context
-- *
-- * xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
-- *
-- * This is what the older xml-name Working Draft specified, a bunch of
-- * other stuff may still rely on it, so support is still here as
-- * if it was declared on the root of the Tree:-(
-- *
-- * TODO: remove from library
-- *
-- * To be removed at next drop of binary compatibility
-- */
--
--void
--xmlParseNamespace(xmlParserCtxtPtr ctxt) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParseNamespace() deprecated function reached\n");
-- deprecated = 1;
-- }
--
--#if 0
-- xmlChar *href = NULL;
-- xmlChar *prefix = NULL;
-- int garbage = 0;
--
-- /*
-- * We just skipped "namespace" or "xml:namespace"
-- */
-- SKIP_BLANKS;
--
--xmlGenericError(xmlGenericErrorContext,
-- "xmlParseNamespace: reached loop 5\n");
-- while (IS_CHAR(RAW) && (RAW != '>')) { /* NOT REACHED */
-- /*
-- * We can have "ns" or "prefix" attributes
-- * Old encoding as 'href' or 'AS' attributes is still supported
-- */
-- if ((RAW == 'n') && (NXT(1) == 's')) {
-- garbage = 0;
-- SKIP(2);
-- SKIP_BLANKS;
--
-- if (RAW != '=') continue;
-- NEXT;
-- SKIP_BLANKS;
--
-- href = xmlParseQuotedString(ctxt);
-- SKIP_BLANKS;
-- } else if ((RAW == 'h') && (NXT(1) == 'r') &&
-- (NXT(2) == 'e') && (NXT(3) == 'f')) {
-- garbage = 0;
-- SKIP(4);
-- SKIP_BLANKS;
--
-- if (RAW != '=') continue;
-- NEXT;
-- SKIP_BLANKS;
--
-- href = xmlParseQuotedString(ctxt);
-- SKIP_BLANKS;
-- } else if ((RAW == 'p') && (NXT(1) == 'r') &&
-- (NXT(2) == 'e') && (NXT(3) == 'f') &&
-- (NXT(4) == 'i') && (NXT(5) == 'x')) {
-- garbage = 0;
-- SKIP(6);
-- SKIP_BLANKS;
--
-- if (RAW != '=') continue;
-- NEXT;
-- SKIP_BLANKS;
--
-- prefix = xmlParseQuotedString(ctxt);
-- SKIP_BLANKS;
-- } else if ((RAW == 'A') && (NXT(1) == 'S')) {
-- garbage = 0;
-- SKIP(2);
-- SKIP_BLANKS;
--
-- if (RAW != '=') continue;
-- NEXT;
-- SKIP_BLANKS;
--
-- prefix = xmlParseQuotedString(ctxt);
-- SKIP_BLANKS;
-- } else if ((RAW == '?') && (NXT(1) == '>')) {
-- garbage = 0;
-- NEXT;
-- } else {
-- /*
-- * Found garbage when parsing the namespace
-- */
-- if (!garbage) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "xmlParseNamespace found garbage\n");
-- }
-- ctxt->errNo = XML_ERR_NS_DECL_ERROR;
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- NEXT;
-- }
-- }
--
-- MOVETO_ENDTAG(CUR_PTR);
-- NEXT;
--
-- /*
-- * Register the DTD.
-- if (href != NULL)
-- if ((ctxt->sax != NULL) && (ctxt->sax->globalNamespace != NULL))
-- ctxt->sax->globalNamespace(ctxt->userData, href, prefix);
-- */
--
-- if (prefix != NULL) xmlFree(prefix);
-- if (href != NULL) xmlFree(href);
--#endif
--}
--
--/**
-- * xmlScanName:
-- * @ctxt: an XML parser context
-- *
-- * Trickery: parse an XML name but without consuming the input flow
-- * Needed for rollback cases. Used only when parsing entities references.
-- *
-- * TODO: seems deprecated now, only used in the default part of
-- * xmlParserHandleReference
-- *
-- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-- * CombiningChar | Extender
-- *
-- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-- *
-- * [6] Names ::= Name (S Name)*
-- *
-- * Returns the Name parsed or NULL
-- */
--
--xmlChar *
--xmlScanName(xmlParserCtxtPtr ctxt) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlScanName() deprecated function reached\n");
-- deprecated = 1;
-- }
-- return(NULL);
--
--#if 0
-- xmlChar buf[XML_MAX_NAMELEN];
-- int len = 0;
--
-- GROW;
-- if (!IS_LETTER(RAW) && (RAW != '_') &&
-- (RAW != ':')) {
-- return(NULL);
-- }
--
--
-- while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || /* NOT REACHED */
-- (NXT(len) == '.') || (NXT(len) == '-') ||
-- (NXT(len) == '_') || (NXT(len) == ':') ||
-- (IS_COMBINING(NXT(len))) ||
-- (IS_EXTENDER(NXT(len)))) {
-- GROW;
-- buf[len] = NXT(len);
-- len++;
-- if (len >= XML_MAX_NAMELEN) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlScanName: reached XML_MAX_NAMELEN limit\n");
-- while ((IS_LETTER(NXT(len))) || /* NOT REACHED */
-- (IS_DIGIT(NXT(len))) ||
-- (NXT(len) == '.') || (NXT(len) == '-') ||
-- (NXT(len) == '_') || (NXT(len) == ':') ||
-- (IS_COMBINING(NXT(len))) ||
-- (IS_EXTENDER(NXT(len))))
-- len++;
-- break;
-- }
-- }
-- return(xmlStrndup(buf, len));
--#endif
--}
--
--/**
-- * xmlParserHandleReference:
-- * @ctxt: the parser context
-- *
-- * TODO: Remove, now deprecated ... the test is done directly in the
-- * content parsing
-- * routines.
-- *
-- * [67] Reference ::= EntityRef | CharRef
-- *
-- * [68] EntityRef ::= '&' Name ';'
-- *
-- * [ WFC: Entity Declared ]
-- * the Name given in the entity reference must match that in an entity
-- * declaration, except that well-formed documents need not declare any
-- * of the following entities: amp, lt, gt, apos, quot.
-- *
-- * [ WFC: Parsed Entity ]
-- * An entity reference must not contain the name of an unparsed entity
-- *
-- * [66] CharRef ::= '&#' [0-9]+ ';' |
-- * '&#x' [0-9a-fA-F]+ ';'
-- *
-- * A PEReference may have been detectect in the current input stream
-- * the handling is done accordingly to
-- * http://www.w3.org/TR/REC-xml#entproc
-- */
--void
--xmlParserHandleReference(xmlParserCtxtPtr ctxt) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserHandleReference() deprecated function reached\n");
-- deprecated = 1;
-- }
--
--#if 0
-- xmlParserInputPtr input;
-- xmlChar *name;
-- xmlEntityPtr ent = NULL;
--
-- if (ctxt->token != 0) {
-- return;
-- }
-- if (RAW != '&') return;
-- GROW;
-- if ((RAW == '&') && (NXT(1) == '#')) {
-- switch(ctxt->instate) {
-- case XML_PARSER_ENTITY_DECL:
-- case XML_PARSER_PI:
-- case XML_PARSER_CDATA_SECTION:
-- case XML_PARSER_COMMENT:
-- case XML_PARSER_SYSTEM_LITERAL:
-- /* we just ignore it there */
-- return;
-- case XML_PARSER_START_TAG:
-- return;
-- case XML_PARSER_END_TAG:
-- return;
-- case XML_PARSER_EOF:
-- ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "CharRef at EOF\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_PROLOG:
-- case XML_PARSER_START:
-- case XML_PARSER_MISC:
-- ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_EPILOG:
-- ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "CharRef in epilog!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_DTD:
-- ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "CharRef are forbiden in DTDs!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_ENTITY_VALUE:
-- /*
-- * NOTE: in the case of entity values, we don't do the
-- * substitution here since we need the literal
-- * entity value to be able to save the internal
-- * subset of the document.
-- * This will be handled by xmlStringDecodeEntities
-- */
-- return;
-- case XML_PARSER_CONTENT:
-- return;
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- /* ctxt->token = xmlParseCharRef(ctxt); */
-- return;
-- case XML_PARSER_IGNORE:
-- return;
-- }
-- return;
-- }
--
-- switch(ctxt->instate) {
-- case XML_PARSER_CDATA_SECTION:
-- return;
-- case XML_PARSER_PI:
-- case XML_PARSER_COMMENT:
-- case XML_PARSER_SYSTEM_LITERAL:
-- case XML_PARSER_CONTENT:
-- return;
-- case XML_PARSER_START_TAG:
-- return;
-- case XML_PARSER_END_TAG:
-- return;
-- case XML_PARSER_EOF:
-- ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Reference at EOF\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_PROLOG:
-- case XML_PARSER_START:
-- case XML_PARSER_MISC:
-- ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Reference in prolog!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_EPILOG:
-- ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Reference in epilog!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_ENTITY_VALUE:
-- /*
-- * NOTE: in the case of entity values, we don't do the
-- * substitution here since we need the literal
-- * entity value to be able to save the internal
-- * subset of the document.
-- * This will be handled by xmlStringDecodeEntities
-- */
-- return;
-- case XML_PARSER_ATTRIBUTE_VALUE:
-- /*
-- * NOTE: in the case of attributes values, we don't do the
-- * substitution here unless we are in a mode where
-- * the parser is explicitely asked to substitute
-- * entities. The SAX callback is called with values
-- * without entity substitution.
-- * This will then be handled by xmlStringDecodeEntities
-- */
-- return;
-- case XML_PARSER_ENTITY_DECL:
-- /*
-- * we just ignore it there
-- * the substitution will be done once the entity is referenced
-- */
-- return;
-- case XML_PARSER_DTD:
-- ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity references are forbiden in DTDs!\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- case XML_PARSER_IGNORE:
-- return;
-- }
--
--/* TODO: this seems not reached anymore .... Verify ... */
--xmlGenericError(xmlGenericErrorContext,
-- "Reached deprecated section in xmlParserHandleReference()\n");
--xmlGenericError(xmlGenericErrorContext,
-- "Please forward the document to Daniel.Veillard@w3.org\n");
--xmlGenericError(xmlGenericErrorContext,
-- "indicating the version: %s, thanks !\n", xmlParserVersion);
-- NEXT;
-- name = xmlScanName(ctxt);
-- if (name == NULL) {
-- ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "Entity reference: no name\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->token = '&';
-- return;
-- }
-- if (NXT(xmlStrlen(name)) != ';') {
-- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity reference: ';' expected\n");
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- ctxt->token = '&';
-- xmlFree(name);
-- return;
-- }
-- SKIP(xmlStrlen(name) + 1);
-- if (ctxt->sax != NULL) {
-- if (ctxt->sax->getEntity != NULL)
-- ent = ctxt->sax->getEntity(ctxt->userData, name);
-- }
--
-- /*
-- * [ WFC: Entity Declared ]
-- * the Name given in the entity reference must match that in an entity
-- * declaration, except that well-formed documents need not declare any
-- * of the following entities: amp, lt, gt, apos, quot.
-- */
-- if (ent == NULL)
-- ent = xmlGetPredefinedEntity(name);
-- if (ent == NULL) {
-- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity reference: entity %s not declared\n",
-- name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- xmlFree(name);
-- return;
-- }
--
-- /*
-- * [ WFC: Parsed Entity ]
-- * An entity reference must not contain the name of an unparsed entity
-- */
-- if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData,
-- "Entity reference to unparsed entity %s\n", name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- }
--
-- if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
-- ctxt->token = ent->content[0];
-- xmlFree(name);
-- return;
-- }
-- input = xmlNewEntityInputStream(ctxt, ent);
-- xmlPushInput(ctxt, input);
-- xmlFree(name);
--#endif
-- return;
--}
--
--/**
-- * xmlHandleEntity:
-- * @ctxt: an XML parser context
-- * @entity: an XML entity pointer.
-- *
-- * Default handling of defined entities, when should we define a new input
-- * stream ? When do we just handle that as a set of chars ?
-- *
-- * OBSOLETE: to be removed at some point.
-- */
--
--void
--xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlHandleEntity() deprecated function reached\n");
-- deprecated = 1;
-- }
--
--#if 0
-- int len;
-- xmlParserInputPtr input;
--
-- if (entity->content == NULL) {
-- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-- ctxt->sax->error(ctxt->userData, "xmlHandleEntity %s: content == NULL\n",
-- entity->name);
-- ctxt->wellFormed = 0;
-- ctxt->disableSAX = 1;
-- return;
-- }
-- len = xmlStrlen(entity->content);
-- if (len <= 2) goto handle_as_char;
--
-- /*
-- * Redefine its content as an input stream.
-- */
-- input = xmlNewEntityInputStream(ctxt, entity);
-- xmlPushInput(ctxt, input);
-- return;
--
--handle_as_char:
-- /*
-- * Just handle the content as a set of chars.
-- */
-- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-- (ctxt->sax->characters != NULL))
-- ctxt->sax->characters(ctxt->userData, entity->content, len);
--#endif
--}
--
--/**
-- * xmlNewGlobalNs:
-- * @doc: the document carrying the namespace
-- * @href: the URI associated
-- * @prefix: the prefix for the namespace
-- *
-- * Creation of a Namespace, the old way using PI and without scoping
-- * DEPRECATED !!!
-- * It now create a namespace on the root element of the document if found.
-- * Returns NULL this functionnality had been removed
-- */
--xmlNsPtr
--xmlNewGlobalNs(xmlDocPtr doc, const xmlChar *href, const xmlChar *prefix) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewGlobalNs() deprecated function reached\n");
-- deprecated = 1;
-- }
-- return(NULL);
--#if 0
-- xmlNodePtr root;
--
-- xmlNsPtr cur;
--
-- root = xmlDocGetRootElement(doc);
-- if (root != NULL)
-- return(xmlNewNs(root, href, prefix));
--
-- /*
-- * if there is no root element yet, create an old Namespace type
-- * and it will be moved to the root at save time.
-- */
-- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewGlobalNs : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNs));
-- cur->type = XML_GLOBAL_NAMESPACE;
--
-- if (href != NULL)
-- cur->href = xmlStrdup(href);
-- if (prefix != NULL)
-- cur->prefix = xmlStrdup(prefix);
--
-- /*
-- * Add it at the end to preserve parsing order ...
-- */
-- if (doc != NULL) {
-- if (doc->oldNs == NULL) {
-- doc->oldNs = cur;
-- } else {
-- xmlNsPtr prev = doc->oldNs;
--
-- while (prev->next != NULL) prev = prev->next;
-- prev->next = cur;
-- }
-- }
--
-- return(NULL);
--#endif
--}
--
--/**
-- * xmlUpgradeOldNs:
-- * @doc: a document pointer
-- *
-- * Upgrade old style Namespaces (PI) and move them to the root of the document.
-- * DEPRECATED
-- */
--void
--xmlUpgradeOldNs(xmlDocPtr doc) {
-- static int deprecated = 0;
-- if (!deprecated) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewGlobalNs() deprecated function reached\n");
-- deprecated = 1;
-- }
--#if 0
-- xmlNsPtr cur;
--
-- if ((doc == NULL) || (doc->oldNs == NULL)) return;
-- if (doc->children == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlUpgradeOldNs: failed no root !\n");
--#endif
-- return;
-- }
--
-- cur = doc->oldNs;
-- while (cur->next != NULL) {
-- cur->type = XML_LOCAL_NAMESPACE;
-- cur = cur->next;
-- }
-- cur->type = XML_LOCAL_NAMESPACE;
-- cur->next = doc->children->nsDef;
-- doc->children->nsDef = doc->oldNs;
-- doc->oldNs = NULL;
--#endif
--}
--
-diff -Nru libxml2-2.3.0/tree.c libxml2-2.3.0.new/tree.c
---- libxml2-2.3.0/tree.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/tree.c Thu Jan 1 01:00:00 1970
-@@ -1,6039 +0,0 @@
--/*
-- * tree.c : implemetation of access function for an XML tree.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- *
-- * 14 Nov 2000 ht - Changed the name of function xmlBufferWriteChar under VMS
-- * as it was similar to xmlBufferWriteCHAR when compiling without case
-- * sensitivity.
-- *
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h> /* for memset() only ! */
--
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_ZLIB_H
--#include <zlib.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/entities.h>
--#include <libxml/valid.h>
--#include <libxml/xmlerror.h>
--
--xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 };
--xmlChar xmlStringTextNoenc[] =
-- { 't', 'e', 'x', 't', 'n', 'o', 'e', 'n', 'c', 0 };
--xmlChar xmlStringComment[] = { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
--int oldXMLWDcompatibility = 0;
--int xmlIndentTreeOutput = 0;
--xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
--
--static int xmlCompressMode = 0;
--static int xmlCheckDTD = 1;
--int xmlSaveNoEmptyTags = 0;
--
--#define IS_BLANK(c) \
-- (((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
--
--#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) { \
-- xmlNodePtr ulccur = (n)->children; \
-- if (ulccur == NULL) { \
-- (n)->last = NULL; \
-- } else { \
-- while (ulccur->next != NULL) { \
-- ulccur->parent = (n); \
-- ulccur = ulccur->next; \
-- } \
-- ulccur->parent = (n); \
-- (n)->last = ulccur; \
--}}
--
--/* #define DEBUG_BUFFER */
--/* #define DEBUG_TREE */
--
--/************************************************************************
-- * *
-- * Allocation and deallocation of basic structures *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlSetBufferAllocationScheme:
-- * @scheme: allocation method to use
-- *
-- * Set the buffer allocation method. Types are
-- * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
-- * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
-- * improves performance
-- */
--void
--xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
-- xmlBufferAllocScheme = scheme;
--}
--
--/**
-- * xmlGetBufferAllocationScheme:
-- *
-- * Types are
-- * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
-- * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
-- * improves performance
-- *
-- * Returns the current allocation scheme
-- */
--xmlBufferAllocationScheme
--xmlGetBufferAllocationScheme() {
-- return xmlBufferAllocScheme;
--}
--
--/**
-- * xmlNewNs:
-- * @node: the element carrying the namespace
-- * @href: the URI associated
-- * @prefix: the prefix for the namespace
-- *
-- * Creation of a new Namespace. This function will refuse to create
-- * a namespace with a similar prefix than an existing one present on this
-- * node.
-- * We use href==NULL in the case of an element creation where the namespace
-- * was not defined.
-- * Returns returns a new namespace pointer or NULL
-- */
--xmlNsPtr
--xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
-- xmlNsPtr cur;
--
-- if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
-- return(NULL);
--
-- /*
-- * Allocate a new Namespace and fill the fields.
-- */
-- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewNs : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNs));
-- cur->type = XML_LOCAL_NAMESPACE;
--
-- if (href != NULL)
-- cur->href = xmlStrdup(href);
-- if (prefix != NULL)
-- cur->prefix = xmlStrdup(prefix);
--
-- /*
-- * Add it at the end to preserve parsing order ...
-- * and checks for existing use of the prefix
-- */
-- if (node != NULL) {
-- if (node->nsDef == NULL) {
-- node->nsDef = cur;
-- } else {
-- xmlNsPtr prev = node->nsDef;
--
-- if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
-- (xmlStrEqual(prev->prefix, cur->prefix))) {
-- xmlFreeNs(cur);
-- return(NULL);
-- }
-- while (prev->next != NULL) {
-- prev = prev->next;
-- if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
-- (xmlStrEqual(prev->prefix, cur->prefix))) {
-- xmlFreeNs(cur);
-- return(NULL);
-- }
-- }
-- prev->next = cur;
-- }
-- }
-- return(cur);
--}
--
--/**
-- * xmlSetNs:
-- * @node: a node in the document
-- * @ns: a namespace pointer
-- *
-- * Associate a namespace to a node, a posteriori.
-- */
--void
--xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
-- if (node == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSetNs: node == NULL\n");
--#endif
-- return;
-- }
-- node->ns = ns;
--}
--
--/**
-- * xmlFreeNs:
-- * @cur: the namespace pointer
-- *
-- * Free up the structures associated to a namespace
-- */
--void
--xmlFreeNs(xmlNsPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeNs : ns == NULL\n");
--#endif
-- return;
-- }
-- if (cur->href != NULL) xmlFree((char *) cur->href);
-- if (cur->prefix != NULL) xmlFree((char *) cur->prefix);
-- memset(cur, -1, sizeof(xmlNs));
-- xmlFree(cur);
--}
--
--/**
-- * xmlFreeNsList:
-- * @cur: the first namespace pointer
-- *
-- * Free up all the structures associated to the chained namespaces.
-- */
--void
--xmlFreeNsList(xmlNsPtr cur) {
-- xmlNsPtr next;
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeNsList : ns == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- next = cur->next;
-- xmlFreeNs(cur);
-- cur = next;
-- }
--}
--
--/**
-- * xmlNewDtd:
-- * @doc: the document pointer
-- * @name: the DTD name
-- * @ExternalID: the external ID
-- * @SystemID: the system ID
-- *
-- * Creation of a new DTD for the external subset. To create an
-- * internal subset, use xmlCreateIntSubset().
-- *
-- * Returns a pointer to the new DTD structure
-- */
--xmlDtdPtr
--xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
-- const xmlChar *ExternalID, const xmlChar *SystemID) {
-- xmlDtdPtr cur;
--
-- if ((doc != NULL) && (doc->extSubset != NULL)) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewDtd(%s): document %s already have a DTD %s\n",
-- /* !!! */ (char *) name, doc->name,
-- /* !!! */ (char *)doc->extSubset->name);
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new DTD and fill the fields.
-- */
-- cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewDtd : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0 , sizeof(xmlDtd));
-- cur->type = XML_DTD_NODE;
--
-- if (name != NULL)
-- cur->name = xmlStrdup(name);
-- if (ExternalID != NULL)
-- cur->ExternalID = xmlStrdup(ExternalID);
-- if (SystemID != NULL)
-- cur->SystemID = xmlStrdup(SystemID);
-- if (doc != NULL)
-- doc->extSubset = cur;
-- cur->doc = doc;
--
-- return(cur);
--}
--
--/**
-- * xmlGetIntSubset:
-- * @doc: the document pointer
-- *
-- * Get the internal subset of a document
-- * Returns a pointer to the DTD structure or NULL if not found
-- */
--
--xmlDtdPtr
--xmlGetIntSubset(xmlDocPtr doc) {
-- xmlNodePtr cur;
--
-- if (doc == NULL)
-- return(NULL);
-- cur = doc->children;
-- while (cur != NULL) {
-- if (cur->type == XML_DTD_NODE)
-- return((xmlDtdPtr) cur);
-- cur = cur->next;
-- }
-- return((xmlDtdPtr) doc->intSubset);
--}
--
--/**
-- * xmlCreateIntSubset:
-- * @doc: the document pointer
-- * @name: the DTD name
-- * @ExternalID: the external ID
-- * @SystemID: the system ID
-- *
-- * Create the internal subset of a document
-- * Returns a pointer to the new DTD structure
-- */
--xmlDtdPtr
--xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
-- const xmlChar *ExternalID, const xmlChar *SystemID) {
-- xmlDtdPtr cur;
--
-- if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
--
-- "xmlCreateIntSubset(): document %s already have an internal subset\n",
-- doc->name);
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new DTD and fill the fields.
-- */
-- cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewDtd : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlDtd));
-- cur->type = XML_DTD_NODE;
--
-- if (name != NULL)
-- cur->name = xmlStrdup(name);
-- if (ExternalID != NULL)
-- cur->ExternalID = xmlStrdup(ExternalID);
-- if (SystemID != NULL)
-- cur->SystemID = xmlStrdup(SystemID);
-- if (doc != NULL) {
-- doc->intSubset = cur;
-- cur->parent = doc;
-- cur->doc = doc;
-- if (doc->children == NULL) {
-- doc->children = (xmlNodePtr) cur;
-- doc->last = (xmlNodePtr) cur;
-- } else {
-- xmlNodePtr prev;
--
-- if (doc->type == XML_HTML_DOCUMENT_NODE) {
-- prev = doc->children;
-- prev->prev = (xmlNodePtr) cur;
-- cur->next = prev;
-- doc->children = (xmlNodePtr) cur;
-- } else {
-- prev = doc->last;
-- prev->next = (xmlNodePtr) cur;
-- cur->prev = prev;
-- doc->last = (xmlNodePtr) cur;
-- }
-- }
-- }
-- return(cur);
--}
--
--/**
-- * xmlFreeDtd:
-- * @cur: the DTD structure to free up
-- *
-- * Free a DTD structure.
-- */
--void
--xmlFreeDtd(xmlDtdPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeDtd : DTD == NULL\n");
--#endif
-- return;
-- }
-- if (cur->children != NULL) {
-- xmlNodePtr next, c = cur->children;
--
-- /*
-- * Cleanup all the DTD comments they are not in the Dtd
-- * indexes.
-- */
-- while (c != NULL) {
-- next = c->next;
-- if (c->type == XML_COMMENT_NODE) {
-- xmlUnlinkNode(c);
-- xmlFreeNode(c);
-- }
-- c = next;
-- }
-- }
-- if (cur->name != NULL) xmlFree((char *) cur->name);
-- if (cur->SystemID != NULL) xmlFree((char *) cur->SystemID);
-- if (cur->ExternalID != NULL) xmlFree((char *) cur->ExternalID);
-- /* TODO !!! */
-- if (cur->notations != NULL)
-- xmlFreeNotationTable((xmlNotationTablePtr) cur->notations);
--
-- if (cur->elements != NULL)
-- xmlFreeElementTable((xmlElementTablePtr) cur->elements);
-- if (cur->attributes != NULL)
-- xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes);
-- if (cur->entities != NULL)
-- xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
-- if (cur->pentities != NULL)
-- xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
--
-- memset(cur, -1, sizeof(xmlDtd));
-- xmlFree(cur);
--}
--
--/**
-- * xmlNewDoc:
-- * @version: xmlChar string giving the version of XML "1.0"
-- *
-- * Returns a new document
-- */
--xmlDocPtr
--xmlNewDoc(const xmlChar *version) {
-- xmlDocPtr cur;
--
-- if (version == NULL)
-- version = (const xmlChar *) "1.0";
--
-- /*
-- * Allocate a new document and fill the fields.
-- */
-- cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewDoc : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlDoc));
-- cur->type = XML_DOCUMENT_NODE;
--
-- cur->version = xmlStrdup(version);
-- cur->standalone = -1;
-- cur->compression = -1; /* not initialized */
-- cur->doc = cur;
-- return(cur);
--}
--
--/**
-- * xmlFreeDoc:
-- * @cur: pointer to the document
-- * @:
-- *
-- * Free up all the structures used by a document, tree included.
-- */
--void
--xmlFreeDoc(xmlDocPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeDoc : document == NULL\n");
--#endif
-- return;
-- }
-- if (cur->version != NULL) xmlFree((char *) cur->version);
-- if (cur->name != NULL) xmlFree((char *) cur->name);
-- if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
-- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-- if (cur->intSubset != NULL) xmlFreeDtd(cur->intSubset);
-- if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset);
-- if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
-- if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
-- if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
-- if (cur->URL != NULL) xmlFree((char *) cur->URL);
-- memset(cur, -1, sizeof(xmlDoc));
-- xmlFree(cur);
--}
--
--/**
-- * xmlStringLenGetNodeList:
-- * @doc: the document
-- * @value: the value of the text
-- * @len: the length of the string value
-- *
-- * Parse the value string and build the node list associated. Should
-- * produce a flat tree with only TEXTs and ENTITY_REFs.
-- * Returns a pointer to the first child
-- */
--xmlNodePtr
--xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
-- xmlNodePtr ret = NULL, last = NULL;
-- xmlNodePtr node;
-- xmlChar *val;
-- const xmlChar *cur = value;
-- const xmlChar *q;
-- xmlEntityPtr ent;
--
-- if (value == NULL) return(NULL);
--
-- q = cur;
-- while ((*cur != 0) && (cur - value < len)) {
-- if (*cur == '&') {
-- /*
-- * Save the current text.
-- */
-- if (cur != q) {
-- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-- xmlNodeAddContentLen(last, q, cur - q);
-- } else {
-- node = xmlNewDocTextLen(doc, q, cur - q);
-- if (node == NULL) return(ret);
-- if (last == NULL)
-- last = ret = node;
-- else {
-- last->next = node;
-- node->prev = last;
-- last = node;
-- }
-- }
-- }
-- /*
-- * Read the entity string
-- */
-- cur++;
-- q = cur;
-- while ((*cur != 0) && (cur - value < len) && (*cur != ';')) cur++;
-- if ((*cur == 0) || (cur - value >= len)) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlStringLenGetNodeList: unterminated entity %30s\n", q);
--#endif
-- return(ret);
-- }
-- if (cur != q) {
-- /*
-- * Predefined entities don't generate nodes
-- */
-- val = xmlStrndup(q, cur - q);
-- ent = xmlGetDocEntity(doc, val);
-- if ((ent != NULL) &&
-- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-- if (last == NULL) {
-- node = xmlNewDocText(doc, ent->content);
-- last = ret = node;
-- } else
-- xmlNodeAddContent(last, ent->content);
--
-- } else {
-- /*
-- * Create a new REFERENCE_REF node
-- */
-- node = xmlNewReference(doc, val);
-- if (node == NULL) {
-- if (val != NULL) xmlFree(val);
-- return(ret);
-- }
-- if (last == NULL)
-- last = ret = node;
-- else {
-- last->next = node;
-- node->prev = last;
-- last = node;
-- }
-- }
-- xmlFree(val);
-- }
-- cur++;
-- q = cur;
-- } else
-- cur++;
-- }
-- if (cur != q) {
-- /*
-- * Handle the last piece of text.
-- */
-- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-- xmlNodeAddContentLen(last, q, cur - q);
-- } else {
-- node = xmlNewDocTextLen(doc, q, cur - q);
-- if (node == NULL) return(ret);
-- if (last == NULL)
-- last = ret = node;
-- else {
-- last->next = node;
-- node->prev = last;
-- last = node;
-- }
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlStringGetNodeList:
-- * @doc: the document
-- * @value: the value of the attribute
-- *
-- * Parse the value string and build the node list associated. Should
-- * produce a flat tree with only TEXTs and ENTITY_REFs.
-- * Returns a pointer to the first child
-- */
--xmlNodePtr
--xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
-- xmlNodePtr ret = NULL, last = NULL;
-- xmlNodePtr node;
-- xmlChar *val;
-- const xmlChar *cur = value;
-- const xmlChar *q;
-- xmlEntityPtr ent;
--
-- if (value == NULL) return(NULL);
--
-- q = cur;
-- while (*cur != 0) {
-- if (*cur == '&') {
-- /*
-- * Save the current text.
-- */
-- if (cur != q) {
-- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-- xmlNodeAddContentLen(last, q, cur - q);
-- } else {
-- node = xmlNewDocTextLen(doc, q, cur - q);
-- if (node == NULL) return(ret);
-- if (last == NULL)
-- last = ret = node;
-- else {
-- last->next = node;
-- node->prev = last;
-- last = node;
-- }
-- }
-- }
-- /*
-- * Read the entity string
-- */
-- cur++;
-- q = cur;
-- while ((*cur != 0) && (*cur != ';')) cur++;
-- if (*cur == 0) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlStringGetNodeList: unterminated entity %30s\n", q);
--#endif
-- return(ret);
-- }
-- if (cur != q) {
-- /*
-- * Predefined entities don't generate nodes
-- */
-- val = xmlStrndup(q, cur - q);
-- ent = xmlGetDocEntity(doc, val);
-- if ((ent != NULL) &&
-- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-- if (last == NULL) {
-- node = xmlNewDocText(doc, ent->content);
-- last = ret = node;
-- } else
-- xmlNodeAddContent(last, ent->content);
--
-- } else {
-- /*
-- * Create a new REFERENCE_REF node
-- */
-- node = xmlNewReference(doc, val);
-- if (node == NULL) {
-- if (val != NULL) xmlFree(val);
-- return(ret);
-- }
-- if (last == NULL)
-- last = ret = node;
-- else {
-- last->next = node;
-- node->prev = last;
-- last = node;
-- }
-- }
-- xmlFree(val);
-- }
-- cur++;
-- q = cur;
-- } else
-- cur++;
-- }
-- if (cur != q) {
-- /*
-- * Handle the last piece of text.
-- */
-- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
-- xmlNodeAddContentLen(last, q, cur - q);
-- } else {
-- node = xmlNewDocTextLen(doc, q, cur - q);
-- if (node == NULL) return(ret);
-- if (last == NULL)
-- last = ret = node;
-- else {
-- last->next = node;
-- node->prev = last;
-- last = node;
-- }
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlNodeListGetString:
-- * @doc: the document
-- * @list: a Node list
-- * @inLine: should we replace entity contents or show their external form
-- *
-- * Returns the string equivalent to the text contained in the Node list
-- * made of TEXTs and ENTITY_REFs
-- * Returns a pointer to the string copy, the calller must free it.
-- */
--xmlChar *
--xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
-- xmlNodePtr node = list;
-- xmlChar *ret = NULL;
-- xmlEntityPtr ent;
--
-- if (list == NULL) return(NULL);
--
-- while (node != NULL) {
-- if ((node->type == XML_TEXT_NODE) ||
-- (node->type == XML_CDATA_SECTION_NODE)) {
-- if (inLine) {
--#ifndef XML_USE_BUFFER_CONTENT
-- ret = xmlStrcat(ret, node->content);
--#else
-- ret = xmlStrcat(ret, xmlBufferContent(node->content));
--#endif
-- } else {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeEntitiesReentrant(doc, node->content);
--#else
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(node->content));
--#endif
-- if (buffer != NULL) {
-- ret = xmlStrcat(ret, buffer);
-- xmlFree(buffer);
-- }
-- }
-- } else if (node->type == XML_ENTITY_REF_NODE) {
-- if (inLine) {
-- ent = xmlGetDocEntity(doc, node->name);
-- if (ent != NULL)
-- ret = xmlStrcat(ret, ent->content);
-- else {
--#ifndef XML_USE_BUFFER_CONTENT
-- ret = xmlStrcat(ret, node->content);
--#else
-- ret = xmlStrcat(ret, xmlBufferContent(node->content));
--#endif
-- }
-- } else {
-- xmlChar buf[2];
-- buf[0] = '&'; buf[1] = 0;
-- ret = xmlStrncat(ret, buf, 1);
-- ret = xmlStrcat(ret, node->name);
-- buf[0] = ';'; buf[1] = 0;
-- ret = xmlStrncat(ret, buf, 1);
-- }
-- }
--#if 0
-- else {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlGetNodeListString : invalide node type %d\n",
-- node->type);
-- }
--#endif
-- node = node->next;
-- }
-- return(ret);
--}
--
--/**
-- * xmlNodeListGetRawString:
-- * @doc: the document
-- * @list: a Node list
-- * @inLine: should we replace entity contents or show their external form
-- *
-- * Returns the string equivalent to the text contained in the Node list
-- * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
-- * this function doesn't do any character encoding handling.
-- *
-- * Returns a pointer to the string copy, the calller must free it.
-- */
--xmlChar *
--xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
-- xmlNodePtr node = list;
-- xmlChar *ret = NULL;
-- xmlEntityPtr ent;
--
-- if (list == NULL) return(NULL);
--
-- while (node != NULL) {
-- if (node->type == XML_TEXT_NODE) {
-- if (inLine) {
--#ifndef XML_USE_BUFFER_CONTENT
-- ret = xmlStrcat(ret, node->content);
--#else
-- ret = xmlStrcat(ret, xmlBufferContent(node->content));
--#endif
-- } else {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeSpecialChars(doc, node->content);
--#else
-- buffer = xmlEncodeSpecialChars(doc,
-- xmlBufferContent(node->content));
--#endif
-- if (buffer != NULL) {
-- ret = xmlStrcat(ret, buffer);
-- xmlFree(buffer);
-- }
-- }
-- } else if (node->type == XML_ENTITY_REF_NODE) {
-- if (inLine) {
-- ent = xmlGetDocEntity(doc, node->name);
-- if (ent != NULL)
-- ret = xmlStrcat(ret, ent->content);
-- else {
--#ifndef XML_USE_BUFFER_CONTENT
-- ret = xmlStrcat(ret, node->content);
--#else
-- ret = xmlStrcat(ret, xmlBufferContent(node->content));
--#endif
-- }
-- } else {
-- xmlChar buf[2];
-- buf[0] = '&'; buf[1] = 0;
-- ret = xmlStrncat(ret, buf, 1);
-- ret = xmlStrcat(ret, node->name);
-- buf[0] = ';'; buf[1] = 0;
-- ret = xmlStrncat(ret, buf, 1);
-- }
-- }
--#if 0
-- else {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlGetNodeListString : invalide node type %d\n",
-- node->type);
-- }
--#endif
-- node = node->next;
-- }
-- return(ret);
--}
--
--/**
-- * xmlNewProp:
-- * @node: the holding node
-- * @name: the name of the attribute
-- * @value: the value of the attribute
-- *
-- * Create a new property carried by a node.
-- * Returns a pointer to the attribute
-- */
--xmlAttrPtr
--xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
-- xmlAttrPtr cur;
-- xmlDocPtr doc = NULL;
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewProp : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new property and fill the fields.
-- */
-- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewProp : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlAttr));
-- cur->type = XML_ATTRIBUTE_NODE;
--
-- cur->parent = node;
-- if (node != NULL) {
-- doc = node->doc;
-- cur->doc = doc;
-- }
-- cur->name = xmlStrdup(name);
-- if (value != NULL) {
-- xmlChar *buffer;
-- xmlNodePtr tmp;
--
-- buffer = xmlEncodeEntitiesReentrant(doc, value);
-- cur->children = xmlStringGetNodeList(doc, buffer);
-- cur->last = NULL;
-- tmp = cur->children;
-- while (tmp != NULL) {
-- tmp->parent = (xmlNodePtr) cur;
-- tmp->doc = doc;
-- if (tmp->next == NULL)
-- cur->last = tmp;
-- tmp = tmp->next;
-- }
-- xmlFree(buffer);
-- }
--
-- /*
-- * Add it at the end to preserve parsing order ...
-- */
-- if (node != NULL) {
-- if (node->properties == NULL) {
-- node->properties = cur;
-- } else {
-- xmlAttrPtr prev = node->properties;
--
-- while (prev->next != NULL) prev = prev->next;
-- prev->next = cur;
-- cur->prev = prev;
-- }
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewNsProp:
-- * @node: the holding node
-- * @ns: the namespace
-- * @name: the name of the attribute
-- * @value: the value of the attribute
-- *
-- * Create a new property tagged with a namespace and carried by a node.
-- * Returns a pointer to the attribute
-- */
--xmlAttrPtr
--xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
-- const xmlChar *value) {
-- xmlAttrPtr cur;
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewProp : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new property and fill the fields.
-- */
-- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewProp : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlAttr));
-- cur->type = XML_ATTRIBUTE_NODE;
--
-- cur->parent = node;
-- if (node != NULL)
-- cur->doc = node->doc;
-- cur->ns = ns;
-- cur->name = xmlStrdup(name);
-- if (value != NULL) {
-- xmlChar *buffer;
-- xmlNodePtr tmp;
--
-- buffer = xmlEncodeEntitiesReentrant(node->doc, value);
-- cur->children = xmlStringGetNodeList(node->doc, buffer);
-- cur->last = NULL;
-- tmp = cur->children;
-- while (tmp != NULL) {
-- tmp->parent = (xmlNodePtr) cur;
-- if (tmp->next == NULL)
-- cur->last = tmp;
-- tmp = tmp->next;
-- }
-- xmlFree(buffer);
-- }
--
-- /*
-- * Add it at the end to preserve parsing order ...
-- */
-- if (node != NULL) {
-- if (node->properties == NULL) {
-- node->properties = cur;
-- } else {
-- xmlAttrPtr prev = node->properties;
--
-- while (prev->next != NULL) prev = prev->next;
-- prev->next = cur;
-- cur->prev = prev;
-- }
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewDocProp:
-- * @doc: the document
-- * @name: the name of the attribute
-- * @value: the value of the attribute
-- *
-- * Create a new property carried by a document.
-- * Returns a pointer to the attribute
-- */
--xmlAttrPtr
--xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
-- xmlAttrPtr cur;
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewProp : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new property and fill the fields.
-- */
-- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewProp : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlAttr));
-- cur->type = XML_ATTRIBUTE_NODE;
--
-- cur->name = xmlStrdup(name);
-- cur->doc = doc;
-- if (value != NULL) {
-- xmlNodePtr tmp;
--
-- cur->children = xmlStringGetNodeList(doc, value);
-- cur->last = NULL;
--
-- tmp = cur->children;
-- while (tmp != NULL) {
-- tmp->parent = (xmlNodePtr) cur;
-- if (tmp->next == NULL)
-- cur->last = tmp;
-- tmp = tmp->next;
-- }
-- }
-- return(cur);
--}
--
--/**
-- * xmlFreePropList:
-- * @cur: the first property in the list
-- *
-- * Free a property and all its siblings, all the children are freed too.
-- */
--void
--xmlFreePropList(xmlAttrPtr cur) {
-- xmlAttrPtr next;
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreePropList : property == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- next = cur->next;
-- xmlFreeProp(cur);
-- cur = next;
-- }
--}
--
--/**
-- * xmlFreeProp:
-- * @cur: an attribute
-- *
-- * Free one attribute, all the content is freed too
-- */
--void
--xmlFreeProp(xmlAttrPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeProp : property == NULL\n");
--#endif
-- return;
-- }
-- /* Check for ID removal -> leading to invalid references ! */
-- if ((cur->parent != NULL) &&
-- (xmlIsID(cur->parent->doc, cur->parent, cur)))
-- xmlRemoveID(cur->parent->doc, cur);
-- if (cur->name != NULL) xmlFree((char *) cur->name);
-- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-- memset(cur, -1, sizeof(xmlAttr));
-- xmlFree(cur);
--}
--
--/**
-- * xmlRemoveProp:
-- * @cur: an attribute
-- *
-- * Unlink and free one attribute, all the content is freed too
-- * Note this doesn't work for namespace definition attributes
-- *
-- * Returns 0 if success and -1 in case of error.
-- */
--int
--xmlRemoveProp(xmlAttrPtr cur) {
-- xmlAttrPtr tmp;
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlRemoveProp : cur == NULL\n");
--#endif
-- return(-1);
-- }
-- if (cur->parent == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlRemoveProp : cur->parent == NULL\n");
--#endif
-- return(-1);
-- }
-- tmp = cur->parent->properties;
-- if (tmp == cur) {
-- cur->parent->properties = cur->next;
-- xmlFreeProp(cur);
-- return(0);
-- }
-- while (tmp != NULL) {
-- if (tmp->next == cur) {
-- tmp->next = cur->next;
-- if (tmp->next != NULL)
-- tmp->next->prev = tmp;
-- xmlFreeProp(cur);
-- return(0);
-- }
-- tmp = tmp->next;
-- }
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlRemoveProp : attribute not owned by its node\n");
--#endif
-- return(-1);
--}
--
--/**
-- * xmlNewPI:
-- * @name: the processing instruction name
-- * @content: the PI content
-- *
-- * Creation of a processing instruction element.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewPI(const xmlChar *name, const xmlChar *content) {
-- xmlNodePtr cur;
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewPI : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewPI : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_PI_NODE;
--
-- cur->name = xmlStrdup(name);
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrdup(content);
--#else
-- cur->content = xmlBufferCreateSize(0);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, -1);
--#endif
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewNode:
-- * @ns: namespace if any
-- * @name: the node name
-- *
-- * Creation of a new node element. @ns is optionnal (NULL).
-- *
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewNode(xmlNsPtr ns, const xmlChar *name) {
-- xmlNodePtr cur;
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewNode : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewNode : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_ELEMENT_NODE;
--
-- cur->name = xmlStrdup(name);
-- cur->ns = ns;
-- return(cur);
--}
--
--/**
-- * xmlNewDocNode:
-- * @doc: the document
-- * @ns: namespace if any
-- * @name: the node name
-- * @content: the XML text content if any
-- *
-- * Creation of a new node element within a document. @ns and @content
-- * are optionnal (NULL).
-- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
-- * references, but XML special chars need to be escaped first by using
-- * xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
-- * need entities support.
-- *
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
-- const xmlChar *name, const xmlChar *content) {
-- xmlNodePtr cur;
--
-- cur = xmlNewNode(ns, name);
-- if (cur != NULL) {
-- cur->doc = doc;
-- if (content != NULL) {
-- cur->children = xmlStringGetNodeList(doc, content);
-- UPDATE_LAST_CHILD_AND_PARENT(cur)
-- }
-- }
-- return(cur);
--}
--
--
--/**
-- * xmlNewDocRawNode:
-- * @doc: the document
-- * @ns: namespace if any
-- * @name: the node name
-- * @content: the text content if any
-- *
-- * Creation of a new node element within a document. @ns and @content
-- * are optionnal (NULL).
-- *
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
-- const xmlChar *name, const xmlChar *content) {
-- xmlNodePtr cur;
--
-- cur = xmlNewNode(ns, name);
-- if (cur != NULL) {
-- cur->doc = doc;
-- if (content != NULL) {
-- cur->children = xmlNewDocText(doc, content);
-- UPDATE_LAST_CHILD_AND_PARENT(cur)
-- }
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewDocFragment:
-- * @doc: the document owning the fragment
-- *
-- * Creation of a new Fragment node.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewDocFragment(xmlDocPtr doc) {
-- xmlNodePtr cur;
--
-- /*
-- * Allocate a new DocumentFragment node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewDocFragment : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_DOCUMENT_FRAG_NODE;
--
-- cur->doc = doc;
-- return(cur);
--}
--
--/**
-- * xmlNewText:
-- * @content: the text content
-- *
-- * Creation of a new text node.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewText(const xmlChar *content) {
-- xmlNodePtr cur;
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewText : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_TEXT_NODE;
--
-- cur->name = xmlStringText;
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrdup(content);
--#else
-- cur->content = xmlBufferCreateSize(0);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, -1);
--#endif
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewTextChild:
-- * @parent: the parent node
-- * @ns: a namespace if any
-- * @name: the name of the child
-- * @content: the text content of the child if any.
-- *
-- * Creation of a new child element, added at the end of @parent children list.
-- * @ns and @content parameters are optionnal (NULL). If content is non NULL,
-- * a child TEXT node will be created containing the string content.
-- *
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
-- const xmlChar *name, const xmlChar *content) {
-- xmlNodePtr cur, prev;
--
-- if (parent == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewTextChild : parent == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewTextChild : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new node
-- */
-- if (ns == NULL)
-- cur = xmlNewDocRawNode(parent->doc, parent->ns, name, content);
-- else
-- cur = xmlNewDocRawNode(parent->doc, ns, name, content);
-- if (cur == NULL) return(NULL);
--
-- /*
-- * add the new element at the end of the children list.
-- */
-- cur->type = XML_ELEMENT_NODE;
-- cur->parent = parent;
-- cur->doc = parent->doc;
-- if (parent->children == NULL) {
-- parent->children = cur;
-- parent->last = cur;
-- } else {
-- prev = parent->last;
-- prev->next = cur;
-- cur->prev = prev;
-- parent->last = cur;
-- }
--
-- return(cur);
--}
--
--/**
-- * xmlNewCharRef:
-- * @doc: the document
-- * @name: the char ref string, starting with # or "&# ... ;"
-- *
-- * Creation of a new character reference node.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
-- xmlNodePtr cur;
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewText : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_ENTITY_REF_NODE;
--
-- cur->doc = doc;
-- if (name[0] == '&') {
-- int len;
-- name++;
-- len = xmlStrlen(name);
-- if (name[len - 1] == ';')
-- cur->name = xmlStrndup(name, len - 1);
-- else
-- cur->name = xmlStrndup(name, len);
-- } else
-- cur->name = xmlStrdup(name);
-- return(cur);
--}
--
--/**
-- * xmlNewReference:
-- * @doc: the document
-- * @name: the reference name, or the reference string with & and ;
-- *
-- * Creation of a new reference node.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
-- xmlNodePtr cur;
-- xmlEntityPtr ent;
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewText : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_ENTITY_REF_NODE;
--
-- cur->doc = doc;
-- if (name[0] == '&') {
-- int len;
-- name++;
-- len = xmlStrlen(name);
-- if (name[len - 1] == ';')
-- cur->name = xmlStrndup(name, len - 1);
-- else
-- cur->name = xmlStrndup(name, len);
-- } else
-- cur->name = xmlStrdup(name);
--
-- ent = xmlGetDocEntity(doc, cur->name);
-- if (ent != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = ent->content;
--#else
-- /*
-- * CJN 11.18.99 this might be a problem, since the xmlBuffer gets
-- * a copy of this pointer. Let's hope we don't manipulate it
-- * later
-- */
-- cur->content = xmlBufferCreateSize(0);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- if (ent->content != NULL)
-- xmlBufferAdd(cur->content, ent->content, -1);
--#endif
-- /*
-- * The parent pointer in entity is a Dtd pointer and thus is NOT
-- * updated. Not sure if this is 100% correct.
-- * -George
-- */
-- cur->children = (xmlNodePtr) ent;
-- cur->last = (xmlNodePtr) ent;
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewDocText:
-- * @doc: the document
-- * @content: the text content
-- *
-- * Creation of a new text node within a document.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
-- xmlNodePtr cur;
--
-- cur = xmlNewText(content);
-- if (cur != NULL) cur->doc = doc;
-- return(cur);
--}
--
--/**
-- * xmlNewTextLen:
-- * @content: the text content
-- * @len: the text len.
-- *
-- * Creation of a new text node with an extra parameter for the content's lenght
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewTextLen(const xmlChar *content, int len) {
-- xmlNodePtr cur;
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewText : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_TEXT_NODE;
--
-- cur->name = xmlStringText;
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrndup(content, len);
--#else
-- cur->content = xmlBufferCreateSize(len);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, len);
--#endif
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewDocTextLen:
-- * @doc: the document
-- * @content: the text content
-- * @len: the text len.
-- *
-- * Creation of a new text node with an extra content lenght parameter. The
-- * text node pertain to a given document.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
-- xmlNodePtr cur;
--
-- cur = xmlNewTextLen(content, len);
-- if (cur != NULL) cur->doc = doc;
-- return(cur);
--}
--
--/**
-- * xmlNewComment:
-- * @content: the comment content
-- *
-- * Creation of a new node containing a comment.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewComment(const xmlChar *content) {
-- xmlNodePtr cur;
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewComment : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_COMMENT_NODE;
--
-- cur->name = xmlStringComment;
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrdup(content);
--#else
-- cur->content = xmlBufferCreateSize(0);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, -1);
--#endif
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewCDataBlock:
-- * @doc: the document
-- * @content: the CData block content content
-- * @len: the length of the block
-- *
-- * Creation of a new node containing a CData block.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
-- xmlNodePtr cur;
--
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewCDataBlock : malloc failed\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlNode));
-- cur->type = XML_CDATA_SECTION_NODE;
--
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrndup(content, len);
--#else
-- cur->content = xmlBufferCreateSize(len);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, len);
--#endif
-- }
-- return(cur);
--}
--
--/**
-- * xmlNewDocComment:
-- * @doc: the document
-- * @content: the comment content
-- *
-- * Creation of a new node containing a commentwithin a document.
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
-- xmlNodePtr cur;
--
-- cur = xmlNewComment(content);
-- if (cur != NULL) cur->doc = doc;
-- return(cur);
--}
--
--/**
-- * xmlSetTreeDoc:
-- * @tree: the top element
-- * @doc: the document
-- *
-- * update all nodes under the tree to point to the right document
-- */
--void
--xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
-- if (tree == NULL)
-- return;
-- if (tree->type == XML_ENTITY_DECL)
-- return;
-- if (tree->doc != doc) {
-- if (tree->children != NULL)
-- xmlSetListDoc(tree->children, doc);
-- tree->doc = doc;
-- }
--}
--
--/**
-- * xmlSetListDoc:
-- * @tree: the first element
-- * @doc: the document
-- *
-- * update all nodes in the list to point to the right document
-- */
--void
--xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
-- xmlNodePtr cur;
--
-- if (list == NULL)
-- return;
-- cur = list;
-- while (cur != NULL) {
-- if (cur->doc != doc)
-- xmlSetTreeDoc(cur, doc);
-- cur = cur->next;
-- }
--}
--
--
--/**
-- * xmlNewChild:
-- * @parent: the parent node
-- * @ns: a namespace if any
-- * @name: the name of the child
-- * @content: the XML content of the child if any.
-- *
-- * Creation of a new child element, added at the end of @parent children list.
-- * @ns and @content parameters are optionnal (NULL). If content is non NULL,
-- * a child list containing the TEXTs and ENTITY_REFs node will be created.
-- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
-- * references, but XML special chars need to be escaped first by using
-- * xmlEncodeEntitiesReentrant(). Use xmlNewTextChild() if entities
-- * support is not needed.
-- *
-- * Returns a pointer to the new node object.
-- */
--xmlNodePtr
--xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
-- const xmlChar *name, const xmlChar *content) {
-- xmlNodePtr cur, prev;
--
-- if (parent == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewChild : parent == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if (name == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewChild : name == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Allocate a new node
-- */
-- if (ns == NULL)
-- cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
-- else
-- cur = xmlNewDocNode(parent->doc, ns, name, content);
-- if (cur == NULL) return(NULL);
--
-- /*
-- * add the new element at the end of the children list.
-- */
-- cur->type = XML_ELEMENT_NODE;
-- cur->parent = parent;
-- cur->doc = parent->doc;
-- if (parent->children == NULL) {
-- parent->children = cur;
-- parent->last = cur;
-- } else {
-- prev = parent->last;
-- prev->next = cur;
-- cur->prev = prev;
-- parent->last = cur;
-- }
--
-- return(cur);
--}
--
--/**
-- * xmlAddNextSibling:
-- * @cur: the child node
-- * @elem: the new node
-- *
-- * Add a new element @elem as the next siblings of @cur
-- * If the new element was already inserted in a document it is
-- * first unlinked from its existing context.
-- * As a result of text merging @elem may be freed.
-- *
-- * Returns the new element or NULL in case of error.
-- */
--xmlNodePtr
--xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNextSibling : cur == NULL\n");
--#endif
-- return(NULL);
-- }
-- if (elem == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNextSibling : elem == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- xmlUnlinkNode(elem);
--
-- if (elem->type == XML_TEXT_NODE) {
-- if (cur->type == XML_TEXT_NODE) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(cur, elem->content);
--#else
-- xmlNodeAddContent(cur, xmlBufferContent(elem->content));
--#endif
-- xmlFreeNode(elem);
-- return(cur);
-- }
-- if ((cur->next != NULL) && (cur->type == XML_TEXT_NODE)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlChar *tmp;
--
-- tmp = xmlStrdup(elem->content);
-- tmp = xmlStrcat(tmp, cur->next->content);
-- xmlNodeSetContent(cur->next, tmp);
-- xmlFree(tmp);
--#else
-- xmlBufferAddHead(cur->next->content,
-- xmlBufferContent(elem->content),
-- xmlBufferLength(elem->content));
--#endif
-- xmlFreeNode(elem);
-- return(cur->next);
-- }
-- }
--
-- if (elem->doc != cur->doc) {
-- xmlSetTreeDoc(elem, cur->doc);
-- }
-- elem->parent = cur->parent;
-- elem->prev = cur;
-- elem->next = cur->next;
-- cur->next = elem;
-- if (elem->next != NULL)
-- elem->next->prev = elem;
-- if ((elem->parent != NULL) && (elem->parent->last == cur))
-- elem->parent->last = elem;
-- return(elem);
--}
--
--/**
-- * xmlAddPrevSibling:
-- * @cur: the child node
-- * @elem: the new node
-- *
-- * Add a new element @elem as the previous siblings of @cur
-- * merging adjacent TEXT nodes (@elem may be freed)
-- * If the new element was already inserted in a document it is
-- * first unlinked from its existing context.
-- *
-- * Returns the new element or NULL in case of error.
-- */
--xmlNodePtr
--xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddPrevSibling : cur == NULL\n");
--#endif
-- return(NULL);
-- }
-- if (elem == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddPrevSibling : elem == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- xmlUnlinkNode(elem);
--
-- if (elem->type == XML_TEXT_NODE) {
-- if (cur->type == XML_TEXT_NODE) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlChar *tmp;
--
-- tmp = xmlStrdup(elem->content);
-- tmp = xmlStrcat(tmp, cur->content);
-- xmlNodeSetContent(cur, tmp);
-- xmlFree(tmp);
--#else
-- xmlBufferAddHead(cur->content, xmlBufferContent(elem->content),
-- xmlBufferLength(elem->content));
--#endif
-- xmlFreeNode(elem);
-- return(cur);
-- }
-- if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(cur->prev, elem->content);
--#else
-- xmlNodeAddContent(cur->prev, xmlBufferContent(elem->content));
--#endif
-- xmlFreeNode(elem);
-- return(cur->prev);
-- }
-- }
--
-- if (elem->doc != cur->doc) {
-- xmlSetTreeDoc(elem, cur->doc);
-- }
-- elem->parent = cur->parent;
-- elem->next = cur;
-- elem->prev = cur->prev;
-- cur->prev = elem;
-- if (elem->prev != NULL)
-- elem->prev->next = elem;
-- if ((elem->parent != NULL) && (elem->parent->children == cur))
-- elem->parent->children = elem;
-- return(elem);
--}
--
--/**
-- * xmlAddSibling:
-- * @cur: the child node
-- * @elem: the new node
-- *
-- * Add a new element @elem to the list of siblings of @cur
-- * merging adjacent TEXT nodes (@elem may be freed)
-- * If the new element was already inserted in a document it is
-- * first unlinked from its existing context.
-- *
-- * Returns the new element or NULL in case of error.
-- */
--xmlNodePtr
--xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
-- xmlNodePtr parent;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddSibling : cur == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if (elem == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddSibling : elem == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- /*
-- * Constant time is we can rely on the ->parent->last to find
-- * the last sibling.
-- */
-- if ((cur->parent != NULL) &&
-- (cur->parent->children != NULL) &&
-- (cur->parent->last != NULL) &&
-- (cur->parent->last->next == NULL)) {
-- cur = cur->parent->last;
-- } else {
-- while (cur->next != NULL) cur = cur->next;
-- }
--
-- xmlUnlinkNode(elem);
--
-- if ((cur->type == XML_TEXT_NODE) && (elem->type == XML_TEXT_NODE)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(cur, elem->content);
--#else
-- xmlNodeAddContent(cur, xmlBufferContent(elem->content));
--#endif
-- xmlFreeNode(elem);
-- return(cur);
-- }
--
-- if (elem->doc != cur->doc) {
-- xmlSetTreeDoc(elem, cur->doc);
-- }
-- parent = cur->parent;
-- elem->prev = cur;
-- elem->next = NULL;
-- elem->parent = parent;
-- cur->next = elem;
-- if (parent != NULL)
-- parent->last = elem;
--
-- return(elem);
--}
--
--/**
-- * xmlAddChildList:
-- * @parent: the parent node
-- * @cur: the first node in the list
-- *
-- * Add a list of node at the end of the child list of the parent
-- * merging adjacent TEXT nodes (@cur may be freed)
-- *
-- * Returns the last child or NULL in case of error.
-- */
--xmlNodePtr
--xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
-- xmlNodePtr prev;
--
-- if (parent == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddChild : parent == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddChild : child == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if ((cur->doc != NULL) && (parent->doc != NULL) &&
-- (cur->doc != parent->doc)) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "Elements moved to a different document\n");
--#endif
-- }
--
-- /*
-- * add the first element at the end of the children list.
-- */
-- if (parent->children == NULL) {
-- parent->children = cur;
-- } else {
-- /*
-- * If cur and parent->last both are TEXT nodes, then merge them.
-- */
-- if ((cur->type == XML_TEXT_NODE) &&
-- (parent->last->type == XML_TEXT_NODE)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(parent->last, cur->content);
--#else
-- xmlNodeAddContent(parent->last, xmlBufferContent(cur->content));
--#endif
-- /*
-- * if it's the only child, nothing more to be done.
-- */
-- if (cur->next == NULL) {
-- xmlFreeNode(cur);
-- return(parent->last);
-- }
-- prev = cur;
-- cur = cur->next;
-- xmlFreeNode(prev);
-- }
-- prev = parent->last;
-- prev->next = cur;
-- cur->prev = prev;
-- }
-- while (cur->next != NULL) {
-- cur->parent = parent;
-- if (cur->doc != parent->doc) {
-- xmlSetTreeDoc(cur, parent->doc);
-- }
-- cur = cur->next;
-- }
-- cur->parent = parent;
-- cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
-- parent->last = cur;
--
-- return(cur);
--}
--
--/**
-- * xmlAddChild:
-- * @parent: the parent node
-- * @cur: the child node
-- *
-- * Add a new child element, to @parent, at the end of the child list
-- * merging adjacent TEXT nodes (in which case @cur is freed)
-- * Returns the child or NULL in case of error.
-- */
--xmlNodePtr
--xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
-- xmlNodePtr prev;
--
-- if (parent == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddChild : parent == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddChild : child == NULL\n");
--#endif
-- return(NULL);
-- }
--
-- if ((cur->doc != NULL) && (parent->doc != NULL) &&
-- (cur->doc != parent->doc)) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "Elements moved to a different document\n");
--#endif
-- }
--
-- /*
-- * If cur is a TEXT node, merge its content with adjacent TEXT nodes
-- * or with parent->content if parent->content != NULL.
-- * cur is then freed.
-- */
-- if (cur->type == XML_TEXT_NODE) {
-- if (((parent->type == XML_ELEMENT_NODE) ||
-- (parent->type == XML_TEXT_NODE)) &&
-- (parent->content != NULL)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(parent, cur->content);
--#else
-- xmlNodeAddContent(parent, xmlBufferContent(cur->content));
--#endif
-- xmlFreeNode(cur);
-- return(parent);
-- }
-- if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(parent->last, cur->content);
--#else
-- xmlNodeAddContent(parent->last, xmlBufferContent(cur->content));
--#endif
-- xmlFreeNode(cur);
-- return(parent->last);
-- }
-- }
--
-- /*
-- * add the new element at the end of the children list.
-- */
-- cur->parent = parent;
-- if (cur->doc != parent->doc) {
-- xmlSetTreeDoc(cur, parent->doc);
-- }
--
-- /*
-- * Handle the case where parent->content != NULL, in that case it will
-- * create a intermediate TEXT node.
-- */
-- if (((parent->type == XML_ELEMENT_NODE) || (parent->type == XML_TEXT_NODE)) &&
-- (parent->content != NULL)) {
-- xmlNodePtr text;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- text = xmlNewDocText(parent->doc, parent->content);
--#else
-- text = xmlNewDocText(parent->doc, xmlBufferContent(parent->content));
--#endif
-- if (text != NULL) {
-- text->next = parent->children;
-- if (text->next != NULL)
-- text->next->prev = text;
-- parent->children = text;
-- UPDATE_LAST_CHILD_AND_PARENT(parent)
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlFree(parent->content);
--#else
-- xmlBufferFree(parent->content);
--#endif
-- parent->content = NULL;
-- }
-- }
-- if (parent->children == NULL) {
-- parent->children = cur;
-- parent->last = cur;
-- } else {
-- prev = parent->last;
-- prev->next = cur;
-- cur->prev = prev;
-- parent->last = cur;
-- }
--
-- return(cur);
--}
--
--/**
-- * xmlGetLastChild:
-- * @parent: the parent node
-- *
-- * Search the last child of a node.
-- * Returns the last child or NULL if none.
-- */
--xmlNodePtr
--xmlGetLastChild(xmlNodePtr parent) {
-- if (parent == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlGetLastChild : parent == NULL\n");
--#endif
-- return(NULL);
-- }
-- return(parent->last);
--}
--
--/**
-- * xmlFreeNodeList:
-- * @cur: the first node in the list
-- *
-- * Free a node and all its siblings, this is a recursive behaviour, all
-- * the children are freed too.
-- */
--void
--xmlFreeNodeList(xmlNodePtr cur) {
-- xmlNodePtr next;
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeNodeList : node == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- next = cur->next;
-- xmlFreeNode(cur);
-- cur = next;
-- }
--}
--
--/**
-- * xmlFreeNode:
-- * @cur: the node
-- *
-- * Free a node, this is a recursive behaviour, all the children are freed too.
-- * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
-- */
--void
--xmlFreeNode(xmlNodePtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeNode : node == NULL\n");
--#endif
-- return;
-- }
-- if (cur->type == XML_DTD_NODE)
-- return;
-- cur->doc = NULL;
-- cur->parent = NULL;
-- cur->next = NULL;
-- cur->prev = NULL;
-- if ((cur->children != NULL) &&
-- (cur->type != XML_ENTITY_REF_NODE))
-- xmlFreeNodeList(cur->children);
-- if (cur->properties != NULL) xmlFreePropList(cur->properties);
-- if (cur->type != XML_ENTITY_REF_NODE)
--#ifndef XML_USE_BUFFER_CONTENT
-- if (cur->content != NULL) xmlFree(cur->content);
--#else
-- if (cur->content != NULL) xmlBufferFree(cur->content);
--#endif
-- if ((cur->name != NULL) &&
-- (cur->name != xmlStringText) &&
-- (cur->name != xmlStringTextNoenc) &&
-- (cur->name != xmlStringComment))
-- xmlFree((char *) cur->name);
-- if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
-- memset(cur, -1, sizeof(xmlNode));
-- xmlFree(cur);
--}
--
--/**
-- * xmlUnlinkNode:
-- * @cur: the node
-- *
-- * Unlink a node from it's current context, the node is not freed
-- */
--void
--xmlUnlinkNode(xmlNodePtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlUnlinkNode : node == NULL\n");
--#endif
-- return;
-- }
-- if ((cur->parent != NULL) && (cur->parent->children == cur))
-- cur->parent->children = cur->next;
-- if ((cur->parent != NULL) && (cur->parent->last == cur))
-- cur->parent->last = cur->prev;
-- if (cur->next != NULL)
-- cur->next->prev = cur->prev;
-- if (cur->prev != NULL)
-- cur->prev->next = cur->next;
-- cur->next = cur->prev = NULL;
-- cur->parent = NULL;
--}
--
--/**
-- * xmlReplaceNode:
-- * @old: the old node
-- * @cur: the node
-- *
-- * Unlink the old node from it's current context, prune the new one
-- * at the same place. If cur was already inserted in a document it is
-- * first unlinked from its existing context.
-- *
-- * Returns the old node
-- */
--xmlNodePtr
--xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
-- if (old == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReplaceNode : old == NULL\n");
--#endif
-- return(NULL);
-- }
-- if (cur == NULL) {
-- xmlUnlinkNode(old);
-- return(old);
-- }
-- if (cur == old) {
-- return(old);
-- }
-- xmlUnlinkNode(cur);
-- cur->doc = old->doc;
-- cur->parent = old->parent;
-- cur->next = old->next;
-- if (cur->next != NULL)
-- cur->next->prev = cur;
-- cur->prev = old->prev;
-- if (cur->prev != NULL)
-- cur->prev->next = cur;
-- if (cur->parent != NULL) {
-- if (cur->parent->children == old)
-- cur->parent->children = cur;
-- if (cur->parent->last == old)
-- cur->parent->last = cur;
-- }
-- old->next = old->prev = NULL;
-- old->parent = NULL;
-- return(old);
--}
--
--/************************************************************************
-- * *
-- * Copy operations *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlCopyNamespace:
-- * @cur: the namespace
-- *
-- * Do a copy of the namespace.
-- *
-- * Returns: a new xmlNsPtr, or NULL in case of error.
-- */
--xmlNsPtr
--xmlCopyNamespace(xmlNsPtr cur) {
-- xmlNsPtr ret;
--
-- if (cur == NULL) return(NULL);
-- switch (cur->type) {
-- case XML_LOCAL_NAMESPACE:
-- ret = xmlNewNs(NULL, cur->href, cur->prefix);
-- break;
-- default:
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCopyNamespace: invalid type %d\n", cur->type);
--#endif
-- return(NULL);
-- }
-- return(ret);
--}
--
--/**
-- * xmlCopyNamespaceList:
-- * @cur: the first namespace
-- *
-- * Do a copy of an namespace list.
-- *
-- * Returns: a new xmlNsPtr, or NULL in case of error.
-- */
--xmlNsPtr
--xmlCopyNamespaceList(xmlNsPtr cur) {
-- xmlNsPtr ret = NULL;
-- xmlNsPtr p = NULL,q;
--
-- while (cur != NULL) {
-- q = xmlCopyNamespace(cur);
-- if (p == NULL) {
-- ret = p = q;
-- } else {
-- p->next = q;
-- p = q;
-- }
-- cur = cur->next;
-- }
-- return(ret);
--}
--
--static xmlNodePtr
--xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
--/**
-- * xmlCopyProp:
-- * @target: the element where the attribute will be grafted
-- * @cur: the attribute
-- *
-- * Do a copy of the attribute.
-- *
-- * Returns: a new xmlAttrPtr, or NULL in case of error.
-- */
--xmlAttrPtr
--xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
-- xmlAttrPtr ret;
--
-- if (cur == NULL) return(NULL);
-- if (target != NULL)
-- ret = xmlNewDocProp(target->doc, cur->name, NULL);
-- else if (cur->parent != NULL)
-- ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
-- else if (cur->children != NULL)
-- ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
-- else
-- ret = xmlNewDocProp(NULL, cur->name, NULL);
-- if (ret == NULL) return(NULL);
-- ret->parent = target;
--
-- if ((cur->ns != NULL) && (target != NULL)) {
-- xmlNsPtr ns;
--
-- ns = xmlSearchNs(target->doc, target, cur->ns->prefix);
-- ret->ns = ns;
-- } else
-- ret->ns = NULL;
--
-- if (cur->children != NULL) {
-- xmlNodePtr tmp;
--
-- ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
-- ret->last = NULL;
-- tmp = ret->children;
-- while (tmp != NULL) {
-- /* tmp->parent = (xmlNodePtr)ret; */
-- if (tmp->next == NULL)
-- ret->last = tmp;
-- tmp = tmp->next;
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlCopyPropList:
-- * @target: the element where the attributes will be grafted
-- * @cur: the first attribute
-- *
-- * Do a copy of an attribute list.
-- *
-- * Returns: a new xmlAttrPtr, or NULL in case of error.
-- */
--xmlAttrPtr
--xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
-- xmlAttrPtr ret = NULL;
-- xmlAttrPtr p = NULL,q;
--
-- while (cur != NULL) {
-- q = xmlCopyProp(target, cur);
-- if (p == NULL) {
-- ret = p = q;
-- } else {
-- p->next = q;
-- q->prev = p;
-- p = q;
-- }
-- cur = cur->next;
-- }
-- return(ret);
--}
--
--/*
-- * NOTE abeut the CopyNode operations !
-- *
-- * They are splitted into external and internal parts for one
-- * tricky reason: namespaces. Doing a direct copy of a node
-- * say RPM:Copyright without changing the namespace pointer to
-- * something else can produce stale links. One way to do it is
-- * to keep a reference counter but this doesn't work as soon
-- * as one move the element or the subtree out of the scope of
-- * the existing namespace. The actual solution seems to add
-- * a copy of the namespace at the top of the copied tree if
-- * not available in the subtree.
-- * Hence two functions, the public front-end call the inner ones
-- */
--
--static xmlNodePtr
--xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
--
--static xmlNodePtr
--xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
-- int recursive) {
-- xmlNodePtr ret;
--
-- if (node == NULL) return(NULL);
-- /*
-- * Allocate a new node and fill the fields.
-- */
-- ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlStaticCopyNode : malloc failed\n");
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlNode));
-- ret->type = node->type;
--
-- ret->doc = doc;
-- ret->parent = parent;
-- if (node->name == xmlStringText)
-- ret->name = xmlStringText;
-- else if (node->name == xmlStringTextNoenc)
-- ret->name = xmlStringTextNoenc;
-- else if (node->name == xmlStringComment)
-- ret->name = xmlStringComment;
-- else if (node->name != NULL)
-- ret->name = xmlStrdup(node->name);
-- if ((node->content != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
--#ifndef XML_USE_BUFFER_CONTENT
-- ret->content = xmlStrdup(node->content);
--#else
-- ret->content = xmlBufferCreateSize(xmlBufferLength(node->content));
-- xmlBufferSetAllocationScheme(ret->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(ret->content,
-- xmlBufferContent(node->content),
-- xmlBufferLength(node->content));
--#endif
-- }
-- if (parent != NULL)
-- xmlAddChild(parent, ret);
--
-- if (!recursive) return(ret);
-- if (node->nsDef != NULL)
-- ret->nsDef = xmlCopyNamespaceList(node->nsDef);
--
-- if (node->ns != NULL) {
-- xmlNsPtr ns;
--
-- ns = xmlSearchNs(doc, ret, node->ns->prefix);
-- if (ns == NULL) {
-- /*
-- * Humm, we are copying an element whose namespace is defined
-- * out of the new tree scope. Search it in the original tree
-- * and add it at the top of the new tree
-- */
-- ns = xmlSearchNs(node->doc, node, node->ns->prefix);
-- if (ns != NULL) {
-- xmlNodePtr root = ret;
--
-- while (root->parent != NULL) root = root->parent;
-- xmlNewNs(root, ns->href, ns->prefix);
-- }
-- } else {
-- /*
-- * reference the existing namespace definition in our own tree.
-- */
-- ret->ns = ns;
-- }
-- }
-- if (node->properties != NULL)
-- ret->properties = xmlCopyPropList(ret, node->properties);
-- if (node->children != NULL)
-- ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
-- UPDATE_LAST_CHILD_AND_PARENT(ret)
-- return(ret);
--}
--
--static xmlNodePtr
--xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
-- xmlNodePtr ret = NULL;
-- xmlNodePtr p = NULL,q;
--
-- while (node != NULL) {
-- if( node->type == XML_DTD_NODE )
-- q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
-- else
-- q = xmlStaticCopyNode(node, doc, parent, 1);
-- if (ret == NULL) {
-- q->prev = NULL;
-- ret = p = q;
-- } else {
-- p->next = q;
-- q->prev = p;
-- p = q;
-- }
-- node = node->next;
-- }
-- return(ret);
--}
--
--/**
-- * xmlCopyNode:
-- * @node: the node
-- * @recursive: if 1 do a recursive copy.
-- *
-- * Do a copy of the node.
-- *
-- * Returns: a new xmlNodePtr, or NULL in case of error.
-- */
--xmlNodePtr
--xmlCopyNode(xmlNodePtr node, int recursive) {
-- xmlNodePtr ret;
--
-- ret = xmlStaticCopyNode(node, NULL, NULL, recursive);
-- return(ret);
--}
--
--/**
-- * xmlCopyNodeList:
-- * @node: the first node in the list.
-- *
-- * Do a recursive copy of the node list.
-- *
-- * Returns: a new xmlNodePtr, or NULL in case of error.
-- */
--xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
-- xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
-- return(ret);
--}
--
--/**
-- * xmlCopyElement:
-- * @elem: the element
-- *
-- * Do a copy of the element definition.
-- *
-- * Returns: a new xmlElementPtr, or NULL in case of error.
--xmlElementPtr
--xmlCopyElement(xmlElementPtr elem) {
-- xmlElementPtr ret;
--
-- if (elem == NULL) return(NULL);
-- ret = xmlNewDocElement(elem->doc, elem->ns, elem->name, elem->content);
-- if (ret == NULL) return(NULL);
-- if (!recursive) return(ret);
-- if (elem->properties != NULL)
-- ret->properties = xmlCopyPropList(elem->properties);
--
-- if (elem->nsDef != NULL)
-- ret->nsDef = xmlCopyNamespaceList(elem->nsDef);
-- if (elem->children != NULL)
-- ret->children = xmlCopyElementList(elem->children);
-- return(ret);
--}
-- */
--
--/**
-- * xmlCopyDtd:
-- * @dtd: the dtd
-- *
-- * Do a copy of the dtd.
-- *
-- * Returns: a new xmlDtdPtr, or NULL in case of error.
-- */
--xmlDtdPtr
--xmlCopyDtd(xmlDtdPtr dtd) {
-- xmlDtdPtr ret;
--
-- if (dtd == NULL) return(NULL);
-- ret = xmlNewDtd(NULL, dtd->name, dtd->ExternalID, dtd->SystemID);
-- if (ret == NULL) return(NULL);
-- if (dtd->entities != NULL)
-- ret->entities = (void *) xmlCopyEntitiesTable(
-- (xmlEntitiesTablePtr) dtd->entities);
-- if (dtd->notations != NULL)
-- ret->notations = (void *) xmlCopyNotationTable(
-- (xmlNotationTablePtr) dtd->notations);
-- if (dtd->elements != NULL)
-- ret->elements = (void *) xmlCopyElementTable(
-- (xmlElementTablePtr) dtd->elements);
-- if (dtd->attributes != NULL)
-- ret->attributes = (void *) xmlCopyAttributeTable(
-- (xmlAttributeTablePtr) dtd->attributes);
-- return(ret);
--}
--
--/**
-- * xmlCopyDoc:
-- * @doc: the document
-- * @recursive: if 1 do a recursive copy.
-- *
-- * Do a copy of the document info. If recursive, the content tree will
-- * be copied too as well as Dtd, namespaces and entities.
-- *
-- * Returns: a new xmlDocPtr, or NULL in case of error.
-- */
--xmlDocPtr
--xmlCopyDoc(xmlDocPtr doc, int recursive) {
-- xmlDocPtr ret;
--
-- if (doc == NULL) return(NULL);
-- ret = xmlNewDoc(doc->version);
-- if (ret == NULL) return(NULL);
-- if (doc->name != NULL)
-- ret->name = xmlMemStrdup(doc->name);
-- if (doc->encoding != NULL)
-- ret->encoding = xmlStrdup(doc->encoding);
-- ret->charset = doc->charset;
-- ret->compression = doc->compression;
-- ret->standalone = doc->standalone;
-- if (!recursive) return(ret);
--
-- if (doc->intSubset != NULL)
-- ret->intSubset = xmlCopyDtd(doc->intSubset);
-- if (doc->oldNs != NULL)
-- ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
-- if (doc->children != NULL) {
-- xmlNodePtr tmp;
-- ret->children = xmlStaticCopyNodeList(doc->children, ret,
-- (xmlNodePtr)ret);
-- ret->last = NULL;
-- tmp = ret->children;
-- while (tmp != NULL) {
-- if (tmp->next == NULL)
-- ret->last = tmp;
-- tmp = tmp->next;
-- }
-- }
-- return(ret);
--}
--
--/************************************************************************
-- * *
-- * Content access functions *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlDocGetRootElement:
-- * @doc: the document
-- *
-- * Get the root element of the document (doc->children is a list
-- * containing possibly comments, PIs, etc ...).
-- *
-- * Returns the xmlNodePtr for the root or NULL
-- */
--xmlNodePtr
--xmlDocGetRootElement(xmlDocPtr doc) {
-- xmlNodePtr ret;
--
-- if (doc == NULL) return(NULL);
-- ret = doc->children;
-- while (ret != NULL) {
-- if (ret->type == XML_ELEMENT_NODE)
-- return(ret);
-- ret = ret->next;
-- }
-- return(ret);
--}
--
--/**
-- * xmlDocSetRootElement:
-- * @doc: the document
-- * @root: the new document root element
-- *
-- * Set the root element of the document (doc->children is a list
-- * containing possibly comments, PIs, etc ...).
-- *
-- * Returns the old root element if any was found
-- */
--xmlNodePtr
--xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
-- xmlNodePtr old = NULL;
--
-- if (doc == NULL) return(NULL);
-- old = doc->children;
-- while (old != NULL) {
-- if (old->type == XML_ELEMENT_NODE)
-- break;
-- old = old->next;
-- }
-- if (old == NULL) {
-- if (doc->children == NULL) {
-- doc->children = root;
-- doc->last = root;
-- } else {
-- xmlAddSibling(doc->children, root);
-- }
-- } else {
-- xmlReplaceNode(old, root);
-- }
-- return(old);
--}
--
--/**
-- * xmlNodeSetLang:
-- * @cur: the node being changed
-- * @lang: the langage description
-- *
-- * Set the language of a node, i.e. the values of the xml:lang
-- * attribute.
-- */
--void
--xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
-- if (cur == NULL) return;
-- switch(cur->type) {
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_COMMENT_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_PI_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_NAMESPACE_DECL:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- return;
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- break;
-- }
-- xmlSetProp(cur, BAD_CAST "xml:lang", lang);
--}
--
--/**
-- * xmlNodeGetLang:
-- * @cur: the node being checked
-- *
-- * Searches the language of a node, i.e. the values of the xml:lang
-- * attribute or the one carried by the nearest ancestor.
-- *
-- * Returns a pointer to the lang value, or NULL if not found
-- * It's up to the caller to free the memory.
-- */
--xmlChar *
--xmlNodeGetLang(xmlNodePtr cur) {
-- xmlChar *lang;
--
-- while (cur != NULL) {
-- lang = xmlGetProp(cur, BAD_CAST "xml:lang");
-- if (lang != NULL)
-- return(lang);
-- cur = cur->parent;
-- }
-- return(NULL);
--}
--
--
--/**
-- * xmlNodeSetSpacePreserve:
-- * @cur: the node being changed
-- * @val: the xml:space value ("0": default, 1: "preserve")
-- *
-- * Set (or reset) the space preserving behaviour of a node, i.e. the
-- * value of the xml:space attribute.
-- */
--void
--xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
-- if (cur == NULL) return;
-- switch(cur->type) {
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_COMMENT_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_PI_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return;
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- break;
-- }
-- switch (val) {
-- case 0:
-- xmlSetProp(cur, BAD_CAST "xml:space", BAD_CAST "default");
-- break;
-- case 1:
-- xmlSetProp(cur, BAD_CAST "xml:space",
-- BAD_CAST "preserve");
-- break;
-- }
--}
--
--/**
-- * xmlNodeGetSpacePreserve:
-- * @cur: the node being checked
-- *
-- * Searches the space preserving behaviour of a node, i.e. the values
-- * of the xml:space attribute or the one carried by the nearest
-- * ancestor.
-- *
-- * Returns -1 if xml:space is not inheried, 0 if "default", 1 if "preserve"
-- */
--int
--xmlNodeGetSpacePreserve(xmlNodePtr cur) {
-- xmlChar *space;
--
-- while (cur != NULL) {
-- space = xmlGetProp(cur, BAD_CAST "xml:space");
-- if (space != NULL) {
-- if (xmlStrEqual(space, BAD_CAST "preserve")) {
-- xmlFree(space);
-- return(1);
-- }
-- if (xmlStrEqual(space, BAD_CAST "default")) {
-- xmlFree(space);
-- return(0);
-- }
-- xmlFree(space);
-- }
-- cur = cur->parent;
-- }
-- return(-1);
--}
--
--/**
-- * xmlNodeSetName:
-- * @cur: the node being changed
-- * @name: the new tag name
-- *
-- * Set (or reset) the name of a node.
-- */
--void
--xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
-- if (cur == NULL) return;
-- if (name == NULL) return;
-- switch(cur->type) {
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_COMMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return;
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- case XML_PI_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_DTD_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- break;
-- }
-- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-- cur->name = xmlStrdup(name);
--}
--
--/**
-- * xmlNodeSetBase:
-- * @cur: the node being changed
-- * @uri: the new base URI
-- *
-- * Set (or reset) the base URI of a node, i.e. the value of the
-- * xml:base attribute.
-- */
--void
--xmlNodeSetBase(xmlNodePtr cur, xmlChar* uri) {
-- if (cur == NULL) return;
-- switch(cur->type) {
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_COMMENT_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_PI_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return;
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- break;
-- }
-- xmlSetProp(cur, BAD_CAST "xml:base", uri);
--}
--
--/**
-- * xmlDocumentGetBase:
-- * @doc: the document
-- *
-- * Searches for the Document BASE URL. The code should work on both XML
-- * and HTML document.
-- * It returns the base as defined in RFC 2396 section
-- * 5.1.3. Base URI from the Retrieval URI
-- * However it does not return the computed base (5.1.1 and 5.1.2), use
-- * xmlNodeGetBase() for this
-- *
-- * Returns a pointer to the base URL, or NULL if not found
-- * It's up to the caller to free the memory.
-- */
--xmlChar *
--xmlDocumentGetBase(xmlDocPtr doc) {
-- if (doc == NULL)
-- return(NULL);
-- if (doc->type == XML_HTML_DOCUMENT_NODE) {
-- if (doc->URL != NULL)
-- return(xmlStrdup(doc->URL));
-- return(NULL);
-- }
-- if (doc->URL != NULL)
-- return(xmlStrdup(doc->URL));
-- return(NULL);
--}
--
--/**
-- * xmlNodeGetBase:
-- * @doc: the document the node pertains to
-- * @cur: the node being checked
-- *
-- * Searches for the BASE URL. The code should work on both XML
-- * and HTML document even if base mechanisms are completely different.
-- * It returns the base as defined in RFC 2396 sections
-- * 5.1.1. Base URI within Document Content
-- * and
-- * 5.1.2. Base URI from the Encapsulating Entity
-- * However it does not return the document base (5.1.3), use
-- * xmlDocumentGetBase() for this
-- *
-- * Returns a pointer to the base URL, or NULL if not found
-- * It's up to the caller to free the memory.
-- */
--xmlChar *
--xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
-- xmlChar *base;
--
-- if ((cur == NULL) && (doc == NULL))
-- return(NULL);
-- if (doc == NULL) doc = cur->doc;
-- if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
-- cur = doc->children;
-- while ((cur != NULL) && (cur->name != NULL)) {
-- if (cur->type != XML_ELEMENT_NODE) {
-- cur = cur->next;
-- continue;
-- }
-- if (!xmlStrcasecmp(cur->name, BAD_CAST "html")) {
-- cur = cur->children;
-- continue;
-- }
-- if (!xmlStrcasecmp(cur->name, BAD_CAST "head")) {
-- cur = cur->children;
-- continue;
-- }
-- if (!xmlStrcasecmp(cur->name, BAD_CAST "base")) {
-- return(xmlGetProp(cur, BAD_CAST "href"));
-- }
-- cur = cur->next;
-- }
-- return(NULL);
-- }
-- while (cur != NULL) {
-- if (cur->type == XML_ENTITY_DECL) {
-- xmlEntityPtr ent = (xmlEntityPtr) cur;
-- return(xmlStrdup(ent->URI));
-- }
-- base = xmlGetProp(cur, BAD_CAST "xml:base");
-- if (base != NULL)
-- return(base);
-- cur = cur->parent;
-- }
-- return(NULL);
--}
--
--/**
-- * xmlNodeGetContent:
-- * @cur: the node being read
-- *
-- * Read the value of a node, this can be either the text carried
-- * directly by this node if it's a TEXT node or the aggregate string
-- * of the values carried by this node child's (TEXT and ENTITY_REF).
-- * Entity references are substitued.
-- * Returns a new xmlChar * or NULL if no content is available.
-- * It's up to the caller to free the memory.
-- */
--xmlChar *
--xmlNodeGetContent(xmlNodePtr cur) {
-- if (cur == NULL) return(NULL);
-- switch (cur->type) {
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_ELEMENT_NODE:
-- return(xmlNodeListGetString(cur->doc, cur->children, 1));
-- break;
-- case XML_ATTRIBUTE_NODE: {
-- xmlAttrPtr attr = (xmlAttrPtr) cur;
-- if (attr->parent != NULL)
-- return(xmlNodeListGetString(attr->parent->doc, attr->children, 1));
-- else
-- return(xmlNodeListGetString(NULL, attr->children, 1));
-- break;
-- }
-- case XML_COMMENT_NODE:
-- case XML_PI_NODE:
-- if (cur->content != NULL)
--#ifndef XML_USE_BUFFER_CONTENT
-- return(xmlStrdup(cur->content));
--#else
-- return(xmlStrdup(xmlBufferContent(cur->content)));
--#endif
-- return(NULL);
-- case XML_ENTITY_REF_NODE:
-- /*
-- * Locate the entity, and get it's content
-- * @@@
-- */
-- return(NULL);
-- case XML_ENTITY_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_NOTATION_NODE:
-- case XML_DTD_NODE:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return(NULL);
-- case XML_NAMESPACE_DECL:
-- return(xmlStrdup(((xmlNsPtr)cur)->href));
-- case XML_ELEMENT_DECL:
-- /* TODO !!! */
-- return(NULL);
-- case XML_ATTRIBUTE_DECL:
-- /* TODO !!! */
-- return(NULL);
-- case XML_ENTITY_DECL:
-- /* TODO !!! */
-- return(NULL);
-- case XML_CDATA_SECTION_NODE:
-- case XML_TEXT_NODE:
-- if (cur->content != NULL)
--#ifndef XML_USE_BUFFER_CONTENT
-- return(xmlStrdup(cur->content));
--#else
-- return(xmlStrdup(xmlBufferContent(cur->content)));
--#endif
-- return(NULL);
-- }
-- return(NULL);
--}
--
--/**
-- * xmlNodeSetContent:
-- * @cur: the node being modified
-- * @content: the new value of the content
-- *
-- * Replace the content of a node.
-- */
--void
--xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeSetContent : node == NULL\n");
--#endif
-- return;
-- }
-- switch (cur->type) {
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_ELEMENT_NODE:
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlFree(cur->content);
--#else
-- xmlBufferFree(cur->content);
--#endif
-- cur->content = NULL;
-- }
-- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-- cur->children = xmlStringGetNodeList(cur->doc, content);
-- UPDATE_LAST_CHILD_AND_PARENT(cur)
-- break;
-- case XML_ATTRIBUTE_NODE:
-- break;
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlFree(cur->content);
--#else
-- xmlBufferFree(cur->content);
--#endif
-- }
-- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-- cur->last = cur->children = NULL;
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrdup(content);
--#else
-- cur->content = xmlBufferCreateSize(0);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, -1);
--#endif
-- } else
-- cur->content = NULL;
-- break;
-- case XML_DOCUMENT_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- break;
-- case XML_NOTATION_NODE:
-- break;
-- case XML_DTD_NODE:
-- break;
-- case XML_NAMESPACE_DECL:
-- break;
-- case XML_ELEMENT_DECL:
-- /* TODO !!! */
-- break;
-- case XML_ATTRIBUTE_DECL:
-- /* TODO !!! */
-- break;
-- case XML_ENTITY_DECL:
-- /* TODO !!! */
-- break;
-- }
--}
--
--/**
-- * xmlNodeSetContentLen:
-- * @cur: the node being modified
-- * @content: the new value of the content
-- * @len: the size of @content
-- *
-- * Replace the content of a node.
-- */
--void
--xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeSetContentLen : node == NULL\n");
--#endif
-- return;
-- }
-- switch (cur->type) {
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_ELEMENT_NODE:
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlFree(cur->content);
--#else
-- xmlBufferFree(cur->content);
--#endif
-- cur->content = NULL;
-- }
-- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-- cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
-- UPDATE_LAST_CHILD_AND_PARENT(cur)
-- break;
-- case XML_ATTRIBUTE_NODE:
-- break;
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_NOTATION_NODE:
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlFree(cur->content);
--#else
-- xmlBufferFree(cur->content);
--#endif
-- }
-- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-- cur->children = cur->last = NULL;
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrndup(content, len);
--#else
-- cur->content = xmlBufferCreateSize(len);
-- xmlBufferSetAllocationScheme(cur->content,
-- xmlGetBufferAllocationScheme());
-- xmlBufferAdd(cur->content, content, len);
--#endif
-- } else
-- cur->content = NULL;
-- break;
-- case XML_DOCUMENT_NODE:
-- case XML_DTD_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- break;
-- case XML_ELEMENT_DECL:
-- /* TODO !!! */
-- break;
-- case XML_ATTRIBUTE_DECL:
-- /* TODO !!! */
-- break;
-- case XML_ENTITY_DECL:
-- /* TODO !!! */
-- break;
-- }
--}
--
--/**
-- * xmlNodeAddContentLen:
-- * @cur: the node being modified
-- * @content: extra content
-- * @len: the size of @content
-- *
-- * Append the extra substring to the node content.
-- */
--void
--xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeAddContentLen : node == NULL\n");
--#endif
-- return;
-- }
-- if (len <= 0) return;
-- switch (cur->type) {
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_ELEMENT_NODE: {
-- xmlNodePtr last = NULL, newNode;
--
-- if (cur->children != NULL) {
-- last = cur->last;
-- } else {
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->children = xmlStringGetNodeList(cur->doc, cur->content);
--#else
-- cur->children = xmlStringGetNodeList(cur->doc,
-- xmlBufferContent(cur->content));
--#endif
-- UPDATE_LAST_CHILD_AND_PARENT(cur)
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlFree(cur->content);
--#else
-- xmlBufferFree(cur->content);
--#endif
-- cur->content = NULL;
-- last = cur->last;
-- }
-- }
-- newNode = xmlNewTextLen(content, len);
-- if (newNode != NULL) {
-- xmlAddChild(cur, newNode);
-- if ((last != NULL) && (last->next == newNode)) {
-- xmlTextMerge(last, newNode);
-- }
-- }
-- break;
-- }
-- case XML_ATTRIBUTE_NODE:
-- break;
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_NOTATION_NODE:
-- if (content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- cur->content = xmlStrncat(cur->content, content, len);
--#else
-- xmlBufferAdd(cur->content, content, len);
--#endif
-- }
-- case XML_DOCUMENT_NODE:
-- case XML_DTD_NODE:
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- break;
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- break;
-- }
--}
--
--/**
-- * xmlNodeAddContent:
-- * @cur: the node being modified
-- * @content: extra content
-- *
-- * Append the extra substring to the node content.
-- */
--void
--xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) {
-- int len;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeAddContent : node == NULL\n");
--#endif
-- return;
-- }
-- if (content == NULL) return;
-- len = xmlStrlen(content);
-- xmlNodeAddContentLen(cur, content, len);
--}
--
--/**
-- * xmlTextMerge:
-- * @first: the first text node
-- * @second: the second text node being merged
-- *
-- * Merge two text nodes into one
-- * Returns the first text node augmented
-- */
--xmlNodePtr
--xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
-- if (first == NULL) return(second);
-- if (second == NULL) return(first);
-- if (first->type != XML_TEXT_NODE) return(first);
-- if (second->type != XML_TEXT_NODE) return(first);
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlNodeAddContent(first, second->content);
--#else
-- xmlNodeAddContent(first, xmlBufferContent(second->content));
--#endif
-- xmlUnlinkNode(second);
-- xmlFreeNode(second);
-- return(first);
--}
--
--/**
-- * xmlGetNsList:
-- * @doc: the document
-- * @node: the current node
-- *
-- * Search all the namespace applying to a given element.
-- * Returns an NULL terminated array of all the xmlNsPtr found
-- * that need to be freed by the caller or NULL if no
-- * namespace if defined
-- */
--xmlNsPtr *
--xmlGetNsList(xmlDocPtr doc, xmlNodePtr node) {
-- xmlNsPtr cur;
-- xmlNsPtr *ret = NULL;
-- int nbns = 0;
-- int maxns = 10;
-- int i;
--
-- while (node != NULL) {
-- cur = node->nsDef;
-- while (cur != NULL) {
-- if (ret == NULL) {
-- ret = (xmlNsPtr *) xmlMalloc((maxns + 1) * sizeof(xmlNsPtr));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlGetNsList : out of memory!\n");
-- return(NULL);
-- }
-- ret[nbns] = NULL;
-- }
-- for (i = 0;i < nbns;i++) {
-- if ((cur->prefix == ret[i]->prefix) ||
-- (xmlStrEqual(cur->prefix, ret[i]->prefix))) break;
-- }
-- if (i >= nbns) {
-- if (nbns >= maxns) {
-- maxns *= 2;
-- ret = (xmlNsPtr *) xmlRealloc(ret,
-- (maxns + 1) * sizeof(xmlNsPtr));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlGetNsList : realloc failed!\n");
-- return(NULL);
-- }
-- }
-- ret[nbns++] = cur;
-- ret[nbns] = NULL;
-- }
--
-- cur = cur->next;
-- }
-- node = node->parent;
-- }
-- return(ret);
--}
--
--/**
-- * xmlSearchNs:
-- * @doc: the document
-- * @node: the current node
-- * @nameSpace: the namespace string
-- *
-- * Search a Ns registered under a given name space for a document.
-- * recurse on the parents until it finds the defined namespace
-- * or return NULL otherwise.
-- * @nameSpace can be NULL, this is a search for the default namespace.
-- * We don't allow to cross entities boundaries. If you don't declare
-- * the namespace within those you will be in troubles !!! A warning
-- * is generated to cover this case.
-- *
-- * Returns the namespace pointer or NULL.
-- */
--xmlNsPtr
--xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
-- xmlNsPtr cur;
--
-- if (node == NULL) return(NULL);
-- while (node != NULL) {
-- if ((node->type == XML_ENTITY_REF_NODE) ||
-- (node->type == XML_ENTITY_NODE) ||
-- (node->type == XML_ENTITY_DECL))
-- return(NULL);
-- if (node->type == XML_ELEMENT_NODE) {
-- cur = node->nsDef;
-- while (cur != NULL) {
-- if ((cur->prefix == NULL) && (nameSpace == NULL) &&
-- (cur->href != NULL))
-- return(cur);
-- if ((cur->prefix != NULL) && (nameSpace != NULL) &&
-- (cur->href != NULL) &&
-- (xmlStrEqual(cur->prefix, nameSpace)))
-- return(cur);
-- cur = cur->next;
-- }
-- }
-- node = node->parent;
-- }
-- return(NULL);
--}
--
--/**
-- * xmlSearchNsByHref:
-- * @doc: the document
-- * @node: the current node
-- * @href: the namespace value
-- *
-- * Search a Ns aliasing a given URI. Recurse on the parents until it finds
-- * the defined namespace or return NULL otherwise.
-- * Returns the namespace pointer or NULL.
-- */
--xmlNsPtr
--xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href) {
-- xmlNsPtr cur;
-- xmlNodePtr orig = node;
--
-- if ((node == NULL) || (href == NULL)) return(NULL);
-- while (node != NULL) {
-- cur = node->nsDef;
-- while (cur != NULL) {
-- if ((cur->href != NULL) && (href != NULL) &&
-- (xmlStrEqual(cur->href, href))) {
-- /*
-- * Check that the prefix is not shadowed between orig and node
-- */
-- xmlNodePtr check = orig;
-- xmlNsPtr tst;
--
-- while (check != node) {
-- tst = check->nsDef;
-- while (tst != NULL) {
-- if ((tst->prefix == NULL) && (cur->prefix == NULL))
-- goto shadowed;
-- if ((tst->prefix != NULL) && (cur->prefix != NULL) &&
-- (xmlStrEqual(tst->prefix, cur->prefix)))
-- goto shadowed;
-- tst = tst->next;
-- }
-- check = check->parent;
-- }
-- return(cur);
-- }
--shadowed:
-- cur = cur->next;
-- }
-- node = node->parent;
-- }
-- return(NULL);
--}
--
--/**
-- * xmlNewReconciliedNs
-- * @doc: the document
-- * @tree: a node expected to hold the new namespace
-- * @ns: the original namespace
-- *
-- * This function tries to locate a namespace definition in a tree
-- * ancestors, or create a new namespace definition node similar to
-- * @ns trying to reuse the same prefix. However if the given prefix is
-- * null (default namespace) or reused within the subtree defined by
-- * @tree or on one of its ancestors then a new prefix is generated.
-- * Returns the (new) namespace definition or NULL in case of error
-- */
--xmlNsPtr
--xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
-- xmlNsPtr def;
-- xmlChar prefix[50];
-- int counter = 1;
--
-- if (tree == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewReconciliedNs : tree == NULL\n");
--#endif
-- return(NULL);
-- }
-- if (ns == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewReconciliedNs : ns == NULL\n");
--#endif
-- return(NULL);
-- }
-- /*
-- * Search an existing namespace definition inherited.
-- */
-- def = xmlSearchNsByHref(doc, tree, ns->href);
-- if (def != NULL)
-- return(def);
--
-- /*
-- * Find a close prefix which is not already in use.
-- * Let's strip namespace prefixes longer than 20 chars !
-- */
-- sprintf((char *) prefix, "%.20s", ns->prefix);
-- def = xmlSearchNs(doc, tree, prefix);
-- while (def != NULL) {
-- if (counter > 1000) return(NULL);
-- sprintf((char *) prefix, "%.20s%d", ns->prefix, counter++);
-- def = xmlSearchNs(doc, tree, prefix);
-- }
--
-- /*
-- * Ok, now we are ready to create a new one.
-- */
-- def = xmlNewNs(tree, ns->href, prefix);
-- return(def);
--}
--
--/**
-- * xmlReconciliateNs
-- * @doc: the document
-- * @tree: a node defining the subtree to reconciliate
-- *
-- * This function checks that all the namespaces declared within the given
-- * tree are properly declared. This is needed for example after Copy or Cut
-- * and then paste operations. The subtree may still hold pointers to
-- * namespace declarations outside the subtree or invalid/masked. As much
-- * as possible the function try tu reuse the existing namespaces found in
-- * the new environment. If not possible the new namespaces are redeclared
-- * on @tree at the top of the given subtree.
-- * Returns the number of namespace declarations created or -1 in case of error.
-- */
--int
--xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
-- xmlNsPtr *oldNs = NULL;
-- xmlNsPtr *newNs = NULL;
-- int sizeCache = 0;
-- int nbCache = 0;
--
-- xmlNsPtr n;
-- xmlNodePtr node = tree;
-- xmlAttrPtr attr;
-- int ret = 0, i;
--
-- while (node != NULL) {
-- /*
-- * Reconciliate the node namespace
-- */
-- if (node->ns != NULL) {
-- /*
-- * initialize the cache if needed
-- */
-- if (sizeCache == 0) {
-- sizeCache = 10;
-- oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-- sizeof(xmlNsPtr));
-- if (oldNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- return(-1);
-- }
-- newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-- sizeof(xmlNsPtr));
-- if (newNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- xmlFree(oldNs);
-- return(-1);
-- }
-- }
-- for (i = 0;i < nbCache;i++) {
-- if (oldNs[i] == node->ns) {
-- node->ns = newNs[i];
-- break;
-- }
-- }
-- if (i == nbCache) {
-- /*
-- * Ok we need to recreate a new namespace definition
-- */
-- n = xmlNewReconciliedNs(doc, tree, node->ns);
-- if (n != NULL) { /* :-( what if else ??? */
-- /*
-- * check if we need to grow the cache buffers.
-- */
-- if (sizeCache <= nbCache) {
-- sizeCache *= 2;
-- oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
-- sizeof(xmlNsPtr));
-- if (oldNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- xmlFree(newNs);
-- return(-1);
-- }
-- newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
-- sizeof(xmlNsPtr));
-- if (newNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- xmlFree(oldNs);
-- return(-1);
-- }
-- }
-- newNs[nbCache] = n;
-- oldNs[nbCache++] = node->ns;
-- node->ns = n;
-- }
-- }
-- }
-- /*
-- * now check for namespace hold by attributes on the node.
-- */
-- attr = node->properties;
-- while (attr != NULL) {
-- if (attr->ns != NULL) {
-- /*
-- * initialize the cache if needed
-- */
-- if (sizeCache == 0) {
-- sizeCache = 10;
-- oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-- sizeof(xmlNsPtr));
-- if (oldNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- return(-1);
-- }
-- newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
-- sizeof(xmlNsPtr));
-- if (newNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- xmlFree(oldNs);
-- return(-1);
-- }
-- }
-- for (i = 0;i < nbCache;i++) {
-- if (oldNs[i] == attr->ns) {
-- node->ns = newNs[i];
-- break;
-- }
-- }
-- if (i == nbCache) {
-- /*
-- * Ok we need to recreate a new namespace definition
-- */
-- n = xmlNewReconciliedNs(doc, tree, attr->ns);
-- if (n != NULL) { /* :-( what if else ??? */
-- /*
-- * check if we need to grow the cache buffers.
-- */
-- if (sizeCache <= nbCache) {
-- sizeCache *= 2;
-- oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
-- sizeof(xmlNsPtr));
-- if (oldNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- xmlFree(newNs);
-- return(-1);
-- }
-- newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
-- sizeof(xmlNsPtr));
-- if (newNs == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlReconciliateNs : memory pbm\n");
-- xmlFree(oldNs);
-- return(-1);
-- }
-- }
-- newNs[nbCache] = n;
-- oldNs[nbCache++] = attr->ns;
-- attr->ns = n;
-- }
-- }
-- }
-- attr = attr->next;
-- }
--
-- /*
-- * Browse the full subtree, deep first
-- */
-- if (node->children != NULL) {
-- /* deep first */
-- node = node->children;
-- } else if ((node != tree) && (node->next != NULL)) {
-- /* then siblings */
-- node = node->next;
-- } else if (node != tree) {
-- /* go up to parents->next if needed */
-- while (node != tree) {
-- if (node->parent != NULL)
-- node = node->parent;
-- if ((node != tree) && (node->next != NULL)) {
-- node = node->next;
-- break;
-- }
-- if (node->parent == NULL) {
-- node = NULL;
-- break;
-- }
-- }
-- /* exit condition */
-- if (node == tree)
-- node = NULL;
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlHasProp:
-- * @node: the node
-- * @name: the attribute name
-- *
-- * Search an attribute associated to a node
-- * This function also looks in DTD attribute declaration for #FIXED or
-- * default declaration values unless DTD use has been turned off.
-- *
-- * Returns the attribute or the attribute declaration or NULL if
-- * neither was found.
-- */
--xmlAttrPtr
--xmlHasProp(xmlNodePtr node, const xmlChar *name) {
-- xmlAttrPtr prop;
-- xmlDocPtr doc;
--
-- if ((node == NULL) || (name == NULL)) return(NULL);
-- /*
-- * Check on the properties attached to the node
-- */
-- prop = node->properties;
-- while (prop != NULL) {
-- if (xmlStrEqual(prop->name, name)) {
-- return(prop);
-- }
-- prop = prop->next;
-- }
-- if (!xmlCheckDTD) return(NULL);
--
-- /*
-- * Check if there is a default declaration in the internal
-- * or external subsets
-- */
-- doc = node->doc;
-- if (doc != NULL) {
-- xmlAttributePtr attrDecl;
-- if (doc->intSubset != NULL) {
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
-- if (attrDecl != NULL)
-- return((xmlAttrPtr) attrDecl);
-- }
-- }
-- return(NULL);
--}
--
--/**
-- * xmlGetProp:
-- * @node: the node
-- * @name: the attribute name
-- *
-- * Search and get the value of an attribute associated to a node
-- * This does the entity substitution.
-- * This function looks in DTD attribute declaration for #FIXED or
-- * default declaration values unless DTD use has been turned off.
-- *
-- * Returns the attribute value or NULL if not found.
-- * It's up to the caller to free the memory.
-- */
--xmlChar *
--xmlGetProp(xmlNodePtr node, const xmlChar *name) {
-- xmlAttrPtr prop;
-- xmlDocPtr doc;
--
-- if ((node == NULL) || (name == NULL)) return(NULL);
-- /*
-- * Check on the properties attached to the node
-- */
-- prop = node->properties;
-- while (prop != NULL) {
-- if (xmlStrEqual(prop->name, name)) {
-- xmlChar *ret;
--
-- ret = xmlNodeListGetString(node->doc, prop->children, 1);
-- if (ret == NULL) return(xmlStrdup((xmlChar *)""));
-- return(ret);
-- }
-- prop = prop->next;
-- }
-- if (!xmlCheckDTD) return(NULL);
--
-- /*
-- * Check if there is a default declaration in the internal
-- * or external subsets
-- */
-- doc = node->doc;
-- if (doc != NULL) {
-- xmlAttributePtr attrDecl;
-- if (doc->intSubset != NULL) {
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
-- if (attrDecl != NULL)
-- return(xmlStrdup(attrDecl->defaultValue));
-- }
-- }
-- return(NULL);
--}
--
--/**
-- * xmlGetNsProp:
-- * @node: the node
-- * @name: the attribute name
-- * @namespace: the URI of the namespace
-- *
-- * Search and get the value of an attribute associated to a node
-- * This attribute has to be anchored in the namespace specified.
-- * This does the entity substitution.
-- * This function looks in DTD attribute declaration for #FIXED or
-- * default declaration values unless DTD use has been turned off.
-- *
-- * Returns the attribute value or NULL if not found.
-- * It's up to the caller to free the memory.
-- */
--xmlChar *
--xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) {
-- xmlAttrPtr prop;
-- xmlDocPtr doc;
-- xmlNsPtr ns;
--
-- if (node == NULL)
-- return(NULL);
--
-- prop = node->properties;
-- if (namespace == NULL)
-- return(xmlGetProp(node, name));
-- while (prop != NULL) {
-- /*
-- * One need to have
-- * - same attribute names
-- * - and the attribute carrying that namespace
-- * or
-- * no namespace on the attribute and the element carrying it
-- */
-- if ((xmlStrEqual(prop->name, name)) &&
-- (((prop->ns == NULL) && (node->ns != NULL) &&
-- (xmlStrEqual(node->ns->href, namespace))) ||
-- ((prop->ns != NULL) && (xmlStrEqual(prop->ns->href, namespace))))) {
-- xmlChar *ret;
--
-- ret = xmlNodeListGetString(node->doc, prop->children, 1);
-- if (ret == NULL) return(xmlStrdup((xmlChar *)""));
-- return(ret);
-- }
-- prop = prop->next;
-- }
-- if (!xmlCheckDTD) return(NULL);
--
-- /*
-- * Check if there is a default declaration in the internal
-- * or external subsets
-- */
-- doc = node->doc;
-- if (doc != NULL) {
-- xmlAttributePtr attrDecl;
-- if (doc->intSubset != NULL) {
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
--
-- if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) {
-- /*
-- * The DTD declaration only allows a prefix search
-- */
-- ns = xmlSearchNs(doc, node, attrDecl->prefix);
-- if ((ns != NULL) && (xmlStrEqual(ns->href, namespace)))
-- return(xmlStrdup(attrDecl->defaultValue));
-- }
-- }
-- }
-- return(NULL);
--}
--
--/**
-- * xmlSetProp:
-- * @node: the node
-- * @name: the attribute name
-- * @value: the attribute value
-- *
-- * Set (or reset) an attribute carried by a node.
-- * Returns the attribute pointer.
-- */
--xmlAttrPtr
--xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
-- xmlAttrPtr prop = node->properties;
-- xmlDocPtr doc = NULL;
--
-- if ((node == NULL) || (name == NULL))
-- return(NULL);
-- doc = node->doc;
-- while (prop != NULL) {
-- if (xmlStrEqual(prop->name, name)) {
-- if (prop->children != NULL)
-- xmlFreeNodeList(prop->children);
-- prop->children = NULL;
-- prop->last = NULL;
-- if (value != NULL) {
-- xmlChar *buffer;
-- xmlNodePtr tmp;
--
-- buffer = xmlEncodeEntitiesReentrant(node->doc, value);
-- prop->children = xmlStringGetNodeList(node->doc, buffer);
-- prop->last = NULL;
-- prop->doc = doc;
-- tmp = prop->children;
-- while (tmp != NULL) {
-- tmp->parent = (xmlNodePtr) prop;
-- tmp->doc = doc;
-- if (tmp->next == NULL)
-- prop->last = tmp;
-- tmp = tmp->next;
-- }
-- xmlFree(buffer);
-- }
-- return(prop);
-- }
-- prop = prop->next;
-- }
-- prop = xmlNewProp(node, name, value);
-- return(prop);
--}
--
--/**
-- * xmlSetNsProp:
-- * @node: the node
-- * @ns: the namespace definition
-- * @name: the attribute name
-- * @value: the attribute value
-- *
-- * Set (or reset) an attribute carried by a node.
-- * The ns structure must be in scope, this is not checked.
-- *
-- * Returns the attribute pointer.
-- */
--xmlAttrPtr
--xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
-- const xmlChar *value) {
-- xmlAttrPtr prop;
--
-- if ((node == NULL) || (name == NULL))
-- return(NULL);
--
-- if (ns == NULL)
-- return(xmlSetProp(node, name, value));
-- if (ns->href == NULL)
-- return(NULL);
-- prop = node->properties;
--
-- while (prop != NULL) {
-- /*
-- * One need to have
-- * - same attribute names
-- * - and the attribute carrying that namespace
-- * or
-- * no namespace on the attribute and the element carrying it
-- */
-- if ((xmlStrEqual(prop->name, name)) &&
-- (((prop->ns == NULL) && (node->ns != NULL) &&
-- (xmlStrEqual(node->ns->href, ns->href))) ||
-- ((prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))))) {
-- if (prop->children != NULL)
-- xmlFreeNodeList(prop->children);
-- prop->children = NULL;
-- prop->last = NULL;
-- prop->ns = ns;
-- if (value != NULL) {
-- xmlChar *buffer;
-- xmlNodePtr tmp;
--
-- buffer = xmlEncodeEntitiesReentrant(node->doc, value);
-- prop->children = xmlStringGetNodeList(node->doc, buffer);
-- prop->last = NULL;
-- tmp = prop->children;
-- while (tmp != NULL) {
-- tmp->parent = (xmlNodePtr) prop;
-- if (tmp->next == NULL)
-- prop->last = tmp;
-- tmp = tmp->next;
-- }
-- xmlFree(buffer);
-- }
-- return(prop);
-- }
-- prop = prop->next;
-- }
-- prop = xmlNewNsProp(node, ns, name, value);
-- return(prop);
--}
--
--/**
-- * xmlNodeIsText:
-- * @node: the node
-- *
-- * Is this node a Text node ?
-- * Returns 1 yes, 0 no
-- */
--int
--xmlNodeIsText(xmlNodePtr node) {
-- if (node == NULL) return(0);
--
-- if (node->type == XML_TEXT_NODE) return(1);
-- return(0);
--}
--
--/**
-- * xmlIsBlankNode:
-- * @node: the node
-- *
-- * Checks whether this node is an empty or whitespace only
-- * (and possibly ignorable) text-node.
-- *
-- * Returns 1 yes, 0 no
-- */
--int
--xmlIsBlankNode(xmlNodePtr node) {
-- const xmlChar *cur;
-- if (node == NULL) return(0);
--
-- if (node->type != XML_TEXT_NODE) return(0);
-- if (node->content == NULL) return(1);
--#ifndef XML_USE_BUFFER_CONTENT
-- cur = node->content;
--#else
-- cur = xmlBufferContent(node->content);
--#endif
-- while (*cur != 0) {
-- if (!IS_BLANK(*cur)) return(0);
-- cur++;
-- }
--
-- return(1);
--}
--
--/**
-- * xmlTextConcat:
-- * @node: the node
-- * @content: the content
-- * @len: @content lenght
-- *
-- * Concat the given string at the end of the existing node content
-- */
--
--void
--xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
-- if (node == NULL) return;
--
-- if ((node->type != XML_TEXT_NODE) &&
-- (node->type != XML_CDATA_SECTION_NODE)) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlTextConcat: node is not text nor cdata\n");
--#endif
-- return;
-- }
--#ifndef XML_USE_BUFFER_CONTENT
-- node->content = xmlStrncat(node->content, content, len);
--#else
-- xmlBufferAdd(node->content, content, len);
--#endif
--}
--
--/************************************************************************
-- * *
-- * Output : to a FILE or in memory *
-- * *
-- ************************************************************************/
--
--#define BASE_BUFFER_SIZE 4000
--
--/**
-- * xmlBufferCreate:
-- *
-- * routine to create an XML buffer.
-- * returns the new structure.
-- */
--xmlBufferPtr
--xmlBufferCreate(void) {
-- xmlBufferPtr ret;
--
-- ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferCreate : out of memory!\n");
-- return(NULL);
-- }
-- ret->use = 0;
-- ret->size = BASE_BUFFER_SIZE;
-- ret->alloc = xmlBufferAllocScheme;
-- ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
-- if (ret->content == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferCreate : out of memory!\n");
-- xmlFree(ret);
-- return(NULL);
-- }
-- ret->content[0] = 0;
-- return(ret);
--}
--
--/**
-- * xmlBufferCreateSize:
-- * @size: initial size of buffer
-- *
-- * routine to create an XML buffer.
-- * returns the new structure.
-- */
--xmlBufferPtr
--xmlBufferCreateSize(size_t size) {
-- xmlBufferPtr ret;
--
-- ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferCreate : out of memory!\n");
-- return(NULL);
-- }
-- ret->use = 0;
-- ret->alloc = xmlBufferAllocScheme;
-- ret->size = (size ? size+2 : 0); /* +1 for ending null */
-- if (ret->size){
-- ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
-- if (ret->content == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferCreate : out of memory!\n");
-- xmlFree(ret);
-- return(NULL);
-- }
-- ret->content[0] = 0;
-- } else
-- ret->content = NULL;
-- return(ret);
--}
--
--/**
-- * xmlBufferSetAllocationScheme:
-- * @buf: the buffer to free
-- * @scheme: allocation scheme to use
-- *
-- * Sets the allocation scheme for this buffer
-- */
--void
--xmlBufferSetAllocationScheme(xmlBufferPtr buf,
-- xmlBufferAllocationScheme scheme) {
-- if (buf == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferSetAllocationScheme: buf == NULL\n");
--#endif
-- return;
-- }
--
-- buf->alloc = scheme;
--}
--
--/**
-- * xmlBufferFree:
-- * @buf: the buffer to free
-- *
-- * Frees an XML buffer.
-- */
--void
--xmlBufferFree(xmlBufferPtr buf) {
-- if (buf == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferFree: buf == NULL\n");
--#endif
-- return;
-- }
-- if (buf->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- memset(buf->content, -1, BASE_BUFFER_SIZE);
--#else
-- memset(buf->content, -1, buf->size);
--#endif
-- xmlFree(buf->content);
-- }
-- memset(buf, -1, sizeof(xmlBuffer));
-- xmlFree(buf);
--}
--
--/**
-- * xmlBufferEmpty:
-- * @buf: the buffer
-- *
-- * empty a buffer.
-- */
--void
--xmlBufferEmpty(xmlBufferPtr buf) {
-- if (buf->content == NULL) return;
-- buf->use = 0;
-- memset(buf->content, -1, buf->size);/* just for debug */
--}
--
--/**
-- * xmlBufferShrink:
-- * @buf: the buffer to dump
-- * @len: the number of xmlChar to remove
-- *
-- * Remove the beginning of an XML buffer.
-- *
-- * Returns the number of xmlChar removed, or -1 in case of failure.
-- */
--int
--xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
-- if (len == 0) return(0);
-- if (len > buf->use) return(-1);
--
-- buf->use -= len;
-- memmove(buf->content, &buf->content[len], buf->use * sizeof(xmlChar));
--
-- buf->content[buf->use] = 0;
-- return(len);
--}
--
--/**
-- * xmlBufferGrow:
-- * @buf: the buffer
-- * @len: the minimum free size to allocate
-- *
-- * Grow the available space of an XML buffer.
-- *
-- * Returns the new available space or -1 in case of error
-- */
--int
--xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
-- int size;
-- xmlChar *newbuf;
--
-- if (len + buf->use < buf->size) return(0);
--
-- size = buf->use + len + 100;
--
-- newbuf = (xmlChar *) xmlRealloc(buf->content, size);
-- if (newbuf == NULL) return(-1);
-- buf->content = newbuf;
-- buf->size = size;
-- return(buf->size - buf->use);
--}
--
--/**
-- * xmlBufferDump:
-- * @file: the file output
-- * @buf: the buffer to dump
-- *
-- * Dumps an XML buffer to a FILE *.
-- * Returns the number of xmlChar written
-- */
--int
--xmlBufferDump(FILE *file, xmlBufferPtr buf) {
-- int ret;
--
-- if (buf == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferDump: buf == NULL\n");
--#endif
-- return(0);
-- }
-- if (buf->content == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferDump: buf->content == NULL\n");
--#endif
-- return(0);
-- }
-- if (file == NULL) file = stdout;
-- ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
-- return(ret);
--}
--
--/**
-- * xmlBufferContent:
-- * @buf: the buffer to resize
-- *
-- * Returns the internal content
-- */
--
--const xmlChar*
--xmlBufferContent(const xmlBufferPtr buf)
--{
-- if(!buf)
-- return NULL;
--
-- return buf->content;
--}
--
--/**
-- * xmlBufferLength:
-- * @buf: the buffer
-- *
-- * Returns the length of data in the internal content
-- */
--
--int
--xmlBufferLength(const xmlBufferPtr buf)
--{
-- if(!buf)
-- return 0;
--
-- return buf->use;
--}
--
--/**
-- * xmlBufferResize:
-- * @buf: the buffer to resize
-- * @size: the desired size
-- *
-- * Resize a buffer to accomodate minimum size of @size.
-- *
-- * Returns 0 in case of problems, 1 otherwise
-- */
--int
--xmlBufferResize(xmlBufferPtr buf, unsigned int size)
--{
-- unsigned int newSize;
-- xmlChar* rebuf = NULL;
--
-- /*take care of empty case*/
-- newSize = (buf->size ? buf->size*2 : size);
--
-- /* Don't resize if we don't have to */
-- if (size < buf->size)
-- return 1;
--
-- /* figure out new size */
-- switch (buf->alloc){
-- case XML_BUFFER_ALLOC_DOUBLEIT:
-- while (size > newSize) newSize *= 2;
-- break;
-- case XML_BUFFER_ALLOC_EXACT:
-- newSize = size+10;
-- break;
-- default:
-- newSize = size+10;
-- break;
-- }
--
-- if (buf->content == NULL)
-- rebuf = (xmlChar *) xmlMalloc(newSize * sizeof(xmlChar));
-- else
-- rebuf = (xmlChar *) xmlRealloc(buf->content,
-- newSize * sizeof(xmlChar));
-- if (rebuf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd : out of memory!\n");
-- return 0;
-- }
-- buf->content = rebuf;
-- buf->size = newSize;
--
-- return 1;
--}
--
--/**
-- * xmlBufferAdd:
-- * @buf: the buffer to dump
-- * @str: the xmlChar string
-- * @len: the number of xmlChar to add
-- *
-- * Add a string range to an XML buffer. if len == -1, the lenght of
-- * str is recomputed.
-- */
--void
--xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
-- unsigned int needSize;
--
-- if (str == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd: str == NULL\n");
--#endif
-- return;
-- }
-- if (len < -1) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd: len < 0\n");
--#endif
-- return;
-- }
-- if (len == 0) return;
--
-- if (len < 0)
-- len = xmlStrlen(str);
--
-- if (len <= 0) return;
--
-- needSize = buf->use + len + 2;
-- if (needSize > buf->size){
-- if (!xmlBufferResize(buf, needSize)){
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd : out of memory!\n");
-- return;
-- }
-- }
--
-- memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
-- buf->use += len;
-- buf->content[buf->use] = 0;
--}
--
--/**
-- * xmlBufferAddHead:
-- * @buf: the buffer
-- * @str: the xmlChar string
-- * @len: the number of xmlChar to add
-- *
-- * Add a string range to the beginning of an XML buffer.
-- * if len == -1, the lenght of @str is recomputed.
-- */
--void
--xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
-- unsigned int needSize;
--
-- if (str == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd: str == NULL\n");
--#endif
-- return;
-- }
-- if (len < -1) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd: len < 0\n");
--#endif
-- return;
-- }
-- if (len == 0) return;
--
-- if (len < 0)
-- len = xmlStrlen(str);
--
-- if (len <= 0) return;
--
-- needSize = buf->use + len + 2;
-- if (needSize > buf->size){
-- if (!xmlBufferResize(buf, needSize)){
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAddHead : out of memory!\n");
-- return;
-- }
-- }
--
-- memmove(&buf->content[len], &buf->content[0], buf->use * sizeof(xmlChar));
-- memmove(&buf->content[0], str, len * sizeof(xmlChar));
-- buf->use += len;
-- buf->content[buf->use] = 0;
--}
--
--/**
-- * xmlBufferCat:
-- * @buf: the buffer to dump
-- * @str: the xmlChar string
-- *
-- * Append a zero terminated string to an XML buffer.
-- */
--void
--xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
-- if (str != NULL)
-- xmlBufferAdd(buf, str, -1);
--}
--
--/**
-- * xmlBufferCCat:
-- * @buf: the buffer to dump
-- * @str: the C char string
-- *
-- * Append a zero terminated C string to an XML buffer.
-- */
--void
--xmlBufferCCat(xmlBufferPtr buf, const char *str) {
-- const char *cur;
--
-- if (str == NULL) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferAdd: str == NULL\n");
--#endif
-- return;
-- }
-- for (cur = str;*cur != 0;cur++) {
-- if (buf->use + 10 >= buf->size) {
-- if (!xmlBufferResize(buf, buf->use+10)){
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferCCat : out of memory!\n");
-- return;
-- }
-- }
-- buf->content[buf->use++] = *cur;
-- }
-- buf->content[buf->use] = 0;
--}
--
--/**
-- * xmlBufferWriteCHAR:
-- * @buf: the XML buffer
-- * @string: the string to add
-- *
-- * routine which manages and grows an output buffer. This one adds
-- * xmlChars at the end of the buffer.
-- */
--void
--#ifdef VMS
--xmlBufferWriteXmlCHAR
--#else
--xmlBufferWriteCHAR
--#endif
--(xmlBufferPtr buf, const xmlChar *string) {
-- xmlBufferCat(buf, string);
--}
--
--/**
-- * xmlBufferWriteChar:
-- * @buf: the XML buffer output
-- * @string: the string to add
-- *
-- * routine which manage and grows an output buffer. This one add
-- * C chars at the end of the array.
-- */
--void
--xmlBufferWriteChar(xmlBufferPtr buf, const char *string) {
-- xmlBufferCCat(buf, string);
--}
--
--
--/**
-- * xmlBufferWriteQuotedString:
-- * @buf: the XML buffer output
-- * @string: the string to add
-- *
-- * routine which manage and grows an output buffer. This one writes
-- * a quoted or double quoted xmlChar string, checking first if it holds
-- * quote or double-quotes internally
-- */
--void
--xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
-- if (xmlStrchr(string, '"')) {
-- if (xmlStrchr(string, '\'')) {
--#ifdef DEBUG_BUFFER
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
--#endif
-- }
-- xmlBufferCCat(buf, "'");
-- xmlBufferCat(buf, string);
-- xmlBufferCCat(buf, "'");
-- } else {
-- xmlBufferCCat(buf, "\"");
-- xmlBufferCat(buf, string);
-- xmlBufferCCat(buf, "\"");
-- }
--}
--
--
--/************************************************************************
-- * *
-- * Dumping XML tree content to a simple buffer *
-- * *
-- ************************************************************************/
--
--void
--xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-- int format);
--static void
--xmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-- int format);
--void
--htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur);
--
--/**
-- * xmlNsDump:
-- * @buf: the XML buffer output
-- * @cur: a namespace
-- *
-- * Dump a local Namespace definition.
-- * Should be called in the context of attributes dumps.
-- */
--static void
--xmlNsDump(xmlBufferPtr buf, xmlNsPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNsDump : Ns == NULL\n");
--#endif
-- return;
-- }
-- if (cur->type == XML_LOCAL_NAMESPACE) {
-- /* Within the context of an element attributes */
-- if (cur->prefix != NULL) {
-- xmlBufferWriteChar(buf, " xmlns:");
-- xmlBufferWriteCHAR(buf, cur->prefix);
-- } else
-- xmlBufferWriteChar(buf, " xmlns");
-- xmlBufferWriteChar(buf, "=");
-- xmlBufferWriteQuotedString(buf, cur->href);
-- }
--}
--
--/**
-- * xmlNsListDump:
-- * @buf: the XML buffer output
-- * @cur: the first namespace
-- *
-- * Dump a list of local Namespace definitions.
-- * Should be called in the context of attributes dumps.
-- */
--static void
--xmlNsListDump(xmlBufferPtr buf, xmlNsPtr cur) {
-- while (cur != NULL) {
-- xmlNsDump(buf, cur);
-- cur = cur->next;
-- }
--}
--
--/**
-- * xmlDtdDump:
-- * @buf: the XML buffer output
-- * @doc: the document
-- *
-- * Dump the XML document DTD, if any.
-- */
--static void
--xmlDtdDump(xmlBufferPtr buf, xmlDtdPtr dtd) {
-- if (dtd == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDtdDump : no internal subset\n");
--#endif
-- return;
-- }
-- xmlBufferWriteChar(buf, "<!DOCTYPE ");
-- xmlBufferWriteCHAR(buf, dtd->name);
-- if (dtd->ExternalID != NULL) {
-- xmlBufferWriteChar(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf, dtd->ExternalID);
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteQuotedString(buf, dtd->SystemID);
-- } else if (dtd->SystemID != NULL) {
-- xmlBufferWriteChar(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf, dtd->SystemID);
-- }
-- if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
-- (dtd->attributes == NULL) && (dtd->notations == NULL)) {
-- xmlBufferWriteChar(buf, ">");
-- return;
-- }
-- xmlBufferWriteChar(buf, " [\n");
-- xmlNodeListDump(buf, dtd->doc, dtd->children, -1, 0);
--#if 0
-- if (dtd->entities != NULL)
-- xmlDumpEntitiesTable(buf, (xmlEntitiesTablePtr) dtd->entities);
-- if (dtd->notations != NULL)
-- xmlDumpNotationTable(buf, (xmlNotationTablePtr) dtd->notations);
-- if (dtd->elements != NULL)
-- xmlDumpElementTable(buf, (xmlElementTablePtr) dtd->elements);
-- if (dtd->attributes != NULL)
-- xmlDumpAttributeTable(buf, (xmlAttributeTablePtr) dtd->attributes);
--#endif
-- xmlBufferWriteChar(buf, "]>");
--}
--
--/**
-- * xmlAttrDump:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the attribute pointer
-- *
-- * Dump an XML attribute
-- */
--static void
--xmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-- xmlChar *value;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAttrDump : property == NULL\n");
--#endif
-- return;
-- }
-- xmlBufferWriteChar(buf, " ");
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- xmlBufferWriteCHAR(buf, cur->ns->prefix);
-- xmlBufferWriteChar(buf, ":");
-- }
-- xmlBufferWriteCHAR(buf, cur->name);
-- value = xmlNodeListGetString(doc, cur->children, 0);
-- if (value != NULL) {
-- xmlBufferWriteChar(buf, "=");
-- xmlBufferWriteQuotedString(buf, value);
-- xmlFree(value);
-- } else {
-- xmlBufferWriteChar(buf, "=\"\"");
-- }
--}
--
--/**
-- * xmlAttrListDump:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the first attribute pointer
-- *
-- * Dump a list of XML attributes
-- */
--static void
--xmlAttrListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAttrListDump : property == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- xmlAttrDump(buf, doc, cur);
-- cur = cur->next;
-- }
--}
--
--
--
--/**
-- * xmlNodeListDump:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the first node
-- * @level: the imbrication level for indenting
-- * @format: is formatting allowed
-- *
-- * Dump an XML node list, recursive behaviour,children are printed too.
-- */
--static void
--xmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-- int format) {
-- int i;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeListDump : node == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- if ((format) && (xmlIndentTreeOutput) &&
-- (cur->type == XML_ELEMENT_NODE))
-- for (i = 0;i < level;i++)
-- xmlBufferWriteChar(buf, " ");
-- xmlNodeDump(buf, doc, cur, level, format);
-- if (format) {
-- xmlBufferWriteChar(buf, "\n");
-- }
-- cur = cur->next;
-- }
--}
--
--/**
-- * xmlNodeDump:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the current node
-- * @level: the imbrication level for indenting
-- * @format: is formatting allowed
-- *
-- * Dump an XML node, recursive behaviour,children are printed too.
-- */
--void
--xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
-- int format) {
-- int i;
-- xmlNodePtr tmp;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeDump : node == NULL\n");
--#endif
-- return;
-- }
-- if (cur->type == XML_XINCLUDE_START)
-- return;
-- if (cur->type == XML_XINCLUDE_END)
-- return;
-- if (cur->type == XML_DTD_NODE) {
-- xmlDtdDump(buf, (xmlDtdPtr) cur);
-- return;
-- }
-- if (cur->type == XML_ELEMENT_DECL) {
-- xmlDumpElementDecl(buf, (xmlElementPtr) cur);
-- return;
-- }
-- if (cur->type == XML_ATTRIBUTE_DECL) {
-- xmlDumpAttributeDecl(buf, (xmlAttributePtr) cur);
-- return;
-- }
-- if (cur->type == XML_ENTITY_DECL) {
-- xmlDumpEntityDecl(buf, (xmlEntityPtr) cur);
-- return;
-- }
-- if (cur->type == XML_TEXT_NODE) {
-- if (cur->content != NULL) {
-- if ((cur->name == xmlStringText) ||
-- (cur->name != xmlStringTextNoenc)) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
--#else
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlBufferWriteCHAR(buf, buffer);
-- xmlFree(buffer);
-- }
-- } else {
-- /*
-- * Disable escaping, needed for XSLT
-- */
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlBufferWriteCHAR(buf, cur->content);
--#else
-- xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
--#endif
-- }
-- }
-- return;
-- }
-- if (cur->type == XML_PI_NODE) {
-- if (cur->content != NULL) {
-- xmlBufferWriteChar(buf, "<?");
-- xmlBufferWriteCHAR(buf, cur->name);
-- if (cur->content != NULL) {
-- xmlBufferWriteChar(buf, " ");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlBufferWriteCHAR(buf, cur->content);
--#else
-- xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
--#endif
-- }
-- xmlBufferWriteChar(buf, "?>");
-- } else {
-- xmlBufferWriteChar(buf, "<?");
-- xmlBufferWriteCHAR(buf, cur->name);
-- xmlBufferWriteChar(buf, "?>");
-- }
-- return;
-- }
-- if (cur->type == XML_COMMENT_NODE) {
-- if (cur->content != NULL) {
-- xmlBufferWriteChar(buf, "<!--");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlBufferWriteCHAR(buf, cur->content);
--#else
-- xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
--#endif
-- xmlBufferWriteChar(buf, "-->");
-- }
-- return;
-- }
-- if (cur->type == XML_ENTITY_REF_NODE) {
-- xmlBufferWriteChar(buf, "&");
-- xmlBufferWriteCHAR(buf, cur->name);
-- xmlBufferWriteChar(buf, ";");
-- return;
-- }
-- if (cur->type == XML_CDATA_SECTION_NODE) {
-- xmlBufferWriteChar(buf, "<![CDATA[");
-- if (cur->content != NULL)
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlBufferWriteCHAR(buf, cur->content);
--#else
-- xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
--#endif
-- xmlBufferWriteChar(buf, "]]>");
-- return;
-- }
--
-- if (format == 1) {
-- tmp = cur->children;
-- while (tmp != NULL) {
-- if ((tmp->type == XML_TEXT_NODE) ||
-- (tmp->type == XML_ENTITY_REF_NODE)) {
-- format = 0;
-- break;
-- }
-- tmp = tmp->next;
-- }
-- }
-- xmlBufferWriteChar(buf, "<");
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- xmlBufferWriteCHAR(buf, cur->ns->prefix);
-- xmlBufferWriteChar(buf, ":");
-- }
--
-- xmlBufferWriteCHAR(buf, cur->name);
-- if (cur->nsDef)
-- xmlNsListDump(buf, cur->nsDef);
-- if (cur->properties != NULL)
-- xmlAttrListDump(buf, doc, cur->properties);
--
-- if ((cur->content == NULL) && (cur->children == NULL) &&
-- (!xmlSaveNoEmptyTags)) {
-- xmlBufferWriteChar(buf, "/>");
-- return;
-- }
-- xmlBufferWriteChar(buf, ">");
-- if (cur->content != NULL) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
--#else
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlBufferWriteCHAR(buf, buffer);
-- xmlFree(buffer);
-- }
-- }
-- if (cur->children != NULL) {
-- if (format) xmlBufferWriteChar(buf, "\n");
-- xmlNodeListDump(buf, doc, cur->children,
-- (level >= 0?level+1:-1), format);
-- if ((xmlIndentTreeOutput) && (format))
-- for (i = 0;i < level;i++)
-- xmlBufferWriteChar(buf, " ");
-- }
-- xmlBufferWriteChar(buf, "</");
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- xmlBufferWriteCHAR(buf, cur->ns->prefix);
-- xmlBufferWriteChar(buf, ":");
-- }
--
-- xmlBufferWriteCHAR(buf, cur->name);
-- xmlBufferWriteChar(buf, ">");
--}
--
--/**
-- * xmlElemDump:
-- * @f: the FILE * for the output
-- * @doc: the document
-- * @cur: the current node
-- *
-- * Dump an XML/HTML node, recursive behaviour,children are printed too.
-- */
--void
--xmlElemDump(FILE *f, xmlDocPtr doc, xmlNodePtr cur) {
-- xmlBufferPtr buf;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlElemDump : cur == NULL\n");
--#endif
-- return;
-- }
-- if (doc == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlElemDump : doc == NULL\n");
--#endif
-- }
-- buf = xmlBufferCreate();
-- if (buf == NULL) return;
-- if ((doc != NULL) &&
-- (doc->type == XML_HTML_DOCUMENT_NODE)) {
--#ifdef LIBXML_HTML_ENABLED
-- htmlNodeDump(buf, doc, cur);
--#else
-- xmlGenericError(xmlGenericErrorContext,
-- "HTML support not compiled in\n");
--#endif /* LIBXML_HTML_ENABLED */
-- } else
-- xmlNodeDump(buf, doc, cur, 0, 1);
-- xmlBufferDump(f, buf);
-- xmlBufferFree(buf);
--}
--
--/************************************************************************
-- * *
-- * Dumping XML tree content to an I/O output buffer *
-- * *
-- ************************************************************************/
--
--void
--xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
-- int level, int format, const char *encoding);
--static void
--xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
-- int level, int format, const char *encoding);
--/**
-- * xmlNsDumpOutput:
-- * @buf: the XML buffer output
-- * @cur: a namespace
-- *
-- * Dump a local Namespace definition.
-- * Should be called in the context of attributes dumps.
-- */
--static void
--xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNsDump : Ns == NULL\n");
--#endif
-- return;
-- }
-- if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
-- /* Within the context of an element attributes */
-- if (cur->prefix != NULL) {
-- xmlOutputBufferWriteString(buf, " xmlns:");
-- xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
-- } else
-- xmlOutputBufferWriteString(buf, " xmlns");
-- xmlOutputBufferWriteString(buf, "=");
-- xmlBufferWriteQuotedString(buf->buffer, cur->href);
-- }
--}
--
--/**
-- * xmlNsListDumpOutput:
-- * @buf: the XML buffer output
-- * @cur: the first namespace
-- *
-- * Dump a list of local Namespace definitions.
-- * Should be called in the context of attributes dumps.
-- */
--static void
--xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
-- while (cur != NULL) {
-- xmlNsDumpOutput(buf, cur);
-- cur = cur->next;
-- }
--}
--
--/**
-- * xmlDtdDumpOutput:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @encoding: an optional encoding string
-- *
-- * Dump the XML document DTD, if any.
-- */
--static void
--xmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDtdPtr dtd, const char *encoding) {
-- if (dtd == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDtdDump : no internal subset\n");
--#endif
-- return;
-- }
-- xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
-- xmlOutputBufferWriteString(buf, (const char *)dtd->name);
-- if (dtd->ExternalID != NULL) {
-- xmlOutputBufferWriteString(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID);
-- xmlOutputBufferWriteString(buf, " ");
-- xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
-- } else if (dtd->SystemID != NULL) {
-- xmlOutputBufferWriteString(buf, " SYSTEM ");
-- xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
-- }
-- if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
-- (dtd->attributes == NULL) && (dtd->notations == NULL)) {
-- xmlOutputBufferWriteString(buf, ">");
-- return;
-- }
-- xmlOutputBufferWriteString(buf, " [\n");
-- xmlNodeListDumpOutput(buf, dtd->doc, dtd->children, -1, 0, encoding);
-- xmlOutputBufferWriteString(buf, "]>");
--}
--
--/**
-- * xmlAttrDumpOutput:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the attribute pointer
-- * @encoding: an optional encoding string
-- *
-- * Dump an XML attribute
-- */
--static void
--xmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
-- const char *encoding) {
-- xmlChar *value;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAttrDump : property == NULL\n");
--#endif
-- return;
-- }
-- xmlOutputBufferWriteString(buf, " ");
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
-- xmlOutputBufferWriteString(buf, ":");
-- }
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- value = xmlNodeListGetString(doc, cur->children, 0);
-- if (value) {
-- xmlOutputBufferWriteString(buf, "=");
-- xmlBufferWriteQuotedString(buf->buffer, value);
-- xmlFree(value);
-- } else {
-- xmlOutputBufferWriteString(buf, "=\"\"");
-- }
--}
--
--/**
-- * xmlAttrListDumpOutput:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the first attribute pointer
-- * @encoding: an optional encoding string
-- *
-- * Dump a list of XML attributes
-- */
--static void
--xmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
-- xmlAttrPtr cur, const char *encoding) {
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAttrListDump : property == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- xmlAttrDumpOutput(buf, doc, cur, encoding);
-- cur = cur->next;
-- }
--}
--
--
--
--/**
-- * xmlNodeListDumpOutput:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the first node
-- * @level: the imbrication level for indenting
-- * @format: is formatting allowed
-- * @encoding: an optional encoding string
-- *
-- * Dump an XML node list, recursive behaviour,children are printed too.
-- */
--static void
--xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
-- xmlNodePtr cur, int level, int format, const char *encoding) {
-- int i;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeListDump : node == NULL\n");
--#endif
-- return;
-- }
-- while (cur != NULL) {
-- if ((format) && (xmlIndentTreeOutput) &&
-- (cur->type == XML_ELEMENT_NODE))
-- for (i = 0;i < level;i++)
-- xmlOutputBufferWriteString(buf, " ");
-- xmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
-- if (format) {
-- xmlOutputBufferWriteString(buf, "\n");
-- }
-- cur = cur->next;
-- }
--}
--
--/**
-- * xmlNodeDumpOutput:
-- * @buf: the XML buffer output
-- * @doc: the document
-- * @cur: the current node
-- * @level: the imbrication level for indenting
-- * @format: is formatting allowed
-- * @encoding: an optional encoding string
-- *
-- * Dump an XML node, recursive behaviour,children are printed too.
-- */
--void
--xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
-- int level, int format, const char *encoding) {
-- int i;
-- xmlNodePtr tmp;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNodeDump : node == NULL\n");
--#endif
-- return;
-- }
-- if (cur->type == XML_XINCLUDE_START)
-- return;
-- if (cur->type == XML_XINCLUDE_END)
-- return;
-- if (cur->type == XML_DTD_NODE) {
-- xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
-- return;
-- }
-- if (cur->type == XML_ELEMENT_DECL) {
-- xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
-- return;
-- }
-- if (cur->type == XML_ATTRIBUTE_DECL) {
-- xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
-- return;
-- }
-- if (cur->type == XML_ENTITY_DECL) {
-- xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
-- return;
-- }
-- if (cur->type == XML_TEXT_NODE) {
-- if (cur->content != NULL) {
-- if ((cur->name == xmlStringText) ||
-- (cur->name != xmlStringTextNoenc)) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- if (encoding == NULL)
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-- else
-- buffer = xmlEncodeSpecialChars(doc, cur->content);
--#else
-- if (encoding == NULL)
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
-- else
-- buffer = xmlEncodeSpecialChars(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlOutputBufferWriteString(buf, (const char *)buffer);
-- xmlFree(buffer);
-- }
-- } else {
-- /*
-- * Disable escaping, needed for XSLT
-- */
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *) cur->content);
--#else
-- xmlOutputBufferWriteString(buf, xmlBufferContent(cur->content));
--#endif
-- }
-- }
--
-- return;
-- }
-- if (cur->type == XML_PI_NODE) {
-- if (cur->content != NULL) {
-- xmlOutputBufferWriteString(buf, "<?");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- if (cur->content != NULL) {
-- xmlOutputBufferWriteString(buf, " ");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *)cur->content);
--#else
-- xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
--#endif
-- }
-- xmlOutputBufferWriteString(buf, "?>");
-- } else {
-- xmlOutputBufferWriteString(buf, "<?");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- xmlOutputBufferWriteString(buf, "?>");
-- }
-- return;
-- }
-- if (cur->type == XML_COMMENT_NODE) {
-- if (cur->content != NULL) {
-- xmlOutputBufferWriteString(buf, "<!--");
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *)cur->content);
--#else
-- xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
--#endif
-- xmlOutputBufferWriteString(buf, "-->");
-- }
-- return;
-- }
-- if (cur->type == XML_ENTITY_REF_NODE) {
-- xmlOutputBufferWriteString(buf, "&");
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- xmlOutputBufferWriteString(buf, ";");
-- return;
-- }
-- if (cur->type == XML_CDATA_SECTION_NODE) {
-- xmlOutputBufferWriteString(buf, "<![CDATA[");
-- if (cur->content != NULL)
--#ifndef XML_USE_BUFFER_CONTENT
-- xmlOutputBufferWriteString(buf, (const char *)cur->content);
--#else
-- xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
--#endif
-- xmlOutputBufferWriteString(buf, "]]>");
-- return;
-- }
--
-- if (format == 1) {
-- tmp = cur->children;
-- while (tmp != NULL) {
-- if ((tmp->type == XML_TEXT_NODE) ||
-- (tmp->type == XML_ENTITY_REF_NODE)) {
-- format = 0;
-- break;
-- }
-- tmp = tmp->next;
-- }
-- }
-- xmlOutputBufferWriteString(buf, "<");
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
-- xmlOutputBufferWriteString(buf, ":");
-- }
--
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- if (cur->nsDef)
-- xmlNsListDumpOutput(buf, cur->nsDef);
-- if (cur->properties != NULL)
-- xmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
--
-- if ((cur->content == NULL) && (cur->children == NULL) &&
-- (!xmlSaveNoEmptyTags)) {
-- xmlOutputBufferWriteString(buf, "/>");
-- return;
-- }
-- xmlOutputBufferWriteString(buf, ">");
-- if (cur->content != NULL) {
-- xmlChar *buffer;
--
--#ifndef XML_USE_BUFFER_CONTENT
-- if (encoding == NULL)
-- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
-- else
-- buffer = xmlEncodeSpecialChars(doc, cur->content);
--#else
-- if (encoding == NULL)
-- buffer = xmlEncodeEntitiesReentrant(doc,
-- xmlBufferContent(cur->content));
-- else
-- buffer = xmlEncodeSpecialChars(doc,
-- xmlBufferContent(cur->content));
--#endif
-- if (buffer != NULL) {
-- xmlOutputBufferWriteString(buf, (const char *)buffer);
-- xmlFree(buffer);
-- }
-- }
-- if (cur->children != NULL) {
-- if (format) xmlOutputBufferWriteString(buf, "\n");
-- xmlNodeListDumpOutput(buf, doc, cur->children,
-- (level >= 0?level+1:-1), format, encoding);
-- if ((xmlIndentTreeOutput) && (format))
-- for (i = 0;i < level;i++)
-- xmlOutputBufferWriteString(buf, " ");
-- }
-- xmlOutputBufferWriteString(buf, "</");
-- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
-- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
-- xmlOutputBufferWriteString(buf, ":");
-- }
--
-- xmlOutputBufferWriteString(buf, (const char *)cur->name);
-- xmlOutputBufferWriteString(buf, ">");
--}
--
--/**
-- * xmlDocContentDumpOutput:
-- * @buf: the XML buffer output
-- * @cur: the document
-- * @encoding: an optional encoding string
-- * @format: should formatting spaces been added
-- *
-- * Dump an XML document.
-- */
--static void
--xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
-- const char *encoding, int format) {
-- xmlOutputBufferWriteString(buf, "<?xml version=");
-- if (cur->version != NULL)
-- xmlBufferWriteQuotedString(buf->buffer, cur->version);
-- else
-- xmlOutputBufferWriteString(buf, "\"1.0\"");
-- if (encoding == NULL) {
-- if (cur->encoding != NULL)
-- encoding = (const char *) cur->encoding;
-- else if (cur->charset != XML_CHAR_ENCODING_UTF8)
-- encoding = xmlGetCharEncodingName((xmlCharEncoding) cur->charset);
-- }
-- if (encoding != NULL) {
-- xmlOutputBufferWriteString(buf, " encoding=");
-- xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
-- }
-- switch (cur->standalone) {
-- case 0:
-- xmlOutputBufferWriteString(buf, " standalone=\"no\"");
-- break;
-- case 1:
-- xmlOutputBufferWriteString(buf, " standalone=\"yes\"");
-- break;
-- }
-- xmlOutputBufferWriteString(buf, "?>\n");
-- if (cur->children != NULL) {
-- xmlNodePtr child = cur->children;
--
-- while (child != NULL) {
-- xmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
-- xmlOutputBufferWriteString(buf, "\n");
-- child = child->next;
-- }
-- }
--}
--
--/************************************************************************
-- * *
-- * Saving functions front-ends *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlDocDumpMemoryEnc:
-- * @out_doc: Document to generate XML text from
-- * @doc_txt_ptr: Memory pointer for allocated XML text
-- * @doc_txt_len: Length of the generated XML text
-- * @txt_encoding: Character encoding to use when generating XML text
-- * @format: should formatting spaces been added
-- *
-- * Dump the current DOM tree into memory using the character encoding specified
-- * by the caller. Note it is up to the caller of this function to free the
-- * allocated memory.
-- */
--
--void
--xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
-- int * doc_txt_len, const char * txt_encoding, int format) {
-- int dummy = 0;
--
-- xmlCharEncoding doc_charset;
-- xmlOutputBufferPtr out_buff = NULL;
-- xmlCharEncodingHandlerPtr conv_hdlr = NULL;
--
-- if (doc_txt_len == NULL) {
-- doc_txt_len = &dummy; /* Continue, caller just won't get length */
-- }
--
-- if (doc_txt_ptr == NULL) {
-- *doc_txt_len = 0;
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDumpFormatMemoryEnc: Null return buffer pointer.");
-- return;
-- }
--
-- *doc_txt_ptr = NULL;
-- *doc_txt_len = 0;
--
-- if (out_doc == NULL) {
-- /* No document, no output */
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDumpFormatMemoryEnc: Null DOM tree document pointer.\n");
-- return;
-- }
--
-- /*
-- * Validate the encoding value, if provided.
-- * This logic is copied from xmlSaveFileEnc.
-- */
--
-- if (txt_encoding == NULL)
-- txt_encoding = (const char *) out_doc->encoding;
-- if (txt_encoding != NULL) {
-- doc_charset = xmlParseCharEncoding(txt_encoding);
--
-- if (out_doc->charset != XML_CHAR_ENCODING_UTF8) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDumpFormatMemoryEnc: Source document not in UTF8\n");
-- return;
--
-- } else if (doc_charset != XML_CHAR_ENCODING_UTF8) {
-- conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
-- if ( conv_hdlr == NULL ) {
-- xmlGenericError(xmlGenericErrorContext,
-- "%s: %s %s '%s'\n",
-- "xmlDocDumpFormatMemoryEnc",
-- "Failed to identify encoding handler for",
-- "character set",
-- txt_encoding);
-- return;
-- }
-- }
-- }
--
-- if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDumpFormatMemoryEnc: Failed to allocate output buffer.\n");
-- return;
-- }
--
-- xmlDocContentDumpOutput(out_buff, out_doc, txt_encoding, 1);
-- xmlOutputBufferFlush(out_buff);
-- if (out_buff->conv != NULL) {
-- *doc_txt_len = out_buff->conv->use;
-- *doc_txt_ptr = xmlStrndup(out_buff->conv->content, *doc_txt_len);
-- } else {
-- *doc_txt_len = out_buff->buffer->use;
-- *doc_txt_ptr = xmlStrndup(out_buff->buffer->content, *doc_txt_len);
-- }
-- (void)xmlOutputBufferClose(out_buff);
--
-- if ((*doc_txt_ptr == NULL) && (*doc_txt_len > 0)) {
-- *doc_txt_len = 0;
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDumpFormatMemoryEnc: %s\n",
-- "Failed to allocate memory for document text representation.");
-- }
--
-- return;
--}
--
--/**
-- * xmlDocDumpMemory:
-- * @cur: the document
-- * @mem: OUT: the memory pointer
-- * @size: OUT: the memory lenght
-- *
-- * Dump an XML document in memory and return the xmlChar * and it's size.
-- * It's up to the caller to free the memory.
-- */
--void
--xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
-- xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
--}
--
--/**
-- * xmlDocDumpFormatMemory:
-- * @cur: the document
-- * @mem: OUT: the memory pointer
-- * @size: OUT: the memory lenght
-- * @format: should formatting spaces been added
-- *
-- *
-- * Dump an XML document in memory and return the xmlChar * and it's size.
-- * It's up to the caller to free the memory.
-- */
--void
--xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
-- xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
--}
--
--/**
-- * xmlDocDumpMemoryEnc:
-- * @out_doc: Document to generate XML text from
-- * @doc_txt_ptr: Memory pointer for allocated XML text
-- * @doc_txt_len: Length of the generated XML text
-- * @txt_encoding: Character encoding to use when generating XML text
-- *
-- * Dump the current DOM tree into memory using the character encoding specified
-- * by the caller. Note it is up to the caller of this function to free the
-- * allocated memory.
-- */
--
--void
--xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
-- int * doc_txt_len, const char * txt_encoding) {
-- xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
-- txt_encoding, 1);
--}
--
--/**
-- * xmlGetDocCompressMode:
-- * @doc: the document
-- *
-- * get the compression ratio for a document, ZLIB based
-- * Returns 0 (uncompressed) to 9 (max compression)
-- */
--int
--xmlGetDocCompressMode (xmlDocPtr doc) {
-- if (doc == NULL) return(-1);
-- return(doc->compression);
--}
--
--/**
-- * xmlSetDocCompressMode:
-- * @doc: the document
-- * @mode: the compression ratio
-- *
-- * set the compression ratio for a document, ZLIB based
-- * Correct values: 0 (uncompressed) to 9 (max compression)
-- */
--void
--xmlSetDocCompressMode (xmlDocPtr doc, int mode) {
-- if (doc == NULL) return;
-- if (mode < 0) doc->compression = 0;
-- else if (mode > 9) doc->compression = 9;
-- else doc->compression = mode;
--}
--
--/**
-- * xmlGetCompressMode:
-- *
-- * get the default compression mode used, ZLIB based.
-- * Returns 0 (uncompressed) to 9 (max compression)
-- */
--int
-- xmlGetCompressMode(void) {
-- return(xmlCompressMode);
--}
--
--/**
-- * xmlSetCompressMode:
-- * @mode: the compression ratio
-- *
-- * set the default compression mode used, ZLIB based
-- * Correct values: 0 (uncompressed) to 9 (max compression)
-- */
--void
--xmlSetCompressMode(int mode) {
-- if (mode < 0) xmlCompressMode = 0;
-- else if (mode > 9) xmlCompressMode = 9;
-- else xmlCompressMode = mode;
--}
--
--/**
-- * xmlDocDump:
-- * @f: the FILE*
-- * @cur: the document
-- *
-- * Dump an XML document to an open FILE.
-- *
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--xmlDocDump(FILE *f, xmlDocPtr cur) {
-- xmlOutputBufferPtr buf;
-- const char * encoding;
-- xmlCharEncodingHandlerPtr handler = NULL;
-- int ret;
--
-- if (cur == NULL) {
--#ifdef DEBUG_TREE
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDump : document == NULL\n");
--#endif
-- return(-1);
-- }
-- encoding = (const char *) cur->encoding;
--
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
--
-- enc = xmlParseCharEncoding(encoding);
--
-- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDocDump: document not in UTF8\n");
-- return(-1);
-- }
-- if (enc != XML_CHAR_ENCODING_UTF8) {
-- handler = xmlFindCharEncodingHandler(encoding);
-- if (handler == NULL) {
-- xmlFree((char *) cur->encoding);
-- cur->encoding = NULL;
-- }
-- }
-- }
-- buf = xmlOutputBufferCreateFile(f, handler);
-- if (buf == NULL) return(-1);
-- xmlDocContentDumpOutput(buf, cur, NULL, 1);
--
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--
--/**
-- * xmlSaveFileTo:
-- * @buf: an output I/O buffer
-- * @cur: the document
-- * @encoding: the encoding if any assuming the i/O layer handles the trancoding
-- *
-- * Dump an XML document to an I/O buffer.
-- *
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--xmlSaveFileTo(xmlOutputBuffer *buf, xmlDocPtr cur, const char *encoding) {
-- int ret;
--
-- if (buf == NULL) return(0);
-- xmlDocContentDumpOutput(buf, cur, encoding, 1);
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--
--/**
-- * xmlSaveFileEnc:
-- * @filename: the filename (or URL)
-- * @cur: the document
-- * @encoding: the name of an encoding (or NULL)
-- *
-- * Dump an XML document, converting it to the given encoding
-- *
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
-- xmlOutputBufferPtr buf;
-- xmlCharEncodingHandlerPtr handler = NULL;
-- int ret;
--
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
--
-- enc = xmlParseCharEncoding(encoding);
-- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveFileEnc: document not in UTF8\n");
-- return(-1);
-- }
-- if (enc != XML_CHAR_ENCODING_UTF8) {
-- handler = xmlFindCharEncodingHandler(encoding);
-- if (handler == NULL) {
-- return(-1);
-- }
-- }
-- }
--
-- /*
-- * save the content to a temp buffer.
-- */
-- buf = xmlOutputBufferCreateFilename(filename, handler, 0);
-- if (buf == NULL) return(-1);
--
-- xmlDocContentDumpOutput(buf, cur, encoding, 1);
--
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--
--/**
-- * xmlSaveFile:
-- * @filename: the filename (or URL)
-- * @cur: the document
-- *
-- * Dump an XML document to a file. Will use compression if
-- * compiled in and enabled. If @filename is "-" the stdout file is
-- * used.
-- * returns: the number of byte written or -1 in case of failure.
-- */
--int
--xmlSaveFile(const char *filename, xmlDocPtr cur) {
-- xmlOutputBufferPtr buf;
-- const char *encoding;
-- xmlCharEncodingHandlerPtr handler = NULL;
-- int ret;
--
-- if (cur == NULL)
-- return(-1);
-- encoding = (const char *) cur->encoding;
--
-- /*
-- * save the content to a temp buffer.
-- */
--#ifdef HAVE_ZLIB_H
-- if (cur->compression < 0) cur->compression = xmlCompressMode;
--#endif
-- if (encoding != NULL) {
-- xmlCharEncoding enc;
--
-- enc = xmlParseCharEncoding(encoding);
--
-- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveFile: document not in UTF8\n");
-- return(-1);
-- }
-- if (enc != XML_CHAR_ENCODING_UTF8) {
-- handler = xmlFindCharEncodingHandler(encoding);
-- if (handler == NULL) {
-- xmlFree((char *) cur->encoding);
-- cur->encoding = NULL;
-- }
-- }
-- }
--
-- buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
-- if (buf == NULL) return(-1);
--
-- xmlDocContentDumpOutput(buf, cur, NULL, 1);
--
-- ret = xmlOutputBufferClose(buf);
-- return(ret);
--}
--
-diff -Nru libxml2-2.3.0/uri.c libxml2-2.3.0.new/uri.c
---- libxml2-2.3.0/uri.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/uri.c Thu Jan 1 01:00:00 1970
-@@ -1,1943 +0,0 @@
--/**
-- * uri.c: set of generic URI related routines
-- *
-- * Reference: RFC 2396
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#define INCLUDE_WINSOCK
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--
--#include <libxml/xmlmemory.h>
--#include <libxml/uri.h>
--#include <libxml/xmlerror.h>
--
--/************************************************************************
-- * *
-- * Macros to differenciate various character type *
-- * directly extracted from RFC 2396 *
-- * *
-- ************************************************************************/
--
--/*
-- * alpha = lowalpha | upalpha
-- */
--#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x))
--
--
--/*
-- * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" |
-- * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" |
-- * "u" | "v" | "w" | "x" | "y" | "z"
-- */
--
--#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))
--
--/*
-- * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" |
-- * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" |
-- * "U" | "V" | "W" | "X" | "Y" | "Z"
-- */
--#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z'))
--
--/*
-- * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-- */
--
--#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))
--
--/*
-- * alphanum = alpha | digit
-- */
--
--#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
--
--/*
-- * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
-- * "a" | "b" | "c" | "d" | "e" | "f"
-- */
--
--#define IS_HEX(x) ((IS_DIGIT(x)) || (((x) >= 'a') && ((x) <= 'f')) || \
-- (((x) >= 'A') && ((x) <= 'F')))
--
--/*
-- * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
-- */
--
--#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \
-- ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \
-- ((x) == '(') || ((x) == ')'))
--
--
--/*
-- * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
-- */
--
--#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
-- ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
-- ((x) == '+') || ((x) == '$') || ((x) == ','))
--
--/*
-- * unreserved = alphanum | mark
-- */
--
--#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
--
--/*
-- * escaped = "%" hex hex
-- */
--
--#define IS_ESCAPED(p) ((*(p) == '%') && (IS_HEX((p)[1])) && \
-- (IS_HEX((p)[2])))
--
--/*
-- * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
-- * "&" | "=" | "+" | "$" | ","
-- */
--#define IS_URIC_NO_SLASH(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||\
-- ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||\
-- ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||\
-- ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
--
--/*
-- * pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
-- */
--#define IS_PCHAR(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-- ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||\
-- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||\
-- ((*(p) == ',')))
--
--/*
-- * rel_segment = 1*( unreserved | escaped |
-- * ";" | "@" | "&" | "=" | "+" | "$" | "," )
-- */
--
--#define IS_SEGMENT(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-- ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || \
-- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
-- ((*(p) == ',')))
--
--/*
-- * scheme = alpha *( alpha | digit | "+" | "-" | "." )
-- */
--
--#define IS_SCHEME(x) ((IS_ALPHA(x)) || (IS_DIGIT(x)) || \
-- ((x) == '+') || ((x) == '-') || ((x) == '.'))
--
--/*
-- * reg_name = 1*( unreserved | escaped | "$" | "," |
-- * ";" | ":" | "@" | "&" | "=" | "+" )
-- */
--
--#define IS_REG_NAME(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-- ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || \
-- ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || \
-- ((*(p) == '=')) || ((*(p) == '+')))
--
--/*
-- * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" |
-- * "+" | "$" | "," )
-- */
--#define IS_USERINFO(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-- ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) || \
-- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
-- ((*(p) == ',')))
--
--/*
-- * uric = reserved | unreserved | escaped
-- */
--
--#define IS_URIC(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
-- (IS_RESERVED(*(p))))
--
--/*
-- * Skip to next pointer char, handle escaped sequences
-- */
--
--#define NEXT(p) ((*p == '%')? p += 3 : p++)
--
--/*
-- * Productions from the spec.
-- *
-- * authority = server | reg_name
-- * reg_name = 1*( unreserved | escaped | "$" | "," |
-- * ";" | ":" | "@" | "&" | "=" | "+" )
-- *
-- * path = [ abs_path | opaque_part ]
-- */
--
--/************************************************************************
-- * *
-- * Generic URI structure functions *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlCreateURI:
-- *
-- * Simply creates an empty xmlURI
-- *
-- * Returns the new structure or NULL in case of error
-- */
--xmlURIPtr
--xmlCreateURI(void) {
-- xmlURIPtr ret;
--
-- ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCreateURI: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlURI));
-- return(ret);
--}
--
--/**
-- * xmlSaveUri:
-- * @uri: pointer to an xmlURI
-- *
-- * Save the URI as an escaped string
-- *
-- * Returns a new string (to be deallocated by caller)
-- */
--xmlChar *
--xmlSaveUri(xmlURIPtr uri) {
-- xmlChar *ret = NULL;
-- const char *p;
-- int len;
-- int max;
--
-- if (uri == NULL) return(NULL);
--
--
-- max = 80;
-- ret = (xmlChar *) xmlMalloc((max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- len = 0;
--
-- if (uri->scheme != NULL) {
-- p = uri->scheme;
-- while (*p != 0) {
-- if (len >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = *p++;
-- }
-- if (len >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = ':';
-- }
-- if (uri->opaque != NULL) {
-- p = uri->opaque;
-- while (*p != 0) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((IS_UNRESERVED(*(p))) ||
-- ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||
-- ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||
-- ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
-- ret[len++] = *p++;
-- else {
-- int val = *(unsigned char *)p++;
-- int hi = val / 0x10, lo = val % 0x10;
-- ret[len++] = '%';
-- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-- }
-- }
-- if (len >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = 0;
-- } else {
-- if (uri->server != NULL) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = '/';
-- ret[len++] = '/';
-- if (uri->user != NULL) {
-- p = uri->user;
-- while (*p != 0) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((IS_UNRESERVED(*(p))) ||
-- ((*(p) == ';')) || ((*(p) == ':')) ||
-- ((*(p) == '&')) || ((*(p) == '=')) ||
-- ((*(p) == '+')) || ((*(p) == '$')) ||
-- ((*(p) == ',')))
-- ret[len++] = *p++;
-- else {
-- int val = *(unsigned char *)p++;
-- int hi = val / 0x10, lo = val % 0x10;
-- ret[len++] = '%';
-- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-- }
-- }
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = '@';
-- }
-- p = uri->server;
-- while (*p != 0) {
-- if (len >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = *p++;
-- }
-- if (uri->port > 0) {
-- if (len + 10 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- len += sprintf((char *) &ret[len], ":%d", uri->port);
-- }
-- } else if (uri->authority != NULL) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = '/';
-- ret[len++] = '/';
-- p = uri->authority;
-- while (*p != 0) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((IS_UNRESERVED(*(p))) ||
-- ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
-- ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||
-- ((*(p) == '=')) || ((*(p) == '+')))
-- ret[len++] = *p++;
-- else {
-- int val = *(unsigned char *)p++;
-- int hi = val / 0x10, lo = val % 0x10;
-- ret[len++] = '%';
-- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-- }
-- }
-- } else if (uri->scheme != NULL) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = '/';
-- ret[len++] = '/';
-- }
-- if (uri->path != NULL) {
-- p = uri->path;
-- while (*p != 0) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
-- ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
-- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||
-- ((*(p) == ',')))
-- ret[len++] = *p++;
-- else {
-- int val = *(unsigned char *)p++;
-- int hi = val / 0x10, lo = val % 0x10;
-- ret[len++] = '%';
-- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-- }
-- }
-- }
-- if (uri->query != NULL) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = '?';
-- p = uri->query;
-- while (*p != 0) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
-- ret[len++] = *p++;
-- else {
-- int val = *(unsigned char *)p++;
-- int hi = val / 0x10, lo = val % 0x10;
-- ret[len++] = '%';
-- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-- }
-- }
-- }
-- if (uri->fragment != NULL) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = '#';
-- p = uri->fragment;
-- while (*p != 0) {
-- if (len + 3 >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret,
-- (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
-- ret[len++] = *p++;
-- else {
-- int val = *(unsigned char *)p++;
-- int hi = val / 0x10, lo = val % 0x10;
-- ret[len++] = '%';
-- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
-- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
-- }
-- }
-- }
-- if (len >= max) {
-- max *= 2;
-- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlSaveUri: out of memory\n");
-- return(NULL);
-- }
-- }
-- ret[len++] = 0;
-- }
-- return(ret);
--}
--
--/**
-- * xmlPrintURI:
-- * @stream: a FILE* for the output
-- * @uri: pointer to an xmlURI
-- *
-- * Prints the URI in the stream @steam.
-- */
--void
--xmlPrintURI(FILE *stream, xmlURIPtr uri) {
-- xmlChar *out;
--
-- out = xmlSaveUri(uri);
-- if (out != NULL) {
-- fprintf(stream, "%s", out);
-- xmlFree(out);
-- }
--}
--
--/**
-- * xmlCleanURI:
-- * @uri: pointer to an xmlURI
-- *
-- * Make sure the xmlURI struct is free of content
-- */
--void
--xmlCleanURI(xmlURIPtr uri) {
-- if (uri == NULL) return;
--
-- if (uri->scheme != NULL) xmlFree(uri->scheme);
-- uri->scheme = NULL;
-- if (uri->server != NULL) xmlFree(uri->server);
-- uri->server = NULL;
-- if (uri->user != NULL) xmlFree(uri->user);
-- uri->user = NULL;
-- if (uri->path != NULL) xmlFree(uri->path);
-- uri->path = NULL;
-- if (uri->fragment != NULL) xmlFree(uri->fragment);
-- uri->fragment = NULL;
-- if (uri->opaque != NULL) xmlFree(uri->opaque);
-- uri->opaque = NULL;
-- if (uri->authority != NULL) xmlFree(uri->authority);
-- uri->authority = NULL;
-- if (uri->query != NULL) xmlFree(uri->query);
-- uri->query = NULL;
--}
--
--/**
-- * xmlFreeURI:
-- * @uri: pointer to an xmlURI
-- *
-- * Free up the xmlURI struct
-- */
--void
--xmlFreeURI(xmlURIPtr uri) {
-- if (uri == NULL) return;
--
-- if (uri->scheme != NULL) xmlFree(uri->scheme);
-- if (uri->server != NULL) xmlFree(uri->server);
-- if (uri->user != NULL) xmlFree(uri->user);
-- if (uri->path != NULL) xmlFree(uri->path);
-- if (uri->fragment != NULL) xmlFree(uri->fragment);
-- if (uri->opaque != NULL) xmlFree(uri->opaque);
-- if (uri->authority != NULL) xmlFree(uri->authority);
-- if (uri->query != NULL) xmlFree(uri->query);
-- memset(uri, -1, sizeof(xmlURI));
-- xmlFree(uri);
--}
--
--/************************************************************************
-- * *
-- * Helper functions *
-- * *
-- ************************************************************************/
--
--#if 0
--/**
-- * xmlNormalizeURIPath:
-- * @path: pointer to the path string
-- *
-- * applies the 5 normalization steps to a path string
-- * Normalization occurs directly on the string, no new allocation is done
-- *
-- * Returns 0 or an error code
-- */
--int
--xmlNormalizeURIPath(char *path) {
-- int cur, out;
--
-- if (path == NULL)
-- return(-1);
-- cur = 0;
-- out = 0;
-- while ((path[cur] != 0) && (path[cur] != '/')) cur++;
-- if (path[cur] == 0)
-- return(0);
--
-- /* we are positionned at the beginning of the first segment */
-- cur++;
-- out = cur;
--
-- /*
-- * Analyze each segment in sequence.
-- */
-- while (path[cur] != 0) {
-- /*
-- * c) All occurrences of "./", where "." is a complete path segment,
-- * are removed from the buffer string.
-- */
-- if ((path[cur] == '.') && (path[cur + 1] == '/')) {
-- cur += 2;
-- if (path[cur] == 0) {
-- path[out++] = 0;
-- }
-- continue;
-- }
--
-- /*
-- * d) If the buffer string ends with "." as a complete path segment,
-- * that "." is removed.
-- */
-- if ((path[cur] == '.') && (path[cur + 1] == 0)) {
-- path[out] = 0;
-- break;
-- }
--
-- /* read the segment */
-- while ((path[cur] != 0) && (path[cur] != '/')) {
-- path[out++] = path[cur++];
-- }
-- path[out++] = path[cur];
-- if (path[cur] != 0) {
-- cur++;
-- }
-- }
--
-- cur = 0;
-- out = 0;
-- while ((path[cur] != 0) && (path[cur] != '/')) cur++;
-- if (path[cur] == 0)
-- return(0);
-- /* we are positionned at the beginning of the first segment */
-- cur++;
-- out = cur;
-- /*
-- * Analyze each segment in sequence.
-- */
-- while (path[cur] != 0) {
-- /*
-- * e) All occurrences of "<segment>/../", where <segment> is a
-- * complete path segment not equal to "..", are removed from the
-- * buffer string. Removal of these path segments is performed
-- * iteratively, removing the leftmost matching pattern on each
-- * iteration, until no matching pattern remains.
-- */
-- if ((cur > 1) && (out > 1) &&
-- (path[cur] == '/') && (path[cur + 1] == '.') &&
-- (path[cur + 2] == '.') && (path[cur + 3] == '/') &&
-- ((path[out] != '.') || (path[out - 1] != '.') ||
-- (path[out - 2] != '/'))) {
-- cur += 3;
-- out --;
-- while ((out > 0) && (path[out] != '/')) { out --; }
-- path[out] = 0;
-- continue;
-- }
--
-- /*
-- * f) If the buffer string ends with "<segment>/..", where <segment>
-- * is a complete path segment not equal to "..", that
-- * "<segment>/.." is removed.
-- */
-- if ((path[cur] == '/') && (path[cur + 1] == '.') &&
-- (path[cur + 2] == '.') && (path[cur + 3] == 0) &&
-- ((path[out] != '.') || (path[out - 1] != '.') ||
-- (path[out - 2] != '/'))) {
-- cur += 4;
-- out --;
-- while ((out > 0) && (path[out - 1] != '/')) { out --; }
-- path[out] = 0;
-- continue;
-- }
--
-- path[out++] = path[cur++]; /* / or 0 */
-- }
-- path[out] = 0;
--
-- /*
-- * g) If the resulting buffer string still begins with one or more
-- * complete path segments of "..", then the reference is
-- * considered to be in error. Implementations may handle this
-- * error by retaining these components in the resolved path (i.e.,
-- * treating them as part of the final URI), by removing them from
-- * the resolved path (i.e., discarding relative levels above the
-- * root), or by avoiding traversal of the reference.
-- *
-- * We discard them from the final path.
-- */
-- cur = 0;
-- while ((path[cur] == '/') && (path[cur + 1] == '.') &&
-- (path[cur + 2] == '.'))
-- cur += 3;
-- if (cur != 0) {
-- out = 0;
-- while (path[cur] != 0) path[out++] = path[cur++];
-- path[out] = 0;
-- }
-- return(0);
--}
--#else
--/**
-- * xmlNormalizeURIPath:
-- * @path: pointer to the path string
-- *
-- * Applies the 5 normalization steps to a path string--that is, RFC 2396
-- * Section 5.2, steps 6.c through 6.g.
-- *
-- * Normalization occurs directly on the string, no new allocation is done
-- *
-- * Returns 0 or an error code
-- */
--int
--xmlNormalizeURIPath(char *path) {
-- char *cur, *out;
--
-- if (path == NULL)
-- return(-1);
--
-- /* Skip all initial "/" chars. We want to get to the beginning of the
-- * first non-empty segment.
-- */
-- cur = path;
-- while (cur[0] == '/')
-- ++cur;
-- if (cur[0] == '\0')
-- return(0);
--
-- /* Keep everything we've seen so far. */
-- out = cur;
--
-- /*
-- * Analyze each segment in sequence for cases (c) and (d).
-- */
-- while (cur[0] != '\0') {
-- /*
-- * c) All occurrences of "./", where "." is a complete path segment,
-- * are removed from the buffer string.
-- */
-- if ((cur[0] == '.') && (cur[1] == '/')) {
-- cur += 2;
-- continue;
-- }
--
-- /*
-- * d) If the buffer string ends with "." as a complete path segment,
-- * that "." is removed.
-- */
-- if ((cur[0] == '.') && (cur[1] == '\0'))
-- break;
--
-- /* Otherwise keep the segment. */
-- while (cur[0] != '/') {
-- if (cur[0] == '\0')
-- goto done_cd;
-- (out++)[0] = (cur++)[0];
-- }
-- (out++)[0] = (cur++)[0];
-- }
-- done_cd:
-- out[0] = '\0';
--
-- /* Reset to the beginning of the first segment for the next sequence. */
-- cur = path;
-- while (cur[0] == '/')
-- ++cur;
-- if (cur[0] == '\0')
-- return(0);
--
-- /*
-- * Analyze each segment in sequence for cases (e) and (f).
-- *
-- * e) All occurrences of "<segment>/../", where <segment> is a
-- * complete path segment not equal to "..", are removed from the
-- * buffer string. Removal of these path segments is performed
-- * iteratively, removing the leftmost matching pattern on each
-- * iteration, until no matching pattern remains.
-- *
-- * f) If the buffer string ends with "<segment>/..", where <segment>
-- * is a complete path segment not equal to "..", that
-- * "<segment>/.." is removed.
-- *
-- * To satisfy the "iterative" clause in (e), we need to collapse the
-- * string every time we find something that needs to be removed. Thus,
-- * we don't need to keep two pointers into the string: we only need a
-- * "current position" pointer.
-- */
-- while (1) {
-- char *segp;
--
-- /* At the beginning of each iteration of this loop, "cur" points to
-- * the first character of the segment we want to examine.
-- */
--
-- /* Find the end of the current segment. */
-- segp = cur;
-- while ((segp[0] != '/') && (segp[0] != '\0'))
-- ++segp;
--
-- /* If this is the last segment, we're done (we need at least two
-- * segments to meet the criteria for the (e) and (f) cases).
-- */
-- if (segp[0] == '\0')
-- break;
--
-- /* If the first segment is "..", or if the next segment _isn't_ "..",
-- * keep this segment and try the next one.
-- */
-- ++segp;
-- if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
-- || ((segp[0] != '.') || (segp[1] != '.')
-- || ((segp[2] != '/') && (segp[2] != '\0')))) {
-- cur = segp;
-- continue;
-- }
--
-- /* If we get here, remove this segment and the next one and back up
-- * to the previous segment (if there is one), to implement the
-- * "iteratively" clause. It's pretty much impossible to back up
-- * while maintaining two pointers into the buffer, so just compact
-- * the whole buffer now.
-- */
--
-- /* If this is the end of the buffer, we're done. */
-- if (segp[2] == '\0') {
-- cur[0] = '\0';
-- break;
-- }
-- strcpy(cur, segp + 3);
--
-- /* If there are no previous segments, then keep going from here. */
-- segp = cur;
-- while ((segp > path) && ((--segp)[0] == '/'))
-- ;
-- if (segp == path)
-- continue;
--
-- /* "segp" is pointing to the end of a previous segment; find it's
-- * start. We need to back up to the previous segment and start
-- * over with that to handle things like "foo/bar/../..". If we
-- * don't do this, then on the first pass we'll remove the "bar/..",
-- * but be pointing at the second ".." so we won't realize we can also
-- * remove the "foo/..".
-- */
-- cur = segp;
-- while ((cur > path) && (cur[-1] != '/'))
-- --cur;
-- }
-- out[0] = '\0';
--
-- /*
-- * g) If the resulting buffer string still begins with one or more
-- * complete path segments of "..", then the reference is
-- * considered to be in error. Implementations may handle this
-- * error by retaining these components in the resolved path (i.e.,
-- * treating them as part of the final URI), by removing them from
-- * the resolved path (i.e., discarding relative levels above the
-- * root), or by avoiding traversal of the reference.
-- *
-- * We discard them from the final path.
-- */
-- if (path[0] == '/') {
-- cur = path;
-- while ((cur[1] == '.') && (cur[2] == '.')
-- && ((cur[3] == '/') || (cur[3] == '\0')))
-- cur += 3;
--
-- if (cur != path) {
-- out = path;
-- while (cur[0] != '\0')
-- (out++)[0] = (cur++)[0];
-- out[0] = 0;
-- }
-- }
--
-- return(0);
--}
--#endif
--
--/**
-- * xmlURIUnescapeString:
-- * @str: the string to unescape
-- * @len: the lenght in bytes to unescape (or <= 0 to indicate full string)
-- * @target: optionnal destination buffer
-- *
-- * Unescaping routine, does not do validity checks !
-- * Output is direct unsigned char translation of %XX values (no encoding)
-- *
-- * Returns an copy of the string, but unescaped
-- */
--char *
--xmlURIUnescapeString(const char *str, int len, char *target) {
-- char *ret, *out;
-- const char *in;
--
-- if (str == NULL)
-- return(NULL);
-- if (len <= 0) len = strlen(str);
-- if (len <= 0) return(NULL);
--
-- if (target == NULL) {
-- ret = (char *) xmlMalloc(len + 1);
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlURIUnescapeString: out of memory\n");
-- return(NULL);
-- }
-- } else
-- ret = target;
-- in = str;
-- out = ret;
-- while(len > 0) {
-- if (*in == '%') {
-- in++;
-- if ((*in >= '0') && (*in <= '9'))
-- *out = (*in - '0');
-- else if ((*in >= 'a') && (*in <= 'f'))
-- *out = (*in - 'a') + 10;
-- else if ((*in >= 'A') && (*in <= 'F'))
-- *out = (*in - 'A') + 10;
-- in++;
-- if ((*in >= '0') && (*in <= '9'))
-- *out = *out * 16 + (*in - '0');
-- else if ((*in >= 'a') && (*in <= 'f'))
-- *out = *out * 16 + (*in - 'a') + 10;
-- else if ((*in >= 'A') && (*in <= 'F'))
-- *out = *out * 16 + (*in - 'A') + 10;
-- in++;
-- len -= 3;
-- out++;
-- } else {
-- *out++ = *in++;
-- len--;
-- }
-- }
-- *out = 0;
-- return(ret);
--}
--
--/**
-- * xmlURIEscape:
-- * @str: the string of the URI to escape
-- *
-- * Escaping routine, does not do validity checks !
-- * It will try to escape the chars needing this, but this is heuristic
-- * based it's impossible to be sure.
-- *
-- * Returns an copy of the string, but escaped
-- */
--xmlChar *
--xmlURIEscape(const xmlChar *str) {
-- xmlChar *ret;
-- const xmlChar *in;
-- unsigned int len, out;
--
-- if (str == NULL)
-- return(NULL);
-- len = xmlStrlen(str);
-- if (len <= 0) return(NULL);
--
-- len += 20;
-- ret = (xmlChar *) xmlMalloc(len);
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlURIEscape: out of memory\n");
-- return(NULL);
-- }
-- in = (const xmlChar *) str;
-- out = 0;
-- while(*in != 0) {
-- if (len - out <= 3) {
-- len += 20;
-- ret = (xmlChar *) xmlRealloc(ret, len);
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlURIEscape: out of memory\n");
-- return(NULL);
-- }
-- }
-- if ((!IS_UNRESERVED(*in)) && (*in != ':') && (*in != '/') &&
-- (*in != '?') && (*in != '#')) {
-- unsigned char val;
-- ret[out++] = '%';
-- val = *in >> 4;
-- if (val <= 9)
-- ret[out++] = '0' + val;
-- else
-- ret[out++] = 'A' + val - 0xA;
-- val = *in & 0xF;
-- if (val <= 9)
-- ret[out++] = '0' + val;
-- else
-- ret[out++] = 'A' + val - 0xA;
-- in++;
-- } else {
-- ret[out++] = *in++;
-- }
-- }
-- ret[out] = 0;
-- return(ret);
--}
--
--/************************************************************************
-- * *
-- * Escaped URI parsing *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlParseURIFragment:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an URI fragment string and fills in the appropriate fields
-- * of the @uri structure.
-- *
-- * fragment = *uric
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIFragment(xmlURIPtr uri, const char **str) {
-- const char *cur = *str;
--
-- if (str == NULL) return(-1);
--
-- while (IS_URIC(cur)) NEXT(cur);
-- if (uri != NULL) {
-- if (uri->fragment != NULL) xmlFree(uri->fragment);
-- uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIQuery:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse the query part of an URI
-- *
-- * query = *uric
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIQuery(xmlURIPtr uri, const char **str) {
-- const char *cur = *str;
--
-- if (str == NULL) return(-1);
--
-- while (IS_URIC(cur)) NEXT(cur);
-- if (uri != NULL) {
-- if (uri->query != NULL) xmlFree(uri->query);
-- uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIScheme:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an URI scheme
-- *
-- * scheme = alpha *( alpha | digit | "+" | "-" | "." )
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIScheme(xmlURIPtr uri, const char **str) {
-- const char *cur;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
-- if (!IS_ALPHA(*cur))
-- return(2);
-- cur++;
-- while (IS_SCHEME(*cur)) cur++;
-- if (uri != NULL) {
-- if (uri->scheme != NULL) xmlFree(uri->scheme);
-- /* !!! strndup */
-- uri->scheme = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIOpaquePart:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an URI opaque part
-- *
-- * opaque_part = uric_no_slash *uric
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIOpaquePart(xmlURIPtr uri, const char **str) {
-- const char *cur;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
-- if (!IS_URIC_NO_SLASH(cur)) {
-- return(3);
-- }
-- NEXT(cur);
-- while (IS_URIC(cur)) NEXT(cur);
-- if (uri != NULL) {
-- if (uri->opaque != NULL) xmlFree(uri->opaque);
-- uri->opaque = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIServer:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse a server subpart of an URI, it's a finer grain analysis
-- * of the authority part.
-- *
-- * server = [ [ userinfo "@" ] hostport ]
-- * userinfo = *( unreserved | escaped |
-- * ";" | ":" | "&" | "=" | "+" | "$" | "," )
-- * hostport = host [ ":" port ]
-- * host = hostname | IPv4address
-- * hostname = *( domainlabel "." ) toplabel [ "." ]
-- * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
-- * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
-- * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
-- * port = *digit
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIServer(xmlURIPtr uri, const char **str) {
-- const char *cur;
-- const char *host, *tmp;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
--
-- /*
-- * is there an userinfo ?
-- */
-- while (IS_USERINFO(cur)) NEXT(cur);
-- if (*cur == '@') {
-- if (uri != NULL) {
-- if (uri->user != NULL) xmlFree(uri->user);
-- uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- cur++;
-- } else {
-- if (uri != NULL) {
-- if (uri->user != NULL) xmlFree(uri->user);
-- uri->user = NULL;
-- }
-- cur = *str;
-- }
-- /*
-- * This can be empty in the case where there is no server
-- */
-- host = cur;
-- if (*cur == '/') {
-- if (uri != NULL) {
-- if (uri->authority != NULL) xmlFree(uri->authority);
-- uri->authority = NULL;
-- if (uri->server != NULL) xmlFree(uri->server);
-- uri->server = NULL;
-- uri->port = 0;
-- }
-- return(0);
-- }
-- /*
-- * host part of hostport can derive either an IPV4 address
-- * or an unresolved name. Check the IP first, it easier to detect
-- * errors if wrong one
-- */
-- if (IS_DIGIT(*cur)) {
-- while(IS_DIGIT(*cur)) cur++;
-- if (*cur != '.')
-- goto host_name;
-- cur++;
-- if (!IS_DIGIT(*cur))
-- goto host_name;
-- while(IS_DIGIT(*cur)) cur++;
-- if (*cur != '.')
-- goto host_name;
-- cur++;
-- if (!IS_DIGIT(*cur))
-- goto host_name;
-- while(IS_DIGIT(*cur)) cur++;
-- if (*cur != '.')
-- goto host_name;
-- cur++;
-- if (!IS_DIGIT(*cur))
-- goto host_name;
-- while(IS_DIGIT(*cur)) cur++;
-- if (uri != NULL) {
-- if (uri->authority != NULL) xmlFree(uri->authority);
-- uri->authority = NULL;
-- if (uri->server != NULL) xmlFree(uri->server);
-- uri->server = xmlURIUnescapeString(host, cur - host, NULL);
-- }
-- goto host_done;
-- }
--host_name:
-- /*
-- * the hostname production as-is is a parser nightmare.
-- * simplify it to
-- * hostname = *( domainlabel "." ) domainlabel [ "." ]
-- * and just make sure the last label starts with a non numeric char.
-- */
-- if (!IS_ALPHANUM(*cur))
-- return(6);
-- while (IS_ALPHANUM(*cur)) {
-- while ((IS_ALPHANUM(*cur)) || (*cur == '-')) cur++;
-- if (*cur == '.')
-- cur++;
-- }
-- tmp = cur;
-- tmp--;
-- while (IS_ALPHANUM(*tmp) && (*tmp != '.') && (tmp >= host)) tmp--;
-- tmp++;
-- if (!IS_ALPHA(*tmp))
-- return(7);
-- if (uri != NULL) {
-- if (uri->authority != NULL) xmlFree(uri->authority);
-- uri->authority = NULL;
-- if (uri->server != NULL) xmlFree(uri->server);
-- uri->server = xmlURIUnescapeString(host, cur - host, NULL);
-- }
--
--host_done:
--
-- /*
-- * finish by checking for a port presence.
-- */
-- if (*cur == ':') {
-- cur++;
-- if (IS_DIGIT(*cur)) {
-- if (uri != NULL)
-- uri->port = 0;
-- while (IS_DIGIT(*cur)) {
-- if (uri != NULL)
-- uri->port = uri->port * 10 + (*cur - '0');
-- cur++;
-- }
-- }
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIRelSegment:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an URI relative segment
-- *
-- * rel_segment = 1*( unreserved | escaped | ";" | "@" | "&" | "=" |
-- * "+" | "$" | "," )
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIRelSegment(xmlURIPtr uri, const char **str) {
-- const char *cur;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
-- if (!IS_SEGMENT(cur)) {
-- return(3);
-- }
-- NEXT(cur);
-- while (IS_SEGMENT(cur)) NEXT(cur);
-- if (uri != NULL) {
-- if (uri->path != NULL) xmlFree(uri->path);
-- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIPathSegments:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- * @slash: should we add a leading slash
-- *
-- * Parse an URI set of path segments
-- *
-- * path_segments = segment *( "/" segment )
-- * segment = *pchar *( ";" param )
-- * param = *pchar
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash) {
-- const char *cur;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
--
-- do {
-- while (IS_PCHAR(cur)) NEXT(cur);
-- if (*cur == ';') {
-- cur++;
-- while (IS_PCHAR(cur)) NEXT(cur);
-- }
-- if (*cur != '/') break;
-- cur++;
-- } while (1);
-- if (uri != NULL) {
-- int len, len2 = 0;
-- char *path;
--
-- /*
-- * Concat the set of path segments to the current path
-- */
-- len = cur - *str;
-- if (slash)
-- len++;
--
-- if (uri->path != NULL) {
-- len2 = strlen(uri->path);
-- len += len2;
-- }
-- path = (char *) xmlMalloc(len + 1);
-- if (path == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParseURIPathSegments: out of memory\n");
-- *str = cur;
-- return(-1);
-- }
-- if (uri->path != NULL)
-- memcpy(path, uri->path, len2);
-- if (slash) {
-- path[len2] = '/';
-- len2++;
-- }
-- path[len2] = 0;
-- if (cur - *str > 0)
-- xmlURIUnescapeString(*str, cur - *str, &path[len2]);
-- if (uri->path != NULL)
-- xmlFree(uri->path);
-- uri->path = path;
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIAuthority:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse the authority part of an URI.
-- *
-- * authority = server | reg_name
-- * server = [ [ userinfo "@" ] hostport ]
-- * reg_name = 1*( unreserved | escaped | "$" | "," | ";" | ":" |
-- * "@" | "&" | "=" | "+" )
-- *
-- * Note : this is completely ambiguous since reg_name is allowed to
-- * use the full set of chars in use by server:
-- *
-- * 3.2.1. Registry-based Naming Authority
-- *
-- * The structure of a registry-based naming authority is specific
-- * to the URI scheme, but constrained to the allowed characters
-- * for an authority component.
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIAuthority(xmlURIPtr uri, const char **str) {
-- const char *cur;
-- int ret;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
--
-- /*
-- * try first to parse it as a server string.
-- */
-- ret = xmlParseURIServer(uri, str);
-- if (ret == 0)
-- return(0);
--
-- /*
-- * failed, fallback to reg_name
-- */
-- if (!IS_REG_NAME(cur)) {
-- return(5);
-- }
-- NEXT(cur);
-- while (IS_REG_NAME(cur)) NEXT(cur);
-- if (uri != NULL) {
-- if (uri->server != NULL) xmlFree(uri->server);
-- uri->server = NULL;
-- if (uri->user != NULL) xmlFree(uri->user);
-- uri->user = NULL;
-- if (uri->authority != NULL) xmlFree(uri->authority);
-- uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseURIHierPart:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an URI hirarchical part
-- *
-- * hier_part = ( net_path | abs_path ) [ "?" query ]
-- * abs_path = "/" path_segments
-- * net_path = "//" authority [ abs_path ]
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIHierPart(xmlURIPtr uri, const char **str) {
-- int ret;
-- const char *cur;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
--
-- if ((cur[0] == '/') && (cur[1] == '/')) {
-- cur += 2;
-- ret = xmlParseURIAuthority(uri, &cur);
-- if (ret != 0)
-- return(ret);
-- if (cur[0] == '/') {
-- cur++;
-- ret = xmlParseURIPathSegments(uri, &cur, 1);
-- }
-- } else if (cur[0] == '/') {
-- cur++;
-- ret = xmlParseURIPathSegments(uri, &cur, 1);
-- } else {
-- return(4);
-- }
-- if (ret != 0)
-- return(ret);
-- if (*cur == '?') {
-- cur++;
-- ret = xmlParseURIQuery(uri, &cur);
-- if (ret != 0)
-- return(ret);
-- }
-- *str = cur;
-- return(0);
--}
--
--/**
-- * xmlParseAbsoluteURI:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an URI reference string and fills in the appropriate fields
-- * of the @uri structure
-- *
-- * absoluteURI = scheme ":" ( hier_part | opaque_part )
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseAbsoluteURI(xmlURIPtr uri, const char **str) {
-- int ret;
--
-- if (str == NULL)
-- return(-1);
--
-- ret = xmlParseURIScheme(uri, str);
-- if (ret != 0) return(ret);
-- if (**str != ':')
-- return(1);
-- (*str)++;
-- if (**str == '/')
-- return(xmlParseURIHierPart(uri, str));
-- return(xmlParseURIOpaquePart(uri, str));
--}
--
--/**
-- * xmlParseRelativeURI:
-- * @uri: pointer to an URI structure
-- * @str: pointer to the string to analyze
-- *
-- * Parse an relative URI string and fills in the appropriate fields
-- * of the @uri structure
-- *
-- * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
-- * abs_path = "/" path_segments
-- * net_path = "//" authority [ abs_path ]
-- * rel_path = rel_segment [ abs_path ]
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseRelativeURI(xmlURIPtr uri, const char **str) {
-- int ret = 0;
-- const char *cur;
--
-- if (str == NULL)
-- return(-1);
--
-- cur = *str;
-- if ((cur[0] == '/') && (cur[1] == '/')) {
-- cur += 2;
-- ret = xmlParseURIAuthority(uri, &cur);
-- if (ret != 0)
-- return(ret);
-- if (cur[0] == '/') {
-- cur++;
-- ret = xmlParseURIPathSegments(uri, &cur, 1);
-- }
-- } else if (cur[0] == '/') {
-- cur++;
-- ret = xmlParseURIPathSegments(uri, &cur, 1);
-- } else if (cur[0] != '#' && cur[0] != '?') {
-- ret = xmlParseURIRelSegment(uri, &cur);
-- if (ret != 0)
-- return(ret);
-- if (cur[0] == '/') {
-- cur++;
-- ret = xmlParseURIPathSegments(uri, &cur, 1);
-- }
-- }
-- if (ret != 0)
-- return(ret);
-- if (*cur == '?') {
-- cur++;
-- ret = xmlParseURIQuery(uri, &cur);
-- if (ret != 0)
-- return(ret);
-- }
-- *str = cur;
-- return(ret);
--}
--
--/**
-- * xmlParseURIReference:
-- * @uri: pointer to an URI structure
-- * @str: the string to analyze
-- *
-- * Parse an URI reference string and fills in the appropriate fields
-- * of the @uri structure
-- *
-- * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-- *
-- * Returns 0 or the error code
-- */
--int
--xmlParseURIReference(xmlURIPtr uri, const char *str) {
-- int ret;
-- const char *tmp = str;
--
-- if (str == NULL)
-- return(-1);
-- xmlCleanURI(uri);
--
-- /*
-- * Try first to parse aboslute refs, then fallback to relative if
-- * it fails.
-- */
-- ret = xmlParseAbsoluteURI(uri, &str);
-- if (ret != 0) {
-- xmlCleanURI(uri);
-- str = tmp;
-- ret = xmlParseRelativeURI(uri, &str);
-- }
-- if (ret != 0) {
-- xmlCleanURI(uri);
-- return(ret);
-- }
--
-- if (*str == '#') {
-- str++;
-- ret = xmlParseURIFragment(uri, &str);
-- if (ret != 0) return(ret);
-- }
-- if (*str != 0) {
-- xmlCleanURI(uri);
-- return(1);
-- }
-- return(0);
--}
--
--/**
-- * xmlParseURI:
-- * @str: the URI string to analyze
-- *
-- * Parse an URI
-- *
-- * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-- *
-- * Returns a newly build xmlURIPtr or NULL in case of error
-- */
--xmlURIPtr
--xmlParseURI(const char *str) {
-- xmlURIPtr uri;
-- int ret;
--
-- if (str == NULL)
-- return(NULL);
-- uri = xmlCreateURI();
-- if (uri != NULL) {
-- ret = xmlParseURIReference(uri, str);
-- if (ret) {
-- xmlFreeURI(uri);
-- return(NULL);
-- }
-- }
-- return(uri);
--}
--
--/************************************************************************
-- * *
-- * Public functions *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlBuildURI:
-- * @URI: the URI instance found in the document
-- * @base: the base value
-- *
-- * Computes he final URI of the reference done by checking that
-- * the given URI is valid, and building the final URI using the
-- * base URI. This is processed according to section 5.2 of the
-- * RFC 2396
-- *
-- * 5.2. Resolving Relative References to Absolute Form
-- *
-- * Returns a new URI string (to be freed by the caller) or NULL in case
-- * of error.
-- */
--xmlChar *
--xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
-- xmlChar *val = NULL;
-- int ret, len, index, cur, out;
-- xmlURIPtr ref = NULL;
-- xmlURIPtr bas = NULL;
-- xmlURIPtr res = NULL;
--
-- /*
-- * 1) The URI reference is parsed into the potential four components and
-- * fragment identifier, as described in Section 4.3.
-- *
-- * NOTE that a completely empty URI is treated by modern browsers
-- * as a reference to "." rather than as a synonym for the current
-- * URI. Should we do that here?
-- */
-- if (URI == NULL)
-- ret = -1;
-- else {
-- if (*URI) {
-- ref = xmlCreateURI();
-- if (ref == NULL)
-- goto done;
-- ret = xmlParseURIReference(ref, (const char *) URI);
-- }
-- else
-- ret = 0;
-- }
-- if (ret != 0)
-- goto done;
-- if (base == NULL)
-- ret = -1;
-- else {
-- bas = xmlCreateURI();
-- if (bas == NULL)
-- goto done;
-- ret = xmlParseURIReference(bas, (const char *) base);
-- }
-- if (ret != 0) {
-- if (ref)
-- val = xmlSaveUri(ref);
-- goto done;
-- }
-- if (ref == NULL) {
-- /*
-- * the base fragment must be ignored
-- */
-- if (bas->fragment != NULL) {
-- xmlFree(bas->fragment);
-- bas->fragment = NULL;
-- }
-- val = xmlSaveUri(bas);
-- goto done;
-- }
--
-- /*
-- * 2) If the path component is empty and the scheme, authority, and
-- * query components are undefined, then it is a reference to the
-- * current document and we are done. Otherwise, the reference URI's
-- * query and fragment components are defined as found (or not found)
-- * within the URI reference and not inherited from the base URI.
-- *
-- * NOTE that in modern browsers, the parsing differs from the above
-- * in the following aspect: the query component is allowed to be
-- * defined while still treating this as a reference to the current
-- * document.
-- */
-- res = xmlCreateURI();
-- if (res == NULL)
-- goto done;
-- if ((ref->scheme == NULL) && (ref->path == NULL) &&
-- ((ref->authority == NULL) && (ref->server == NULL))) {
-- if (bas->scheme != NULL)
-- res->scheme = xmlMemStrdup(bas->scheme);
-- if (bas->authority != NULL)
-- res->authority = xmlMemStrdup(bas->authority);
-- else if (bas->server != NULL) {
-- res->server = xmlMemStrdup(bas->server);
-- if (bas->user != NULL)
-- res->user = xmlMemStrdup(bas->user);
-- res->port = bas->port;
-- }
-- if (bas->path != NULL)
-- res->path = xmlMemStrdup(bas->path);
-- if (ref->query != NULL)
-- res->query = xmlMemStrdup(ref->query);
-- else if (bas->query != NULL)
-- res->query = xmlMemStrdup(bas->query);
-- if (ref->fragment != NULL)
-- res->fragment = xmlMemStrdup(ref->fragment);
-- goto step_7;
-- }
--
-- if (ref->query != NULL)
-- res->query = xmlMemStrdup(ref->query);
-- if (ref->fragment != NULL)
-- res->fragment = xmlMemStrdup(ref->fragment);
--
-- /*
-- * 3) If the scheme component is defined, indicating that the reference
-- * starts with a scheme name, then the reference is interpreted as an
-- * absolute URI and we are done. Otherwise, the reference URI's
-- * scheme is inherited from the base URI's scheme component.
-- */
-- if (ref->scheme != NULL) {
-- val = xmlSaveUri(ref);
-- goto done;
-- }
-- if (bas->scheme != NULL)
-- res->scheme = xmlMemStrdup(bas->scheme);
--
-- /*
-- * 4) If the authority component is defined, then the reference is a
-- * network-path and we skip to step 7. Otherwise, the reference
-- * URI's authority is inherited from the base URI's authority
-- * component, which will also be undefined if the URI scheme does not
-- * use an authority component.
-- */
-- if ((ref->authority != NULL) || (ref->server != NULL)) {
-- if (ref->authority != NULL)
-- res->authority = xmlMemStrdup(ref->authority);
-- else {
-- res->server = xmlMemStrdup(ref->server);
-- if (ref->user != NULL)
-- res->user = xmlMemStrdup(ref->user);
-- res->port = ref->port;
-- }
-- if (ref->path != NULL)
-- res->path = xmlMemStrdup(ref->path);
-- goto step_7;
-- }
-- if (bas->authority != NULL)
-- res->authority = xmlMemStrdup(bas->authority);
-- else if (bas->server != NULL) {
-- res->server = xmlMemStrdup(bas->server);
-- if (bas->user != NULL)
-- res->user = xmlMemStrdup(bas->user);
-- res->port = bas->port;
-- }
--
-- /*
-- * 5) If the path component begins with a slash character ("/"), then
-- * the reference is an absolute-path and we skip to step 7.
-- */
-- if ((ref->path != NULL) && (ref->path[0] == '/')) {
-- res->path = xmlMemStrdup(ref->path);
-- goto step_7;
-- }
--
--
-- /*
-- * 6) If this step is reached, then we are resolving a relative-path
-- * reference. The relative path needs to be merged with the base
-- * URI's path. Although there are many ways to do this, we will
-- * describe a simple method using a separate string buffer.
-- *
-- * Allocate a buffer large enough for the result string.
-- */
-- len = 2; /* extra / and 0 */
-- if (ref->path != NULL)
-- len += strlen(ref->path);
-- if (bas->path != NULL)
-- len += strlen(bas->path);
-- res->path = (char *) xmlMalloc(len);
-- if (res->path == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlBuildURI: out of memory\n");
-- goto done;
-- }
-- res->path[0] = 0;
--
-- /*
-- * a) All but the last segment of the base URI's path component is
-- * copied to the buffer. In other words, any characters after the
-- * last (right-most) slash character, if any, are excluded.
-- */
-- cur = 0;
-- out = 0;
-- if (bas->path != NULL) {
-- while (bas->path[cur] != 0) {
-- while ((bas->path[cur] != 0) && (bas->path[cur] != '/'))
-- cur++;
-- if (bas->path[cur] == 0)
-- break;
--
-- cur++;
-- while (out < cur) {
-- res->path[out] = bas->path[out];
-- out++;
-- }
-- }
-- }
-- res->path[out] = 0;
--
-- /*
-- * b) The reference's path component is appended to the buffer
-- * string.
-- */
-- if (ref->path != NULL && ref->path[0] != 0) {
-- index = 0;
-- /*
-- * Ensure the path includes a '/'
-- */
-- if ((out == 0) && (bas->server != NULL))
-- res->path[out++] = '/';
-- while (ref->path[index] != 0) {
-- res->path[out++] = ref->path[index++];
-- }
-- }
-- res->path[out] = 0;
--
-- /*
-- * Steps c) to h) are really path normalization steps
-- */
-- xmlNormalizeURIPath(res->path);
--
--step_7:
--
-- /*
-- * 7) The resulting URI components, including any inherited from the
-- * base URI, are recombined to give the absolute form of the URI
-- * reference.
-- */
-- val = xmlSaveUri(res);
--
--done:
-- if (ref != NULL)
-- xmlFreeURI(ref);
-- if (bas != NULL)
-- xmlFreeURI(bas);
-- if (res != NULL)
-- xmlFreeURI(res);
-- return(val);
--}
--
--
-diff -Nru libxml2-2.3.0/valid.c libxml2-2.3.0.new/valid.c
---- libxml2-2.3.0/valid.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/valid.c Thu Jan 1 01:00:00 1970
-@@ -1,4025 +0,0 @@
--/*
-- * valid.c : part of the code use to do the DTD handling and the validity
-- * checking
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/hash.h>
--#include <libxml/valid.h>
--#include <libxml/parser.h>
--#include <libxml/parserInternals.h>
--#include <libxml/xmlerror.h>
--
--/*
-- * Generic function for accessing stacks in the Validity Context
-- */
--
--#define PUSH_AND_POP(scope, type, name) \
--scope int name##VPush(xmlValidCtxtPtr ctxt, type value) { \
-- if (ctxt->name##Nr >= ctxt->name##Max) { \
-- ctxt->name##Max *= 2; \
-- ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-- ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-- if (ctxt->name##Tab == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "realloc failed !\n"); \
-- return(0); \
-- } \
-- } \
-- ctxt->name##Tab[ctxt->name##Nr] = value; \
-- ctxt->name = value; \
-- return(ctxt->name##Nr++); \
--} \
--scope type name##VPop(xmlValidCtxtPtr ctxt) { \
-- type ret; \
-- if (ctxt->name##Nr <= 0) return(0); \
-- ctxt->name##Nr--; \
-- if (ctxt->name##Nr > 0) \
-- ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-- else \
-- ctxt->name = NULL; \
-- ret = ctxt->name##Tab[ctxt->name##Nr]; \
-- ctxt->name##Tab[ctxt->name##Nr] = 0; \
-- return(ret); \
--} \
--
--PUSH_AND_POP(static, xmlNodePtr, node)
--
--/* #define DEBUG_VALID_ALGO */
--
--#ifdef DEBUG_VALID_ALGO
--void xmlValidPrintNodeList(xmlNodePtr cur) {
-- if (cur == NULL)
-- xmlGenericError(xmlGenericErrorContext, "null ");
-- while (cur != NULL) {
-- switch (cur->type) {
-- case XML_ELEMENT_NODE:
-- xmlGenericError(xmlGenericErrorContext, "%s ", cur->name);
-- break;
-- case XML_TEXT_NODE:
-- xmlGenericError(xmlGenericErrorContext, "text ");
-- break;
-- case XML_CDATA_SECTION_NODE:
-- xmlGenericError(xmlGenericErrorContext, "cdata ");
-- break;
-- case XML_ENTITY_REF_NODE:
-- xmlGenericError(xmlGenericErrorContext, "&%s; ", cur->name);
-- break;
-- case XML_PI_NODE:
-- xmlGenericError(xmlGenericErrorContext, "pi(%s) ", cur->name);
-- break;
-- case XML_COMMENT_NODE:
-- xmlGenericError(xmlGenericErrorContext, "comment ");
-- break;
-- case XML_ATTRIBUTE_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?attr? ");
-- break;
-- case XML_ENTITY_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?ent? ");
-- break;
-- case XML_DOCUMENT_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?doc? ");
-- break;
-- case XML_DOCUMENT_TYPE_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?doctype? ");
-- break;
-- case XML_DOCUMENT_FRAG_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?frag? ");
-- break;
-- case XML_NOTATION_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?nota? ");
-- break;
-- case XML_HTML_DOCUMENT_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?html? ");
-- break;
-- case XML_DTD_NODE:
-- xmlGenericError(xmlGenericErrorContext, "?dtd? ");
-- break;
-- case XML_ELEMENT_DECL:
-- xmlGenericError(xmlGenericErrorContext, "?edecl? ");
-- break;
-- case XML_ATTRIBUTE_DECL:
-- xmlGenericError(xmlGenericErrorContext, "?adecl? ");
-- break;
-- case XML_ENTITY_DECL:
-- xmlGenericError(xmlGenericErrorContext, "?entdecl? ");
-- break;
-- }
-- cur = cur->next;
-- }
--}
--
--void xmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) {
-- char expr[1000];
--
-- expr[0] = 0;
-- xmlGenericError(xmlGenericErrorContext, "valid: ");
-- xmlValidPrintNodeList(cur);
-- xmlGenericError(xmlGenericErrorContext, "against ");
-- xmlSprintfElementContent(expr, cont, 0);
-- xmlGenericError(xmlGenericErrorContext, "%s\n", expr);
--}
--
--#define DEBUG_VALID_STATE(n,c) xmlValidDebug(n,c);
--#else
--#define DEBUG_VALID_STATE(n,c)
--#endif
--
--/* TODO: use hash table for accesses to elem and attribute dedinitions */
--
--#define VERROR \
-- if ((ctxt != NULL) && (ctxt->error != NULL)) ctxt->error
--
--#define VWARNING \
-- if ((ctxt != NULL) && (ctxt->warning != NULL)) ctxt->warning
--
--#define CHECK_DTD \
-- if (doc == NULL) return(0); \
-- else if ((doc->intSubset == NULL) && \
-- (doc->extSubset == NULL)) return(0)
--
--xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name);
--xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
--
--/************************************************************************
-- * *
-- * QName handling helper *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlSplitQName2:
-- * @name: an XML parser context
-- * @prefix: a xmlChar **
-- *
-- * parse an XML qualified name string
-- *
-- * [NS 5] QName ::= (Prefix ':')? LocalPart
-- *
-- * [NS 6] Prefix ::= NCName
-- *
-- * [NS 7] LocalPart ::= NCName
-- *
-- * Returns NULL if not a QName, otherwise the local part, and prefix
-- * is updated to get the Prefix if any.
-- */
--
--xmlChar *
--xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
-- int len = 0;
-- xmlChar *ret = NULL;
--
-- *prefix = NULL;
--
-- /* xml: prefix is not really a namespace */
-- if ((name[0] == 'x') && (name[1] == 'm') &&
-- (name[2] == 'l') && (name[3] == ':'))
-- return(NULL);
--
-- /* nasty but valid */
-- if (name[0] == ':')
-- return(NULL);
--
-- /*
-- * we are not trying to validate but just to cut, and yes it will
-- * work even if this is as set of UTF-8 encoded chars
-- */
-- while ((name[len] != 0) && (name[len] != ':'))
-- len++;
--
-- if (name[len] == 0)
-- return(NULL);
--
-- *prefix = xmlStrndup(name, len);
-- ret = xmlStrdup(&name[len + 1]);
--
-- return(ret);
--}
--
--/****************************************************************
-- * *
-- * Util functions for data allocation/deallocation *
-- * *
-- ****************************************************************/
--
--/**
-- * xmlNewElementContent:
-- * @name: the subelement name or NULL
-- * @type: the type of element content decl
-- *
-- * Allocate an element content structure.
-- *
-- * Returns NULL if not, othervise the new element content structure
-- */
--xmlElementContentPtr
--xmlNewElementContent(xmlChar *name, xmlElementContentType type) {
-- xmlElementContentPtr ret;
--
-- switch(type) {
-- case XML_ELEMENT_CONTENT_ELEMENT:
-- if (name == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewElementContent : name == NULL !\n");
-- }
-- break;
-- case XML_ELEMENT_CONTENT_PCDATA:
-- case XML_ELEMENT_CONTENT_SEQ:
-- case XML_ELEMENT_CONTENT_OR:
-- if (name != NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewElementContent : name != NULL !\n");
-- }
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewElementContent: unknown type %d\n", type);
-- return(NULL);
-- }
-- ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlNewElementContent : out of memory!\n");
-- return(NULL);
-- }
-- ret->type = type;
-- ret->ocur = XML_ELEMENT_CONTENT_ONCE;
-- if (name != NULL)
-- ret->name = xmlStrdup(name);
-- else
-- ret->name = NULL;
-- ret->c1 = ret->c2 = NULL;
-- return(ret);
--}
--
--/**
-- * xmlCopyElementContent:
-- * @content: An element content pointer.
-- *
-- * Build a copy of an element content description.
-- *
-- * Returns the new xmlElementContentPtr or NULL in case of error.
-- */
--xmlElementContentPtr
--xmlCopyElementContent(xmlElementContentPtr cur) {
-- xmlElementContentPtr ret;
--
-- if (cur == NULL) return(NULL);
-- ret = xmlNewElementContent((xmlChar *) cur->name, cur->type);
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCopyElementContent : out of memory\n");
-- return(NULL);
-- }
-- ret->ocur = cur->ocur;
-- if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1);
-- if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2);
-- return(ret);
--}
--
--/**
-- * xmlFreeElementContent:
-- * @cur: the element content tree to free
-- *
-- * Free an element content structure. This is a recursive call !
-- */
--void
--xmlFreeElementContent(xmlElementContentPtr cur) {
-- if (cur == NULL) return;
-- switch (cur->type) {
-- case XML_ELEMENT_CONTENT_PCDATA:
-- case XML_ELEMENT_CONTENT_ELEMENT:
-- case XML_ELEMENT_CONTENT_SEQ:
-- case XML_ELEMENT_CONTENT_OR:
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFreeElementContent : type %d\n", cur->type);
-- return;
-- }
-- if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
-- if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
-- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-- memset(cur, -1, sizeof(xmlElementContent));
-- xmlFree(cur);
--}
--
--/**
-- * xmlDumpElementContent:
-- * @buf: An XML buffer
-- * @content: An element table
-- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
-- *
-- * This will dump the content of the element table as an XML DTD definition
-- */
--void
--xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
-- if (content == NULL) return;
--
-- if (glob) xmlBufferWriteChar(buf, "(");
-- switch (content->type) {
-- case XML_ELEMENT_CONTENT_PCDATA:
-- xmlBufferWriteChar(buf, "#PCDATA");
-- break;
-- case XML_ELEMENT_CONTENT_ELEMENT:
-- xmlBufferWriteCHAR(buf, content->name);
-- break;
-- case XML_ELEMENT_CONTENT_SEQ:
-- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-- xmlDumpElementContent(buf, content->c1, 1);
-- else
-- xmlDumpElementContent(buf, content->c1, 0);
-- xmlBufferWriteChar(buf, " , ");
-- if (content->c2->type == XML_ELEMENT_CONTENT_OR)
-- xmlDumpElementContent(buf, content->c2, 1);
-- else
-- xmlDumpElementContent(buf, content->c2, 0);
-- break;
-- case XML_ELEMENT_CONTENT_OR:
-- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-- xmlDumpElementContent(buf, content->c1, 1);
-- else
-- xmlDumpElementContent(buf, content->c1, 0);
-- xmlBufferWriteChar(buf, " | ");
-- if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
-- xmlDumpElementContent(buf, content->c2, 1);
-- else
-- xmlDumpElementContent(buf, content->c2, 0);
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDumpElementContent: unknown type %d\n",
-- content->type);
-- }
-- if (glob)
-- xmlBufferWriteChar(buf, ")");
-- switch (content->ocur) {
-- case XML_ELEMENT_CONTENT_ONCE:
-- break;
-- case XML_ELEMENT_CONTENT_OPT:
-- xmlBufferWriteChar(buf, "?");
-- break;
-- case XML_ELEMENT_CONTENT_MULT:
-- xmlBufferWriteChar(buf, "*");
-- break;
-- case XML_ELEMENT_CONTENT_PLUS:
-- xmlBufferWriteChar(buf, "+");
-- break;
-- }
--}
--
--/**
-- * xmlSprintfElementContent:
-- * @buf: an output buffer
-- * @content: An element table
-- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
-- *
-- * This will dump the content of the element content definition
-- * Intended just for the debug routine
-- */
--void
--xmlSprintfElementContent(char *buf, xmlElementContentPtr content, int glob) {
-- if (content == NULL) return;
-- if (glob) strcat(buf, "(");
-- switch (content->type) {
-- case XML_ELEMENT_CONTENT_PCDATA:
-- strcat(buf, "#PCDATA");
-- break;
-- case XML_ELEMENT_CONTENT_ELEMENT:
-- strcat(buf, (char *) content->name);
-- break;
-- case XML_ELEMENT_CONTENT_SEQ:
-- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-- xmlSprintfElementContent(buf, content->c1, 1);
-- else
-- xmlSprintfElementContent(buf, content->c1, 0);
-- strcat(buf, " , ");
-- if (content->c2->type == XML_ELEMENT_CONTENT_OR)
-- xmlSprintfElementContent(buf, content->c2, 1);
-- else
-- xmlSprintfElementContent(buf, content->c2, 0);
-- break;
-- case XML_ELEMENT_CONTENT_OR:
-- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
-- xmlSprintfElementContent(buf, content->c1, 1);
-- else
-- xmlSprintfElementContent(buf, content->c1, 0);
-- strcat(buf, " | ");
-- if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
-- xmlSprintfElementContent(buf, content->c2, 1);
-- else
-- xmlSprintfElementContent(buf, content->c2, 0);
-- break;
-- }
-- if (glob)
-- strcat(buf, ")");
-- switch (content->ocur) {
-- case XML_ELEMENT_CONTENT_ONCE:
-- break;
-- case XML_ELEMENT_CONTENT_OPT:
-- strcat(buf, "?");
-- break;
-- case XML_ELEMENT_CONTENT_MULT:
-- strcat(buf, "*");
-- break;
-- case XML_ELEMENT_CONTENT_PLUS:
-- strcat(buf, "+");
-- break;
-- }
--}
--
--/****************************************************************
-- * *
-- * Registration of DTD declarations *
-- * *
-- ****************************************************************/
--
--/**
-- * xmlCreateElementTable:
-- *
-- * create and initialize an empty element hash table.
-- *
-- * Returns the xmlElementTablePtr just created or NULL in case of error.
-- */
--xmlElementTablePtr
--xmlCreateElementTable(void) {
-- return(xmlHashCreate(0));
--}
--
--/**
-- * xmlFreeElement:
-- * @elem: An element
-- *
-- * Deallocate the memory used by an element definition
-- */
--void
--xmlFreeElement(xmlElementPtr elem) {
-- if (elem == NULL) return;
-- xmlUnlinkNode((xmlNodePtr) elem);
-- xmlFreeElementContent(elem->content);
-- if (elem->name != NULL)
-- xmlFree((xmlChar *) elem->name);
-- if (elem->prefix != NULL)
-- xmlFree((xmlChar *) elem->prefix);
-- memset(elem, -1, sizeof(xmlElement));
-- xmlFree(elem);
--}
--
--
--/**
-- * xmlAddElementDecl:
-- * @ctxt: the validation context
-- * @dtd: pointer to the DTD
-- * @name: the entity name
-- * @type: the element type
-- * @content: the element content tree or NULL
-- *
-- * Register a new element declaration
-- *
-- * Returns NULL if not, othervise the entity
-- */
--xmlElementPtr
--xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
-- xmlElementTypeVal type,
-- xmlElementContentPtr content) {
-- xmlElementPtr ret;
-- xmlElementTablePtr table;
-- xmlChar *ns, *uqname;
--
-- if (dtd == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: dtd == NULL\n");
-- return(NULL);
-- }
-- if (name == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: name == NULL\n");
-- return(NULL);
-- }
-- switch (type) {
-- case XML_ELEMENT_TYPE_EMPTY:
-- if (content != NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: content != NULL for EMPTY\n");
-- return(NULL);
-- }
-- break;
-- case XML_ELEMENT_TYPE_ANY:
-- if (content != NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: content != NULL for ANY\n");
-- return(NULL);
-- }
-- break;
-- case XML_ELEMENT_TYPE_MIXED:
-- if (content == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: content == NULL for MIXED\n");
-- return(NULL);
-- }
-- break;
-- case XML_ELEMENT_TYPE_ELEMENT:
-- if (content == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: content == NULL for ELEMENT\n");
-- return(NULL);
-- }
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: unknown type %d\n", type);
-- return(NULL);
-- }
--
-- /*
-- * check if name is a QName
-- */
-- uqname = xmlSplitQName2(name, &ns);
-- if (uqname != NULL)
-- name = uqname;
--
-- /*
-- * Create the Element table if needed.
-- */
-- table = (xmlElementTablePtr) dtd->elements;
-- if (table == NULL) {
-- table = xmlCreateElementTable();
-- dtd->elements = (void *) table;
-- }
-- if (table == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: Table creation failed!\n");
-- return(NULL);
-- }
--
-- ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddElementDecl: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlElement));
-- ret->type = XML_ELEMENT_DECL;
--
-- /*
-- * fill the structure.
-- */
-- ret->etype = type;
-- ret->name = xmlStrdup(name);
-- ret->prefix = ns;
-- ret->content = xmlCopyElementContent(content);
-- ret->attributes = xmlScanAttributeDecl(dtd, name);
--
-- /*
-- * Validity Check:
-- * Insertion must not fail
-- */
-- if (xmlHashAddEntry2(table, name, ns, ret)) {
-- /*
-- * The element is already defined in this Dtd.
-- */
-- VERROR(ctxt->userData, "Redefinition of element %s\n", name);
-- xmlFreeElement(ret);
-- if (uqname != NULL)
-- xmlFree(uqname);
-- return(NULL);
-- }
--
-- /*
-- * Link it to the Dtd
-- */
-- ret->parent = dtd;
-- ret->doc = dtd->doc;
-- if (dtd->last == NULL) {
-- dtd->children = dtd->last = (xmlNodePtr) ret;
-- } else {
-- dtd->last->next = (xmlNodePtr) ret;
-- ret->prev = dtd->last;
-- dtd->last = (xmlNodePtr) ret;
-- }
-- if (uqname != NULL)
-- xmlFree(uqname);
-- return(ret);
--}
--
--/**
-- * xmlFreeElementTable:
-- * @table: An element table
-- *
-- * Deallocate the memory used by an element hash table.
-- */
--void
--xmlFreeElementTable(xmlElementTablePtr table) {
-- xmlHashFree(table, (xmlHashDeallocator) xmlFreeElement);
--}
--
--/**
-- * xmlCopyElement:
-- * @elem: An element
-- *
-- * Build a copy of an element.
-- *
-- * Returns the new xmlElementPtr or NULL in case of error.
-- */
--xmlElementPtr
--xmlCopyElement(xmlElementPtr elem) {
-- xmlElementPtr cur;
--
-- cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCopyElement: out of memory !\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlElement));
-- cur->type = XML_ELEMENT_DECL;
-- cur->etype = elem->etype;
-- if (elem->name != NULL)
-- cur->name = xmlStrdup(elem->name);
-- else
-- cur->name = NULL;
-- if (elem->prefix != NULL)
-- cur->prefix = xmlStrdup(elem->prefix);
-- else
-- cur->prefix = NULL;
-- cur->content = xmlCopyElementContent(elem->content);
-- /* TODO : rebuild the attribute list on the copy */
-- cur->attributes = NULL;
-- return(cur);
--}
--
--/**
-- * xmlCopyElementTable:
-- * @table: An element table
-- *
-- * Build a copy of an element table.
-- *
-- * Returns the new xmlElementTablePtr or NULL in case of error.
-- */
--xmlElementTablePtr
--xmlCopyElementTable(xmlElementTablePtr table) {
-- return((xmlElementTablePtr) xmlHashCopy(table,
-- (xmlHashCopier) xmlCopyElement));
--}
--
--/**
-- * xmlDumpElementDecl:
-- * @buf: the XML buffer output
-- * @elem: An element table
-- *
-- * This will dump the content of the element declaration as an XML
-- * DTD definition
-- */
--void
--xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
-- switch (elem->etype) {
-- case XML_ELEMENT_TYPE_EMPTY:
-- xmlBufferWriteChar(buf, "<!ELEMENT ");
-- xmlBufferWriteCHAR(buf, elem->name);
-- xmlBufferWriteChar(buf, " EMPTY>\n");
-- break;
-- case XML_ELEMENT_TYPE_ANY:
-- xmlBufferWriteChar(buf, "<!ELEMENT ");
-- xmlBufferWriteCHAR(buf, elem->name);
-- xmlBufferWriteChar(buf, " ANY>\n");
-- break;
-- case XML_ELEMENT_TYPE_MIXED:
-- xmlBufferWriteChar(buf, "<!ELEMENT ");
-- xmlBufferWriteCHAR(buf, elem->name);
-- xmlBufferWriteChar(buf, " ");
-- xmlDumpElementContent(buf, elem->content, 1);
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- case XML_ELEMENT_TYPE_ELEMENT:
-- xmlBufferWriteChar(buf, "<!ELEMENT ");
-- xmlBufferWriteCHAR(buf, elem->name);
-- xmlBufferWriteChar(buf, " ");
-- xmlDumpElementContent(buf, elem->content, 1);
-- xmlBufferWriteChar(buf, ">\n");
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDumpElementDecl: internal: unknown type %d\n",
-- elem->etype);
-- }
--}
--
--/**
-- * xmlDumpElementTable:
-- * @buf: the XML buffer output
-- * @table: An element table
-- *
-- * This will dump the content of the element table as an XML DTD definition
-- */
--void
--xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
-- xmlHashScan(table, (xmlHashScanner) xmlDumpElementDecl, buf);
--}
--
--/**
-- * xmlCreateEnumeration:
-- * @name: the enumeration name or NULL
-- *
-- * create and initialize an enumeration attribute node.
-- *
-- * Returns the xmlEnumerationPtr just created or NULL in case
-- * of error.
-- */
--xmlEnumerationPtr
--xmlCreateEnumeration(xmlChar *name) {
-- xmlEnumerationPtr ret;
--
-- ret = (xmlEnumerationPtr) xmlMalloc(sizeof(xmlEnumeration));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCreateEnumeration : xmlMalloc(%ld) failed\n",
-- (long)sizeof(xmlEnumeration));
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlEnumeration));
--
-- if (name != NULL)
-- ret->name = xmlStrdup(name);
-- return(ret);
--}
--
--/**
-- * xmlFreeEnumeration:
-- * @cur: the tree to free.
-- *
-- * free an enumeration attribute node (recursive).
-- */
--void
--xmlFreeEnumeration(xmlEnumerationPtr cur) {
-- if (cur == NULL) return;
--
-- if (cur->next != NULL) xmlFreeEnumeration(cur->next);
--
-- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-- memset(cur, -1, sizeof(xmlEnumeration));
-- xmlFree(cur);
--}
--
--/**
-- * xmlCopyEnumeration:
-- * @cur: the tree to copy.
-- *
-- * Copy an enumeration attribute node (recursive).
-- *
-- * Returns the xmlEnumerationPtr just created or NULL in case
-- * of error.
-- */
--xmlEnumerationPtr
--xmlCopyEnumeration(xmlEnumerationPtr cur) {
-- xmlEnumerationPtr ret;
--
-- if (cur == NULL) return(NULL);
-- ret = xmlCreateEnumeration((xmlChar *) cur->name);
--
-- if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
-- else ret->next = NULL;
--
-- return(ret);
--}
--
--/**
-- * xmlDumpEnumeration:
-- * @buf: the XML buffer output
-- * @enum: An enumeration
-- *
-- * This will dump the content of the enumeration
-- */
--void
--xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
-- if (cur == NULL) return;
--
-- xmlBufferWriteCHAR(buf, cur->name);
-- if (cur->next == NULL)
-- xmlBufferWriteChar(buf, ")");
-- else {
-- xmlBufferWriteChar(buf, " | ");
-- xmlDumpEnumeration(buf, cur->next);
-- }
--}
--
--/**
-- * xmlCreateAttributeTable:
-- *
-- * create and initialize an empty attribute hash table.
-- *
-- * Returns the xmlAttributeTablePtr just created or NULL in case
-- * of error.
-- */
--xmlAttributeTablePtr
--xmlCreateAttributeTable(void) {
-- return(xmlHashCreate(0));
--}
--
--/**
-- * xmlScanAttributeDeclCallback:
-- * @attr: the attribute decl
-- * @list: the list to update
-- *
-- * Callback called by xmlScanAttributeDecl when a new attribute
-- * has to be entered in the list.
-- */
--void
--xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
-- const xmlChar* name) {
-- attr->nexth = *list;
-- *list = attr;
--}
--
--/**
-- * xmlScanAttributeDecl:
-- * @dtd: pointer to the DTD
-- * @elem: the element name
-- *
-- * When inserting a new element scan the DtD for existing attributes
-- * for taht element and initialize the Attribute chain
-- *
-- * Returns the pointer to the first attribute decl in the chain,
-- * possibly NULL.
-- */
--xmlAttributePtr
--xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
-- xmlAttributePtr ret = NULL;
-- xmlAttributeTablePtr table;
--
-- if (dtd == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlScanAttributeDecl: dtd == NULL\n");
-- return(NULL);
-- }
-- if (elem == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlScanAttributeDecl: elem == NULL\n");
-- return(NULL);
-- }
-- table = (xmlAttributeTablePtr) dtd->attributes;
-- if (table == NULL)
-- return(NULL);
--
-- /* WRONG !!! */
-- xmlHashScan3(table, NULL, NULL, elem,
-- (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
-- return(ret);
--}
--
--/**
-- * xmlScanIDAttributeDecl:
-- * @ctxt: the validation context
-- * @elem: the element name
-- *
-- * Verify that the element don't have too many ID attributes
-- * declared.
-- *
-- * Returns the number of ID attributes found.
-- */
--int
--xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
-- xmlAttributePtr cur;
-- int ret = 0;
--
-- if (elem == NULL) return(0);
-- cur = elem->attributes;
-- while (cur != NULL) {
-- if (cur->atype == XML_ATTRIBUTE_ID) {
-- ret ++;
-- if (ret > 1)
-- VERROR(ctxt->userData,
-- "Element %s has too may ID attributes defined : %s\n",
-- elem->name, cur->name);
-- }
-- cur = cur->nexth;
-- }
-- return(ret);
--}
--
--/**
-- * xmlFreeAttribute:
-- * @elem: An attribute
-- *
-- * Deallocate the memory used by an attribute definition
-- */
--void
--xmlFreeAttribute(xmlAttributePtr attr) {
-- if (attr == NULL) return;
-- xmlUnlinkNode((xmlNodePtr) attr);
-- if (attr->tree != NULL)
-- xmlFreeEnumeration(attr->tree);
-- if (attr->elem != NULL)
-- xmlFree((xmlChar *) attr->elem);
-- if (attr->name != NULL)
-- xmlFree((xmlChar *) attr->name);
-- if (attr->defaultValue != NULL)
-- xmlFree((xmlChar *) attr->defaultValue);
-- if (attr->prefix != NULL)
-- xmlFree((xmlChar *) attr->prefix);
-- memset(attr, -1, sizeof(xmlAttribute));
-- xmlFree(attr);
--}
--
--
--/**
-- * xmlAddAttributeDecl:
-- * @ctxt: the validation context
-- * @dtd: pointer to the DTD
-- * @elem: the element name
-- * @name: the attribute name
-- * @ns: the attribute namespace prefix
-- * @type: the attribute type
-- * @def: the attribute default type
-- * @defaultValue: the attribute default value
-- * @tree: if it's an enumeration, the associated list
-- *
-- * Register a new attribute declaration
-- * Note that @tree becomes the ownership of the DTD
-- *
-- * Returns NULL if not new, othervise the attribute decl
-- */
--xmlAttributePtr
--xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
-- const xmlChar *name, const xmlChar *ns,
-- xmlAttributeType type, xmlAttributeDefault def,
-- const xmlChar *defaultValue, xmlEnumerationPtr tree) {
-- xmlAttributePtr ret;
-- xmlAttributeTablePtr table;
-- xmlElementPtr elemDef;
--
-- if (dtd == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddAttributeDecl: dtd == NULL\n");
-- xmlFreeEnumeration(tree);
-- return(NULL);
-- }
-- if (name == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddAttributeDecl: name == NULL\n");
-- xmlFreeEnumeration(tree);
-- return(NULL);
-- }
-- if (elem == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddAttributeDecl: elem == NULL\n");
-- xmlFreeEnumeration(tree);
-- return(NULL);
-- }
-- /*
-- * Check the type and possibly the default value.
-- */
-- switch (type) {
-- case XML_ATTRIBUTE_CDATA:
-- break;
-- case XML_ATTRIBUTE_ID:
-- break;
-- case XML_ATTRIBUTE_IDREF:
-- break;
-- case XML_ATTRIBUTE_IDREFS:
-- break;
-- case XML_ATTRIBUTE_ENTITY:
-- break;
-- case XML_ATTRIBUTE_ENTITIES:
-- break;
-- case XML_ATTRIBUTE_NMTOKEN:
-- break;
-- case XML_ATTRIBUTE_NMTOKENS:
-- break;
-- case XML_ATTRIBUTE_ENUMERATION:
-- break;
-- case XML_ATTRIBUTE_NOTATION:
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddAttributeDecl: unknown type %d\n", type);
-- xmlFreeEnumeration(tree);
-- return(NULL);
-- }
-- if ((defaultValue != NULL) &&
-- (!xmlValidateAttributeValue(type, defaultValue))) {
-- VERROR(ctxt->userData, "Attribute %s on %s: invalid default value\n",
-- elem, name, defaultValue);
-- defaultValue = NULL;
-- }
--
-- /*
-- * Create the Attribute table if needed.
-- */
-- table = (xmlAttributeTablePtr) dtd->attributes;
-- if (table == NULL) {
-- table = xmlCreateAttributeTable();
-- dtd->attributes = (void *) table;
-- }
-- if (table == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddAttributeDecl: Table creation failed!\n");
-- return(NULL);
-- }
--
--
-- ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddAttributeDecl: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlAttribute));
-- ret->type = XML_ATTRIBUTE_DECL;
--
-- /*
-- * fill the structure.
-- */
-- ret->atype = type;
-- ret->name = xmlStrdup(name);
-- ret->prefix = xmlStrdup(ns);
-- ret->elem = xmlStrdup(elem);
-- ret->def = def;
-- ret->tree = tree;
-- if (defaultValue != NULL)
-- ret->defaultValue = xmlStrdup(defaultValue);
--
-- /*
-- * Validity Check:
-- * Search the DTD for previous declarations of the ATTLIST
-- */
-- if (xmlHashAddEntry3(table, name, ns, elem, ret) < 0) {
-- /*
-- * The attribute is already defined in this Dtd.
-- */
-- VWARNING(ctxt->userData,
-- "Attribute %s on %s: already defined\n",
-- name, elem);
-- xmlFreeAttribute(ret);
-- return(NULL);
-- }
--
-- /*
-- * Validity Check:
-- * Multiple ID per element
-- */
-- elemDef = xmlGetDtdElementDesc(dtd, elem);
-- if (elemDef != NULL) {
-- if ((type == XML_ATTRIBUTE_ID) &&
-- (xmlScanIDAttributeDecl(NULL, elemDef) != 0))
-- VERROR(ctxt->userData,
-- "Element %s has too may ID attributes defined : %s\n",
-- elem, name);
-- ret->nexth = elemDef->attributes;
-- elemDef->attributes = ret;
-- }
--
-- /*
-- * Link it to the Dtd
-- */
-- ret->parent = dtd;
-- ret->doc = dtd->doc;
-- if (dtd->last == NULL) {
-- dtd->children = dtd->last = (xmlNodePtr) ret;
-- } else {
-- dtd->last->next = (xmlNodePtr) ret;
-- ret->prev = dtd->last;
-- dtd->last = (xmlNodePtr) ret;
-- }
-- return(ret);
--}
--
--/**
-- * xmlFreeAttributeTable:
-- * @table: An attribute table
-- *
-- * Deallocate the memory used by an entities hash table.
-- */
--void
--xmlFreeAttributeTable(xmlAttributeTablePtr table) {
-- xmlHashFree(table, (xmlHashDeallocator) xmlFreeAttribute);
--}
--
--/**
-- * xmlCopyAttribute:
-- * @attr: An attribute
-- *
-- * Build a copy of an attribute.
-- *
-- * Returns the new xmlAttributePtr or NULL in case of error.
-- */
--xmlAttributePtr
--xmlCopyAttribute(xmlAttributePtr attr) {
-- xmlAttributePtr cur;
--
-- cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCopyAttribute: out of memory !\n");
-- return(NULL);
-- }
-- memset(cur, 0, sizeof(xmlAttribute));
-- cur->atype = attr->atype;
-- cur->def = attr->def;
-- cur->tree = xmlCopyEnumeration(attr->tree);
-- if (attr->elem != NULL)
-- cur->elem = xmlStrdup(attr->elem);
-- if (attr->name != NULL)
-- cur->name = xmlStrdup(attr->name);
-- if (attr->defaultValue != NULL)
-- cur->defaultValue = xmlStrdup(attr->defaultValue);
-- return(cur);
--}
--
--/**
-- * xmlCopyAttributeTable:
-- * @table: An attribute table
-- *
-- * Build a copy of an attribute table.
-- *
-- * Returns the new xmlAttributeTablePtr or NULL in case of error.
-- */
--xmlAttributeTablePtr
--xmlCopyAttributeTable(xmlAttributeTablePtr table) {
-- return((xmlAttributeTablePtr) xmlHashCopy(table,
-- (xmlHashCopier) xmlCopyAttribute));
--}
--
--/**
-- * xmlDumpAttributeDecl:
-- * @buf: the XML buffer output
-- * @attr: An attribute declaration
-- *
-- * This will dump the content of the attribute declaration as an XML
-- * DTD definition
-- */
--void
--xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
-- xmlBufferWriteChar(buf, "<!ATTLIST ");
-- xmlBufferWriteCHAR(buf, attr->elem);
-- xmlBufferWriteChar(buf, " ");
-- if (attr->prefix != NULL) {
-- xmlBufferWriteCHAR(buf, attr->prefix);
-- xmlBufferWriteChar(buf, ":");
-- }
-- xmlBufferWriteCHAR(buf, attr->name);
-- switch (attr->atype) {
-- case XML_ATTRIBUTE_CDATA:
-- xmlBufferWriteChar(buf, " CDATA");
-- break;
-- case XML_ATTRIBUTE_ID:
-- xmlBufferWriteChar(buf, " ID");
-- break;
-- case XML_ATTRIBUTE_IDREF:
-- xmlBufferWriteChar(buf, " IDREF");
-- break;
-- case XML_ATTRIBUTE_IDREFS:
-- xmlBufferWriteChar(buf, " IDREFS");
-- break;
-- case XML_ATTRIBUTE_ENTITY:
-- xmlBufferWriteChar(buf, " ENTITY");
-- break;
-- case XML_ATTRIBUTE_ENTITIES:
-- xmlBufferWriteChar(buf, " ENTITIES");
-- break;
-- case XML_ATTRIBUTE_NMTOKEN:
-- xmlBufferWriteChar(buf, " NMTOKEN");
-- break;
-- case XML_ATTRIBUTE_NMTOKENS:
-- xmlBufferWriteChar(buf, " NMTOKENS");
-- break;
-- case XML_ATTRIBUTE_ENUMERATION:
-- xmlBufferWriteChar(buf, " (");
-- xmlDumpEnumeration(buf, attr->tree);
-- break;
-- case XML_ATTRIBUTE_NOTATION:
-- xmlBufferWriteChar(buf, " NOTATION (");
-- xmlDumpEnumeration(buf, attr->tree);
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDumpAttributeTable: internal: unknown type %d\n",
-- attr->atype);
-- }
-- switch (attr->def) {
-- case XML_ATTRIBUTE_NONE:
-- break;
-- case XML_ATTRIBUTE_REQUIRED:
-- xmlBufferWriteChar(buf, " #REQUIRED");
-- break;
-- case XML_ATTRIBUTE_IMPLIED:
-- xmlBufferWriteChar(buf, " #IMPLIED");
-- break;
-- case XML_ATTRIBUTE_FIXED:
-- xmlBufferWriteChar(buf, " #FIXED");
-- break;
-- default:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDumpAttributeTable: internal: unknown default %d\n",
-- attr->def);
-- }
-- if (attr->defaultValue != NULL) {
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteQuotedString(buf, attr->defaultValue);
-- }
-- xmlBufferWriteChar(buf, ">\n");
--}
--
--/**
-- * xmlDumpAttributeTable:
-- * @buf: the XML buffer output
-- * @table: An attribute table
-- *
-- * This will dump the content of the attribute table as an XML DTD definition
-- */
--void
--xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
-- xmlHashScan(table, (xmlHashScanner) xmlDumpAttributeDecl, buf);
--}
--
--/************************************************************************
-- * *
-- * NOTATIONs *
-- * *
-- ************************************************************************/
--/**
-- * xmlCreateNotationTable:
-- *
-- * create and initialize an empty notation hash table.
-- *
-- * Returns the xmlNotationTablePtr just created or NULL in case
-- * of error.
-- */
--xmlNotationTablePtr
--xmlCreateNotationTable(void) {
-- return(xmlHashCreate(0));
--}
--
--/**
-- * xmlFreeNotation:
-- * @not: A notation
-- *
-- * Deallocate the memory used by an notation definition
-- */
--void
--xmlFreeNotation(xmlNotationPtr nota) {
-- if (nota == NULL) return;
-- if (nota->name != NULL)
-- xmlFree((xmlChar *) nota->name);
-- if (nota->PublicID != NULL)
-- xmlFree((xmlChar *) nota->PublicID);
-- if (nota->SystemID != NULL)
-- xmlFree((xmlChar *) nota->SystemID);
-- memset(nota, -1, sizeof(xmlNotation));
-- xmlFree(nota);
--}
--
--
--/**
-- * xmlAddNotationDecl:
-- * @dtd: pointer to the DTD
-- * @ctxt: the validation context
-- * @name: the entity name
-- * @PublicID: the public identifier or NULL
-- * @SystemID: the system identifier or NULL
-- *
-- * Register a new notation declaration
-- *
-- * Returns NULL if not, othervise the entity
-- */
--xmlNotationPtr
--xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
-- const xmlChar *PublicID, const xmlChar *SystemID) {
-- xmlNotationPtr ret;
-- xmlNotationTablePtr table;
--
-- if (dtd == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNotationDecl: dtd == NULL\n");
-- return(NULL);
-- }
-- if (name == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNotationDecl: name == NULL\n");
-- return(NULL);
-- }
-- if ((PublicID == NULL) && (SystemID == NULL)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
-- }
--
-- /*
-- * Create the Notation table if needed.
-- */
-- table = (xmlNotationTablePtr) dtd->notations;
-- if (table == NULL)
-- dtd->notations = table = xmlCreateNotationTable();
-- if (table == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNotationDecl: Table creation failed!\n");
-- return(NULL);
-- }
--
-- ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNotationDecl: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0, sizeof(xmlNotation));
--
-- /*
-- * fill the structure.
-- */
-- ret->name = xmlStrdup(name);
-- if (SystemID != NULL)
-- ret->SystemID = xmlStrdup(SystemID);
-- if (PublicID != NULL)
-- ret->PublicID = xmlStrdup(PublicID);
--
-- /*
-- * Validity Check:
-- * Check the DTD for previous declarations of the ATTLIST
-- */
-- if (xmlHashAddEntry(table, name, ret)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddNotationDecl: %s already defined\n", name);
-- xmlFreeNotation(ret);
-- return(NULL);
-- }
-- return(ret);
--}
--
--/**
-- * xmlFreeNotationTable:
-- * @table: An notation table
-- *
-- * Deallocate the memory used by an entities hash table.
-- */
--void
--xmlFreeNotationTable(xmlNotationTablePtr table) {
-- xmlHashFree(table, (xmlHashDeallocator) xmlFreeNotation);
--}
--
--/**
-- * xmlCopyNotation:
-- * @nota: A notation
-- *
-- * Build a copy of a notation.
-- *
-- * Returns the new xmlNotationPtr or NULL in case of error.
-- */
--xmlNotationPtr
--xmlCopyNotation(xmlNotationPtr nota) {
-- xmlNotationPtr cur;
--
-- cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
-- if (cur == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlCopyNotation: out of memory !\n");
-- return(NULL);
-- }
-- if (nota->name != NULL)
-- cur->name = xmlStrdup(nota->name);
-- else
-- cur->name = NULL;
-- if (nota->PublicID != NULL)
-- cur->PublicID = xmlStrdup(nota->PublicID);
-- else
-- cur->PublicID = NULL;
-- if (nota->SystemID != NULL)
-- cur->SystemID = xmlStrdup(nota->SystemID);
-- else
-- cur->SystemID = NULL;
-- return(cur);
--}
--
--/**
-- * xmlCopyNotationTable:
-- * @table: A notation table
-- *
-- * Build a copy of a notation table.
-- *
-- * Returns the new xmlNotationTablePtr or NULL in case of error.
-- */
--xmlNotationTablePtr
--xmlCopyNotationTable(xmlNotationTablePtr table) {
-- return((xmlNotationTablePtr) xmlHashCopy(table,
-- (xmlHashCopier) xmlCopyNotation));
--}
--
--/**
-- * xmlDumpNotationDecl:
-- * @buf: the XML buffer output
-- * @nota: A notation declaration
-- *
-- * This will dump the content the notation declaration as an XML DTD definition
-- */
--void
--xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) {
-- xmlBufferWriteChar(buf, "<!NOTATION ");
-- xmlBufferWriteCHAR(buf, nota->name);
-- if (nota->PublicID != NULL) {
-- xmlBufferWriteChar(buf, " PUBLIC ");
-- xmlBufferWriteQuotedString(buf, nota->PublicID);
-- if (nota->SystemID != NULL) {
-- xmlBufferWriteChar(buf, " ");
-- xmlBufferWriteCHAR(buf, nota->SystemID);
-- }
-- } else {
-- xmlBufferWriteChar(buf, " SYSTEM ");
-- xmlBufferWriteCHAR(buf, nota->SystemID);
-- }
-- xmlBufferWriteChar(buf, " >\n");
--}
--
--/**
-- * xmlDumpNotationTable:
-- * @buf: the XML buffer output
-- * @table: A notation table
-- *
-- * This will dump the content of the notation table as an XML DTD definition
-- */
--void
--xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
-- xmlHashScan(table, (xmlHashScanner) xmlDumpNotationDecl, buf);
--}
--
--/************************************************************************
-- * *
-- * IDs *
-- * *
-- ************************************************************************/
--/**
-- * xmlCreateIDTable:
-- *
-- * create and initialize an empty id hash table.
-- *
-- * Returns the xmlIDTablePtr just created or NULL in case
-- * of error.
-- */
--xmlIDTablePtr
--xmlCreateIDTable(void) {
-- return(xmlHashCreate(0));
--}
--
--/**
-- * xmlFreeID:
-- * @not: A id
-- *
-- * Deallocate the memory used by an id definition
-- */
--void
--xmlFreeID(xmlIDPtr id) {
-- if (id == NULL) return;
-- if (id->value != NULL)
-- xmlFree((xmlChar *) id->value);
-- memset(id, -1, sizeof(xmlID));
-- xmlFree(id);
--}
--
--/**
-- * xmlAddID:
-- * @ctxt: the validation context
-- * @doc: pointer to the document
-- * @value: the value name
-- * @attr: the attribute holding the ID
-- *
-- * Register a new id declaration
-- *
-- * Returns NULL if not, othervise the new xmlIDPtr
-- */
--xmlIDPtr
--xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
-- xmlAttrPtr attr) {
-- xmlIDPtr ret;
-- xmlIDTablePtr table;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddIDDecl: doc == NULL\n");
-- return(NULL);
-- }
-- if (value == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddIDDecl: value == NULL\n");
-- return(NULL);
-- }
-- if (attr == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddIDDecl: attr == NULL\n");
-- return(NULL);
-- }
--
-- /*
-- * Create the ID table if needed.
-- */
-- table = (xmlIDTablePtr) doc->ids;
-- if (table == NULL)
-- doc->ids = table = xmlCreateIDTable();
-- if (table == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddID: Table creation failed!\n");
-- return(NULL);
-- }
--
-- ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddID: out of memory\n");
-- return(NULL);
-- }
--
-- /*
-- * fill the structure.
-- */
-- ret->value = xmlStrdup(value);
-- ret->attr = attr;
--
-- if (xmlHashAddEntry(table, value, ret) < 0) {
-- /*
-- * The id is already defined in this Dtd.
-- */
-- VERROR(ctxt->userData, "ID %s already defined\n", value);
-- xmlFreeID(ret);
-- return(NULL);
-- }
-- return(ret);
--}
--
--/**
-- * xmlFreeIDTable:
-- * @table: An id table
-- *
-- * Deallocate the memory used by an ID hash table.
-- */
--void
--xmlFreeIDTable(xmlIDTablePtr table) {
-- xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
--}
--
--/**
-- * xmlIsID:
-- * @doc: the document
-- * @elem: the element carrying the attribute
-- * @attr: the attribute
-- *
-- * Determine whether an attribute is of type ID. In case we have Dtd(s)
-- * then this is simple, otherwise we use an heuristic: name ID (upper
-- * or lowercase).
-- *
-- * Returns 0 or 1 depending on the lookup result
-- */
--int
--xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
-- if (doc == NULL) return(0);
-- if (attr == NULL) return(0);
-- if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
-- return(0);
-- } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
-- if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
-- (xmlStrEqual(BAD_CAST "name", attr->name)))
-- return(1);
-- return(0);
-- } else {
-- xmlAttributePtr attrDecl;
--
-- if (elem == NULL) return(0);
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name,
-- attr->name);
--
-- if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
-- return(1);
-- }
-- return(0);
--}
--
--/**
-- * xmlRemoveID
-- * @doc: the document
-- * @attr: the attribute
-- *
-- * Remove the given attribute from the ID table maintained internally.
-- *
-- * Returns -1 if the lookup failed and 0 otherwise
-- */
--int
--xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
-- xmlAttrPtr cur;
-- xmlIDTablePtr table;
-- xmlChar *ID;
--
-- if (doc == NULL) return(-1);
-- if (attr == NULL) return(-1);
-- table = (xmlIDTablePtr) doc->ids;
-- if (table == NULL)
-- return(-1);
--
-- if (attr == NULL)
-- return(-1);
-- ID = xmlNodeListGetString(doc, attr->children, 1);
-- if (ID == NULL)
-- return(-1);
-- cur = xmlHashLookup(table, ID);
-- if (cur != attr) {
-- xmlFree(ID);
-- return(-1);
-- }
-- xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeID);
-- xmlFree(ID);
-- return(0);
--}
--
--/**
-- * xmlGetID:
-- * @doc: pointer to the document
-- * @ID: the ID value
-- *
-- * Search the attribute declaring the given ID
-- *
-- * Returns NULL if not found, otherwise the xmlAttrPtr defining the ID
-- */
--xmlAttrPtr
--xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
-- xmlIDTablePtr table;
-- xmlIDPtr id;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "xmlGetID: doc == NULL\n");
-- return(NULL);
-- }
--
-- if (ID == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "xmlGetID: ID == NULL\n");
-- return(NULL);
-- }
--
-- table = (xmlIDTablePtr) doc->ids;
-- if (table == NULL)
-- return(NULL);
--
-- id = xmlHashLookup(table, ID);
-- if (id == NULL)
-- return(NULL);
-- return(id->attr);
--}
--
--/************************************************************************
-- * *
-- * Refs *
-- * *
-- ************************************************************************/
--/**
-- * xmlCreateRefTable:
-- *
-- * create and initialize an empty ref hash table.
-- *
-- * Returns the xmlRefTablePtr just created or NULL in case
-- * of error.
-- */
--xmlRefTablePtr
--xmlCreateRefTable(void) {
-- return(xmlHashCreate(0));
--}
--
--/**
-- * xmlFreeRef:
-- * @ref: A ref
-- *
-- * Deallocate the memory used by an ref definition
-- */
--void
--xmlFreeRef(xmlRefPtr ref) {
-- if (ref == NULL) return;
-- if (ref->value != NULL)
-- xmlFree((xmlChar *) ref->value);
-- memset(ref, -1, sizeof(xmlRef));
-- xmlFree(ref);
--}
--
--/**
-- * xmlAddRef:
-- * @ctxt: the validation context
-- * @doc: pointer to the document
-- * @value: the value name
-- * @attr: the attribute holding the Ref
-- *
-- * Register a new ref declaration
-- *
-- * Returns NULL if not, othervise the new xmlRefPtr
-- */
--xmlRefPtr
--xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
-- xmlAttrPtr attr) {
-- xmlRefPtr ret;
-- xmlRefTablePtr table;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddRefDecl: doc == NULL\n");
-- return(NULL);
-- }
-- if (value == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddRefDecl: value == NULL\n");
-- return(NULL);
-- }
-- if (attr == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddRefDecl: attr == NULL\n");
-- return(NULL);
-- }
--
-- /*
-- * Create the Ref table if needed.
-- */
-- table = (xmlRefTablePtr) doc->refs;
-- if (table == NULL)
-- doc->refs = table = xmlCreateRefTable();
-- if (table == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddRef: Table creation failed!\n");
-- return(NULL);
-- }
--
-- ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAddRef: out of memory\n");
-- return(NULL);
-- }
--
-- /*
-- * fill the structure.
-- */
-- ret->value = xmlStrdup(value);
-- ret->attr = attr;
--
-- /*
-- * !!! Should we keep track of all refs ? and use xmlHashAddEntry2 ?
-- */
-- if (xmlHashAddEntry(table, value, ret) < 0) {
-- /*
-- * Since there is no discrimination on error returns
-- * from xmlHashAddEntry, I'm presuming <0 means the
-- * key already exists.
-- */
-- xmlHashUpdateEntry(table, value, ret, (xmlHashDeallocator) xmlFreeRef);
-- }
-- return(ret);
--}
--
--/**
-- * xmlFreeRefTable:
-- * @table: An ref table
-- *
-- * Deallocate the memory used by an Ref hash table.
-- */
--void
--xmlFreeRefTable(xmlRefTablePtr table) {
-- xmlHashFree(table, (xmlHashDeallocator) xmlFreeRef);
--}
--
--/**
-- * xmlIsRef:
-- * @doc: the document
-- * @elem: the element carrying the attribute
-- * @attr: the attribute
-- *
-- * Determine whether an attribute is of type Ref. In case we have Dtd(s)
-- * then this is simple, otherwise we use an heuristic: name Ref (upper
-- * or lowercase).
-- *
-- * Returns 0 or 1 depending on the lookup result
-- */
--int
--xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
-- if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
-- return(0);
-- } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
-- /* TODO @@@ */
-- return(0);
-- } else {
-- xmlAttributePtr attrDecl;
--
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name,
-- attr->name);
--
-- if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_IDREF))
-- return(1);
-- }
-- return(0);
--}
--
--/**
-- * xmlRemoveRef
-- * @doc: the document
-- * @attr: the attribute
-- *
-- * Remove the given attribute from the Ref table maintained internally.
-- *
-- * Returns -1 if the lookup failed and 0 otherwise
-- */
--int
--xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
-- xmlAttrPtr cur;
-- xmlRefTablePtr table;
-- xmlChar *ID;
--
-- if (doc == NULL) return(-1);
-- if (attr == NULL) return(-1);
-- table = (xmlRefTablePtr) doc->refs;
-- if (table == NULL)
-- return(-1);
--
-- if (attr == NULL)
-- return(-1);
-- ID = xmlNodeListGetString(doc, attr->children, 1);
-- if (ID == NULL)
-- return(-1);
-- cur = xmlHashLookup(table, ID);
-- if (cur != attr) {
-- xmlFree(ID);
-- return(-1);
-- }
-- xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeRef);
-- xmlFree(ID);
-- return(0);
--}
--
--/**
-- * xmlGetRef:
-- * @doc: pointer to the document
-- * @Ref: the Ref value
-- *
-- * Search the next attribute declaring the given Ref
-- *
-- * Returns NULL if not found, otherwise the xmlAttrPtr defining the Ref
-- */
--xmlAttrPtr
--xmlGetRef(xmlDocPtr doc, const xmlChar *Ref) {
-- xmlRefTablePtr table;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "xmlGetRef: doc == NULL\n");
-- return(NULL);
-- }
--
-- if (Ref == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "xmlGetRef: Ref == NULL\n");
-- return(NULL);
-- }
--
-- table = (xmlRefTablePtr) doc->refs;
-- if (table == NULL)
-- return(NULL);
--
-- return(xmlHashLookup(table, Ref));
--}
--
--/************************************************************************
-- * *
-- * Routines for validity checking *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlGetDtdElementDesc:
-- * @dtd: a pointer to the DtD to search
-- * @name: the element name
-- *
-- * Search the Dtd for the description of this element
-- *
-- * returns the xmlElementPtr if found or NULL
-- */
--
--xmlElementPtr
--xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
-- xmlElementTablePtr table;
-- xmlElementPtr cur;
-- xmlChar *uqname = NULL, *prefix = NULL;
--
-- if (dtd == NULL) return(NULL);
-- if (dtd->elements == NULL) return(NULL);
-- table = (xmlElementTablePtr) dtd->elements;
--
-- uqname = xmlSplitQName2(name, &prefix);
-- if (uqname != NULL) {
-- cur = xmlHashLookup2(table, uqname, prefix);
-- if (prefix != NULL) xmlFree(prefix);
-- if (uqname != NULL) xmlFree(uqname);
-- } else
-- cur = xmlHashLookup2(table, name, NULL);
-- return(cur);
--}
--
--/**
-- * xmlGetDtdQElementDesc:
-- * @dtd: a pointer to the DtD to search
-- * @name: the element name
-- * @prefix: the element namespace prefix
-- *
-- * Search the Dtd for the description of this element
-- *
-- * returns the xmlElementPtr if found or NULL
-- */
--
--xmlElementPtr
--xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
-- const xmlChar *prefix) {
-- xmlElementTablePtr table;
--
-- if (dtd == NULL) return(NULL);
-- if (dtd->elements == NULL) return(NULL);
-- table = (xmlElementTablePtr) dtd->elements;
--
-- return(xmlHashLookup2(table, name, prefix));
--}
--
--/**
-- * xmlGetDtdAttrDesc:
-- * @dtd: a pointer to the DtD to search
-- * @elem: the element name
-- * @name: the attribute name
-- *
-- * Search the Dtd for the description of this attribute on
-- * this element.
-- *
-- * returns the xmlAttributePtr if found or NULL
-- */
--
--xmlAttributePtr
--xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
-- xmlAttributeTablePtr table;
-- xmlAttributePtr cur;
-- xmlChar *uqname = NULL, *prefix = NULL;
--
-- if (dtd == NULL) return(NULL);
-- if (dtd->attributes == NULL) return(NULL);
--
-- table = (xmlAttributeTablePtr) dtd->attributes;
-- if (table == NULL)
-- return(NULL);
--
-- uqname = xmlSplitQName2(name, &prefix);
--
-- if (uqname != NULL) {
-- cur = xmlHashLookup3(table, uqname, prefix, elem);
-- if (prefix != NULL) xmlFree(prefix);
-- if (uqname != NULL) xmlFree(uqname);
-- } else
-- cur = xmlHashLookup3(table, name, NULL, elem);
-- return(cur);
--}
--
--/**
-- * xmlGetDtdQAttrDesc:
-- * @dtd: a pointer to the DtD to search
-- * @elem: the element name
-- * @name: the attribute name
-- * @prefix: the attribute namespace prefix
-- *
-- * Search the Dtd for the description of this qualified attribute on
-- * this element.
-- *
-- * returns the xmlAttributePtr if found or NULL
-- */
--
--xmlAttributePtr
--xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
-- const xmlChar *prefix) {
-- xmlAttributeTablePtr table;
--
-- if (dtd == NULL) return(NULL);
-- if (dtd->attributes == NULL) return(NULL);
-- table = (xmlAttributeTablePtr) dtd->attributes;
--
-- return(xmlHashLookup3(table, name, prefix, elem));
--}
--
--/**
-- * xmlGetDtdNotationDesc:
-- * @dtd: a pointer to the DtD to search
-- * @name: the notation name
-- *
-- * Search the Dtd for the description of this notation
-- *
-- * returns the xmlNotationPtr if found or NULL
-- */
--
--xmlNotationPtr
--xmlGetDtdNotationDesc(xmlDtdPtr dtd, const xmlChar *name) {
-- xmlNotationTablePtr table;
--
-- if (dtd == NULL) return(NULL);
-- if (dtd->notations == NULL) return(NULL);
-- table = (xmlNotationTablePtr) dtd->notations;
--
-- return(xmlHashLookup(table, name));
--}
--
--/**
-- * xmlValidateNotationUse:
-- * @ctxt: the validation context
-- * @doc: the document
-- * @notationName: the notation name to check
-- *
-- * Validate that the given mame match a notation declaration.
-- * - [ VC: Notation Declared ]
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- const xmlChar *notationName) {
-- xmlNotationPtr notaDecl;
-- if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
--
-- notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
-- if ((notaDecl == NULL) && (doc->extSubset != NULL))
-- notaDecl = xmlGetDtdNotationDesc(doc->extSubset, notationName);
--
-- if (notaDecl == NULL) {
-- VERROR(ctxt->userData, "NOTATION %s is not declared\n",
-- notationName);
-- return(0);
-- }
-- return(1);
--}
--
--/**
-- * xmlIsMixedElement
-- * @doc: the document
-- * @name: the element name
-- *
-- * Search in the DtDs whether an element accept Mixed content (or ANY)
-- * basically if it is supposed to accept text childs
-- *
-- * returns 0 if no, 1 if yes, and -1 if no element description is available
-- */
--
--int
--xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
-- xmlElementPtr elemDecl;
--
-- if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
--
-- elemDecl = xmlGetDtdElementDesc(doc->intSubset, name);
-- if ((elemDecl == NULL) && (doc->extSubset != NULL))
-- elemDecl = xmlGetDtdElementDesc(doc->extSubset, name);
-- if (elemDecl == NULL) return(-1);
-- switch (elemDecl->etype) {
-- case XML_ELEMENT_TYPE_ELEMENT:
-- return(0);
-- case XML_ELEMENT_TYPE_EMPTY:
-- /*
-- * return 1 for EMPTY since we want VC error to pop up
-- * on <empty> </empty> for example
-- */
-- case XML_ELEMENT_TYPE_ANY:
-- case XML_ELEMENT_TYPE_MIXED:
-- return(1);
-- }
-- return(1);
--}
--
--/**
-- * xmlValidateNameValue:
-- * @value: an Name value
-- *
-- * Validate that the given value match Name production
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateNameValue(const xmlChar *value) {
-- const xmlChar *cur;
--
-- if (value == NULL) return(0);
-- cur = value;
--
-- if (!IS_LETTER(*cur) && (*cur != '_') &&
-- (*cur != ':')) {
-- return(0);
-- }
--
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
--
-- if (*cur != 0) return(0);
--
-- return(1);
--}
--
--/**
-- * xmlValidateNamesValue:
-- * @value: an Names value
-- *
-- * Validate that the given value match Names production
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateNamesValue(const xmlChar *value) {
-- const xmlChar *cur;
--
-- if (value == NULL) return(0);
-- cur = value;
--
-- if (!IS_LETTER(*cur) && (*cur != '_') &&
-- (*cur != ':')) {
-- return(0);
-- }
--
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
--
-- while (IS_BLANK(*cur)) {
-- while (IS_BLANK(*cur)) cur++;
--
-- if (!IS_LETTER(*cur) && (*cur != '_') &&
-- (*cur != ':')) {
-- return(0);
-- }
--
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
-- }
--
-- if (*cur != 0) return(0);
--
-- return(1);
--}
--
--/**
-- * xmlValidateNmtokenValue:
-- * @value: an Mntoken value
-- *
-- * Validate that the given value match Nmtoken production
-- *
-- * [ VC: Name Token ]
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateNmtokenValue(const xmlChar *value) {
-- const xmlChar *cur;
--
-- if (value == NULL) return(0);
-- cur = value;
--
-- if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
-- (*cur != '.') && (*cur != '-') &&
-- (*cur != '_') && (*cur != ':') &&
-- (!IS_COMBINING(*cur)) &&
-- (!IS_EXTENDER(*cur)))
-- return(0);
--
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
--
-- if (*cur != 0) return(0);
--
-- return(1);
--}
--
--/**
-- * xmlValidateNmtokensValue:
-- * @value: an Mntokens value
-- *
-- * Validate that the given value match Nmtokens production
-- *
-- * [ VC: Name Token ]
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateNmtokensValue(const xmlChar *value) {
-- const xmlChar *cur;
--
-- if (value == NULL) return(0);
-- cur = value;
--
-- while (IS_BLANK(*cur)) cur++;
-- if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
-- (*cur != '.') && (*cur != '-') &&
-- (*cur != '_') && (*cur != ':') &&
-- (!IS_COMBINING(*cur)) &&
-- (!IS_EXTENDER(*cur)))
-- return(0);
--
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
--
-- while (IS_BLANK(*cur)) {
-- while (IS_BLANK(*cur)) cur++;
-- if (*cur == 0) return(1);
--
-- if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
-- (*cur != '.') && (*cur != '-') &&
-- (*cur != '_') && (*cur != ':') &&
-- (!IS_COMBINING(*cur)) &&
-- (!IS_EXTENDER(*cur)))
-- return(0);
--
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
-- }
--
-- if (*cur != 0) return(0);
--
-- return(1);
--}
--
--/**
-- * xmlValidateNotationDecl:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @nota: a notation definition
-- *
-- * Try to validate a single notation definition
-- * basically it does the following checks as described by the
-- * XML-1.0 recommendation:
-- * - it seems that no validity constraing exist on notation declarations
-- * But this function get called anyway ...
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateNotationDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- xmlNotationPtr nota) {
-- int ret = 1;
--
-- return(ret);
--}
--
--/**
-- * xmlValidateAttributeValue:
-- * @type: an attribute type
-- * @value: an attribute value
-- *
-- * Validate that the given attribute value match the proper production
-- *
-- * [ VC: ID ]
-- * Values of type ID must match the Name production....
-- *
-- * [ VC: IDREF ]
-- * Values of type IDREF must match the Name production, and values
-- * of type IDREFS must match Names ...
-- *
-- * [ VC: Entity Name ]
-- * Values of type ENTITY must match the Name production, values
-- * of type ENTITIES must match Names ...
-- *
-- * [ VC: Name Token ]
-- * Values of type NMTOKEN must match the Nmtoken production; values
-- * of type NMTOKENS must match Nmtokens.
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) {
-- switch (type) {
-- case XML_ATTRIBUTE_ENTITIES:
-- case XML_ATTRIBUTE_IDREFS:
-- return(xmlValidateNamesValue(value));
-- case XML_ATTRIBUTE_ENTITY:
-- case XML_ATTRIBUTE_IDREF:
-- case XML_ATTRIBUTE_ID:
-- case XML_ATTRIBUTE_NOTATION:
-- return(xmlValidateNameValue(value));
-- case XML_ATTRIBUTE_NMTOKENS:
-- case XML_ATTRIBUTE_ENUMERATION:
-- return(xmlValidateNmtokensValue(value));
-- case XML_ATTRIBUTE_NMTOKEN:
-- return(xmlValidateNmtokenValue(value));
-- case XML_ATTRIBUTE_CDATA:
-- break;
-- }
-- return(1);
--}
--
--/**
-- * xmlValidateAttributeValue2:
-- * @ctxt: the validation context
-- * @doc: the document
-- * @name: the attribute name (used for error reporting only)
-- * @type: the attribute type
-- * @value: the attribute value
-- *
-- * Validate that the given attribute value match a given type.
-- * This typically cannot be done before having finished parsing
-- * the subsets.
-- *
-- * [ VC: IDREF ]
-- * Values of type IDREF must match one of the declared IDs
-- * Values of type IDREFS must match a sequence of the declared IDs
-- * each Name must match the value of an ID attribute on some element
-- * in the XML document; i.e. IDREF values must match the value of
-- * some ID attribute
-- *
-- * [ VC: Entity Name ]
-- * Values of type ENTITY must match one declared entity
-- * Values of type ENTITIES must match a sequence of declared entities
-- *
-- * [ VC: Notation Attributes ]
-- * all notation names in the declaration must be declared.
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- const xmlChar *name, xmlAttributeType type, const xmlChar *value) {
-- int ret = 1;
-- switch (type) {
-- case XML_ATTRIBUTE_IDREFS:
-- case XML_ATTRIBUTE_IDREF:
-- case XML_ATTRIBUTE_ID:
-- case XML_ATTRIBUTE_NMTOKENS:
-- case XML_ATTRIBUTE_ENUMERATION:
-- case XML_ATTRIBUTE_NMTOKEN:
-- case XML_ATTRIBUTE_CDATA:
-- break;
-- case XML_ATTRIBUTE_ENTITY: {
-- xmlEntityPtr ent;
--
-- ent = xmlGetDocEntity(doc, value);
-- if (ent == NULL) {
-- VERROR(ctxt->userData,
-- "ENTITY attribute %s reference an unknown entity \"%s\"\n",
-- name, value);
-- ret = 0;
-- } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-- VERROR(ctxt->userData,
-- "ENTITY attribute %s reference an entity \"%s\" of wrong type\n",
-- name, value);
-- ret = 0;
-- }
-- break;
-- }
-- case XML_ATTRIBUTE_ENTITIES: {
-- xmlChar *dup, *nam = NULL, *cur, save;
-- xmlEntityPtr ent;
--
-- dup = xmlStrdup(value);
-- if (dup == NULL)
-- return(0);
-- cur = dup;
-- while (*cur != 0) {
-- nam = cur;
-- while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
-- save = *cur;
-- *cur = 0;
-- ent = xmlGetDocEntity(doc, nam);
-- if (ent == NULL) {
-- VERROR(ctxt->userData,
-- "ENTITIES attribute %s reference an unknown entity \"%s\"\n",
-- name, nam);
-- ret = 0;
-- } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-- VERROR(ctxt->userData,
-- "ENTITIES attribute %s reference an entity \"%s\" of wrong type\n",
-- name, nam);
-- ret = 0;
-- }
-- if (save == 0)
-- break;
-- *cur = save;
-- while (IS_BLANK(*cur)) cur++;
-- }
-- xmlFree(dup);
-- break;
-- }
-- case XML_ATTRIBUTE_NOTATION: {
-- xmlNotationPtr nota;
--
-- nota = xmlGetDtdNotationDesc(doc->intSubset, value);
-- if ((nota == NULL) && (doc->extSubset != NULL))
-- nota = xmlGetDtdNotationDesc(doc->extSubset, value);
--
-- if (nota == NULL) {
-- VERROR(ctxt->userData,
-- "NOTATION attribute %s reference an unknown notation \"%s\"\n",
-- name, value);
-- ret = 0;
-- }
-- break;
-- }
-- }
-- return(ret);
--}
--
--/**
-- * xmlValidNormalizeAttributeValue:
-- * @doc: the document
-- * @elem: the parent
-- * @name: the attribute name
-- * @value: the attribute value
-- *
-- * Does the validation related extra step of the normalization of attribute
-- * values:
-- *
-- * If the declared value is not CDATA, then the XML processor must further
-- * process the normalized attribute value by discarding any leading and
-- * trailing space (#x20) characters, and by replacing sequences of space
-- * (#x20) characters by single space (#x20) character.
-- *
-- * returns a new normalized string if normalization is needed, NULL otherwise
-- * the caller must free the returned value.
-- */
--
--xmlChar *
--xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
-- const xmlChar *name, const xmlChar *value) {
-- xmlChar *ret, *dst;
-- const xmlChar *src;
-- xmlAttributePtr attrDecl = NULL;
--
-- if (doc == NULL) return(NULL);
-- if (elem == NULL) return(NULL);
-- if (name == NULL) return(NULL);
-- if (value == NULL) return(NULL);
--
-- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
-- xmlChar qname[500];
--#ifdef HAVE_SNPRINTF
-- snprintf((char *) qname, sizeof(qname), "%s:%s",
-- elem->ns->prefix, elem->name);
--#else
-- sprintf((char *) qname, "%s:%s", elem->ns->prefix, elem->name);
--#endif
-- qname[sizeof(qname) - 1] = 0;
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name);
-- }
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
--
-- if (attrDecl == NULL)
-- return(NULL);
-- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
-- return(NULL);
--
-- ret = xmlStrdup(value);
-- if (ret == NULL)
-- return(NULL);
-- src = value;
-- dst = ret;
-- while (*src == 0x20) src++;
-- while (*src != 0) {
-- if (*src == 0x20) {
-- while (*src == 0x20) src++;
-- if (*src != 0)
-- *dst++ = 0x20;
-- } else {
-- *dst++ = *src++;
-- }
-- }
-- *dst = 0;
-- return(ret);
--}
--
--void
--xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count,
-- const xmlChar* name) {
-- if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
--}
--
--/**
-- * xmlValidateAttributeDecl:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @attr: an attribute definition
-- *
-- * Try to validate a single attribute definition
-- * basically it does the following checks as described by the
-- * XML-1.0 recommendation:
-- * - [ VC: Attribute Default Legal ]
-- * - [ VC: Enumeration ]
-- * - [ VC: ID Attribute Default ]
-- *
-- * The ID/IDREF uniqueness and matching are done separately
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- xmlAttributePtr attr) {
-- int ret = 1;
-- int val;
-- CHECK_DTD;
-- if(attr == NULL) return(1);
--
-- /* Attribute Default Legal */
-- /* Enumeration */
-- if (attr->defaultValue != NULL) {
-- val = xmlValidateAttributeValue(attr->atype, attr->defaultValue);
-- if (val == 0) {
-- VERROR(ctxt->userData,
-- "Syntax of default value for attribute %s on %s is not valid\n",
-- attr->name, attr->elem);
-- }
-- ret &= val;
-- }
--
-- /* ID Attribute Default */
-- if ((attr->atype == XML_ATTRIBUTE_ID)&&
-- (attr->def != XML_ATTRIBUTE_IMPLIED) &&
-- (attr->def != XML_ATTRIBUTE_REQUIRED)) {
-- VERROR(ctxt->userData,
-- "ID attribute %s on %s is not valid must be #IMPLIED or #REQUIRED\n",
-- attr->name, attr->elem);
-- ret = 0;
-- }
--
-- /* One ID per Element Type */
-- if (attr->atype == XML_ATTRIBUTE_ID) {
-- int nbId;
--
-- /* the trick is taht we parse DtD as their own internal subset */
-- xmlElementPtr elem = xmlGetDtdElementDesc(doc->intSubset,
-- attr->elem);
-- if (elem != NULL) {
-- nbId = xmlScanIDAttributeDecl(NULL, elem);
-- } else {
-- xmlAttributeTablePtr table;
--
-- /*
-- * The attribute may be declared in the internal subset and the
-- * element in the external subset.
-- */
-- nbId = 0;
-- table = (xmlAttributeTablePtr) doc->intSubset->attributes;
-- xmlHashScan3(table, NULL, NULL, attr->elem, (xmlHashScanner)
-- xmlValidateAttributeIdCallback, &nbId);
-- }
-- if (nbId > 1) {
-- VERROR(ctxt->userData,
-- "Element %s has %d ID attribute defined in the internal subset : %s\n",
-- attr->elem, nbId, attr->name);
-- } else if (doc->extSubset != NULL) {
-- int extId = 0;
-- elem = xmlGetDtdElementDesc(doc->extSubset, attr->elem);
-- if (elem != NULL) {
-- extId = xmlScanIDAttributeDecl(NULL, elem);
-- }
-- if (extId > 1) {
-- VERROR(ctxt->userData,
-- "Element %s has %d ID attribute defined in the external subset : %s\n",
-- attr->elem, extId, attr->name);
-- } else if (extId + nbId > 1) {
-- VERROR(ctxt->userData,
--"Element %s has ID attributes defined in the internal and external subset : %s\n",
-- attr->elem, attr->name);
-- }
-- }
-- }
--
-- /* Validity Constraint: Enumeration */
-- if ((attr->defaultValue != NULL) && (attr->tree != NULL)) {
-- xmlEnumerationPtr tree = attr->tree;
-- while (tree != NULL) {
-- if (xmlStrEqual(tree->name, attr->defaultValue)) break;
-- tree = tree->next;
-- }
-- if (tree == NULL) {
-- VERROR(ctxt->userData,
--"Default value \"%s\" for attribute %s on %s is not among the enumerated set\n",
-- attr->defaultValue, attr->name, attr->elem);
-- ret = 0;
-- }
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlValidateElementDecl:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @elem: an element definition
-- *
-- * Try to validate a single element definition
-- * basically it does the following checks as described by the
-- * XML-1.0 recommendation:
-- * - [ VC: One ID per Element Type ]
-- * - [ VC: No Duplicate Types ]
-- * - [ VC: Unique Element Type Declaration ]
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- xmlElementPtr elem) {
-- int ret = 1;
-- xmlElementPtr tst;
--
-- CHECK_DTD;
--
-- if (elem == NULL) return(1);
--
-- /* No Duplicate Types */
-- if (elem->etype == XML_ELEMENT_TYPE_MIXED) {
-- xmlElementContentPtr cur, next;
-- const xmlChar *name;
--
-- cur = elem->content;
-- while (cur != NULL) {
-- if (cur->type != XML_ELEMENT_CONTENT_OR) break;
-- if (cur->c1 == NULL) break;
-- if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
-- name = cur->c1->name;
-- next = cur->c2;
-- while (next != NULL) {
-- if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
-- if (xmlStrEqual(next->name, name)) {
-- VERROR(ctxt->userData,
-- "Definition of %s has duplicate references of %s\n",
-- elem->name, name);
-- ret = 0;
-- }
-- break;
-- }
-- if (next->c1 == NULL) break;
-- if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
-- if (xmlStrEqual(next->c1->name, name)) {
-- VERROR(ctxt->userData,
-- "Definition of %s has duplicate references of %s\n",
-- elem->name, name);
-- ret = 0;
-- }
-- next = next->c2;
-- }
-- }
-- cur = cur->c2;
-- }
-- }
--
-- /* VC: Unique Element Type Declaration */
-- tst = xmlGetDtdElementDesc(doc->intSubset, elem->name);
-- if ((tst != NULL ) && (tst != elem)) {
-- VERROR(ctxt->userData, "Redefinition of element %s\n",
-- elem->name);
-- ret = 0;
-- }
-- tst = xmlGetDtdElementDesc(doc->extSubset, elem->name);
-- if ((tst != NULL ) && (tst != elem)) {
-- VERROR(ctxt->userData, "Redefinition of element %s\n",
-- elem->name);
-- ret = 0;
-- }
--
-- /* One ID per Element Type */
-- if (xmlScanIDAttributeDecl(ctxt, elem) > 1) {
-- ret = 0;
-- }
-- return(ret);
--}
--
--/**
-- * xmlValidateOneAttribute:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @elem: an element instance
-- * @attr: an attribute instance
-- * @value: the attribute value (without entities processing)
-- *
-- * Try to validate a single attribute for an element
-- * basically it does the following checks as described by the
-- * XML-1.0 recommendation:
-- * - [ VC: Attribute Value Type ]
-- * - [ VC: Fixed Attribute Default ]
-- * - [ VC: Entity Name ]
-- * - [ VC: Name Token ]
-- * - [ VC: ID ]
-- * - [ VC: IDREF ]
-- * - [ VC: Entity Name ]
-- * - [ VC: Notation Attributes ]
-- *
-- * The ID/IDREF uniqueness and matching are done separately
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) {
-- /* xmlElementPtr elemDecl; */
-- xmlAttributePtr attrDecl = NULL;
-- int val;
-- int ret = 1;
--
-- CHECK_DTD;
-- if ((elem == NULL) || (elem->name == NULL)) return(0);
-- if ((attr == NULL) || (attr->name == NULL)) return(0);
--
-- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
-- xmlChar qname[500];
--#ifdef HAVE_SNPRINTF
-- snprintf((char *) qname, sizeof(qname), "%s:%s",
-- elem->ns->prefix, elem->name);
--#else
-- sprintf((char *) qname, "%s:%s", elem->ns->prefix, elem->name);
--#endif
-- qname[sizeof(qname) - 1] = 0;
-- if (attr->ns != NULL) {
-- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname,
-- attr->name, attr->ns->prefix);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname,
-- attr->name, attr->ns->prefix);
-- } else {
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attr->name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
-- qname, attr->name);
-- }
-- }
-- if (attrDecl == NULL) {
-- if (attr->ns != NULL) {
-- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
-- attr->name, attr->ns->prefix);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
-- attr->name, attr->ns->prefix);
-- } else {
-- attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
-- elem->name, attr->name);
-- if ((attrDecl == NULL) && (doc->extSubset != NULL))
-- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
-- elem->name, attr->name);
-- }
-- }
--
--
-- /* Validity Constraint: Attribute Value Type */
-- if (attrDecl == NULL) {
-- VERROR(ctxt->userData,
-- "No declaration for attribute %s on element %s\n",
-- attr->name, elem->name);
-- return(0);
-- }
-- attr->atype = attrDecl->atype;
--
-- val = xmlValidateAttributeValue(attrDecl->atype, value);
-- if (val == 0) {
-- VERROR(ctxt->userData,
-- "Syntax of value for attribute %s on %s is not valid\n",
-- attr->name, elem->name);
-- ret = 0;
-- }
--
-- /* Validity constraint: Fixed Attribute Default */
-- if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
-- if (!xmlStrEqual(value, attrDecl->defaultValue)) {
-- VERROR(ctxt->userData,
-- "Value for attribute %s on %s is differnt from default \"%s\"\n",
-- attr->name, elem->name, attrDecl->defaultValue);
-- ret = 0;
-- }
-- }
--
-- /* Validity Constraint: ID uniqueness */
-- if (attrDecl->atype == XML_ATTRIBUTE_ID) {
-- if (xmlAddID(ctxt, doc, value, attr) == NULL)
-- ret = 0;
-- }
--
-- if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
-- (attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
-- if (xmlAddRef(ctxt, doc, value, attr) == NULL)
-- ret = 0;
-- }
--
-- /* Validity Constraint: Notation Attributes */
-- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
-- xmlEnumerationPtr tree = attrDecl->tree;
-- xmlNotationPtr nota;
--
-- /* First check that the given NOTATION was declared */
-- nota = xmlGetDtdNotationDesc(doc->intSubset, value);
-- if (nota == NULL)
-- nota = xmlGetDtdNotationDesc(doc->extSubset, value);
--
-- if (nota == NULL) {
-- VERROR(ctxt->userData,
-- "Value \"%s\" for attribute %s on %s is not a declared Notation\n",
-- value, attr->name, elem->name);
-- ret = 0;
-- }
--
-- /* Second, verify that it's among the list */
-- while (tree != NULL) {
-- if (xmlStrEqual(tree->name, value)) break;
-- tree = tree->next;
-- }
-- if (tree == NULL) {
-- VERROR(ctxt->userData,
--"Value \"%s\" for attribute %s on %s is not among the enumerated notations\n",
-- value, attr->name, elem->name);
-- ret = 0;
-- }
-- }
--
-- /* Validity Constraint: Enumeration */
-- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
-- xmlEnumerationPtr tree = attrDecl->tree;
-- while (tree != NULL) {
-- if (xmlStrEqual(tree->name, value)) break;
-- tree = tree->next;
-- }
-- if (tree == NULL) {
-- VERROR(ctxt->userData,
-- "Value \"%s\" for attribute %s on %s is not among the enumerated set\n",
-- value, attr->name, elem->name);
-- ret = 0;
-- }
-- }
--
-- /* Fixed Attribute Default */
-- if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
-- (!xmlStrEqual(attrDecl->defaultValue, value))) {
-- VERROR(ctxt->userData,
-- "Value for attribute %s on %s must be \"%s\"\n",
-- attr->name, elem->name, attrDecl->defaultValue);
-- ret = 0;
-- }
--
-- /* Extra check for the attribute value */
-- ret &= xmlValidateAttributeValue2(ctxt, doc, attr->name,
-- attrDecl->atype, value);
--
-- return(ret);
--}
--
--/* Find the next XML_ELEMENT_NODE, subject to the content constraints.
-- * Return -1 if we found something unexpected, or 1 otherwise.
-- */
--
--static int
--xmlValidateFindNextElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-- xmlElementContentPtr cont)
--{
-- while (*child && (*child)->type != XML_ELEMENT_NODE) {
-- switch ((*child)->type) {
-- /*
-- * If there is an entity declared and it's not empty
-- * Push the current node on the stack and process with the
-- * entity content.
-- */
-- case XML_ENTITY_REF_NODE:
-- if (((*child)->children != NULL) &&
-- ((*child)->children->children != NULL)) {
-- nodeVPush(ctxt, *child);
-- *child = (*child)->children->children;
-- continue;
-- }
-- break;
--
-- /* These things are ignored (skipped) during validation. */
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- break;
--
-- case XML_TEXT_NODE:
-- if (xmlIsBlankNode(*child)
-- && (cont->type == XML_ELEMENT_CONTENT_ELEMENT
-- || cont->type == XML_ELEMENT_CONTENT_SEQ
-- || cont->type == XML_ELEMENT_CONTENT_OR))
-- break;
-- return -1;
--
-- default:
-- return -1;
-- }
-- *child = (*child)->next;
-- }
--
-- return 1;
--}
--
--int xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-- xmlElementContentPtr cont);
--
--/**
-- * xmlValidateElementTypeExpr:
-- * @ctxt: the validation context
-- * @child: pointer to the child list
-- * @cont: pointer to the content declaration
-- *
-- * Try to validate the content of an element of type element
-- * but don't handle the occurence factor
-- *
-- * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
-- * also update child value in-situ.
-- */
--
--int
--xmlValidateElementTypeExpr(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-- xmlElementContentPtr cont) {
-- xmlNodePtr cur;
-- int ret = 1;
--
-- if (cont == NULL) return(-1);
-- DEBUG_VALID_STATE(*child, cont)
-- ret = xmlValidateFindNextElement(ctxt, child, cont);
-- if (ret < 0)
-- return(-1);
-- DEBUG_VALID_STATE(*child, cont)
-- switch (cont->type) {
-- case XML_ELEMENT_CONTENT_PCDATA:
-- if (*child == NULL) return(0);
-- if ((*child)->type == XML_TEXT_NODE) return(1);
-- return(0);
-- case XML_ELEMENT_CONTENT_ELEMENT:
-- if (*child == NULL) return(0);
-- ret = (xmlStrEqual((*child)->name, cont->name));
-- if (ret == 1) {
-- while ((*child)->next == NULL) {
-- if (((*child)->parent != NULL) &&
-- ((*child)->parent->type == XML_ENTITY_DECL)) {
-- *child = nodeVPop(ctxt);
-- } else
-- break;
-- }
-- *child = (*child)->next;
-- }
-- return(ret);
-- case XML_ELEMENT_CONTENT_OR:
-- cur = *child;
-- ret = xmlValidateElementTypeElement(ctxt, child, cont->c1);
-- if (ret == -1) return(-1);
-- if (ret == 1) {
-- return(1);
-- }
-- /* rollback and retry the other path */
-- *child = cur;
-- ret = xmlValidateElementTypeElement(ctxt, child, cont->c2);
-- if (ret == -1) return(-1);
-- if (ret == 0) {
-- *child = cur;
-- return(0);
-- }
-- return(1);
-- case XML_ELEMENT_CONTENT_SEQ:
-- cur = *child;
-- ret = xmlValidateElementTypeElement(ctxt, child, cont->c1);
-- if (ret == -1) return(-1);
-- if (ret == 0) {
-- *child = cur;
-- return(0);
-- }
-- ret = xmlValidateElementTypeElement(ctxt, child, cont->c2);
-- if (ret == -1) return(-1);
-- if (ret == 0) {
-- *child = cur;
-- return(0);
-- }
-- return(1);
-- }
-- return(ret);
--}
--
--/**
-- * xmlValidateElementTypeElement:
-- * @ctxt: the validation context
-- * @child: pointer to the child list
-- * @cont: pointer to the content declaration
-- *
-- * Try to validate the content of an element of type element
-- * yeah, Yet Another Regexp Implementation, and recursive
-- *
-- * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
-- * also update child and content values in-situ.
-- */
--
--int
--xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
-- xmlElementContentPtr cont) {
-- xmlNodePtr cur;
-- int ret;
--
-- if (cont == NULL) return(-1);
--
-- DEBUG_VALID_STATE(*child, cont)
-- ret = xmlValidateFindNextElement(ctxt, child, cont);
-- if (ret < 0)
-- return(-1);
-- DEBUG_VALID_STATE(*child, cont)
-- cur = *child;
-- ret = xmlValidateElementTypeExpr(ctxt, child, cont);
-- if (ret == -1) return(-1);
-- switch (cont->ocur) {
-- case XML_ELEMENT_CONTENT_ONCE:
-- if (ret == 1) {
-- /* skip ignorable elems */
-- while ((*child != NULL) &&
-- ((*child)->type == XML_PI_NODE
-- || (*child)->type == XML_COMMENT_NODE
-- || (*child)->type == XML_XINCLUDE_START
-- || (*child)->type == XML_XINCLUDE_END)) {
-- while ((*child)->next == NULL) {
-- if (((*child)->parent != NULL) &&
-- ((*child)->parent->type == XML_ENTITY_REF_NODE)) {
-- *child = (*child)->parent;
-- } else
-- break;
-- }
-- *child = (*child)->next;
-- }
-- return(1);
-- }
-- *child = cur;
-- return(0);
-- case XML_ELEMENT_CONTENT_OPT:
-- if (ret == 0) {
-- *child = cur;
-- return(1);
-- }
-- break;
-- case XML_ELEMENT_CONTENT_MULT:
-- if (ret == 0) {
-- *child = cur;
-- break;
-- }
-- /* no break on purpose */
-- case XML_ELEMENT_CONTENT_PLUS:
-- if (ret == 0) {
-- *child = cur;
-- return(0);
-- }
-- if (ret == -1) return(-1);
-- cur = *child;
-- do {
-- if (*child == NULL)
-- break; /* while */
-- if ((*child)->type == XML_TEXT_NODE
-- && xmlIsBlankNode(*child)) {
-- *child = (*child)->next;
-- continue;
-- }
-- ret = xmlValidateElementTypeExpr(ctxt, child, cont);
-- if (ret == 1)
-- cur = *child;
-- } while (ret == 1);
-- if (ret == -1) return(-1);
-- *child = cur;
-- break;
-- }
--
-- return xmlValidateFindNextElement(ctxt, child, cont);
--}
--
--/**
-- * xmlSprintfElementChilds:
-- * @buf: an output buffer
-- * @content: An element
-- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
-- *
-- * This will dump the list of childs to the buffer
-- * Intended just for the debug routine
-- */
--void
--xmlSprintfElementChilds(char *buf, xmlNodePtr node, int glob) {
-- xmlNodePtr cur;
--
-- if (node == NULL) return;
-- if (glob) strcat(buf, "(");
-- cur = node->children;
-- while (cur != NULL) {
-- switch (cur->type) {
-- case XML_ELEMENT_NODE:
-- strcat(buf, (char *) cur->name);
-- if (cur->next != NULL)
-- strcat(buf, " ");
-- break;
-- case XML_TEXT_NODE:
-- if (xmlIsBlankNode(cur))
-- break;
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- strcat(buf, "CDATA");
-- if (cur->next != NULL)
-- strcat(buf, " ");
-- break;
-- case XML_ATTRIBUTE_NODE:
-- case XML_DOCUMENT_NODE:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_NOTATION_NODE:
-- case XML_NAMESPACE_DECL:
-- strcat(buf, "???");
-- if (cur->next != NULL)
-- strcat(buf, " ");
-- break;
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_DTD_NODE:
-- case XML_COMMENT_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- break;
-- }
-- cur = cur->next;
-- }
-- if (glob) strcat(buf, ")");
--}
--
--
--/**
-- * xmlValidateOneElement:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @elem: an element instance
-- *
-- * Try to validate a single element and it's attributes,
-- * basically it does the following checks as described by the
-- * XML-1.0 recommendation:
-- * - [ VC: Element Valid ]
-- * - [ VC: Required Attribute ]
-- * Then call xmlValidateOneAttribute() for each attribute present.
-- *
-- * The ID/IDREF checkings are done separately
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-- xmlNodePtr elem) {
-- xmlElementPtr elemDecl = NULL;
-- xmlElementContentPtr cont;
-- xmlAttributePtr attr;
-- xmlNodePtr child;
-- int ret = 1;
-- const xmlChar *name;
--
-- CHECK_DTD;
--
-- if (elem == NULL) return(0);
-- if (elem->type == XML_TEXT_NODE) {
-- }
-- switch (elem->type) {
-- case XML_ATTRIBUTE_NODE:
-- VERROR(ctxt->userData,
-- "Attribute element not expected here\n");
-- return(0);
-- case XML_TEXT_NODE:
-- if (elem->children != NULL) {
-- VERROR(ctxt->userData, "Text element has childs !\n");
-- return(0);
-- }
-- if (elem->properties != NULL) {
-- VERROR(ctxt->userData, "Text element has attributes !\n");
-- return(0);
-- }
-- if (elem->ns != NULL) {
-- VERROR(ctxt->userData, "Text element has namespace !\n");
-- return(0);
-- }
-- if (elem->nsDef != NULL) {
-- VERROR(ctxt->userData,
-- "Text element carries namespace definitions !\n");
-- return(0);
-- }
-- if (elem->content == NULL) {
-- VERROR(ctxt->userData,
-- "Text element has no content !\n");
-- return(0);
-- }
-- return(1);
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- return(1);
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- return(1);
-- case XML_ENTITY_NODE:
-- VERROR(ctxt->userData,
-- "Entity element not expected here\n");
-- return(0);
-- case XML_NOTATION_NODE:
-- VERROR(ctxt->userData,
-- "Notation element not expected here\n");
-- return(0);
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- VERROR(ctxt->userData,
-- "Document element not expected here\n");
-- return(0);
-- case XML_HTML_DOCUMENT_NODE:
-- VERROR(ctxt->userData,
-- "\n");
-- return(0);
-- case XML_ELEMENT_NODE:
-- break;
-- default:
-- VERROR(ctxt->userData,
-- "unknown element type %d\n", elem->type);
-- return(0);
-- }
-- if (elem->name == NULL) return(0);
--
-- /*
-- * Fetch the declaration for the qualified name
-- */
-- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
-- elemDecl = xmlGetDtdQElementDesc(doc->intSubset,
-- elem->name, elem->ns->prefix);
-- if ((elemDecl == NULL) && (doc->extSubset != NULL))
-- elemDecl = xmlGetDtdQElementDesc(doc->extSubset,
-- elem->name, elem->ns->prefix);
-- }
--
-- /*
-- * Fetch the declaration for the non qualified name
-- */
-- if (elemDecl == NULL) {
-- elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
-- if ((elemDecl == NULL) && (doc->extSubset != NULL))
-- elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
-- }
-- if (elemDecl == NULL) {
-- VERROR(ctxt->userData, "No declaration for element %s\n",
-- elem->name);
-- return(0);
-- }
--
-- /* Check taht the element content matches the definition */
-- switch (elemDecl->etype) {
-- case XML_ELEMENT_TYPE_EMPTY:
-- if (elem->children != NULL) {
-- VERROR(ctxt->userData,
-- "Element %s was declared EMPTY this one has content\n",
-- elem->name);
-- ret = 0;
-- }
-- break;
-- case XML_ELEMENT_TYPE_ANY:
-- /* I don't think anything is required then */
-- break;
-- case XML_ELEMENT_TYPE_MIXED:
-- /* Hum, this start to get messy */
-- child = elem->children;
-- while (child != NULL) {
-- if (child->type == XML_ELEMENT_NODE) {
-- name = child->name;
-- if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
-- xmlChar qname[500];
--#ifdef HAVE_SNPRINTF
-- snprintf((char *) qname, sizeof(qname), "%s:%s",
-- child->ns->prefix, child->name);
--#else
-- sprintf((char *) qname, "%s:%s",
-- child->ns->prefix, child->name);
--#endif
-- qname[sizeof(qname) - 1] = 0;
-- cont = elemDecl->content;
-- while (cont != NULL) {
-- if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
-- if (xmlStrEqual(cont->name, qname)) break;
-- } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
-- (cont->c1 != NULL) &&
-- (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
-- if (xmlStrEqual(cont->c1->name, qname)) break;
-- } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
-- (cont->c1 == NULL) ||
-- (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
-- /* Internal error !!! */
-- xmlGenericError(xmlGenericErrorContext,
-- "Internal: MIXED struct bad\n");
-- break;
-- }
-- cont = cont->c2;
-- }
-- if (cont != NULL)
-- goto child_ok;
-- }
-- cont = elemDecl->content;
-- while (cont != NULL) {
-- if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
-- if (xmlStrEqual(cont->name, name)) break;
-- } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
-- (cont->c1 != NULL) &&
-- (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)) {
-- if (xmlStrEqual(cont->c1->name, name)) break;
-- } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
-- (cont->c1 == NULL) ||
-- (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)) {
-- /* Internal error !!! */
-- xmlGenericError(xmlGenericErrorContext,
-- "Internal: MIXED struct bad\n");
-- break;
-- }
-- cont = cont->c2;
-- }
-- if (cont == NULL) {
-- VERROR(ctxt->userData,
-- "Element %s is not declared in %s list of possible childs\n",
-- name, elem->name);
-- ret = 0;
-- }
-- }
--child_ok:
-- child = child->next;
-- }
-- break;
-- case XML_ELEMENT_TYPE_ELEMENT:
-- child = elem->children;
-- cont = elemDecl->content;
-- ret = xmlValidateElementTypeElement(ctxt, &child, cont);
-- while ((child != NULL) && (child->type == XML_TEXT_NODE) &&
-- (xmlIsBlankNode(child))) {
-- child = child->next;
-- continue;
-- }
-- if ((ret == 0) || (child != NULL)) {
-- char expr[1000];
-- char list[2000];
--
-- expr[0] = 0;
-- xmlSprintfElementContent(expr, cont, 1);
-- list[0] = 0;
-- xmlSprintfElementChilds(list, elem, 1);
--
-- VERROR(ctxt->userData,
-- "Element %s content doesn't follow the Dtd\nExpecting %s, got %s\n",
-- elem->name, expr, list);
-- ret = 0;
-- }
-- break;
-- }
--
-- /* [ VC: Required Attribute ] */
-- attr = elemDecl->attributes;
-- while (attr != NULL) {
-- if (attr->def == XML_ATTRIBUTE_REQUIRED) {
-- xmlAttrPtr attrib;
-- int qualified = -1;
--
-- attrib = elem->properties;
-- while (attrib != NULL) {
-- if (xmlStrEqual(attrib->name, attr->name)) {
-- if (attr->prefix != NULL) {
-- xmlNsPtr nameSpace = attrib->ns;
--
-- if (nameSpace == NULL)
-- nameSpace = elem->ns;
-- /*
-- * qualified names handling is problematic, having a
-- * different prefix should be possible but DTDs don't
-- * allow to define the URI instead of the prefix :-(
-- */
-- if (nameSpace == NULL) {
-- if (qualified < 0)
-- qualified = 0;
-- } else if (!xmlStrEqual(nameSpace->prefix, attr->prefix)) {
-- if (qualified < 1)
-- qualified = 1;
-- } else
-- goto found;
-- } else {
-- /*
-- * We should allow applications to define namespaces
-- * for their application even if the DTD doesn't
-- * carry one, otherwise, basically we would always
-- * break.
-- */
-- goto found;
-- }
-- }
-- attrib = attrib->next;
-- }
-- if (qualified == -1) {
-- if (attr->prefix == NULL) {
-- VERROR(ctxt->userData,
-- "Element %s doesn't carry attribute %s\n",
-- elem->name, attr->name);
-- ret = 0;
-- } else {
-- VERROR(ctxt->userData,
-- "Element %s doesn't carry attribute %s:%s\n",
-- elem->name, attr->prefix,attr->name);
-- ret = 0;
-- }
-- } else if (qualified == 0) {
-- VWARNING(ctxt->userData,
-- "Element %s required attribute %s:%s has no prefix\n",
-- elem->name, attr->prefix,attr->name);
-- } else if (qualified == 1) {
-- VWARNING(ctxt->userData,
-- "Element %s required attribute %s:%s has different prefix\n",
-- elem->name, attr->prefix,attr->name);
-- }
-- }
--found:
-- attr = attr->nexth;
-- }
-- return(ret);
--}
--
--/**
-- * xmlValidateRoot:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- *
-- * Try to validate a the root element
-- * basically it does the following check as described by the
-- * XML-1.0 recommendation:
-- * - [ VC: Root Element Type ]
-- * it doesn't try to recurse or apply other check to the element
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-- xmlNodePtr root;
-- if (doc == NULL) return(0);
--
-- root = xmlDocGetRootElement(doc);
-- if ((root == NULL) || (root->name == NULL)) {
-- VERROR(ctxt->userData, "Not valid: no root element\n");
-- return(0);
-- }
--
-- /*
-- * When doing post validation against a separate DTD, those may
-- * no internal subset has been generated
-- */
-- if ((doc->intSubset != NULL) &&
-- (doc->intSubset->name != NULL)) {
-- /*
-- * Check first the document root against the NQName
-- */
-- if (!xmlStrEqual(doc->intSubset->name, root->name)) {
-- if ((root->ns != NULL) && (root->ns->prefix != NULL)) {
-- xmlChar qname[500];
--#ifdef HAVE_SNPRINTF
-- snprintf((char *) qname, sizeof(qname), "%s:%s",
-- root->ns->prefix, root->name);
--#else
-- sprintf((char *) qname, "%s:%s", root->ns->prefix, root->name);
--#endif
-- qname[sizeof(qname) - 1] = 0;
-- if (xmlStrEqual(doc->intSubset->name, qname))
-- goto name_ok;
-- }
-- if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) &&
-- (xmlStrEqual(root->name, BAD_CAST "html")))
-- goto name_ok;
-- VERROR(ctxt->userData,
-- "Not valid: root and DtD name do not match '%s' and '%s'\n",
-- root->name, doc->intSubset->name);
-- return(0);
--
-- }
-- }
--name_ok:
-- return(1);
--}
--
--
--/**
-- * xmlValidateElement:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @elem: an element instance
-- *
-- * Try to validate the subtree under an element
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
-- xmlNodePtr child;
-- xmlAttrPtr attr;
-- xmlChar *value;
-- int ret = 1;
--
-- if (elem == NULL) return(0);
--
-- /*
-- * XInclude elements were added after parsing in the infoset,
-- * they don't really mean anything validation wise.
-- */
-- if ((elem->type == XML_XINCLUDE_START) ||
-- (elem->type == XML_XINCLUDE_END))
-- return(1);
--
-- CHECK_DTD;
--
-- ret &= xmlValidateOneElement(ctxt, doc, elem);
-- attr = elem->properties;
-- while(attr != NULL) {
-- value = xmlNodeListGetString(doc, attr->children, 0);
-- ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
-- if (value != NULL)
-- xmlFree(value);
-- attr= attr->next;
-- }
-- child = elem->children;
-- while (child != NULL) {
-- ret &= xmlValidateElement(ctxt, doc, child);
-- child = child->next;
-- }
--
-- return(ret);
--}
--
--
--void
--xmlValidateCheckRefCallback(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
-- const xmlChar *name) {
-- xmlAttrPtr id;
-- xmlAttrPtr attr;
--
-- if (ref == NULL)
-- return;
-- attr = ref->attr;
-- if (attr == NULL)
-- return;
-- if (attr->atype == XML_ATTRIBUTE_IDREF) {
-- id = xmlGetID(ctxt->doc, name);
-- if (id == NULL) {
-- VERROR(ctxt->userData,
-- "IDREF attribute %s reference an unknown ID \"%s\"\n",
-- attr->name, name);
-- ctxt->valid = 0;
-- }
-- } else if (attr->atype == XML_ATTRIBUTE_IDREFS) {
-- xmlChar *dup, *str = NULL, *cur, save;
--
-- dup = xmlStrdup(name);
-- if (dup == NULL) {
-- ctxt->valid = 0;
-- return;
-- }
-- cur = dup;
-- while (*cur != 0) {
-- str = cur;
-- while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
-- save = *cur;
-- *cur = 0;
-- id = xmlGetID(ctxt->doc, str);
-- if (id == NULL) {
-- VERROR(ctxt->userData,
-- "IDREFS attribute %s reference an unknown ID \"%s\"\n",
-- attr->name, str);
-- ctxt->valid = 0;
-- }
-- if (save == 0)
-- break;
-- *cur = save;
-- while (IS_BLANK(*cur)) cur++;
-- }
-- xmlFree(dup);
-- }
--}
--
--/**
-- * xmlValidateDocumentFinal:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- *
-- * Does the final step for the document validation once all the
-- * incremental validation steps have been completed
-- *
-- * basically it does the following checks described by the XML Rec
-- *
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-- xmlRefTablePtr table;
--
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlValidateDocumentFinal: doc == NULL\n");
-- return(0);
-- }
--
-- /*
-- * Check all the NOTATION/NOTATIONS attributes
-- */
-- /*
-- * Check all the ENTITY/ENTITIES attributes definition for validity
-- */
-- /*
-- * Check all the IDREF/IDREFS attributes definition for validity
-- */
-- table = (xmlRefTablePtr) doc->refs;
-- ctxt->doc = doc;
-- ctxt->valid = 1;
-- xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
-- return(ctxt->valid);
--}
--
--/**
-- * xmlValidateDtd:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- * @dtd: a dtd instance
-- *
-- * Try to validate the document against the dtd instance
-- *
-- * basically it does check all the definitions in the DtD.
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
-- int ret;
-- xmlDtdPtr oldExt;
-- xmlNodePtr root;
--
-- if (dtd == NULL) return(0);
-- if (doc == NULL) return(0);
-- oldExt = doc->extSubset;
-- doc->extSubset = dtd;
-- ret = xmlValidateRoot(ctxt, doc);
-- if (ret == 0) {
-- doc->extSubset = oldExt;
-- return(ret);
-- }
-- if (doc->ids != NULL) {
-- xmlFreeIDTable(doc->ids);
-- doc->ids = NULL;
-- }
-- if (doc->refs != NULL) {
-- xmlFreeRefTable(doc->refs);
-- doc->refs = NULL;
-- }
-- root = xmlDocGetRootElement(doc);
-- ret = xmlValidateElement(ctxt, doc, root);
-- ret &= xmlValidateDocumentFinal(ctxt, doc);
-- doc->extSubset = oldExt;
-- return(ret);
--}
--
--void
--xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
-- const xmlChar *name) {
-- if (cur == NULL)
-- return;
-- switch (cur->atype) {
-- case XML_ATTRIBUTE_CDATA:
-- case XML_ATTRIBUTE_ID:
-- case XML_ATTRIBUTE_IDREF :
-- case XML_ATTRIBUTE_IDREFS:
-- case XML_ATTRIBUTE_NMTOKEN:
-- case XML_ATTRIBUTE_NMTOKENS:
-- case XML_ATTRIBUTE_ENUMERATION:
-- break;
-- case XML_ATTRIBUTE_ENTITY:
-- case XML_ATTRIBUTE_ENTITIES:
-- case XML_ATTRIBUTE_NOTATION:
-- if (cur->defaultValue != NULL) {
-- ctxt->valid &= xmlValidateAttributeValue2(ctxt, ctxt->doc,
-- cur->name, cur->atype, cur->defaultValue);
-- }
-- if (cur->tree != NULL) {
-- xmlEnumerationPtr tree = cur->tree;
-- while (tree != NULL) {
-- ctxt->valid &= xmlValidateAttributeValue2(ctxt, ctxt->doc,
-- cur->name, cur->atype, tree->name);
-- tree = tree->next;
-- }
-- }
-- }
--}
--
--/**
-- * xmlValidateDtdFinal:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- *
-- * Does the final step for the dtds validation once all the
-- * subsets have been parsed
-- *
-- * basically it does the following checks described by the XML Rec
-- * - check that ENTITY and ENTITIES type attributes default or
-- * possible values matches one of the defined entities.
-- * - check that NOTATION type attributes default or
-- * possible values matches one of the defined notations.
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-- int ret = 1;
-- xmlDtdPtr dtd;
-- xmlAttributeTablePtr table;
--
-- if (doc == NULL) return(0);
-- if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
-- return(0);
-- ctxt->doc = doc;
-- ctxt->valid = ret;
-- dtd = doc->intSubset;
-- if ((dtd != NULL) && (dtd->attributes != NULL)) {
-- table = (xmlAttributeTablePtr) dtd->attributes;
-- xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
-- }
-- dtd = doc->extSubset;
-- if ((dtd != NULL) && (dtd->attributes != NULL)) {
-- table = (xmlAttributeTablePtr) dtd->attributes;
-- xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
-- }
-- return(ctxt->valid);
--}
--
--/**
-- * xmlValidateDocument:
-- * @ctxt: the validation context
-- * @doc: a document instance
-- *
-- * Try to validate the document instance
-- *
-- * basically it does the all the checks described by the XML Rec
-- * i.e. validates the internal and external subset (if present)
-- * and validate the document tree.
-- *
-- * returns 1 if valid or 0 otherwise
-- */
--
--int
--xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
-- int ret;
-- xmlNodePtr root;
--
-- if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
-- return(0);
-- if ((doc->intSubset != NULL) && ((doc->intSubset->SystemID != NULL) ||
-- (doc->intSubset->ExternalID != NULL)) && (doc->extSubset == NULL)) {
-- doc->extSubset = xmlParseDTD(doc->intSubset->ExternalID,
-- doc->intSubset->SystemID);
-- if (doc->extSubset == NULL) {
-- if (doc->intSubset->SystemID != NULL) {
-- VERROR(ctxt->userData,
-- "Could not load the external subset \"%s\"\n",
-- doc->intSubset->SystemID);
-- } else {
-- VERROR(ctxt->userData,
-- "Could not load the external subset \"%s\"\n",
-- doc->intSubset->ExternalID);
-- }
-- return(0);
-- }
-- }
--
-- if (doc->ids != NULL) {
-- xmlFreeIDTable(doc->ids);
-- doc->ids = NULL;
-- }
-- if (doc->refs != NULL) {
-- xmlFreeRefTable(doc->refs);
-- doc->refs = NULL;
-- }
-- ret = xmlValidateDtdFinal(ctxt, doc);
-- if (!xmlValidateRoot(ctxt, doc)) return(0);
--
-- root = xmlDocGetRootElement(doc);
-- ret &= xmlValidateElement(ctxt, doc, root);
-- ret &= xmlValidateDocumentFinal(ctxt, doc);
-- return(ret);
--}
--
--
--/************************************************************************
-- * *
-- * Routines for dynamic validation editing *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlValidGetPotentialChildren:
-- * @ctree: an element content tree
-- * @list: an array to store the list of child names
-- * @len: a pointer to the number of element in the list
-- * @max: the size of the array
-- *
-- * Build/extend a list of potential children allowed by the content tree
-- *
-- * returns the number of element in the list, or -1 in case of error.
-- */
--
--int
--xmlValidGetPotentialChildren(xmlElementContent *ctree, const xmlChar **list,
-- int *len, int max) {
-- int i;
--
-- if ((ctree == NULL) || (list == NULL) || (len == NULL))
-- return(-1);
-- if (*len >= max) return(*len);
--
-- switch (ctree->type) {
-- case XML_ELEMENT_CONTENT_PCDATA:
-- for (i = 0; i < *len;i++)
-- if (xmlStrEqual(BAD_CAST "#PCDATA", list[i])) return(*len);
-- list[(*len)++] = BAD_CAST "#PCDATA";
-- break;
-- case XML_ELEMENT_CONTENT_ELEMENT:
-- for (i = 0; i < *len;i++)
-- if (xmlStrEqual(ctree->name, list[i])) return(*len);
-- list[(*len)++] = ctree->name;
-- break;
-- case XML_ELEMENT_CONTENT_SEQ:
-- xmlValidGetPotentialChildren(ctree->c1, list, len, max);
-- xmlValidGetPotentialChildren(ctree->c2, list, len, max);
-- break;
-- case XML_ELEMENT_CONTENT_OR:
-- xmlValidGetPotentialChildren(ctree->c1, list, len, max);
-- xmlValidGetPotentialChildren(ctree->c2, list, len, max);
-- break;
-- }
--
-- return(*len);
--}
--
--/**
-- * xmlValidGetValidElements:
-- * @prev: an element to insert after
-- * @next: an element to insert next
-- * @list: an array to store the list of child names
-- * @max: the size of the array
-- *
-- * This function returns the list of authorized children to insert
-- * within an existing tree while respecting the validity constraints
-- * forced by the Dtd. The insertion point is defined using @prev and
-- * @next in the following ways:
-- * to insert before 'node': xmlValidGetValidElements(node->prev, node, ...
-- * to insert next 'node': xmlValidGetValidElements(node, node->next, ...
-- * to replace 'node': xmlValidGetValidElements(node->prev, node->next, ...
-- * to prepend a child to 'node': xmlValidGetValidElements(NULL, node->childs,
-- * to append a child to 'node': xmlValidGetValidElements(node->last, NULL, ...
-- *
-- * pointers to the element names are inserted at the beginning of the array
-- * and do not need to be freed.
-- *
-- * returns the number of element in the list, or -1 in case of error. If
-- * the function returns the value @max the caller is invited to grow the
-- * receiving array and retry.
-- */
--
--int
--xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **list,
-- int max) {
-- int nb_valid_elements = 0;
-- const xmlChar *elements[256];
-- int nb_elements = 0, i;
--
-- xmlNode *ref_node;
-- xmlNode *parent;
-- xmlNode *test_node;
--
-- xmlNode *prev_next;
-- xmlNode *next_prev;
-- xmlNode *parent_childs;
-- xmlNode *parent_last;
--
-- xmlElement *element_desc;
--
-- if (prev == NULL && next == NULL)
-- return(-1);
--
-- if (list == NULL) return(-1);
-- if (max <= 0) return(-1);
--
-- nb_valid_elements = 0;
-- ref_node = prev ? prev : next;
-- parent = ref_node->parent;
--
-- /*
-- * Retrieves the parent element declaration
-- */
-- element_desc = xmlGetDtdElementDesc(parent->doc->intSubset,
-- parent->name);
-- if ((element_desc == NULL) && (parent->doc->extSubset != NULL))
-- element_desc = xmlGetDtdElementDesc(parent->doc->extSubset,
-- parent->name);
-- if (element_desc == NULL) return(-1);
--
-- /*
-- * Do a backup of the current tree structure
-- */
-- prev_next = prev ? prev->next : NULL;
-- next_prev = next ? next->prev : NULL;
-- parent_childs = parent->children;
-- parent_last = parent->last;
--
-- /*
-- * Creates a dummy node and insert it into the tree
-- */
-- test_node = xmlNewNode (NULL, BAD_CAST "<!dummy?>");
-- test_node->doc = ref_node->doc;
-- test_node->parent = parent;
-- test_node->prev = prev;
-- test_node->next = next;
--
-- if (prev) prev->next = test_node;
-- else parent->children = test_node;
--
-- if (next) next->prev = test_node;
-- else parent->last = test_node;
--
-- /*
-- * Insert each potential child node and check if the parent is
-- * still valid
-- */
-- nb_elements = xmlValidGetPotentialChildren(element_desc->content,
-- elements, &nb_elements, 256);
--
-- for (i = 0;i < nb_elements;i++) {
-- test_node->name = elements[i];
-- if (xmlValidateOneElement(NULL, parent->doc, parent)) {
-- int j;
--
-- for (j = 0; j < nb_valid_elements;j++)
-- if (xmlStrEqual(elements[i], list[j])) break;
-- list[nb_valid_elements++] = elements[i];
-- if (nb_valid_elements >= max) break;
-- }
-- }
--
-- /*
-- * Restore the tree structure
-- */
-- if (prev) prev->next = prev_next;
-- if (next) next->prev = next_prev;
-- parent->children = parent_childs;
-- parent->last = parent_last;
--
-- return(nb_valid_elements);
--}
-diff -Nru libxml2-2.3.0/xinclude.c libxml2-2.3.0.new/xinclude.c
---- libxml2-2.3.0/xinclude.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xinclude.c Thu Jan 1 01:00:00 1970
-@@ -1,806 +0,0 @@
--/*
-- * xinclude.c : Code to implement XInclude processing
-- *
-- * World Wide Web Consortium Working Draft 26 October 2000
-- * http://www.w3.org/TR/2000/WD-xinclude-20001026
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--/*
-- * TODO: compute XPointers nodesets
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/uri.h>
--#include <libxml/xpointer.h>
--#include <libxml/parserInternals.h>
--#ifdef LIBXML_DEBUG_ENABLED
--#include <libxml/debugXML.h>
--#endif
--#include <libxml/xmlerror.h>
--
--#ifdef LIBXML_XINCLUDE_ENABLED
--#include <libxml/xinclude.h>
--
--#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/1999/XML/xinclude"
--#define XINCLUDE_NODE (const xmlChar *) "include"
--#define XINCLUDE_HREF (const xmlChar *) "href"
--#define XINCLUDE_PARSE (const xmlChar *) "parse"
--#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
--#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
--
--/* #define DEBUG_XINCLUDE */
--
--/************************************************************************
-- * *
-- * XInclude contexts handling *
-- * *
-- ************************************************************************/
--
--/*
-- * An XInclude context
-- */
--typedef xmlChar *URL;
--typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
--typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;
--struct _xmlXIncludeCtxt {
-- xmlDocPtr doc; /* the source document */
-- int incNr; /* number of includes */
-- int incMax; /* size of includes tab */
-- xmlNodePtr *incTab; /* array of include nodes */
-- xmlNodePtr *repTab; /* array of replacement node lists */
-- int docNr; /* number of parsed documents */
-- int docMax; /* size of parsed documents tab */
-- xmlDocPtr *docTab; /* array of parsed documents */
-- URL *urlTab; /* array of parsed documents URLs */
-- int txtNr; /* number of unparsed documents */
-- int txtMax; /* size of unparsed documents tab */
-- xmlNodePtr *txtTab; /* array of unparsed text nodes */
-- URL *txturlTab; /* array of unparsed txtuments URLs */
--};
--
--/**
-- * xmlXIncludeAddNode:
-- * @ctxt: the XInclude context
-- * @node: the new node
-- *
-- * Add a new node to process to an XInclude context
-- */
--void
--xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
-- if (ctxt->incMax == 0) {
-- ctxt->incMax = 4;
-- ctxt->incTab = (xmlNodePtr *) xmlMalloc(ctxt->incMax *
-- sizeof(ctxt->incTab[0]));
-- if (ctxt->incTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc failed !\n");
-- return;
-- }
-- ctxt->repTab = (xmlNodePtr *) xmlMalloc(ctxt->incMax *
-- sizeof(ctxt->repTab[0]));
-- if (ctxt->repTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc failed !\n");
-- return;
-- }
-- }
-- if (ctxt->incNr >= ctxt->incMax) {
-- ctxt->incMax *= 2;
-- ctxt->incTab = (xmlNodePtr *) xmlRealloc(ctxt->incTab,
-- ctxt->incMax * sizeof(ctxt->incTab[0]));
-- if (ctxt->incTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return;
-- }
-- ctxt->repTab = (xmlNodePtr *) xmlRealloc(ctxt->repTab,
-- ctxt->incMax * sizeof(ctxt->repTab[0]));
-- if (ctxt->repTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return;
-- }
-- }
-- ctxt->incTab[ctxt->incNr] = node;
-- ctxt->repTab[ctxt->incNr] = NULL;
-- ctxt->incNr++;
--}
--
--/**
-- * xmlXIncludeAddDoc:
-- * @ctxt: the XInclude context
-- * @doc: the new document
-- * @url: the associated URL
-- *
-- * Add a new document to the list
-- */
--void
--xmlXIncludeAddDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, const URL url) {
-- if (ctxt->docMax == 0) {
-- ctxt->docMax = 4;
-- ctxt->docTab = (xmlDocPtr *) xmlMalloc(ctxt->docMax *
-- sizeof(ctxt->docTab[0]));
-- if (ctxt->docTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc failed !\n");
-- return;
-- }
-- ctxt->urlTab = (URL *) xmlMalloc(ctxt->docMax *
-- sizeof(ctxt->urlTab[0]));
-- if (ctxt->urlTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc failed !\n");
-- return;
-- }
-- }
-- if (ctxt->docNr >= ctxt->docMax) {
-- ctxt->docMax *= 2;
-- ctxt->docTab = (xmlDocPtr *) xmlRealloc(ctxt->docTab,
-- ctxt->docMax * sizeof(ctxt->docTab[0]));
-- if (ctxt->docTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return;
-- }
-- ctxt->urlTab = (URL *) xmlRealloc(ctxt->urlTab,
-- ctxt->docMax * sizeof(ctxt->urlTab[0]));
-- if (ctxt->urlTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return;
-- }
-- }
-- ctxt->docTab[ctxt->docNr] = doc;
-- ctxt->urlTab[ctxt->docNr] = xmlStrdup(url);
-- ctxt->docNr++;
--}
--
--/**
-- * xmlXIncludeAddTxt:
-- * @ctxt: the XInclude context
-- * @txt: the new text node
-- * @url: the associated URL
-- *
-- * Add a new txtument to the list
-- */
--void
--xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const URL url) {
-- if (ctxt->txtMax == 0) {
-- ctxt->txtMax = 4;
-- ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
-- sizeof(ctxt->txtTab[0]));
-- if (ctxt->txtTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc failed !\n");
-- return;
-- }
-- ctxt->txturlTab = (URL *) xmlMalloc(ctxt->txtMax *
-- sizeof(ctxt->txturlTab[0]));
-- if (ctxt->txturlTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "malloc failed !\n");
-- return;
-- }
-- }
-- if (ctxt->txtNr >= ctxt->txtMax) {
-- ctxt->txtMax *= 2;
-- ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
-- ctxt->txtMax * sizeof(ctxt->txtTab[0]));
-- if (ctxt->txtTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return;
-- }
-- ctxt->txturlTab = (URL *) xmlRealloc(ctxt->txturlTab,
-- ctxt->txtMax * sizeof(ctxt->urlTab[0]));
-- if (ctxt->txturlTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "realloc failed !\n");
-- return;
-- }
-- }
-- ctxt->txtTab[ctxt->txtNr] = txt;
-- ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url);
-- ctxt->txtNr++;
--}
--
--/**
-- * xmlXIncludeNewContext:
-- * @doc: an XML Document
-- *
-- * Creates a new XInclude context
-- *
-- * Returns the new set
-- */
--xmlXIncludeCtxtPtr
--xmlXIncludeNewContext(xmlDocPtr doc) {
-- xmlXIncludeCtxtPtr ret;
--
-- if (doc == NULL)
-- return(NULL);
-- ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
-- if (ret == NULL)
-- return(NULL);
-- memset(ret, 0, sizeof(xmlXIncludeCtxt));
-- ret->doc = doc;
-- ret->incNr = 0;
-- ret->incMax = 0;
-- ret->incTab = NULL;
-- ret->repTab = NULL;
-- ret->docNr = 0;
-- ret->docMax = 0;
-- ret->docTab = NULL;
-- ret->urlTab = NULL;
-- return(ret);
--}
--
--/**
-- * xmlXIncludeFreeContext:
-- * @ctxt: the XInclude context
-- *
-- * Free an XInclude context
-- */
--void
--xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
-- int i;
--
-- if (ctxt == NULL)
-- return;
-- for (i = 0;i < ctxt->docNr;i++) {
-- xmlFreeDoc(ctxt->docTab[i]);
-- if (ctxt->urlTab[i] != NULL)
-- xmlFree(ctxt->urlTab[i]);
-- }
-- for (i = 0;i < ctxt->txtNr;i++) {
-- if (ctxt->txturlTab[i] != NULL)
-- xmlFree(ctxt->txturlTab[i]);
-- }
-- if (ctxt->incTab != NULL)
-- xmlFree(ctxt->incTab);
-- if (ctxt->repTab != NULL)
-- xmlFree(ctxt->repTab);
-- if (ctxt->urlTab != NULL)
-- xmlFree(ctxt->urlTab);
-- if (ctxt->docTab != NULL)
-- xmlFree(ctxt->docTab);
-- if (ctxt->txtTab != NULL)
-- xmlFree(ctxt->txtTab);
-- if (ctxt->txturlTab != NULL)
-- xmlFree(ctxt->txturlTab);
-- memset(ctxt, 0xeb, sizeof(xmlXIncludeCtxt));
-- xmlFree(ctxt);
--}
--
--/************************************************************************
-- * *
-- * XInclude I/O handling *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXIncludeLoadDoc:
-- * @ctxt: the XInclude context
-- * @url: the associated URL
-- * @nr: the xinclude node number
-- *
-- * Load the document, and store the result in the XInclude context
-- */
--void
--xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
-- xmlDocPtr doc;
-- xmlURIPtr uri;
-- xmlChar *URL;
-- xmlChar *fragment = NULL;
-- int i;
-- /*
-- * Check the URL and remove any fragment identifier
-- */
-- uri = xmlParseURI((const char *)url);
-- if (uri == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: invalid value URI %s\n", url);
-- return;
-- }
-- if (uri->fragment != NULL) {
-- fragment = (xmlChar *) uri->fragment;
-- uri->fragment = NULL;
-- }
-- URL = xmlSaveUri(uri);
-- xmlFreeURI(uri);
-- if (URL == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: invalid value URI %s\n", url);
-- if (fragment != NULL)
-- xmlFree(fragment);
-- return;
-- }
--
-- /*
-- * Handling of references to the local document are done
-- * directly through ctxt->doc.
-- */
-- if ((URL[0] == 0) || (URL[0] == '#')) {
-- doc = NULL;
-- goto loaded;
-- }
--
-- /*
-- * Prevent reloading twice the document.
-- */
-- for (i = 0; i < ctxt->docNr; i++) {
-- if (xmlStrEqual(URL, ctxt->urlTab[i])) {
-- doc = ctxt->docTab[i];
-- goto loaded;
-- }
-- }
-- /*
-- * Load it.
-- */
-- doc = xmlParseFile((const char *)URL);
-- if (doc == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: could not load %s\n", URL);
-- xmlFree(URL);
-- if (fragment != NULL)
-- xmlFree(fragment);
-- return;
-- }
-- xmlXIncludeAddDoc(ctxt, doc, URL);
--
--loaded:
-- if (fragment == NULL) {
-- /*
-- * Add the top children list as the replacement copy.
-- * ISSUE: seems we should scrap DTD info from the copied list.
-- */
-- if (doc == NULL)
-- ctxt->repTab[nr] = xmlCopyNodeList(ctxt->doc->children);
-- else
-- ctxt->repTab[nr] = xmlCopyNodeList(doc->children);
-- } else {
-- /*
-- * Computes the XPointer expression and make a copy used
-- * as the replacement copy.
-- */
-- xmlXPathObjectPtr xptr;
-- xmlXPathContextPtr xptrctxt;
--
-- if (doc == NULL) {
-- xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr], NULL);
-- } else {
-- xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
-- }
-- if (xptrctxt == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: could create XPointer context\n");
-- xmlFree(URL);
-- xmlFree(fragment);
-- return;
-- }
-- xptr = xmlXPtrEval(fragment, xptrctxt);
-- if (xptr == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: XPointer evaluation failed: #%s\n",
-- fragment);
-- xmlXPathFreeContext(xptrctxt);
-- xmlFree(URL);
-- xmlFree(fragment);
-- return;
-- }
-- ctxt->repTab[nr] = xmlXPtrBuildNodeList(xptr);
-- xmlXPathFreeObject(xptr);
-- xmlXPathFreeContext(xptrctxt);
-- xmlFree(fragment);
-- }
-- xmlFree(URL);
--}
--
--/**
-- * xmlXIncludeLoadTxt:
-- * @ctxt: the XInclude context
-- * @url: the associated URL
-- * @nr: the xinclude node number
-- *
-- * Load the content, and store the result in the XInclude context
-- */
--void
--xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
-- xmlParserInputBufferPtr buf;
-- xmlNodePtr node;
-- xmlURIPtr uri;
-- xmlChar *URL;
-- int i;
-- /*
-- * Check the URL and remove any fragment identifier
-- */
-- uri = xmlParseURI((const char *)url);
-- if (uri == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: invalid value URI %s\n", url);
-- return;
-- }
-- if (uri->fragment != NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: fragment identifier forbidden for text: %s\n",
-- uri->fragment);
-- xmlFreeURI(uri);
-- return;
-- }
-- URL = xmlSaveUri(uri);
-- xmlFreeURI(uri);
-- if (URL == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: invalid value URI %s\n", url);
-- return;
-- }
--
-- /*
-- * Handling of references to the local document are done
-- * directly through ctxt->doc.
-- */
-- if (URL[0] == 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: text serialization of document not available\n");
-- xmlFree(URL);
-- return;
-- }
--
-- /*
-- * Prevent reloading twice the document.
-- */
-- for (i = 0; i < ctxt->txtNr; i++) {
-- if (xmlStrEqual(URL, ctxt->txturlTab[i])) {
-- node = xmlCopyNode(ctxt->txtTab[i], 1);
-- goto loaded;
-- }
-- }
-- /*
-- * Load it.
-- * Issue 62: how to detect the encoding
-- */
-- buf = xmlParserInputBufferCreateFilename((const char *)URL, 0);
-- if (buf == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: could not load %s\n", URL);
-- xmlFree(URL);
-- return;
-- }
-- node = xmlNewText(NULL);
--
-- /*
-- * Scan all chars from the resource and add the to the node
-- */
-- while (xmlParserInputBufferRead(buf, 128) > 0) {
-- int len;
-- const xmlChar *content;
--
-- content = xmlBufferContent(buf->buffer);
-- len = xmlBufferLength(buf->buffer);
-- for (i = 0;i < len; i++) {
-- /*
-- * TODO: if the encoding issue is solved, scan UTF8 chars instead
-- */
-- if (!IS_CHAR(content[i])) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: %s contains invalid char %d\n", URL, content[i]);
-- } else {
-- xmlNodeAddContentLen(node, &content[i], 1);
-- }
-- }
-- xmlBufferShrink(buf->buffer, len);
-- }
-- xmlFreeParserInputBuffer(buf);
-- xmlXIncludeAddTxt(ctxt, node, URL);
--
--loaded:
-- /*
-- * Add the element as the replacement copy.
-- */
-- ctxt->repTab[nr] = node;
-- xmlFree(URL);
--}
--
--/************************************************************************
-- * *
-- * XInclude Processing *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXIncludePreProcessNode:
-- * @ctxt: an XInclude context
-- * @node: an XInclude node
-- *
-- * Implement the infoset replacement lookup on the XML element @node
-- *
-- * Returns the result list or NULL in case of error
-- */
--xmlNodePtr
--xmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
-- xmlXIncludeAddNode(ctxt, node);
-- return(0);
--}
--
--/**
-- * xmlXIncludeLoadNode:
-- * @ctxt: an XInclude context
-- * @nr: the node number
-- *
-- * Find and load the infoset replacement for the given node.
-- *
-- * Returns 0 if substition succeeded, -1 if some processing failed
-- */
--int
--xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
-- xmlNodePtr cur;
-- xmlChar *href;
-- xmlChar *parse;
-- xmlChar *base;
-- xmlChar *URI;
-- int xml = 1; /* default Issue 64 */
--
-- if (ctxt == NULL)
-- return(-1);
-- if ((nr < 0) || (nr >= ctxt->incNr))
-- return(-1);
-- cur = ctxt->incTab[nr];
-- if (cur == NULL)
-- return(-1);
--
--#ifdef DEBUG_XINCLUDE
-- xmlDebugDumpNode(stdout, cur, 0);
--#endif
-- /*
-- * read the attributes
-- */
-- href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
-- if (href == NULL) {
-- href = xmlGetProp(cur, XINCLUDE_HREF);
-- if (href == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
-- return(-1);
-- }
-- }
-- parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
-- if (parse == NULL) {
-- parse = xmlGetProp(cur, XINCLUDE_PARSE);
-- }
-- if (parse != NULL) {
-- if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
-- xml = 1;
-- else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
-- xml = 0;
-- else {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: invalid value %s for %s\n",
-- parse, XINCLUDE_PARSE);
-- if (href != NULL)
-- xmlFree(href);
-- if (parse != NULL)
-- xmlFree(parse);
-- return(-1);
-- }
-- }
--
-- /*
-- * compute the URI
-- */
-- base = xmlNodeGetBase(ctxt->doc, cur);
-- if (base == NULL) {
-- URI = xmlBuildURI(href, ctxt->doc->URL);
-- } else {
-- URI = xmlBuildURI(href, base);
-- }
-- if (URI == NULL) {
-- xmlChar *escbase;
-- xmlChar *eschref;
-- /*
-- * Some escapeing may be needed
-- */
-- escbase = xmlURIEscape(base);
-- eschref = xmlURIEscape(href);
-- URI = xmlBuildURI(eschref, escbase);
-- if (escbase != NULL)
-- xmlFree(escbase);
-- if (eschref != NULL)
-- xmlFree(eschref);
-- }
-- if (URI == NULL) {
-- xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
-- if (parse != NULL)
-- xmlFree(parse);
-- if (href != NULL)
-- xmlFree(href);
-- if (base != NULL)
-- xmlFree(base);
-- return(-1);
-- }
--#ifdef DEBUG_XINCLUDE
-- xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
-- xml ? "xml": "text");
-- xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
--#endif
--
-- /*
-- * Cleanup
-- */
-- if (xml) {
-- xmlXIncludeLoadDoc(ctxt, URI, nr);
-- /* xmlXIncludeGetFragment(ctxt, cur, URI); */
-- } else {
-- xmlXIncludeLoadTxt(ctxt, URI, nr);
-- }
--
-- /*
-- * Cleanup
-- */
-- if (URI != NULL)
-- xmlFree(URI);
-- if (parse != NULL)
-- xmlFree(parse);
-- if (href != NULL)
-- xmlFree(href);
-- if (base != NULL)
-- xmlFree(base);
-- return(0);
--}
--
--/**
-- * xmlXIncludeIncludeNode:
-- * @ctxt: an XInclude context
-- * @nr: the node number
-- *
-- * Inplement the infoset replacement for the given node
-- *
-- * Returns 0 if substition succeeded, -1 if some processing failed
-- */
--int
--xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
-- xmlNodePtr cur, end, list;
--
-- if (ctxt == NULL)
-- return(-1);
-- if ((nr < 0) || (nr >= ctxt->incNr))
-- return(-1);
-- cur = ctxt->incTab[nr];
-- if (cur == NULL)
-- return(-1);
--
-- /*
-- * Change the current node as an XInclude start one, and add an
-- * entity end one
-- */
-- cur->type = XML_XINCLUDE_START;
-- end = xmlNewNode(cur->ns, cur->name);
-- if (end == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "XInclude: failed to build node\n");
-- return(-1);
-- }
-- end->type = XML_XINCLUDE_END;
-- xmlAddNextSibling(cur, end);
--
-- /*
-- * Add the list of nodes
-- */
-- list = ctxt->repTab[nr];
-- ctxt->repTab[nr] = NULL;
-- while (list != NULL) {
-- cur = list;
-- list = list->next;
--
-- xmlAddPrevSibling(end, cur);
-- }
-- return(0);
--}
--
--/**
-- * xmlXIncludeTestNode:
-- * @doc: an XML document
-- * @node: an XInclude node
-- *
-- * test if the node is an XInclude node
-- *
-- * Returns 1 true, 0 otherwise
-- */
--int
--xmlXIncludeTestNode(xmlDocPtr doc, xmlNodePtr node) {
-- if (node == NULL)
-- return(0);
-- if (node->ns == NULL)
-- return(0);
-- if ((xmlStrEqual(node->name, XINCLUDE_NODE)) &&
-- (xmlStrEqual(node->ns->href, XINCLUDE_NS))) return(1);
-- return(0);
--}
--
--/**
-- * xmlXIncludeProcess:
-- * @doc: an XML document
-- *
-- * Implement the XInclude substitution on the XML document @doc
-- *
-- * Returns 0 if no substition were done, -1 if some processing failed
-- * or the number of substitutions done.
-- */
--int
--xmlXIncludeProcess(xmlDocPtr doc) {
-- xmlXIncludeCtxtPtr ctxt;
-- xmlNodePtr cur;
-- int ret = 0;
-- int i;
--
-- if (doc == NULL)
-- return(-1);
-- ctxt = xmlXIncludeNewContext(doc);
-- if (ctxt == NULL)
-- return(-1);
--
-- /*
-- * First phase: lookup the elements in the document
-- */
-- cur = xmlDocGetRootElement(doc);
-- if (xmlXIncludeTestNode(doc, cur))
-- xmlXIncludePreProcessNode(ctxt, cur);
-- while (cur != NULL) {
-- /* TODO: need to work on entities -> stack */
-- if ((cur->children != NULL) &&
-- (cur->children->type != XML_ENTITY_DECL)) {
-- cur = cur->children;
-- if (xmlXIncludeTestNode(doc, cur))
-- xmlXIncludePreProcessNode(ctxt, cur);
-- } else if (cur->next != NULL) {
-- cur = cur->next;
-- if (xmlXIncludeTestNode(doc, cur))
-- xmlXIncludePreProcessNode(ctxt, cur);
-- } else {
-- do {
-- cur = cur->parent;
-- if (cur == NULL) break; /* do */
-- if (cur->next != NULL) {
-- cur = cur->next;
-- if (xmlXIncludeTestNode(doc, cur))
-- xmlXIncludePreProcessNode(ctxt, cur);
-- break; /* do */
-- }
-- } while (cur != NULL);
-- }
-- }
--
-- /*
-- * Second Phase : collect the infosets fragments
-- */
-- for (i = 0;i < ctxt->incNr; i++) {
-- xmlXIncludeLoadNode(ctxt, i);
-- }
--
-- /*
-- * Third phase: extend the original document infoset.
-- */
-- for (i = 0;i < ctxt->incNr; i++) {
-- xmlXIncludeIncludeNode(ctxt, i);
-- }
--
-- /*
-- * Cleanup
-- */
-- xmlXIncludeFreeContext(ctxt);
-- return(ret);
--}
--
--#else /* !LIBXML_XINCLUDE_ENABLED */
--#endif
-diff -Nru libxml2-2.3.0/xlink.c libxml2-2.3.0.new/xlink.c
---- libxml2-2.3.0/xlink.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xlink.c Thu Jan 1 01:00:00 1970
-@@ -1,187 +0,0 @@
--/*
-- * xlink.c : implementation of the hyperlinks detection module
-- * This version supports both XML XLinks and HTML simple links
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h> /* for memset() only */
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_SYS_STAT_H
--#include <sys/stat.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_ZLIB_H
--#include <zlib.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/parser.h>
--#include <libxml/valid.h>
--#include <libxml/xlink.h>
--
--#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
--#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
--
--/****************************************************************
-- * *
-- * Default setting and related functions *
-- * *
-- ****************************************************************/
--
--xlinkHandlerPtr xlinkDefaultHandler = NULL;
--xlinkNodeDetectFunc xlinkDefaultDetect = NULL;
--
--/**
-- * xlinkGetDefaultHandler:
-- *
-- * Get the default xlink handler.
-- *
-- * Returns the current xlinkHandlerPtr value.
-- */
--xlinkHandlerPtr
--xlinkGetDefaultHandler(void) {
-- return(xlinkDefaultHandler);
--}
--
--
--/**
-- * xlinkSetDefaultHandler:
-- * @handler: the new value for the xlink handler block
-- *
-- * Set the default xlink handlers
-- */
--void
--xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
-- xlinkDefaultHandler = handler;
--}
--
--/**
-- * xlinkGetDefaultDetect:
-- *
-- * Get the default xlink detection routine
-- *
-- * Returns the current function or NULL;
-- */
--xlinkNodeDetectFunc
--xlinkGetDefaultDetect (void) {
-- return(xlinkDefaultDetect);
--}
--
--/**
-- * xlinkSetDefaultDetect:
-- * @func: pointer to the new detction routine.
-- *
-- * Set the default xlink detection routine
-- */
--void
--xlinkSetDefaultDetect (xlinkNodeDetectFunc func) {
-- xlinkDefaultDetect = func;
--}
--
--/****************************************************************
-- * *
-- * The detection routines *
-- * *
-- ****************************************************************/
--
--
--/**
-- * xlinkIsLink:
-- * @doc: the document containing the node
-- * @node: the node pointer itself
-- *
-- * Check whether the given node carries the attributes needed
-- * to be a link element (or is one of the linking elements issued
-- * from the (X)HTML DtDs).
-- * This routine don't try to do full checking of the link validity
-- * but tries to detect and return the appropriate link type.
-- *
-- * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
-- * link detected.
-- */
--xlinkType
--xlinkIsLink (xmlDocPtr doc, xmlNodePtr node) {
-- xmlChar *type = NULL, *role = NULL;
-- xlinkType ret = XLINK_TYPE_NONE;
--
-- if (node == NULL) return(XLINK_TYPE_NONE);
-- if (doc == NULL) doc = node->doc;
-- if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
-- /*
-- * This is an HTML document.
-- */
-- } else if ((node->ns != NULL) &&
-- (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) {
-- /*
-- * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
-- */
-- /*
-- * This is an XHTML element within an XML document
-- * Check whether it's one of the element able to carry links
-- * and in that case if it holds the attributes.
-- */
-- }
--
-- /*
-- * We don't prevent a-priori having XML Linking constructs on
-- * XHTML elements
-- */
-- type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
-- if (type != NULL) {
-- if (!xmlStrEqual(type, BAD_CAST "simple")) {
-- ret = XLINK_TYPE_SIMPLE;
-- } if (!xmlStrEqual(type, BAD_CAST "extended")) {
-- role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
-- if (role != NULL) {
-- xmlNsPtr xlink;
-- xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
-- if (xlink == NULL) {
-- /* Humm, fallback method */
-- if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset"))
-- ret = XLINK_TYPE_EXTENDED_SET;
-- } else {
-- xmlChar buf[200];
--#ifdef HAVE_SNPRINTF
-- snprintf((char *) buf, sizeof(buf), "%s:external-linkset",
-- (char *) xlink->prefix);
--#else
-- sprintf((char *) buf, "%s:external-linkset",
-- (char *) xlink->prefix);
--#endif
-- buf[sizeof(buf) - 1] = 0;
-- if (xmlStrEqual(role, buf))
-- ret = XLINK_TYPE_EXTENDED_SET;
--
-- }
--
-- }
-- ret = XLINK_TYPE_EXTENDED;
-- }
-- }
--
-- if (type != NULL) xmlFree(type);
-- if (role != NULL) xmlFree(role);
-- return(ret);
--}
-diff -Nru libxml2-2.3.0/xml2-config.1 libxml2-2.3.0.new/xml2-config.1
---- libxml2-2.3.0/xml2-config.1 Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xml2-config.1 Thu Jan 1 01:00:00 1970
-@@ -1,31 +0,0 @@
--.TH GNOME-XML 1 "3 July 1999" Version 1.1.0
--.SH NAME
--xml-config - script to get information about the installed version of GNOME-XML
--.SH SYNOPSIS
--.B xml-config
--[\-\-prefix\fI[=DIR]\fP] [\-\-libs] [\-\-cflags] [\-\-version] [\-\-help]
--.SH DESCRIPTION
--\fIxml-config\fP is a tool that is used to determine the compile and
--linker flags that should be used to compile and link programs that use
--\fIGNOME-XML\fP.
--.SH OPTIONS
--.l
--\fIxml-config\fP accepts the following options:
--.TP 8
--.B \-\-version
--Print the currently installed version of \fIGNOME-XML\fP on the standard output.
--.TP 8
--.B \-\-libs
--Print the linker flags that are necessary to link a \fIGNOME-XML\fP program.
--.TP 8
--.B \-\-cflags
--Print the compiler flags that are necessary to compile a \fIGNOME-XML\fP program.
--.TP 8
--.B \-\-prefix=PREFIX
--If specified, use PREFIX instead of the installation prefix that
--\fIGNOME-XML\fP was built with when computing the output for the
--\-\-cflags and \-\-libs options. This option must be specified before
--any \-\-libs or \-\-cflags options.
--.SH AUTHOR
--This manual page was written by Fredrik Hallenberg <hallon@lysator.liu.se>,
--for the Debian GNU/linux system (but may be used by others).
-diff -Nru libxml2-2.3.0/xml2-config.in libxml2-2.3.0.new/xml2-config.in
---- libxml2-2.3.0/xml2-config.in Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xml2-config.in Thu Jan 1 01:00:00 1970
-@@ -1,72 +0,0 @@
--#! /bin/sh
--
--prefix=@prefix@
--exec_prefix=@exec_prefix@
--includedir=@includedir@
--libdir=@libdir@
--
--usage()
--{
-- cat <<EOF
--Usage: xml-config [OPTION]
--
--Known values for OPTION are:
--
-- --prefix=DIR change libxml prefix [default $prefix]
-- --libs print library linking information
-- --cflags print pre-processor and compiler flags
-- --help display this help and exit
-- --version output version information
--EOF
--
-- exit $1
--}
--
--if test $# -eq 0; then
-- usage 1
--fi
--
--cflags=false
--libs=false
--
--while test $# -gt 0; do
-- case "$1" in
-- -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
-- *) optarg= ;;
-- esac
--
-- case "$1" in
-- --prefix=*)
-- prefix=$optarg
-- ;;
--
-- --prefix)
-- echo $prefix
-- ;;
--
-- --version)
-- echo @VERSION@
-- exit 0
-- ;;
--
-- --help)
-- usage 0
-- ;;
--
-- --cflags)
-- echo @XML_INCLUDEDIR@ @XML_CFLAGS@
-- ;;
--
-- --libs)
-- echo @XML_LIBDIR@ @XML_LIBS@
-- ;;
--
-- *)
-- usage
-- exit 1
-- ;;
-- esac
-- shift
--done
--
--exit 0
-diff -Nru libxml2-2.3.0/xml2Conf.sh.in libxml2-2.3.0.new/xml2Conf.sh.in
---- libxml2-2.3.0/xml2Conf.sh.in Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xml2Conf.sh.in Thu Jan 1 01:00:00 1970
-@@ -1,8 +0,0 @@
--#
--# Configuration file for using the XML library in GNOME applications
--#
--XML_LIBDIR="@XML_LIBDIR@"
--XML_LIBS="@XML_LIBS@"
--XML_INCLUDEDIR="@XML_INCLUDEDIR@"
--MODULE_VERSION="xml-@VERSION@"
--
-diff -Nru libxml2-2.3.0/xmlIO.c libxml2-2.3.0.new/xmlIO.c
---- libxml2-2.3.0/xmlIO.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xmlIO.c Thu Jan 1 01:00:00 1970
-@@ -1,1743 +0,0 @@
--/*
-- * xmlIO.c : implementation of the I/O interfaces used by the parser
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- *
-- * 14 Nov 2000 ht - for VMS, truncated name of long functions to under 32 char
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--#include <errno.h>
--
--#ifdef HAVE_SYS_TYPES_H
--#include <sys/types.h>
--#endif
--#ifdef HAVE_SYS_STAT_H
--#include <sys/stat.h>
--#endif
--#ifdef HAVE_FCNTL_H
--#include <fcntl.h>
--#endif
--#ifdef HAVE_UNISTD_H
--#include <unistd.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_ZLIB_H
--#include <zlib.h>
--#endif
--
--/* Figure a portable way to know if a file is a directory. */
--#ifndef HAVE_STAT
--# ifdef HAVE__STAT
--# define stat(x,y) _stat(x,y)
--# define HAVE_STAT
--# endif
--#endif
--#ifdef HAVE_STAT
--# ifndef S_ISDIR
--# ifdef _S_ISDIR
--# define S_ISDIR(x) _S_ISDIR(x)
--# else
--# ifdef S_IFDIR
--# ifndef S_IFMT
--# ifdef _S_IFMT
--# define S_IFMT _S_IFMT
--# endif
--# endif
--# ifdef S_IFMT
--# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
--# endif
--# endif
--# endif
--# endif
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/parser.h>
--#include <libxml/parserInternals.h>
--#include <libxml/xmlIO.h>
--#include <libxml/nanohttp.h>
--#include <libxml/nanoftp.h>
--#include <libxml/xmlerror.h>
--
--#ifdef VMS
--#define xmlRegisterDefaultInputCallbacks xmlRegisterDefInputCallbacks
--#define xmlRegisterDefaultOutputCallbacks xmlRegisterDefOutputCallbacks
--#endif
--
--/* #define VERBOSE_FAILURE */
--/* #define DEBUG_EXTERNAL_ENTITIES */
--/* #define DEBUG_INPUT */
--
--#ifdef DEBUG_INPUT
--#define MINLEN 40
--#else
--#define MINLEN 4000
--#endif
--
--/*
-- * Input I/O callback sets
-- */
--typedef struct _xmlInputCallback {
-- xmlInputMatchCallback matchcallback;
-- xmlInputOpenCallback opencallback;
-- xmlInputReadCallback readcallback;
-- xmlInputCloseCallback closecallback;
--} xmlInputCallback;
--
--#define MAX_INPUT_CALLBACK 15
--
--xmlInputCallback xmlInputCallbackTable[MAX_INPUT_CALLBACK];
--int xmlInputCallbackNr = 0;
--int xmlInputCallbackInitialized = 0;
--
--/*
-- * Output I/O callback sets
-- */
--typedef struct _xmlOutputCallback {
-- xmlOutputMatchCallback matchcallback;
-- xmlOutputOpenCallback opencallback;
-- xmlOutputWriteCallback writecallback;
-- xmlOutputCloseCallback closecallback;
--} xmlOutputCallback;
--
--#define MAX_OUTPUT_CALLBACK 15
--
--xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
--int xmlOutputCallbackNr = 0;
--int xmlOutputCallbackInitialized = 0;
--
--/************************************************************************
-- * *
-- * Standard I/O for file accesses *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlCheckFilename
-- * @path: the path to check
-- *
-- * function checks to see if @path is a valid source
-- * (file, socket...) for XML.
-- *
-- * if stat is not available on the target machine,
-- * returns 1. if stat fails, returns 0 (if calling
-- * stat on the filename fails, it can't be right).
-- * if stat succeeds and the file is a directory,
-- * sets errno to EISDIR and returns 0. otherwise
-- * returns 1.
-- */
--
--static int
--xmlCheckFilename (const char *path)
--{
--#ifdef HAVE_STAT
--#ifdef S_ISDIR
-- struct stat stat_buffer;
--
-- if (stat(path, &stat_buffer) == -1)
-- return 0;
--
-- if (S_ISDIR(stat_buffer.st_mode)) {
-- errno = EISDIR;
-- return 0;
-- }
--
--#endif
--#endif
-- return 1;
--}
--
--int
--xmlNop(void) {
-- return(0);
--}
--
--/**
-- * xmlFdMatch:
-- * @filename: the URI for matching
-- *
-- * input from file descriptor
-- *
-- * Returns 1 if matches, 0 otherwise
-- */
--int
--xmlFdMatch (const char *filename) {
-- return(1);
--}
--
--/**
-- * xmlFdOpen:
-- * @filename: the URI for matching
-- *
-- * input from file descriptor, supports compressed input
-- * if @filename is " " then the standard input is used
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlFdOpen (const char *filename) {
-- const char *path = NULL;
-- int fd;
--
-- if (!strcmp(filename, "-")) {
-- fd = 0;
-- return((void *) fd);
-- }
--
-- if (!strncmp(filename, "file://localhost", 16))
-- path = &filename[16];
-- else if (!strncmp(filename, "file:///", 8))
-- path = &filename[8];
-- else if (filename[0] == '/')
-- path = filename;
-- if (path == NULL)
-- return(NULL);
--
--#ifdef WIN32
-- fd = _open (path, O_RDONLY | _O_BINARY);
--#else
-- fd = open (path, O_RDONLY);
--#endif
--
-- return((void *) fd);
--}
--
--/**
-- * xmlFdOpenW:
-- * @filename: the URI for matching
-- *
-- * input from file descriptor,
-- * if @filename is "-" then the standard output is used
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlFdOpenW (const char *filename) {
-- const char *path = NULL;
-- int fd;
--
-- if (!strcmp(filename, "-")) {
-- fd = 1;
-- return((void *) fd);
-- }
--
-- if (!strncmp(filename, "file://localhost", 16))
-- path = &filename[16];
-- else if (!strncmp(filename, "file:///", 8))
-- path = &filename[8];
-- else if (filename[0] == '/')
-- path = filename;
-- if (path == NULL)
-- return(NULL);
--
-- fd = open (path, O_WRONLY);
--
-- return((void *) fd);
--}
--
--/**
-- * xmlFdRead:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to read
-- *
-- * Read @len bytes to @buffer from the I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlFdRead (void * context, char * buffer, int len) {
-- return(read((int) context, &buffer[0], len));
--}
--
--/**
-- * xmlFdWrite:
-- * @context: the I/O context
-- * @buffer: where to get data
-- * @len: number of bytes to write
-- *
-- * Write @len bytes from @buffer to the I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlFdWrite (void * context, const char * buffer, int len) {
-- return(write((int) context, &buffer[0], len));
--}
--
--/**
-- * xmlFdClose:
-- * @context: the I/O context
-- *
-- * Close an I/O channel
-- */
--void
--xmlFdClose (void * context) {
-- close((int) context);
--}
--
--/**
-- * xmlFileMatch:
-- * @filename: the URI for matching
-- *
-- * input from FILE *
-- *
-- * Returns 1 if matches, 0 otherwise
-- */
--int
--xmlFileMatch (const char *filename) {
-- return(1);
--}
--
--/**
-- * xmlFileOpen:
-- * @filename: the URI for matching
-- *
-- * input from FILE *, supports compressed input
-- * if @filename is " " then the standard input is used
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlFileOpen (const char *filename) {
-- const char *path = NULL;
-- FILE *fd;
--
-- if (!strcmp(filename, "-")) {
-- fd = stdin;
-- return((void *) fd);
-- }
--
-- if (!strncmp(filename, "file://localhost", 16))
-- path = &filename[16];
-- else if (!strncmp(filename, "file:///", 8))
-- path = &filename[8];
-- else
-- path = filename;
--
-- if (path == NULL)
-- return(NULL);
-- if (!xmlCheckFilename(path))
-- return(NULL);
--
--#ifdef WIN32
-- fd = fopen(path, "rb");
--#else
-- fd = fopen(path, "r");
--#endif /* WIN32 */
-- return((void *) fd);
--}
--
--/**
-- * xmlFileOpenW:
-- * @filename: the URI for matching
-- *
-- * output to from FILE *,
-- * if @filename is "-" then the standard output is used
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlFileOpenW (const char *filename) {
-- const char *path = NULL;
-- FILE *fd;
--
-- if (!strcmp(filename, "-")) {
-- fd = stdout;
-- return((void *) fd);
-- }
--
-- if (!strncmp(filename, "file://localhost", 16))
-- path = &filename[16];
-- else if (!strncmp(filename, "file:///", 8))
-- path = &filename[8];
-- else
-- path = filename;
--
-- if (path == NULL)
-- return(NULL);
--
-- fd = fopen(path, "w");
-- return((void *) fd);
--}
--
--/**
-- * xmlFileRead:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to write
-- *
-- * Read @len bytes to @buffer from the I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlFileRead (void * context, char * buffer, int len) {
-- return(fread(&buffer[0], 1, len, (FILE *) context));
--}
--
--/**
-- * xmlFileWrite:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to write
-- *
-- * Write @len bytes from @buffer to the I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlFileWrite (void * context, const char * buffer, int len) {
-- return(fwrite(&buffer[0], 1, len, (FILE *) context));
--}
--
--/**
-- * xmlFileClose:
-- * @context: the I/O context
-- *
-- * Close an I/O channel
-- */
--void
--xmlFileClose (void * context) {
-- fclose((FILE *) context);
--}
--
--/**
-- * xmlFileFlush:
-- * @context: the I/O context
-- *
-- * Flush an I/O channel
-- */
--void
--xmlFileFlush (void * context) {
-- fflush((FILE *) context);
--}
--
--#ifdef HAVE_ZLIB_H
--/************************************************************************
-- * *
-- * I/O for compressed file accesses *
-- * *
-- ************************************************************************/
--/**
-- * xmlGzfileMatch:
-- * @filename: the URI for matching
-- *
-- * input from compressed file test
-- *
-- * Returns 1 if matches, 0 otherwise
-- */
--int
--xmlGzfileMatch (const char *filename) {
-- return(1);
--}
--
--/**
-- * xmlGzfileOpen:
-- * @filename: the URI for matching
-- *
-- * input from compressed file open
-- * if @filename is " " then the standard input is used
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlGzfileOpen (const char *filename) {
-- const char *path = NULL;
-- gzFile fd;
--
-- if (!strcmp(filename, "-")) {
-- fd = gzdopen(fileno(stdin), "rb");
-- return((void *) fd);
-- }
--
-- if (!strncmp(filename, "file://localhost", 16))
-- path = &filename[16];
-- else if (!strncmp(filename, "file:///", 8))
-- path = &filename[7];
-- else
-- path = filename;
--
-- if (path == NULL)
-- return(NULL);
-- if (!xmlCheckFilename(path))
-- return(NULL);
--
-- fd = gzopen(path, "rb");
-- return((void *) fd);
--}
--
--/**
-- * xmlGzfileOpenW:
-- * @filename: the URI for matching
-- * @compression: the compression factor (0 - 9 included)
-- *
-- * input from compressed file open
-- * if @filename is " " then the standard input is used
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlGzfileOpenW (const char *filename, int compression) {
-- const char *path = NULL;
-- char mode[15];
-- gzFile fd;
--
-- sprintf(mode, "wb%d", compression);
-- if (!strcmp(filename, "-")) {
-- fd = gzdopen(1, mode);
-- return((void *) fd);
-- }
--
-- if (!strncmp(filename, "file://localhost", 16))
-- path = &filename[16];
-- else if (!strncmp(filename, "file:///", 8))
-- path = &filename[8];
-- else
-- path = filename;
--
-- if (path == NULL)
-- return(NULL);
--
-- fd = gzopen(path, mode);
-- return((void *) fd);
--}
--
--/**
-- * xmlGzfileRead:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to write
-- *
-- * Read @len bytes to @buffer from the compressed I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlGzfileRead (void * context, char * buffer, int len) {
-- return(gzread((gzFile) context, &buffer[0], len));
--}
--
--/**
-- * xmlGzfileWrite:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to write
-- *
-- * Write @len bytes from @buffer to the compressed I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlGzfileWrite (void * context, const char * buffer, int len) {
-- return(gzwrite((gzFile) context, (char *) &buffer[0], len));
--}
--
--/**
-- * xmlGzfileClose:
-- * @context: the I/O context
-- *
-- * Close a compressed I/O channel
-- */
--void
--xmlGzfileClose (void * context) {
-- gzclose((gzFile) context);
--}
--#endif /* HAVE_ZLIB_H */
--
--#ifdef LIBXML_HTTP_ENABLED
--/************************************************************************
-- * *
-- * I/O for HTTP file accesses *
-- * *
-- ************************************************************************/
--/**
-- * xmlIOHTTPMatch:
-- * @filename: the URI for matching
-- *
-- * check if the URI matches an HTTP one
-- *
-- * Returns 1 if matches, 0 otherwise
-- */
--int
--xmlIOHTTPMatch (const char *filename) {
-- if (!strncmp(filename, "http://", 7))
-- return(1);
-- return(0);
--}
--
--/**
-- * xmlIOHTTPOpen:
-- * @filename: the URI for matching
-- *
-- * open an HTTP I/O channel
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlIOHTTPOpen (const char *filename) {
-- return(xmlNanoHTTPOpen(filename, NULL));
--}
--
--/**
-- * xmlIOHTTPRead:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to write
-- *
-- * Read @len bytes to @buffer from the I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlIOHTTPRead(void * context, char * buffer, int len) {
-- return(xmlNanoHTTPRead(context, &buffer[0], len));
--}
--
--/**
-- * xmlIOHTTPClose:
-- * @context: the I/O context
-- *
-- * Close an HTTP I/O channel
-- */
--void
--xmlIOHTTPClose (void * context) {
-- xmlNanoHTTPClose(context);
--}
--#endif /* LIBXML_HTTP_ENABLED */
--
--#ifdef LIBXML_FTP_ENABLED
--/************************************************************************
-- * *
-- * I/O for FTP file accesses *
-- * *
-- ************************************************************************/
--/**
-- * xmlIOFTPMatch:
-- * @filename: the URI for matching
-- *
-- * check if the URI matches an FTP one
-- *
-- * Returns 1 if matches, 0 otherwise
-- */
--int
--xmlIOFTPMatch (const char *filename) {
-- if (!strncmp(filename, "ftp://", 6))
-- return(1);
-- return(0);
--}
--
--/**
-- * xmlIOFTPOpen:
-- * @filename: the URI for matching
-- *
-- * open an FTP I/O channel
-- *
-- * Returns an I/O context or NULL in case of error
-- */
--void *
--xmlIOFTPOpen (const char *filename) {
-- return(xmlNanoFTPOpen(filename));
--}
--
--/**
-- * xmlIOFTPRead:
-- * @context: the I/O context
-- * @buffer: where to drop data
-- * @len: number of bytes to write
-- *
-- * Read @len bytes to @buffer from the I/O channel.
-- *
-- * Returns the number of bytes written
-- */
--int
--xmlIOFTPRead(void * context, char * buffer, int len) {
-- return(xmlNanoFTPRead(context, &buffer[0], len));
--}
--
--/**
-- * xmlIOFTPClose:
-- * @context: the I/O context
-- *
-- * Close an FTP I/O channel
-- */
--void
--xmlIOFTPClose (void * context) {
-- xmlNanoFTPClose(context);
--}
--#endif /* LIBXML_FTP_ENABLED */
--
--
--/**
-- * xmlRegisterInputCallbacks:
-- * @match: the xmlInputMatchCallback
-- * @open: the xmlInputOpenCallback
-- * @read: the xmlInputReadCallback
-- * @close: the xmlInputCloseCallback
-- *
-- * Register a new set of I/O callback for handling parser input.
-- *
-- * Returns the registered handler number or -1 in case of error
-- */
--int
--xmlRegisterInputCallbacks(xmlInputMatchCallback match,
-- xmlInputOpenCallback open, xmlInputReadCallback read,
-- xmlInputCloseCallback close) {
-- if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) {
-- return(-1);
-- }
-- xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = match;
-- xmlInputCallbackTable[xmlInputCallbackNr].opencallback = open;
-- xmlInputCallbackTable[xmlInputCallbackNr].readcallback = read;
-- xmlInputCallbackTable[xmlInputCallbackNr].closecallback = close;
-- return(xmlInputCallbackNr++);
--}
--
--/**
-- * xmlRegisterOutputCallbacks:
-- * @match: the xmlOutputMatchCallback
-- * @open: the xmlOutputOpenCallback
-- * @write: the xmlOutputWriteCallback
-- * @close: the xmlOutputCloseCallback
-- *
-- * Register a new set of I/O callback for handling output.
-- *
-- * Returns the registered handler number or -1 in case of error
-- */
--int
--xmlRegisterOutputCallbacks(xmlOutputMatchCallback match,
-- xmlOutputOpenCallback open, xmlOutputWriteCallback write,
-- xmlOutputCloseCallback close) {
-- if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) {
-- return(-1);
-- }
-- xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = match;
-- xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = open;
-- xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = write;
-- xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = close;
-- return(xmlOutputCallbackNr++);
--}
--
--/**
-- * xmlRegisterDefaultInputCallbacks:
-- *
-- * Registers the default compiled-in I/O handlers.
-- */
--void
--#ifdef VMS
--xmlRegisterDefInputCallbacks
--#else
--xmlRegisterDefaultInputCallbacks
--#endif
--(void) {
-- if (xmlInputCallbackInitialized)
-- return;
--
-- xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
-- xmlFileRead, xmlFileClose);
--#ifdef HAVE_ZLIB_H
-- xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
-- xmlGzfileRead, xmlGzfileClose);
--#endif /* HAVE_ZLIB_H */
--
--#ifdef LIBXML_HTTP_ENABLED
-- xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
-- xmlIOHTTPRead, xmlIOHTTPClose);
--#endif /* LIBXML_HTTP_ENABLED */
--
--#ifdef LIBXML_FTP_ENABLED
-- xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
-- xmlIOFTPRead, xmlIOFTPClose);
--#endif /* LIBXML_FTP_ENABLED */
-- xmlInputCallbackInitialized = 1;
--}
--
--/**
-- * xmlRegisterDefaultOutputCallbacks:
-- *
-- * Registers the default compiled-in I/O handlers.
-- */
--void
--#ifdef VMS
--xmlRegisterDefOutputCallbacks
--#else
--xmlRegisterDefaultOutputCallbacks
--#endif
--(void) {
-- if (xmlOutputCallbackInitialized)
-- return;
--
-- xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
-- xmlFileWrite, xmlFileClose);
--/*********************************
-- No way a-priori to distinguish between gzipped files from
-- uncompressed ones except opening if existing then closing
-- and saving with same compression ratio ... a pain.
--
--#ifdef HAVE_ZLIB_H
-- xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
-- xmlGzfileWrite, xmlGzfileClose);
--#endif
-- No HTTP PUT support yet, patches welcome
--
--#ifdef LIBXML_HTTP_ENABLED
-- xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
-- xmlIOHTTPWrite, xmlIOHTTPClose);
--#endif
--
-- Nor FTP PUT ....
--#ifdef LIBXML_FTP_ENABLED
-- xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
-- xmlIOFTPWrite, xmlIOFTPClose);
--#endif
-- **********************************/
-- xmlOutputCallbackInitialized = 1;
--}
--
--/**
-- * xmlAllocParserInputBuffer:
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered parser input for progressive parsing
-- *
-- * Returns the new parser input or NULL
-- */
--xmlParserInputBufferPtr
--xmlAllocParserInputBuffer(xmlCharEncoding enc) {
-- xmlParserInputBufferPtr ret;
--
-- ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAllocParserInputBuffer : out of memory!\n");
-- return(NULL);
-- }
-- memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
-- ret->buffer = xmlBufferCreate();
-- if (ret->buffer == NULL) {
-- xmlFree(ret);
-- return(NULL);
-- }
-- ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
-- ret->encoder = xmlGetCharEncodingHandler(enc);
-- if (ret->encoder != NULL)
-- ret->raw = xmlBufferCreate();
-- else
-- ret->raw = NULL;
-- ret->readcallback = NULL;
-- ret->closecallback = NULL;
-- ret->context = NULL;
--
-- return(ret);
--}
--
--/**
-- * xmlAllocOutputBuffer:
-- * @encoder: the encoding converter or NULL
-- *
-- * Create a buffered parser output
-- *
-- * Returns the new parser output or NULL
-- */
--xmlOutputBufferPtr
--xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
-- xmlOutputBufferPtr ret;
--
-- ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlAllocOutputBuffer : out of memory!\n");
-- return(NULL);
-- }
-- memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
-- ret->buffer = xmlBufferCreate();
-- if (ret->buffer == NULL) {
-- xmlFree(ret);
-- return(NULL);
-- }
-- ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
-- ret->encoder = encoder;
-- if (encoder != NULL) {
-- ret->conv = xmlBufferCreateSize(4000);
-- /*
-- * This call is designed to initiate the encoder state
-- */
-- xmlCharEncOutFunc(encoder, ret->conv, NULL);
-- } else
-- ret->conv = NULL;
-- ret->writecallback = NULL;
-- ret->closecallback = NULL;
-- ret->context = NULL;
-- ret->written = 0;
--
-- return(ret);
--}
--
--/**
-- * xmlFreeParserInputBuffer:
-- * @in: a buffered parser input
-- *
-- * Free up the memory used by a buffered parser input
-- */
--void
--xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) {
-- if (in->raw) {
-- xmlBufferFree(in->raw);
-- in->raw = NULL;
-- }
-- if (in->encoder != NULL) {
-- xmlCharEncCloseFunc(in->encoder);
-- }
-- if (in->closecallback != NULL) {
-- in->closecallback(in->context);
-- }
-- if (in->buffer != NULL) {
-- xmlBufferFree(in->buffer);
-- in->buffer = NULL;
-- }
--
-- memset(in, 0xbe, (size_t) sizeof(xmlParserInputBuffer));
-- xmlFree(in);
--}
--
--/**
-- * xmlOutputBufferClose:
-- * @out: a buffered output
-- *
-- * flushes and close the output I/O channel
-- * and free up all the associated resources
-- *
-- * Returns the number of byte written or -1 in case of error.
-- */
--int
--xmlOutputBufferClose(xmlOutputBufferPtr out) {
-- int written;
--
-- if (out == NULL)
-- return(-1);
-- if (out->writecallback != NULL)
-- xmlOutputBufferFlush(out);
-- if (out->closecallback != NULL) {
-- out->closecallback(out->context);
-- }
-- written = out->written;
-- if (out->conv) {
-- xmlBufferFree(out->conv);
-- out->conv = NULL;
-- }
-- if (out->encoder != NULL) {
-- xmlCharEncCloseFunc(out->encoder);
-- }
-- if (out->buffer != NULL) {
-- xmlBufferFree(out->buffer);
-- out->buffer = NULL;
-- }
--
-- memset(out, 0xbe, (size_t) sizeof(xmlOutputBuffer));
-- xmlFree(out);
-- return(written);
--}
--
--/**
-- * xmlParserInputBufferCreateFilename:
-- * @URI: a C string containing the URI or filename
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered parser input for the progressive parsing of a file
-- * If filename is "-' then we use stdin as the input.
-- * Automatic support for ZLIB/Compress compressed document is provided
-- * by default if found at compile-time.
-- * Do an encoding check if enc == XML_CHAR_ENCODING_NONE
-- *
-- * Returns the new parser input or NULL
-- */
--xmlParserInputBufferPtr
--#ifdef VMS
--xmlParserInputBufferCreateFname
--#else
--xmlParserInputBufferCreateFilename
--#endif
--(const char *URI, xmlCharEncoding enc) {
-- xmlParserInputBufferPtr ret;
-- int i;
-- void *context = NULL;
--
-- if (xmlInputCallbackInitialized == 0)
-- xmlRegisterDefaultInputCallbacks();
--
-- if (URI == NULL) return(NULL);
--
-- /*
-- * Try to find one of the input accept method accepting taht scheme
-- * Go in reverse to give precedence to user defined handlers.
-- */
-- for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
-- if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
-- (xmlInputCallbackTable[i].matchcallback(URI) != 0)) {
-- context = xmlInputCallbackTable[i].opencallback(URI);
-- if (context != NULL)
-- break;
-- }
-- }
-- if (context == NULL) {
-- return(NULL);
-- }
--
-- /*
-- * Allocate the Input buffer front-end.
-- */
-- ret = xmlAllocParserInputBuffer(enc);
-- if (ret != NULL) {
-- ret->context = context;
-- ret->readcallback = xmlInputCallbackTable[i].readcallback;
-- ret->closecallback = xmlInputCallbackTable[i].closecallback;
-- }
-- return(ret);
--}
--
--/**
-- * xmlOutputBufferCreateFilename:
-- * @URI: a C string containing the URI or filename
-- * @encoder: the encoding converter or NULL
-- * @compression: the compression ration (0 none, 9 max).
-- *
-- * Create a buffered output for the progressive saving of a file
-- * If filename is "-' then we use stdout as the output.
-- * Automatic support for ZLIB/Compress compressed document is provided
-- * by default if found at compile-time.
-- * TODO: currently if compression is set, the library only support
-- * writing to a local file.
-- *
-- * Returns the new output or NULL
-- */
--xmlOutputBufferPtr
--xmlOutputBufferCreateFilename(const char *URI,
-- xmlCharEncodingHandlerPtr encoder,
-- int compression) {
-- xmlOutputBufferPtr ret;
-- int i;
-- void *context = NULL;
--
-- if (xmlOutputCallbackInitialized == 0)
-- xmlRegisterDefaultOutputCallbacks();
--
-- if (URI == NULL) return(NULL);
--
--#ifdef HAVE_ZLIB_H
-- if ((compression > 0) && (compression <= 9)) {
-- context = xmlGzfileOpenW(URI, compression);
-- if (context != NULL) {
-- ret = xmlAllocOutputBuffer(encoder);
-- if (ret != NULL) {
-- ret->context = context;
-- ret->writecallback = xmlGzfileWrite;
-- ret->closecallback = xmlGzfileClose;
-- }
-- return(ret);
-- }
-- }
--#endif
--
-- /*
-- * Try to find one of the output accept method accepting taht scheme
-- * Go in reverse to give precedence to user defined handlers.
-- */
-- for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
-- if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
-- (xmlOutputCallbackTable[i].matchcallback(URI) != 0)) {
-- context = xmlOutputCallbackTable[i].opencallback(URI);
-- if (context != NULL)
-- break;
-- }
-- }
-- if (context == NULL) {
-- return(NULL);
-- }
--
-- /*
-- * Allocate the Output buffer front-end.
-- */
-- ret = xmlAllocOutputBuffer(encoder);
-- if (ret != NULL) {
-- ret->context = context;
-- ret->writecallback = xmlOutputCallbackTable[i].writecallback;
-- ret->closecallback = xmlOutputCallbackTable[i].closecallback;
-- }
-- return(ret);
--}
--
--/**
-- * xmlParserInputBufferCreateFile:
-- * @file: a FILE*
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered parser input for the progressive parsing of a FILE *
-- * buffered C I/O
-- *
-- * Returns the new parser input or NULL
-- */
--xmlParserInputBufferPtr
--xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) {
-- xmlParserInputBufferPtr ret;
--
-- if (xmlInputCallbackInitialized == 0)
-- xmlRegisterDefaultInputCallbacks();
--
-- if (file == NULL) return(NULL);
--
-- ret = xmlAllocParserInputBuffer(enc);
-- if (ret != NULL) {
-- ret->context = file;
-- ret->readcallback = xmlFileRead;
-- ret->closecallback = xmlFileFlush;
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlOutputBufferCreateFile:
-- * @file: a FILE*
-- * @encoder: the encoding converter or NULL
-- *
-- * Create a buffered output for the progressive saving to a FILE *
-- * buffered C I/O
-- *
-- * Returns the new parser output or NULL
-- */
--xmlOutputBufferPtr
--xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
-- xmlOutputBufferPtr ret;
--
-- if (xmlOutputCallbackInitialized == 0)
-- xmlRegisterDefaultOutputCallbacks();
--
-- if (file == NULL) return(NULL);
--
-- ret = xmlAllocOutputBuffer(encoder);
-- if (ret != NULL) {
-- ret->context = file;
-- ret->writecallback = xmlFileWrite;
-- ret->closecallback = xmlFileFlush;
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlParserInputBufferCreateFd:
-- * @fd: a file descriptor number
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered parser input for the progressive parsing for the input
-- * from a file descriptor
-- *
-- * Returns the new parser input or NULL
-- */
--xmlParserInputBufferPtr
--xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
-- xmlParserInputBufferPtr ret;
--
-- if (fd < 0) return(NULL);
--
-- ret = xmlAllocParserInputBuffer(enc);
-- if (ret != NULL) {
-- ret->context = (void *) fd;
-- ret->readcallback = xmlFdRead;
-- ret->closecallback = xmlFdClose;
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlParserInputBufferCreateMem:
-- * @mem: the memory input
-- * @size: the length of the memory block
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered parser input for the progressive parsing for the input
-- * from a memory area.
-- *
-- * Returns the new parser input or NULL
-- */
--xmlParserInputBufferPtr
--xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
-- xmlParserInputBufferPtr ret;
--
-- if (size <= 0) return(NULL);
-- if (mem == NULL) return(NULL);
--
-- ret = xmlAllocParserInputBuffer(enc);
-- if (ret != NULL) {
-- ret->context = (void *) mem;
-- ret->readcallback = (xmlInputReadCallback) xmlNop;
-- ret->closecallback = NULL;
-- xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size);
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlOutputBufferCreateFd:
-- * @fd: a file descriptor number
-- * @encoder: the encoding converter or NULL
-- *
-- * Create a buffered output for the progressive saving
-- * to a file descriptor
-- *
-- * Returns the new parser output or NULL
-- */
--xmlOutputBufferPtr
--xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
-- xmlOutputBufferPtr ret;
--
-- if (fd < 0) return(NULL);
--
-- ret = xmlAllocOutputBuffer(encoder);
-- if (ret != NULL) {
-- ret->context = (void *) fd;
-- ret->writecallback = xmlFdWrite;
-- ret->closecallback = xmlFdClose;
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlParserInputBufferCreateIO:
-- * @ioread: an I/O read function
-- * @ioclose: an I/O close function
-- * @ioctx: an I/O handler
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered parser input for the progressive parsing for the input
-- * from an I/O handler
-- *
-- * Returns the new parser input or NULL
-- */
--xmlParserInputBufferPtr
--xmlParserInputBufferCreateIO(xmlInputReadCallback ioread,
-- xmlInputCloseCallback ioclose, void *ioctx, xmlCharEncoding enc) {
-- xmlParserInputBufferPtr ret;
--
-- if (ioread == NULL) return(NULL);
--
-- ret = xmlAllocParserInputBuffer(enc);
-- if (ret != NULL) {
-- ret->context = (void *) ioctx;
-- ret->readcallback = ioread;
-- ret->closecallback = ioclose;
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlOutputBufferCreateIO:
-- * @iowrite: an I/O write function
-- * @ioclose: an I/O close function
-- * @ioctx: an I/O handler
-- * @enc: the charset encoding if known
-- *
-- * Create a buffered output for the progressive saving
-- * to an I/O handler
-- *
-- * Returns the new parser output or NULL
-- */
--xmlOutputBufferPtr
--xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite,
-- xmlOutputCloseCallback ioclose, void *ioctx,
-- xmlCharEncodingHandlerPtr encoder) {
-- xmlOutputBufferPtr ret;
--
-- if (iowrite == NULL) return(NULL);
--
-- ret = xmlAllocOutputBuffer(encoder);
-- if (ret != NULL) {
-- ret->context = (void *) ioctx;
-- ret->writecallback = iowrite;
-- ret->closecallback = ioclose;
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlParserInputBufferPush:
-- * @in: a buffered parser input
-- * @len: the size in bytes of the array.
-- * @buf: an char array
-- *
-- * Push the content of the arry in the input buffer
-- * This routine handle the I18N transcoding to internal UTF-8
-- * This is used when operating the parser in progressive (push) mode.
-- *
-- * Returns the number of chars read and stored in the buffer, or -1
-- * in case of error.
-- */
--int
--xmlParserInputBufferPush(xmlParserInputBufferPtr in,
-- int len, const char *buf) {
-- int nbchars = 0;
--
-- if (len < 0) return(0);
-- if (in->encoder != NULL) {
-- /*
-- * Store the data in the incoming raw buffer
-- */
-- if (in->raw == NULL) {
-- in->raw = xmlBufferCreate();
-- }
-- xmlBufferAdd(in->raw, (const xmlChar *) buf, len);
--
-- /*
-- * convert as much as possible to the parser reading buffer.
-- */
-- nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-- if (nbchars < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInputBufferPush: encoder error\n");
-- return(-1);
-- }
-- } else {
-- nbchars = len;
-- xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
-- }
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext,
-- "I/O: pushed %d chars, buffer %d/%d\n",
-- nbchars, in->buffer->use, in->buffer->size);
--#endif
-- return(nbchars);
--}
--
--/**
-- * xmlParserInputBufferGrow:
-- * @in: a buffered parser input
-- * @len: indicative value of the amount of chars to read
-- *
-- * Grow up the content of the input buffer, the old data are preserved
-- * This routine handle the I18N transcoding to internal UTF-8
-- * This routine is used when operating the parser in normal (pull) mode
-- *
-- * TODO: one should be able to remove one extra copy by copying directy
-- * onto in->buffer or in->raw
-- *
-- * Returns the number of chars read and stored in the buffer, or -1
-- * in case of error.
-- */
--int
--xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
-- char *buffer = NULL;
-- int res = 0;
-- int nbchars = 0;
-- int buffree;
--
-- if ((len <= MINLEN) && (len != 4))
-- len = MINLEN;
-- buffree = in->buffer->size - in->buffer->use;
-- if (buffree <= 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInputBufferGrow : buffer full !\n");
-- return(0);
-- }
-- if (len > buffree)
-- len = buffree;
--
-- buffer = (char *) xmlMalloc((len + 1) * sizeof(char));
-- if (buffer == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInputBufferGrow : out of memory !\n");
-- return(-1);
-- }
--
-- /*
-- * Call the read method for this I/O type.
-- */
-- if (in->readcallback != NULL) {
-- res = in->readcallback(in->context, &buffer[0], len);
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInputBufferGrow : no input !\n");
-- xmlFree(buffer);
-- return(-1);
-- }
-- if (res < 0) {
-- perror ("read error");
-- xmlFree(buffer);
-- return(-1);
-- }
-- len = res;
-- if (in->encoder != NULL) {
-- /*
-- * Store the data in the incoming raw buffer
-- */
-- if (in->raw == NULL) {
-- in->raw = xmlBufferCreate();
-- }
-- xmlBufferAdd(in->raw, (const xmlChar *) buffer, len);
--
-- /*
-- * convert as much as possible to the parser reading buffer.
-- */
-- nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-- if (nbchars < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlParserInputBufferGrow: encoder error\n");
-- return(-1);
-- }
-- } else {
-- nbchars = len;
-- buffer[nbchars] = 0;
-- xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars);
-- }
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext,
-- "I/O: read %d chars, buffer %d/%d\n",
-- nbchars, in->buffer->use, in->buffer->size);
--#endif
-- xmlFree(buffer);
-- return(nbchars);
--}
--
--/**
-- * xmlParserInputBufferRead:
-- * @in: a buffered parser input
-- * @len: indicative value of the amount of chars to read
-- *
-- * Refresh the content of the input buffer, the old data are considered
-- * consumed
-- * This routine handle the I18N transcoding to internal UTF-8
-- *
-- * Returns the number of chars read and stored in the buffer, or -1
-- * in case of error.
-- */
--int
--xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) {
-- /* xmlBufferEmpty(in->buffer); */
-- if (in->readcallback != NULL)
-- return(xmlParserInputBufferGrow(in, len));
-- else
-- return(-1);
--}
--
--/**
-- * xmlOutputBufferWrite:
-- * @out: a buffered parser output
-- * @len: the size in bytes of the array.
-- * @buf: an char array
-- *
-- * Write the content of the array in the output I/O buffer
-- * This routine handle the I18N transcoding from internal UTF-8
-- * The buffer is lossless, i.e. will store in case of partial
-- * or delayed writes.
-- *
-- * Returns the number of chars immediately written, or -1
-- * in case of error.
-- */
--int
--xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
-- int nbchars = 0; /* number of chars to output to I/O */
-- int ret; /* return from function call */
-- int written = 0; /* number of char written to I/O so far */
-- int chunk; /* number of byte curreent processed from buf */
--
-- if (len < 0) return(0);
--
-- do {
-- chunk = len;
-- if (chunk > 4 * MINLEN)
-- chunk = 4 * MINLEN;
--
-- /*
-- * first handle encoding stuff.
-- */
-- if (out->encoder != NULL) {
-- /*
-- * Store the data in the incoming raw buffer
-- */
-- if (out->conv == NULL) {
-- out->conv = xmlBufferCreate();
-- }
-- xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
--
-- if ((out->buffer->use < MINLEN) && (chunk == len))
-- goto done;
--
-- /*
-- * convert as much as possible to the parser reading buffer.
-- */
-- ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
-- if (ret < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlOutputBufferWrite: encoder error\n");
-- return(-1);
-- }
-- nbchars = out->conv->use;
-- } else {
-- xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
-- nbchars = out->buffer->use;
-- }
-- buf += chunk;
-- len -= chunk;
--
-- if ((nbchars < MINLEN) && (len <= 0))
-- goto done;
--
-- if (out->writecallback) {
-- /*
-- * second write the stuff to the I/O channel
-- */
-- if (out->encoder != NULL) {
-- ret = out->writecallback(out->context,
-- (const char *)out->conv->content, nbchars);
-- if (ret >= 0)
-- xmlBufferShrink(out->conv, nbchars);
-- } else {
-- ret = out->writecallback(out->context,
-- (const char *)out->buffer->content, nbchars);
-- if (ret >= 0)
-- xmlBufferShrink(out->buffer, nbchars);
-- }
-- if (ret < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "I/O: error %d writing %d bytes\n", ret, nbchars);
-- return(ret);
-- }
-- out->written += ret;
-- }
-- written += nbchars;
-- } while (len > 0);
--
--done:
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext,
-- "I/O: wrote %d chars\n", written);
--#endif
-- return(written);
--}
--
--/**
-- * xmlOutputBufferWriteString:
-- * @out: a buffered parser output
-- * @str: a zero terminated C string
-- *
-- * Write the content of the string in the output I/O buffer
-- * This routine handle the I18N transcoding from internal UTF-8
-- * The buffer is lossless, i.e. will store in case of partial
-- * or delayed writes.
-- *
-- * Returns the number of chars immediately written, or -1
-- * in case of error.
-- */
--int
--xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
-- int len;
--
-- if (str == NULL)
-- return(-1);
-- len = strlen(str);
--
-- if (len > 0)
-- return(xmlOutputBufferWrite(out, len, str));
-- return(len);
--}
--
--/**
-- * xmlOutputBufferFlush:
-- * @out: a buffered output
-- *
-- * flushes the output I/O channel
-- *
-- * Returns the number of byte written or -1 in case of error.
-- */
--int
--xmlOutputBufferFlush(xmlOutputBufferPtr out) {
-- int nbchars = 0, ret = 0;
--
-- /*
-- * first handle encoding stuff.
-- */
-- if ((out->conv != NULL) && (out->encoder != NULL)) {
-- /*
-- * convert as much as possible to the parser reading buffer.
-- */
-- nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
-- if (nbchars < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlOutputBufferWrite: encoder error\n");
-- return(-1);
-- }
-- }
--
-- /*
-- * second flush the stuff to the I/O channel
-- */
-- if ((out->conv != NULL) && (out->encoder != NULL) &&
-- (out->writecallback != NULL)) {
-- ret = out->writecallback(out->context,
-- (const char *)out->conv->content, out->conv->use);
-- if (ret >= 0)
-- xmlBufferShrink(out->conv, ret);
-- } else if (out->writecallback != NULL) {
-- ret = out->writecallback(out->context,
-- (const char *)out->buffer->content, out->buffer->use);
-- if (ret >= 0)
-- xmlBufferShrink(out->buffer, ret);
-- }
-- if (ret < 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "I/O: error %d flushing %d bytes\n", ret, nbchars);
-- return(ret);
-- }
-- out->written += ret;
--
--#ifdef DEBUG_INPUT
-- xmlGenericError(xmlGenericErrorContext,
-- "I/O: flushed %d chars\n", ret);
--#endif
-- return(ret);
--}
--
--/*
-- * xmlParserGetDirectory:
-- * @filename: the path to a file
-- *
-- * lookup the directory for that file
-- *
-- * Returns a new allocated string containing the directory, or NULL.
-- */
--char *
--xmlParserGetDirectory(const char *filename) {
-- char *ret = NULL;
-- char dir[1024];
-- char *cur;
-- char sep = '/';
--
-- if (xmlInputCallbackInitialized == 0)
-- xmlRegisterDefaultInputCallbacks();
--
-- if (filename == NULL) return(NULL);
--#ifdef WIN32
-- sep = '\\';
--#endif
--
-- strncpy(dir, filename, 1023);
-- dir[1023] = 0;
-- cur = &dir[strlen(dir)];
-- while (cur > dir) {
-- if (*cur == sep) break;
-- cur --;
-- }
-- if (*cur == sep) {
-- if (cur == dir) dir[1] = 0;
-- else *cur = 0;
-- ret = xmlMemStrdup(dir);
-- } else {
-- if (getcwd(dir, 1024) != NULL) {
-- dir[1023] = 0;
-- ret = xmlMemStrdup(dir);
-- }
-- }
-- return(ret);
--}
--
--/****************************************************************
-- * *
-- * External entities loading *
-- * *
-- ****************************************************************/
--
--/*
-- * xmlDefaultExternalEntityLoader:
-- * @URL: the URL for the entity to load
-- * @ID: the System ID for the entity to load
-- * @ctxt: the context in which the entity is called or NULL
-- *
-- * By default we don't load external entitites, yet.
-- *
-- * Returns a new allocated xmlParserInputPtr, or NULL.
-- */
--static
--xmlParserInputPtr
--xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
-- xmlParserCtxtPtr ctxt) {
-- xmlParserInputPtr ret = NULL;
--
--#ifdef DEBUG_EXTERNAL_ENTITIES
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
--#endif
-- if (URL == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt,
-- "failed to load external entity \"%s\"\n", ID);
-- return(NULL);
-- }
-- ret = xmlNewInputFromFile(ctxt, URL);
-- if (ret == NULL) {
-- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
-- ctxt->sax->warning(ctxt,
-- "failed to load external entity \"%s\"\n", URL);
-- }
-- return(ret);
--}
--
--static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
-- xmlDefaultExternalEntityLoader;
--
--/*
-- * xmlSetExternalEntityLoader:
-- * @f: the new entity resolver function
-- *
-- * Changes the defaultexternal entity resolver function for the application
-- */
--void
--xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
-- xmlCurrentExternalEntityLoader = f;
--}
--
--/*
-- * xmlGetExternalEntityLoader:
-- *
-- * Get the default external entity resolver function for the application
-- *
-- * Returns the xmlExternalEntityLoader function pointer
-- */
--xmlExternalEntityLoader
--xmlGetExternalEntityLoader(void) {
-- return(xmlCurrentExternalEntityLoader);
--}
--
--/*
-- * xmlLoadExternalEntity:
-- * @URL: the URL for the entity to load
-- * @ID: the System ID for the entity to load
-- * @ctxt: the context in which the entity is called or NULL
-- *
-- * Load an external entity, note that the use of this function for
-- * unparsed entities may generate problems
-- * TODO: a more generic External entitiy API must be designed
-- *
-- * Returns the xmlParserInputPtr or NULL
-- */
--xmlParserInputPtr
--xmlLoadExternalEntity(const char *URL, const char *ID,
-- xmlParserCtxtPtr ctxt) {
-- return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));
--}
--
-diff -Nru libxml2-2.3.0/xmlmemory.c libxml2-2.3.0.new/xmlmemory.c
---- libxml2-2.3.0/xmlmemory.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xmlmemory.c Thu Jan 1 01:00:00 1970
-@@ -1,707 +0,0 @@
--/*
-- * memory.c: libxml memory allocator wrapper.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <stdio.h>
--#include <string.h>
--
--#ifdef HAVE_SYS_TYPES_H
--#include <sys/types.h>
--#endif
--#ifdef HAVE_TIME_H
--#include <time.h>
--#endif
--#ifdef HAVE_MALLOC_H
--#include <malloc.h>
--#endif
--#ifdef HAVE_STDLIB_H
--#include <stdlib.h>
--#endif
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--
--
--#include <libxml/xmlmemory.h>
--#include <libxml/xmlerror.h>
--
--#ifdef xmlMalloc
--#undef xmlMalloc
--#endif
--#ifdef xmlRealloc
--#undef xmlRealloc
--#endif
--#ifdef xmlMemStrdup
--#undef xmlMemStrdup
--#endif
--
--
--/*
-- * Each of the blocks allocated begin with a header containing informations
-- */
--
--#define MEMTAG 0x5aa5
--
--#define MALLOC_TYPE 1
--#define REALLOC_TYPE 2
--#define STRDUP_TYPE 3
--
--typedef struct memnod {
-- unsigned int mh_tag;
-- unsigned int mh_type;
-- unsigned long mh_number;
-- size_t mh_size;
--#ifdef MEM_LIST
-- struct memnod *mh_next;
-- struct memnod *mh_prev;
--#endif
-- const char *mh_file;
-- unsigned int mh_line;
--} MEMHDR;
--
--
--#ifdef SUN4
--#define ALIGN_SIZE 16
--#else
--#define ALIGN_SIZE sizeof(double)
--#endif
--#define HDR_SIZE sizeof(MEMHDR)
--#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
-- / ALIGN_SIZE ) * ALIGN_SIZE)
--
--
--#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
--#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
--
--
--static unsigned long debugMemSize = 0;
--static unsigned long debugMaxMemSize = 0;
--static int block=0;
--int xmlMemStopAtBlock = 0;
--int xmlMemInitialized = 0;
--#ifdef MEM_LIST
--static MEMHDR *memlist = NULL;
--#endif
--
--void debugmem_tag_error(void *addr);
--#ifdef MEM_LIST
--void debugmem_list_add(MEMHDR *);
--void debugmem_list_delete(MEMHDR *);
--#endif
--#define Mem_Tag_Err(a) debugmem_tag_error(a);
--
--#ifndef TEST_POINT
--#define TEST_POINT
--#endif
--
--/**
-- * xmlMallocBreakpoint:
-- *
-- * Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
-- * number reaches the specified value this function is called. One need to add a breakpoint
-- * to it to get the context in which the given block is allocated.
-- */
--
--void
--xmlMallocBreakpoint(void) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
--}
--
--/**
-- * xmlMallocLoc:
-- * @size: an int specifying the size in byte to allocate.
-- * @file: the file name or NULL
-- * @line: the line number
-- *
-- * a malloc() equivalent, with logging of the allocation info.
-- *
-- * Returns a pointer to the allocated area or NULL in case of lack of memory.
-- */
--
--void *
--xmlMallocLoc(int size, const char * file, int line)
--{
-- MEMHDR *p;
--
-- if (!xmlMemInitialized) xmlInitMemory();
--#ifdef DEBUG_MEMORY
-- xmlGenericError(xmlGenericErrorContext,
-- "Malloc(%d)\n",size);
--#endif
--
-- TEST_POINT
--
-- p = (MEMHDR *) malloc(RESERVE_SIZE+size);
--
-- if (!p) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlMalloc : Out of free space\n");
-- xmlMemoryDump();
-- return(NULL);
-- }
-- p->mh_tag = MEMTAG;
-- p->mh_number = ++block;
-- p->mh_size = size;
-- p->mh_type = MALLOC_TYPE;
-- p->mh_file = file;
-- p->mh_line = line;
-- debugMemSize += size;
-- if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
--#ifdef MEM_LIST
-- debugmem_list_add(p);
--#endif
--
--#ifdef DEBUG_MEMORY
-- xmlGenericError(xmlGenericErrorContext,
-- "Malloc(%d) Ok\n",size);
--#endif
--
-- if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
--
-- TEST_POINT
--
-- return(HDR_2_CLIENT(p));
--}
--
--/**
-- * xmlMemMalloc:
-- * @size: an int specifying the size in byte to allocate.
-- *
-- * a malloc() equivalent, with logging of the allocation info.
-- *
-- * Returns a pointer to the allocated area or NULL in case of lack of memory.
-- */
--
--void *
--xmlMemMalloc(int size)
--{
-- return(xmlMallocLoc(size, "none", 0));
--}
--
--/**
-- * xmlReallocLoc:
-- * @ptr: the initial memory block pointer
-- * @size: an int specifying the size in byte to allocate.
-- * @file: the file name or NULL
-- * @line: the line number
-- *
-- * a realloc() equivalent, with logging of the allocation info.
-- *
-- * Returns a pointer to the allocated area or NULL in case of lack of memory.
-- */
--
--void *
--xmlReallocLoc(void *ptr,int size, const char * file, int line)
--{
-- MEMHDR *p;
-- unsigned long number;
--
-- if (!xmlMemInitialized) xmlInitMemory();
-- TEST_POINT
--
-- p = CLIENT_2_HDR(ptr);
-- number = p->mh_number;
-- if (p->mh_tag != MEMTAG) {
-- Mem_Tag_Err(p);
-- goto error;
-- }
-- p->mh_tag = ~MEMTAG;
-- debugMemSize -= p->mh_size;
--#ifdef MEM_LIST
-- debugmem_list_delete(p);
--#endif
--
-- p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
-- if (!p) {
-- goto error;
-- }
-- p->mh_tag = MEMTAG;
-- p->mh_number = number;
-- p->mh_type = REALLOC_TYPE;
-- p->mh_size = size;
-- p->mh_file = file;
-- p->mh_line = line;
-- debugMemSize += size;
-- if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
--#ifdef MEM_LIST
-- debugmem_list_add(p);
--#endif
--
-- TEST_POINT
--
-- return(HDR_2_CLIENT(p));
--
--error:
-- return(NULL);
--}
--
--/**
-- * xmlMemRealloc:
-- * @ptr: the initial memory block pointer
-- * @size: an int specifying the size in byte to allocate.
-- *
-- * a realloc() equivalent, with logging of the allocation info.
-- *
-- * Returns a pointer to the allocated area or NULL in case of lack of memory.
-- */
--
--void *
--xmlMemRealloc(void *ptr,int size) {
-- return(xmlReallocLoc(ptr, size, "none", 0));
--}
--
--/**
-- * xmlMemFree:
-- * @ptr: the memory block pointer
-- *
-- * a free() equivalent, with error checking.
-- */
--void
--xmlMemFree(void *ptr)
--{
-- MEMHDR *p;
--
-- TEST_POINT
--
-- p = CLIENT_2_HDR(ptr);
-- if (p->mh_tag != MEMTAG) {
-- Mem_Tag_Err(p);
-- goto error;
-- }
-- p->mh_tag = ~MEMTAG;
-- debugMemSize -= p->mh_size;
--
--#ifdef MEM_LIST
-- debugmem_list_delete(p);
--#endif
-- free(p);
--
-- TEST_POINT
--
-- return;
--
--error:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlFree(%X) error\n", (unsigned int) ptr);
-- return;
--}
--
--/**
-- * xmlMemStrdupLoc:
-- * @ptr: the initial string pointer
-- * @file: the file name or NULL
-- * @line: the line number
-- *
-- * a strdup() equivalent, with logging of the allocation info.
-- *
-- * Returns a pointer to the new string or NULL if allocation error occured.
-- */
--
--char *
--xmlMemStrdupLoc(const char *str, const char *file, int line)
--{
-- char *s;
-- size_t size = strlen(str) + 1;
-- MEMHDR *p;
--
-- if (!xmlMemInitialized) xmlInitMemory();
-- TEST_POINT
--
-- p = (MEMHDR *) malloc(RESERVE_SIZE+size);
-- if (!p) {
-- goto error;
-- }
-- p->mh_tag = MEMTAG;
-- p->mh_number = ++block;
-- p->mh_size = size;
-- p->mh_type = STRDUP_TYPE;
-- p->mh_file = file;
-- p->mh_line = line;
-- debugMemSize += size;
-- if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
--#ifdef MEM_LIST
-- debugmem_list_add(p);
--#endif
-- s = (char *) HDR_2_CLIENT(p);
--
-- if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
--
-- if (s != NULL)
-- strcpy(s,str);
-- else
-- goto error;
--
-- TEST_POINT
--
-- return(s);
--
--error:
-- return(NULL);
--}
--
--/**
-- * xmlMemoryStrdup:
-- * @ptr: the initial string pointer
-- *
-- * a strdup() equivalent, with logging of the allocation info.
-- *
-- * Returns a pointer to the new string or NULL if allocation error occured.
-- */
--
--char *
--xmlMemoryStrdup(const char *str) {
-- return(xmlMemStrdupLoc(str, "none", 0));
--}
--
--/**
-- * xmlMemUsed:
-- *
-- * returns the amount of memory currenly allocated
-- *
-- * Returns an int representing the amount of memory allocated.
-- */
--
--int
--xmlMemUsed(void) {
-- return(debugMemSize);
--}
--
--#ifdef MEM_LIST
--/**
-- * xmlMemContentShow:
-- * @fp: a FILE descriptor used as the output file
-- * @p: a memory block header
-- *
-- * tries to show some content from the memory block
-- */
--
--void
--xmlMemContentShow(FILE *fp, MEMHDR *p)
--{
-- int i,j,len = p->mh_size;
-- const char *buf = (const char *) HDR_2_CLIENT(p);
--
-- if (p == NULL) {
-- fprintf(fp, " NULL");
-- return;
-- }
--
-- for (i = 0;i < len;i++) {
-- if (buf[i] == 0) break;
-- if (!isprint(buf[i])) break;
-- }
-- if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
-- if (len >= 4) {
-- MEMHDR *q;
-- void *cur;
--
-- for (j = 0;j < len -3;j += 4) {
-- cur = *((void **) &buf[j]);
-- q = CLIENT_2_HDR(cur);
-- p = memlist;
-- while (p != NULL) {
-- if (p == q) break;
-- p = p->mh_next;
-- }
-- if ((p != NULL) && (p == q)) {
-- fprintf(fp, " pointer to #%lu at index %d",
-- p->mh_number, j);
-- return;
-- }
-- }
-- }
-- } else if ((i == 0) && (buf[i] == 0)) {
-- fprintf(fp," null");
-- } else {
-- if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
-- else {
-- fprintf(fp," [");
-- for (j = 0;j < i;j++)
-- fprintf(fp,"%c", buf[j]);
-- fprintf(fp,"]");
-- }
-- }
--}
--#endif
--
--/**
-- * xmlMemShow:
-- * @fp: a FILE descriptor used as the output file
-- * @nr: number of entries to dump
-- *
-- * show a show display of the memory allocated, and dump
-- * the @nr last allocated areas which were not freed
-- */
--
--void
--xmlMemShow(FILE *fp, int nr)
--{
--#ifdef MEM_LIST
-- MEMHDR *p;
--#endif
--
-- if (fp != NULL)
-- fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
-- debugMemSize, debugMaxMemSize);
--#ifdef MEM_LIST
-- if (nr > 0) {
-- fprintf(fp,"NUMBER SIZE TYPE WHERE\n");
-- p = memlist;
-- while ((p) && nr > 0) {
-- fprintf(fp,"%6lu %6u ",p->mh_number,p->mh_size);
-- switch (p->mh_type) {
-- case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
-- case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
-- case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
-- default:fprintf(fp," ??? in ");break;
-- }
-- if (p->mh_file != NULL)
-- fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
-- if (p->mh_tag != MEMTAG)
-- fprintf(fp," INVALID");
-- xmlMemContentShow(fp, p);
-- fprintf(fp,"\n");
-- nr--;
-- p = p->mh_next;
-- }
-- }
--#endif /* MEM_LIST */
--}
--
--/**
-- * xmlMemDisplay:
-- * @fp: a FILE descriptor used as the output file, if NULL, the result is
-- * written to the file .memorylist
-- *
-- * show in-extenso the memory blocks allocated
-- */
--
--void
--xmlMemDisplay(FILE *fp)
--{
--#ifdef MEM_LIST
-- MEMHDR *p;
-- int idx;
--#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
-- time_t currentTime;
-- char buf[500];
-- struct tm * tstruct;
--
-- currentTime = time(NULL);
-- tstruct = localtime(¤tTime);
-- strftime(buf, sizeof(buf) - 1, "%c", tstruct);
-- fprintf(fp," %s\n\n", buf);
--#endif
--
--
-- fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
-- debugMemSize, debugMaxMemSize);
-- fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
-- idx = 0;
-- p = memlist;
-- while (p) {
-- fprintf(fp,"%-5u %6lu %6u ",idx++,p->mh_number,p->mh_size);
-- switch (p->mh_type) {
-- case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
-- case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
-- case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
-- default:fprintf(fp," ??? in ");break;
-- }
-- if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
-- if (p->mh_tag != MEMTAG)
-- fprintf(fp," INVALID");
-- xmlMemContentShow(fp, p);
-- fprintf(fp,"\n");
-- p = p->mh_next;
-- }
--#else
-- fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
--#endif
--}
--
--#ifdef MEM_LIST
--
--void debugmem_list_add(MEMHDR *p)
--{
-- p->mh_next = memlist;
-- p->mh_prev = NULL;
-- if (memlist) memlist->mh_prev = p;
-- memlist = p;
--#ifdef MEM_LIST_DEBUG
-- if (stderr)
-- Mem_Display(stderr);
--#endif
--}
--
--void debugmem_list_delete(MEMHDR *p)
--{
-- if (p->mh_next)
-- p->mh_next->mh_prev = p->mh_prev;
-- if (p->mh_prev)
-- p->mh_prev->mh_next = p->mh_next;
-- else memlist = p->mh_next;
--#ifdef MEM_LIST_DEBUG
-- if (stderr)
-- Mem_Display(stderr);
--#endif
--}
--
--#endif
--
--/*
-- * debugmem_tag_error : internal error function.
-- */
--
--void debugmem_tag_error(void *p)
--{
-- xmlGenericError(xmlGenericErrorContext,
-- "Memory tag error occurs :%p \n\t bye\n", p);
--#ifdef MEM_LIST
-- if (stderr)
-- xmlMemDisplay(stderr);
--#endif
--}
--
--FILE *xmlMemoryDumpFile = NULL;
--
--
--/**
-- * xmlMemoryDump:
-- *
-- * Dump in-extenso the memory blocks allocated to the file .memorylist
-- */
--
--void
--xmlMemoryDump(void)
--{
--#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
-- FILE *dump;
--
-- dump = fopen(".memdump", "w");
-- if (dump == NULL) xmlMemoryDumpFile = stdout;
-- else xmlMemoryDumpFile = dump;
--
-- xmlMemDisplay(xmlMemoryDumpFile);
--
-- if (dump != NULL) fclose(dump);
--#endif
--}
--
--
--/****************************************************************
-- * *
-- * Initialization Routines *
-- * *
-- ****************************************************************/
--
--#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
--xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
--xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
--xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
--xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
--#else
--xmlFreeFunc xmlFree = (xmlFreeFunc) free;
--xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc;
--xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc;
--xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) strdup;
--#endif
--
--/**
-- * xmlInitMemory:
-- *
-- * Initialize the memory layer.
-- *
-- * Returns 0 on success
-- */
--
--static int xmlInitMemoryDone = 0;
--
--int
--xmlInitMemory(void)
--{
-- int ret;
--
--#ifdef HAVE_STDLIB_H
-- char *breakpoint;
--#endif
--
-- if (xmlInitMemoryDone) return(-1);
--
--#ifdef HAVE_STDLIB_H
-- breakpoint = getenv("XML_MEM_BREAKPOINT");
-- if (breakpoint != NULL) {
-- sscanf(breakpoint, "%d", &xmlMemStopAtBlock);
-- }
--#endif
--
--#ifdef DEBUG_MEMORY
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlInitMemory() Ok\n");
--#endif
-- ret = 0;
-- return(ret);
--}
--
--/**
-- * xmlMemSetup:
-- * @freeFunc: the free() function to use
-- * @mallocFunc: the malloc() function to use
-- * @reallocFunc: the realloc() function to use
-- * @strdupFunc: the strdup() function to use
-- *
-- * Override the default memory access functions with a new set
-- * This has to be called before any other libxml routines !
-- *
-- * Should this be blocked if there was already some allocations
-- * done ?
-- *
-- * Returns 0 on success
-- */
--int
--xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
-- xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
-- if (freeFunc == NULL)
-- return(-1);
-- if (mallocFunc == NULL)
-- return(-1);
-- if (reallocFunc == NULL)
-- return(-1);
-- if (strdupFunc == NULL)
-- return(-1);
-- xmlFree = freeFunc;
-- xmlMalloc = mallocFunc;
-- xmlRealloc = reallocFunc;
-- xmlMemStrdup = strdupFunc;
-- return(0);
--}
--
--/**
-- * xmlMemGet:
-- * @freeFunc: the free() function in use
-- * @mallocFunc: the malloc() function in use
-- * @reallocFunc: the realloc() function in use
-- * @strdupFunc: the strdup() function in use
-- *
-- * Return the memory access functions set currently in use
-- *
-- * Returns 0 on success
-- */
--int
--xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
-- xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
-- if (freeFunc != NULL) *freeFunc = xmlFree;
-- if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
-- if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
-- if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
-- return(0);
--}
--
-diff -Nru libxml2-2.3.0/xmlversion.h.in libxml2-2.3.0.new/xmlversion.h.in
---- libxml2-2.3.0/xmlversion.h.in Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xmlversion.h.in Thu Jan 1 01:00:00 1970
-@@ -1,129 +0,0 @@
--/*
-- * xmlversion.h : compile-time version informations for the XML parser.
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifndef __XML_VERSION_H__
--#define __XML_VERSION_H__
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*
-- * use those to be sure nothing nasty will happen if
-- * your library and includes mismatch
-- */
--extern void xmlCheckVersion(int version);
--#define LIBXML_DOTTED_VERSION "@VERSION@"
--#define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
--#define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
--#define LIBXML_TEST_VERSION xmlCheckVersion(@LIBXML_VERSION_NUMBER@);
--
--/*
-- * Whether the FTP support is configured in
-- */
--#if @WITH_FTP@
--#define LIBXML_FTP_ENABLED
--#else
--#define LIBXML_FTP_DISABLED
--#endif
--
--/*
-- * Whether the HTTP support is configured in
-- */
--#if @WITH_HTTP@
--#define LIBXML_HTTP_ENABLED
--#else
--#define LIBXML_HTTP_DISABLED
--#endif
--
--/*
-- * Whether the HTML support is configured in
-- */
--#if @WITH_HTML@
--#define LIBXML_HTML_ENABLED
--#else
--#define LIBXML_HTML_DISABLED
--#endif
--
--/*
-- * Whether the Docbook support is configured in
--#if @WITH_SGML@
--#define LIBXML_SGML_ENABLED
--#else
--#define LIBXML_SGML_DISABLED
--#endif
-- */
--
--/*
-- * Whether XPath is configured in
-- */
--#if @WITH_XPATH@
--#define LIBXML_XPATH_ENABLED
--#else
--#define LIBXML_XPATH_DISABLED
--#endif
--
--/*
-- * Whether XPointer is configured in
-- */
--#if @WITH_XPTR@
--#define LIBXML_XPTR_ENABLED
--#else
--#define LIBXML_XPTR_DISABLED
--#endif
--
--/*
-- * Whether XInclude is configured in
-- */
--#if @WITH_XINCLUDE@
--#define LIBXML_XINCLUDE_ENABLED
--#else
--#define LIBXML_XINCLUDE_DISABLED
--#endif
--
--/*
-- * Whether iconv support is available
-- */
--#ifndef WIN32
--#if @WITH_ICONV@
--#define LIBXML_ICONV_ENABLED
--#else
--#define LIBXML_ICONV_DISABLED
--#endif
--#endif
--
--/*
-- * Whether Debugging module is configured in
-- */
--#if @WITH_DEBUG@
--#define LIBXML_DEBUG_ENABLED
--#else
--#define LIBXML_DEBUG_DISABLED
--#endif
--
--/*
-- * Whether the memory debugging is configured in
-- */
--#if @WITH_MEM_DEBUG@
--#define DEBUG_MEMORY_LOCATION
--#endif
--
--#ifndef LIBXML_DLL_IMPORT
--#if defined(WIN32) && !defined(STATIC)
--#define LIBXML_DLL_IMPORT __declspec(dllimport)
--#else
--#define LIBXML_DLL_IMPORT
--#endif
--#endif
--
--#ifdef __cplusplus
--}
--#endif /* __cplusplus */
--#endif
--
--
-diff -Nru libxml2-2.3.0/xpath.c libxml2-2.3.0.new/xpath.c
---- libxml2-2.3.0/xpath.c Mon Feb 12 04:11:20 2001
-+++ libxml2-2.3.0.new/xpath.c Thu Jan 1 01:00:00 1970
-@@ -1,6293 +0,0 @@
--/*
-- * xpath.c: XML Path Language implementation
-- * XPath is a language for addressing parts of an XML document,
-- * designed to be used by both XSLT and XPointer
-- *
-- * Reference: W3C Recommendation 16 November 1999
-- * http://www.w3.org/TR/1999/REC-xpath-19991116
-- * Public reference:
-- * http://www.w3.org/TR/xpath
-- *
-- * See COPYRIGHT for the status of this software
-- *
-- * Author: Daniel.Veillard@w3.org
-- *
-- * 14 Nov 2000 ht - truncated declaration of xmlXPathEvalRelativeLocationPath
-- * for VMS
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--#include <libxml/xmlversion.h>
--#ifdef LIBXML_XPATH_ENABLED
--
--#include <stdio.h>
--#include <string.h>
--
--#ifdef HAVE_SYS_TYPES_H
--#include <sys/types.h>
--#endif
--#ifdef HAVE_MATH_H
--#include <math.h>
--#endif
--#ifdef HAVE_FLOAT_H
--#include <float.h>
--#endif
--#ifdef HAVE_IEEEFP_H
--#include <ieeefp.h>
--#endif
--#ifdef HAVE_NAN_H
--#include <nan.h>
--#endif
--#ifdef HAVE_CTYPE_H
--#include <ctype.h>
--#endif
--
--#include <libxml/xmlmemory.h>
--#include <libxml/tree.h>
--#include <libxml/valid.h>
--#include <libxml/xpath.h>
--#include <libxml/xpathInternals.h>
--#include <libxml/parserInternals.h>
--#include <libxml/hash.h>
--#ifdef LIBXML_XPTR_ENABLED
--#include <libxml/xpointer.h>
--#endif
--#ifdef LIBXML_DEBUG_ENABLED
--#include <libxml/debugXML.h>
--#endif
--#include <libxml/xmlerror.h>
--
--/* #define DEBUG */
--/* #define DEBUG_STEP */
--/* #define DEBUG_EXPR */
--
--void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
--double xmlXPathStringEvalNumber(const xmlChar *str);
--
--/*
-- * Setup stuff for floating point
-- * The lack of portability of this section of the libc is annoying !
-- */
--double xmlXPathNAN = 0;
--double xmlXPathPINF = 1;
--double xmlXPathNINF = -1;
--
--#ifndef isinf
--#ifndef HAVE_ISINF
--
--#if HAVE_FPCLASS
--
--int isinf(double d) {
-- fpclass_t type = fpclass(d);
-- switch (type) {
-- case FP_NINF:
-- return(-1);
-- case FP_PINF:
-- return(1);
-- }
-- return(0);
--}
--
--#elif defined(HAVE_FP_CLASS) || defined(HAVE_FP_CLASS_D)
--
--#if HAVE_FP_CLASS_H
--#include <fp_class.h>
--#endif
--
--int isinf(double d) {
--#if HAVE_FP_CLASS
-- int fpclass = fp_class(d);
--#else
-- int fpclass = fp_class_d(d);
--#endif
-- if (fpclass == FP_POS_INF)
-- return(1);
-- if (fpclass == FP_NEG_INF)
-- return(-1);
-- return(0);
--}
--
--#elif defined(HAVE_CLASS)
--
--int isinf(double d) {
-- int fpclass = class(d);
-- if (fpclass == FP_PLUS_INF)
-- return(1);
-- if (fpclass == FP_MINUS_INF)
-- return(-1);
-- return(0);
--}
--#elif defined(finite) || defined(HAVE_FINITE)
--int isinf(double x) { return !finite(x) && x==x; }
--#elif defined(HUGE_VAL)
--int isinf(double x)
--{
-- if (x == HUGE_VAL)
-- return(1);
-- if (x == -HUGE_VAL)
-- return(-1);
-- return(0);
--}
--#endif
--
--#endif /* ! HAVE_ISINF */
--#endif /* ! defined(isinf) */
--
--#ifndef isnan
--#ifndef HAVE_ISNAN
--
--#ifdef HAVE_ISNAND
--#define isnan(f) isnand(f)
--#endif /* HAVE_iSNAND */
--
--#endif /* ! HAVE_iSNAN */
--#endif /* ! defined(isnan) */
--
--/**
-- * xmlXPathInit:
-- *
-- * Initialize the XPath environment
-- */
--void
--xmlXPathInit(void) {
-- static int initialized = 0;
--
-- if (initialized) return;
--
-- xmlXPathNAN = 0;
-- xmlXPathNAN /= 0;
--
-- xmlXPathPINF = 1;
-- xmlXPathPINF /= 0;
--
-- xmlXPathNINF = -1;
-- xmlXPathNINF /= 0;
--
-- initialized = 1;
--}
--
--/************************************************************************
-- * *
-- * Debugging related functions *
-- * *
-- ************************************************************************/
--
--#define TODO \
-- xmlGenericError(xmlGenericErrorContext, \
-- "Unimplemented block at %s:%d\n", \
-- __FILE__, __LINE__);
--
--#define STRANGE \
-- xmlGenericError(xmlGenericErrorContext, \
-- "Internal error at %s:%d\n", \
-- __FILE__, __LINE__);
--
--#ifdef LIBXML_DEBUG_ENABLED
--void xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
-- if (cur == NULL) {
-- fprintf(output, shift);
-- fprintf(output, "Node is NULL !\n");
-- return;
--
-- }
--
-- if ((cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- fprintf(output, shift);
-- fprintf(output, " /\n");
-- } else if (cur->type == XML_ATTRIBUTE_NODE)
-- xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
-- else
-- xmlDebugDumpOneNode(output, cur, depth);
--}
--
--void xmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- if (cur == NULL) {
-- fprintf(output, shift);
-- fprintf(output, "NodeSet is NULL !\n");
-- return;
--
-- }
--
-- fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
-- for (i = 0;i < cur->nodeNr;i++) {
-- fprintf(output, shift);
-- fprintf(output, "%d", i + 1);
-- xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
-- }
--}
--
--#if defined(LIBXML_XPTR_ENABLED)
--void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
--void xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- if (cur == NULL) {
-- fprintf(output, shift);
-- fprintf(output, "LocationSet is NULL !\n");
-- return;
--
-- }
--
-- for (i = 0;i < cur->locNr;i++) {
-- fprintf(output, shift);
-- fprintf(output, "%d : ", i + 1);
-- xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
-- }
--}
--#endif
--
--void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
-- int i;
-- char shift[100];
--
-- for (i = 0;((i < depth) && (i < 25));i++)
-- shift[2 * i] = shift[2 * i + 1] = ' ';
-- shift[2 * i] = shift[2 * i + 1] = 0;
--
-- fprintf(output, shift);
--
-- if (cur == NULL) {
-- fprintf(output, "Object is empty (NULL)\n");
-- return;
-- }
-- switch(cur->type) {
-- case XPATH_UNDEFINED:
-- fprintf(output, "Object is uninitialized\n");
-- break;
-- case XPATH_NODESET:
-- fprintf(output, "Object is a Node Set :\n");
-- xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
-- break;
-- case XPATH_XSLT_TREE:
-- fprintf(output, "Object is an XSLT value tree :\n");
-- xmlXPathDebugDumpNode(output, cur->user, depth);
-- break;
-- case XPATH_BOOLEAN:
-- fprintf(output, "Object is a Boolean : ");
-- if (cur->boolval) fprintf(output, "true\n");
-- else fprintf(output, "false\n");
-- break;
-- case XPATH_NUMBER:
-- fprintf(output, "Object is a number : %0g\n", cur->floatval);
-- break;
-- case XPATH_STRING:
-- fprintf(output, "Object is a string : ");
-- xmlDebugDumpString(output, cur->stringval);
-- fprintf(output, "\n");
-- break;
-- case XPATH_POINT:
-- fprintf(output, "Object is a point : index %d in node", cur->index);
-- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
-- fprintf(output, "\n");
-- break;
-- case XPATH_RANGE:
-- if ((cur->user2 == NULL) ||
-- ((cur->user2 == cur->user) && (cur->index == cur->index2))) {
-- fprintf(output, "Object is a collapsed range :\n");
-- fprintf(output, shift);
-- if (cur->index >= 0)
-- fprintf(output, "index %d in ", cur->index);
-- fprintf(output, "node\n");
-- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
-- depth + 1);
-- } else {
-- fprintf(output, "Object is a range :\n");
-- fprintf(output, shift);
-- fprintf(output, "From ");
-- if (cur->index >= 0)
-- fprintf(output, "index %d in ", cur->index);
-- fprintf(output, "node\n");
-- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
-- depth + 1);
-- fprintf(output, shift);
-- fprintf(output, "To ");
-- if (cur->index2 >= 0)
-- fprintf(output, "index %d in ", cur->index2);
-- fprintf(output, "node\n");
-- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
-- depth + 1);
-- fprintf(output, "\n");
-- }
-- break;
-- case XPATH_LOCATIONSET:
--#if defined(LIBXML_XPTR_ENABLED)
-- fprintf(output, "Object is a Location Set:\n");
-- xmlXPathDebugDumpLocationSet(output,
-- (xmlLocationSetPtr) cur->user, depth);
--#endif
-- break;
-- case XPATH_USERS:
-- fprintf(output, "Object is user defined\n");
-- break;
-- }
--}
--#endif
--
--/************************************************************************
-- * *
-- * Parser stacks related functions and macros *
-- * *
-- ************************************************************************/
--
--/*
-- * Generic function for accessing stacks in the Parser Context
-- */
--
--#define PUSH_AND_POP(type, name) \
--extern int name##Push(xmlXPathParserContextPtr ctxt, type value) { \
-- if (ctxt->name##Nr >= ctxt->name##Max) { \
-- ctxt->name##Max *= 2; \
-- ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
-- ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
-- if (ctxt->name##Tab == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "realloc failed !\n"); \
-- return(0); \
-- } \
-- } \
-- ctxt->name##Tab[ctxt->name##Nr] = value; \
-- ctxt->name = value; \
-- return(ctxt->name##Nr++); \
--} \
--extern type name##Pop(xmlXPathParserContextPtr ctxt) { \
-- type ret; \
-- if (ctxt->name##Nr <= 0) return(0); \
-- ctxt->name##Nr--; \
-- if (ctxt->name##Nr > 0) \
-- ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
-- else \
-- ctxt->name = NULL; \
-- ret = ctxt->name##Tab[ctxt->name##Nr]; \
-- ctxt->name##Tab[ctxt->name##Nr] = 0; \
-- return(ret); \
--} \
--
--PUSH_AND_POP(xmlXPathObjectPtr, value)
--
--/*
-- * Macros for accessing the content. Those should be used only by the parser,
-- * and not exported.
-- *
-- * Dirty macros, i.e. one need to make assumption on the context to use them
-- *
-- * CUR_PTR return the current pointer to the xmlChar to be parsed.
-- * CUR returns the current xmlChar value, i.e. a 8 bit value
-- * in ISO-Latin or UTF-8.
-- * This should be used internally by the parser
-- * only to compare to ASCII values otherwise it would break when
-- * running with UTF-8 encoding.
-- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-- * to compare on ASCII based substring.
-- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-- * strings within the parser.
-- * CURRENT Returns the current char value, with the full decoding of
-- * UTF-8 if we are using this mode. It returns an int.
-- * NEXT Skip to the next character, this does the proper decoding
-- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-- * It returns the pointer to the current xmlChar.
-- */
--
--#define CUR (*ctxt->cur)
--#define SKIP(val) ctxt->cur += (val)
--#define NXT(val) ctxt->cur[(val)]
--#define CUR_PTR ctxt->cur
--
--#define SKIP_BLANKS \
-- while (IS_BLANK(*(ctxt->cur))) NEXT
--
--#define CURRENT (*ctxt->cur)
--#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
--
--/************************************************************************
-- * *
-- * Error handling routines *
-- * *
-- ************************************************************************/
--
--
--const char *xmlXPathErrorMessages[] = {
-- "Ok",
-- "Number encoding",
-- "Unfinished litteral",
-- "Start of litteral",
-- "Expected $ for variable reference",
-- "Undefined variable",
-- "Invalid predicate",
-- "Invalid expression",
-- "Missing closing curly brace",
-- "Unregistered function",
-- "Invalid operand",
-- "Invalid type",
-- "Invalid number of arguments",
-- "Invalid context size",
-- "Invalid context position",
-- "Memory allocation error",
-- "Syntax error",
-- "Resource error",
-- "Sub resource error",
-- "Undefined namespace prefix"
--};
--
--/**
-- * xmlXPathError:
-- * @ctxt: the XPath Parser context
-- * @file: the file name
-- * @line: the line number
-- * @no: the error number
-- *
-- * Create a new xmlNodeSetPtr of type double and of value @val
-- *
-- * Returns the newly created object.
-- */
--void
--xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file,
-- int line, int no) {
-- int n;
-- const xmlChar *cur;
-- const xmlChar *base;
--
-- xmlGenericError(xmlGenericErrorContext,
-- "Error %s:%d: %s\n", file, line,
-- xmlXPathErrorMessages[no]);
--
-- cur = ctxt->cur;
-- base = ctxt->base;
-- while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
-- cur--;
-- }
-- n = 0;
-- while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
-- cur--;
-- if ((*cur == '\n') || (*cur == '\r')) cur++;
-- base = cur;
-- n = 0;
-- while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
-- xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++);
-- n++;
-- }
-- xmlGenericError(xmlGenericErrorContext, "\n");
-- cur = ctxt->cur;
-- while ((*cur == '\n') || (*cur == '\r'))
-- cur--;
-- n = 0;
-- while ((cur != base) && (n++ < 80)) {
-- xmlGenericError(xmlGenericErrorContext, " ");
-- base++;
-- }
-- xmlGenericError(xmlGenericErrorContext,"^\n");
--}
--
--
--/************************************************************************
-- * *
-- * Routines to handle NodeSets *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPathCmpNodes:
-- * @node1: the first node
-- * @node2: the second node
-- *
-- * Compare two nodes w.r.t document order
-- *
-- * Returns -2 in case of error 1 if first point < second point, 0 if
-- * that's the same node, -1 otherwise
-- */
--int
--xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
-- int depth1, depth2;
-- xmlNodePtr cur, root;
--
-- if ((node1 == NULL) || (node2 == NULL))
-- return(-2);
-- /*
-- * a couple of optimizations which will avoid computations in most cases
-- */
-- if (node1 == node2)
-- return(0);
-- if (node1 == node2->prev)
-- return(1);
-- if (node1 == node2->next)
-- return(-1);
--
-- /*
-- * compute depth to root
-- */
-- for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
-- if (cur == node1)
-- return(1);
-- depth2++;
-- }
-- root = cur;
-- for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
-- if (cur == node2)
-- return(-1);
-- depth1++;
-- }
-- /*
-- * Distinct document (or distinct entities :-( ) case.
-- */
-- if (root != cur) {
-- return(-2);
-- }
-- /*
-- * get the nearest common ancestor.
-- */
-- while (depth1 > depth2) {
-- depth1--;
-- node1 = node1->parent;
-- }
-- while (depth2 > depth1) {
-- depth2--;
-- node2 = node2->parent;
-- }
-- while (node1->parent != node2->parent) {
-- node1 = node1->parent;
-- node2 = node2->parent;
-- /* should not happen but just in case ... */
-- if ((node1 == NULL) || (node2 == NULL))
-- return(-2);
-- }
-- /*
-- * Find who's first.
-- */
-- if (node1 == node2->next)
-- return(-1);
-- for (cur = node1->next;cur != NULL;cur = cur->next)
-- if (cur == node2)
-- return(1);
-- return(-1); /* assume there is no sibling list corruption */
--}
--
--#define XML_NODESET_DEFAULT 10
--/**
-- * xmlXPathNodeSetCreate:
-- * @val: an initial xmlNodePtr, or NULL
-- *
-- * Create a new xmlNodeSetPtr of type double and of value @val
-- *
-- * Returns the newly created object.
-- */
--xmlNodeSetPtr
--xmlXPathNodeSetCreate(xmlNodePtr val) {
-- xmlNodeSetPtr ret;
--
-- ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewNodeSet: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
-- if (val != NULL) {
-- ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-- sizeof(xmlNodePtr));
-- if (ret->nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewNodeSet: out of memory\n");
-- return(NULL);
-- }
-- memset(ret->nodeTab, 0 ,
-- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-- ret->nodeMax = XML_NODESET_DEFAULT;
-- ret->nodeTab[ret->nodeNr++] = val;
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPathNodeSetAdd:
-- * @cur: the initial node set
-- * @val: a new xmlNodePtr
-- *
-- * add a new xmlNodePtr ot an existing NodeSet
-- */
--void
--xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
-- int i;
--
-- if (val == NULL) return;
--
-- /*
-- * check against doublons
-- */
-- for (i = 0;i < cur->nodeNr;i++)
-- if (cur->nodeTab[i] == val) return;
--
-- /*
-- * grow the nodeTab if needed
-- */
-- if (cur->nodeMax == 0) {
-- cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-- sizeof(xmlNodePtr));
-- if (cur->nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetAdd: out of memory\n");
-- return;
-- }
-- memset(cur->nodeTab, 0 ,
-- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-- cur->nodeMax = XML_NODESET_DEFAULT;
-- } else if (cur->nodeNr == cur->nodeMax) {
-- xmlNodePtr *temp;
--
-- cur->nodeMax *= 2;
-- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
-- sizeof(xmlNodePtr));
-- if (temp == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetAdd: out of memory\n");
-- return;
-- }
-- cur->nodeTab = temp;
-- }
-- cur->nodeTab[cur->nodeNr++] = val;
--}
--
--/**
-- * xmlXPathNodeSetAddUnique:
-- * @cur: the initial node set
-- * @val: a new xmlNodePtr
-- *
-- * add a new xmlNodePtr ot an existing NodeSet, optimized version
-- * when we are sure the node is not already in the set.
-- */
--void
--xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
-- if (val == NULL) return;
--
-- /*
-- * grow the nodeTab if needed
-- */
-- if (cur->nodeMax == 0) {
-- cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-- sizeof(xmlNodePtr));
-- if (cur->nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetAddUnique: out of memory\n");
-- return;
-- }
-- memset(cur->nodeTab, 0 ,
-- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-- cur->nodeMax = XML_NODESET_DEFAULT;
-- } else if (cur->nodeNr == cur->nodeMax) {
-- xmlNodePtr *temp;
--
-- cur->nodeMax *= 2;
-- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
-- sizeof(xmlNodePtr));
-- if (temp == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetAddUnique: out of memory\n");
-- return;
-- }
-- cur->nodeTab = temp;
-- }
-- cur->nodeTab[cur->nodeNr++] = val;
--}
--
--/**
-- * xmlXPathNodeSetMerge:
-- * @val1: the first NodeSet or NULL
-- * @val2: the second NodeSet
-- *
-- * Merges two nodesets, all nodes from @val2 are added to @val1
-- * if @val1 is NULL, a new set is created and copied from @val2
-- *
-- * Returns val1 once extended or NULL in case of error.
-- */
--xmlNodeSetPtr
--xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
-- int i, j, initNr;
--
-- if (val2 == NULL) return(val1);
-- if (val1 == NULL) {
-- val1 = xmlXPathNodeSetCreate(NULL);
-- }
--
-- initNr = val1->nodeNr;
--
-- for (i = 0;i < val2->nodeNr;i++) {
-- /*
-- * check against doublons
-- */
-- for (j = 0; j < initNr; j++)
-- if (val1->nodeTab[j] == val2->nodeTab[i]) continue;
--
-- /*
-- * grow the nodeTab if needed
-- */
-- if (val1->nodeMax == 0) {
-- val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
-- sizeof(xmlNodePtr));
-- if (val1->nodeTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetMerge: out of memory\n");
-- return(NULL);
-- }
-- memset(val1->nodeTab, 0 ,
-- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
-- val1->nodeMax = XML_NODESET_DEFAULT;
-- } else if (val1->nodeNr == val1->nodeMax) {
-- xmlNodePtr *temp;
--
-- val1->nodeMax *= 2;
-- temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
-- sizeof(xmlNodePtr));
-- if (temp == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetMerge: out of memory\n");
-- return(NULL);
-- }
-- val1->nodeTab = temp;
-- }
-- val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
-- }
--
-- return(val1);
--}
--
--/**
-- * xmlXPathNodeSetDel:
-- * @cur: the initial node set
-- * @val: an xmlNodePtr
-- *
-- * Removes an xmlNodePtr from an existing NodeSet
-- */
--void
--xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
-- int i;
--
-- if (cur == NULL) return;
-- if (val == NULL) return;
--
-- /*
-- * check against doublons
-- */
-- for (i = 0;i < cur->nodeNr;i++)
-- if (cur->nodeTab[i] == val) break;
--
-- if (i >= cur->nodeNr) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
-- val->name);
--#endif
-- return;
-- }
-- cur->nodeNr--;
-- for (;i < cur->nodeNr;i++)
-- cur->nodeTab[i] = cur->nodeTab[i + 1];
-- cur->nodeTab[cur->nodeNr] = NULL;
--}
--
--/**
-- * xmlXPathNodeSetRemove:
-- * @cur: the initial node set
-- * @val: the index to remove
-- *
-- * Removes an entry from an existing NodeSet list.
-- */
--void
--xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
-- if (cur == NULL) return;
-- if (val >= cur->nodeNr) return;
-- cur->nodeNr--;
-- for (;val < cur->nodeNr;val++)
-- cur->nodeTab[val] = cur->nodeTab[val + 1];
-- cur->nodeTab[cur->nodeNr] = NULL;
--}
--
--/**
-- * xmlXPathFreeNodeSet:
-- * @obj: the xmlNodeSetPtr to free
-- *
-- * Free the NodeSet compound (not the actual nodes !).
-- */
--void
--xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
-- if (obj == NULL) return;
-- if (obj->nodeTab != NULL) {
--#ifdef DEBUG
-- memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
--#endif
-- xmlFree(obj->nodeTab);
-- }
--#ifdef DEBUG
-- memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
--#endif
-- xmlFree(obj);
--}
--
--/**
-- * xmlXPathFreeValueTree:
-- * @obj: the xmlNodeSetPtr to free
-- *
-- * Free the NodeSet compound and the actual tree, this is different
-- * from xmlXPathFreeNodeSet()
-- */
--void
--xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
-- int i;
--
-- if (obj == NULL) return;
-- for (i = 0;i < obj->nodeNr;i++)
-- if (obj->nodeTab[i] != NULL)
-- xmlFreeNode(obj->nodeTab[i]);
--
-- if (obj->nodeTab != NULL) {
--#ifdef DEBUG
-- memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
--#endif
-- xmlFree(obj->nodeTab);
-- }
--#ifdef DEBUG
-- memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
--#endif
-- xmlFree(obj);
--}
--
--#if defined(DEBUG) || defined(DEBUG_STEP)
--/**
-- * xmlGenericErrorContextNodeSet:
-- * @output: a FILE * for the output
-- * @obj: the xmlNodeSetPtr to free
-- *
-- * Quick display of a NodeSet
-- */
--void
--xmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
-- int i;
--
-- if (output == NULL) output = xmlGenericErrorContext;
-- if (obj == NULL) {
-- fprintf(output, "NodeSet == NULL !\n");
-- return;
-- }
-- if (obj->nodeNr == 0) {
-- fprintf(output, "NodeSet is empty\n");
-- return;
-- }
-- if (obj->nodeTab == NULL) {
-- fprintf(output, " nodeTab == NULL !\n");
-- return;
-- }
-- for (i = 0; i < obj->nodeNr; i++) {
-- if (obj->nodeTab[i] == NULL) {
-- fprintf(output, " NULL !\n");
-- return;
-- }
-- if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
-- (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
-- fprintf(output, " /");
-- else if (obj->nodeTab[i]->name == NULL)
-- fprintf(output, " noname!");
-- else fprintf(output, " %s", obj->nodeTab[i]->name);
-- }
-- fprintf(output, "\n");
--}
--#endif
--
--/**
-- * xmlXPathNewNodeSet:
-- * @val: the NodePtr value
-- *
-- * Create a new xmlXPathObjectPtr of type NodeSet and initialize
-- * it with the single Node @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewNodeSet(xmlNodePtr val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewNodeSet: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_NODESET;
-- ret->nodesetval = xmlXPathNodeSetCreate(val);
-- return(ret);
--}
--
--/**
-- * xmlXPathNewValueTree:
-- * @val: the NodePtr value
-- *
-- * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
-- * it with the tree root @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewValueTree(xmlNodePtr val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewNodeSet: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_XSLT_TREE;
-- ret->nodesetval = xmlXPathNodeSetCreate(val);
-- return(ret);
--}
--
--/**
-- * xmlXPathNewNodeSetList:
-- * @val: an existing NodeSet
-- *
-- * Create a new xmlXPathObjectPtr of type NodeSet and initialize
-- * it with the Nodeset @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewNodeSetList(xmlNodeSetPtr val) {
-- xmlXPathObjectPtr ret;
-- int i;
--
-- if (val == NULL)
-- ret = NULL;
-- else if (val->nodeTab == NULL)
-- ret = xmlXPathNewNodeSet(NULL);
-- else
-- {
-- ret = xmlXPathNewNodeSet(val->nodeTab[0]);
-- for (i = 1; i < val->nodeNr; ++i)
-- xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
-- }
--
-- return(ret);
--}
--
--/**
-- * xmlXPathWrapNodeSet:
-- * @val: the NodePtr value
-- *
-- * Wrap the Nodeset @val in a new xmlXPathObjectPtr
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathWrapNodeSet: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_NODESET;
-- ret->nodesetval = val;
-- return(ret);
--}
--
--/**
-- * xmlXPathFreeNodeSetList:
-- * @obj: an existing NodeSetList object
-- *
-- * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
-- * the list contrary to xmlXPathFreeObject().
-- */
--void
--xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
-- if (obj == NULL) return;
--#ifdef DEBUG
-- memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
--#endif
-- xmlFree(obj);
--}
--
--/************************************************************************
-- * *
-- * Routines to handle extra functions *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPathRegisterFunc:
-- * @ctxt: the XPath context
-- * @name: the function name
-- * @f: the function implementation or NULL
-- *
-- * Register a new function. If @f is NULL it unregisters the function
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
-- xmlXPathFunction f) {
-- return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
--}
--
--/**
-- * xmlXPathRegisterFuncNS:
-- * @ctxt: the XPath context
-- * @name: the function name
-- * @ns_uri: the function namespace URI
-- * @f: the function implementation or NULL
-- *
-- * Register a new function. If @f is NULL it unregisters the function
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-- const xmlChar *ns_uri, xmlXPathFunction f) {
-- if (ctxt == NULL)
-- return(-1);
-- if (name == NULL)
-- return(-1);
--
-- if (ctxt->funcHash == NULL)
-- ctxt->funcHash = xmlHashCreate(0);
-- if (ctxt->funcHash == NULL)
-- return(-1);
-- return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f));
--}
--
--/**
-- * xmlXPathFunctionLookup:
-- * @ctxt: the XPath context
-- * @name: the function name
-- *
-- * Search in the Function array of the context for the given
-- * function.
-- *
-- * Returns the xmlXPathFunction or NULL if not found
-- */
--xmlXPathFunction
--xmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
-- return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
--}
--
--/**
-- * xmlXPathFunctionLookupNS:
-- * @ctxt: the XPath context
-- * @name: the function name
-- * @ns_uri: the function namespace URI
-- *
-- * Search in the Function array of the context for the given
-- * function.
-- *
-- * Returns the xmlXPathFunction or NULL if not found
-- */
--xmlXPathFunction
--xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-- const xmlChar *ns_uri) {
-- if (ctxt == NULL)
-- return(NULL);
-- if (ctxt->funcHash == NULL)
-- return(NULL);
-- if (name == NULL)
-- return(NULL);
--
-- return((xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri));
--}
--
--/**
-- * xmlXPathRegisteredFuncsCleanup:
-- * @ctxt: the XPath context
-- *
-- * Cleanup the XPath context data associated to registered functions
-- */
--void
--xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
-- if (ctxt == NULL)
-- return;
--
-- xmlHashFree(ctxt->funcHash, NULL);
-- ctxt->funcHash = NULL;
--}
--
--/************************************************************************
-- * *
-- * Routines to handle Variable *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPathRegisterVariable:
-- * @ctxt: the XPath context
-- * @name: the variable name
-- * @value: the variable value or NULL
-- *
-- * Register a new variable value. If @value is NULL it unregisters
-- * the variable
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
-- xmlXPathObjectPtr value) {
-- return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
--}
--
--/**
-- * xmlXPathRegisterVariableNS:
-- * @ctxt: the XPath context
-- * @name: the variable name
-- * @ns_uri: the variable namespace URI
-- * @value: the variable value or NULL
-- *
-- * Register a new variable value. If @value is NULL it unregisters
-- * the variable
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-- const xmlChar *ns_uri,
-- xmlXPathObjectPtr value) {
-- if (ctxt == NULL)
-- return(-1);
-- if (name == NULL)
-- return(-1);
--
-- if (ctxt->varHash == NULL)
-- ctxt->varHash = xmlHashCreate(0);
-- if (ctxt->varHash == NULL)
-- return(-1);
-- return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
-- (void *) value,
-- (xmlHashDeallocator)xmlXPathFreeObject));
--}
--
--/**
-- * xmlXPathRegisterVariableLookup:
-- * @ctxt: the XPath context
-- * @f: the lookup function
-- * @data: the lookup data
-- *
-- * register an external mechanism to do variable lookup
-- */
--void
--xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
-- xmlXPathVariableLookupFunc f, void *data) {
-- if (ctxt == NULL)
-- return;
-- ctxt->varLookupFunc = (void *) f;
-- ctxt->varLookupData = data;
--}
--
--/**
-- * xmlXPathVariableLookup:
-- * @ctxt: the XPath context
-- * @name: the variable name
-- *
-- * Search in the Variable array of the context for the given
-- * variable value.
-- *
-- * Returns the value or NULL if not found
-- */
--xmlXPathObjectPtr
--xmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
-- if (ctxt == NULL)
-- return(NULL);
--
-- if (ctxt->varLookupFunc != NULL) {
-- xmlXPathObjectPtr ret;
--
-- ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
-- (ctxt->varLookupData, name, NULL);
-- if (ret != NULL) return(ret);
-- }
-- return(xmlXPathVariableLookupNS(ctxt, name, NULL));
--}
--
--/**
-- * xmlXPathVariableLookupNS:
-- * @ctxt: the XPath context
-- * @name: the variable name
-- * @ns_uri: the variable namespace URI
-- *
-- * Search in the Variable array of the context for the given
-- * variable value.
-- *
-- * Returns the value or NULL if not found
-- */
--xmlXPathObjectPtr
--xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
-- const xmlChar *ns_uri) {
-- if (ctxt == NULL)
-- return(NULL);
--
-- if (ctxt->varLookupFunc != NULL) {
-- xmlXPathObjectPtr ret;
--
-- ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
-- (ctxt->varLookupData, name, ns_uri);
-- if (ret != NULL) return(ret);
-- }
--
-- if (ctxt->varHash == NULL)
-- return(NULL);
-- if (name == NULL)
-- return(NULL);
--
-- return((xmlXPathObjectPtr) xmlHashLookup2(ctxt->varHash, name, ns_uri));
--}
--
--/**
-- * xmlXPathRegisteredVariablesCleanup:
-- * @ctxt: the XPath context
-- *
-- * Cleanup the XPath context data associated to registered variables
-- */
--void
--xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
-- if (ctxt == NULL)
-- return;
--
-- xmlHashFree(ctxt->varHash, NULL);
-- ctxt->varHash = NULL;
--}
--
--/**
-- * xmlXPathRegisterNs:
-- * @ctxt: the XPath context
-- * @prefix: the namespace prefix
-- * @ns_uri: the namespace name
-- *
-- * Register a new namespace. If @ns_uri is NULL it unregisters
-- * the namespace
-- *
-- * Returns 0 in case of success, -1 in case of error
-- */
--int
--xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
-- const xmlChar *ns_uri) {
-- if (ctxt == NULL)
-- return(-1);
-- if (prefix == NULL)
-- return(-1);
--
-- if (ctxt->nsHash == NULL)
-- ctxt->nsHash = xmlHashCreate(10);
-- if (ctxt->nsHash == NULL)
-- return(-1);
-- return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) ns_uri,
-- (xmlHashDeallocator)xmlFree));
--}
--
--/**
-- * xmlXPathNsLookup:
-- * @ctxt: the XPath context
-- * @prefix: the namespace prefix value
-- *
-- * Search in the namespace declaration array of the context for the given
-- * namespace name associated to the given prefix
-- *
-- * Returns the value or NULL if not found
-- */
--const xmlChar *
--xmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
-- if (ctxt == NULL)
-- return(NULL);
-- if (prefix == NULL)
-- return(NULL);
-- if (ctxt->nsHash == NULL)
-- return(NULL);
--
-- return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
--}
--
--/**
-- * xmlXPathRegisteredVariablesCleanup:
-- * @ctxt: the XPath context
-- *
-- * Cleanup the XPath context data associated to registered variables
-- */
--void
--xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
-- if (ctxt == NULL)
-- return;
--
-- xmlHashFree(ctxt->nsHash, NULL);
-- ctxt->nsHash = NULL;
--}
--
--/************************************************************************
-- * *
-- * Routines to handle Values *
-- * *
-- ************************************************************************/
--
--/* Allocations are terrible, one need to optimize all this !!! */
--
--/**
-- * xmlXPathNewFloat:
-- * @val: the double value
-- *
-- * Create a new xmlXPathObjectPtr of type double and of value @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewFloat(double val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewFloat: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_NUMBER;
-- ret->floatval = val;
-- return(ret);
--}
--
--/**
-- * xmlXPathNewBoolean:
-- * @val: the boolean value
-- *
-- * Create a new xmlXPathObjectPtr of type boolean and of value @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewBoolean(int val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewBoolean: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_BOOLEAN;
-- ret->boolval = (val != 0);
-- return(ret);
--}
--
--/**
-- * xmlXPathNewString:
-- * @val: the xmlChar * value
-- *
-- * Create a new xmlXPathObjectPtr of type string and of value @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewString(const xmlChar *val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewString: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_STRING;
-- if (val != NULL)
-- ret->stringval = xmlStrdup(val);
-- else
-- ret->stringval = xmlStrdup((const xmlChar *)"");
-- return(ret);
--}
--
--/**
-- * xmlXPathNewCString:
-- * @val: the char * value
-- *
-- * Create a new xmlXPathObjectPtr of type string and of value @val
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathNewCString(const char *val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewCString: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_STRING;
-- ret->stringval = xmlStrdup(BAD_CAST val);
-- return(ret);
--}
--
--/**
-- * xmlXPathObjectCopy:
-- * @val: the original object
-- *
-- * allocate a new copy of a given object
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPathObjectCopy(xmlXPathObjectPtr val) {
-- xmlXPathObjectPtr ret;
--
-- if (val == NULL)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathObjectCopy: out of memory\n");
-- return(NULL);
-- }
-- memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
-- switch (val->type) {
-- case XPATH_BOOLEAN:
-- case XPATH_NUMBER:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- break;
-- case XPATH_STRING:
-- ret->stringval = xmlStrdup(val->stringval);
-- break;
-- case XPATH_XSLT_TREE:
-- if ((val->nodesetval != NULL) &&
-- (val->nodesetval->nodeTab != NULL))
-- ret->nodesetval = xmlXPathNodeSetCreate(
-- xmlCopyNode(val->nodesetval->nodeTab[0], 1));
-- else
-- ret->nodesetval = xmlXPathNodeSetCreate(NULL);
-- break;
-- case XPATH_NODESET:
-- ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
-- break;
-- case XPATH_LOCATIONSET:
--#ifdef LIBXML_XPTR_ENABLED
-- {
-- xmlLocationSetPtr loc = val->user;
-- ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
-- break;
-- }
--#endif
-- case XPATH_UNDEFINED:
-- case XPATH_USERS:
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathObjectCopy: unsupported type %d\n",
-- val->type);
-- break;
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPathFreeObject:
-- * @obj: the object to free
-- *
-- * Free up an xmlXPathObjectPtr object.
-- */
--void
--xmlXPathFreeObject(xmlXPathObjectPtr obj) {
-- if (obj == NULL) return;
-- if (obj->type == XPATH_NODESET) {
-- if (obj->nodesetval != NULL)
-- xmlXPathFreeNodeSet(obj->nodesetval);
--#ifdef LIBXML_XPTR_ENABLED
-- } else if (obj->type == XPATH_LOCATIONSET) {
-- if (obj->user != NULL)
-- xmlXPtrFreeLocationSet(obj->user);
--#endif
-- } else if (obj->type == XPATH_STRING) {
-- if (obj->stringval != NULL)
-- xmlFree(obj->stringval);
-- } else if (obj->type == XPATH_XSLT_TREE) {
-- if (obj->nodesetval != NULL)
-- xmlXPathFreeValueTree(obj->nodesetval);
-- }
--
--#ifdef DEBUG
-- memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
--#endif
-- xmlFree(obj);
--}
--
--/************************************************************************
-- * *
-- * Routines to handle XPath contexts *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPathNewContext:
-- * @doc: the XML document
-- *
-- * Create a new xmlXPathContext
-- *
-- * Returns the xmlXPathContext just allocated.
-- */
--xmlXPathContextPtr
--xmlXPathNewContext(xmlDocPtr doc) {
-- xmlXPathContextPtr ret;
--
-- ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewContext: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
-- ret->doc = doc;
-- ret->node = NULL;
--
-- ret->varHash = NULL;
--
-- ret->nb_types = 0;
-- ret->max_types = 0;
-- ret->types = NULL;
--
-- ret->funcHash = xmlHashCreate(0);
--
-- ret->nb_axis = 0;
-- ret->max_axis = 0;
-- ret->axis = NULL;
--
-- ret->nsHash = NULL;
-- ret->user = NULL;
--
-- ret->contextSize = -1;
-- ret->proximityPosition = -1;
--
-- xmlXPathRegisterAllFunctions(ret);
--
-- return(ret);
--}
--
--/**
-- * xmlXPathFreeContext:
-- * @ctxt: the context to free
-- *
-- * Free up an xmlXPathContext
-- */
--void
--xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
-- xmlXPathRegisteredNsCleanup(ctxt);
-- xmlXPathRegisteredFuncsCleanup(ctxt);
-- xmlXPathRegisteredVariablesCleanup(ctxt);
--#ifdef DEBUG
-- memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
--#endif
-- xmlFree(ctxt);
--}
--
--/************************************************************************
-- * *
-- * Routines to handle XPath parser contexts *
-- * *
-- ************************************************************************/
--
--#define CHECK_CTXT(ctxt) \
-- if (ctxt == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "%s:%d Internal error: ctxt == NULL\n", \
-- __FILE__, __LINE__); \
-- } \
--
--
--#define CHECK_CONTEXT(ctxt) \
-- if (ctxt == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "%s:%d Internal error: no context\n", \
-- __FILE__, __LINE__); \
-- } \
-- else if (ctxt->doc == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "%s:%d Internal error: no document\n", \
-- __FILE__, __LINE__); \
-- } \
-- else if (ctxt->doc->children == NULL) { \
-- xmlGenericError(xmlGenericErrorContext, \
-- "%s:%d Internal error: document without root\n", \
-- __FILE__, __LINE__); \
-- } \
--
--
--/**
-- * xmlXPathNewParserContext:
-- * @str: the XPath expression
-- * @ctxt: the XPath context
-- *
-- * Create a new xmlXPathParserContext
-- *
-- * Returns the xmlXPathParserContext just allocated.
-- */
--xmlXPathParserContextPtr
--xmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
-- xmlXPathParserContextPtr ret;
--
-- ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathNewParserContext: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
-- ret->cur = ret->base = str;
-- ret->context = ctxt;
--
-- /* Allocate the value stack */
-- ret->valueTab = (xmlXPathObjectPtr *)
-- xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
-- ret->valueNr = 0;
-- ret->valueMax = 10;
-- ret->value = NULL;
-- return(ret);
--}
--
--/**
-- * xmlXPathFreeParserContext:
-- * @ctxt: the context to free
-- *
-- * Free up an xmlXPathParserContext
-- */
--void
--xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
-- if (ctxt->valueTab != NULL) {
--#ifdef DEBUG
-- memset(ctxt->valueTab, 0xB , 10 * (size_t) sizeof(xmlXPathObjectPtr));
--#endif
-- xmlFree(ctxt->valueTab);
-- }
--#ifdef DEBUG
-- memset(ctxt, 0xB , (size_t) sizeof(xmlXPathParserContext));
--#endif
-- xmlFree(ctxt);
--}
--
--/************************************************************************
-- * *
-- * The implicit core function library *
-- * *
-- ************************************************************************/
--
--/*
-- * Auto-pop and cast to a number
-- */
--void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
--
--
--#define POP_FLOAT \
-- arg = valuePop(ctxt); \
-- if (arg == NULL) { \
-- XP_ERROR(XPATH_INVALID_OPERAND); \
-- } \
-- if (arg->type != XPATH_NUMBER) { \
-- valuePush(ctxt, arg); \
-- xmlXPathNumberFunction(ctxt, 1); \
-- arg = valuePop(ctxt); \
-- }
--
--/**
-- * xmlXPathCompareNodeSetFloat:
-- * @ctxt: the XPath Parser context
-- * @inf: less than (1) or greater than (0)
-- * @strict: is the comparison strict
-- * @arg: the node set
-- * @f: the value
-- *
-- * Implement the compare operation between a nodeset and a number
-- * @ns < @val (1, 1, ...
-- * @ns <= @val (1, 0, ...
-- * @ns > @val (0, 1, ...
-- * @ns >= @val (0, 0, ...
-- *
-- * If one object to be compared is a node-set and the other is a number,
-- * then the comparison will be true if and only if there is a node in the
-- * node-set such that the result of performing the comparison on the number
-- * to be compared and on the result of converting the string-value of that
-- * node to a number using the number function is true.
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
-- xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
-- int i, ret = 0;
-- xmlNodeSetPtr ns;
-- xmlChar *str2;
--
-- if ((f == NULL) || (arg == NULL) ||
-- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
-- xmlXPathFreeObject(arg);
-- xmlXPathFreeObject(f);
-- return(0);
-- }
-- ns = arg->nodesetval;
-- for (i = 0;i < ns->nodeNr;i++) {
-- str2 = xmlNodeGetContent(ns->nodeTab[i]);
-- if (str2 != NULL) {
-- valuePush(ctxt,
-- xmlXPathNewString(str2));
-- xmlFree(str2);
-- xmlXPathNumberFunction(ctxt, 1);
-- valuePush(ctxt, xmlXPathObjectCopy(f));
-- ret = xmlXPathCompareValues(ctxt, inf, strict);
-- if (ret)
-- break;
-- }
-- }
-- xmlXPathFreeObject(arg);
-- xmlXPathFreeObject(f);
-- return(ret);
--}
--
--/**
-- * xmlXPathCompareNodeSetString:
-- * @ctxt: the XPath Parser context
-- * @inf: less than (1) or greater than (0)
-- * @strict: is the comparison strict
-- * @arg: the node set
-- * @s: the value
-- *
-- * Implement the compare operation between a nodeset and a string
-- * @ns < @val (1, 1, ...
-- * @ns <= @val (1, 0, ...
-- * @ns > @val (0, 1, ...
-- * @ns >= @val (0, 0, ...
-- *
-- * If one object to be compared is a node-set and the other is a string,
-- * then the comparison will be true if and only if there is a node in
-- * the node-set such that the result of performing the comparison on the
-- * string-value of the node and the other string is true.
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
-- xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
-- int i, ret = 0;
-- xmlNodeSetPtr ns;
-- xmlChar *str2;
--
-- if ((s == NULL) || (arg == NULL) ||
-- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
-- xmlXPathFreeObject(arg);
-- xmlXPathFreeObject(s);
-- return(0);
-- }
-- ns = arg->nodesetval;
-- for (i = 0;i < ns->nodeNr;i++) {
-- str2 = xmlNodeGetContent(ns->nodeTab[i]);
-- if (str2 != NULL) {
-- valuePush(ctxt,
-- xmlXPathNewString(str2));
-- xmlFree(str2);
-- valuePush(ctxt, xmlXPathObjectCopy(s));
-- ret = xmlXPathCompareValues(ctxt, inf, strict);
-- if (ret)
-- break;
-- }
-- }
-- xmlXPathFreeObject(arg);
-- xmlXPathFreeObject(s);
-- return(ret);
--}
--
--/**
-- * xmlXPathCompareNodeSets:
-- * @ctxt: the XPath Parser context
-- * @op: less than (-1), equal (0) or greater than (1)
-- * @strict: is the comparison strict
-- * @ns1: the fist node set
-- * @ns2: the second node set
-- *
-- * Implement the compare operation on nodesets:
-- *
-- * If both objects to be compared are node-sets, then the comparison will be true if
-- * and only if there is a node in the first node-set and a node in the second node-set
-- * such that the result of performing the comparison on the string-values of the two
-- * nodes is true.
-- */
--int
--xmlXPathCompareNodeSets(xmlXPathParserContextPtr ctxt, int inf, int strict,
-- xmlXPathObjectPtr ns1, xmlXPathObjectPtr ns2) {
-- TODO
-- return(0);
--}
--
--/**
-- * xmlXPathCompareNodeSetValue:
-- * @ctxt: the XPath Parser context
-- * @inf: less than (1) or greater than (0)
-- * @strict: is the comparison strict
-- * @arg: the node set
-- * @val: the value
-- *
-- * Implement the compare operation between a nodeset and a value
-- * @ns < @val (1, 1, ...
-- * @ns <= @val (1, 0, ...
-- * @ns > @val (0, 1, ...
-- * @ns >= @val (0, 0, ...
-- *
-- * If one object to be compared is a node-set and the other is a boolean, then the
-- * comparison will be true if and only if the result of performing the comparison
-- * on the boolean and on the result of converting the node-set to a boolean using
-- * the boolean function is true.
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
-- xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
-- if ((val == NULL) || (arg == NULL) ||
-- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
-- return(0);
--
-- switch(val->type) {
-- case XPATH_NUMBER:
-- return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
-- case XPATH_NODESET:
-- case XPATH_XSLT_TREE:
-- return(xmlXPathCompareNodeSets(ctxt, inf, strict, arg, val));
-- case XPATH_STRING:
-- return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
-- case XPATH_BOOLEAN:
-- valuePush(ctxt, arg);
-- xmlXPathBooleanFunction(ctxt, 1);
-- valuePush(ctxt, val);
-- return(xmlXPathCompareValues(ctxt, inf, strict));
-- default:
-- TODO
-- return(0);
-- }
-- return(0);
--}
--
--/**
-- * xmlXPathEqualNodeSetString
-- * @arg: the nodeset object argument
-- * @str: the string to compare to.
-- *
-- * Implement the equal operation on XPath objects content: @arg1 == @arg2
-- * If one object to be compared is a node-set and the other is a string,
-- * then the comparison will be true if and only if there is a node in
-- * the node-set such that the result of performing the comparison on the
-- * string-value of the node and the other string is true.
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar *str) {
-- int i;
-- xmlNodeSetPtr ns;
-- xmlChar *str2;
--
-- if ((str == NULL) || (arg == NULL) ||
-- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
-- return(0);
-- ns = arg->nodesetval;
-- for (i = 0;i < ns->nodeNr;i++) {
-- str2 = xmlNodeGetContent(ns->nodeTab[i]);
-- if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
-- xmlFree(str2);
-- return(1);
-- }
-- xmlFree(str2);
-- }
-- return(0);
--}
--
--/**
-- * xmlXPathEqualNodeSetFloat
-- * @arg: the nodeset object argument
-- * @f: the float to compare to
-- *
-- * Implement the equal operation on XPath objects content: @arg1 == @arg2
-- * If one object to be compared is a node-set and the other is a number,
-- * then the comparison will be true if and only if there is a node in
-- * the node-set such that the result of performing the comparison on the
-- * number to be compared and on the result of converting the string-value
-- * of that node to a number using the number function is true.
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathEqualNodeSetFloat(xmlXPathObjectPtr arg, float f) {
-- char buf[100] = "";
--
-- if ((arg == NULL) ||
-- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
-- return(0);
--
-- if (isnan(f))
-- sprintf(buf, "NaN");
-- else if (isinf(f) > 0)
-- sprintf(buf, "+Infinity");
-- else if (isinf(f) < 0)
-- sprintf(buf, "-Infinity");
-- else
-- sprintf(buf, "%0g", f);
--
-- return(xmlXPathEqualNodeSetString(arg, BAD_CAST buf));
--}
--
--
--/**
-- * xmlXPathEqualNodeSets
-- * @arg1: first nodeset object argument
-- * @arg2: second nodeset object argument
-- *
-- * Implement the equal operation on XPath nodesets: @arg1 == @arg2
-- * If both objects to be compared are node-sets, then the comparison
-- * will be true if and only if there is a node in the first node-set and
-- * a node in the second node-set such that the result of performing the
-- * comparison on the string-values of the two nodes is true.
-- *
-- * (needless to say, this is a costly operation)
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
-- int i;
-- xmlNodeSetPtr ns;
-- xmlChar *str;
--
-- if ((arg1 == NULL) ||
-- ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
-- return(0);
-- if ((arg2 == NULL) ||
-- ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
-- return(0);
--
-- ns = arg1->nodesetval;
-- for (i = 0;i < ns->nodeNr;i++) {
-- str = xmlNodeGetContent(ns->nodeTab[i]);
-- if ((str != NULL) && (xmlXPathEqualNodeSetString(arg2, str))) {
-- xmlFree(str);
-- return(1);
-- }
-- xmlFree(str);
-- }
-- return(0);
--}
--
--/**
-- * xmlXPathEqualValues:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the equal operation on XPath objects content: @arg1 == @arg2
-- *
-- * Returns 0 or 1 depending on the results of the test.
-- */
--int
--xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg1, arg2;
-- int ret = 0;
--
-- arg1 = valuePop(ctxt);
-- if (arg1 == NULL)
-- XP_ERROR0(XPATH_INVALID_OPERAND);
--
-- arg2 = valuePop(ctxt);
-- if (arg2 == NULL) {
-- xmlXPathFreeObject(arg1);
-- XP_ERROR0(XPATH_INVALID_OPERAND);
-- }
--
-- if (arg1 == arg2) {
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: by pointer\n");
--#endif
-- return(1);
-- }
--
-- switch (arg1->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: undefined\n");
--#endif
-- break;
-- case XPATH_XSLT_TREE:
-- case XPATH_NODESET:
-- switch (arg2->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: undefined\n");
--#endif
-- break;
-- case XPATH_XSLT_TREE:
-- case XPATH_NODESET:
-- ret = xmlXPathEqualNodeSets(arg1, arg2);
-- break;
-- case XPATH_BOOLEAN:
-- if ((arg1->nodesetval == NULL) ||
-- (arg1->nodesetval->nodeNr == 0)) ret = 0;
-- else
-- ret = 1;
-- ret = (ret == arg2->boolval);
-- break;
-- case XPATH_NUMBER:
-- ret = xmlXPathEqualNodeSetFloat(arg1, arg2->floatval);
-- break;
-- case XPATH_STRING:
-- ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
-- break;
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- break;
-- }
-- break;
-- case XPATH_BOOLEAN:
-- switch (arg2->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: undefined\n");
--#endif
-- break;
-- case XPATH_NODESET:
-- case XPATH_XSLT_TREE:
-- if ((arg2->nodesetval == NULL) ||
-- (arg2->nodesetval->nodeNr == 0)) ret = 0;
-- else
-- ret = 1;
-- break;
-- case XPATH_BOOLEAN:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: %d boolean %d \n",
-- arg1->boolval, arg2->boolval);
--#endif
-- ret = (arg1->boolval == arg2->boolval);
-- break;
-- case XPATH_NUMBER:
-- if (arg2->floatval) ret = 1;
-- else ret = 0;
-- ret = (arg1->boolval == ret);
-- break;
-- case XPATH_STRING:
-- if ((arg2->stringval == NULL) ||
-- (arg2->stringval[0] == 0)) ret = 0;
-- else
-- ret = 1;
-- ret = (arg1->boolval == ret);
-- break;
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- break;
-- }
-- break;
-- case XPATH_NUMBER:
-- switch (arg2->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: undefined\n");
--#endif
-- break;
-- case XPATH_NODESET:
-- case XPATH_XSLT_TREE:
-- ret = xmlXPathEqualNodeSetFloat(arg2, arg1->floatval);
-- break;
-- case XPATH_BOOLEAN:
-- if (arg1->floatval) ret = 1;
-- else ret = 0;
-- ret = (arg2->boolval == ret);
-- break;
-- case XPATH_STRING:
-- valuePush(ctxt, arg2);
-- xmlXPathNumberFunction(ctxt, 1);
-- arg2 = valuePop(ctxt);
-- /* no break on purpose */
-- case XPATH_NUMBER:
-- ret = (arg1->floatval == arg2->floatval);
-- break;
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- break;
-- }
-- break;
-- case XPATH_STRING:
-- switch (arg2->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "Equal: undefined\n");
--#endif
-- break;
-- case XPATH_NODESET:
-- case XPATH_XSLT_TREE:
-- ret = xmlXPathEqualNodeSetString(arg2, arg1->stringval);
-- break;
-- case XPATH_BOOLEAN:
-- if ((arg1->stringval == NULL) ||
-- (arg1->stringval[0] == 0)) ret = 0;
-- else
-- ret = 1;
-- ret = (arg2->boolval == ret);
-- break;
-- case XPATH_STRING:
-- ret = xmlStrEqual(arg1->stringval, arg2->stringval);
-- break;
-- case XPATH_NUMBER:
-- valuePush(ctxt, arg1);
-- xmlXPathNumberFunction(ctxt, 1);
-- arg1 = valuePop(ctxt);
-- ret = (arg1->floatval == arg2->floatval);
-- break;
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- break;
-- }
-- break;
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- break;
-- }
-- xmlXPathFreeObject(arg1);
-- xmlXPathFreeObject(arg2);
-- return(ret);
--}
--
--
--/**
-- * xmlXPathCompareValues:
-- * @ctxt: the XPath Parser context
-- * @inf: less than (1) or greater than (0)
-- * @strict: is the comparison strict
-- *
-- * Implement the compare operation on XPath objects:
-- * @arg1 < @arg2 (1, 1, ...
-- * @arg1 <= @arg2 (1, 0, ...
-- * @arg1 > @arg2 (0, 1, ...
-- * @arg1 >= @arg2 (0, 0, ...
-- *
-- * When neither object to be compared is a node-set and the operator is
-- * <=, <, >=, >, then the objects are compared by converted both objects
-- * to numbers and comparing the numbers according to IEEE 754. The <
-- * comparison will be true if and only if the first number is less than the
-- * second number. The <= comparison will be true if and only if the first
-- * number is less than or equal to the second number. The > comparison
-- * will be true if and only if the first number is greater than the second
-- * number. The >= comparison will be true if and only if the first number
-- * is greater than or equal to the second number.
-- *
-- * Returns 1 if the comparaison succeeded, 0 if it failed
-- */
--int
--xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
-- int ret = 0;
-- xmlXPathObjectPtr arg1, arg2;
--
-- arg2 = valuePop(ctxt);
-- if (arg2 == NULL) {
-- XP_ERROR0(XPATH_INVALID_OPERAND);
-- }
--
-- arg1 = valuePop(ctxt);
-- if (arg1 == NULL) {
-- xmlXPathFreeObject(arg2);
-- XP_ERROR0(XPATH_INVALID_OPERAND);
-- }
--
-- if ((arg2->type == XPATH_NODESET) || (arg1->type == XPATH_NODESET)) {
-- if ((arg2->type == XPATH_NODESET) && (arg1->type == XPATH_NODESET)) {
-- ret = xmlXPathCompareNodeSets(ctxt, inf, strict, arg1, arg2);
-- } else {
-- if (arg1->type == XPATH_NODESET) {
-- ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, arg1, arg2);
-- } else {
-- ret = xmlXPathCompareNodeSetValue(ctxt, !inf, !strict, arg2, arg2);
-- }
-- }
-- return(ret);
-- }
--
-- if (arg1->type != XPATH_NUMBER) {
-- valuePush(ctxt, arg1);
-- xmlXPathNumberFunction(ctxt, 1);
-- arg1 = valuePop(ctxt);
-- }
-- if (arg1->type != XPATH_NUMBER) {
-- xmlXPathFreeObject(arg1);
-- xmlXPathFreeObject(arg2);
-- XP_ERROR0(XPATH_INVALID_OPERAND);
-- }
-- if (arg2->type != XPATH_NUMBER) {
-- valuePush(ctxt, arg2);
-- xmlXPathNumberFunction(ctxt, 1);
-- arg2 = valuePop(ctxt);
-- }
-- if (arg2->type != XPATH_NUMBER) {
-- xmlXPathFreeObject(arg1);
-- xmlXPathFreeObject(arg2);
-- XP_ERROR0(XPATH_INVALID_OPERAND);
-- }
-- /*
-- * Add tests for infinity and nan
-- * => feedback on 3.4 for Inf and NaN
-- */
-- if (inf && strict)
-- ret = (arg1->floatval < arg2->floatval);
-- else if (inf && !strict)
-- ret = (arg1->floatval <= arg2->floatval);
-- else if (!inf && strict)
-- ret = (arg1->floatval > arg2->floatval);
-- else if (!inf && !strict)
-- ret = (arg1->floatval >= arg2->floatval);
-- xmlXPathFreeObject(arg1);
-- xmlXPathFreeObject(arg2);
-- return(ret);
--}
--
--/**
-- * xmlXPathValueFlipSign:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the unary - operation on an XPath object
-- * The numeric operators convert their operands to numbers as if
-- * by calling the number function.
-- */
--void
--xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg;
--
-- POP_FLOAT
-- arg->floatval = -arg->floatval;
-- valuePush(ctxt, arg);
--}
--
--/**
-- * xmlXPathAddValues:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the add operation on XPath objects:
-- * The numeric operators convert their operands to numbers as if
-- * by calling the number function.
-- */
--void
--xmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg;
-- double val;
--
-- POP_FLOAT
-- val = arg->floatval;
-- xmlXPathFreeObject(arg);
--
-- POP_FLOAT
-- arg->floatval += val;
-- valuePush(ctxt, arg);
--}
--
--/**
-- * xmlXPathSubValues:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the substraction operation on XPath objects:
-- * The numeric operators convert their operands to numbers as if
-- * by calling the number function.
-- */
--void
--xmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg;
-- double val;
--
-- POP_FLOAT
-- val = arg->floatval;
-- xmlXPathFreeObject(arg);
--
-- POP_FLOAT
-- arg->floatval -= val;
-- valuePush(ctxt, arg);
--}
--
--/**
-- * xmlXPathMultValues:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the multiply operation on XPath objects:
-- * The numeric operators convert their operands to numbers as if
-- * by calling the number function.
-- */
--void
--xmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg;
-- double val;
--
-- POP_FLOAT
-- val = arg->floatval;
-- xmlXPathFreeObject(arg);
--
-- POP_FLOAT
-- arg->floatval *= val;
-- valuePush(ctxt, arg);
--}
--
--/**
-- * xmlXPathDivValues:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the div operation on XPath objects @arg1 / @arg2:
-- * The numeric operators convert their operands to numbers as if
-- * by calling the number function.
-- */
--void
--xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg;
-- double val;
--
-- POP_FLOAT
-- val = arg->floatval;
-- xmlXPathFreeObject(arg);
--
-- POP_FLOAT
-- arg->floatval /= val;
-- valuePush(ctxt, arg);
--}
--
--/**
-- * xmlXPathModValues:
-- * @ctxt: the XPath Parser context
-- *
-- * Implement the mod operation on XPath objects: @arg1 / @arg2
-- * The numeric operators convert their operands to numbers as if
-- * by calling the number function.
-- */
--void
--xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
-- xmlXPathObjectPtr arg;
-- int arg1, arg2;
--
-- POP_FLOAT
-- arg2 = (int) arg->floatval;
-- xmlXPathFreeObject(arg);
--
-- POP_FLOAT
-- arg1 = (int) arg->floatval;
-- arg->floatval = arg1 % arg2;
-- valuePush(ctxt, arg);
--}
--
--/************************************************************************
-- * *
-- * The traversal functions *
-- * *
-- ************************************************************************/
--
--typedef enum {
-- AXIS_ANCESTOR = 1,
-- AXIS_ANCESTOR_OR_SELF,
-- AXIS_ATTRIBUTE,
-- AXIS_CHILD,
-- AXIS_DESCENDANT,
-- AXIS_DESCENDANT_OR_SELF,
-- AXIS_FOLLOWING,
-- AXIS_FOLLOWING_SIBLING,
-- AXIS_NAMESPACE,
-- AXIS_PARENT,
-- AXIS_PRECEDING,
-- AXIS_PRECEDING_SIBLING,
-- AXIS_SELF
--} xmlXPathAxisVal;
--
--/*
-- * A traversal function enumerates nodes along an axis.
-- * Initially it must be called with NULL, and it indicates
-- * termination on the axis by returning NULL.
-- */
--typedef xmlNodePtr (*xmlXPathTraversalFunction)
-- (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
--
--/**
-- * xmlXPathNextSelf:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "self" direction
-- * The self axis contains just the context node itself
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur == NULL)
-- return(ctxt->context->node);
-- return(NULL);
--}
--
--/**
-- * xmlXPathNextChild:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "child" direction
-- * The child axis contains the children of the context node in document order.
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur == NULL) {
-- if (ctxt->context->node == NULL) return(NULL);
-- switch (ctxt->context->node->type) {
-- case XML_ELEMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_NOTATION_NODE:
-- case XML_DTD_NODE:
-- return(ctxt->context->node->children);
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return(((xmlDocPtr) ctxt->context->node)->children);
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_ATTRIBUTE_NODE:
-- case XML_NAMESPACE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- return(NULL);
-- }
-- return(NULL);
-- }
-- if ((cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE))
-- return(NULL);
-- return(cur->next);
--}
--
--/**
-- * xmlXPathNextDescendant:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "descendant" direction
-- * the descendant axis contains the descendants of the context node in document
-- * order; a descendant is a child or a child of a child and so on.
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur == NULL) {
-- if (ctxt->context->node == NULL)
-- return(NULL);
-- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-- (ctxt->context->node->type == XML_NAMESPACE_DECL))
-- return(NULL);
--
-- if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
-- return(ctxt->context->doc->children);
-- return(ctxt->context->node->children);
-- }
--
-- if (cur->children != NULL)
-- {
-- if (cur->children->type != XML_ENTITY_DECL)
-- return(cur->children);
-- }
-- if (cur->next != NULL) return(cur->next);
--
-- do {
-- cur = cur->parent;
-- if (cur == NULL) return(NULL);
-- if (cur == ctxt->context->node) return(NULL);
-- if (cur->next != NULL) {
-- cur = cur->next;
-- return(cur);
-- }
-- } while (cur != NULL);
-- return(cur);
--}
--
--/**
-- * xmlXPathNextDescendantOrSelf:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "descendant-or-self" direction
-- * the descendant-or-self axis contains the context node and the descendants
-- * of the context node in document order; thus the context node is the first
-- * node on the axis, and the first child of the context node is the second node
-- * on the axis
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur == NULL) {
-- if (ctxt->context->node == NULL)
-- return(NULL);
-- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-- (ctxt->context->node->type == XML_NAMESPACE_DECL))
-- return(NULL);
-- return(ctxt->context->node);
-- }
--
-- return(xmlXPathNextDescendant(ctxt, cur));
--}
--
--/**
-- * xmlXPathNextParent:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "parent" direction
-- * The parent axis contains the parent of the context node, if there is one.
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- /*
-- * the parent of an attribute or namespace node is the element
-- * to which the attribute or namespace node is attached
-- * Namespace handling !!!
-- */
-- if (cur == NULL) {
-- if (ctxt->context->node == NULL) return(NULL);
-- switch (ctxt->context->node->type) {
-- case XML_ELEMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_NOTATION_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- case XML_ENTITY_DECL:
-- if (ctxt->context->node->parent == NULL)
-- return((xmlNodePtr) ctxt->context->doc);
-- return(ctxt->context->node->parent);
-- case XML_ATTRIBUTE_NODE: {
-- xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
--
-- return(att->parent);
-- }
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return(NULL);
-- case XML_NAMESPACE_DECL:
-- /*
-- * TODO !!! may require extending struct _xmlNs with
-- * parent field
-- * C.f. Infoset case...
-- */
-- return(NULL);
-- }
-- }
-- return(NULL);
--}
--
--/**
-- * xmlXPathNextAncestor:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "ancestor" direction
-- * the ancestor axis contains the ancestors of the context node; the ancestors
-- * of the context node consist of the parent of context node and the parent's
-- * parent and so on; the nodes are ordered in reverse document order; thus the
-- * parent is the first node on the axis, and the parent's parent is the second
-- * node on the axis
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- /*
-- * the parent of an attribute or namespace node is the element
-- * to which the attribute or namespace node is attached
-- * !!!!!!!!!!!!!
-- */
-- if (cur == NULL) {
-- if (ctxt->context->node == NULL) return(NULL);
-- switch (ctxt->context->node->type) {
-- case XML_ELEMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_NOTATION_NODE:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- if (ctxt->context->node->parent == NULL)
-- return((xmlNodePtr) ctxt->context->doc);
-- return(ctxt->context->node->parent);
-- case XML_ATTRIBUTE_NODE: {
-- xmlAttrPtr cur = (xmlAttrPtr) ctxt->context->node;
--
-- return(cur->parent);
-- }
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return(NULL);
-- case XML_NAMESPACE_DECL:
-- /*
-- * TODO !!! may require extending struct _xmlNs with
-- * parent field
-- * C.f. Infoset case...
-- */
-- return(NULL);
-- }
-- return(NULL);
-- }
-- if (cur == ctxt->context->doc->children)
-- return((xmlNodePtr) ctxt->context->doc);
-- if (cur == (xmlNodePtr) ctxt->context->doc)
-- return(NULL);
-- switch (cur->type) {
-- case XML_ELEMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_ENTITY_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_NOTATION_NODE:
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_DECL:
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- return(cur->parent);
-- case XML_ATTRIBUTE_NODE: {
-- xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
--
-- return(att->parent);
-- }
-- case XML_DOCUMENT_NODE:
-- case XML_DOCUMENT_TYPE_NODE:
-- case XML_DOCUMENT_FRAG_NODE:
-- case XML_HTML_DOCUMENT_NODE:
--#ifdef LIBXML_SGML_ENABLED
-- case XML_SGML_DOCUMENT_NODE:
--#endif
-- return(NULL);
-- case XML_NAMESPACE_DECL:
-- /*
-- * TODO !!! may require extending struct _xmlNs with
-- * parent field
-- * C.f. Infoset case...
-- */
-- return(NULL);
-- }
-- return(NULL);
--}
--
--/**
-- * xmlXPathNextAncestorOrSelf:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "ancestor-or-self" direction
-- * he ancestor-or-self axis contains the context node and ancestors of
-- * the context node in reverse document order; thus the context node is
-- * the first node on the axis, and the context node's parent the second;
-- * parent here is defined the same as with the parent axis.
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur == NULL)
-- return(ctxt->context->node);
-- return(xmlXPathNextAncestor(ctxt, cur));
--}
--
--/**
-- * xmlXPathNextFollowingSibling:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "following-sibling" direction
-- * The following-sibling axis contains the following siblings of the context
-- * node in document order.
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-- (ctxt->context->node->type == XML_NAMESPACE_DECL))
-- return(NULL);
-- if (cur == (xmlNodePtr) ctxt->context->doc)
-- return(NULL);
-- if (cur == NULL)
-- return(ctxt->context->node->next);
-- return(cur->next);
--}
--
--/**
-- * xmlXPathNextPrecedingSibling:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "preceding-sibling" direction
-- * The preceding-sibling axis contains the preceding siblings of the context
-- * node in reverse document order; the first preceding sibling is first on the
-- * axis; the sibling preceding that node is the second on the axis and so on.
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-- (ctxt->context->node->type == XML_NAMESPACE_DECL))
-- return(NULL);
-- if (cur == (xmlNodePtr) ctxt->context->doc)
-- return(NULL);
-- if (cur == NULL)
-- return(ctxt->context->node->prev);
-- return(cur->prev);
--}
--
--/**
-- * xmlXPathNextFollowing:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "following" direction
-- * The following axis contains all nodes in the same document as the context
-- * node that are after the context node in document order, excluding any
-- * descendants and excluding attribute nodes and namespace nodes; the nodes
-- * are ordered in document order
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur != NULL && cur->children != NULL)
-- return cur->children ;
-- if (cur == NULL) cur = ctxt->context->node;
-- if (cur == NULL) return(NULL) ; /* ERROR */
-- if (cur->next != NULL) return(cur->next) ;
-- do {
-- cur = cur->parent;
-- if (cur == NULL) return(NULL);
-- if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
-- if (cur->next != NULL) return(cur->next);
-- } while (cur != NULL);
-- return(cur);
--}
--
--/*
-- * xmlXPathIsAncestor:
-- * @ancestor: the ancestor node
-- * @node: the current node
-- *
-- * Check that @ancestor is a @node's ancestor
-- *
-- * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
-- */
--static int
--xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
-- if ((ancestor == NULL) || (node == NULL)) return(0);
-- /* nodes need to be in the same document */
-- if (ancestor->doc != node->doc) return(0);
-- /* avoid searching if ancestor or node is the root node */
-- if (ancestor == (xmlNodePtr) node->doc) return(1);
-- if (node == (xmlNodePtr) ancestor->doc) return(0);
-- while (node->parent != NULL) {
-- if (node->parent == ancestor)
-- return(1);
-- node = node->parent;
-- }
-- return(0);
--}
--
--/**
-- * xmlXPathNextPreceding:
-- * @ctxt: the XPath Parser context
-- * @cur: the current node in the traversal
-- *
-- * Traversal function for the "preceding" direction
-- * the preceding axis contains all nodes in the same document as the context
-- * node that are before the context node in document order, excluding any
-- * ancestors and excluding attribute nodes and namespace nodes; the nodes are
-- * ordered in reverse document order
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (cur == NULL)
-- cur = ctxt->context->node ;
-- do {
-- if (cur->prev != NULL) {
-- for (cur = cur->prev ; cur->last != NULL ; cur = cur->last)
-- ;
-- return(cur) ;
-- }
--
-- cur = cur->parent;
-- if (cur == NULL) return(NULL);
-- if (cur == ctxt->context->doc->children) return(NULL);
-- } while (xmlXPathIsAncestor(cur, ctxt->context->node));
-- return(cur);
--}
--
--/**
-- * xmlXPathNextNamespace:
-- * @ctxt: the XPath Parser context
-- * @cur: the current attribute in the traversal
-- *
-- * Traversal function for the "namespace" direction
-- * the namespace axis contains the namespace nodes of the context node;
-- * the order of nodes on this axis is implementation-defined; the axis will
-- * be empty unless the context node is an element
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
-- if ((cur == NULL) || (ctxt->context->namespaces == NULL)) {
-- if (ctxt->context->namespaces != NULL)
-- xmlFree(ctxt->context->namespaces);
-- ctxt->context->namespaces =
-- xmlGetNsList(ctxt->context->doc, ctxt->context->node);
-- if (ctxt->context->namespaces == NULL) return(NULL);
-- ctxt->context->nsNr = 0;
-- }
-- return((xmlNodePtr)ctxt->context->namespaces[ctxt->context->nsNr++]);
--}
--
--/**
-- * xmlXPathNextAttribute:
-- * @ctxt: the XPath Parser context
-- * @cur: the current attribute in the traversal
-- *
-- * Traversal function for the "attribute" direction
-- * TODO: support DTD inherited default attributes
-- *
-- * Returns the next element following that axis
-- */
--xmlNodePtr
--xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-- if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
-- if (cur == NULL) {
-- if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
-- return(NULL);
-- return((xmlNodePtr)ctxt->context->node->properties);
-- }
-- return((xmlNodePtr)cur->next);
--}
--
--/************************************************************************
-- * *
-- * NodeTest Functions *
-- * *
-- ************************************************************************/
--
--typedef enum {
-- NODE_TEST_NONE = 0,
-- NODE_TEST_TYPE = 1,
-- NODE_TEST_PI = 2,
-- NODE_TEST_ALL = 3,
-- NODE_TEST_NS = 4,
-- NODE_TEST_NAME = 5
--} xmlXPathTestVal;
--
--typedef enum {
-- NODE_TYPE_NODE = 0,
-- NODE_TYPE_COMMENT = XML_COMMENT_NODE,
-- NODE_TYPE_TEXT = XML_TEXT_NODE,
-- NODE_TYPE_PI = XML_PI_NODE
--} xmlXPathTypeVal;
--
--#define IS_FUNCTION 200
--
--/**
-- * xmlXPathNodeCollectAndTest:
-- * @ctxt: the XPath Parser context
-- * @axis: the XPath axis
-- * @test: the XPath test
-- * @type: the XPath type
-- * @prefix: the namesapce prefix if any
-- * @name: the name used in the search if any
-- *
-- * This is the function implementing a step: based on the current list
-- * of nodes, it builds up a new list, looking at all nodes under that
-- * axis and selecting them.
-- *
-- * Returns the new NodeSet resulting from the search.
-- */
--void
--xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
-- xmlXPathTestVal test, xmlXPathTypeVal type,
-- const xmlChar *prefix, const xmlChar *name) {
--#ifdef DEBUG_STEP
-- int n = 0, t = 0;
--#endif
-- int i;
-- xmlNodeSetPtr ret;
-- xmlXPathTraversalFunction next = NULL;
-- void (*addNode)(xmlNodeSetPtr, xmlNodePtr);
-- xmlNodePtr cur = NULL;
-- xmlXPathObjectPtr obj;
-- xmlNodeSetPtr nodelist;
--
-- CHECK_TYPE(XPATH_NODESET);
-- obj = valuePop(ctxt);
-- addNode = xmlXPathNodeSetAdd;
--
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "new step : ");
--#endif
-- switch (axis) {
-- case AXIS_ANCESTOR:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'ancestors' ");
--#endif
-- next = xmlXPathNextAncestor; break;
-- case AXIS_ANCESTOR_OR_SELF:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'ancestors-or-self' ");
--#endif
-- next = xmlXPathNextAncestorOrSelf; break;
-- case AXIS_ATTRIBUTE:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'attributes' ");
--#endif
-- next = xmlXPathNextAttribute; break;
-- break;
-- case AXIS_CHILD:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'child' ");
--#endif
-- next = xmlXPathNextChild; break;
-- case AXIS_DESCENDANT:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'descendant' ");
--#endif
-- next = xmlXPathNextDescendant; break;
-- case AXIS_DESCENDANT_OR_SELF:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'descendant-or-self' ");
--#endif
-- next = xmlXPathNextDescendantOrSelf; break;
-- case AXIS_FOLLOWING:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'following' ");
--#endif
-- next = xmlXPathNextFollowing; break;
-- case AXIS_FOLLOWING_SIBLING:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'following-siblings' ");
--#endif
-- next = xmlXPathNextFollowingSibling; break;
-- case AXIS_NAMESPACE:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'namespace' ");
--#endif
-- next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; break;
-- break;
-- case AXIS_PARENT:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'parent' ");
--#endif
-- next = xmlXPathNextParent; break;
-- case AXIS_PRECEDING:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'preceding' ");
--#endif
-- next = xmlXPathNextPreceding; break;
-- case AXIS_PRECEDING_SIBLING:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'preceding-sibling' ");
--#endif
-- next = xmlXPathNextPrecedingSibling; break;
-- case AXIS_SELF:
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "axis 'self' ");
--#endif
-- next = xmlXPathNextSelf; break;
-- }
-- if (next == NULL)
-- return;
--
-- nodelist = obj->nodesetval;
-- if ((nodelist != NULL) &&
-- (nodelist->nodeNr <= 1))
-- addNode = xmlXPathNodeSetAddUnique;
-- else
-- addNode = xmlXPathNodeSetAdd;
-- ret = xmlXPathNodeSetCreate(NULL);
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- " context contains %d nodes\n",
-- nodelist->nodeNr);
-- switch (test) {
-- case NODE_TEST_NODE:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching all nodes\n");
-- break;
-- case NODE_TEST_NONE:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching for none !!!\n");
-- break;
-- case NODE_TEST_TYPE:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching for type %d\n", type);
-- break;
-- case NODE_TEST_PI:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching for PI !!!\n");
-- break;
-- case NODE_TEST_ALL:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching for *\n");
-- break;
-- case NODE_TEST_NS:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching for namespace %s\n",
-- prefix);
-- break;
-- case NODE_TEST_NAME:
-- xmlGenericError(xmlGenericErrorContext,
-- " searching for name %s\n", name);
-- if (prefix != NULL)
-- xmlGenericError(xmlGenericErrorContext,
-- " with namespace %s\n",
-- prefix);
-- break;
-- }
-- xmlGenericError(xmlGenericErrorContext, "Testing : ");
--#endif
-- /*
-- * 2.3 Node Tests
-- * - For the attribute axis, the principal node type is attribute.
-- * - For the namespace axis, the principal node type is namespace.
-- * - For other axes, the principal node type is element.
-- *
-- * A node test * is true for any node of the
-- * principal node type. For example, child::* willi
-- * select all element children of the context node
-- */
-- for (i = 0;i < nodelist->nodeNr; i++) {
-- ctxt->context->node = nodelist->nodeTab[i];
--
-- cur = NULL;
-- do {
-- cur = next(ctxt, cur);
-- if (cur == NULL) break;
--#ifdef DEBUG_STEP
-- t++;
-- xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
--#endif
-- switch (test) {
-- case NODE_TEST_NONE:
-- STRANGE
-- return;
-- case NODE_TEST_TYPE:
-- if ((cur->type == type) ||
-- ((type == NODE_TYPE_NODE) &&
-- ((cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE) ||
-- (cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_PI_NODE) ||
-- (cur->type == XML_COMMENT_NODE) ||
-- (cur->type == XML_CDATA_SECTION_NODE) ||
-- (cur->type == XML_TEXT_NODE)))) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- break;
-- case NODE_TEST_PI:
-- if (cur->type == XML_PI_NODE) {
-- if ((name != NULL) &&
-- (!xmlStrEqual(name, cur->name)))
-- break;
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- break;
-- case NODE_TEST_ALL:
-- if (axis == AXIS_ATTRIBUTE) {
-- if (cur->type == XML_ATTRIBUTE_NODE) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- } else if (axis == AXIS_NAMESPACE) {
-- if (cur->type == XML_NAMESPACE_DECL) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- } else {
-- if ((cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- if (prefix == NULL) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- } else if ((cur->ns != NULL) &&
-- (xmlStrEqual(prefix,
-- cur->ns->href))) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- }
-- }
-- break;
-- case NODE_TEST_NS: {
-- TODO;
-- break;
-- }
-- case NODE_TEST_NAME:
-- switch (cur->type) {
-- case XML_ELEMENT_NODE:
-- if (xmlStrEqual(name, cur->name)) {
-- if (prefix == NULL) {
-- if ((cur->ns == NULL) ||
-- (cur->ns->prefix == NULL)) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- } else {
-- if ((cur->ns != NULL) &&
-- (xmlStrEqual(prefix,
-- cur->ns->href))) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- }
-- }
-- break;
-- case XML_ATTRIBUTE_NODE: {
-- xmlAttrPtr attr = (xmlAttrPtr) cur;
-- if (xmlStrEqual(name, attr->name)) {
--#ifdef DEBUG_STEP
-- n++;
--#endif
-- addNode(ret, cur);
-- }
-- break;
-- }
-- case XML_NAMESPACE_DECL: {
-- TODO;
-- break;
-- }
-- default:
-- break;
-- }
-- break;
-- }
-- } while (cur != NULL);
-- }
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "\nExamined %d nodes, found %d nodes at that step\n", t, n);
--#endif
-- xmlXPathFreeObject(obj);
-- valuePush(ctxt, xmlXPathWrapNodeSet(ret));
--}
--
--
--/************************************************************************
-- * *
-- * Implicit tree core function library *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPathRoot:
-- * @ctxt: the XPath Parser context
-- *
-- * Initialize the context to the root of the document
-- */
--void
--xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
-- ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
--}
--
--/************************************************************************
-- * *
-- * The explicit core function library *
-- *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib *
-- * *
-- ************************************************************************/
--
--
--/**
-- * xmlXPathLastFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the last() XPath function
-- * number last()
-- * The last function returns the number of nodes in the context node list.
-- */
--void
--xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- CHECK_ARITY(0);
-- if (ctxt->context->contextSize > 0) {
-- valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize));
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext,
-- "last() : %d\n", ctxt->context->contextSize);
--#endif
-- } else {
-- XP_ERROR(XPATH_INVALID_CTXT_SIZE);
-- }
--}
--
--/**
-- * xmlXPathPositionFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the position() XPath function
-- * number position()
-- * The position function returns the position of the context node in the
-- * context node list. The first position is 1, and so the last positionr
-- * will be equal to last().
-- */
--void
--xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- CHECK_ARITY(0);
-- if (ctxt->context->proximityPosition >= 0) {
-- valuePush(ctxt,
-- xmlXPathNewFloat((double) ctxt->context->proximityPosition));
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
-- ctxt->context->proximityPosition);
--#endif
-- } else {
-- XP_ERROR(XPATH_INVALID_CTXT_POSITION);
-- }
--}
--
--/**
-- * xmlXPathCountFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the count() XPath function
-- * number count(node-set)
-- */
--void
--xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_XSLT_TREE)))
-- XP_ERROR(XPATH_INVALID_TYPE);
-- cur = valuePop(ctxt);
--
-- valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr));
-- xmlXPathFreeObject(cur);
--}
--
--/**
-- * xmlXPathIdFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the id() XPath function
-- * node-set id(object)
-- * The id function selects elements by their unique ID
-- * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
-- * then the result is the union of the result of applying id to the
-- * string value of each of the nodes in the argument node-set. When the
-- * argument to id is of any other type, the argument is converted to a
-- * string as if by a call to the string function; the string is split
-- * into a whitespace-separated list of tokens (whitespace is any sequence
-- * of characters matching the production S); the result is a node-set
-- * containing the elements in the same document as the context node that
-- * have a unique ID equal to any of the tokens in the list.
-- */
--void
--xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- const xmlChar *tokens;
-- const xmlChar *cur;
-- xmlChar *ID;
-- xmlAttrPtr attr;
-- xmlNodePtr elem = NULL;
-- xmlXPathObjectPtr ret, obj;
--
-- CHECK_ARITY(1);
-- obj = valuePop(ctxt);
-- if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
-- if (obj->type == XPATH_NODESET) {
-- xmlXPathObjectPtr newobj;
-- int i;
--
-- ret = xmlXPathNewNodeSet(NULL);
--
-- for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-- valuePush(ctxt,
-- xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
-- xmlXPathStringFunction(ctxt, 1);
-- xmlXPathIdFunction(ctxt, 1);
-- newobj = valuePop(ctxt);
-- ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
-- newobj->nodesetval);
-- xmlXPathFreeObject(newobj);
-- }
--
-- xmlXPathFreeObject(obj);
-- valuePush(ctxt, ret);
-- return;
-- }
-- if (obj->type != XPATH_STRING) {
-- valuePush(ctxt, obj);
-- xmlXPathStringFunction(ctxt, 1);
-- obj = valuePop(ctxt);
-- if (obj->type != XPATH_STRING) {
-- xmlXPathFreeObject(obj);
-- return;
-- }
-- }
-- tokens = obj->stringval;
--
-- ret = xmlXPathNewNodeSet(NULL);
-- valuePush(ctxt, ret);
-- if (tokens == NULL) {
-- xmlXPathFreeObject(obj);
-- return;
-- }
--
-- cur = tokens;
--
-- while (IS_BLANK(*cur)) cur++;
-- while (*cur != 0) {
-- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
-- (*cur == '.') || (*cur == '-') ||
-- (*cur == '_') || (*cur == ':') ||
-- (IS_COMBINING(*cur)) ||
-- (IS_EXTENDER(*cur)))
-- cur++;
--
-- if ((!IS_BLANK(*cur)) && (*cur != 0)) break;
--
-- ID = xmlStrndup(tokens, cur - tokens);
-- attr = xmlGetID(ctxt->context->doc, ID);
-- if (attr != NULL) {
-- elem = attr->parent;
-- xmlXPathNodeSetAdd(ret->nodesetval, elem);
-- }
-- if (ID != NULL)
-- xmlFree(ID);
--
-- while (IS_BLANK(*cur)) cur++;
-- tokens = cur;
-- }
-- xmlXPathFreeObject(obj);
-- return;
--}
--
--/**
-- * xmlXPathLocalNameFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the local-name() XPath function
-- * string local-name(node-set?)
-- * The local-name function returns a string containing the local part
-- * of the name of the node in the argument node-set that is first in
-- * document order. If the node-set is empty or the first node has no
-- * name, an empty string is returned. If the argument is omitted it
-- * defaults to the context node.
-- */
--void
--xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
--
-- if (nargs == 0) {
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-- nargs = 1;
-- }
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_XSLT_TREE)))
-- XP_ERROR(XPATH_INVALID_TYPE);
-- cur = valuePop(ctxt);
--
-- if (cur->nodesetval->nodeNr == 0) {
-- valuePush(ctxt, xmlXPathNewCString(""));
-- } else {
-- int i = 0; /* Should be first in document order !!!!! */
-- switch (cur->nodesetval->nodeTab[i]->type) {
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- case XML_PI_NODE:
-- valuePush(ctxt,
-- xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
-- break;
-- case XML_NAMESPACE_DECL:
-- valuePush(ctxt, xmlXPathNewString(
-- ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
-- break;
-- default:
-- valuePush(ctxt, xmlXPathNewCString(""));
-- }
-- }
-- xmlXPathFreeObject(cur);
--}
--
--/**
-- * xmlXPathNamespaceURIFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the namespace-uri() XPath function
-- * string namespace-uri(node-set?)
-- * The namespace-uri function returns a string containing the
-- * namespace URI of the expanded name of the node in the argument
-- * node-set that is first in document order. If the node-set is empty,
-- * the first node has no name, or the expanded name has no namespace
-- * URI, an empty string is returned. If the argument is omitted it
-- * defaults to the context node.
-- */
--void
--xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
--
-- if (nargs == 0) {
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-- nargs = 1;
-- }
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_XSLT_TREE)))
-- XP_ERROR(XPATH_INVALID_TYPE);
-- cur = valuePop(ctxt);
--
-- if (cur->nodesetval->nodeNr == 0) {
-- valuePush(ctxt, xmlXPathNewCString(""));
-- } else {
-- int i = 0; /* Should be first in document order !!!!! */
-- switch (cur->nodesetval->nodeTab[i]->type) {
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- if (cur->nodesetval->nodeTab[i]->ns == NULL)
-- valuePush(ctxt, xmlXPathNewCString(""));
-- else
-- valuePush(ctxt, xmlXPathNewString(
-- cur->nodesetval->nodeTab[i]->ns->href));
-- break;
-- default:
-- valuePush(ctxt, xmlXPathNewCString(""));
-- }
-- }
-- xmlXPathFreeObject(cur);
--}
--
--/**
-- * xmlXPathNameFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the name() XPath function
-- * string name(node-set?)
-- * The name function returns a string containing a QName representing
-- * the name of the node in the argument node-set that is first in documenti
-- * order. The QName must represent the name with respect to the namespace
-- * declarations in effect on the node whose name is being represented.
-- * Typically, this will be the form in which the name occurred in the XML
-- * source. This need not be the case if there are namespace declarations
-- * in effect on the node that associate multiple prefixes with the same
-- * namespace. However, an implementation may include information about
-- * the original prefix in its representation of nodes; in this case, an
-- * implementation can ensure that the returned string is always the same
-- * as the QName used in the XML source. If the argument it omitted it
-- * defaults to the context node.
-- * Libxml keep the original prefix so the "real qualified name" used is
-- * returned.
-- */
--void
--xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
--
-- if (nargs == 0) {
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-- nargs = 1;
-- }
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_XSLT_TREE)))
-- XP_ERROR(XPATH_INVALID_TYPE);
-- cur = valuePop(ctxt);
--
-- if (cur->nodesetval->nodeNr == 0) {
-- valuePush(ctxt, xmlXPathNewCString(""));
-- } else {
-- int i = 0; /* Should be first in document order !!!!! */
--
-- switch (cur->nodesetval->nodeTab[i]->type) {
-- case XML_ELEMENT_NODE:
-- case XML_ATTRIBUTE_NODE:
-- if (cur->nodesetval->nodeTab[i]->ns == NULL)
-- valuePush(ctxt, xmlXPathNewString(
-- cur->nodesetval->nodeTab[i]->name));
--
-- else {
-- char name[2000];
--#ifdef HAVE_SNPRINTF
-- snprintf(name, sizeof(name), "%s:%s",
-- (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
-- (char *) cur->nodesetval->nodeTab[i]->name);
--#else
-- sprintf(name, "%s:%s",
-- (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
-- (char *) cur->nodesetval->nodeTab[i]->name);
--#endif
-- name[sizeof(name) - 1] = 0;
-- valuePush(ctxt, xmlXPathNewCString(name));
-- }
-- break;
-- default:
-- valuePush(ctxt,
-- xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
-- xmlXPathLocalNameFunction(ctxt, 1);
-- }
-- }
-- xmlXPathFreeObject(cur);
--}
--
--/**
-- * xmlXPathStringFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the string() XPath function
-- * string string(object?)
-- * he string function converts an object to a string as follows:
-- * - A node-set is converted to a string by returning the value of
-- * the node in the node-set that is first in document order.
-- * If the node-set is empty, an empty string is returned.
-- * - A number is converted to a string as follows
-- * + NaN is converted to the string NaN
-- * + positive zero is converted to the string 0
-- * + negative zero is converted to the string 0
-- * + positive infinity is converted to the string Infinity
-- * + negative infinity is converted to the string -Infinity
-- * + if the number is an integer, the number is represented in
-- * decimal form as a Number with no decimal point and no leading
-- * zeros, preceded by a minus sign (-) if the number is negative
-- * + otherwise, the number is represented in decimal form as a
-- * Number including a decimal point with at least one digit
-- * before the decimal point and at least one digit after the
-- * decimal point, preceded by a minus sign (-) if the number
-- * is negative; there must be no leading zeros before the decimal
-- * point apart possibly from the one required digit immediatelyi
-- * before the decimal point; beyond the one required digit
-- * after the decimal point there must be as many, but only as
-- * many, more digits as are needed to uniquely distinguish the
-- * number from all other IEEE 754 numeric values.
-- * - The boolean false value is converted to the string false.
-- * The boolean true value is converted to the string true.
-- *
-- * If the argument is omitted, it defaults to a node-set with the
-- * context node as its only member.
-- */
--void
--xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
--
-- if (nargs == 0) {
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-- nargs = 1;
-- }
--
-- CHECK_ARITY(1);
-- cur = valuePop(ctxt);
-- if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
-- switch (cur->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
--#endif
-- valuePush(ctxt, xmlXPathNewCString(""));
-- break;
-- case XPATH_XSLT_TREE:
-- case XPATH_NODESET:
-- if (cur->nodesetval->nodeNr == 0) {
-- valuePush(ctxt, xmlXPathNewCString(""));
-- } else {
-- xmlChar *res;
-- int i = 0; /* Should be first in document order !!!!! */
-- res = xmlNodeGetContent(cur->nodesetval->nodeTab[i]);
-- valuePush(ctxt, xmlXPathNewString(res));
-- if (res != NULL)
-- xmlFree(res);
-- }
-- xmlXPathFreeObject(cur);
-- return;
-- case XPATH_STRING:
-- valuePush(ctxt, cur);
-- return;
-- case XPATH_BOOLEAN:
-- if (cur->boolval) valuePush(ctxt, xmlXPathNewCString("true"));
-- else valuePush(ctxt, xmlXPathNewCString("false"));
-- xmlXPathFreeObject(cur);
-- return;
-- case XPATH_NUMBER: {
-- char buf[100];
--
-- if (isnan(cur->floatval))
-- sprintf(buf, "NaN");
-- else if (isinf(cur->floatval) > 0)
-- sprintf(buf, "+Infinity");
-- else if (isinf(cur->floatval) < 0)
-- sprintf(buf, "-Infinity");
-- else
-- sprintf(buf, "%0g", cur->floatval);
-- valuePush(ctxt, xmlXPathNewCString(buf));
-- xmlXPathFreeObject(cur);
-- return;
-- }
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- valuePush(ctxt, xmlXPathNewCString(""));
-- break;
-- }
-- STRANGE
--}
--
--/**
-- * xmlXPathStringLengthFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the string-length() XPath function
-- * number string-length(string?)
-- * The string-length returns the number of characters in the string
-- * (see [3.6 Strings]). If the argument is omitted, it defaults to
-- * the context node converted to a string, in other words the value
-- * of the context node.
-- */
--void
--xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
--
-- if (nargs == 0) {
-- if (ctxt->context->node == NULL) {
-- valuePush(ctxt, xmlXPathNewFloat(0));
-- } else {
-- xmlChar *content;
--
-- content = xmlNodeGetContent(ctxt->context->node);
-- valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(content)));
-- xmlFree(content);
-- }
-- return;
-- }
-- CHECK_ARITY(1);
-- CAST_TO_STRING;
-- CHECK_TYPE(XPATH_STRING);
-- cur = valuePop(ctxt);
-- valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(cur->stringval)));
-- xmlXPathFreeObject(cur);
--}
--
--/**
-- * xmlXPathConcatFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the concat() XPath function
-- * string concat(string, string, string*)
-- * The concat function returns the concatenation of its arguments.
-- */
--void
--xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur, newobj;
-- xmlChar *tmp;
--
-- if (nargs < 2) {
-- CHECK_ARITY(2);
-- }
--
-- CAST_TO_STRING;
-- cur = valuePop(ctxt);
-- if ((cur == NULL) || (cur->type != XPATH_STRING)) {
-- xmlXPathFreeObject(cur);
-- return;
-- }
-- nargs--;
--
-- while (nargs > 0) {
-- CAST_TO_STRING;
-- newobj = valuePop(ctxt);
-- if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
-- xmlXPathFreeObject(newobj);
-- xmlXPathFreeObject(cur);
-- XP_ERROR(XPATH_INVALID_TYPE);
-- }
-- tmp = xmlStrcat(newobj->stringval, cur->stringval);
-- newobj->stringval = cur->stringval;
-- cur->stringval = tmp;
--
-- xmlXPathFreeObject(newobj);
-- nargs--;
-- }
-- valuePush(ctxt, cur);
--}
--
--/**
-- * xmlXPathContainsFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the contains() XPath function
-- * boolean contains(string, string)
-- * The contains function returns true if the first argument string
-- * contains the second argument string, and otherwise returns false.
-- */
--void
--xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr hay, needle;
--
-- CHECK_ARITY(2);
-- CAST_TO_STRING;
-- CHECK_TYPE(XPATH_STRING);
-- needle = valuePop(ctxt);
-- CAST_TO_STRING;
-- hay = valuePop(ctxt);
-- if ((hay == NULL) || (hay->type != XPATH_STRING)) {
-- xmlXPathFreeObject(hay);
-- xmlXPathFreeObject(needle);
-- XP_ERROR(XPATH_INVALID_TYPE);
-- }
-- if (xmlStrstr(hay->stringval, needle->stringval))
-- valuePush(ctxt, xmlXPathNewBoolean(1));
-- else
-- valuePush(ctxt, xmlXPathNewBoolean(0));
-- xmlXPathFreeObject(hay);
-- xmlXPathFreeObject(needle);
--}
--
--/**
-- * xmlXPathStartsWithFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the starts-with() XPath function
-- * boolean starts-with(string, string)
-- * The starts-with function returns true if the first argument string
-- * starts with the second argument string, and otherwise returns false.
-- */
--void
--xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr hay, needle;
-- int n;
--
-- CHECK_ARITY(2);
-- CAST_TO_STRING;
-- CHECK_TYPE(XPATH_STRING);
-- needle = valuePop(ctxt);
-- CAST_TO_STRING;
-- hay = valuePop(ctxt);
-- if ((hay == NULL) || (hay->type != XPATH_STRING)) {
-- xmlXPathFreeObject(hay);
-- xmlXPathFreeObject(needle);
-- XP_ERROR(XPATH_INVALID_TYPE);
-- }
-- n = xmlStrlen(needle->stringval);
-- if (xmlStrncmp(hay->stringval, needle->stringval, n))
-- valuePush(ctxt, xmlXPathNewBoolean(0));
-- else
-- valuePush(ctxt, xmlXPathNewBoolean(1));
-- xmlXPathFreeObject(hay);
-- xmlXPathFreeObject(needle);
--}
--
--/**
-- * xmlXPathSubstringFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the substring() XPath function
-- * string substring(string, number, number?)
-- * The substring function returns the substring of the first argument
-- * starting at the position specified in the second argument with
-- * length specified in the third argument. For example,
-- * substring("12345",2,3) returns "234". If the third argument is not
-- * specified, it returns the substring starting at the position specified
-- * in the second argument and continuing to the end of the string. For
-- * example, substring("12345",2) returns "2345". More precisely, each
-- * character in the string (see [3.6 Strings]) is considered to have a
-- * numeric position: the position of the first character is 1, the position
-- * of the second character is 2 and so on. The returned substring contains
-- * those characters for which the position of the character is greater than
-- * or equal to the second argument and, if the third argument is specified,
-- * less than the sum of the second and third arguments; the comparisons
-- * and addition used for the above follow the standard IEEE 754 rules. Thus:
-- * - substring("12345", 1.5, 2.6) returns "234"
-- * - substring("12345", 0, 3) returns "12"
-- * - substring("12345", 0 div 0, 3) returns ""
-- * - substring("12345", 1, 0 div 0) returns ""
-- * - substring("12345", -42, 1 div 0) returns "12345"
-- * - substring("12345", -1 div 0, 1 div 0) returns ""
-- */
--void
--xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr str, start, len;
-- double le, in;
-- int i, l;
-- xmlChar *ret;
--
-- /*
-- * Conformance needs to be checked !!!!!
-- */
-- if (nargs < 2) {
-- CHECK_ARITY(2);
-- }
-- if (nargs > 3) {
-- CHECK_ARITY(3);
-- }
-- if (nargs == 3) {
-- CAST_TO_NUMBER;
-- CHECK_TYPE(XPATH_NUMBER);
-- len = valuePop(ctxt);
-- le = len->floatval;
-- xmlXPathFreeObject(len);
-- } else {
-- le = 2000000000;
-- }
-- CAST_TO_NUMBER;
-- CHECK_TYPE(XPATH_NUMBER);
-- start = valuePop(ctxt);
-- in = start->floatval;
-- xmlXPathFreeObject(start);
-- CAST_TO_STRING;
-- CHECK_TYPE(XPATH_STRING);
-- str = valuePop(ctxt);
-- le += in;
--
-- /* integer index of the first char */
-- i = (int) in;
-- if (((double)i) != in) i++;
--
-- /* integer index of the last char */
-- l = (int) le;
-- if (((double)l) != le) l++;
--
-- /* back to a zero based len */
-- i--;
-- l--;
--
-- /* check against the string len */
-- if (l > 1024) {
-- l = xmlStrlen(str->stringval);
-- }
-- if (i < 0) {
-- i = 0;
-- }
--
-- /* number of chars to copy */
-- l -= i;
--
-- ret = xmlStrsub(str->stringval, i, l);
-- if (ret == NULL)
-- valuePush(ctxt, xmlXPathNewCString(""));
-- else {
-- valuePush(ctxt, xmlXPathNewString(ret));
-- xmlFree(ret);
-- }
-- xmlXPathFreeObject(str);
--}
--
--/**
-- * xmlXPathSubstringBeforeFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the substring-before() XPath function
-- * string substring-before(string, string)
-- * The substring-before function returns the substring of the first
-- * argument string that precedes the first occurrence of the second
-- * argument string in the first argument string, or the empty string
-- * if the first argument string does not contain the second argument
-- * string. For example, substring-before("1999/04/01","/") returns 1999.
-- */
--void
--xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr str;
-- xmlXPathObjectPtr find;
-- xmlBufferPtr target;
-- const xmlChar *point;
-- int offset;
--
-- CHECK_ARITY(2);
-- CAST_TO_STRING;
-- find = valuePop(ctxt);
-- CAST_TO_STRING;
-- str = valuePop(ctxt);
--
-- target = xmlBufferCreate();
-- if (target) {
-- point = xmlStrstr(str->stringval, find->stringval);
-- if (point) {
-- offset = (int)(point - str->stringval);
-- xmlBufferAdd(target, str->stringval, offset);
-- }
-- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-- xmlBufferFree(target);
-- }
--
-- xmlXPathFreeObject(str);
-- xmlXPathFreeObject(find);
--}
--
--/**
-- * xmlXPathSubstringAfterFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the substring-after() XPath function
-- * string substring-after(string, string)
-- * The substring-after function returns the substring of the first
-- * argument string that follows the first occurrence of the second
-- * argument string in the first argument string, or the empty stringi
-- * if the first argument string does not contain the second argument
-- * string. For example, substring-after("1999/04/01","/") returns 04/01,
-- * and substring-after("1999/04/01","19") returns 99/04/01.
-- */
--void
--xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr str;
-- xmlXPathObjectPtr find;
-- xmlBufferPtr target;
-- const xmlChar *point;
-- int offset;
--
-- CHECK_ARITY(2);
-- CAST_TO_STRING;
-- find = valuePop(ctxt);
-- CAST_TO_STRING;
-- str = valuePop(ctxt);
--
-- target = xmlBufferCreate();
-- if (target) {
-- point = xmlStrstr(str->stringval, find->stringval);
-- if (point) {
-- offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
-- xmlBufferAdd(target, &str->stringval[offset],
-- xmlStrlen(str->stringval) - offset);
-- }
-- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-- xmlBufferFree(target);
-- }
--
-- xmlXPathFreeObject(str);
-- xmlXPathFreeObject(find);
--}
--
--/**
-- * xmlXPathNormalizeFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the normalize-space() XPath function
-- * string normalize-space(string?)
-- * The normalize-space function returns the argument string with white
-- * space normalized by stripping leading and trailing whitespace
-- * and replacing sequences of whitespace characters by a single
-- * space. Whitespace characters are the same allowed by the S production
-- * in XML. If the argument is omitted, it defaults to the context
-- * node converted to a string, in other words the value of the context node.
-- */
--void
--xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr obj = NULL;
-- xmlChar *source = NULL;
-- xmlBufferPtr target;
-- xmlChar blank;
--
-- if (nargs == 0) {
-- /* Use current context node */
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-- xmlXPathStringFunction(ctxt, 1);
-- nargs = 1;
-- }
--
-- CHECK_ARITY(1);
-- CAST_TO_STRING;
-- CHECK_TYPE(XPATH_STRING);
-- obj = valuePop(ctxt);
-- source = obj->stringval;
--
-- target = xmlBufferCreate();
-- if (target && source) {
--
-- /* Skip leading whitespaces */
-- while (IS_BLANK(*source))
-- source++;
--
-- /* Collapse intermediate whitespaces, and skip trailing whitespaces */
-- blank = 0;
-- while (*source) {
-- if (IS_BLANK(*source)) {
-- blank = *source;
-- } else {
-- if (blank) {
-- xmlBufferAdd(target, &blank, 1);
-- blank = 0;
-- }
-- xmlBufferAdd(target, source, 1);
-- }
-- source++;
-- }
--
-- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-- xmlBufferFree(target);
-- }
-- xmlXPathFreeObject(obj);
--}
--
--/**
-- * xmlXPathTranslateFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the translate() XPath function
-- * string translate(string, string, string)
-- * The translate function returns the first argument string with
-- * occurrences of characters in the second argument string replaced
-- * by the character at the corresponding position in the third argument
-- * string. For example, translate("bar","abc","ABC") returns the string
-- * BAr. If there is a character in the second argument string with no
-- * character at a corresponding position in the third argument string
-- * (because the second argument string is longer than the third argument
-- * string), then occurrences of that character in the first argument
-- * string are removed. For example, translate("--aaa--","abc-","ABC")
-- * returns "AAA". If a character occurs more than once in second
-- * argument string, then the first occurrence determines the replacement
-- * character. If the third argument string is longer than the second
-- * argument string, then excess characters are ignored.
-- */
--void
--xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr str;
-- xmlXPathObjectPtr from;
-- xmlXPathObjectPtr to;
-- xmlBufferPtr target;
-- int i, offset, max;
-- xmlChar ch;
-- const xmlChar *point;
--
-- CHECK_ARITY(3);
--
-- CAST_TO_STRING;
-- to = valuePop(ctxt);
-- CAST_TO_STRING;
-- from = valuePop(ctxt);
-- CAST_TO_STRING;
-- str = valuePop(ctxt);
--
-- target = xmlBufferCreate();
-- if (target) {
-- max = xmlStrlen(to->stringval);
-- for (i = 0; (ch = str->stringval[i]); i++) {
-- point = xmlStrchr(from->stringval, ch);
-- if (point) {
-- /* Warning: This may not work with UTF-8 */
-- offset = (int)(point - from->stringval);
-- if (offset < max)
-- xmlBufferAdd(target, &to->stringval[offset], 1);
-- } else
-- xmlBufferAdd(target, &ch, 1);
-- }
-- }
-- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
-- xmlBufferFree(target);
-- xmlXPathFreeObject(str);
-- xmlXPathFreeObject(from);
-- xmlXPathFreeObject(to);
--}
--
--/**
-- * xmlXPathBooleanFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the boolean() XPath function
-- * boolean boolean(object)
-- * he boolean function converts its argument to a boolean as follows:
-- * - a number is true if and only if it is neither positive or
-- * negative zero nor NaN
-- * - a node-set is true if and only if it is non-empty
-- * - a string is true if and only if its length is non-zero
-- */
--void
--xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
-- int res = 0;
--
-- CHECK_ARITY(1);
-- cur = valuePop(ctxt);
-- if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
-- switch (cur->type) {
-- case XPATH_NODESET:
-- case XPATH_XSLT_TREE:
-- if ((cur->nodesetval == NULL) ||
-- (cur->nodesetval->nodeNr == 0)) res = 0;
-- else
-- res = 1;
-- break;
-- case XPATH_STRING:
-- if ((cur->stringval == NULL) ||
-- (cur->stringval[0] == 0)) res = 0;
-- else
-- res = 1;
-- break;
-- case XPATH_BOOLEAN:
-- valuePush(ctxt, cur);
-- return;
-- case XPATH_NUMBER:
-- if (cur->floatval) res = 1;
-- break;
-- default:
-- STRANGE
-- }
-- xmlXPathFreeObject(cur);
-- valuePush(ctxt, xmlXPathNewBoolean(res));
--}
--
--/**
-- * xmlXPathNotFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the not() XPath function
-- * boolean not(boolean)
-- * The not function returns true if its argument is false,
-- * and false otherwise.
-- */
--void
--xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- CHECK_ARITY(1);
-- CAST_TO_BOOLEAN;
-- CHECK_TYPE(XPATH_BOOLEAN);
-- ctxt->value->boolval = ! ctxt->value->boolval;
--}
--
--/**
-- * xmlXPathTrueFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the true() XPath function
-- * boolean true()
-- */
--void
--xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- CHECK_ARITY(0);
-- valuePush(ctxt, xmlXPathNewBoolean(1));
--}
--
--/**
-- * xmlXPathFalseFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the false() XPath function
-- * boolean false()
-- */
--void
--xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- CHECK_ARITY(0);
-- valuePush(ctxt, xmlXPathNewBoolean(0));
--}
--
--/**
-- * xmlXPathLangFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the lang() XPath function
-- * boolean lang(string)
-- * The lang function returns true or false depending on whether the
-- * language of the context node as specified by xml:lang attributes
-- * is the same as or is a sublanguage of the language specified by
-- * the argument string. The language of the context node is determined
-- * by the value of the xml:lang attribute on the context node, or, if
-- * the context node has no xml:lang attribute, by the value of the
-- * xml:lang attribute on the nearest ancestor of the context node that
-- * has an xml:lang attribute. If there is no such attribute, then lang
-- * returns false. If there is such an attribute, then lang returns
-- * true if the attribute value is equal to the argument ignoring case,
-- * or if there is some suffix starting with - such that the attribute
-- * value is equal to the argument ignoring that suffix of the attribute
-- * value and ignoring case.
-- */
--void
--xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr val;
-- const xmlChar *theLang;
-- const xmlChar *lang;
-- int ret = 0;
-- int i;
--
-- CHECK_ARITY(1);
-- CAST_TO_STRING;
-- CHECK_TYPE(XPATH_STRING);
-- val = valuePop(ctxt);
-- lang = val->stringval;
-- theLang = xmlNodeGetLang(ctxt->context->node);
-- if ((theLang != NULL) && (lang != NULL)) {
-- for (i = 0;lang[i] != 0;i++)
-- if (toupper(lang[i]) != toupper(theLang[i]))
-- goto not_equal;
-- ret = 1;
-- }
--not_equal:
-- xmlXPathFreeObject(val);
-- valuePush(ctxt, xmlXPathNewBoolean(ret));
--}
--
--/**
-- * xmlXPathNumberFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the number() XPath function
-- * number number(object?)
-- */
--void
--xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
-- double res;
--
-- if (nargs == 0) {
-- if (ctxt->context->node == NULL) {
-- valuePush(ctxt, xmlXPathNewFloat(0.0));
-- } else {
-- xmlChar* content = xmlNodeGetContent(ctxt->context->node);
--
-- res = xmlXPathStringEvalNumber(content);
-- valuePush(ctxt, xmlXPathNewFloat(res));
-- xmlFree(content);
-- }
-- return;
-- }
--
-- CHECK_ARITY(1);
-- cur = valuePop(ctxt);
-- switch (cur->type) {
-- case XPATH_UNDEFINED:
--#ifdef DEBUG_EXPR
-- xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
--#endif
-- valuePush(ctxt, xmlXPathNewFloat(0.0));
-- break;
-- case XPATH_XSLT_TREE:
-- case XPATH_NODESET:
-- valuePush(ctxt, cur);
-- xmlXPathStringFunction(ctxt, 1);
-- cur = valuePop(ctxt);
-- case XPATH_STRING:
-- res = xmlXPathStringEvalNumber(cur->stringval);
-- valuePush(ctxt, xmlXPathNewFloat(res));
-- xmlXPathFreeObject(cur);
-- return;
-- case XPATH_BOOLEAN:
-- if (cur->boolval) valuePush(ctxt, xmlXPathNewFloat(1.0));
-- else valuePush(ctxt, xmlXPathNewFloat(0.0));
-- xmlXPathFreeObject(cur);
-- return;
-- case XPATH_NUMBER:
-- valuePush(ctxt, cur);
-- return;
-- case XPATH_USERS:
-- case XPATH_POINT:
-- case XPATH_RANGE:
-- case XPATH_LOCATIONSET:
-- TODO
-- valuePush(ctxt, xmlXPathNewFloat(0.0));
-- break;
-- }
-- STRANGE
--}
--
--/**
-- * xmlXPathSumFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the sum() XPath function
-- * number sum(node-set)
-- * The sum function returns the sum of the values of the nodes in
-- * the argument node-set.
-- */
--void
--xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr cur;
-- int i;
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_XSLT_TREE)))
-- XP_ERROR(XPATH_INVALID_TYPE);
-- cur = valuePop(ctxt);
--
-- if (cur->nodesetval->nodeNr == 0) {
-- valuePush(ctxt, xmlXPathNewFloat(0.0));
-- } else {
-- valuePush(ctxt,
-- xmlXPathNewNodeSet(cur->nodesetval->nodeTab[0]));
-- xmlXPathNumberFunction(ctxt, 1);
-- for (i = 1; i < cur->nodesetval->nodeNr; i++) {
-- valuePush(ctxt,
-- xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
-- xmlXPathAddValues(ctxt);
-- }
-- }
-- xmlXPathFreeObject(cur);
--}
--
--/**
-- * xmlXPathFloorFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the floor() XPath function
-- * number floor(number)
-- * The floor function returns the largest (closest to positive infinity)
-- * number that is not greater than the argument and that is an integer.
-- */
--void
--xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- CHECK_ARITY(1);
-- CAST_TO_NUMBER;
-- CHECK_TYPE(XPATH_NUMBER);
--#if 0
-- ctxt->value->floatval = floor(ctxt->value->floatval);
--#else
-- /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
-- ctxt->value->floatval = (double)((int) ctxt->value->floatval);
--#endif
--}
--
--/**
-- * xmlXPathCeilingFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the ceiling() XPath function
-- * number ceiling(number)
-- * The ceiling function returns the smallest (closest to negative infinity)
-- * number that is not less than the argument and that is an integer.
-- */
--void
--xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- double f;
--
-- CHECK_ARITY(1);
-- CAST_TO_NUMBER;
-- CHECK_TYPE(XPATH_NUMBER);
--
--#if 0
-- ctxt->value->floatval = ceil(ctxt->value->floatval);
--#else
-- f = (double)((int) ctxt->value->floatval);
-- if (f != ctxt->value->floatval)
-- ctxt->value->floatval = f + 1;
--#endif
--}
--
--/**
-- * xmlXPathRoundFunction:
-- * @ctxt: the XPath Parser context
-- * @nargs: the number of arguments
-- *
-- * Implement the round() XPath function
-- * number round(number)
-- * The round function returns the number that is closest to the
-- * argument and that is an integer. If there are two such numbers,
-- * then the one that is even is returned.
-- */
--void
--xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- double f;
--
-- CHECK_ARITY(1);
-- CAST_TO_NUMBER;
-- CHECK_TYPE(XPATH_NUMBER);
--
-- if ((ctxt->value->floatval == xmlXPathNAN) ||
-- (ctxt->value->floatval == xmlXPathPINF) ||
-- (ctxt->value->floatval == xmlXPathNINF) ||
-- (ctxt->value->floatval == 0.0))
-- return;
--
--#if 0
-- f = floor(ctxt->value->floatval);
--#else
-- f = (double)((int) ctxt->value->floatval);
--#endif
-- if (ctxt->value->floatval < f + 0.5)
-- ctxt->value->floatval = f;
-- else
-- ctxt->value->floatval = f + 1;
--}
--
--/************************************************************************
-- * *
-- * The Parser *
-- * *
-- ************************************************************************/
--
--/*
-- * a couple of forward declarations since we use a recursive call based
-- * implementation.
-- */
--void xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt);
--void xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt);
--void xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt);
--#ifdef VMS
--void xmlXPathEvalRelLocationPath(xmlXPathParserContextPtr ctxt);
--#define xmlXPathEvalRelativeLocationPath xmlXPathEvalRelLocationPath
--#else
--void xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt);
--#endif
--
--/**
-- * xmlXPathParseNCName:
-- * @ctxt: the XPath Parser context
-- *
-- * parse an XML namespace non qualified name.
-- *
-- * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
-- *
-- * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
-- * CombiningChar | Extender
-- *
-- * Returns the namespace name or NULL
-- */
--
--xmlChar *
--xmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
-- const xmlChar *q;
-- xmlChar *ret = NULL;
--
-- if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
-- q = NEXT;
--
-- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == '.') || (CUR == '-') ||
-- (CUR == '_') ||
-- (IS_COMBINING(CUR)) ||
-- (IS_EXTENDER(CUR)))
-- NEXT;
--
-- ret = xmlStrndup(q, CUR_PTR - q);
--
-- return(ret);
--}
--
--/**
-- * xmlXPathParseQName:
-- * @ctxt: the XPath Parser context
-- * @prefix: a xmlChar **
-- *
-- * parse an XML qualified name
-- *
-- * [NS 5] QName ::= (Prefix ':')? LocalPart
-- *
-- * [NS 6] Prefix ::= NCName
-- *
-- * [NS 7] LocalPart ::= NCName
-- *
-- * Returns the function returns the local part, and prefix is updated
-- * to get the Prefix if any.
-- */
--
--xmlChar *
--xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
-- xmlChar *ret = NULL;
--
-- *prefix = NULL;
-- ret = xmlXPathParseNCName(ctxt);
-- if (CUR == ':') {
-- *prefix = ret;
-- NEXT;
-- ret = xmlXPathParseNCName(ctxt);
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPathParseName:
-- * @ctxt: the XPath Parser context
-- *
-- * parse an XML name
-- *
-- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-- * CombiningChar | Extender
-- *
-- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-- *
-- * Returns the namespace name or NULL
-- */
--
--xmlChar *
--xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
-- const xmlChar *q;
-- xmlChar *ret = NULL;
--
-- if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
-- q = NEXT;
--
-- /* TODO Make this UTF8 compliant !!! */
-- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
-- (CUR == '.') || (CUR == '-') ||
-- (CUR == '_') || (CUR == ':') ||
-- (IS_COMBINING(CUR)) ||
-- (IS_EXTENDER(CUR)))
-- NEXT;
--
-- ret = xmlStrndup(q, CUR_PTR - q);
--
-- return(ret);
--}
--
--/**
-- * xmlXPathStringEvalNumber:
-- * @str: A string to scan
-- *
-- * [30] Number ::= Digits ('.' Digits?)?
-- * | '.' Digits
-- * [31] Digits ::= [0-9]+
-- *
-- * Parse and evaluate a Number in the string
-- * In complement of the Number expression, this function also handles
-- * negative values : '-' Number.
-- *
-- * Returns the double value.
-- */
--double
--xmlXPathStringEvalNumber(const xmlChar *str) {
-- const xmlChar *cur = str;
-- double ret = 0.0;
-- double mult = 1;
-- int ok = 0;
-- int isneg = 0;
--
-- while (*cur == ' ') cur++;
-- if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
-- return(xmlXPathNAN);
-- }
-- if (*cur == '-') {
-- isneg = 1;
-- cur++;
-- }
-- while ((*cur >= '0') && (*cur <= '9')) {
-- ret = ret * 10 + (*cur - '0');
-- ok = 1;
-- cur++;
-- }
-- if (*cur == '.') {
-- cur++;
-- if (((*cur < '0') || (*cur > '9')) && (!ok)) {
-- return(xmlXPathNAN);
-- }
-- while ((*cur >= '0') && (*cur <= '9')) {
-- mult /= 10;
-- ret = ret + (*cur - '0') * mult;
-- cur++;
-- }
-- }
-- while (*cur == ' ') cur++;
-- if (*cur != 0) return(xmlXPathNAN);
-- if (isneg) ret = -ret;
-- return(ret);
--}
--
--/**
-- * xmlXPathEvalNumber:
-- * @ctxt: the XPath Parser context
-- *
-- * [30] Number ::= Digits ('.' Digits?)?
-- * | '.' Digits
-- * [31] Digits ::= [0-9]+
-- *
-- * Parse and evaluate a Number, then push it on the stack
-- *
-- */
--void
--xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) {
-- double ret = 0.0;
-- double mult = 1;
-- int ok = 0;
--
-- CHECK_ERROR;
-- if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
-- XP_ERROR(XPATH_NUMBER_ERROR);
-- }
-- while ((CUR >= '0') && (CUR <= '9')) {
-- ret = ret * 10 + (CUR - '0');
-- ok = 1;
-- NEXT;
-- }
-- if (CUR == '.') {
-- NEXT;
-- if (((CUR < '0') || (CUR > '9')) && (!ok)) {
-- XP_ERROR(XPATH_NUMBER_ERROR);
-- }
-- while ((CUR >= '0') && (CUR <= '9')) {
-- mult /= 10;
-- ret = ret + (CUR - '0') * mult;
-- NEXT;
-- }
-- }
-- valuePush(ctxt, xmlXPathNewFloat(ret));
--}
--
--/**
-- * xmlXPathEvalLiteral:
-- * @ctxt: the XPath Parser context
-- *
-- * Parse a Literal and push it on the stack.
-- *
-- * [29] Literal ::= '"' [^"]* '"'
-- * | "'" [^']* "'"
-- *
-- * TODO: xmlXPathEvalLiteral memory allocation could be improved.
-- */
--void
--xmlXPathEvalLiteral(xmlXPathParserContextPtr ctxt) {
-- const xmlChar *q;
-- xmlChar *ret = NULL;
--
-- if (CUR == '"') {
-- NEXT;
-- q = CUR_PTR;
-- while ((IS_CHAR(CUR)) && (CUR != '"'))
-- NEXT;
-- if (!IS_CHAR(CUR)) {
-- XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
-- } else {
-- ret = xmlStrndup(q, CUR_PTR - q);
-- NEXT;
-- }
-- } else if (CUR == '\'') {
-- NEXT;
-- q = CUR_PTR;
-- while ((IS_CHAR(CUR)) && (CUR != '\''))
-- NEXT;
-- if (!IS_CHAR(CUR)) {
-- XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
-- } else {
-- ret = xmlStrndup(q, CUR_PTR - q);
-- NEXT;
-- }
-- } else {
-- XP_ERROR(XPATH_START_LITERAL_ERROR);
-- }
-- if (ret == NULL) return;
-- valuePush(ctxt, xmlXPathNewString(ret));
-- xmlFree(ret);
--}
--
--/**
-- * xmlXPathEvalVariableReference:
-- * @ctxt: the XPath Parser context
-- *
-- * Parse a VariableReference, evaluate it and push it on the stack.
-- *
-- * The variable bindings consist of a mapping from variable names
-- * to variable values. The value of a variable is an object, which
-- * of any of the types that are possible for the value of an expression,
-- * and may also be of additional types not specified here.
-- *
-- * Early evaluation is possible since:
-- * The variable bindings [...] used to evaluate a subexpression are
-- * always the same as those used to evaluate the containing expression.
-- *
-- * [36] VariableReference ::= '$' QName
-- */
--void
--xmlXPathEvalVariableReference(xmlXPathParserContextPtr ctxt) {
-- xmlChar *name;
-- xmlChar *prefix;
-- xmlXPathObjectPtr value;
--
-- SKIP_BLANKS;
-- if (CUR != '$') {
-- XP_ERROR(XPATH_VARIABLE_REF_ERROR);
-- }
-- NEXT;
-- name = xmlXPathParseQName(ctxt, &prefix);
-- if (name == NULL) {
-- XP_ERROR(XPATH_VARIABLE_REF_ERROR);
-- }
-- if (prefix == NULL) {
-- value = xmlXPathVariableLookup(ctxt->context, name);
-- } else {
-- TODO;
-- value = NULL;
-- }
-- xmlFree(name);
-- if (prefix != NULL) xmlFree(prefix);
-- if (value == NULL) {
-- XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR);
-- }
-- valuePush(ctxt, value);
-- SKIP_BLANKS;
--}
--
--/**
-- * xmlXPathIsNodeType:
-- * @ctxt: the XPath Parser context
-- * @name: a name string
-- *
-- * Is the name given a NodeType one.
-- *
-- * [38] NodeType ::= 'comment'
-- * | 'text'
-- * | 'processing-instruction'
-- * | 'node'
-- *
-- * Returns 1 if true 0 otherwise
-- */
--int
--xmlXPathIsNodeType(const xmlChar *name) {
-- if (name == NULL)
-- return(0);
--
-- if (xmlStrEqual(name, BAD_CAST "comment"))
-- return(1);
-- if (xmlStrEqual(name, BAD_CAST "text"))
-- return(1);
-- if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
-- return(1);
-- if (xmlStrEqual(name, BAD_CAST "node"))
-- return(1);
-- return(0);
--}
--
--/**
-- * xmlXPathEvalFunctionCall:
-- * @ctxt: the XPath Parser context
-- *
-- * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')'
-- * [17] Argument ::= Expr
-- *
-- * Parse and evaluate a function call, the evaluation of all arguments are
-- * pushed on the stack
-- */
--void
--xmlXPathEvalFunctionCall(xmlXPathParserContextPtr ctxt) {
-- xmlChar *name;
-- xmlChar *prefix;
-- xmlXPathFunction func;
-- int nbargs = 0;
--
-- name = xmlXPathParseQName(ctxt, &prefix);
-- if (name == NULL) {
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- SKIP_BLANKS;
-- if (prefix == NULL) {
-- func = xmlXPathFunctionLookup(ctxt->context, name);
-- } else {
-- TODO;
-- func = NULL;
-- }
-- if (func == NULL) {
-- xmlFree(name);
-- if (prefix != NULL) xmlFree(prefix);
-- XP_ERROR(XPATH_UNKNOWN_FUNC_ERROR);
-- }
--#ifdef DEBUG_EXPR
-- if (prefix == NULL)
-- xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
-- name);
-- else
-- xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
-- prefix, name);
--#endif
--
-- xmlFree(name);
-- if (prefix != NULL) xmlFree(prefix);
--
-- if (CUR != '(') {
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
--
-- while (CUR != ')') {
-- xmlXPathEvalExpr(ctxt);
-- nbargs++;
-- if (CUR == ')') break;
-- if (CUR != ',') {
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
-- }
-- NEXT;
-- SKIP_BLANKS;
-- func(ctxt, nbargs);
--}
--
--/**
-- * xmlXPathEvalPrimaryExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [15] PrimaryExpr ::= VariableReference
-- * | '(' Expr ')'
-- * | Literal
-- * | Number
-- * | FunctionCall
-- *
-- * Parse and evaluate a primary expression, then push the result on the stack
-- */
--void
--xmlXPathEvalPrimaryExpr(xmlXPathParserContextPtr ctxt) {
-- SKIP_BLANKS;
-- if (CUR == '$') xmlXPathEvalVariableReference(ctxt);
-- else if (CUR == '(') {
-- NEXT;
-- SKIP_BLANKS;
-- xmlXPathEvalExpr(ctxt);
-- if (CUR != ')') {
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
-- } else if (IS_DIGIT(CUR)) {
-- xmlXPathEvalNumber(ctxt);
-- } else if ((CUR == '\'') || (CUR == '"')) {
-- xmlXPathEvalLiteral(ctxt);
-- } else {
-- xmlXPathEvalFunctionCall(ctxt);
-- }
-- SKIP_BLANKS;
--}
--
--/**
-- * xmlXPathEvalFilterExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [20] FilterExpr ::= PrimaryExpr
-- * | FilterExpr Predicate
-- *
-- * Parse and evaluate a filter expression, then push the result on the stack
-- * Square brackets are used to filter expressions in the same way that
-- * they are used in location paths. It is an error if the expression to
-- * be filtered does not evaluate to a node-set. The context node list
-- * used for evaluating the expression in square brackets is the node-set
-- * to be filtered listed in document order.
-- */
--
--void
--xmlXPathEvalFilterExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalPrimaryExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
--
-- while (CUR == '[') {
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_LOCATIONSET)))
-- XP_ERROR(XPATH_INVALID_TYPE)
--
-- if (ctxt->value->type == XPATH_NODESET)
-- xmlXPathEvalPredicate(ctxt);
-- else
-- xmlXPtrEvalRangePredicate(ctxt);
-- SKIP_BLANKS;
-- }
--
--
--}
--
--/**
-- * xmlXPathScanName:
-- * @ctxt: the XPath Parser context
-- *
-- * Trickery: parse an XML name but without consuming the input flow
-- * Needed to avoid insanity in the parser state.
-- *
-- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-- * CombiningChar | Extender
-- *
-- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-- *
-- * [6] Names ::= Name (S Name)*
-- *
-- * Returns the Name parsed or NULL
-- */
--
--xmlChar *
--xmlXPathScanName(xmlXPathParserContextPtr ctxt) {
-- xmlChar buf[XML_MAX_NAMELEN];
-- int len = 0;
--
-- SKIP_BLANKS;
-- if (!IS_LETTER(CUR) && (CUR != '_') &&
-- (CUR != ':')) {
-- return(NULL);
-- }
--
-- while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
-- (NXT(len) == '.') || (NXT(len) == '-') ||
-- (NXT(len) == '_') || (NXT(len) == ':') ||
-- (IS_COMBINING(NXT(len))) ||
-- (IS_EXTENDER(NXT(len)))) {
-- buf[len] = NXT(len);
-- len++;
-- if (len >= XML_MAX_NAMELEN) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlScanName: reached XML_MAX_NAMELEN limit\n");
-- while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
-- (NXT(len) == '.') || (NXT(len) == '-') ||
-- (NXT(len) == '_') || (NXT(len) == ':') ||
-- (IS_COMBINING(NXT(len))) ||
-- (IS_EXTENDER(NXT(len))))
-- len++;
-- break;
-- }
-- }
-- return(xmlStrndup(buf, len));
--}
--
--/**
-- * xmlXPathEvalPathExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [19] PathExpr ::= LocationPath
-- * | FilterExpr
-- * | FilterExpr '/' RelativeLocationPath
-- * | FilterExpr '//' RelativeLocationPath
-- *
-- * Parse and evaluate a path expression, then push the result on the stack
-- * The / operator and // operators combine an arbitrary expression
-- * and a relative location path. It is an error if the expression
-- * does not evaluate to a node-set.
-- * The / operator does composition in the same way as when / is
-- * used in a location path. As in location paths, // is short for
-- * /descendant-or-self::node()/.
-- */
--
--void
--xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
-- int lc = 1; /* Should we branch to LocationPath ? */
-- xmlChar *name = NULL; /* we may have to preparse a name to find out */
--
-- SKIP_BLANKS;
-- if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
-- (CUR == '\'') || (CUR == '"')) {
-- lc = 0;
-- } else if (CUR == '/') {
-- /* relative or absolute location path */
-- lc = 1;
-- } else if (CUR == '@') {
-- /* relative abbreviated attribute location path */
-- lc = 1;
-- } else if (CUR == '.') {
-- /* relative abbreviated attribute location path */
-- lc = 1;
-- } else {
-- /*
-- * Problem is finding if we have a name here whether it's:
-- * - a nodetype
-- * - a function call in which case it's followed by '('
-- * - an axis in which case it's followed by ':'
-- * - a element name
-- * We do an a priori analysis here rather than having to
-- * maintain parsed token content through the recursive function
-- * calls. This looks uglier but makes the code quite easier to
-- * read/write/debug.
-- */
-- SKIP_BLANKS;
-- name = xmlXPathScanName(ctxt);
-- if (name != NULL) {
-- int len =xmlStrlen(name);
-- int blank = 0;
--
-- while (NXT(len) != 0) {
-- if (NXT(len) == '/') {
-- /* element name */
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "PathExpr: AbbrRelLocation\n");
--#endif
-- lc = 1;
-- break;
-- } else if (IS_BLANK(NXT(len))) {
-- /* skip to next */
-- blank = 1;
-- } else if (NXT(len) == ':') {
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "PathExpr: AbbrRelLocation\n");
--#endif
-- lc = 1;
-- break;
-- } else if ((NXT(len) == '(')) {
-- /* Note Type or Function */
-- if (xmlXPathIsNodeType(name)) {
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "PathExpr: Type search\n");
--#endif
-- lc = 1;
-- } else {
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "PathExpr: function call\n");
--#endif
-- lc = 0;
-- }
-- break;
-- } else if ((NXT(len) == '[')) {
-- /* element name */
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "PathExpr: AbbrRelLocation\n");
--#endif
-- lc = 1;
-- break;
-- } else if ((NXT(len) == '<') || (NXT(len) == '>') ||
-- (NXT(len) == '=')) {
-- lc = 1;
-- break;
-- } else {
-- lc = 1;
-- break;
-- }
-- len++;
-- }
-- if (NXT(len) == 0) {
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "PathExpr: AbbrRelLocation\n");
--#endif
-- /* element name */
-- lc = 1;
-- }
-- xmlFree(name);
-- } else {
-- /* make sure all cases are covered explicitely */
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- }
--
-- if (lc) {
-- if (CUR == '/')
-- xmlXPathRoot(ctxt);
-- else {
-- /* TAG:9999 */
-- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-- }
-- xmlXPathEvalLocationPath(ctxt);
-- } else {
-- xmlXPathEvalFilterExpr(ctxt);
-- CHECK_ERROR;
-- if ((CUR == '/') && (NXT(1) == '/')) {
-- SKIP(2);
-- SKIP_BLANKS;
-- xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
-- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-- ctxt->context->node = NULL;
-- xmlXPathEvalRelativeLocationPath(ctxt);
-- } else if (CUR == '/') {
-- xmlXPathEvalRelativeLocationPath(ctxt);
-- }
-- }
-- SKIP_BLANKS;
--}
--
--/**
-- * xmlXPathEvalUnionExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [18] UnionExpr ::= PathExpr
-- * | UnionExpr '|' PathExpr
-- *
-- * Parse and evaluate an union expression, then push the result on the stack
-- */
--
--void
--xmlXPathEvalUnionExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalPathExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while (CUR == '|') {
-- xmlXPathObjectPtr obj1,obj2, tmp;
--
-- CHECK_TYPE(XPATH_NODESET);
-- obj1 = valuePop(ctxt);
-- tmp = xmlXPathNewNodeSet(ctxt->context->node);
-- valuePush(ctxt, tmp);
--
-- NEXT;
-- SKIP_BLANKS;
-- xmlXPathEvalPathExpr(ctxt);
--
-- CHECK_TYPE(XPATH_NODESET);
-- obj2 = valuePop(ctxt);
-- obj1->nodesetval = xmlXPathNodeSetMerge(obj1->nodesetval,
-- obj2->nodesetval);
-- if (ctxt->value == tmp) {
-- tmp = valuePop(ctxt);
-- xmlXPathFreeObject(tmp);
-- }
-- valuePush(ctxt, obj1);
-- xmlXPathFreeObject(obj2);
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalUnaryExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [27] UnaryExpr ::= UnionExpr
-- * | '-' UnaryExpr
-- *
-- * Parse and evaluate an unary expression, then push the result on the stack
-- */
--
--void
--xmlXPathEvalUnaryExpr(xmlXPathParserContextPtr ctxt) {
-- int minus = 0;
--
-- SKIP_BLANKS;
-- if (CUR == '-') {
-- minus = 1;
-- NEXT;
-- SKIP_BLANKS;
-- }
-- xmlXPathEvalUnionExpr(ctxt);
-- CHECK_ERROR;
-- if (minus) {
-- xmlXPathValueFlipSign(ctxt);
-- }
--}
--
--/**
-- * xmlXPathEvalMultiplicativeExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [26] MultiplicativeExpr ::= UnaryExpr
-- * | MultiplicativeExpr MultiplyOperator UnaryExpr
-- * | MultiplicativeExpr 'div' UnaryExpr
-- * | MultiplicativeExpr 'mod' UnaryExpr
-- * [34] MultiplyOperator ::= '*'
-- *
-- * Parse and evaluate an Additive expression, then push the result on the stack
-- */
--
--void
--xmlXPathEvalMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalUnaryExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while ((CUR == '*') ||
-- ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
-- ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
-- int op = -1;
--
-- if (CUR == '*') {
-- op = 0;
-- NEXT;
-- } else if (CUR == 'd') {
-- op = 1;
-- SKIP(3);
-- } else if (CUR == 'm') {
-- op = 2;
-- SKIP(3);
-- }
-- SKIP_BLANKS;
-- xmlXPathEvalUnaryExpr(ctxt);
-- CHECK_ERROR;
-- switch (op) {
-- case 0:
-- xmlXPathMultValues(ctxt);
-- break;
-- case 1:
-- xmlXPathDivValues(ctxt);
-- break;
-- case 2:
-- xmlXPathModValues(ctxt);
-- break;
-- }
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalAdditiveExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [25] AdditiveExpr ::= MultiplicativeExpr
-- * | AdditiveExpr '+' MultiplicativeExpr
-- * | AdditiveExpr '-' MultiplicativeExpr
-- *
-- * Parse and evaluate an Additive expression, then push the result on the stack
-- */
--
--void
--xmlXPathEvalAdditiveExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalMultiplicativeExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while ((CUR == '+') || (CUR == '-')) {
-- int plus;
--
-- if (CUR == '+') plus = 1;
-- else plus = 0;
-- NEXT;
-- SKIP_BLANKS;
-- xmlXPathEvalMultiplicativeExpr(ctxt);
-- CHECK_ERROR;
-- if (plus) xmlXPathAddValues(ctxt);
-- else xmlXPathSubValues(ctxt);
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalRelationalExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [24] RelationalExpr ::= AdditiveExpr
-- * | RelationalExpr '<' AdditiveExpr
-- * | RelationalExpr '>' AdditiveExpr
-- * | RelationalExpr '<=' AdditiveExpr
-- * | RelationalExpr '>=' AdditiveExpr
-- *
-- * A <= B > C is allowed ? Answer from James, yes with
-- * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
-- * which is basically what got implemented.
-- *
-- * Parse and evaluate a Relational expression, then push the result
-- * on the stack
-- */
--
--void
--xmlXPathEvalRelationalExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalAdditiveExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while ((CUR == '<') ||
-- (CUR == '>') ||
-- ((CUR == '<') && (NXT(1) == '=')) ||
-- ((CUR == '>') && (NXT(1) == '='))) {
-- int inf, strict, ret;
--
-- if (CUR == '<') inf = 1;
-- else inf = 0;
-- if (NXT(1) == '=') strict = 0;
-- else strict = 1;
-- NEXT;
-- if (!strict) NEXT;
-- SKIP_BLANKS;
-- xmlXPathEvalAdditiveExpr(ctxt);
-- CHECK_ERROR;
-- ret = xmlXPathCompareValues(ctxt, inf, strict);
-- valuePush(ctxt, xmlXPathNewBoolean(ret));
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalEqualityExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [23] EqualityExpr ::= RelationalExpr
-- * | EqualityExpr '=' RelationalExpr
-- * | EqualityExpr '!=' RelationalExpr
-- *
-- * A != B != C is allowed ? Answer from James, yes with
-- * (RelationalExpr = RelationalExpr) = RelationalExpr
-- * (RelationalExpr != RelationalExpr) != RelationalExpr
-- * which is basically what got implemented.
-- *
-- * Parse and evaluate an Equality expression, then push the result on the stack
-- *
-- */
--void
--xmlXPathEvalEqualityExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalRelationalExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
-- xmlXPathObjectPtr res;
-- int eq, equal;
--
-- if (CUR == '=') eq = 1;
-- else eq = 0;
-- NEXT;
-- if (!eq) NEXT;
-- SKIP_BLANKS;
-- xmlXPathEvalRelationalExpr(ctxt);
-- CHECK_ERROR;
-- equal = xmlXPathEqualValues(ctxt);
-- if (eq) res = xmlXPathNewBoolean(equal);
-- else res = xmlXPathNewBoolean(!equal);
-- valuePush(ctxt, res);
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalAndExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [22] AndExpr ::= EqualityExpr
-- * | AndExpr 'and' EqualityExpr
-- *
-- * Parse and evaluate an AND expression, then push the result on the stack
-- *
-- */
--void
--xmlXPathEvalAndExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalEqualityExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
-- xmlXPathObjectPtr arg1, arg2;
--
-- SKIP(3);
-- SKIP_BLANKS;
-- xmlXPathEvalEqualityExpr(ctxt);
-- CHECK_ERROR;
-- xmlXPathBooleanFunction(ctxt, 1);
-- arg2 = valuePop(ctxt);
-- xmlXPathBooleanFunction(ctxt, 1);
-- arg1 = valuePop(ctxt);
-- arg1->boolval &= arg2->boolval;
-- valuePush(ctxt, arg1);
-- xmlXPathFreeObject(arg2);
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalExpr:
-- * @ctxt: the XPath Parser context
-- *
-- * [14] Expr ::= OrExpr
-- * [21] OrExpr ::= AndExpr
-- * | OrExpr 'or' AndExpr
-- *
-- * Parse and evaluate an expression, then push the result on the stack
-- *
-- */
--void
--xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
-- xmlXPathEvalAndExpr(ctxt);
-- CHECK_ERROR;
-- SKIP_BLANKS;
-- while ((CUR == 'o') && (NXT(1) == 'r')) {
-- xmlXPathObjectPtr arg1, arg2;
--
-- SKIP(2);
-- SKIP_BLANKS;
-- xmlXPathEvalAndExpr(ctxt);
-- CHECK_ERROR;
-- xmlXPathBooleanFunction(ctxt, 1);
-- arg2 = valuePop(ctxt);
-- xmlXPathBooleanFunction(ctxt, 1);
-- arg1 = valuePop(ctxt);
-- arg1->boolval |= arg2->boolval;
-- valuePush(ctxt, arg1);
-- xmlXPathFreeObject(arg2);
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvaluatePredicateResult:
-- * @ctxt: the XPath Parser context
-- * @res: the Predicate Expression evaluation result
-- *
-- * Evaluate a predicate result for the current node.
-- * A PredicateExpr is evaluated by evaluating the Expr and converting
-- * the result to a boolean. If the result is a number, the result will
-- * be converted to true if the number is equal to the position of the
-- * context node in the context node list (as returned by the position
-- * function) and will be converted to false otherwise; if the result
-- * is not a number, then the result will be converted as if by a call
-- * to the boolean function.
-- *
-- * Return 1 if predicate is true, 0 otherwise
-- */
--int
--xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
-- xmlXPathObjectPtr res) {
-- if (res == NULL) return(0);
-- switch (res->type) {
-- case XPATH_BOOLEAN:
-- return(res->boolval);
-- case XPATH_NUMBER:
-- return(res->floatval == ctxt->context->proximityPosition);
-- case XPATH_NODESET:
-- case XPATH_XSLT_TREE:
-- return(res->nodesetval->nodeNr != 0);
-- case XPATH_STRING:
-- return((res->stringval != NULL) &&
-- (xmlStrlen(res->stringval) != 0));
-- default:
-- STRANGE
-- }
-- return(0);
--}
--
--/**
-- * xmlXPathEvalPredicate:
-- * @ctxt: the XPath Parser context
-- *
-- * [8] Predicate ::= '[' PredicateExpr ']'
-- * [9] PredicateExpr ::= Expr
-- *
-- * ---------------------
-- * For each node in the node-set to be filtered, the PredicateExpr is
-- * evaluated with that node as the context node, with the number of nodes
-- * in the node-set as the context size, and with the proximity position
-- * of the node in the node-set with respect to the axis as the context
-- * position; if PredicateExpr evaluates to true for that node, the node
-- * is included in the new node-set; otherwise, it is not included.
-- * ---------------------
-- *
-- * Parse and evaluate a predicate for all the elements of the
-- * current node list. Then refine the list by removing all
-- * nodes where the predicate is false.
-- */
--void
--xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
-- const xmlChar *cur;
-- xmlXPathObjectPtr res;
-- xmlXPathObjectPtr obj, tmp;
-- xmlNodeSetPtr newset = NULL;
-- xmlNodeSetPtr oldset;
-- int i;
--
-- SKIP_BLANKS;
-- if (CUR != '[') {
-- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
--
-- /*
-- * Extract the old set, and then evaluate the result of the
-- * expression for all the element in the set. use it to grow
-- * up a new set.
-- */
-- CHECK_TYPE(XPATH_NODESET);
-- obj = valuePop(ctxt);
-- oldset = obj->nodesetval;
-- ctxt->context->node = NULL;
--
-- if ((oldset == NULL) || (oldset->nodeNr == 0)) {
-- ctxt->context->contextSize = 0;
-- ctxt->context->proximityPosition = 0;
-- xmlXPathEvalExpr(ctxt);
-- res = valuePop(ctxt);
-- if (res != NULL)
-- xmlXPathFreeObject(res);
-- valuePush(ctxt, obj);
-- CHECK_ERROR;
-- } else {
-- /*
-- * Save the expression pointer since we will have to evaluate
-- * it multiple times. Initialize the new set.
-- */
-- cur = ctxt->cur;
-- newset = xmlXPathNodeSetCreate(NULL);
--
-- for (i = 0; i < oldset->nodeNr; i++) {
-- ctxt->cur = cur;
--
-- /*
-- * Run the evaluation with a node list made of a single item
-- * in the nodeset.
-- */
-- ctxt->context->node = oldset->nodeTab[i];
-- tmp = xmlXPathNewNodeSet(ctxt->context->node);
-- valuePush(ctxt, tmp);
-- ctxt->context->contextSize = oldset->nodeNr;
-- ctxt->context->proximityPosition = i + 1;
--
-- xmlXPathEvalExpr(ctxt);
-- CHECK_ERROR;
--
-- /*
-- * The result of the evaluation need to be tested to
-- * decided whether the filter succeeded or not
-- */
-- res = valuePop(ctxt);
-- if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-- xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
-- }
--
-- /*
-- * Cleanup
-- */
-- if (res != NULL)
-- xmlXPathFreeObject(res);
-- if (ctxt->value == tmp) {
-- res = valuePop(ctxt);
-- xmlXPathFreeObject(res);
-- }
--
-- ctxt->context->node = NULL;
-- }
--
-- /*
-- * The result is used as the new evaluation set.
-- */
-- xmlXPathFreeObject(obj);
-- ctxt->context->node = NULL;
-- ctxt->context->contextSize = -1;
-- ctxt->context->proximityPosition = -1;
-- valuePush(ctxt, xmlXPathWrapNodeSet(newset));
-- }
-- if (CUR != ']') {
-- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-- }
--
-- NEXT;
-- SKIP_BLANKS;
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext, "After predicate : ");
-- xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
-- ctxt->value->nodesetval);
--#endif
--}
--
--/**
-- * xmlXPathEvalNodeTest:
-- * @ctxt: the XPath Parser context
-- * @test: pointer to a xmlXPathTestVal
-- * @type: pointer to a xmlXPathTypeVal
-- * @prefix: placeholder for a possible name prefix
-- *
-- * [7] NodeTest ::= NameTest
-- * | NodeType '(' ')'
-- * | 'processing-instruction' '(' Literal ')'
-- *
-- * [37] NameTest ::= '*'
-- * | NCName ':' '*'
-- * | QName
-- * [38] NodeType ::= 'comment'
-- * | 'text'
-- * | 'processing-instruction'
-- * | 'node'
-- *
-- * Returns the name found and update @test, @type and @prefix appropriately
-- */
--xmlChar *
--xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
-- xmlXPathTypeVal *type, const xmlChar **prefix, xmlChar *name) {
-- int blanks;
--
-- if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
-- STRANGE;
-- return(NULL);
-- }
-- *type = 0;
-- *test = 0;
-- *prefix = NULL;
-- SKIP_BLANKS;
--
-- if ((name == NULL) && (CUR == '*')) {
-- /*
-- * All elements
-- */
-- NEXT;
-- *test = NODE_TEST_ALL;
-- return(NULL);
-- }
--
-- if (name == NULL)
-- name = xmlXPathParseNCName(ctxt);
-- if (name == NULL) {
-- XP_ERROR0(XPATH_EXPR_ERROR);
-- }
--
-- blanks = IS_BLANK(CUR);
-- SKIP_BLANKS;
-- if (CUR == '(') {
-- NEXT;
-- /*
-- * NodeType or PI search
-- */
-- if (xmlStrEqual(name, BAD_CAST "comment"))
-- *type = NODE_TYPE_COMMENT;
-- else if (xmlStrEqual(name, BAD_CAST "node"))
-- *type = NODE_TYPE_NODE;
-- else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
-- *type = NODE_TYPE_PI;
-- else if (xmlStrEqual(name, BAD_CAST "text"))
-- *type = NODE_TYPE_TEXT;
-- else {
-- if (name != NULL)
-- xmlFree(name);
-- XP_ERROR0(XPATH_EXPR_ERROR);
-- }
--
-- *test = NODE_TEST_TYPE;
--
-- SKIP_BLANKS;
-- if (*type == NODE_TYPE_PI) {
-- /*
-- * Specific case: search a PI by name.
-- */
-- xmlXPathObjectPtr cur;
--
-- if (name != NULL)
-- xmlFree(name);
--
-- xmlXPathEvalLiteral(ctxt);
-- CHECK_ERROR 0;
-- xmlXPathStringFunction(ctxt, 1);
-- CHECK_ERROR0;
-- cur = valuePop(ctxt);
-- name = xmlStrdup(cur->stringval);
-- xmlXPathFreeObject(cur);
-- SKIP_BLANKS;
-- }
-- if (CUR != ')') {
-- if (name != NULL)
-- xmlFree(name);
-- XP_ERROR0(XPATH_UNCLOSED_ERROR);
-- }
-- NEXT;
-- return(name);
-- }
-- *test = NODE_TEST_NAME;
-- if ((!blanks) && (CUR == ':')) {
-- NEXT;
--
-- /*
-- * get the namespace name for this prefix
-- */
-- *prefix = xmlXPathNsLookup(ctxt->context, name);
-- if (name != NULL)
-- xmlFree(name);
-- if (*prefix == NULL) {
-- XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
-- }
--
-- if (CUR == '*') {
-- /*
-- * All elements
-- */
-- NEXT;
-- *test = NODE_TEST_ALL;
-- return(NULL);
-- }
--
-- name = xmlXPathParseNCName(ctxt);
-- if (name == NULL) {
-- XP_ERROR0(XPATH_EXPR_ERROR);
-- }
-- }
-- return(name);
--}
--
--/**
-- * xmlXPathIsAxisName:
-- * @name: a preparsed name token
-- *
-- * [6] AxisName ::= 'ancestor'
-- * | 'ancestor-or-self'
-- * | 'attribute'
-- * | 'child'
-- * | 'descendant'
-- * | 'descendant-or-self'
-- * | 'following'
-- * | 'following-sibling'
-- * | 'namespace'
-- * | 'parent'
-- * | 'preceding'
-- * | 'preceding-sibling'
-- * | 'self'
-- *
-- * Returns the axis or 0
-- */
--xmlXPathAxisVal
--xmlXPathIsAxisName(const xmlChar *name) {
-- xmlXPathAxisVal ret = 0;
-- switch (name[0]) {
-- case 'a':
-- if (xmlStrEqual(name, BAD_CAST "ancestor"))
-- ret = AXIS_ANCESTOR;
-- if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
-- ret = AXIS_ANCESTOR_OR_SELF;
-- if (xmlStrEqual(name, BAD_CAST "attribute"))
-- ret = AXIS_ATTRIBUTE;
-- break;
-- case 'c':
-- if (xmlStrEqual(name, BAD_CAST "child"))
-- ret = AXIS_CHILD;
-- break;
-- case 'd':
-- if (xmlStrEqual(name, BAD_CAST "descendant"))
-- ret = AXIS_DESCENDANT;
-- if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
-- ret = AXIS_DESCENDANT_OR_SELF;
-- break;
-- case 'f':
-- if (xmlStrEqual(name, BAD_CAST "following"))
-- ret = AXIS_FOLLOWING;
-- if (xmlStrEqual(name, BAD_CAST "following-sibling"))
-- ret = AXIS_FOLLOWING_SIBLING;
-- break;
-- case 'n':
-- if (xmlStrEqual(name, BAD_CAST "namespace"))
-- ret = AXIS_NAMESPACE;
-- break;
-- case 'p':
-- if (xmlStrEqual(name, BAD_CAST "parent"))
-- ret = AXIS_PARENT;
-- if (xmlStrEqual(name, BAD_CAST "preceding"))
-- ret = AXIS_PRECEDING;
-- if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
-- ret = AXIS_PRECEDING_SIBLING;
-- break;
-- case 's':
-- if (xmlStrEqual(name, BAD_CAST "self"))
-- ret = AXIS_SELF;
-- break;
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPathEvalAxisSpecifier:
-- * @ctxt: the XPath Parser context
-- *
-- *
-- * Returns the axis found
-- */
--xmlXPathAxisVal
--xmlXPathEvalAxisSpecifier(xmlXPathParserContextPtr ctxt) {
-- xmlXPathAxisVal ret = AXIS_CHILD;
-- int blank = 0;
-- xmlChar *name;
--
-- if (CUR == '@') {
-- NEXT;
-- return(AXIS_ATTRIBUTE);
-- } else {
-- name = xmlXPathParseNCName(ctxt);
-- if (name == NULL) {
-- XP_ERROR0(XPATH_EXPR_ERROR);
-- }
-- if (IS_BLANK(CUR))
-- blank = 1;
-- SKIP_BLANKS;
-- if ((CUR == ':') && (NXT(1) == ':')) {
-- ret = xmlXPathIsAxisName(name);
-- } else if ((blank) && (CUR == ':'))
-- XP_ERROR0(XPATH_EXPR_ERROR);
--
-- xmlFree(name);
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPathEvalStep:
-- * @ctxt: the XPath Parser context
-- *
-- * [4] Step ::= AxisSpecifier NodeTest Predicate*
-- * | AbbreviatedStep
-- *
-- * [12] AbbreviatedStep ::= '.' | '..'
-- *
-- * [5] AxisSpecifier ::= AxisName '::'
-- * | AbbreviatedAxisSpecifier
-- *
-- * [13] AbbreviatedAxisSpecifier ::= '@'?
-- *
-- * Modified for XPtr range support as:
-- *
-- * [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
-- * | AbbreviatedStep
-- * | 'range-to' '(' Expr ')' Predicate*
-- *
-- * Evaluate one step in a Location Path
-- * A location step of . is short for self::node(). This is
-- * particularly useful in conjunction with //. For example, the
-- * location path .//para is short for
-- * self::node()/descendant-or-self::node()/child::para
-- * and so will select all para descendant elements of the context
-- * node.
-- * Similarly, a location step of .. is short for parent::node().
-- * For example, ../title is short for parent::node()/child::title
-- * and so will select the title children of the parent of the context
-- * node.
-- */
--void
--xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
-- SKIP_BLANKS;
-- if ((CUR == '.') && (NXT(1) == '.')) {
-- SKIP(2);
-- SKIP_BLANKS;
-- xmlXPathNodeCollectAndTest(ctxt, AXIS_PARENT,
-- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-- } else if (CUR == '.') {
-- NEXT;
-- SKIP_BLANKS;
-- } else {
-- xmlChar *name = NULL;
-- const xmlChar *prefix = NULL;
-- xmlXPathTestVal test;
-- xmlXPathAxisVal axis;
-- xmlXPathTypeVal type;
--
-- /*
-- * The modification needed for XPointer change to the production
-- */
--#ifdef LIBXML_XPTR_ENABLED
-- if (ctxt->context->xptr) {
-- name = xmlXPathParseNCName(ctxt);
-- if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
-- xmlFree(name);
-- SKIP_BLANKS;
-- if (CUR != '(') {
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
--
-- xmlXPtrRangeToFunction(ctxt, 1);
-- CHECK_ERROR;
--
-- SKIP_BLANKS;
-- if (CUR != ')') {
-- XP_ERROR(XPATH_EXPR_ERROR);
-- }
-- NEXT;
-- goto eval_predicates;
-- }
-- }
--#endif
-- if (name == NULL)
-- name = xmlXPathParseNCName(ctxt);
-- if (name != NULL) {
-- axis = xmlXPathIsAxisName(name);
-- if (axis != 0) {
-- SKIP_BLANKS;
-- if ((CUR == ':') && (NXT(1) == ':')) {
-- SKIP(2);
-- xmlFree(name);
-- name = NULL;
-- } else {
-- /* an element name can conflict with an axis one :-\ */
-- axis = AXIS_CHILD;
-- }
-- } else {
-- axis = AXIS_CHILD;
-- }
-- } else if (CUR == '@') {
-- NEXT;
-- axis = AXIS_ATTRIBUTE;
-- } else {
-- axis = AXIS_CHILD;
-- }
--
-- CHECK_ERROR;
--
-- name = xmlXPathEvalNodeTest(ctxt, &test, &type, &prefix, name);
-- if (test == 0)
-- return;
--
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext,
-- "Basis : computing new set\n");
--#endif
-- xmlXPathNodeCollectAndTest(ctxt, axis, test, type, prefix, name);
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext, "Basis : ");
-- xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
--#endif
-- if (name != NULL)
-- xmlFree(name);
--
--eval_predicates:
-- SKIP_BLANKS;
-- while (CUR == '[') {
-- xmlXPathEvalPredicate(ctxt);
-- }
-- }
--#ifdef DEBUG_STEP
-- xmlGenericError(xmlGenericErrorContext, "Step : ");
-- xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
-- ctxt->value->nodesetval);
--#endif
--}
--
--/**
-- * xmlXPathEvalRelativeLocationPath:
-- * @ctxt: the XPath Parser context
-- *
-- * [3] RelativeLocationPath ::= Step
-- * | RelativeLocationPath '/' Step
-- * | AbbreviatedRelativeLocationPath
-- * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step
-- *
-- */
--void
--#ifdef VMS
--xmlXPathEvalRelLocationPath
--#else
--xmlXPathEvalRelativeLocationPath
--#endif
--(xmlXPathParserContextPtr ctxt) {
-- SKIP_BLANKS;
-- if ((CUR == '/') && (NXT(1) == '/')) {
-- SKIP(2);
-- SKIP_BLANKS;
-- xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
-- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-- } else if (CUR == '/') {
-- NEXT;
-- SKIP_BLANKS;
-- }
-- xmlXPathEvalStep(ctxt);
-- SKIP_BLANKS;
-- while (CUR == '/') {
-- if ((CUR == '/') && (NXT(1) == '/')) {
-- SKIP(2);
-- SKIP_BLANKS;
-- xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
-- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
-- xmlXPathEvalStep(ctxt);
-- } else if (CUR == '/') {
-- NEXT;
-- SKIP_BLANKS;
-- xmlXPathEvalStep(ctxt);
-- }
-- SKIP_BLANKS;
-- }
--}
--
--/**
-- * xmlXPathEvalLocationPath:
-- * @ctxt: the XPath Parser context
-- *
-- * [1] LocationPath ::= RelativeLocationPath
-- * | AbsoluteLocationPath
-- * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath?
-- * | AbbreviatedAbsoluteLocationPath
-- * [10] AbbreviatedAbsoluteLocationPath ::=
-- * '//' RelativeLocationPath
-- *
-- * // is short for /descendant-or-self::node()/. For example,
-- * //para is short for /descendant-or-self::node()/child::para and
-- * so will select any para element in the document (even a para element
-- * that is a document element will be selected by //para since the
-- * document element node is a child of the root node); div//para is
-- * short for div/descendant-or-self::node()/child::para and so will
-- * select all para descendants of div children.
-- */
--void
--xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
-- SKIP_BLANKS;
-- if (CUR != '/') {
-- xmlXPathEvalRelativeLocationPath(ctxt);
-- } else {
-- while (CUR == '/') {
-- if ((CUR == '/') && (NXT(1) == '/')) {
-- SKIP(2);
-- SKIP_BLANKS;
-- xmlXPathNodeCollectAndTest(ctxt,
-- AXIS_DESCENDANT_OR_SELF, NODE_TEST_TYPE,
-- NODE_TYPE_NODE, NULL, NULL);
-- xmlXPathEvalRelativeLocationPath(ctxt);
-- } else if (CUR == '/') {
-- NEXT;
-- SKIP_BLANKS;
-- if (CUR != 0)
-- xmlXPathEvalRelativeLocationPath(ctxt);
-- }
-- }
-- }
--}
--
--/**
-- * xmlXPathEval:
-- * @str: the XPath expression
-- * @ctx: the XPath context
-- *
-- * Evaluate the XPath Location Path in the given context.
-- *
-- * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
-- * the caller has to free the object.
-- */
--xmlXPathObjectPtr
--xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
-- xmlXPathParserContextPtr ctxt;
-- xmlXPathObjectPtr res = NULL, tmp, init = NULL;
-- int stack = 0;
--
-- xmlXPathInit();
--
-- CHECK_CONTEXT(ctx)
--
-- ctxt = xmlXPathNewParserContext(str, ctx);
-- /**** TAG:9999
-- if (ctx->node != NULL) {
-- init = xmlXPathNewNodeSet(ctx->node);
-- valuePush(ctxt, init);
-- }
-- ****/
-- xmlXPathEvalExpr(ctxt);
--
-- if (ctxt->value == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathEval: evaluation failed\n");
-- } else {
-- res = valuePop(ctxt);
-- }
--
-- do {
-- tmp = valuePop(ctxt);
-- if (tmp != NULL) {
-- if (tmp != init)
-- stack++;
-- xmlXPathFreeObject(tmp);
-- }
-- } while (tmp != NULL);
-- if (stack != 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathEval: %d object left on the stack\n",
-- stack);
-- }
-- if (ctxt->error != XPATH_EXPRESSION_OK) {
-- xmlXPathFreeObject(res);
-- res = NULL;
-- }
--
-- xmlXPathFreeParserContext(ctxt);
-- return(res);
--}
--
--/**
-- * xmlXPathEvalExpression:
-- * @str: the XPath expression
-- * @ctxt: the XPath context
-- *
-- * Evaluate the XPath expression in the given context.
-- *
-- * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
-- * the caller has to free the object.
-- */
--xmlXPathObjectPtr
--xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
-- xmlXPathParserContextPtr pctxt;
-- xmlXPathObjectPtr res, tmp;
-- int stack = 0;
--
-- xmlXPathInit();
--
-- CHECK_CONTEXT(ctxt)
--
-- pctxt = xmlXPathNewParserContext(str, ctxt);
-- xmlXPathEvalExpr(pctxt);
--
-- res = valuePop(pctxt);
-- do {
-- tmp = valuePop(pctxt);
-- if (tmp != NULL) {
-- xmlXPathFreeObject(tmp);
-- stack++;
-- }
-- } while (tmp != NULL);
-- if (stack != 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPathEvalExpression: %d object left on the stack\n",
-- stack);
-- }
-- xmlXPathFreeParserContext(pctxt);
-- return(res);
--}
--
--/**
-- * xmlXPathRegisterAllFunctions:
-- * @ctxt: the XPath context
-- *
-- * Registers all default XPath functions in this context
-- */
--void
--xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
--{
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
-- xmlXPathBooleanFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
-- xmlXPathCeilingFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
-- xmlXPathCountFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
-- xmlXPathConcatFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
-- xmlXPathContainsFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
-- xmlXPathIdFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
-- xmlXPathFalseFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
-- xmlXPathFloorFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
-- xmlXPathLastFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
-- xmlXPathLangFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
-- xmlXPathLocalNameFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
-- xmlXPathNotFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
-- xmlXPathNameFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
-- xmlXPathNamespaceURIFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
-- xmlXPathNormalizeFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
-- xmlXPathNumberFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
-- xmlXPathPositionFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
-- xmlXPathRoundFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
-- xmlXPathStringFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
-- xmlXPathStringLengthFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
-- xmlXPathStartsWithFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
-- xmlXPathSubstringFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
-- xmlXPathSubstringBeforeFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
-- xmlXPathSubstringAfterFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
-- xmlXPathSumFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
-- xmlXPathTrueFunction);
-- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
-- xmlXPathTranslateFunction);
--}
--
--#endif /* LIBXML_XPATH_ENABLED */
-diff -Nru libxml2-2.3.0/xpointer.c libxml2-2.3.0.new/xpointer.c
---- libxml2-2.3.0/xpointer.c Mon Feb 12 04:11:21 2001
-+++ libxml2-2.3.0.new/xpointer.c Thu Jan 1 01:00:00 1970
-@@ -1,2903 +0,0 @@
--/*
-- * xpointer.c : Code to handle XML Pointer
-- *
-- * World Wide Web Consortium Working Draft 03-March-1998
-- * http://www.w3.org/TR/2000/CR-xptr-20000607
-- *
-- * See Copyright for the status of this software.
-- *
-- * Daniel.Veillard@w3.org
-- */
--
--#ifdef WIN32
--#include "win32config.h"
--#else
--#include "config.h"
--#endif
--
--/**
-- * TODO: better handling of error cases, the full expression should
-- * be parsed beforehand instead of a progressive evaluation
-- * TODO: Access into entities references are not supported now ...
-- * need a start to be able to pop out of entities refs since
-- * parent is the endity declaration, not the ref.
-- */
--
--#include <stdio.h>
--#include <string.h>
--#include <libxml/xpointer.h>
--#include <libxml/xmlmemory.h>
--#include <libxml/parserInternals.h>
--#include <libxml/uri.h>
--#include <libxml/xpath.h>
--#include <libxml/xpathInternals.h>
--#ifdef LIBXML_DEBUG_ENABLED
--#include <libxml/debugXML.h>
--#endif
--#include <libxml/xmlerror.h>
--
--#ifdef LIBXML_XPTR_ENABLED
--
--/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
--#define XPTR_XMLNS_SCHEME
--
--/* #define DEBUG_RANGES */
--
--#define TODO \
-- xmlGenericError(xmlGenericErrorContext, \
-- "Unimplemented block at %s:%d\n", \
-- __FILE__, __LINE__);
--
--#define STRANGE \
-- xmlGenericError(xmlGenericErrorContext, \
-- "Internal error at %s:%d\n", \
-- __FILE__, __LINE__);
--
--/************************************************************************
-- * *
-- * A few helper functions for child sequences *
-- * *
-- ************************************************************************/
--
--xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
--/**
-- * xmlXPtrGetArity:
-- * @cur: the node
-- *
-- * Returns the number of child for an element, -1 in case of error
-- */
--int
--xmlXPtrGetArity(xmlNodePtr cur) {
-- int i;
-- if (cur == NULL)
-- return(-1);
-- cur = cur->children;
-- for (i = 0;cur != NULL;cur = cur->next) {
-- if ((cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- i++;
-- }
-- }
-- return(i);
--}
--
--/**
-- * xmlXPtrGetIndex:
-- * @cur: the node
-- *
-- * Returns the index of the node in its parent children list, -1
-- * in case of error
-- */
--int
--xmlXPtrGetIndex(xmlNodePtr cur) {
-- int i;
-- if (cur == NULL)
-- return(-1);
-- for (i = 1;cur != NULL;cur = cur->prev) {
-- if ((cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- i++;
-- }
-- }
-- return(i);
--}
--
--/**
-- * xmlXPtrGetNthChild:
-- * @cur: the node
-- * @no: the child number
-- *
-- * Returns the @no'th element child of @cur or NULL
-- */
--xmlNodePtr
--xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
-- int i;
-- if (cur == NULL)
-- return(cur);
-- cur = cur->children;
-- for (i = 0;i <= no;cur = cur->next) {
-- if (cur == NULL)
-- return(cur);
-- if ((cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- i++;
-- if (i == no)
-- break;
-- }
-- }
-- return(cur);
--}
--
--/************************************************************************
-- * *
-- * Handling of XPointer specific types *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPtrCmpPoints:
-- * @node1: the first node
-- * @index1: the first index
-- * @node2: the second node
-- * @index2: the second index
-- *
-- * Compare two points w.r.t document order
-- *
-- * Returns -2 in case of error 1 if first point < second point, 0 if
-- * that's the same point, -1 otherwise
-- */
--int
--xmlXPtrCmpPoints(xmlNodePtr node1, int index1, xmlNodePtr node2, int index2) {
-- if ((node1 == NULL) || (node2 == NULL))
-- return(-2);
-- /*
-- * a couple of optimizations which will avoid computations in most cases
-- */
-- if (node1 == node2) {
-- if (index1 < index2)
-- return(1);
-- if (index1 > index2)
-- return(-1);
-- return(0);
-- }
-- return(xmlXPathCmpNodes(node1, node2));
--}
--
--/**
-- * xmlXPtrNewPoint:
-- * @node: the xmlNodePtr
-- * @index: the index within the node
-- *
-- * Create a new xmlXPathObjectPtr of type point
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewPoint(xmlNodePtr node, int index) {
-- xmlXPathObjectPtr ret;
--
-- if (node == NULL)
-- return(NULL);
-- if (index < 0)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewPoint: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_POINT;
-- ret->user = (void *) node;
-- ret->index = index;
-- return(ret);
--}
--
--/**
-- * xmlXPtrRangeCheckOrder:
-- * @range: an object range
-- *
-- * Make sure the points in the range are in the right order
-- */
--void
--xmlXPtrRangeCheckOrder(xmlXPathObjectPtr range) {
-- int tmp;
-- xmlNodePtr tmp2;
-- if (range == NULL)
-- return;
-- if (range->type != XPATH_RANGE)
-- return;
-- if (range->user2 == NULL)
-- return;
-- tmp = xmlXPtrCmpPoints(range->user, range->index,
-- range->user2, range->index2);
-- if (tmp == -1) {
-- tmp2 = range->user;
-- range->user = range->user2;
-- range->user2 = tmp2;
-- tmp = range->index;
-- range->index = range->index2;
-- range->index2 = tmp;
-- }
--}
--
--/**
-- * xmlXPtrRangesEqual:
-- * @range1: the first range
-- * @range2: the second range
-- *
-- * Compare two ranges
-- *
-- * Return 1 if equal, 0 otherwise
-- */
--int
--xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
-- if (range1 == range2)
-- return(1);
-- if ((range1 == NULL) || (range2 == NULL))
-- return(0);
-- if (range1->type != range2->type)
-- return(0);
-- if (range1->type != XPATH_RANGE)
-- return(0);
-- if (range1->user != range2->user)
-- return(0);
-- if (range1->index != range2->index)
-- return(0);
-- if (range1->user2 != range2->user2)
-- return(0);
-- if (range1->index2 != range2->index2)
-- return(0);
-- return(1);
--}
--
--/**
-- * xmlXPtrNewRange:
-- * @start: the starting node
-- * @startindex: the start index
-- * @end: the ending point
-- * @endindex: the ending index
-- *
-- * Create a new xmlXPathObjectPtr of type range
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewRange(xmlNodePtr start, int startindex,
-- xmlNodePtr end, int endindex) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
-- if (end == NULL)
-- return(NULL);
-- if (startindex < 0)
-- return(NULL);
-- if (endindex < 0)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangePoints: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start;
-- ret->index = startindex;
-- ret->user2 = end;
-- ret->index2 = endindex;
-- xmlXPtrRangeCheckOrder(ret);
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewRangePoints:
-- * @start: the starting point
-- * @end: the ending point
-- *
-- * Create a new xmlXPathObjectPtr of type range using 2 Points
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
-- if (end == NULL)
-- return(NULL);
-- if (start->type != XPATH_POINT)
-- return(NULL);
-- if (end->type != XPATH_POINT)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangePoints: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start->user;
-- ret->index = start->index;
-- ret->user2 = end->user;
-- ret->index2 = end->index;
-- xmlXPtrRangeCheckOrder(ret);
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewRangePointNode:
-- * @start: the starting point
-- * @end: the ending node
-- *
-- * Create a new xmlXPathObjectPtr of type range from a point to a node
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
-- if (end == NULL)
-- return(NULL);
-- if (start->type != XPATH_POINT)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangePointNode: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start->user;
-- ret->index = start->index;
-- ret->user2 = end;
-- ret->index2 = -1;
-- xmlXPtrRangeCheckOrder(ret);
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewRangeNodePoint:
-- * @start: the starting node
-- * @end: the ending point
-- *
-- * Create a new xmlXPathObjectPtr of type range from a node to a point
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
-- if (end == NULL)
-- return(NULL);
-- if (start->type != XPATH_POINT)
-- return(NULL);
-- if (end->type != XPATH_POINT)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangeNodePoint: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start;
-- ret->index = -1;
-- ret->user2 = end->user;
-- ret->index2 = end->index;
-- xmlXPtrRangeCheckOrder(ret);
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewRangeNodes:
-- * @start: the starting node
-- * @end: the ending node
-- *
-- * Create a new xmlXPathObjectPtr of type range using 2 nodes
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
-- if (end == NULL)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangeNodes: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start;
-- ret->index = -1;
-- ret->user2 = end;
-- ret->index2 = -1;
-- xmlXPtrRangeCheckOrder(ret);
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewCollapsedRange:
-- * @start: the starting and ending node
-- *
-- * Create a new xmlXPathObjectPtr of type range using a single nodes
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewCollapsedRange(xmlNodePtr start) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangeNodes: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start;
-- ret->index = -1;
-- ret->user2 = NULL;
-- ret->index2 = -1;
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewRangeNodeObject:
-- * @start: the starting node
-- * @end: the ending object
-- *
-- * Create a new xmlXPathObjectPtr of type range from a not to an object
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
-- xmlXPathObjectPtr ret;
--
-- if (start == NULL)
-- return(NULL);
-- if (end == NULL)
-- return(NULL);
-- switch (end->type) {
-- case XPATH_POINT:
-- break;
-- case XPATH_NODESET:
-- /*
-- * Empty set ...
-- */
-- if (end->nodesetval->nodeNr <= 0)
-- return(NULL);
-- break;
-- default:
-- TODO
-- return(NULL);
-- }
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewRangeNodeObject: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_RANGE;
-- ret->user = start;
-- ret->index = -1;
-- switch (end->type) {
-- case XPATH_POINT:
-- ret->user2 = end->user;
-- ret->index2 = end->index;
-- case XPATH_NODESET: {
-- ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
-- ret->index2 = -1;
-- break;
-- }
-- default:
-- STRANGE
-- return(NULL);
-- }
-- xmlXPtrRangeCheckOrder(ret);
-- return(ret);
--}
--
--#define XML_RANGESET_DEFAULT 10
--
--/**
-- * xmlXPtrLocationSetCreate:
-- * @val: an initial xmlXPathObjectPtr, or NULL
-- *
-- * Create a new xmlLocationSetPtr of type double and of value @val
-- *
-- * Returns the newly created object.
-- */
--xmlLocationSetPtr
--xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) {
-- xmlLocationSetPtr ret;
--
-- ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrLocationSetCreate: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlLocationSet));
-- if (val != NULL) {
-- ret->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
-- sizeof(xmlXPathObjectPtr));
-- if (ret->locTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrLocationSetCreate: out of memory\n");
-- return(NULL);
-- }
-- memset(ret->locTab, 0 ,
-- XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
-- ret->locMax = XML_RANGESET_DEFAULT;
-- ret->locTab[ret->locNr++] = val;
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPtrLocationSetAdd:
-- * @cur: the initial range set
-- * @val: a new xmlXPathObjectPtr
-- *
-- * add a new xmlXPathObjectPtr ot an existing LocationSet
-- * If the location already exist in the set @val is freed.
-- */
--void
--xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
-- int i;
--
-- if (val == NULL) return;
--
-- /*
-- * check against doublons
-- */
-- for (i = 0;i < cur->locNr;i++) {
-- if (xmlXPtrRangesEqual(cur->locTab[i], val)) {
-- xmlXPathFreeObject(val);
-- return;
-- }
-- }
--
-- /*
-- * grow the locTab if needed
-- */
-- if (cur->locMax == 0) {
-- cur->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
-- sizeof(xmlXPathObjectPtr));
-- if (cur->locTab == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrLocationSetAdd: out of memory\n");
-- return;
-- }
-- memset(cur->locTab, 0 ,
-- XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
-- cur->locMax = XML_RANGESET_DEFAULT;
-- } else if (cur->locNr == cur->locMax) {
-- xmlXPathObjectPtr *temp;
--
-- cur->locMax *= 2;
-- temp = (xmlXPathObjectPtr *) xmlRealloc(cur->locTab, cur->locMax *
-- sizeof(xmlXPathObjectPtr));
-- if (temp == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrLocationSetAdd: out of memory\n");
-- return;
-- }
-- cur->locTab = temp;
-- }
-- cur->locTab[cur->locNr++] = val;
--}
--
--/**
-- * xmlXPtrLocationSetMerge:
-- * @val1: the first LocationSet
-- * @val2: the second LocationSet
-- *
-- * Merges two rangesets, all ranges from @val2 are added to @val1
-- *
-- * Returns val1 once extended or NULL in case of error.
-- */
--xmlLocationSetPtr
--xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) {
-- int i;
--
-- if (val1 == NULL) return(NULL);
-- if (val2 == NULL) return(val1);
--
-- /*
-- * !!!!! this can be optimized a lot, knowing that both
-- * val1 and val2 already have unicity of their values.
-- */
--
-- for (i = 0;i < val2->locNr;i++)
-- xmlXPtrLocationSetAdd(val1, val2->locTab[i]);
--
-- return(val1);
--}
--
--/**
-- * xmlXPtrLocationSetDel:
-- * @cur: the initial range set
-- * @val: an xmlXPathObjectPtr
-- *
-- * Removes an xmlXPathObjectPtr from an existing LocationSet
-- */
--void
--xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
-- int i;
--
-- if (cur == NULL) return;
-- if (val == NULL) return;
--
-- /*
-- * check against doublons
-- */
-- for (i = 0;i < cur->locNr;i++)
-- if (cur->locTab[i] == val) break;
--
-- if (i >= cur->locNr) {
--#ifdef DEBUG
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrLocationSetDel: Range %s wasn't found in RangeList\n",
-- val->name);
--#endif
-- return;
-- }
-- cur->locNr--;
-- for (;i < cur->locNr;i++)
-- cur->locTab[i] = cur->locTab[i + 1];
-- cur->locTab[cur->locNr] = NULL;
--}
--
--/**
-- * xmlXPtrLocationSetRemove:
-- * @cur: the initial range set
-- * @val: the index to remove
-- *
-- * Removes an entry from an existing LocationSet list.
-- */
--void
--xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) {
-- if (cur == NULL) return;
-- if (val >= cur->locNr) return;
-- cur->locNr--;
-- for (;val < cur->locNr;val++)
-- cur->locTab[val] = cur->locTab[val + 1];
-- cur->locTab[cur->locNr] = NULL;
--}
--
--/**
-- * xmlXPtrFreeLocationSet:
-- * @obj: the xmlLocationSetPtr to free
-- *
-- * Free the LocationSet compound (not the actual ranges !).
-- */
--void
--xmlXPtrFreeLocationSet(xmlLocationSetPtr obj) {
-- int i;
--
-- if (obj == NULL) return;
-- if (obj->locTab != NULL) {
-- for (i = 0;i < obj->locNr; i++) {
-- xmlXPathFreeObject(obj->locTab[i]);
-- }
--#ifdef DEBUG
-- memset(obj->locTab, 0xB ,
-- (size_t) sizeof(xmlXPathObjectPtr) * obj->locMax);
--#endif
-- xmlFree(obj->locTab);
-- }
--#ifdef DEBUG
-- memset(obj, 0xB , (size_t) sizeof(xmlLocationSet));
--#endif
-- xmlFree(obj);
--}
--
--/**
-- * xmlXPtrNewLocationSetNodes:
-- * @start: the start NodePtr value
-- * @end: the end NodePtr value or NULL
-- *
-- * Create a new xmlXPathObjectPtr of type LocationSet and initialize
-- * it with the single range made of the two nodes @start and @end
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewLocationSetNodes: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_LOCATIONSET;
-- if (end == NULL)
-- ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewCollapsedRange(start));
-- else
-- ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewRangeNodes(start,end));
-- return(ret);
--}
--
--/**
-- * xmlXPtrNewLocationSetNodeSet:
-- * @set: a node set
-- *
-- * Create a new xmlXPathObjectPtr of type LocationSet and initialize
-- * it with all the nodes from @set
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrNewLocationSetNodes: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_LOCATIONSET;
-- if (set != NULL) {
-- int i;
-- xmlLocationSetPtr newset;
--
-- newset = xmlXPtrLocationSetCreate(NULL);
-- if (newset == NULL)
-- return(ret);
--
-- for (i = 0;i < set->nodeNr;i++)
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrNewCollapsedRange(set->nodeTab[i]));
--
-- ret->user = (void *) newset;
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPtrWrapLocationSet:
-- * @val: the LocationSet value
-- *
-- * Wrap the LocationSet @val in a new xmlXPathObjectPtr
-- *
-- * Returns the newly created object.
-- */
--xmlXPathObjectPtr
--xmlXPtrWrapLocationSet(xmlLocationSetPtr val) {
-- xmlXPathObjectPtr ret;
--
-- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-- if (ret == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrWrapLocationSet: out of memory\n");
-- return(NULL);
-- }
-- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-- ret->type = XPATH_LOCATIONSET;
-- ret->user = (void *) val;
-- return(ret);
--}
--
--/************************************************************************
-- * *
-- * The parser *
-- * *
-- ************************************************************************/
--
--/*
-- * Macros for accessing the content. Those should be used only by the parser,
-- * and not exported.
-- *
-- * Dirty macros, i.e. one need to make assumption on the context to use them
-- *
-- * CUR_PTR return the current pointer to the xmlChar to be parsed.
-- * CUR returns the current xmlChar value, i.e. a 8 bit value
-- * in ISO-Latin or UTF-8.
-- * This should be used internally by the parser
-- * only to compare to ASCII values otherwise it would break when
-- * running with UTF-8 encoding.
-- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
-- * to compare on ASCII based substring.
-- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
-- * strings within the parser.
-- * CURRENT Returns the current char value, with the full decoding of
-- * UTF-8 if we are using this mode. It returns an int.
-- * NEXT Skip to the next character, this does the proper decoding
-- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
-- * It returns the pointer to the current xmlChar.
-- */
--
--#define CUR (*ctxt->cur)
--#define SKIP(val) ctxt->cur += (val)
--#define NXT(val) ctxt->cur[(val)]
--#define CUR_PTR ctxt->cur
--
--#define SKIP_BLANKS \
-- while (IS_BLANK(*(ctxt->cur))) NEXT
--
--#define CURRENT (*ctxt->cur)
--#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
--
--/*
-- * xmlXPtrGetChildNo:
-- * @ctxt: the XPointer Parser context
-- * @index: the child number
-- *
-- * Move the current node of the nodeset on the stack to the
-- * given child if found
-- */
--void
--xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int index) {
-- xmlNodePtr cur = NULL;
-- xmlXPathObjectPtr obj;
-- xmlNodeSetPtr oldset;
--
-- CHECK_TYPE(XPATH_NODESET);
-- obj = valuePop(ctxt);
-- oldset = obj->nodesetval;
-- if ((index <= 0) || (oldset == NULL) || (oldset->nodeNr != 1)) {
-- xmlXPathFreeObject(obj);
-- valuePush(ctxt, xmlXPathNewNodeSet(NULL));
-- return;
-- }
-- cur = xmlXPtrGetNthChild(oldset->nodeTab[0], index);
-- if (cur == NULL) {
-- xmlXPathFreeObject(obj);
-- valuePush(ctxt, xmlXPathNewNodeSet(NULL));
-- return;
-- }
-- oldset->nodeTab[0] = cur;
-- valuePush(ctxt, obj);
--}
--
--/**
-- * xmlXPtrEvalXPtrPart:
-- * @ctxt: the XPointer Parser context
-- * @name: the preparsed Scheme for the XPtrPart
-- *
-- * XPtrPart ::= 'xpointer' '(' XPtrExpr ')'
-- * | Scheme '(' SchemeSpecificExpr ')'
-- *
-- * Scheme ::= NCName - 'xpointer' [VC: Non-XPointer schemes]
-- *
-- * SchemeSpecificExpr ::= StringWithBalancedParens
-- *
-- * StringWithBalancedParens ::=
-- * [^()]* ('(' StringWithBalancedParens ')' [^()]*)*
-- * [VC: Parenthesis escaping]
-- *
-- * XPtrExpr ::= Expr [VC: Parenthesis escaping]
-- *
-- * VC: Parenthesis escaping:
-- * The end of an XPointer part is signaled by the right parenthesis ")"
-- * character that is balanced with the left parenthesis "(" character
-- * that began the part. Any unbalanced parenthesis character inside the
-- * expression, even within literals, must be escaped with a circumflex (^)
-- * character preceding it. If the expression contains any literal
-- * occurrences of the circumflex, each must be escaped with an additional
-- * circumflex (that is, ^^). If the unescaped parentheses in the expression
-- * are not balanced, a syntax error results.
-- *
-- * Parse and evaluate an XPtrPart. Basically it generates the unescaped
-- * string and if the scheme is 'xpointer' it will call the XPath interprter.
-- *
-- * TODO: there is no new scheme registration mechanism
-- */
--
--void
--xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
-- xmlChar *buffer, *cur;
-- int len;
-- int level;
--
-- if (name == NULL)
-- name = xmlXPathParseName(ctxt);
-- if (name == NULL)
-- XP_ERROR(XPATH_EXPR_ERROR);
--
-- if (CUR != '(')
-- XP_ERROR(XPATH_EXPR_ERROR);
-- NEXT;
-- level = 1;
--
-- len = xmlStrlen(ctxt->cur);
-- len++;
-- buffer = (xmlChar *) xmlMalloc(len * sizeof (xmlChar));
-- if (buffer == NULL) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrEvalXPtrPart: out of memory\n");
-- return;
-- }
--
-- cur = buffer;
-- while (CUR != 0) {
-- if (CUR == ')') {
-- level--;
-- if (level == 0) {
-- NEXT;
-- break;
-- }
-- *cur++ = CUR;
-- } else if (CUR == '(') {
-- level++;
-- *cur++ = CUR;
-- } else if (CUR == '^') {
-- NEXT;
-- if ((CUR == ')') || (CUR == '(') || (CUR == '^')) {
-- *cur++ = CUR;
-- } else {
-- *cur++ = '^';
-- *cur++ = CUR;
-- }
-- } else {
-- *cur++ = CUR;
-- }
-- NEXT;
-- }
-- *cur = 0;
--
-- if ((level != 0) && (CUR == 0)) {
-- xmlFree(buffer);
-- XP_ERROR(XPTR_SYNTAX_ERROR);
-- }
--
-- if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
-- const xmlChar *left = CUR_PTR;
--
-- CUR_PTR = buffer;
-- xmlXPathRoot(ctxt);
-- xmlXPathEvalExpr(ctxt);
-- CUR_PTR=left;
--#ifdef XPTR_XMLNS_SCHEME
-- } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
-- const xmlChar *left = CUR_PTR;
-- xmlChar *prefix;
-- xmlChar *URI;
-- xmlURIPtr value;
--
-- CUR_PTR = buffer;
-- prefix = xmlXPathParseNCName(ctxt);
-- if (prefix == NULL) {
-- xmlFree(buffer);
-- xmlFree(name);
-- XP_ERROR(XPTR_SYNTAX_ERROR);
-- }
-- SKIP_BLANKS;
-- if (CUR != '=') {
-- xmlFree(prefix);
-- xmlFree(buffer);
-- xmlFree(name);
-- XP_ERROR(XPTR_SYNTAX_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
-- /* @@ check escaping in the XPointer WD */
--
-- value = xmlParseURI((const char *)ctxt->cur);
-- if (value == NULL) {
-- xmlFree(prefix);
-- xmlFree(buffer);
-- xmlFree(name);
-- XP_ERROR(XPTR_SYNTAX_ERROR);
-- }
-- URI = xmlSaveUri(value);
-- xmlFreeURI(value);
-- if (URI == NULL) {
-- xmlFree(prefix);
-- xmlFree(buffer);
-- xmlFree(name);
-- XP_ERROR(XPATH_MEMORY_ERROR);
-- }
--
-- xmlXPathRegisterNs(ctxt->context, prefix, URI);
-- CUR_PTR = left;
--#endif /* XPTR_XMLNS_SCHEME */
-- } else {
-- xmlGenericError(xmlGenericErrorContext,
-- "unsupported scheme '%s'\n", name);
-- }
-- xmlFree(buffer);
-- xmlFree(name);
--}
--
--/**
-- * xmlXPtrEvalFullXPtr:
-- * @ctxt: the XPointer Parser context
-- * @name: the preparsed Scheme for the first XPtrPart
-- *
-- * FullXPtr ::= XPtrPart (S? XPtrPart)*
-- *
-- * As the specs says:
-- * -----------
-- * When multiple XPtrParts are provided, they must be evaluated in
-- * left-to-right order. If evaluation of one part fails, the nexti
-- * is evaluated. The following conditions cause XPointer part failure:
-- *
-- * - An unknown scheme
-- * - A scheme that does not locate any sub-resource present in the resource
-- * - A scheme that is not applicable to the media type of the resource
-- *
-- * The XPointer application must consume a failed XPointer part and
-- * attempt to evaluate the next one, if any. The result of the first
-- * XPointer part whose evaluation succeeds is taken to be the fragment
-- * located by the XPointer as a whole. If all the parts fail, the result
-- * for the XPointer as a whole is a sub-resource error.
-- * -----------
-- *
-- * Parse and evaluate a Full XPtr i.e. possibly a cascade of XPath based
-- * expressions or other shemes.
-- */
--void
--xmlXPtrEvalFullXPtr(xmlXPathParserContextPtr ctxt, xmlChar *name) {
-- if (name == NULL)
-- name = xmlXPathParseName(ctxt);
-- if (name == NULL)
-- XP_ERROR(XPATH_EXPR_ERROR);
-- while (name != NULL) {
-- xmlXPtrEvalXPtrPart(ctxt, name);
--
-- /* in case of syntax error, break here */
-- if (ctxt->error != XPATH_EXPRESSION_OK)
-- return;
--
-- /*
-- * If the returned value is a non-empty nodeset
-- * or location set, return here.
-- */
-- if (ctxt->value != NULL) {
-- xmlXPathObjectPtr obj = ctxt->value;
--
-- switch (obj->type) {
-- case XPATH_LOCATIONSET: {
-- xmlLocationSetPtr loc = ctxt->value->user;
-- if ((loc != NULL) && (loc->locNr > 0))
-- return;
-- break;
-- }
-- case XPATH_NODESET: {
-- xmlNodeSetPtr loc = ctxt->value->nodesetval;
-- if ((loc != NULL) && (loc->nodeNr > 0))
-- return;
-- break;
-- }
-- default:
-- break;
-- }
--
-- /*
-- * Evaluating to improper values is equivalent to
-- * a sub-resource error, clean-up the stack
-- */
-- do {
-- obj = valuePop(ctxt);
-- if (obj != NULL) {
-- xmlXPathFreeObject(obj);
-- }
-- } while (obj != NULL);
-- }
--
-- /*
-- * Is there another XPoointer part.
-- */
-- SKIP_BLANKS;
-- name = xmlXPathParseName(ctxt);
-- }
--}
--
--/**
-- * xmlXPtrEvalChildSeq:
-- * @ctxt: the XPointer Parser context
-- * @name: a possible ID name of the child sequence
-- *
-- * ChildSeq ::= '/1' ('/' [0-9]*)*
-- * | Name ('/' [0-9]*)+
-- *
-- * Parse and evaluate a Child Sequence. This routine also handle the
-- * case of a Bare Name used to get a document ID.
-- */
--void
--xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
-- /*
-- * XPointer don't allow by syntax to adress in mutirooted trees
-- * this might prove useful in some cases, warn about it.
-- */
-- if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) {
-- xmlGenericError(xmlGenericErrorContext,
-- "warning: ChildSeq not starting by /1\n");
-- }
--
-- if (name != NULL) {
-- valuePush(ctxt, xmlXPathNewString(name));
-- xmlFree(name);
-- xmlXPathIdFunction(ctxt, 1);
-- CHECK_ERROR;
-- }
--
-- while (CUR == '/') {
-- int child = 0;
-- NEXT;
--
-- while ((CUR >= '0') && (CUR <= '9')) {
-- child = child * 10 + (CUR - '0');
-- NEXT;
-- }
-- xmlXPtrGetChildNo(ctxt, child);
-- }
--}
--
--
--/**
-- * xmlXPtrEvalXPointer:
-- * @ctxt: the XPointer Parser context
-- *
-- * XPointer ::= Name
-- * | ChildSeq
-- * | FullXPtr
-- *
-- * Parse and evaluate an XPointer
-- */
--void
--xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
-- SKIP_BLANKS;
-- if (CUR == '/') {
-- xmlXPathRoot(ctxt);
-- xmlXPtrEvalChildSeq(ctxt, NULL);
-- } else {
-- xmlChar *name;
--
-- name = xmlXPathParseName(ctxt);
-- if (name == NULL)
-- XP_ERROR(XPATH_EXPR_ERROR);
-- if (CUR == '(') {
-- xmlXPtrEvalFullXPtr(ctxt, name);
-- /* Short evaluation */
-- return;
-- } else {
-- /* this handle both Bare Names and Child Sequences */
-- xmlXPtrEvalChildSeq(ctxt, name);
-- }
-- }
-- SKIP_BLANKS;
-- if (CUR != 0)
-- XP_ERROR(XPATH_EXPR_ERROR);
--}
--
--
--/************************************************************************
-- * *
-- * General routines *
-- * *
-- ************************************************************************/
--
--void xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);
--void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
--
--/**
-- * xmlXPtrNewContext:
-- * @doc: the XML document
-- * @here: the node that directly contains the XPointer being evaluated or NULL
-- * @origin: the element from which a user or program initiated traversal of
-- * the link, or NULL.
-- *
-- * Create a new XPointer context
-- *
-- * Returns the xmlXPathContext just allocated.
-- */
--xmlXPathContextPtr
--xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
-- xmlXPathContextPtr ret;
--
-- ret = xmlXPathNewContext(doc);
-- if (ret == NULL)
-- return(ret);
-- ret->xptr = 1;
-- ret->here = here;
-- ret->origin = origin;
--
-- xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
-- xmlXPtrRangeToFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)"range",
-- xmlXPtrRangeFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
-- xmlXPtrRangeInsideFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)"string-range",
-- xmlXPtrStringRangeFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)"start-point",
-- xmlXPtrStartPointFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)"end-point",
-- xmlXPtrEndPointFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)"here",
-- xmlXPtrHereFunction);
-- xmlXPathRegisterFunc(ret, (xmlChar *)" origin",
-- xmlXPtrOriginFunction);
--
-- return(ret);
--}
--
--/**
-- * xmlXPtrEval:
-- * @str: the XPointer expression
-- * @ctx: the XPointer context
-- *
-- * Evaluate the XPath Location Path in the given context.
-- *
-- * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
-- * the caller has to free the object.
-- */
--xmlXPathObjectPtr
--xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
-- xmlXPathParserContextPtr ctxt;
-- xmlXPathObjectPtr res = NULL, tmp;
-- xmlXPathObjectPtr init = NULL;
-- int stack = 0;
--
-- xmlXPathInit();
--
-- if ((ctx == NULL) || (str == NULL))
-- return(NULL);
--
-- ctxt = xmlXPathNewParserContext(str, ctx);
-- /* TAG:9999
-- if (ctx->node != NULL) {
-- init = xmlXPathNewNodeSet(ctx->node);
-- valuePush(ctxt, init);
-- }
-- */
-- xmlXPtrEvalXPointer(ctxt);
--
-- if ((ctxt->value != NULL) &&
-- (ctxt->value->type != XPATH_NODESET) &&
-- (ctxt->value->type != XPATH_LOCATIONSET)) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrEval: evaluation failed to return a node set\n");
-- } else {
-- res = valuePop(ctxt);
-- }
--
-- do {
-- tmp = valuePop(ctxt);
-- if (tmp != NULL) {
-- if (tmp != init) {
-- if (tmp->type == XPATH_NODESET) {
-- /*
-- * Evaluation may push a root nodeset which is unused
-- */
-- xmlNodeSetPtr set;
-- set = tmp->nodesetval;
-- if ((set->nodeNr != 1) ||
-- (set->nodeTab[0] != (xmlNodePtr) ctx->doc))
-- stack++;
-- } else
-- stack++;
-- }
-- xmlXPathFreeObject(tmp);
-- }
-- } while (tmp != NULL);
-- if (stack != 0) {
-- xmlGenericError(xmlGenericErrorContext,
-- "xmlXPtrEval: %d object left on the stack\n",
-- stack);
-- }
-- if (ctxt->error != XPATH_EXPRESSION_OK) {
-- xmlXPathFreeObject(res);
-- res = NULL;
-- }
--
-- xmlXPathFreeParserContext(ctxt);
-- return(res);
--}
--
--/**
-- * xmlXPtrBuildRangeNodeList:
-- * @range: a range object
-- *
-- * Build a node list tree copy of the range
-- *
-- * Returns an xmlNodePtr list or NULL.
-- * the caller has to free the node tree.
-- */
--xmlNodePtr
--xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
-- /* pointers to generated nodes */
-- xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;
-- /* pointers to traversal nodes */
-- xmlNodePtr start, cur, end;
-- int index, index2;
--
-- if (range == NULL)
-- return(NULL);
-- if (range->type != XPATH_RANGE)
-- return(NULL);
-- start = (xmlNodePtr) range->user;
--
-- if (start == NULL)
-- return(NULL);
-- end = range->user2;
-- if (end == NULL)
-- return(xmlCopyNode(start, 1));
--
-- cur = start;
-- index = range->index;
-- index2 = range->index2;
-- while (cur != NULL) {
-- if (cur == end) {
-- if (cur->type == XML_TEXT_NODE) {
-- const xmlChar *content = cur->content;
-- int len;
--
-- if (content == NULL) {
-- tmp = xmlNewTextLen(NULL, 0);
-- } else {
-- len = index2;
-- if ((cur == start) && (index > 1)) {
-- content += (index - 1);
-- len -= (index - 1);
-- index = 0;
-- } else {
-- len = index2;
-- }
-- tmp = xmlNewTextLen(content, len);
-- }
-- /* single sub text node selection */
-- if (list == NULL)
-- return(tmp);
-- /* prune and return full set */
-- if (last != NULL)
-- xmlAddNextSibling(last, tmp);
-- else
-- xmlAddChild(parent, tmp);
-- return(list);
-- } else {
-- tmp = xmlCopyNode(cur, 0);
-- if (list == NULL)
-- list = tmp;
-- else {
-- if (last != NULL)
-- xmlAddNextSibling(last, tmp);
-- else
-- xmlAddChild(parent, tmp);
-- }
-- last = NULL;
-- parent = tmp;
--
-- if (index2 > 1) {
-- end = xmlXPtrGetNthChild(cur, index2 - 1);
-- index2 = 0;
-- }
-- if ((cur == start) && (index > 1)) {
-- cur = xmlXPtrGetNthChild(cur, index - 1);
-- index = 0;
-- } else {
-- cur = cur->children;
-- }
-- /*
-- * Now gather the remaining nodes from cur to end
-- */
-- continue; /* while */
-- }
-- } else if ((cur == start) &&
-- (list == NULL) /* looks superfluous but ... */ ) {
-- if (cur->type == XML_TEXT_NODE) {
-- const xmlChar *content = cur->content;
--
-- if (content == NULL) {
-- tmp = xmlNewTextLen(NULL, 0);
-- } else {
-- if (index > 1) {
-- content += (index - 1);
-- }
-- tmp = xmlNewText(content);
-- }
-- last = list = tmp;
-- } else {
-- if ((cur == start) && (index > 1)) {
-- tmp = xmlCopyNode(cur, 0);
-- list = tmp;
-- parent = tmp;
-- last = NULL;
-- cur = xmlXPtrGetNthChild(cur, index - 1);
-- index = 0;
-- /*
-- * Now gather the remaining nodes from cur to end
-- */
-- continue; /* while */
-- }
-- tmp = xmlCopyNode(cur, 1);
-- list = tmp;
-- parent = NULL;
-- last = tmp;
-- }
-- } else {
-- tmp = NULL;
-- switch (cur->type) {
-- case XML_DTD_NODE:
-- case XML_ELEMENT_DECL:
-- case XML_ATTRIBUTE_DECL:
-- case XML_ENTITY_NODE:
-- /* Do not copy DTD informations */
-- break;
-- case XML_ENTITY_DECL:
-- TODO /* handle csossing entities -> stack needed */
-- break;
-- case XML_XINCLUDE_START:
-- case XML_XINCLUDE_END:
-- /* don't consider it part of the tree content */
-- break;
-- case XML_ATTRIBUTE_NODE:
-- /* Humm, should not happen ! */
-- STRANGE
-- break;
-- default:
-- tmp = xmlCopyNode(cur, 1);
-- break;
-- }
-- if (tmp != NULL) {
-- if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
-- STRANGE
-- return(NULL);
-- }
-- if (last != NULL)
-- xmlAddNextSibling(last, tmp);
-- else {
-- xmlAddChild(parent, tmp);
-- last = tmp;
-- }
-- }
-- }
-- /*
-- * Skip to next node in document order
-- */
-- if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
-- STRANGE
-- return(NULL);
-- }
-- cur = xmlXPtrAdvanceNode(cur);
-- }
-- return(list);
--}
--
--/**
-- * xmlXPtrBuildNodeList:
-- * @obj: the XPointer result from the evaluation.
-- *
-- * Build a node list tree copy of the XPointer result.
-- *
-- * Returns an xmlNodePtr list or NULL.
-- * the caller has to free the node tree.
-- */
--xmlNodePtr
--xmlXPtrBuildNodeList(xmlXPathObjectPtr obj) {
-- xmlNodePtr list = NULL, last = NULL;
-- int i;
--
-- if (obj == NULL)
-- return(NULL);
-- switch (obj->type) {
-- case XPATH_NODESET: {
-- xmlNodeSetPtr set = obj->nodesetval;
-- if (set == NULL)
-- return(NULL);
-- for (i = 0;i < set->nodeNr;i++) {
-- if (last == NULL)
-- list = last = xmlCopyNode(set->nodeTab[i], 1);
-- else {
-- xmlAddNextSibling(last, xmlCopyNode(set->nodeTab[i], 1));
-- if (last->next != NULL)
-- last = last->next;
-- }
-- }
-- break;
-- }
-- case XPATH_LOCATIONSET: {
-- xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
-- if (set == NULL)
-- return(NULL);
-- for (i = 0;i < set->locNr;i++) {
-- if (last == NULL)
-- list = last = xmlXPtrBuildNodeList(set->locTab[i]);
-- else
-- xmlAddNextSibling(last,
-- xmlXPtrBuildNodeList(set->locTab[i]));
-- if (last != NULL) {
-- while (last->next != NULL)
-- last = last->next;
-- }
-- }
-- break;
-- }
-- case XPATH_RANGE:
-- return(xmlXPtrBuildRangeNodeList(obj));
-- case XPATH_POINT:
-- return(xmlCopyNode(obj->user, 0));
-- default:
-- break;
-- }
-- return(list);
--}
--
--/************************************************************************
-- * *
-- * XPointer functions *
-- * *
-- ************************************************************************/
--
--/**
-- * xmlXPtrNbLocChildren:
-- * @node: an xmlNodePtr
-- *
-- * Count the number of location children of @node or the lenght of the
-- * string value in case of text/PI/Comments nodes
-- *
-- * Returns the number of location children
-- */
--int
--xmlXPtrNbLocChildren(xmlNodePtr node) {
-- int ret = 0;
-- if (node == NULL)
-- return(-1);
-- switch (node->type) {
-- case XML_HTML_DOCUMENT_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_ELEMENT_NODE:
-- node = node->children;
-- while (node != NULL) {
-- if (node->type == XML_ELEMENT_NODE)
-- ret++;
-- node = node->next;
-- }
-- break;
-- case XML_ATTRIBUTE_NODE:
-- return(-1);
--
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
--#ifndef XML_USE_BUFFER_CONTENT
-- ret = xmlStrlen(node->content);
--#else
-- ret = xmlBufferLength(node->content);
--#endif
-- break;
-- default:
-- return(-1);
-- }
-- return(ret);
--}
--
--/**
-- * xmlXPtrHereFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing here() operation
-- * as described in 5.4.3
-- */
--void
--xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- if (ctxt->context->here == NULL)
-- XP_ERROR(XPTR_SYNTAX_ERROR);
--
-- valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));
--}
--
--/**
-- * xmlXPtrOriginFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing origin() operation
-- * as described in 5.4.3
-- */
--void
--xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- if (ctxt->context->origin == NULL)
-- XP_ERROR(XPTR_SYNTAX_ERROR);
--
-- valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));
--}
--
--/**
-- * xmlXPtrStartPointFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing start-point() operation
-- * as described in 5.4.3
-- * ----------------
-- * location-set start-point(location-set)
-- *
-- * For each location x in the argument location-set, start-point adds a
-- * location of type point to the result location-set. That point represents
-- * the start point of location x and is determined by the following rules:
-- *
-- * - If x is of type point, the start point is x.
-- * - If x is of type range, the start point is the start point of x.
-- * - If x is of type root, element, text, comment, or processing instruction,
-- * - the container node of the start point is x and the index is 0.
-- * - If x is of type attribute or namespace, the function must signal a
-- * syntax error.
-- * ----------------
-- *
-- */
--void
--xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr tmp, obj, point;
-- xmlLocationSetPtr newset = NULL;
-- xmlLocationSetPtr oldset = NULL;
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_LOCATIONSET) &&
-- (ctxt->value->type != XPATH_NODESET)))
-- XP_ERROR(XPATH_INVALID_TYPE)
--
-- obj = valuePop(ctxt);
-- if (obj->type == XPATH_NODESET) {
-- /*
-- * First convert to a location set
-- */
-- tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
-- xmlXPathFreeObject(obj);
-- obj = tmp;
-- }
--
-- newset = xmlXPtrLocationSetCreate(NULL);
-- if (newset == NULL) {
-- xmlXPathFreeObject(obj);
-- XP_ERROR(XPATH_MEMORY_ERROR);
-- }
-- oldset = (xmlLocationSetPtr) obj->user;
-- if (oldset != NULL) {
-- int i;
--
-- for (i = 0; i < oldset->locNr; i++) {
-- tmp = oldset->locTab[i];
-- if (tmp == NULL)
-- continue;
-- point = NULL;
-- switch (tmp->type) {
-- case XPATH_POINT:
-- point = xmlXPtrNewPoint(tmp->user, tmp->index);
-- break;
-- case XPATH_RANGE: {
-- xmlNodePtr node = tmp->user;
-- if (node != NULL) {
-- if (node->type == XML_ATTRIBUTE_NODE) {
-- /* TODO: Namespace Nodes ??? */
-- xmlXPathFreeObject(obj);
-- xmlXPtrFreeLocationSet(newset);
-- XP_ERROR(XPTR_SYNTAX_ERROR);
-- }
-- point = xmlXPtrNewPoint(node, tmp->index);
-- }
-- break;
-- }
-- default:
-- /*** Should we raise an error ?
-- xmlXPathFreeObject(obj);
-- xmlXPathFreeObject(newset);
-- XP_ERROR(XPATH_INVALID_TYPE)
-- ***/
-- break;
-- }
-- if (point != NULL)
-- xmlXPtrLocationSetAdd(newset, point);
-- }
-- }
-- xmlXPathFreeObject(obj);
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
--}
--
--/**
-- * xmlXPtrEndPointFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing end-point() operation
-- * as described in 5.4.3
-- * ----------------------------
-- * location-set end-point(location-set)
-- *
-- * For each location x in the argument location-set, end-point adds a
-- * location of type point to the result location-set. That point representsi
-- * the end point of location x and is determined by the following rules:
-- *
-- * - If x is of type point, the resulting point is x.
-- * - If x is of type range, the resulting point is the end point of x.
-- * - If x is of type root or element, the container node of the resulting
-- * point is x and the index is the number of location children of x.
-- * - If x is of type text, comment, or processing instruction, the container
-- * node of the resulting point is x and the index is the length of thei
-- * string-value of x.
-- * - If x is of type attribute or namespace, the function must signal a
-- * syntax error.
-- * ----------------------------
-- */
--void
--xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr tmp, obj, point;
-- xmlLocationSetPtr newset = NULL;
-- xmlLocationSetPtr oldset = NULL;
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_LOCATIONSET) &&
-- (ctxt->value->type != XPATH_NODESET)))
-- XP_ERROR(XPATH_INVALID_TYPE)
--
-- obj = valuePop(ctxt);
-- if (obj->type == XPATH_NODESET) {
-- /*
-- * First convert to a location set
-- */
-- tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
-- xmlXPathFreeObject(obj);
-- obj = tmp;
-- }
--
-- newset = xmlXPtrLocationSetCreate(NULL);
-- oldset = (xmlLocationSetPtr) obj->user;
-- if (oldset != NULL) {
-- int i;
--
-- for (i = 0; i < oldset->locNr; i++) {
-- tmp = oldset->locTab[i];
-- if (tmp == NULL)
-- continue;
-- point = NULL;
-- switch (tmp->type) {
-- case XPATH_POINT:
-- point = xmlXPtrNewPoint(tmp->user, tmp->index);
-- break;
-- case XPATH_RANGE: {
-- xmlNodePtr node = tmp->user2;
-- if (node != NULL) {
-- if (node->type == XML_ATTRIBUTE_NODE) {
-- /* TODO: Namespace Nodes ??? */
-- xmlXPathFreeObject(obj);
-- xmlXPtrFreeLocationSet(newset);
-- XP_ERROR(XPTR_SYNTAX_ERROR);
-- }
-- point = xmlXPtrNewPoint(node, tmp->index2);
-- } else if (tmp->user == NULL) {
-- point = xmlXPtrNewPoint(node,
-- xmlXPtrNbLocChildren(node));
-- }
-- break;
-- }
-- default:
-- /*** Should we raise an error ?
-- xmlXPathFreeObject(obj);
-- xmlXPathFreeObject(newset);
-- XP_ERROR(XPATH_INVALID_TYPE)
-- ***/
-- break;
-- }
-- if (point != NULL)
-- xmlXPtrLocationSetAdd(newset, point);
-- }
-- }
-- xmlXPathFreeObject(obj);
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
--}
--
--
--/**
-- * xmlXPtrCoveringRange:
-- * @ctxt: the XPointer Parser context
-- * @loc: the location for which the covering range must be computed
-- *
-- * A covering range is a range that wholly encompasses a location
-- * Section 5.3.3. Covering Ranges for All Location Types
-- * http://www.w3.org/TR/xptr#N2267
-- *
-- * Returns a new location or NULL in case of error
-- */
--xmlXPathObjectPtr
--xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
-- if (loc == NULL)
-- return(NULL);
-- if ((ctxt == NULL) || (ctxt->context == NULL) ||
-- (ctxt->context->doc == NULL))
-- return(NULL);
-- switch (loc->type) {
-- case XPATH_POINT:
-- return(xmlXPtrNewRange(loc->user, loc->index,
-- loc->user, loc->index));
-- case XPATH_RANGE:
-- if (loc->user2 != NULL) {
-- return(xmlXPtrNewRange(loc->user, loc->index,
-- loc->user2, loc->index2));
-- } else {
-- xmlNodePtr node = (xmlNodePtr) loc->user;
-- if (node == (xmlNodePtr) ctxt->context->doc) {
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlXPtrGetArity(node)));
-- } else {
-- switch (node->type) {
-- case XML_ATTRIBUTE_NODE:
-- /* !!! our model is slightly different than XPath */
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlXPtrGetArity(node)));
-- case XML_ELEMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE: {
-- int index = xmlXPtrGetIndex(node);
--
-- node = node->parent;
-- return(xmlXPtrNewRange(node, index - 1,
-- node, index + 1));
-- }
-- default:
-- return(NULL);
-- }
-- }
-- }
-- default:
-- TODO /* missed one case ??? */
-- }
-- return(NULL);
--}
--
--/**
-- * xmlXPtrRangeFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing the range() function 5.4.3
-- * location-set range(location-set )
-- *
-- * The range function returns ranges covering the locations in
-- * the argument location-set. For each location x in the argument
-- * location-set, a range location representing the covering range of
-- * x is added to the result location-set.
-- */
--void
--xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- int i;
-- xmlXPathObjectPtr set;
-- xmlLocationSetPtr oldset;
-- xmlLocationSetPtr newset;
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_LOCATIONSET) &&
-- (ctxt->value->type != XPATH_NODESET)))
-- XP_ERROR(XPATH_INVALID_TYPE)
--
-- set = valuePop(ctxt);
-- if (set->type == XPATH_NODESET) {
-- xmlXPathObjectPtr tmp;
--
-- /*
-- * First convert to a location set
-- */
-- tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
-- xmlXPathFreeObject(set);
-- set = tmp;
-- }
-- oldset = (xmlLocationSetPtr) set->user;
--
-- /*
-- * The loop is to compute the covering range for each item and add it
-- */
-- newset = xmlXPtrLocationSetCreate(NULL);
-- for (i = 0;i < oldset->locNr;i++) {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
-- }
--
-- /*
-- * Save the new value and cleanup
-- */
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-- xmlXPathFreeObject(set);
--}
--
--/**
-- * xmlXPtrInsideRange:
-- * @ctxt: the XPointer Parser context
-- * @loc: the location for which the inside range must be computed
-- *
-- * A inside range is a range described in the range-inside() description
-- *
-- * Returns a new location or NULL in case of error
-- */
--xmlXPathObjectPtr
--xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
-- if (loc == NULL)
-- return(NULL);
-- if ((ctxt == NULL) || (ctxt->context == NULL) ||
-- (ctxt->context->doc == NULL))
-- return(NULL);
-- switch (loc->type) {
-- case XPATH_POINT: {
-- xmlNodePtr node = (xmlNodePtr) loc->user;
-- switch (node->type) {
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE: {
-- if (node->content == NULL) {
-- return(xmlXPtrNewRange(node, 0, node, 0));
-- } else {
--#ifndef XML_USE_BUFFER_CONTENT
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlStrlen(node->content)));
--#else
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlBufferLength(node->content)));
--#endif
-- }
-- }
-- case XML_ATTRIBUTE_NODE:
-- case XML_ELEMENT_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE: {
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlXPtrGetArity(node)));
-- }
-- default:
-- return(NULL);
-- }
-- return(NULL);
-- }
-- case XPATH_RANGE: {
-- xmlNodePtr node = (xmlNodePtr) loc->user;
-- if (loc->user2 != NULL) {
-- return(xmlXPtrNewRange(node, loc->index,
-- loc->user2, loc->index2));
-- } else {
-- switch (node->type) {
-- case XML_PI_NODE:
-- case XML_COMMENT_NODE:
-- case XML_TEXT_NODE:
-- case XML_CDATA_SECTION_NODE: {
-- if (node->content == NULL) {
-- return(xmlXPtrNewRange(node, 0, node, 0));
-- } else {
--#ifndef XML_USE_BUFFER_CONTENT
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlStrlen(node->content)));
--#else
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlBufferLength(node->content)));
--#endif
-- }
-- }
-- case XML_ATTRIBUTE_NODE:
-- case XML_ELEMENT_NODE:
-- case XML_ENTITY_REF_NODE:
-- case XML_DOCUMENT_NODE:
-- case XML_NOTATION_NODE:
-- case XML_HTML_DOCUMENT_NODE: {
-- return(xmlXPtrNewRange(node, 0, node,
-- xmlXPtrGetArity(node)));
-- }
-- default:
-- return(NULL);
-- }
-- return(NULL);
-- }
-- }
-- default:
-- TODO /* missed one case ??? */
-- }
-- return(NULL);
--}
--
--/**
-- * xmlXPtrRangeInsideFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing the range-inside() function 5.4.3
-- * location-set range-inside(location-set )
-- *
-- * The range-inside function returns ranges covering the contents of
-- * the locations in the argument location-set. For each location x in
-- * the argument location-set, a range location is added to the result
-- * location-set. If x is a range location, then x is added to the
-- * result location-set. If x is not a range location, then x is used
-- * as the container location of the start and end points of the range
-- * location to be added; the index of the start point of the range is
-- * zero; if the end point is a character point then its index is the
-- * length of the string-value of x, and otherwise is the number of
-- * location children of x.
-- *
-- */
--void
--xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- int i;
-- xmlXPathObjectPtr set;
-- xmlLocationSetPtr oldset;
-- xmlLocationSetPtr newset;
--
-- CHECK_ARITY(1);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_LOCATIONSET) &&
-- (ctxt->value->type != XPATH_NODESET)))
-- XP_ERROR(XPATH_INVALID_TYPE)
--
-- set = valuePop(ctxt);
-- if (set->type == XPATH_NODESET) {
-- xmlXPathObjectPtr tmp;
--
-- /*
-- * First convert to a location set
-- */
-- tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
-- xmlXPathFreeObject(set);
-- set = tmp;
-- }
-- oldset = (xmlLocationSetPtr) set->user;
--
-- /*
-- * The loop is to compute the covering range for each item and add it
-- */
-- newset = xmlXPtrLocationSetCreate(NULL);
-- for (i = 0;i < oldset->locNr;i++) {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
-- }
--
-- /*
-- * Save the new value and cleanup
-- */
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-- xmlXPathFreeObject(set);
--}
--
--/**
-- * xmlXPtrRangeToFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Implement the range-to() XPointer function
-- */
--void
--xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- xmlXPathObjectPtr range;
-- const xmlChar *cur;
-- xmlXPathObjectPtr res, obj;
-- xmlXPathObjectPtr tmp;
-- xmlLocationSetPtr newset = NULL;
-- xmlNodeSetPtr oldset;
-- int i;
--
-- CHECK_ARITY(1);
-- /*
-- * Save the expression pointer since we will have to evaluate
-- * it multiple times. Initialize the new set.
-- */
-- CHECK_TYPE(XPATH_NODESET);
-- obj = valuePop(ctxt);
-- oldset = obj->nodesetval;
-- ctxt->context->node = NULL;
--
-- cur = ctxt->cur;
-- newset = xmlXPtrLocationSetCreate(NULL);
--
-- for (i = 0; i < oldset->nodeNr; i++) {
-- ctxt->cur = cur;
--
-- /*
-- * Run the evaluation with a node list made of a single item
-- * in the nodeset.
-- */
-- ctxt->context->node = oldset->nodeTab[i];
-- tmp = xmlXPathNewNodeSet(ctxt->context->node);
-- valuePush(ctxt, tmp);
--
-- xmlXPathEvalExpr(ctxt);
-- CHECK_ERROR;
--
-- /*
-- * The result of the evaluation need to be tested to
-- * decided whether the filter succeeded or not
-- */
-- res = valuePop(ctxt);
-- range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
-- if (range != NULL) {
-- xmlXPtrLocationSetAdd(newset, range);
-- }
--
-- /*
-- * Cleanup
-- */
-- if (res != NULL)
-- xmlXPathFreeObject(res);
-- if (ctxt->value == tmp) {
-- res = valuePop(ctxt);
-- xmlXPathFreeObject(res);
-- }
--
-- ctxt->context->node = NULL;
-- }
--
-- /*
-- * The result is used as the new evaluation set.
-- */
-- xmlXPathFreeObject(obj);
-- ctxt->context->node = NULL;
-- ctxt->context->contextSize = -1;
-- ctxt->context->proximityPosition = -1;
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
--}
--
--/**
-- * xmlXPtrAdvanceNode:
-- * @cur: the node
-- *
-- * Advance to the next element or text node in document order
-- * TODO: add a stack for entering/exiting entities
-- *
-- * Returns -1 in case of failure, 0 otherwise
-- */
--xmlNodePtr
--xmlXPtrAdvanceNode(xmlNodePtr cur) {
--next:
-- if (cur == NULL)
-- return(NULL);
-- if (cur->children != NULL) {
-- cur = cur->children ;
-- goto found;
-- }
-- if (cur->next != NULL) {
-- cur = cur->next;
-- goto found;
-- }
-- do {
-- cur = cur->parent;
-- if (cur == NULL) return(NULL);
-- if (cur->next != NULL) {
-- cur = cur->next;
-- goto found;
-- }
-- } while (cur != NULL);
--
--found:
-- if ((cur->type != XML_ELEMENT_NODE) &&
-- (cur->type != XML_TEXT_NODE) &&
-- (cur->type != XML_DOCUMENT_NODE) &&
-- (cur->type != XML_HTML_DOCUMENT_NODE) &&
-- (cur->type != XML_CDATA_SECTION_NODE))
-- goto next;
-- if (cur->type == XML_ENTITY_REF_NODE) {
-- TODO
-- }
-- return(cur);
--}
--
--/**
-- * xmlXPtrAdvanceChar:
-- * @node: the node
-- * @index: the index
-- * @bytes: the number of bytes
-- *
-- * Advance a point of the associated number of bytes (not UTF8 chars)
-- *
-- * Returns -1 in case of failure, 0 otherwise
-- */
--int
--xmlXPtrAdvanceChar(xmlNodePtr *node, int *index, int bytes) {
-- xmlNodePtr cur;
-- int pos;
-- int len;
--
-- if ((node == NULL) || (index == NULL))
-- return(-1);
-- cur = *node;
-- if (cur == NULL)
-- return(-1);
-- pos = *index;
--
-- while (bytes >= 0) {
-- /*
-- * First position to the beginning of the first text node
-- * corresponding to this point
-- */
-- while ((cur != NULL) &&
-- ((cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE))) {
-- if (pos > 0) {
-- cur = xmlXPtrGetNthChild(cur, pos);
-- pos = 0;
-- } else {
-- cur = xmlXPtrAdvanceNode(cur);
-- pos = 0;
-- }
-- }
--
-- if (cur == NULL) {
-- *node = NULL;
-- *index = 0;
-- return(-1);
-- }
--
-- /*
-- * if there is no move needed return the current value.
-- */
-- if (pos == 0) pos = 1;
-- if (bytes == 0) {
-- *node = cur;
-- *index = pos;
-- return(0);
-- }
-- /*
-- * We should have a text (or cdata) node ...
-- */
-- len = 0;
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- len = xmlStrlen(cur->content);
--#else
-- len = xmlBufferLength(cur->content);
--#endif
-- }
-- if (pos > len) {
-- /* Strange, the index in the text node is greater than it's len */
-- STRANGE
-- pos = len;
-- }
-- if (pos + bytes >= len) {
-- bytes -= (len - pos);
-- cur = xmlXPtrAdvanceNode(cur);
-- cur = 0;
-- } else if (pos + bytes < len) {
-- pos += bytes;
-- *node = cur;
-- *index = pos;
-- return(0);
-- }
-- }
-- return(-1);
--}
--
--/**
-- * xmlXPtrMatchString:
-- * @string: the string to search
-- * @start: the start textnode
-- * @startindex: the start index
-- * @end: the end textnode IN/OUT
-- * @endindex: the end index IN/OUT
-- *
-- * Check whether the document contains @string at the position
-- * (@start, @startindex) and limited by the (@end, @endindex) point
-- *
-- * Returns -1 in case of failure, 0 if not found, 1 if found in which case
-- * (@start, @startindex) will indicate the position of the beginning
-- * of the range and (@end, @endindex) will endicate the end
-- * of the range
-- */
--int
--xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
-- xmlNodePtr *end, int *endindex) {
-- xmlNodePtr cur;
-- int pos; /* 0 based */
-- int len; /* in bytes */
-- int stringlen; /* in bytes */
-- int match;
--
-- if (string == NULL)
-- return(-1);
-- if (start == NULL)
-- return(-1);
-- if ((end == NULL) || (endindex == NULL))
-- return(-1);
-- cur = start;
-- if (cur == NULL)
-- return(-1);
-- pos = startindex - 1;
-- stringlen = xmlStrlen(string);
--
-- while (stringlen > 0) {
-- if ((cur == *end) && (pos + stringlen > *endindex))
-- return(0);
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- len = xmlStrlen(cur->content);
--#else
-- len = xmlBufferLength(cur->content);
--#endif
-- if (len >= pos + stringlen) {
--#ifndef XML_USE_BUFFER_CONTENT
-- match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
--#else
-- len = (!xmlStrncmp(&xmlBufferContent(cur->content)[pos],
-- string, stringlen));
--#endif
-- if (match) {
--#ifdef DEBUG_RANGES
-- xmlGenericError(xmlGenericErrorContext,
-- "found range %d bytes at index %d of ->",
-- stringlen, pos + 1);
-- xmlDebugDumpString(stdout, cur->content);
-- xmlGenericError(xmlGenericErrorContext, "\n");
--#endif
-- *end = cur;
-- *endindex = pos + stringlen;
-- return(1);
-- } else {
-- return(0);
-- }
-- } else {
-- int sub = len - pos;
--#ifndef XML_USE_BUFFER_CONTENT
-- match = (!xmlStrncmp(&cur->content[pos], string, sub));
--#else
-- len = (!xmlStrncmp(&xmlBufferContent(cur->content)[pos],
-- string, sub));
--#endif
-- if (match) {
--#ifdef DEBUG_RANGES
-- xmlGenericError(xmlGenericErrorContext,
-- "found subrange %d bytes at index %d of ->",
-- sub, pos + 1);
-- xmlDebugDumpString(stdout, cur->content);
-- xmlGenericError(xmlGenericErrorContext, "\n");
--#endif
-- string = &string[sub];
-- stringlen -= sub;
-- } else {
-- return(0);
-- }
-- }
-- }
-- cur = xmlXPtrAdvanceNode(cur);
-- if (cur == NULL)
-- return(0);
-- pos = 0;
-- }
-- return(1);
--}
--
--/**
-- * xmlXPtrSearchString:
-- * @string: the string to search
-- * @start: the start textnode IN/OUT
-- * @startindex: the start index IN/OUT
-- * @end: the end textnode
-- * @endindex: the end index
-- *
-- * Search the next occurence of @string within the document content
-- * until the (@end, @endindex) point is reached
-- *
-- * Returns -1 in case of failure, 0 if not found, 1 if found in which case
-- * (@start, @startindex) will indicate the position of the beginning
-- * of the range and (@end, @endindex) will endicate the end
-- * of the range
-- */
--int
--xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
-- xmlNodePtr *end, int *endindex) {
-- xmlNodePtr cur;
-- const xmlChar *str;
-- int pos; /* 0 based */
-- int len; /* in bytes */
-- int stringlen; /* in bytes */
-- xmlChar first;
--
-- if (string == NULL)
-- return(-1);
-- if ((start == NULL) || (startindex == NULL))
-- return(-1);
-- if ((end == NULL) || (endindex == NULL))
-- return(-1);
-- cur = *start;
-- if (cur == NULL)
-- return(-1);
-- pos = *startindex - 1;
-- first = string[0];
-- stringlen = xmlStrlen(string);
--
-- while (cur != NULL) {
-- if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- len = xmlStrlen(cur->content);
--#else
-- len = xmlBufferLength(cur->content);
--#endif
-- while (pos <= len) {
-- if (first != 0) {
--#ifndef XML_USE_BUFFER_CONTENT
-- str = xmlStrchr(&cur->content[pos], first);
--#else
-- str = xmlStrchr(&xmlBufferContent(cur->content)[pos],
-- first);
--#endif
-- if (str != NULL) {
-- pos = (str - (xmlChar *)(cur->content));
--#ifdef DEBUG_RANGES
-- xmlGenericError(xmlGenericErrorContext,
-- "found '%c' at index %d of ->",
-- first, pos + 1);
-- xmlDebugDumpString(stdout, cur->content);
-- xmlGenericError(xmlGenericErrorContext, "\n");
--#endif
-- if (xmlXPtrMatchString(string, cur, pos + 1,
-- end, endindex)) {
-- *start = cur;
-- *startindex = pos + 1;
-- return(1);
-- }
-- pos++;
-- } else {
-- pos = len + 1;
-- }
-- } else {
-- /*
-- * An empty string is considered to match before each
-- * character of the string-value and after the final
-- * character.
-- */
--#ifdef DEBUG_RANGES
-- xmlGenericError(xmlGenericErrorContext,
-- "found '' at index %d of ->",
-- pos + 1);
-- xmlDebugDumpString(stdout, cur->content);
-- xmlGenericError(xmlGenericErrorContext, "\n");
--#endif
-- *start = cur;
-- *startindex = pos + 1;
-- *end = cur;
-- *endindex = pos + 1;
-- return(1);
-- }
-- }
-- }
-- if ((cur == *end) && (pos >= *endindex))
-- return(0);
-- cur = xmlXPtrAdvanceNode(cur);
-- if (cur == NULL)
-- return(0);
-- pos = 1;
-- }
-- return(0);
--}
--
--/**
-- * xmlXPtrGetLastChar:
-- * @node: the node
-- * @index: the index
-- *
-- * Computes the point coordinates of the last char of this point
-- *
-- * Returns -1 in case of failure, 0 otherwise
-- */
--int
--xmlXPtrGetLastChar(xmlNodePtr *node, int *index) {
-- xmlNodePtr cur;
-- int pos, len = 0;
--
-- if ((node == NULL) || (index == NULL))
-- return(-1);
-- cur = *node;
-- pos = *index;
--
-- if (cur == NULL)
-- return(-1);
--
-- if ((cur->type == XML_ELEMENT_NODE) ||
-- (cur->type == XML_DOCUMENT_NODE) ||
-- (cur->type == XML_HTML_DOCUMENT_NODE)) {
-- if (pos > 0) {
-- cur = xmlXPtrGetNthChild(cur, pos);
-- pos = 0;
-- }
-- }
-- while (cur != NULL) {
-- if (cur->last != NULL)
-- cur = cur->last;
-- else if (cur->content != NULL) {
--#ifndef XML_USE_BUFFER_CONTENT
-- len = xmlStrlen(cur->content);
--#else
-- len = xmlBufferLength(cur->content);
--#endif
-- break;
-- } else {
-- return(-1);
-- }
-- }
-- if (cur == NULL)
-- return(-1);
-- *node = cur;
-- *index = len;
-- return(0);
--}
--
--/**
-- * xmlXPtrGetStartPoint:
-- * @obj: an range
-- * @node: the resulting node
-- * @index: the resulting index
-- *
-- * read the object and return the start point coordinates.
-- *
-- * Returns -1 in case of failure, 0 otherwise
-- */
--int
--xmlXPtrGetStartPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *index) {
-- if ((obj == NULL) || (node == NULL) || (index == NULL))
-- return(-1);
--
-- switch (obj->type) {
-- case XPATH_POINT:
-- *node = obj->user;
-- if (obj->index <= 0)
-- *index = 0;
-- else
-- *index = obj->index;
-- return(0);
-- case XPATH_RANGE:
-- *node = obj->user;
-- if (obj->index <= 0)
-- *index = 0;
-- else
-- *index = obj->index;
-- return(0);
-- default:
-- return(-1);
-- }
-- return(-1);
--}
--
--/**
-- * xmlXPtrGetEndPoint:
-- * @obj: an range
-- * @node: the resulting node
-- * @index: the resulting index
-- *
-- * read the object and return the end point coordinates.
-- *
-- * Returns -1 in case of failure, 0 otherwise
-- */
--int
--xmlXPtrGetEndPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *index) {
-- if ((obj == NULL) || (node == NULL) || (index == NULL))
-- return(-1);
--
-- switch (obj->type) {
-- case XPATH_POINT:
-- *node = obj->user;
-- if (obj->index <= 0)
-- *index = 0;
-- else
-- *index = obj->index;
-- return(0);
-- case XPATH_RANGE:
-- *node = obj->user;
-- if (obj->index <= 0)
-- *index = 0;
-- else
-- *index = obj->index;
-- return(0);
-- default:
-- return(-1);
-- }
-- return(-1);
--}
--
--/**
-- * xmlXPtrStringRangeFunction:
-- * @ctxt: the XPointer Parser context
-- *
-- * Function implementing the string-range() function
-- * range as described in 5.4.2
-- *
-- * ------------------------------
-- * [Definition: For each location in the location-set argument,
-- * string-range returns a set of string ranges, a set of substrings in a
-- * string. Specifically, the string-value of the location is searched for
-- * substrings that match the string argument, and the resulting location-set
-- * will contain a range location for each non-overlapping match.]
-- * An empty string is considered to match before each character of the
-- * string-value and after the final character. Whitespace in a string
-- * is matched literally, with no normalization except that provided by
-- * XML for line ends. The third argument gives the position of the first
-- * character to be in the resulting range, relative to the start of the
-- * match. The default value is 1, which makes the range start immediately
-- * before the first character of the matched string. The fourth argument
-- * gives the number of characters in the range; the default is that the
-- * range extends to the end of the matched string.
-- *
-- * Element boundaries, as well as entire embedded nodes such as processing
-- * instructions and comments, are ignored as defined in [XPath].
-- *
-- * If the string in the second argument is not found in the string-value
-- * of the location, or if a value in the third or fourth argument indicates
-- * a string that is beyond the beginning or end of the document, the
-- * expression fails.
-- *
-- * The points of the range-locations in the returned location-set will
-- * all be character points.
-- * ------------------------------
-- */
--void
--xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-- int i, startindex, endindex, fendindex;
-- xmlNodePtr start, end, fend;
-- xmlXPathObjectPtr set;
-- xmlLocationSetPtr oldset;
-- xmlLocationSetPtr newset;
-- xmlXPathObjectPtr string;
-- xmlXPathObjectPtr position = NULL;
-- xmlXPathObjectPtr number = NULL;
-- int found, pos, num;
--
-- /*
-- * Grab the arguments
-- */
-- if ((nargs < 2) || (nargs > 4))
-- XP_ERROR(XPATH_INVALID_ARITY);
--
-- if (nargs >= 4) {
-- CHECK_TYPE(XPATH_NUMBER);
-- number = valuePop(ctxt);
-- if (number != NULL)
-- num = number->floatval;
-- }
-- if (nargs >= 3) {
-- CHECK_TYPE(XPATH_NUMBER);
-- position = valuePop(ctxt);
-- if (position != NULL)
-- pos = position->floatval;
-- }
-- CHECK_TYPE(XPATH_STRING);
-- string = valuePop(ctxt);
-- if ((ctxt->value == NULL) ||
-- ((ctxt->value->type != XPATH_LOCATIONSET) &&
-- (ctxt->value->type != XPATH_NODESET)))
-- XP_ERROR(XPATH_INVALID_TYPE)
--
-- set = valuePop(ctxt);
-- if (set->type == XPATH_NODESET) {
-- xmlXPathObjectPtr tmp;
--
-- /*
-- * First convert to a location set
-- */
-- tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
-- xmlXPathFreeObject(set);
-- set = tmp;
-- }
-- oldset = (xmlLocationSetPtr) set->user;
--
-- /*
-- * The loop is to search for each element in the location set
-- * the list of location set corresponding to that search
-- */
-- newset = xmlXPtrLocationSetCreate(NULL);
-- for (i = 0;i < oldset->locNr;i++) {
--#ifdef DEBUG_RANGES
-- xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
--#endif
--
-- xmlXPtrGetStartPoint(oldset->locTab[i], &start, &startindex);
-- xmlXPtrGetEndPoint(oldset->locTab[i], &end, &endindex);
-- xmlXPtrAdvanceChar(&start, &startindex, 0);
-- xmlXPtrGetLastChar(&end, &endindex);
--
--#ifdef DEBUG_RANGES
-- xmlGenericError(xmlGenericErrorContext,
-- "from index %d of ->", startindex);
-- xmlDebugDumpString(stdout, start->content);
-- xmlGenericError(xmlGenericErrorContext, "\n");
-- xmlGenericError(xmlGenericErrorContext,
-- "to index %d of ->", endindex);
-- xmlDebugDumpString(stdout, end->content);
-- xmlGenericError(xmlGenericErrorContext, "\n");
--#endif
-- do {
-- fend = end;
-- fendindex = endindex;
-- found = xmlXPtrSearchString(string->stringval, &start, &startindex,
-- &fend, &fendindex);
-- if (found == 1) {
-- if (position == NULL) {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrNewRange(start, startindex, fend, fendindex));
-- } else if (xmlXPtrAdvanceChar(&start, &startindex,
-- pos - 1) == 0) {
-- if ((number != NULL) && (num > 0)) {
-- int rindex;
-- xmlNodePtr rend;
-- rend = start;
-- rindex = startindex - 1;
-- if (xmlXPtrAdvanceChar(&rend, &rindex,
-- num) == 0) {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrNewRange(start, startindex,
-- rend, rindex));
-- }
-- } else if ((number != NULL) && (num <= 0)) {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrNewRange(start, startindex,
-- start, startindex));
-- } else {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPtrNewRange(start, startindex,
-- fend, fendindex));
-- }
-- }
-- start = fend;
-- startindex = fendindex;
-- if (string->stringval[0] == 0)
-- startindex++;
-- }
-- } while (found == 1);
-- }
--
-- /*
-- * Save the new value and cleanup
-- */
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-- xmlXPathFreeObject(set);
-- xmlXPathFreeObject(string);
-- if (position) xmlXPathFreeObject(position);
-- if (number) xmlXPathFreeObject(number);
--}
--
--/**
-- * xmlXPtrEvalRangePredicate:
-- * @ctxt: the XPointer Parser context
-- *
-- * [8] Predicate ::= '[' PredicateExpr ']'
-- * [9] PredicateExpr ::= Expr
-- *
-- * Evaluate a predicate as in xmlXPathEvalPredicate() but for
-- * a Location Set instead of a node set
-- */
--void
--xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
-- const xmlChar *cur;
-- xmlXPathObjectPtr res;
-- xmlXPathObjectPtr obj, tmp;
-- xmlLocationSetPtr newset = NULL;
-- xmlLocationSetPtr oldset;
-- int i;
--
-- SKIP_BLANKS;
-- if (CUR != '[') {
-- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-- }
-- NEXT;
-- SKIP_BLANKS;
--
-- /*
-- * Extract the old set, and then evaluate the result of the
-- * expression for all the element in the set. use it to grow
-- * up a new set.
-- */
-- CHECK_TYPE(XPATH_LOCATIONSET);
-- obj = valuePop(ctxt);
-- oldset = obj->user;
-- ctxt->context->node = NULL;
--
-- if ((oldset == NULL) || (oldset->locNr == 0)) {
-- ctxt->context->contextSize = 0;
-- ctxt->context->proximityPosition = 0;
-- xmlXPathEvalExpr(ctxt);
-- res = valuePop(ctxt);
-- if (res != NULL)
-- xmlXPathFreeObject(res);
-- valuePush(ctxt, obj);
-- CHECK_ERROR;
-- } else {
-- /*
-- * Save the expression pointer since we will have to evaluate
-- * it multiple times. Initialize the new set.
-- */
-- cur = ctxt->cur;
-- newset = xmlXPtrLocationSetCreate(NULL);
--
-- for (i = 0; i < oldset->locNr; i++) {
-- ctxt->cur = cur;
--
-- /*
-- * Run the evaluation with a node list made of a single item
-- * in the nodeset.
-- */
-- ctxt->context->node = oldset->locTab[i]->user;
-- tmp = xmlXPathNewNodeSet(ctxt->context->node);
-- valuePush(ctxt, tmp);
-- ctxt->context->contextSize = oldset->locNr;
-- ctxt->context->proximityPosition = i + 1;
--
-- xmlXPathEvalExpr(ctxt);
-- CHECK_ERROR;
--
-- /*
-- * The result of the evaluation need to be tested to
-- * decided whether the filter succeeded or not
-- */
-- res = valuePop(ctxt);
-- if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-- xmlXPtrLocationSetAdd(newset,
-- xmlXPathObjectCopy(oldset->locTab[i]));
-- }
--
-- /*
-- * Cleanup
-- */
-- if (res != NULL)
-- xmlXPathFreeObject(res);
-- if (ctxt->value == tmp) {
-- res = valuePop(ctxt);
-- xmlXPathFreeObject(res);
-- }
--
-- ctxt->context->node = NULL;
-- }
--
-- /*
-- * The result is used as the new evaluation set.
-- */
-- xmlXPathFreeObject(obj);
-- ctxt->context->node = NULL;
-- ctxt->context->contextSize = -1;
-- ctxt->context->proximityPosition = -1;
-- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-- }
-- if (CUR != ']') {
-- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
-- }
--
-- NEXT;
-- SKIP_BLANKS;
--}
--
--#else
--#endif
--