Commit da3fee40 authored by Daniel Veillard's avatar Daniel Veillard

Borland C fix from Moritz Both regenerate, workaround a problem for buffer

* trionan.c: Borland C fix from Moritz Both
* testapi.c: regenerate, workaround a problem for buffer testing
* xmlIO.c HTMLtree.c: new internal entry point to hide even better
  xmlAllocOutputBufferInternal
* tree.c: harden the code around buffer allocation schemes
* parser.c: restore the warning when namespace names are not absolute
  URIs
* runxmlconf.c: continue regression tests if we get the expected
  number of errors
* Makefile.am: run the python tests on make check
* xmlsave.c: handle the HTML documents and trees
* python/libxml.c: convert python serialization to the xmlSave APIs
  and avoid some horrible hacks
Daniel

svn path=/trunk/; revision=3790
parent 1572425c
Mon Sep 1 15:02:05 CEST 2008 Daniel Veillard <daniel@veillard.com>
* trionan.c: Borland C fix from Moritz Both
* testapi.c: regenerate, workaround a problem for buffer testing
* xmlIO.c HTMLtree.c: new internal entry point to hide even better
xmlAllocOutputBufferInternal
* tree.c: harden the code around buffer allocation schemes
* parser.c: restore the warning when namespace names are not absolute
URIs
* runxmlconf.c: continue regression tests if we get the expected
number of errors
* Makefile.am: run the python tests on make check
* xmlsave.c: handle the HTML documents and trees
* python/libxml.c: convert python serialization to the xmlSave APIs
and avoid some horrible hacks
Sat Aug 30 16:58:40 CEST 2008 Daniel Veillard <daniel@veillard.com>
* configure.in, doc/*: preparing 2.7.0 release
......
......@@ -316,6 +316,11 @@ htmlIsBooleanAttr(const xmlChar *name)
}
#ifdef LIBXML_OUTPUT_ENABLED
/*
* private routine exported from xmlIO.c
*/
xmlOutputBufferPtr
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
/************************************************************************
* *
* Output error handlers *
......@@ -566,7 +571,7 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
if (handler == NULL)
handler = xmlFindCharEncodingHandler("ascii");
buf = xmlAllocOutputBuffer(handler);
buf = xmlAllocOutputBufferInternal(handler);
if (buf == NULL) {
*mem = NULL;
*size = 0;
......
......@@ -157,7 +157,7 @@ rebuild_testapi:
# that one is just to make sure it is rebuilt if missing
# but adding the dependances generate mess
testapi.c:
testapi.c: $(srcdir)/gentest.py
-@(if [ "$(PYTHON)" != "" ] ; then \
$(PYTHON) $(srcdir)/gentest.py $(srcdir) ; fi )
......@@ -178,6 +178,8 @@ runxmlconf_LDADD= $(LDADDS)
runtests:
$(CHECKER) ./runtest$(EXEEXT) && $(CHECKER) ./testrecurse$(EXEEXT) &&$(CHECKER) ./testapi$(EXEEXT) && $(CHECKER) ./testchar$(EXEEXT)&& $(CHECKER) ./testdict$(EXEEXT) && $(CHECKER) ./runxmlconf$(EXEEXT)
@(if [ "@PYTHON_SUBDIR@" != "" ] ; then cd python ; \
$(MAKE) MAKEFLAGS+=--silent tests ; fi)
check: all runtests
......
......@@ -15,6 +15,33 @@ ChangeLog.html
to the SVN at
http://svn.gnome.org/viewcvs/libxml2/trunk/
code base.Here is the list of public releases:
2.7.0: Aug 30 2008:
- Documentation: switch ChangeLog to UTF-8, improve mutithreads and
xmlParserCleanup docs
- Portability fixes: Older Win32 platforms (Rob Richards), MSVC
porting fix (Rob Richards), Mac OS X regression tests (Sven Herzberg),
non GNUCC builds (Rob Richards), compilation on Haiku (Andreas Färber)
- Bug fixes: various realloc problems (Ashwin), potential double-free
(Ashwin), regexp crash, icrash with invalid whitespace facets (Rob
Richards), pattern fix when streaming (William Brack), various XML
parsing and validation fixes based on the W3C regression tests, reader
tree skipping function fix (Ashwin), Schemas regexps escaping fix
(Volker Grabsch), handling of entity push errors (Ashwin), fix a slowdown
when encoder cant serialize characters on output
- Code cleanup: compilation fix without the reader, without the output
(Robert Schwebel), python whitespace (Martin), many space/tabs cleanups,
serious cleanup of the entity handling code
- Improvement: switch parser to XML-1.0 5th edition, add parsing flags
for old versions, switch URI parsing to RFC 3986,
add xmlSchemaValidCtxtGetParserCtxt (Holger Kaelberer),
new hashing functions for dictionnaries (based on Stefan Behnel work),
improve handling of misplaced html/head/body in HTML parser, better
regression test tools and code coverage display, better algorithms
to detect various versions of the billion laughts attacks, make
arbitrary parser limits avoidable as a parser option
2.6.32: Apr 8 2008:
- Documentation: returning heap memory to kernel (Wolfram Sang),
trying to clarify xmlCleanupParser() use, xmlXPathContext improvement
......
......@@ -260,6 +260,7 @@ extra_post_call = {
"xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
"xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
"xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
"xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}"
}
modules = []
......
......@@ -8694,7 +8694,7 @@ reparse:
"xmlns: '%s' is not a valid URI\n",
URL, NULL, NULL);
} else {
if ((ctxt->pedantic) && (uri->scheme == NULL)) {
if (uri->scheme == NULL) {
xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
"xmlns: URI %s is not absolute\n",
URL, NULL, NULL);
......
......@@ -24,6 +24,7 @@
#include <libxml/xmlIO.h>
#include <libxml/c14n.h>
#include <libxml/xmlreader.h>
#include <libxml/xmlsave.h>
#include "libxml_wrap.h"
#include "libxml2-py.h"
......@@ -2761,6 +2762,9 @@ libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
const char *encoding;
int format;
int len;
xmlSaveCtxtPtr ctxt;
xmlBufferPtr buf;
int options = 0;
if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
&encoding, &format))
......@@ -2773,137 +2777,52 @@ libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
}
if (node->type == XML_DOCUMENT_NODE) {
doc = (xmlDocPtr) node;
xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
(const char *) encoding, format);
py_retval = libxml_charPtrWrap((char *) c_retval);
node = NULL;
#ifdef LIBXML_HTML_ENABLED
} else if (node->type == XML_HTML_DOCUMENT_NODE) {
xmlOutputBufferPtr buf;
xmlCharEncodingHandlerPtr handler = NULL;
doc = (xmlDocPtr) node;
if (encoding != NULL)
htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
encoding = (const char *) htmlGetMetaEncoding(doc);
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
}
/*
* Fallback to HTML or ASCII when the encoding is unspecified
*/
if (handler == NULL)
handler = xmlFindCharEncodingHandler("HTML");
if (handler == NULL)
handler = xmlFindCharEncodingHandler("ascii");
buf = xmlAllocOutputBuffer(handler);
if (buf == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
xmlOutputBufferFlush(buf);
if (buf->conv != NULL) {
len = buf->conv->use;
c_retval = buf->conv->content;
buf->conv->content = NULL;
} else {
len = buf->buffer->use;
c_retval = buf->buffer->content;
buf->buffer->content = NULL;
}
(void) xmlOutputBufferClose(buf);
py_retval = libxml_charPtrWrap((char *) c_retval);
#endif /* LIBXML_HTML_ENABLED */
node = NULL;
#endif
} else {
if (node->type == XML_NAMESPACE_DECL)
doc = NULL;
else
doc = node->doc;
if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
xmlOutputBufferPtr buf;
xmlCharEncodingHandlerPtr handler = NULL;
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
}
buf = xmlAllocOutputBuffer(handler);
if (buf == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
xmlOutputBufferFlush(buf);
if (buf->conv != NULL) {
len = buf->conv->use;
c_retval = buf->conv->content;
buf->conv->content = NULL;
} else {
len = buf->buffer->use;
c_retval = buf->buffer->content;
buf->buffer->content = NULL;
}
(void) xmlOutputBufferClose(buf);
py_retval = libxml_charPtrWrap((char *) c_retval);
#ifdef LIBXML_HTML_ENABLED
} else if (doc->type == XML_HTML_DOCUMENT_NODE) {
xmlOutputBufferPtr buf;
xmlCharEncodingHandlerPtr handler = NULL;
if (encoding != NULL)
htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
encoding = (const char *) htmlGetMetaEncoding(doc);
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
}
/*
* Fallback to HTML or ASCII when the encoding is unspecified
*/
if (handler == NULL)
handler = xmlFindCharEncodingHandler("HTML");
if (handler == NULL)
handler = xmlFindCharEncodingHandler("ascii");
buf = xmlAllocOutputBuffer(handler);
if (buf == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
xmlOutputBufferFlush(buf);
if (buf->conv != NULL) {
len = buf->conv->use;
c_retval = buf->conv->content;
buf->conv->content = NULL;
} else {
len = buf->buffer->use;
c_retval = buf->buffer->content;
buf->buffer->content = NULL;
}
(void) xmlOutputBufferClose(buf);
py_retval = libxml_charPtrWrap((char *) c_retval);
#endif /* LIBXML_HTML_ENABLED */
} else {
Py_INCREF(Py_None);
return (Py_None);
}
}
buf = xmlBufferCreate();
if (buf == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
if (format) options |= XML_SAVE_FORMAT;
ctxt = xmlSaveToBuffer(buf, encoding, options);
if (ctxt == NULL) {
xmlBufferFree(buf);
Py_INCREF(Py_None);
return (Py_None);
}
if (node == NULL)
xmlSaveDoc(ctxt, doc);
else
xmlSaveTree(ctxt, node);
xmlSaveClose(ctxt);
c_retval = buf->content;
buf->content = NULL;
xmlBufferFree(buf);
py_retval = libxml_charPtrWrap((char *) c_retval);
return (py_retval);
}
......
......@@ -33,7 +33,7 @@
static FILE *logfile = NULL;
static int verbose = 0;
#define NB_EXPECTED_ERRORS 15
#if defined(_WIN32) && !defined(__CYGWIN__)
......@@ -588,10 +588,14 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
printf("Total %d tests, no errors\n",
nb_tests);
} else {
ret = 1;
ret = 1;
printf("Total %d tests, %d errors, %d leaks\n",
nb_tests, nb_errors, nb_leaks);
printf("See %s for detailed output\n", LOGFILE);
if ((nb_leaks == 0) && (nb_errors == NB_EXPECTED_ERRORS)) {
printf("%d errors were expected\n", nb_errors);
ret = 0;
}
}
xmlXPathFreeContext(ctxtXPath);
xmlCleanupParser();
......
......@@ -599,9 +599,10 @@ static void des_xmlTextReaderPtr(int no ATTRIBUTE_UNUSED, xmlTextReaderPtr val,
#endif
#define gen_nb_xmlBufferPtr 3
static const char *static_buf_content = "a static buffer";
static xmlBufferPtr gen_xmlBufferPtr(int no, int nr ATTRIBUTE_UNUSED) {
if (no == 0) return(xmlBufferCreate());
if (no == 1) return(xmlBufferCreateStatic((void *)"a static buffer", 13));
if (no == 1) return(xmlBufferCreateStatic((void *)static_buf_content, 13));
return(NULL);
}
static void des_xmlBufferPtr(int no ATTRIBUTE_UNUSED, xmlBufferPtr val, int nr ATTRIBUTE_UNUSED) {
......@@ -18827,6 +18828,7 @@ test_xmlBufferSetAllocationScheme(void) {
scheme = gen_xmlBufferAllocationScheme(n_scheme, 1);
xmlBufferSetAllocationScheme(buf, scheme);
if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
des_xmlBufferAllocationScheme(n_scheme, scheme, 1);
......@@ -680,7 +680,9 @@ try_complex:
*/
void
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
xmlBufferAllocScheme = scheme;
if ((scheme == XML_BUFFER_ALLOC_EXACT) ||
(scheme == XML_BUFFER_ALLOC_DOUBLEIT))
xmlBufferAllocScheme = scheme;
}
/**
......@@ -6736,9 +6738,12 @@ xmlBufferSetAllocationScheme(xmlBufferPtr buf,
#endif
return;
}
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
buf->alloc = scheme;
if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
(buf->alloc == XML_BUFFER_ALLOC_IO)) return;
if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
(scheme == XML_BUFFER_ALLOC_EXACT) ||
(scheme == XML_BUFFER_ALLOC_IMMUTABLE))
buf->alloc = scheme;
}
/**
......
......@@ -129,7 +129,11 @@ static TRIO_CONST char rcsid[] = "@(#)$Id$";
*/
#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
#if (defined(__BORLANDC__) && __BORLANDC__ >= 0x0590)
static TRIO_CONST double internalEndianMagic = 7.949928895127362e-275;
#else
static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
#endif
/* Mask for the exponent */
static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
......
......@@ -135,6 +135,9 @@ typedef struct _xmlOutputCallback {
static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
static int xmlOutputCallbackNr = 0;
static int xmlOutputCallbackInitialized = 0;
xmlOutputBufferPtr
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
......@@ -1720,7 +1723,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression)
{
/* Any character conversions should have been done before this */
ctxt->doc_buff = xmlAllocOutputBuffer(NULL);
ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL);
}
if (ctxt->doc_buff == NULL) {
......@@ -1731,7 +1734,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression)
return (ctxt);
}
#endif /* LIBXML_OUTPUT_ENABLED */
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlIOHTTPDfltOpenW
......@@ -2275,8 +2278,57 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
return(NULL);
}
ret->encoder = encoder;
if (encoder != NULL) {
ret->conv = xmlBufferCreateSize(4000);
if (ret->conv == NULL) {
xmlFree(ret);
return(NULL);
}
/*
* 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);
}
/**
* xmlAllocOutputBufferInternal:
* @encoder: the encoding converter or NULL
*
* Create a buffered parser output
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) {
xmlOutputBufferPtr ret;
ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
if (ret == NULL) {
xmlIOErrMemory("creating output buffer");
return(NULL);
}
memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
ret->buffer = xmlBufferCreate();
if (ret->buffer == NULL) {
xmlFree(ret);
return(NULL);
}
/*
* For conversion buffers we use the special IO handling
* We don't do that from the exported API to avoid confusing
* user's code.
*/
ret->buffer->alloc = XML_BUFFER_ALLOC_IO;
ret->buffer->contentIO = ret->buffer->content;
......@@ -2302,6 +2354,7 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
......@@ -2502,7 +2555,7 @@ __xmlOutputBufferCreateFilename(const char *URI,
if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
context = xmlGzfileOpenW(unescaped, compression);
if (context != NULL) {
ret = xmlAllocOutputBuffer(encoder);
ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = context;
ret->writecallback = xmlGzfileWrite;
......@@ -2539,7 +2592,7 @@ __xmlOutputBufferCreateFilename(const char *URI,
if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
context = xmlGzfileOpenW(URI, compression);
if (context != NULL) {
ret = xmlAllocOutputBuffer(encoder);
ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = context;
ret->writecallback = xmlGzfileWrite;
......@@ -2572,7 +2625,7 @@ __xmlOutputBufferCreateFilename(const char *URI,
/*
* Allocate the Output buffer front-end.
*/
ret = xmlAllocOutputBuffer(encoder);
ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = context;
ret->writecallback = xmlOutputCallbackTable[i].writecallback;
......@@ -2656,7 +2709,7 @@ xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
if (file == NULL) return(NULL);
ret = xmlAllocOutputBuffer(encoder);
ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = file;
ret->writecallback = xmlFileWrite;
......@@ -2814,7 +2867,7 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
if (fd < 0) return(NULL);
ret = xmlAllocOutputBuffer(encoder);
ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = (void *) (long) fd;
ret->writecallback = xmlFdWrite;
......@@ -2875,7 +2928,7 @@ xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite,
if (iowrite == NULL) return(NULL);
ret = xmlAllocOutputBuffer(encoder);
ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = (void *) ioctx;
ret->writecallback = iowrite;
......
......@@ -457,6 +457,40 @@ xmlAttrSerializeContent(xmlOutputBufferPtr buf, xmlAttrPtr attr)
* *
************************************************************************/
static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
xmlOutputBufferPtr buf = ctxt->buf;
if ((encoding != NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) {
buf->encoder = xmlFindCharEncodingHandler((const char *)encoding);
if (buf->encoder == NULL) {
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL,
(const char *)encoding);
return(-1);
}
buf->conv = xmlBufferCreate();
if (buf->conv == NULL) {
xmlCharEncCloseFunc(buf->encoder);
xmlSaveErrMemory("creating encoding buffer");
return(-1);
}
/*
* initialize the state, e.g. if outputting a BOM
*/
xmlCharEncOutFunc(buf->encoder, buf->conv, NULL);
}
return(0);
}
static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
xmlOutputBufferPtr buf = ctxt->buf;
xmlOutputBufferFlush(buf);
xmlCharEncCloseFunc(buf->encoder);
xmlBufferFree(buf->conv);
buf->encoder = NULL;
buf->conv = NULL;
return(0);
}
#ifdef LIBXML_HTML_ENABLED
static void
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
......@@ -638,6 +672,66 @@ xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
}
}
#ifdef LIBXML_HTML_ENABLED
/**
* xmlNodeDumpOutputInternal:
* @cur: the current node
*
* Dump an HTML node, recursive behaviour, children are printed too.
*/
static int
htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
const xmlChar *oldenc = NULL;
const xmlChar *oldctxtenc = ctxt->encoding;
const xmlChar *encoding = ctxt->encoding;
xmlOutputBufferPtr buf = ctxt->buf;
int switched_encoding = 0;
xmlDocPtr doc;
xmlInitParser();
doc = cur->doc; {
if (doc != NULL)
oldenc = doc->encoding;
if (ctxt->encoding != NULL) {
doc->encoding = BAD_CAST ctxt->encoding;
} else if (doc->encoding != NULL) {
encoding = doc->encoding;
}
}
if ((encoding != NULL) && (doc != NULL))
htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
if ((encoding == NULL) && (doc != NULL))
encoding = htmlGetMetaEncoding(doc);
if (encoding == NULL)
encoding = BAD_CAST "HTML";
if ((encoding != NULL) && (oldctxtenc == NULL) &&
(buf->encoder == NULL) && (buf->conv == NULL)) {
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
doc->encoding = oldenc;
return(-1);
}
switched_encoding = 1;
}
if (ctxt->options & XML_SAVE_FORMAT)
htmlNodeDumpFormatOutput(buf, doc, cur,
(const char *)encoding, 1);
else
htmlNodeDumpFormatOutput(buf, doc, cur,
(const char *)encoding, 0);
/*
* Restore the state of the saving context at the end of the document
*/
if ((switched_encoding) && (oldctxtenc == NULL)) {
xmlSaveClearEncoding(ctxt);
}
if (doc != NULL)
doc->encoding = oldenc;
return(0);
}
#endif
/**
* xmlNodeDumpOutputInternal:
* @cur: the current node
......@@ -662,6 +756,13 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
return;
}
#ifdef LIBXML_HTML_ENABLED
if ((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) &&
(cur->doc->type == XML_HTML_DOCUMENT_NODE)) {
htmlNodeDumpOutputInternal(ctxt, cur);
return;
}
#endif
if (cur->type == XML_DTD_NODE) {
xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
return;
......@@ -835,9 +936,14 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
xmlCharEncodingOutputFunc oldescapeAttr = ctxt->escapeAttr;
xmlOutputBufferPtr buf = ctxt->buf;
xmlCharEncoding enc;
int switched_encoding = 0;
xmlInitParser();
if ((cur->type != XML_HTML_DOCUMENT_NODE) &&
(cur->type != XML_DOCUMENT_NODE))
return(-1);
if (ctxt->encoding != NULL) {
cur->encoding = BAD_CAST ctxt->encoding;
} else if (cur->encoding != NULL) {
......@@ -847,110 +953,119 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
xmlGetCharEncodingName((xmlCharEncoding) cur->charset);
}
enc = xmlParseCharEncoding((const char*) encoding);
if ((encoding != NULL) && (oldctxtenc == NULL) &&
(buf->encoder == NULL) && (buf->conv == NULL) &&
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
if ((enc != XML_CHAR_ENCODING_UTF8) &&
(enc != XML_CHAR_ENCODING_NONE) &&
(enc != XML_CHAR_ENCODING_ASCII)) {
/*
* we need to switch to this encoding but just for this document
* since we output the XMLDecl the conversion must be done to not
* generate not well formed documents.
*/
buf->encoder = xmlFindCharEncodingHandler((const char *)encoding);
if (buf->encoder == NULL) {
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL,
(const char *)encoding);
if (cur->type == XML_HTML_DOCUMENT_NODE) {
#ifdef LIBXML_HTML_ENABLED
if (encoding != NULL)
htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
if (encoding == NULL)
encoding = htmlGetMetaEncoding(cur);
if (encoding == NULL)
encoding = BAD_CAST "HTML";
if ((encoding != NULL) && (oldctxtenc == NULL) &&
(buf->encoder == NULL) && (buf->conv == NULL)) {
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
cur->encoding = oldenc;
return(-1);
}
buf->conv = xmlBufferCreate();
if (buf->conv == NULL) {
xmlCharEncCloseFunc(buf->encoder);
xmlSaveErrMemory("creating encoding buffer");
return(-1);
switched_encoding = 1;
}
if (ctxt->options & XML_SAVE_FORMAT)
htmlDocContentDumpFormatOutput(buf, cur,
(const char *)encoding, 1);
else
htmlDocContentDumpFormatOutput(buf, cur,
(const char *)encoding, 0);
if (ctxt->encoding != NULL)
cur->encoding = oldenc;
return(0);
#else
return(-1);
#endif
} else if (cur->type == XML_DOCUMENT_NODE) {
enc = xmlParseCharEncoding((const char*) encoding);
if ((encoding != NULL) && (oldctxtenc == NULL) &&
(buf->encoder == NULL) && (buf->conv == NULL) &&
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
if ((enc != XML_CHAR_ENCODING_UTF8) &&
(enc != XML_CHAR_ENCODING_NONE) &&
(enc != XML_CHAR_ENCODING_ASCII)) {
/*
* we need to switch to this encoding but just for this
* document since we output the XMLDecl the conversion
* must be done to not generate not well formed documents.
*/
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
cur->encoding = oldenc;
return(-1);
}
switched_encoding = 1;
}
/*
* initialize the state, e.g. if outputting a BOM
*/
xmlCharEncOutFunc(buf->encoder, buf->conv, NULL);
if (ctxt->escape == xmlEscapeEntities)
ctxt->escape = NULL;