1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +03:00

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
This commit is contained in:
Daniel Veillard 2008-09-01 13:08:57 +00:00
parent 1572425c27
commit da3fee406d
13 changed files with 373 additions and 220 deletions

View File

@ -1,3 +1,19 @@
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

View File

@ -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;

View File

@ -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

27
NEWS
View File

@ -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

View File

@ -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 = []

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -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);

13
tree.c
View File

@ -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;
}
/**

View File

@ -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[] = {

69
xmlIO.c
View File

@ -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;

291
xmlsave.c
View File

@ -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);
}
/*
* initialize the state, e.g. if outputting a BOM
*/
xmlCharEncOutFunc(buf->encoder, buf->conv, NULL);
switched_encoding = 1;
}
if (ctxt->escape == xmlEscapeEntities)
ctxt->escape = NULL;
if (ctxt->escapeAttr == xmlEscapeEntities)
ctxt->escapeAttr = NULL;
}
/*
* Save the XML declaration
*/
if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
xmlOutputBufferWrite(buf, 14, "<?xml version=");
if (cur->version != NULL)
xmlBufferWriteQuotedString(buf->buffer, cur->version);
if (ctxt->options & XML_SAVE_FORMAT)
htmlDocContentDumpFormatOutput(buf, cur,
(const char *)encoding, 1);
else
xmlOutputBufferWrite(buf, 5, "\"1.0\"");
if (encoding != NULL) {
xmlOutputBufferWrite(buf, 10, " encoding=");
xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
}
switch (cur->standalone) {
case 0:
xmlOutputBufferWrite(buf, 16, " standalone=\"no\"");
break;
case 1:
xmlOutputBufferWrite(buf, 17, " standalone=\"yes\"");
break;
}
xmlOutputBufferWrite(buf, 3, "?>\n");
}
#ifdef LIBXML_HTML_ENABLED
if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
dtd = xmlGetIntSubset(cur);
if (dtd != NULL) {
is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
if (is_xhtml < 0) is_xhtml = 0;
}
}
htmlDocContentDumpFormatOutput(buf, cur,
(const char *)encoding, 0);
if (ctxt->encoding != NULL)
cur->encoding = oldenc;
return(0);
#else
return(-1);
#endif
if (cur->children != NULL) {
xmlNodePtr child = cur->children;
} 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;
}
if (ctxt->escape == xmlEscapeEntities)
ctxt->escape = NULL;
if (ctxt->escapeAttr == xmlEscapeEntities)
ctxt->escapeAttr = NULL;
}
while (child != NULL) {
ctxt->level = 0;
#ifdef LIBXML_HTML_ENABLED
if (is_xhtml)
xhtmlNodeDumpOutput(ctxt, child);
/*
* Save the XML declaration
*/
if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
xmlOutputBufferWrite(buf, 14, "<?xml version=");
if (cur->version != NULL)
xmlBufferWriteQuotedString(buf->buffer, cur->version);
else
xmlOutputBufferWrite(buf, 5, "\"1.0\"");
if (encoding != NULL) {
xmlOutputBufferWrite(buf, 10, " encoding=");
xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
}
switch (cur->standalone) {
case 0:
xmlOutputBufferWrite(buf, 16, " standalone=\"no\"");
break;
case 1:
xmlOutputBufferWrite(buf, 17, " standalone=\"yes\"");
break;
}
xmlOutputBufferWrite(buf, 3, "?>\n");
}
#ifdef LIBXML_HTML_ENABLED
if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
dtd = xmlGetIntSubset(cur);
if (dtd != NULL) {
is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
if (is_xhtml < 0) is_xhtml = 0;
}
}
#endif
xmlNodeDumpOutputInternal(ctxt, child);
xmlOutputBufferWrite(buf, 1, "\n");
child = child->next;
if (cur->children != NULL) {
xmlNodePtr child = cur->children;
while (child != NULL) {
ctxt->level = 0;
#ifdef LIBXML_HTML_ENABLED
if (is_xhtml)
xhtmlNodeDumpOutput(ctxt, child);
else
#endif
xmlNodeDumpOutputInternal(ctxt, child);
xmlOutputBufferWrite(buf, 1, "\n");
child = child->next;
}
}
}
if (ctxt->encoding != NULL)
cur->encoding = oldenc;
/*
* Restore the state of the saving context at the end of the document
*/
if ((encoding != NULL) && (oldctxtenc == NULL) &&
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
if ((enc != XML_CHAR_ENCODING_UTF8) &&
(enc != XML_CHAR_ENCODING_NONE) &&
(enc != XML_CHAR_ENCODING_ASCII)) {
xmlOutputBufferFlush(buf);
xmlCharEncCloseFunc(buf->encoder);
xmlBufferFree(buf->conv);
buf->encoder = NULL;
buf->conv = NULL;
}
if ((switched_encoding) && (oldctxtenc == NULL)) {
xmlSaveClearEncoding(ctxt);
ctxt->escape = oldescape;
ctxt->escapeAttr = oldescapeAttr;
}
cur->encoding = oldenc;
return(0);
}