summaryrefslogtreecommitdiffstats
path: root/contrib/libs/libxml/xmlsave.c
diff options
context:
space:
mode:
authorsetser <[email protected]>2022-05-09 00:13:37 +0300
committersetser <[email protected]>2022-05-09 00:13:37 +0300
commite87e3fc8d0e04eb7ba3eee221bb91613b527ad85 (patch)
tree5279c128bdbdf902b9a08d9fae8e55b91910a553 /contrib/libs/libxml/xmlsave.c
parentf4f3e4024a1f32bd0bc3fa20239025a1b179e42d (diff)
Update libxml to 2.9.13
ref:f572491d236694e847142c36f0f5546c649e05d7
Diffstat (limited to 'contrib/libs/libxml/xmlsave.c')
-rw-r--r--contrib/libs/libxml/xmlsave.c1154
1 files changed, 560 insertions, 594 deletions
diff --git a/contrib/libs/libxml/xmlsave.c b/contrib/libs/libxml/xmlsave.c
index fa009153718..489505f4865 100644
--- a/contrib/libs/libxml/xmlsave.c
+++ b/contrib/libs/libxml/xmlsave.c
@@ -100,7 +100,7 @@ struct _xmlSaveCtxt {
************************************************************************/
/**
* xmlSaveErrMemory:
- * @extra: extra informations
+ * @extra: extra information
*
* Handle an out of memory condition
*/
@@ -114,7 +114,7 @@ xmlSaveErrMemory(const char *extra)
* xmlSaveErr:
* @code: the error number
* @node: the location of the error.
- * @extra: extra informations
+ * @extra: extra information
*
* Handle an out of memory condition
*/
@@ -590,7 +590,6 @@ static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
static void
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
#endif
-static void xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
@@ -705,6 +704,7 @@ xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
static void
xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) {
xmlOutputBufferPtr buf;
+ xmlNodePtr cur;
int format, level;
if (dtd == NULL) return;
@@ -742,7 +742,9 @@ xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) {
level = ctxt->level;
ctxt->format = 0;
ctxt->level = -1;
- xmlNodeListDumpOutput(ctxt, dtd->children);
+ for (cur = dtd->children; cur != NULL; cur = cur->next) {
+ xmlNodeDumpOutputInternal(ctxt, cur);
+ }
ctxt->format = format;
ctxt->level = level;
xmlOutputBufferWrite(buf, 2, "]>");
@@ -776,58 +778,9 @@ xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
xmlOutputBufferWrite(buf, 1, "\"");
}
-/**
- * xmlAttrListDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the first attribute pointer
- * @encoding: an optional encoding string
- *
- * Dump a list of XML attributes
- */
-static void
-xmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
- if (cur == NULL) return;
- while (cur != NULL) {
- xmlAttrDumpOutput(ctxt, cur);
- cur = cur->next;
- }
-}
-
-
-
-/**
- * xmlNodeListDumpOutput:
- * @cur: the first node
- *
- * Dump an XML node list, recursive behaviour, children are printed too.
- */
-static void
-xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
- xmlOutputBufferPtr buf;
-
- if (cur == NULL) return;
- buf = ctxt->buf;
- while (cur != NULL) {
- if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
- ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_COMMENT_NODE) ||
- (cur->type == XML_PI_NODE)))
- xmlOutputBufferWrite(buf, ctxt->indent_size *
- (ctxt->level > ctxt->indent_nr ?
- ctxt->indent_nr : ctxt->level),
- ctxt->indent);
- xmlNodeDumpOutputInternal(ctxt, cur);
- if (ctxt->format == 1) {
- xmlOutputBufferWrite(buf, 1, "\n");
- }
- cur = cur->next;
- }
-}
-
#ifdef LIBXML_HTML_ENABLED
/**
- * xmlNodeDumpOutputInternal:
+ * htmlNodeDumpOutputInternal:
* @cur: the current node
*
* Dump an HTML node, recursive behaviour, children are printed too.
@@ -893,57 +846,126 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
*/
static void
xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
- int format;
- xmlNodePtr tmp;
+ int format = ctxt->format;
+ xmlNodePtr tmp, root, unformattedNode = NULL, parent;
+ xmlAttrPtr attr;
xmlChar *start, *end;
xmlOutputBufferPtr buf;
if (cur == NULL) return;
buf = ctxt->buf;
- if (cur->type == XML_XINCLUDE_START)
- return;
- if (cur->type == XML_XINCLUDE_END)
- return;
- if ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
- return;
- }
-#ifdef LIBXML_HTML_ENABLED
- if (ctxt->options & XML_SAVE_XHTML) {
- xhtmlNodeDumpOutput(ctxt, cur);
- return;
- }
- if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) &&
- (cur->doc->type == XML_HTML_DOCUMENT_NODE) &&
- ((ctxt->options & XML_SAVE_AS_XML) == 0)) ||
- (ctxt->options & XML_SAVE_AS_HTML)) {
- htmlNodeDumpOutputInternal(ctxt, cur);
- return;
- }
-#endif
- if (cur->type == XML_DTD_NODE) {
- xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
- return;
- }
- if (cur->type == XML_DOCUMENT_FRAG_NODE) {
- xmlNodeListDumpOutput(ctxt, cur->children);
- return;
- }
- if (cur->type == XML_ELEMENT_DECL) {
- xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
- return;
- }
- if (cur->type == XML_ATTRIBUTE_DECL) {
- xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
- return;
- }
- if (cur->type == XML_ENTITY_DECL) {
- xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
- return;
- }
- if (cur->type == XML_TEXT_NODE) {
- if (cur->content != NULL) {
+
+ root = cur;
+ parent = cur->parent;
+ while (1) {
+ switch (cur->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
+ break;
+
+ case XML_DTD_NODE:
+ xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
+ break;
+
+ case XML_DOCUMENT_FRAG_NODE:
+ /* Always validate cur->parent when descending. */
+ if ((cur->parent == parent) && (cur->children != NULL)) {
+ parent = cur;
+ cur = cur->children;
+ continue;
+ }
+ break;
+
+ case XML_ELEMENT_DECL:
+ xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
+ break;
+
+ case XML_ATTRIBUTE_DECL:
+ xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
+ break;
+
+ case XML_ENTITY_DECL:
+ xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
+ break;
+
+ case XML_ELEMENT_NODE:
+ if ((cur != root) && (ctxt->format == 1) &&
+ (xmlIndentTreeOutput))
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level),
+ ctxt->indent);
+
+ /*
+ * Some users like lxml are known to pass nodes with a corrupted
+ * tree structure. Fall back to a recursive call to handle this
+ * case.
+ */
+ if ((cur->parent != parent) && (cur->children != NULL)) {
+ xmlNodeDumpOutputInternal(ctxt, cur);
+ break;
+ }
+
+ xmlOutputBufferWrite(buf, 1, "<");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+ xmlOutputBufferWrite(buf, 1, ":");
+ }
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (cur->nsDef)
+ xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
+ for (attr = cur->properties; attr != NULL; attr = attr->next)
+ xmlAttrDumpOutput(ctxt, attr);
+
+ if (cur->children == NULL) {
+ if ((ctxt->options & XML_SAVE_NO_EMPTY) == 0) {
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
+ xmlOutputBufferWrite(buf, 2, "/>");
+ } else {
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 1);
+ xmlOutputBufferWrite(buf, 3, "></");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlOutputBufferWriteString(buf,
+ (const char *)cur->ns->prefix);
+ xmlOutputBufferWrite(buf, 1, ":");
+ }
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
+ xmlOutputBufferWrite(buf, 1, ">");
+ }
+ } else {
+ if (ctxt->format == 1) {
+ tmp = cur->children;
+ while (tmp != NULL) {
+ if ((tmp->type == XML_TEXT_NODE) ||
+ (tmp->type == XML_CDATA_SECTION_NODE) ||
+ (tmp->type == XML_ENTITY_REF_NODE)) {
+ ctxt->format = 0;
+ unformattedNode = cur;
+ break;
+ }
+ tmp = tmp->next;
+ }
+ }
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 1);
+ xmlOutputBufferWrite(buf, 1, ">");
+ if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
+ if (ctxt->level >= 0) ctxt->level++;
+ parent = cur;
+ cur = cur->children;
+ continue;
+ }
+
+ break;
+
+ case XML_TEXT_NODE:
+ if (cur->content == NULL)
+ break;
if (cur->name != xmlStringTextNoenc) {
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
} else {
@@ -952,139 +974,136 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
*/
xmlOutputBufferWriteString(buf, (const char *) cur->content);
}
- }
+ break;
- return;
- }
- if (cur->type == XML_PI_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWrite(buf, 2, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->content != NULL) {
- if (ctxt->format == 2)
- xmlOutputBufferWriteWSNonSig(ctxt, 0);
- else
- xmlOutputBufferWrite(buf, 1, " ");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- xmlOutputBufferWrite(buf, 2, "?>");
- } else {
- xmlOutputBufferWrite(buf, 2, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (ctxt->format == 2)
- xmlOutputBufferWriteWSNonSig(ctxt, 0);
- xmlOutputBufferWrite(buf, 2, "?>");
- }
- return;
- }
- if (cur->type == XML_COMMENT_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWrite(buf, 4, "<!--");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWrite(buf, 3, "-->");
- }
- return;
- }
- if (cur->type == XML_ENTITY_REF_NODE) {
- xmlOutputBufferWrite(buf, 1, "&");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWrite(buf, 1, ";");
- return;
- }
- if (cur->type == XML_CDATA_SECTION_NODE) {
- if (cur->content == NULL || *cur->content == '\0') {
- xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
- } else {
- start = end = cur->content;
- while (*end != '\0') {
- if ((*end == ']') && (*(end + 1) == ']') &&
- (*(end + 2) == '>')) {
- end = end + 2;
- xmlOutputBufferWrite(buf, 9, "<![CDATA[");
- xmlOutputBufferWrite(buf, end - start, (const char *)start);
- xmlOutputBufferWrite(buf, 3, "]]>");
- start = end;
- }
- end++;
- }
- if (start != end) {
- xmlOutputBufferWrite(buf, 9, "<![CDATA[");
- xmlOutputBufferWriteString(buf, (const char *)start);
- xmlOutputBufferWrite(buf, 3, "]]>");
- }
- }
- return;
- }
- if (cur->type == XML_ATTRIBUTE_NODE) {
- xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
- return;
- }
- if (cur->type == XML_NAMESPACE_DECL) {
- xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
- return;
- }
+ case XML_PI_NODE:
+ if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput))
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level),
+ ctxt->indent);
+
+ if (cur->content != NULL) {
+ xmlOutputBufferWrite(buf, 2, "<?");
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (cur->content != NULL) {
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
+ else
+ xmlOutputBufferWrite(buf, 1, " ");
+ xmlOutputBufferWriteString(buf,
+ (const char *)cur->content);
+ }
+ xmlOutputBufferWrite(buf, 2, "?>");
+ } else {
+ xmlOutputBufferWrite(buf, 2, "<?");
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
+ xmlOutputBufferWrite(buf, 2, "?>");
+ }
+ break;
+
+ case XML_COMMENT_NODE:
+ if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput))
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level),
+ ctxt->indent);
+
+ if (cur->content != NULL) {
+ xmlOutputBufferWrite(buf, 4, "<!--");
+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
+ xmlOutputBufferWrite(buf, 3, "-->");
+ }
+ break;
+
+ case XML_ENTITY_REF_NODE:
+ xmlOutputBufferWrite(buf, 1, "&");
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ xmlOutputBufferWrite(buf, 1, ";");
+ break;
+
+ case XML_CDATA_SECTION_NODE:
+ if (cur->content == NULL || *cur->content == '\0') {
+ xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
+ } else {
+ start = end = cur->content;
+ while (*end != '\0') {
+ if ((*end == ']') && (*(end + 1) == ']') &&
+ (*(end + 2) == '>')) {
+ end = end + 2;
+ xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+ xmlOutputBufferWrite(buf, end - start,
+ (const char *)start);
+ xmlOutputBufferWrite(buf, 3, "]]>");
+ start = end;
+ }
+ end++;
+ }
+ if (start != end) {
+ xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+ xmlOutputBufferWriteString(buf, (const char *)start);
+ xmlOutputBufferWrite(buf, 3, "]]>");
+ }
+ }
+ break;
- format = ctxt->format;
- if (format == 1) {
- tmp = cur->children;
- while (tmp != NULL) {
- if ((tmp->type == XML_TEXT_NODE) ||
- (tmp->type == XML_CDATA_SECTION_NODE) ||
- (tmp->type == XML_ENTITY_REF_NODE)) {
- ctxt->format = 0;
- break;
- }
- tmp = tmp->next;
- }
- }
- xmlOutputBufferWrite(buf, 1, "<");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWrite(buf, 1, ":");
- }
+ case XML_ATTRIBUTE_NODE:
+ xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
+ break;
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->nsDef)
- xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
- if (cur->properties != NULL)
- xmlAttrListDumpOutput(ctxt, cur->properties);
-
- if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
- (cur->children == NULL) && ((ctxt->options & XML_SAVE_NO_EMPTY) == 0)) {
- if (ctxt->format == 2)
- xmlOutputBufferWriteWSNonSig(ctxt, 0);
- xmlOutputBufferWrite(buf, 2, "/>");
- ctxt->format = format;
- return;
- }
- if (ctxt->format == 2)
- xmlOutputBufferWriteWSNonSig(ctxt, 1);
- xmlOutputBufferWrite(buf, 1, ">");
- if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
- xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
- }
- if (cur->children != NULL) {
- if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
- if (ctxt->level >= 0) ctxt->level++;
- xmlNodeListDumpOutput(ctxt, cur->children);
- if (ctxt->level > 0) ctxt->level--;
- if ((xmlIndentTreeOutput) && (ctxt->format == 1))
- xmlOutputBufferWrite(buf, ctxt->indent_size *
- (ctxt->level > ctxt->indent_nr ?
- ctxt->indent_nr : ctxt->level),
- ctxt->indent);
- }
- xmlOutputBufferWrite(buf, 2, "</");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWrite(buf, 1, ":");
- }
+ case XML_NAMESPACE_DECL:
+ xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
+ break;
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (ctxt->format == 2)
- xmlOutputBufferWriteWSNonSig(ctxt, 0);
- xmlOutputBufferWrite(buf, 1, ">");
- ctxt->format = format;
+ default:
+ break;
+ }
+
+ while (1) {
+ if (cur == root)
+ return;
+ if ((ctxt->format == 1) &&
+ (cur->type != XML_XINCLUDE_START) &&
+ (cur->type != XML_XINCLUDE_END))
+ xmlOutputBufferWrite(buf, 1, "\n");
+ if (cur->next != NULL) {
+ cur = cur->next;
+ break;
+ }
+
+ cur = parent;
+ /* cur->parent was validated when descending. */
+ parent = cur->parent;
+
+ if (cur->type == XML_ELEMENT_NODE) {
+ if (ctxt->level > 0) ctxt->level--;
+ if ((xmlIndentTreeOutput) && (ctxt->format == 1))
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level),
+ ctxt->indent);
+
+ xmlOutputBufferWrite(buf, 2, "</");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlOutputBufferWriteString(buf,
+ (const char *)cur->ns->prefix);
+ xmlOutputBufferWrite(buf, 1, ":");
+ }
+
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
+ xmlOutputBufferWrite(buf, 1, ">");
+
+ if (cur == unformattedNode) {
+ ctxt->format = format;
+ unformattedNode = NULL;
+ }
+ }
+ }
+ }
}
/**
@@ -1224,7 +1243,9 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
else
#endif
xmlNodeDumpOutputInternal(ctxt, child);
- xmlOutputBufferWrite(buf, 1, "\n");
+ if ((child->type != XML_XINCLUDE_START) &&
+ (child->type != XML_XINCLUDE_END))
+ xmlOutputBufferWrite(buf, 1, "\n");
child = child->next;
}
}
@@ -1396,40 +1417,6 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
}
/**
- * xhtmlNodeListDumpOutput:
- * @buf: the XML buffer output
- * @doc: the XHTML document
- * @cur: the first node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- * @encoding: an optional encoding string
- *
- * Dump an XML node list, recursive behaviour, children are printed too.
- * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-static void
-xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
- xmlOutputBufferPtr buf;
-
- if (cur == NULL) return;
- buf = ctxt->buf;
- while (cur != NULL) {
- if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
- (cur->type == XML_ELEMENT_NODE))
- xmlOutputBufferWrite(buf, ctxt->indent_size *
- (ctxt->level > ctxt->indent_nr ?
- ctxt->indent_nr : ctxt->level),
- ctxt->indent);
- xhtmlNodeDumpOutput(ctxt, cur);
- if (ctxt->format == 1) {
- xmlOutputBufferWrite(buf, 1, "\n");
- }
- cur = cur->next;
- }
-}
-
-/**
* xhtmlNodeDumpOutput:
* @buf: the XML buffer output
* @doc: the XHTML document
@@ -1442,48 +1429,195 @@ xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
*/
static void
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
- int format, addmeta = 0;
- xmlNodePtr tmp;
+ int format = ctxt->format, addmeta;
+ xmlNodePtr tmp, root, unformattedNode = NULL;
xmlChar *start, *end;
- xmlOutputBufferPtr buf;
+ xmlOutputBufferPtr buf = ctxt->buf;
if (cur == NULL) return;
- if ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
- return;
- }
- if (cur->type == XML_XINCLUDE_START)
- return;
- if (cur->type == XML_XINCLUDE_END)
- return;
- if (cur->type == XML_NAMESPACE_DECL) {
- xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
- return;
- }
- if (cur->type == XML_DTD_NODE) {
- xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
- return;
- }
- if (cur->type == XML_DOCUMENT_FRAG_NODE) {
- xhtmlNodeListDumpOutput(ctxt, cur->children);
- return;
- }
- buf = ctxt->buf;
- if (cur->type == XML_ELEMENT_DECL) {
- xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
- return;
- }
- if (cur->type == XML_ATTRIBUTE_DECL) {
- xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
- return;
- }
- if (cur->type == XML_ENTITY_DECL) {
- xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
- return;
- }
- if (cur->type == XML_TEXT_NODE) {
- if (cur->content != NULL) {
+
+ root = cur;
+ while (1) {
+ switch (cur->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
+ break;
+
+ case XML_NAMESPACE_DECL:
+ xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
+ break;
+
+ case XML_DTD_NODE:
+ xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
+ break;
+
+ case XML_DOCUMENT_FRAG_NODE:
+ if (cur->children) {
+ cur = cur->children;
+ continue;
+ }
+ break;
+
+ case XML_ELEMENT_DECL:
+ xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
+ break;
+
+ case XML_ATTRIBUTE_DECL:
+ xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
+ break;
+
+ case XML_ENTITY_DECL:
+ xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
+ break;
+
+ case XML_ELEMENT_NODE:
+ addmeta = 0;
+
+ if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput))
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level),
+ ctxt->indent);
+
+ xmlOutputBufferWrite(buf, 1, "<");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+ xmlOutputBufferWrite(buf, 1, ":");
+ }
+
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (cur->nsDef)
+ xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
+ if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
+ (cur->ns == NULL) && (cur->nsDef == NULL))) {
+ /*
+ * 3.1.1. Strictly Conforming Documents A.3.1.1 3/
+ */
+ xmlOutputBufferWriteString(buf,
+ " xmlns=\"http://www.w3.org/1999/xhtml\"");
+ }
+ if (cur->properties != NULL)
+ xhtmlAttrListDumpOutput(ctxt, cur->properties);
+
+ if ((cur->parent != NULL) &&
+ (cur->parent->parent == (xmlNodePtr) cur->doc) &&
+ xmlStrEqual(cur->name, BAD_CAST"head") &&
+ xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
+
+ tmp = cur->children;
+ while (tmp != NULL) {
+ if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
+ xmlChar *httpequiv;
+
+ httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
+ if (httpequiv != NULL) {
+ if (xmlStrcasecmp(httpequiv,
+ BAD_CAST"Content-Type") == 0) {
+ xmlFree(httpequiv);
+ break;
+ }
+ xmlFree(httpequiv);
+ }
+ }
+ tmp = tmp->next;
+ }
+ if (tmp == NULL)
+ addmeta = 1;
+ }
+
+ if (cur->children == NULL) {
+ if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
+ ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
+ /*
+ * C.2. Empty Elements
+ */
+ xmlOutputBufferWrite(buf, 3, " />");
+ } else {
+ if (addmeta == 1) {
+ xmlOutputBufferWrite(buf, 1, ">");
+ if (ctxt->format == 1) {
+ xmlOutputBufferWrite(buf, 1, "\n");
+ if (xmlIndentTreeOutput)
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level + 1 > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level + 1),
+ ctxt->indent);
+ }
+ xmlOutputBufferWriteString(buf,
+ "<meta http-equiv=\"Content-Type\" "
+ "content=\"text/html; charset=");
+ if (ctxt->encoding) {
+ xmlOutputBufferWriteString(buf,
+ (const char *)ctxt->encoding);
+ } else {
+ xmlOutputBufferWrite(buf, 5, "UTF-8");
+ }
+ xmlOutputBufferWrite(buf, 4, "\" />");
+ if (ctxt->format == 1)
+ xmlOutputBufferWrite(buf, 1, "\n");
+ } else {
+ xmlOutputBufferWrite(buf, 1, ">");
+ }
+ /*
+ * C.3. Element Minimization and Empty Element Content
+ */
+ xmlOutputBufferWrite(buf, 2, "</");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlOutputBufferWriteString(buf,
+ (const char *)cur->ns->prefix);
+ xmlOutputBufferWrite(buf, 1, ":");
+ }
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ xmlOutputBufferWrite(buf, 1, ">");
+ }
+ } else {
+ xmlOutputBufferWrite(buf, 1, ">");
+ if (addmeta == 1) {
+ if (ctxt->format == 1) {
+ xmlOutputBufferWrite(buf, 1, "\n");
+ if (xmlIndentTreeOutput)
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level + 1 > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level + 1),
+ ctxt->indent);
+ }
+ xmlOutputBufferWriteString(buf,
+ "<meta http-equiv=\"Content-Type\" "
+ "content=\"text/html; charset=");
+ if (ctxt->encoding) {
+ xmlOutputBufferWriteString(buf,
+ (const char *)ctxt->encoding);
+ } else {
+ xmlOutputBufferWrite(buf, 5, "UTF-8");
+ }
+ xmlOutputBufferWrite(buf, 4, "\" />");
+ }
+
+ if (ctxt->format == 1) {
+ tmp = cur->children;
+ while (tmp != NULL) {
+ if ((tmp->type == XML_TEXT_NODE) ||
+ (tmp->type == XML_ENTITY_REF_NODE)) {
+ unformattedNode = cur;
+ ctxt->format = 0;
+ break;
+ }
+ tmp = tmp->next;
+ }
+ }
+
+ if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
+ if (ctxt->level >= 0) ctxt->level++;
+ cur = cur->children;
+ continue;
+ }
+
+ break;
+
+ case XML_TEXT_NODE:
+ if (cur->content == NULL)
+ break;
if ((cur->name == xmlStringText) ||
(cur->name != xmlStringTextNoenc)) {
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
@@ -1493,286 +1627,115 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
*/
xmlOutputBufferWriteString(buf, (const char *) cur->content);
}
- }
-
- return;
- }
- if (cur->type == XML_PI_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWrite(buf, 2, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->content != NULL) {
- xmlOutputBufferWrite(buf, 1, " ");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- xmlOutputBufferWrite(buf, 2, "?>");
- } else {
- xmlOutputBufferWrite(buf, 2, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWrite(buf, 2, "?>");
- }
- return;
- }
- if (cur->type == XML_COMMENT_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWrite(buf, 4, "<!--");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWrite(buf, 3, "-->");
- }
- return;
- }
- if (cur->type == XML_ENTITY_REF_NODE) {
- xmlOutputBufferWrite(buf, 1, "&");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWrite(buf, 1, ";");
- return;
- }
- if (cur->type == XML_CDATA_SECTION_NODE) {
- if (cur->content == NULL || *cur->content == '\0') {
- xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
- } else {
- start = end = cur->content;
- while (*end != '\0') {
- if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') {
- end = end + 2;
- xmlOutputBufferWrite(buf, 9, "<![CDATA[");
- xmlOutputBufferWrite(buf, end - start, (const char *)start);
- xmlOutputBufferWrite(buf, 3, "]]>");
- start = end;
- }
- end++;
- }
- if (start != end) {
- xmlOutputBufferWrite(buf, 9, "<![CDATA[");
- xmlOutputBufferWriteString(buf, (const char *)start);
- xmlOutputBufferWrite(buf, 3, "]]>");
- }
- }
- return;
- }
- if (cur->type == XML_ATTRIBUTE_NODE) {
- xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
- return;
- }
+ break;
- format = ctxt->format;
- if (format == 1) {
- tmp = cur->children;
- while (tmp != NULL) {
- if ((tmp->type == XML_TEXT_NODE) ||
- (tmp->type == XML_ENTITY_REF_NODE)) {
- format = 0;
- break;
- }
- tmp = tmp->next;
- }
- }
- xmlOutputBufferWrite(buf, 1, "<");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWrite(buf, 1, ":");
- }
+ case XML_PI_NODE:
+ if (cur->content != NULL) {
+ xmlOutputBufferWrite(buf, 2, "<?");
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (cur->content != NULL) {
+ xmlOutputBufferWrite(buf, 1, " ");
+ xmlOutputBufferWriteString(buf,
+ (const char *)cur->content);
+ }
+ xmlOutputBufferWrite(buf, 2, "?>");
+ } else {
+ xmlOutputBufferWrite(buf, 2, "<?");
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ xmlOutputBufferWrite(buf, 2, "?>");
+ }
+ break;
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->nsDef)
- xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
- if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
- (cur->ns == NULL) && (cur->nsDef == NULL))) {
- /*
- * 3.1.1. Strictly Conforming Documents A.3.1.1 3/
- */
- xmlOutputBufferWriteString(buf,
- " xmlns=\"http://www.w3.org/1999/xhtml\"");
- }
- if (cur->properties != NULL)
- xhtmlAttrListDumpOutput(ctxt, cur->properties);
-
- if ((cur->type == XML_ELEMENT_NODE) &&
- (cur->parent != NULL) &&
- (cur->parent->parent == (xmlNodePtr) cur->doc) &&
- xmlStrEqual(cur->name, BAD_CAST"head") &&
- xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
-
- tmp = cur->children;
- while (tmp != NULL) {
- if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
- xmlChar *httpequiv;
-
- httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
- if (httpequiv != NULL) {
- if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) {
- xmlFree(httpequiv);
- break;
+ case XML_COMMENT_NODE:
+ if (cur->content != NULL) {
+ xmlOutputBufferWrite(buf, 4, "<!--");
+ xmlOutputBufferWriteString(buf, (const char *)cur->content);
+ xmlOutputBufferWrite(buf, 3, "-->");
+ }
+ break;
+
+ case XML_ENTITY_REF_NODE:
+ xmlOutputBufferWrite(buf, 1, "&");
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ xmlOutputBufferWrite(buf, 1, ";");
+ break;
+
+ case XML_CDATA_SECTION_NODE:
+ if (cur->content == NULL || *cur->content == '\0') {
+ xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
+ } else {
+ start = end = cur->content;
+ while (*end != '\0') {
+ if (*end == ']' && *(end + 1) == ']' &&
+ *(end + 2) == '>') {
+ end = end + 2;
+ xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+ xmlOutputBufferWrite(buf, end - start,
+ (const char *)start);
+ xmlOutputBufferWrite(buf, 3, "]]>");
+ start = end;
}
- xmlFree(httpequiv);
+ end++;
+ }
+ if (start != end) {
+ xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+ xmlOutputBufferWriteString(buf, (const char *)start);
+ xmlOutputBufferWrite(buf, 3, "]]>");
}
}
- tmp = tmp->next;
+ break;
+
+ case XML_ATTRIBUTE_NODE:
+ xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
+ break;
+
+ default:
+ break;
}
- if (tmp == NULL)
- addmeta = 1;
- }
- if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
- if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
- ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
- /*
- * C.2. Empty Elements
- */
- xmlOutputBufferWrite(buf, 3, " />");
- } else {
- if (addmeta == 1) {
- xmlOutputBufferWrite(buf, 1, ">");
- if (ctxt->format == 1) {
- xmlOutputBufferWrite(buf, 1, "\n");
- if (xmlIndentTreeOutput)
- xmlOutputBufferWrite(buf, ctxt->indent_size *
- (ctxt->level + 1 > ctxt->indent_nr ?
- ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
- }
- xmlOutputBufferWriteString(buf,
- "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
- if (ctxt->encoding) {
- xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
- } else {
- xmlOutputBufferWrite(buf, 5, "UTF-8");
- }
- xmlOutputBufferWrite(buf, 4, "\" />");
- if (ctxt->format == 1)
- xmlOutputBufferWrite(buf, 1, "\n");
- } else {
- xmlOutputBufferWrite(buf, 1, ">");
- }
- /*
- * C.3. Element Minimization and Empty Element Content
- */
- xmlOutputBufferWrite(buf, 2, "</");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWrite(buf, 1, ":");
- }
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWrite(buf, 1, ">");
- }
- return;
- }
- xmlOutputBufferWrite(buf, 1, ">");
- if (addmeta == 1) {
- if (ctxt->format == 1) {
- xmlOutputBufferWrite(buf, 1, "\n");
- if (xmlIndentTreeOutput)
- xmlOutputBufferWrite(buf, ctxt->indent_size *
- (ctxt->level + 1 > ctxt->indent_nr ?
- ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
- }
- xmlOutputBufferWriteString(buf,
- "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
- if (ctxt->encoding) {
- xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
- } else {
- xmlOutputBufferWrite(buf, 5, "UTF-8");
- }
- xmlOutputBufferWrite(buf, 4, "\" />");
- }
- if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
- xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
- }
+ while (1) {
+ if (cur == root)
+ return;
+ if (ctxt->format == 1)
+ xmlOutputBufferWrite(buf, 1, "\n");
+ if (cur->next != NULL) {
+ cur = cur->next;
+ break;
+ }
-#if 0
- /*
- * This was removed due to problems with HTML processors.
- * See bug #345147.
- */
- /*
- * 4.8. Script and Style elements
- */
- if ((cur->type == XML_ELEMENT_NODE) &&
- ((xmlStrEqual(cur->name, BAD_CAST "script")) ||
- (xmlStrEqual(cur->name, BAD_CAST "style"))) &&
- ((cur->ns == NULL) ||
- (xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) {
- xmlNodePtr child = cur->children;
-
- while (child != NULL) {
- if (child->type == XML_TEXT_NODE) {
- if ((xmlStrchr(child->content, '<') == NULL) &&
- (xmlStrchr(child->content, '&') == NULL) &&
- (xmlStrstr(child->content, BAD_CAST "]]>") == NULL)) {
- /* Nothing to escape, so just output as is... */
- /* FIXME: Should we do something about "--" also? */
- int level = ctxt->level;
- int indent = ctxt->format;
-
- ctxt->level = 0;
- ctxt->format = 0;
- xmlOutputBufferWriteString(buf, (const char *) child->content);
- /* (We cannot use xhtmlNodeDumpOutput() here because
- * we wish to leave '>' unescaped!) */
- ctxt->level = level;
- ctxt->format = indent;
- } else {
- /* We must use a CDATA section. Unfortunately,
- * this will break CSS and JavaScript when read by
- * a browser in HTML4-compliant mode. :-( */
- start = end = child->content;
- while (*end != '\0') {
- if (*end == ']' &&
- *(end + 1) == ']' &&
- *(end + 2) == '>') {
- end = end + 2;
- xmlOutputBufferWrite(buf, 9, "<![CDATA[");
- xmlOutputBufferWrite(buf, end - start,
- (const char *)start);
- xmlOutputBufferWrite(buf, 3, "]]>");
- start = end;
- }
- end++;
- }
- if (start != end) {
- xmlOutputBufferWrite(buf, 9, "<![CDATA[");
- xmlOutputBufferWrite(buf, end - start,
- (const char *)start);
- xmlOutputBufferWrite(buf, 3, "]]>");
- }
- }
- } else {
- int level = ctxt->level;
- int indent = ctxt->format;
+ /*
+ * The parent should never be NULL here but we want to handle
+ * corrupted documents gracefully.
+ */
+ if (cur->parent == NULL)
+ return;
+ cur = cur->parent;
+
+ if (cur->type == XML_ELEMENT_NODE) {
+ if (ctxt->level > 0) ctxt->level--;
+ if ((xmlIndentTreeOutput) && (ctxt->format == 1))
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
+ (ctxt->level > ctxt->indent_nr ?
+ ctxt->indent_nr : ctxt->level),
+ ctxt->indent);
+
+ xmlOutputBufferWrite(buf, 2, "</");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlOutputBufferWriteString(buf,
+ (const char *)cur->ns->prefix);
+ xmlOutputBufferWrite(buf, 1, ":");
+ }
- ctxt->level = 0;
- ctxt->format = 0;
- xhtmlNodeDumpOutput(ctxt, child);
- ctxt->level = level;
- ctxt->format = indent;
- }
- child = child->next;
- }
- }
-#endif
+ xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ xmlOutputBufferWrite(buf, 1, ">");
- if (cur->children != NULL) {
- int indent = ctxt->format;
-
- if (format == 1) xmlOutputBufferWrite(buf, 1, "\n");
- if (ctxt->level >= 0) ctxt->level++;
- ctxt->format = format;
- xhtmlNodeListDumpOutput(ctxt, cur->children);
- if (ctxt->level > 0) ctxt->level--;
- ctxt->format = indent;
- if ((xmlIndentTreeOutput) && (format == 1))
- xmlOutputBufferWrite(buf, ctxt->indent_size *
- (ctxt->level > ctxt->indent_nr ?
- ctxt->indent_nr : ctxt->level),
- ctxt->indent);
- }
- xmlOutputBufferWrite(buf, 2, "</");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWrite(buf, 1, ":");
+ if (cur == unformattedNode) {
+ ctxt->format = format;
+ unformattedNode = NULL;
+ }
+ }
+ }
}
-
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWrite(buf, 1, ">");
}
#endif
@@ -1802,6 +1765,7 @@ xmlSaveToFd(int fd, const char *encoding, int options)
if (ret == NULL) return(NULL);
ret->buf = xmlOutputBufferCreateFd(fd, ret->handler);
if (ret->buf == NULL) {
+ xmlCharEncCloseFunc(ret->handler);
xmlFreeSaveCtxt(ret);
return(NULL);
}
@@ -1831,6 +1795,7 @@ xmlSaveToFilename(const char *filename, const char *encoding, int options)
ret->buf = xmlOutputBufferCreateFilename(filename, ret->handler,
compression);
if (ret->buf == NULL) {
+ xmlCharEncCloseFunc(ret->handler);
xmlFreeSaveCtxt(ret);
return(NULL);
}
@@ -1853,28 +1818,15 @@ xmlSaveCtxtPtr
xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options)
{
xmlSaveCtxtPtr ret;
- xmlOutputBufferPtr out_buff;
- xmlCharEncodingHandlerPtr handler;
ret = xmlNewSaveCtxt(encoding, options);
if (ret == NULL) return(NULL);
-
- if (encoding != NULL) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL) {
- xmlFree(ret);
- return(NULL);
- }
- } else
- handler = NULL;
- out_buff = xmlOutputBufferCreateBuffer(buffer, handler);
- if (out_buff == NULL) {
- xmlFree(ret);
- if (handler) xmlCharEncCloseFunc(handler);
- return(NULL);
+ ret->buf = xmlOutputBufferCreateBuffer(buffer, ret->handler);
+ if (ret->buf == NULL) {
+ xmlCharEncCloseFunc(ret->handler);
+ xmlFreeSaveCtxt(ret);
+ return(NULL);
}
-
- ret->buf = out_buff;
return(ret);
}
@@ -1902,6 +1854,7 @@ xmlSaveToIO(xmlOutputWriteCallback iowrite,
if (ret == NULL) return(NULL);
ret->buf = xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, ret->handler);
if (ret->buf == NULL) {
+ xmlCharEncCloseFunc(ret->handler);
xmlFreeSaveCtxt(ret);
return(NULL);
}
@@ -1942,12 +1895,25 @@ xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
* Returns the number of byte written or -1 in case of error
*/
long
-xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node)
+xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr cur)
{
long ret = 0;
- if ((ctxt == NULL) || (node == NULL)) return(-1);
- xmlNodeDumpOutputInternal(ctxt, node);
+ if ((ctxt == NULL) || (cur == NULL)) return(-1);
+#ifdef LIBXML_HTML_ENABLED
+ if (ctxt->options & XML_SAVE_XHTML) {
+ xhtmlNodeDumpOutput(ctxt, cur);
+ return(ret);
+ }
+ if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) &&
+ (cur->doc->type == XML_HTML_DOCUMENT_NODE) &&
+ ((ctxt->options & XML_SAVE_AS_XML) == 0)) ||
+ (ctxt->options & XML_SAVE_AS_HTML)) {
+ htmlNodeDumpOutputInternal(ctxt, cur);
+ return(ret);
+ }
+#endif
+ xmlNodeDumpOutputInternal(ctxt, cur);
return(ret);
}
@@ -2197,7 +2163,7 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
int format)
{
xmlBufPtr buffer;
- int ret;
+ size_t ret;
if ((buf == NULL) || (cur == NULL))
return(-1);