1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-08-08 17:42:14 +03:00

Finally had a bit of time to resynch both trees:

- HTMLparser.[ch]: added a way to avoid adding automatically
  omitted tags. htmlHandleOmittedElem() allows to change the
  default handling.
- tree.[ch] xmllint.c: added xmlDocDumpFormatMemory() and
  xmlDocDumpFormatMemoryEnc(), uses memory functions for output
  of xmllint too when using --memory flag, added a memory test
  suite at the Makefile level.
- xpathInternals.h xpath.[ch] xpointer.c: fixed problems
  with namespace use when encountering QNames in XPath evalation,
  added xmlns() scheme in XPointer.
- nanoftp.c : incorporated a fix
- parser.c xmlIO.c: fixed problems raised with encoding when using
  the memory I/O
- parserInternals.c: closed bug 25934 reported by
  torsten.landschoff@innominate.de
- TODO: updated
Daniel
This commit is contained in:
Daniel Veillard
2000-12-27 10:46:47 +00:00
parent a1fe9104b6
commit a6d8eb6256
21 changed files with 497 additions and 208 deletions

View File

@@ -1,3 +1,22 @@
Wed Dec 27 12:35:49 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* HTMLparser.[ch]: added a way to avoid adding automatically
omitted tags. htmlHandleOmittedElem() allows to change the
default handling.
* tree.[ch] xmllint.c: added xmlDocDumpFormatMemory() and
xmlDocDumpFormatMemoryEnc(), uses memory functions for output
of xmllint too when using --memory flag, added a memory test
suite at the Makefile level.
* xpathInternals.h xpath.[ch] xpointer.c: fixed problems
with namespace use when encountering QNames in XPath evalation,
added xmlns() scheme in XPointer.
* nanoftp.c : incorporated a fix
* parser.c xmlIO.c: fixed problems raised with encoding when using
the memory I/O
* parserInternals.c: closed bug 25934 reported by
torsten.landschoff@innominate.de
* TODO: updated
Sat Nov 25 11:46:27 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org> Sat Nov 25 11:46:27 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* configure.in doc/html/* doc/xml.html: made a 2.2.9 release * configure.in doc/html/* doc/xml.html: made a 2.2.9 release

View File

@@ -53,6 +53,8 @@
/* #define DEBUG */ /* #define DEBUG */
/* #define DEBUG_PUSH */ /* #define DEBUG_PUSH */
int htmlOmittedDefaultValue = 1;
/************************************************************************ /************************************************************************
* * * *
* Parser stacks related functions and macros * * Parser stacks related functions and macros *
@@ -837,12 +839,14 @@ htmlIsAutoClosed(htmlDocPtr doc, htmlNodePtr elem) {
* @ctxt: an HTML parser context * @ctxt: an HTML parser context
* @newtag: The new tag name * @newtag: The new tag name
* *
* The HTmL DtD allows a tag to exists only implicitely * The HTML DtD allows a tag to exists only implicitely
* called when a new tag has been detected and generates the * called when a new tag has been detected and generates the
* appropriates implicit tags if missing * appropriates implicit tags if missing
*/ */
void void
htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) { htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
if (!htmlOmittedDefaultValue)
return;
if (xmlStrEqual(newtag, BAD_CAST"html")) if (xmlStrEqual(newtag, BAD_CAST"html"))
return; return;
if (ctxt->nameNr <= 0) { if (ctxt->nameNr <= 0) {
@@ -2787,6 +2791,10 @@ htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
if ((ctxt == NULL) || (attvalue == NULL)) if ((ctxt == NULL) || (attvalue == NULL))
return; return;
/* do not change encoding */
if (ctxt->input->encoding != NULL)
return;
encoding = xmlStrcasestr(attvalue, BAD_CAST"charset="); encoding = xmlStrcasestr(attvalue, BAD_CAST"charset=");
if (encoding != NULL) { if (encoding != NULL) {
encoding += 8; encoding += 8;
@@ -4822,6 +4830,7 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding)
htmlParserInputPtr inputStream; htmlParserInputPtr inputStream;
xmlParserInputBufferPtr buf; xmlParserInputBufferPtr buf;
/* htmlCharEncoding enc; */ /* htmlCharEncoding enc; */
xmlChar *content, *content_line = (xmlChar *) "charset=";
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
if (buf == NULL) return(NULL); if (buf == NULL) return(NULL);
@@ -4852,6 +4861,18 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding)
inputStream->free = NULL; inputStream->free = NULL;
inputPush(ctxt, inputStream); 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); return(ctxt);
} }
@@ -4913,4 +4934,21 @@ htmlParseFile(const char *filename, const char *encoding) {
return(htmlSAXParseFile(filename, encoding, NULL, NULL)); 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 */ #endif /* LIBXML_HTML_ENABLED */

View File

@@ -91,6 +91,7 @@ int htmlEncodeEntities(unsigned char* out,
const unsigned char* in, const unsigned char* in,
int *inlen, int quoteChar); int *inlen, int quoteChar);
int htmlIsScriptAttribute(const xmlChar *name); int htmlIsScriptAttribute(const xmlChar *name);
int htmlHandleOmittedElem(int val);
/** /**
* Interfaces for the Push mode * Interfaces for the Push mode

View File

@@ -179,6 +179,24 @@ XMLtests : xmllint
diff result.$$name result2.$$name ; \ diff result.$$name result2.$$name ; \
rm result.$$name result2.$$name ; \ rm result.$$name result2.$$name ; \
fi ; fi ; done) fi ; fi ; done)
@echo "##"
@echo "## XML regression tests on memory"
@echo "##"
@(for i in $(srcdir)/test/* ; do \
name=`basename $$i`; \
if [ ! -d $$i ] ; then \
if [ ! -f $(srcdir)/result/$$name ] ; then \
echo New test file $$name ; \
$(top_builddir)/xmllint --memory $$i > $(srcdir)/result/$$name ; \
else \
echo Testing $$name ; \
$(top_builddir)/xmllint --memory $$i > result.$$name ; \
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
diff $(srcdir)/result/$$name result.$$name ; \
$(top_builddir)/xmllint --memory result.$$name > result2.$$name ; \
diff result.$$name result2.$$name ; \
rm result.$$name result2.$$name ; \
fi ; fi ; done)
XMLenttests : xmllint XMLenttests : xmllint
@echo "##" @echo "##"

3
TODO
View File

@@ -32,6 +32,9 @@ TODO:
- jamesh suggestion: SAX like functions to save a document ie. call a - jamesh suggestion: SAX like functions to save a document ie. call a
function to open a new element with given attributes, write character function to open a new element with given attributes, write character
data, close last element, etc data, close last element, etc
- htmlParseDoc has parameter encoding which is not used.
Function htmlCreateDocParserCtxt ignore it.
TODO: TODO:
===== =====

40
aclocal.m4 vendored
View File

@@ -620,31 +620,35 @@ esac
]) ])
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for # AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl convenience library, adds --enable-ltdl-convenience to # the libltdl convenience library and INCLTDL to the include flags for
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor # the libltdl header and adds --enable-ltdl-convenience to the
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed # configure arguments. Note that LIBLTDL and INCLTDL are not
# to be `${top_builddir}/libltdl'. Make sure you start DIR with # AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
# '${top_builddir}/' (note the single quotes!) if your package is not # provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
# flat, and, if you're not using automake, define top_builddir as # with '${top_builddir}/' and INCLTDL will be prefixed with
# appropriate in the Makefiles. # '${top_srcdir}/' (note the single quotes!). If your package is not
# flat and you're not using automake, define top_builddir and
# top_srcdir appropriately in the Makefiles.
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
case "$enable_ltdl_convenience" in case "$enable_ltdl_convenience" in
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
"") enable_ltdl_convenience=yes "") enable_ltdl_convenience=yes
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
esac esac
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
]) ])
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for # AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl installable library, and adds --enable-ltdl-install to # the libltdl installable library and INCLTDL to the include flags for
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor # the libltdl header and adds --enable-ltdl-install to the configure
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed # arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
# to be `${top_builddir}/libltdl'. Make sure you start DIR with # AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
# '${top_builddir}/' (note the single quotes!) if your package is not # libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
# flat, and, if you're not using automake, define top_builddir as # be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
# appropriate in the Makefiles. # with '${top_srcdir}/' (note the single quotes!). If your package is
# not flat and you're not using automake, define top_builddir and
# top_srcdir appropriately in the Makefiles.
# In the future, this macro may have to be called after AC_PROG_LIBTOOL. # In the future, this macro may have to be called after AC_PROG_LIBTOOL.
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_CHECK_LIB(ltdl, main, AC_CHECK_LIB(ltdl, main,
@@ -657,8 +661,8 @@ AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
]) ])
if test x"$enable_ltdl_install" = x"yes"; then if test x"$enable_ltdl_install" = x"yes"; then
ac_configure_args="$ac_configure_args --enable-ltdl-install" ac_configure_args="$ac_configure_args --enable-ltdl-install"
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
else else
ac_configure_args="$ac_configure_args --enable-ltdl-install=no" ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
LIBLTDL="-lltdl" LIBLTDL="-lltdl"

View File

@@ -91,6 +91,7 @@ int htmlEncodeEntities(unsigned char* out,
const unsigned char* in, const unsigned char* in,
int *inlen, int quoteChar); int *inlen, int quoteChar);
int htmlIsScriptAttribute(const xmlChar *name); int htmlIsScriptAttribute(const xmlChar *name);
int htmlHandleOmittedElem(int val);
/** /**
* Interfaces for the Push mode * Interfaces for the Push mode

View File

@@ -634,6 +634,10 @@ int xmlReconciliateNs (xmlDocPtr doc,
/* /*
* Saving * Saving
*/ */
void xmlDocDumpFormatMemory (xmlDocPtr cur,
xmlChar**mem,
int *size,
int format);
void xmlDocDumpMemory (xmlDocPtr cur, void xmlDocDumpMemory (xmlDocPtr cur,
xmlChar**mem, xmlChar**mem,
int *size); int *size);
@@ -641,6 +645,11 @@ void xmlDocDumpMemoryEnc (xmlDocPtr out_doc,
xmlChar **doc_txt_ptr, xmlChar **doc_txt_ptr,
int * doc_txt_len, int * doc_txt_len,
const char *txt_encoding); 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, int xmlDocDump (FILE *f,
xmlDocPtr cur); xmlDocPtr cur);
void xmlElemDump (FILE *f, void xmlElemDump (FILE *f,

View File

@@ -47,7 +47,8 @@ typedef enum {
XPATH_MEMORY_ERROR, XPATH_MEMORY_ERROR,
XPTR_SYNTAX_ERROR, XPTR_SYNTAX_ERROR,
XPTR_RESOURCE_ERROR, XPTR_RESOURCE_ERROR,
XPTR_SUB_RESOURCE_ERROR XPTR_SUB_RESOURCE_ERROR,
XPATH_UNDEF_PREFIX_ERROR
} xmlXPathError; } xmlXPathError;
/* /*
@@ -171,6 +172,8 @@ struct _xmlXPathAxis {
* - a set of variable bindings * - a set of variable bindings
* - a function library * - a function library
* - the set of namespace declarations in scope for the expression * - 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 { struct _xmlXPathContext {
@@ -193,10 +196,10 @@ struct _xmlXPathContext {
int max_axis; /* max number of axis */ int max_axis; /* max number of axis */
xmlXPathAxisPtr axis; /* Array of defined axis */ xmlXPathAxisPtr axis; /* Array of defined axis */
/* Namespace traversal should be implemented with user */ /* the namespace nodes of the context node */
xmlNsPtr *namespaces; /* The namespaces lookup */ xmlNsPtr *namespaces; /* Array of namespaces */
int nsNr; /* the current Namespace index */ int nsNr; /* number of namespace in scope */
void *user; /* user defined extra info */ void *user; /* function to free */
/* extra variables */ /* extra variables */
int contextSize; /* the context size */ int contextSize; /* the context size */
@@ -206,6 +209,9 @@ struct _xmlXPathContext {
int xptr; /* it this an XPointer context */ int xptr; /* it this an XPointer context */
xmlNodePtr here; /* for here() */ xmlNodePtr here; /* for here() */
xmlNodePtr origin; /* for origin() */ xmlNodePtr origin; /* for origin() */
/* the set of namespace declarations in scope for the expression */
xmlHashTablePtr nsHash; /* The namespaces hash table */
}; };
/* /*

View File

@@ -68,6 +68,13 @@ void xmlXPathDebugDumpObject (FILE *output,
/** /**
* Extending a context * 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, int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
const xmlChar *name, const xmlChar *name,
xmlXPathFunction f); xmlXPathFunction f);
@@ -121,6 +128,7 @@ void xmlXPathIdFunction (xmlXPathParserContextPtr ctxt,
void xmlXPathRoot (xmlXPathParserContextPtr ctxt); void xmlXPathRoot (xmlXPathParserContextPtr ctxt);
void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt); void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt);
xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt); xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt);
xmlChar * xmlXPathParseNCName (xmlXPathParserContextPtr ctxt);
/* /*
* Debug * Debug

View File

@@ -650,6 +650,9 @@ get_more:
* and analyzed. * and analyzed.
*/ */
len = xmlNanoFTPGetMore(ctx); len = xmlNanoFTPGetMore(ctx);
if (len < 0) {
return(-1);
}
if ((ctxt->controlBufUsed == 0) && (len == 0)) { if ((ctxt->controlBufUsed == 0) && (len == 0)) {
return(-1); return(-1);
} }

View File

@@ -8189,17 +8189,23 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
if ((terminate) || (ctxt->input->buf->buffer->use > 80)) if ((terminate) || (ctxt->input->buf->buffer->use > 80))
xmlParseTryOrFinish(ctxt, terminate); xmlParseTryOrFinish(ctxt, terminate);
} else if (ctxt->instate != XML_PARSER_EOF) } else if (ctxt->instate != XML_PARSER_EOF) {
if ((ctxt->input != NULL) && ctxt->input->buf != NULL) { if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
xmlParserInputBufferPtr in = ctxt->input->buf; xmlParserInputBufferPtr in = ctxt->input->buf;
int nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw); if ((in->encoder != NULL) && (in->buffer != NULL) &&
if (nbchars < 0) { (in->raw != NULL)) {
xmlGenericError(xmlGenericErrorContext, int nbchars;
"xmlParseChunk: encoder error\n");
return(XML_ERR_INVALID_ENCODING); nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
} if (nbchars < 0) {
} xmlGenericError(xmlGenericErrorContext,
xmlParseTryOrFinish(ctxt, terminate); "xmlParseChunk: encoder error\n");
return(XML_ERR_INVALID_ENCODING);
}
}
}
}
xmlParseTryOrFinish(ctxt, terminate);
if (terminate) { if (terminate) {
/* /*
* Check for termination * Check for termination
@@ -9234,6 +9240,7 @@ xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
} else { } else {
inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt); inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
if (inputStream == NULL) { if (inputStream == NULL) {
xmlFree(uri);
xmlFreeParserCtxt(ctxt); xmlFreeParserCtxt(ctxt);
return(NULL); return(NULL);
} }

View File

@@ -481,7 +481,7 @@ xmlIsBaseChar(int c) {
(((c) >= 0x06D0) && ((c) <= 0x06D3)) || (((c) >= 0x06D0) && ((c) <= 0x06D3)) ||
((c) == 0x06D5) || ((c) == 0x06D5) ||
(((c) >= 0x06E5) && ((c) <= 0x06E6)) || (((c) >= 0x06E5) && ((c) <= 0x06E6)) ||
(((c) > 0x905) && ( /* accelerator */ (((c) >= 0x905) && ( /* accelerator */
(((c) >= 0x0905) && ((c) <= 0x0939)) || (((c) >= 0x0905) && ((c) <= 0x0939)) ||
((c) == 0x093D) || ((c) == 0x093D) ||
(((c) >= 0x0958) && ((c) <= 0x0961)) || (((c) >= 0x0958) && ((c) <= 0x0961)) ||
@@ -572,7 +572,7 @@ xmlIsBaseChar(int c) {
(((c) >= 0x0EC0) && ((c) <= 0x0EC4)) || (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) ||
(((c) >= 0x0F40) && ((c) <= 0x0F47)) || (((c) >= 0x0F40) && ((c) <= 0x0F47)) ||
(((c) >= 0x0F49) && ((c) <= 0x0F69)) || (((c) >= 0x0F49) && ((c) <= 0x0F69)) ||
(((c) > 0x10A0) && ( /* accelerator */ (((c) >= 0x10A0) && ( /* accelerator */
(((c) >= 0x10A0) && ((c) <= 0x10C5)) || (((c) >= 0x10A0) && ((c) <= 0x10C5)) ||
(((c) >= 0x10D0) && ((c) <= 0x10F6)) || (((c) >= 0x10D0) && ((c) <= 0x10F6)) ||
((c) == 0x1100) || ((c) == 0x1100) ||
@@ -697,7 +697,7 @@ xmlIsCombining(int c) {
(((c) >= 0x06E0) && ((c) <= 0x06E4)) || (((c) >= 0x06E0) && ((c) <= 0x06E4)) ||
(((c) >= 0x06E7) && ((c) <= 0x06E8)) || (((c) >= 0x06E7) && ((c) <= 0x06E8)) ||
(((c) >= 0x06EA) && ((c) <= 0x06ED)) || (((c) >= 0x06EA) && ((c) <= 0x06ED)) ||
(((c) > 0x0901) && ( /* accelerator */ (((c) >= 0x0901) && ( /* accelerator */
(((c) >= 0x0901) && ((c) <= 0x0903)) || (((c) >= 0x0901) && ((c) <= 0x0903)) ||
((c) == 0x093C) || ((c) == 0x093C) ||
(((c) >= 0x093E) && ((c) <= 0x094C)) || (((c) >= 0x093E) && ((c) <= 0x094C)) ||
@@ -713,7 +713,7 @@ xmlIsCombining(int c) {
(((c) >= 0x09CB) && ((c) <= 0x09CD)) || (((c) >= 0x09CB) && ((c) <= 0x09CD)) ||
((c) == 0x09D7) || ((c) == 0x09D7) ||
(((c) >= 0x09E2) && ((c) <= 0x09E3)) || (((c) >= 0x09E2) && ((c) <= 0x09E3)) ||
(((c) > 0x0A02) && ( /* accelerator */ (((c) >= 0x0A02) && ( /* accelerator */
((c) == 0x0A02) || ((c) == 0x0A02) ||
((c) == 0x0A3C) || ((c) == 0x0A3C) ||
((c) == 0x0A3E) || ((c) == 0x0A3E) ||
@@ -753,7 +753,7 @@ xmlIsCombining(int c) {
(((c) >= 0x0D46) && ((c) <= 0x0D48)) || (((c) >= 0x0D46) && ((c) <= 0x0D48)) ||
(((c) >= 0x0D4A) && ((c) <= 0x0D4D)) || (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) ||
((c) == 0x0D57) || ((c) == 0x0D57) ||
(((c) > 0x0E31) && ( /* accelerator */ (((c) >= 0x0E31) && ( /* accelerator */
((c) == 0x0E31) || ((c) == 0x0E31) ||
(((c) >= 0x0E34) && ((c) <= 0x0E3A)) || (((c) >= 0x0E34) && ((c) <= 0x0E3A)) ||
(((c) >= 0x0E47) && ((c) <= 0x0E4E)) || (((c) >= 0x0E47) && ((c) <= 0x0E4E)) ||

261
tree.c
View File

@@ -5098,44 +5098,6 @@ xmlElemDump(FILE *f, xmlDocPtr doc, xmlNodePtr cur) {
xmlBufferFree(buf); xmlBufferFree(buf);
} }
/**
* xmlDocContentDump:
* @buf: the XML buffer output
* @cur: the document
*
* Dump an XML document.
*/
static void
xmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur) {
xmlBufferWriteChar(buf, "<?xml version=");
if (cur->version != NULL)
xmlBufferWriteQuotedString(buf, cur->version);
else
xmlBufferWriteChar(buf, "\"1.0\"");
if (cur->encoding != NULL) {
xmlBufferWriteChar(buf, " encoding=");
xmlBufferWriteQuotedString(buf, cur->encoding);
}
switch (cur->standalone) {
case 0:
xmlBufferWriteChar(buf, " standalone=\"no\"");
break;
case 1:
xmlBufferWriteChar(buf, " standalone=\"yes\"");
break;
}
xmlBufferWriteChar(buf, "?>\n");
if (cur->children != NULL) {
xmlNodePtr child = cur->children;
while (child != NULL) {
xmlNodeDump(buf, cur, child, 0, 0);
xmlBufferWriteChar(buf, "\n");
child = child->next;
}
}
}
/************************************************************************ /************************************************************************
* * * *
* Dumping XML tree content to an I/O output buffer * * Dumping XML tree content to an I/O output buffer *
@@ -5522,12 +5484,13 @@ xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
* @buf: the XML buffer output * @buf: the XML buffer output
* @cur: the document * @cur: the document
* @encoding: an optional encoding string * @encoding: an optional encoding string
* @format: should formatting spaces been added
* *
* Dump an XML document. * Dump an XML document.
*/ */
static void static void
xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur, xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
const char *encoding) { const char *encoding, int format) {
xmlOutputBufferWriteString(buf, "<?xml version="); xmlOutputBufferWriteString(buf, "<?xml version=");
if (cur->version != NULL) if (cur->version != NULL)
xmlBufferWriteQuotedString(buf->buffer, cur->version); xmlBufferWriteQuotedString(buf->buffer, cur->version);
@@ -5556,7 +5519,7 @@ xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
xmlNodePtr child = cur->children; xmlNodePtr child = cur->children;
while (child != NULL) { while (child != NULL) {
xmlNodeDumpOutput(buf, cur, child, 0, 1, encoding); xmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
xmlOutputBufferWriteString(buf, "\n"); xmlOutputBufferWriteString(buf, "\n");
child = child->next; child = child->next;
} }
@@ -5569,6 +5532,105 @@ xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
* * * *
************************************************************************/ ************************************************************************/
/**
* 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: * xmlDocDumpMemory:
* @cur: the document * @cur: the document
@@ -5580,27 +5642,23 @@ xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
*/ */
void void
xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) { xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
xmlBufferPtr buf; xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
}
if (cur == NULL) { /**
#ifdef DEBUG_TREE * xmlDocDumpFormatMemory:
xmlGenericError(xmlGenericErrorContext, * @cur: the document
"xmlDocDumpMemory : document == NULL\n"); * @mem: OUT: the memory pointer
#endif * @size: OUT: the memory lenght
*mem = NULL; * @format: should formatting spaces been added
*size = 0; *
return; *
} * Dump an XML document in memory and return the xmlChar * and it's size.
buf = xmlBufferCreate(); * It's up to the caller to free the memory.
if (buf == NULL) { */
*mem = NULL; void
*size = 0; xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
return; xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
}
xmlDocContentDump(buf, cur);
*mem = xmlStrndup(buf->content, buf->use);
*size = buf->use;
xmlBufferFree(buf);
} }
/** /**
@@ -5618,79 +5676,8 @@ xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
void void
xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr, xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
int * doc_txt_len, const char * txt_encoding) { int * doc_txt_len, const char * txt_encoding) {
int dummy = 0; xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
txt_encoding, 1);
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,
"xmlDocDumpMemoryEnc: Null return buffer pointer.");
return;
}
*doc_txt_ptr = NULL;
*doc_txt_len = 0;
if (out_doc == NULL) {
/* No document, no output */
xmlGenericError(xmlGenericErrorContext,
"xmlDocDumpMemoryEnc: Null DOM tree document pointer.\n");
return;
}
/*
* Validate the encoding value, if provided.
* This logic is copied from xmlSaveFileEnc.
*/
if (txt_encoding != NULL) {
doc_charset = xmlParseCharEncoding(txt_encoding);
if (out_doc->charset != XML_CHAR_ENCODING_UTF8) {
xmlGenericError(xmlGenericErrorContext,
"xmlDocDumpMemoryEnc: 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",
"xmlDocDumpMemoryEnc",
"Failed to identify encoding handler for",
"character set",
txt_encoding);
return;
}
}
}
if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
xmlGenericError(xmlGenericErrorContext,
"xmlDocDumpMemoryEnc: Failed to allocate output buffer.\n");
return;
}
xmlDocContentDumpOutput(out_buff, out_doc, txt_encoding);
*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,
"xmlDocDumpMemoryEnc: %s\n",
"Failed to allocate memory for document text representation.");
}
return;
} }
/** /**
@@ -5792,7 +5779,7 @@ xmlDocDump(FILE *f, xmlDocPtr cur) {
} }
buf = xmlOutputBufferCreateFile(f, handler); buf = xmlOutputBufferCreateFile(f, handler);
if (buf == NULL) return(-1); if (buf == NULL) return(-1);
xmlDocContentDumpOutput(buf, cur, NULL); xmlDocContentDumpOutput(buf, cur, NULL, 1);
ret = xmlOutputBufferClose(buf); ret = xmlOutputBufferClose(buf);
return(ret); return(ret);
@@ -5813,7 +5800,7 @@ xmlSaveFileTo(xmlOutputBuffer *buf, xmlDocPtr cur, const char *encoding) {
int ret; int ret;
if (buf == NULL) return(0); if (buf == NULL) return(0);
xmlDocContentDumpOutput(buf, cur, encoding); xmlDocContentDumpOutput(buf, cur, encoding, 1);
ret = xmlOutputBufferClose(buf); ret = xmlOutputBufferClose(buf);
return(ret); return(ret);
} }
@@ -5857,7 +5844,7 @@ xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
buf = xmlOutputBufferCreateFilename(filename, handler, 0); buf = xmlOutputBufferCreateFilename(filename, handler, 0);
if (buf == NULL) return(0); if (buf == NULL) return(0);
xmlDocContentDumpOutput(buf, cur, encoding); xmlDocContentDumpOutput(buf, cur, encoding, 1);
ret = xmlOutputBufferClose(buf); ret = xmlOutputBufferClose(buf);
return(ret); return(ret);
@@ -5912,7 +5899,7 @@ xmlSaveFile(const char *filename, xmlDocPtr cur) {
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression); buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
if (buf == NULL) return(0); if (buf == NULL) return(0);
xmlDocContentDumpOutput(buf, cur, NULL); xmlDocContentDumpOutput(buf, cur, NULL, 1);
ret = xmlOutputBufferClose(buf); ret = xmlOutputBufferClose(buf);
return(ret); return(ret);

9
tree.h
View File

@@ -634,6 +634,10 @@ int xmlReconciliateNs (xmlDocPtr doc,
/* /*
* Saving * Saving
*/ */
void xmlDocDumpFormatMemory (xmlDocPtr cur,
xmlChar**mem,
int *size,
int format);
void xmlDocDumpMemory (xmlDocPtr cur, void xmlDocDumpMemory (xmlDocPtr cur,
xmlChar**mem, xmlChar**mem,
int *size); int *size);
@@ -641,6 +645,11 @@ void xmlDocDumpMemoryEnc (xmlDocPtr out_doc,
xmlChar **doc_txt_ptr, xmlChar **doc_txt_ptr,
int * doc_txt_len, int * doc_txt_len,
const char *txt_encoding); 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, int xmlDocDump (FILE *f,
xmlDocPtr cur); xmlDocPtr cur);
void xmlElemDump (FILE *f, void xmlElemDump (FILE *f,

10
xmlIO.c
View File

@@ -1413,6 +1413,9 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
if (nbchars < MINLEN) if (nbchars < MINLEN)
return(0); return(0);
if (!out->writecallback)
return(nbchars);
/* /*
* second write the stuff to the I/O channel * second write the stuff to the I/O channel
*/ */
@@ -1477,7 +1480,7 @@ xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
*/ */
int int
xmlOutputBufferFlush(xmlOutputBufferPtr out) { xmlOutputBufferFlush(xmlOutputBufferPtr out) {
int nbchars = 0, ret; int nbchars = 0, ret = 0;
/* /*
* first handle encoding stuff. * first handle encoding stuff.
@@ -1497,12 +1500,13 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) {
/* /*
* second flush the stuff to the I/O channel * second flush the stuff to the I/O channel
*/ */
if ((out->conv != NULL) && (out->encoder != NULL)) { if ((out->conv != NULL) && (out->encoder != NULL) &&
(out->writecallback != NULL)) {
ret = out->writecallback(out->context, ret = out->writecallback(out->context,
(const char *)out->conv->content, out->conv->use); (const char *)out->conv->content, out->conv->use);
if (ret >= 0) if (ret >= 0)
xmlBufferShrink(out->conv, ret); xmlBufferShrink(out->conv, ret);
} else { } else if (out->writecallback != NULL) {
ret = out->writecallback(out->context, ret = out->writecallback(out->context,
(const char *)out->buffer->content, out->buffer->use); (const char *)out->buffer->content, out->buffer->use);
if (ret >= 0) if (ret >= 0)

View File

@@ -565,15 +565,31 @@ void parseAndPrintFile(char *filename) {
#ifdef LIBXML_DEBUG_ENABLED #ifdef LIBXML_DEBUG_ENABLED
if (!debug) { if (!debug) {
#endif #endif
if (compress) if (memory) {
xmlChar *result;
int len;
if (encoding != NULL) {
xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
} else {
xmlDocDumpMemory(doc, &result, &len);
}
if (result == NULL) {
fprintf(stderr, "Failed to save\n");
} else {
write(1, result, len);
xmlFree(result);
}
} else if (compress)
xmlSaveFile("-", doc); xmlSaveFile("-", doc);
else if (encoding != NULL) else if (encoding != NULL)
xmlSaveFileEnc("-", doc, encoding); xmlSaveFileEnc("-", doc, encoding);
else else
xmlDocDump(stdout, doc); xmlDocDump(stdout, doc);
#ifdef LIBXML_DEBUG_ENABLED #ifdef LIBXML_DEBUG_ENABLED
} else } else {
xmlDebugDumpDocument(stdout, doc); xmlDebugDumpDocument(stdout, doc);
}
#endif #endif
} }

136
xpath.c
View File

@@ -444,7 +444,8 @@ const char *xmlXPathErrorMessages[] = {
"Memory allocation error", "Memory allocation error",
"Syntax error", "Syntax error",
"Resource error", "Resource error",
"Sub resource error" "Sub resource error",
"Undefined namespace prefix"
}; };
/** /**
@@ -1064,6 +1065,70 @@ xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
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 * * Routines to handle Values *
@@ -1285,9 +1350,8 @@ xmlXPathNewContext(xmlDocPtr doc) {
ret->max_axis = 0; ret->max_axis = 0;
ret->axis = NULL; ret->axis = NULL;
ret->namespaces = NULL; ret->nsHash = NULL;
ret->user = NULL; ret->user = NULL;
ret->nsNr = 0;
ret->contextSize = -1; ret->contextSize = -1;
ret->proximityPosition = -1; ret->proximityPosition = -1;
@@ -1305,9 +1369,7 @@ xmlXPathNewContext(xmlDocPtr doc) {
*/ */
void void
xmlXPathFreeContext(xmlXPathContextPtr ctxt) { xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
if (ctxt->namespaces != NULL) xmlXPathRegisteredNsCleanup(ctxt);
xmlFree(ctxt->namespaces);
xmlXPathRegisteredFuncsCleanup(ctxt); xmlXPathRegisteredFuncsCleanup(ctxt);
xmlXPathRegisteredVariablesCleanup(ctxt); xmlXPathRegisteredVariablesCleanup(ctxt);
#ifdef DEBUG #ifdef DEBUG
@@ -2712,10 +2774,19 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
if ((cur->type == XML_ELEMENT_NODE) || if ((cur->type == XML_ELEMENT_NODE) ||
(cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_DOCUMENT_NODE) ||
(cur->type == XML_HTML_DOCUMENT_NODE)) { (cur->type == XML_HTML_DOCUMENT_NODE)) {
if (prefix == NULL) {
#ifdef DEBUG_STEP #ifdef DEBUG_STEP
n++; n++;
#endif #endif
xmlXPathNodeSetAdd(ret, cur); xmlXPathNodeSetAdd(ret, cur);
} else if ((cur->ns != NULL) &&
(xmlStrEqual(prefix,
cur->ns->href))) {
#ifdef DEBUG_STEP
n++;
#endif
xmlXPathNodeSetAdd(ret, cur);
}
} }
} }
break; break;
@@ -2726,14 +2797,25 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
case NODE_TEST_NAME: case NODE_TEST_NAME:
switch (cur->type) { switch (cur->type) {
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
if (xmlStrEqual(name, cur->name) && if (xmlStrEqual(name, cur->name)) {
(((prefix == NULL) || if (prefix == NULL) {
((cur->ns != NULL) && if ((cur->ns == NULL) ||
(xmlStrEqual(prefix, cur->ns->href)))))) { (cur->ns->prefix == NULL)) {
#ifdef DEBUG_STEP #ifdef DEBUG_STEP
n++; n++;
#endif #endif
xmlXPathNodeSetAdd(ret, cur); xmlXPathNodeSetAdd(ret, cur);
}
} else {
if ((cur->ns != NULL) &&
(xmlStrEqual(prefix,
cur->ns->href))) {
#ifdef DEBUG_STEP
n++;
#endif
xmlXPathNodeSetAdd(ret, cur);
}
}
} }
break; break;
case XML_ATTRIBUTE_NODE: { case XML_ATTRIBUTE_NODE: {
@@ -5106,7 +5188,7 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
*/ */
xmlChar * xmlChar *
xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test, xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
xmlXPathTypeVal *type, xmlChar **prefix, xmlChar *name) { xmlXPathTypeVal *type, const xmlChar **prefix, xmlChar *name) {
int blanks; int blanks;
if ((test == NULL) || (type == NULL) || (prefix == NULL)) { if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
@@ -5148,8 +5230,11 @@ xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
*type = NODE_TYPE_PI; *type = NODE_TYPE_PI;
else if (xmlStrEqual(name, BAD_CAST "text")) else if (xmlStrEqual(name, BAD_CAST "text"))
*type = NODE_TYPE_TEXT; *type = NODE_TYPE_TEXT;
else else {
if (name != NULL)
xmlFree(name);
XP_ERROR0(XPATH_EXPR_ERROR); XP_ERROR0(XPATH_EXPR_ERROR);
}
*test = NODE_TEST_TYPE; *test = NODE_TEST_TYPE;
@@ -5172,8 +5257,11 @@ xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
xmlXPathFreeObject(cur); xmlXPathFreeObject(cur);
SKIP_BLANKS; SKIP_BLANKS;
} }
if (CUR != ')') if (CUR != ')') {
if (name != NULL)
xmlFree(name);
XP_ERROR0(XPATH_UNCLOSED_ERROR); XP_ERROR0(XPATH_UNCLOSED_ERROR);
}
NEXT; NEXT;
return(name); return(name);
} }
@@ -5181,7 +5269,15 @@ xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
if ((!blanks) && (CUR == ':')) { if ((!blanks) && (CUR == ':')) {
NEXT; NEXT;
*prefix = name; /*
* 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 == '*') { if (CUR == '*') {
/* /*
@@ -5347,7 +5443,7 @@ xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
SKIP_BLANKS; SKIP_BLANKS;
} else { } else {
xmlChar *name = NULL; xmlChar *name = NULL;
xmlChar *prefix = NULL; const xmlChar *prefix = NULL;
xmlXPathTestVal test; xmlXPathTestVal test;
xmlXPathAxisVal axis; xmlXPathAxisVal axis;
xmlXPathTypeVal type; xmlXPathTypeVal type;
@@ -5420,8 +5516,6 @@ xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
#endif #endif
if (name != NULL) if (name != NULL)
xmlFree(name); xmlFree(name);
if (prefix != NULL)
xmlFree(prefix);
eval_predicates: eval_predicates:
SKIP_BLANKS; SKIP_BLANKS;

16
xpath.h
View File

@@ -47,7 +47,8 @@ typedef enum {
XPATH_MEMORY_ERROR, XPATH_MEMORY_ERROR,
XPTR_SYNTAX_ERROR, XPTR_SYNTAX_ERROR,
XPTR_RESOURCE_ERROR, XPTR_RESOURCE_ERROR,
XPTR_SUB_RESOURCE_ERROR XPTR_SUB_RESOURCE_ERROR,
XPATH_UNDEF_PREFIX_ERROR
} xmlXPathError; } xmlXPathError;
/* /*
@@ -171,6 +172,8 @@ struct _xmlXPathAxis {
* - a set of variable bindings * - a set of variable bindings
* - a function library * - a function library
* - the set of namespace declarations in scope for the expression * - 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 { struct _xmlXPathContext {
@@ -193,10 +196,10 @@ struct _xmlXPathContext {
int max_axis; /* max number of axis */ int max_axis; /* max number of axis */
xmlXPathAxisPtr axis; /* Array of defined axis */ xmlXPathAxisPtr axis; /* Array of defined axis */
/* Namespace traversal should be implemented with user */ /* the namespace nodes of the context node */
xmlNsPtr *namespaces; /* The namespaces lookup */ xmlNsPtr *namespaces; /* Array of namespaces */
int nsNr; /* the current Namespace index */ int nsNr; /* number of namespace in scope */
void *user; /* user defined extra info */ void *user; /* function to free */
/* extra variables */ /* extra variables */
int contextSize; /* the context size */ int contextSize; /* the context size */
@@ -206,6 +209,9 @@ struct _xmlXPathContext {
int xptr; /* it this an XPointer context */ int xptr; /* it this an XPointer context */
xmlNodePtr here; /* for here() */ xmlNodePtr here; /* for here() */
xmlNodePtr origin; /* for origin() */ xmlNodePtr origin; /* for origin() */
/* the set of namespace declarations in scope for the expression */
xmlHashTablePtr nsHash; /* The namespaces hash table */
}; };
/* /*

View File

@@ -68,6 +68,13 @@ void xmlXPathDebugDumpObject (FILE *output,
/** /**
* Extending a context * 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, int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
const xmlChar *name, const xmlChar *name,
xmlXPathFunction f); xmlXPathFunction f);
@@ -121,6 +128,7 @@ void xmlXPathIdFunction (xmlXPathParserContextPtr ctxt,
void xmlXPathRoot (xmlXPathParserContextPtr ctxt); void xmlXPathRoot (xmlXPathParserContextPtr ctxt);
void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt); void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt);
xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt); xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt);
xmlChar * xmlXPathParseNCName (xmlXPathParserContextPtr ctxt);
/* /*
* Debug * Debug

View File

@@ -28,6 +28,7 @@
#include <libxml/xpointer.h> #include <libxml/xpointer.h>
#include <libxml/xmlmemory.h> #include <libxml/xmlmemory.h>
#include <libxml/parserInternals.h> #include <libxml/parserInternals.h>
#include <libxml/uri.h>
#include <libxml/xpath.h> #include <libxml/xpath.h>
#include <libxml/xpathInternals.h> #include <libxml/xpathInternals.h>
#ifdef LIBXML_DEBUG_ENABLED #ifdef LIBXML_DEBUG_ENABLED
@@ -37,6 +38,9 @@
#ifdef LIBXML_XPTR_ENABLED #ifdef LIBXML_XPTR_ENABLED
/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
#define XPTR_XMLNS_SCHEME
/* #define DEBUG_RANGES */ /* #define DEBUG_RANGES */
#define TODO \ #define TODO \
@@ -1038,6 +1042,50 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
xmlXPathRoot(ctxt); xmlXPathRoot(ctxt);
xmlXPathEvalExpr(ctxt); xmlXPathEvalExpr(ctxt);
CUR_PTR=left; 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 { } else {
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"unsupported scheme '%s'\n", name); "unsupported scheme '%s'\n", name);