Blame HTMLtree.c

Packit Service a31ea6
/*
Packit Service a31ea6
 * HTMLtree.c : implementation of access function for an HTML tree.
Packit Service a31ea6
 *
Packit Service a31ea6
 * See Copyright for the status of this software.
Packit Service a31ea6
 *
Packit Service a31ea6
 * daniel@veillard.com
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
#define IN_LIBXML
Packit Service a31ea6
#include "libxml.h"
Packit Service a31ea6
#ifdef LIBXML_HTML_ENABLED
Packit Service a31ea6
Packit Service a31ea6
#include <string.h> /* for memset() only ! */
Packit Service a31ea6
Packit Service a31ea6
#ifdef HAVE_CTYPE_H
Packit Service a31ea6
#include <ctype.h>
Packit Service a31ea6
#endif
Packit Service a31ea6
#ifdef HAVE_STDLIB_H
Packit Service a31ea6
#include <stdlib.h>
Packit Service a31ea6
#endif
Packit Service a31ea6
Packit Service a31ea6
#include <libxml/xmlmemory.h>
Packit Service a31ea6
#include <libxml/HTMLparser.h>
Packit Service a31ea6
#include <libxml/HTMLtree.h>
Packit Service a31ea6
#include <libxml/entities.h>
Packit Service a31ea6
#include <libxml/valid.h>
Packit Service a31ea6
#include <libxml/xmlerror.h>
Packit Service a31ea6
#include <libxml/parserInternals.h>
Packit Service a31ea6
#include <libxml/globals.h>
Packit Service a31ea6
#include <libxml/uri.h>
Packit Service a31ea6
Packit Service a31ea6
#include "buf.h"
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Getting/Setting encoding meta tags			*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlGetMetaEncoding:
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 *
Packit Service a31ea6
 * Encoding definition lookup in the Meta tags
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the current encoding as flagged in the HTML source
Packit Service a31ea6
 */
Packit Service a31ea6
const xmlChar *
Packit Service a31ea6
htmlGetMetaEncoding(htmlDocPtr doc) {
Packit Service a31ea6
    htmlNodePtr cur;
Packit Service a31ea6
    const xmlChar *content;
Packit Service a31ea6
    const xmlChar *encoding;
Packit Service a31ea6
Packit Service a31ea6
    if (doc == NULL)
Packit Service a31ea6
	return(NULL);
Packit Service a31ea6
    cur = doc->children;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Search the html
Packit Service a31ea6
     */
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
Packit Service a31ea6
	    if (xmlStrEqual(cur->name, BAD_CAST"html"))
Packit Service a31ea6
		break;
Packit Service a31ea6
	    if (xmlStrEqual(cur->name, BAD_CAST"head"))
Packit Service a31ea6
		goto found_head;
Packit Service a31ea6
	    if (xmlStrEqual(cur->name, BAD_CAST"meta"))
Packit Service a31ea6
		goto found_meta;
Packit Service a31ea6
	}
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur == NULL)
Packit Service a31ea6
	return(NULL);
Packit Service a31ea6
    cur = cur->children;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Search the head
Packit Service a31ea6
     */
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
Packit Service a31ea6
	    if (xmlStrEqual(cur->name, BAD_CAST"head"))
Packit Service a31ea6
		break;
Packit Service a31ea6
	    if (xmlStrEqual(cur->name, BAD_CAST"meta"))
Packit Service a31ea6
		goto found_meta;
Packit Service a31ea6
	}
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur == NULL)
Packit Service a31ea6
	return(NULL);
Packit Service a31ea6
found_head:
Packit Service a31ea6
    cur = cur->children;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Search the meta elements
Packit Service a31ea6
     */
Packit Service a31ea6
found_meta:
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
Packit Service a31ea6
	    if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
Packit Service a31ea6
		xmlAttrPtr attr = cur->properties;
Packit Service a31ea6
		int http;
Packit Service a31ea6
		const xmlChar *value;
Packit Service a31ea6
Packit Service a31ea6
		content = NULL;
Packit Service a31ea6
		http = 0;
Packit Service a31ea6
		while (attr != NULL) {
Packit Service a31ea6
		    if ((attr->children != NULL) &&
Packit Service a31ea6
		        (attr->children->type == XML_TEXT_NODE) &&
Packit Service a31ea6
		        (attr->children->next == NULL)) {
Packit Service a31ea6
			value = attr->children->content;
Packit Service a31ea6
			if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
Packit Service a31ea6
			 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
Packit Service a31ea6
			    http = 1;
Packit Service a31ea6
			else if ((value != NULL)
Packit Service a31ea6
			 && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
Packit Service a31ea6
			    content = value;
Packit Service a31ea6
			if ((http != 0) && (content != NULL))
Packit Service a31ea6
			    goto found_content;
Packit Service a31ea6
		    }
Packit Service a31ea6
		    attr = attr->next;
Packit Service a31ea6
		}
Packit Service a31ea6
	    }
Packit Service a31ea6
	}
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(NULL);
Packit Service a31ea6
Packit Service a31ea6
found_content:
Packit Service a31ea6
    encoding = xmlStrstr(content, BAD_CAST"charset=");
Packit Service a31ea6
    if (encoding == NULL)
Packit Service a31ea6
	encoding = xmlStrstr(content, BAD_CAST"Charset=");
Packit Service a31ea6
    if (encoding == NULL)
Packit Service a31ea6
	encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	encoding += 8;
Packit Service a31ea6
    } else {
Packit Service a31ea6
	encoding = xmlStrstr(content, BAD_CAST"charset =");
Packit Service a31ea6
	if (encoding == NULL)
Packit Service a31ea6
	    encoding = xmlStrstr(content, BAD_CAST"Charset =");
Packit Service a31ea6
	if (encoding == NULL)
Packit Service a31ea6
	    encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
Packit Service a31ea6
	if (encoding != NULL)
Packit Service a31ea6
	    encoding += 9;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(encoding);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlSetMetaEncoding:
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Sets the current encoding in the Meta tags
Packit Service a31ea6
 * NOTE: this will not change the document content encoding, just
Packit Service a31ea6
 * the META flag associated.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 0 in case of success and -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
Packit Service a31ea6
    htmlNodePtr cur, meta = NULL, head = NULL;
Packit Service a31ea6
    const xmlChar *content = NULL;
Packit Service a31ea6
    char newcontent[100];
Packit Service a31ea6
Packit Service a31ea6
    newcontent[0] = 0;
Packit Service a31ea6
Packit Service a31ea6
    if (doc == NULL)
Packit Service a31ea6
	return(-1);
Packit Service a31ea6
Packit Service a31ea6
    /* html isn't a real encoding it's just libxml2 way to get entities */
Packit Service a31ea6
    if (!xmlStrcasecmp(encoding, BAD_CAST "html"))
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
Packit Service a31ea6
                (char *)encoding);
Packit Service a31ea6
	newcontent[sizeof(newcontent) - 1] = 0;
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    cur = doc->children;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Search the html
Packit Service a31ea6
     */
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
Packit Service a31ea6
	    if (xmlStrcasecmp(cur->name, BAD_CAST"html") == 0)
Packit Service a31ea6
		break;
Packit Service a31ea6
	    if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
Packit Service a31ea6
		goto found_head;
Packit Service a31ea6
	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
Packit Service a31ea6
		goto found_meta;
Packit Service a31ea6
	}
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur == NULL)
Packit Service a31ea6
	return(-1);
Packit Service a31ea6
    cur = cur->children;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Search the head
Packit Service a31ea6
     */
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
Packit Service a31ea6
	    if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
Packit Service a31ea6
		break;
Packit Service a31ea6
	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
Packit Service a31ea6
                head = cur->parent;
Packit Service a31ea6
		goto found_meta;
Packit Service a31ea6
            }
Packit Service a31ea6
	}
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur == NULL)
Packit Service a31ea6
	return(-1);
Packit Service a31ea6
found_head:
Packit Service a31ea6
    head = cur;
Packit Service a31ea6
    if (cur->children == NULL)
Packit Service a31ea6
        goto create;
Packit Service a31ea6
    cur = cur->children;
Packit Service a31ea6
Packit Service a31ea6
found_meta:
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Search and update all the remaining the meta elements carrying
Packit Service a31ea6
     * encoding informations
Packit Service a31ea6
     */
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
Packit Service a31ea6
	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
Packit Service a31ea6
		xmlAttrPtr attr = cur->properties;
Packit Service a31ea6
		int http;
Packit Service a31ea6
		const xmlChar *value;
Packit Service a31ea6
Packit Service a31ea6
		content = NULL;
Packit Service a31ea6
		http = 0;
Packit Service a31ea6
		while (attr != NULL) {
Packit Service a31ea6
		    if ((attr->children != NULL) &&
Packit Service a31ea6
		        (attr->children->type == XML_TEXT_NODE) &&
Packit Service a31ea6
		        (attr->children->next == NULL)) {
Packit Service a31ea6
			value = attr->children->content;
Packit Service a31ea6
			if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
Packit Service a31ea6
			 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
Packit Service a31ea6
			    http = 1;
Packit Service a31ea6
			else
Packit Service a31ea6
                        {
Packit Service a31ea6
                           if ((value != NULL) &&
Packit Service a31ea6
                               (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
Packit Service a31ea6
			       content = value;
Packit Service a31ea6
                        }
Packit Service a31ea6
		        if ((http != 0) && (content != NULL))
Packit Service a31ea6
			    break;
Packit Service a31ea6
		    }
Packit Service a31ea6
		    attr = attr->next;
Packit Service a31ea6
		}
Packit Service a31ea6
		if ((http != 0) && (content != NULL)) {
Packit Service a31ea6
		    meta = cur;
Packit Service a31ea6
		    break;
Packit Service a31ea6
		}
Packit Service a31ea6
Packit Service a31ea6
	    }
Packit Service a31ea6
	}
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
create:
Packit Service a31ea6
    if (meta == NULL) {
Packit Service a31ea6
        if ((encoding != NULL) && (head != NULL)) {
Packit Service a31ea6
            /*
Packit Service a31ea6
             * Create a new Meta element with the right attributes
Packit Service a31ea6
             */
Packit Service a31ea6
Packit Service a31ea6
            meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
Packit Service a31ea6
            if (head->children == NULL)
Packit Service a31ea6
                xmlAddChild(head, meta);
Packit Service a31ea6
            else
Packit Service a31ea6
                xmlAddPrevSibling(head->children, meta);
Packit Service a31ea6
            xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
Packit Service a31ea6
            xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
Packit Service a31ea6
        }
Packit Service a31ea6
    } else {
Packit Service a31ea6
        /* remove the meta tag if NULL is passed */
Packit Service a31ea6
        if (encoding == NULL) {
Packit Service a31ea6
            xmlUnlinkNode(meta);
Packit Service a31ea6
            xmlFreeNode(meta);
Packit Service a31ea6
        }
Packit Service a31ea6
        /* change the document only if there is a real encoding change */
Packit Service a31ea6
        else if (xmlStrcasestr(content, encoding) == NULL) {
Packit Service a31ea6
            xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent);
Packit Service a31ea6
        }
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
    return(0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * booleanHTMLAttrs:
Packit Service a31ea6
 *
Packit Service a31ea6
 * These are the HTML attributes which will be output
Packit Service a31ea6
 * in minimized form, i.e. <option selected="selected"> will be
Packit Service a31ea6
 * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method"
Packit Service a31ea6
 *
Packit Service a31ea6
 */
Packit Service a31ea6
static const char* htmlBooleanAttrs[] = {
Packit Service a31ea6
  "checked", "compact", "declare", "defer", "disabled", "ismap",
Packit Service a31ea6
  "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
Packit Service a31ea6
  "selected", NULL
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlIsBooleanAttr:
Packit Service a31ea6
 * @name:  the name of the attribute to check
Packit Service a31ea6
 *
Packit Service a31ea6
 * Determine if a given attribute is a boolean attribute.
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns: false if the attribute is not boolean, true otherwise.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlIsBooleanAttr(const xmlChar *name)
Packit Service a31ea6
{
Packit Service a31ea6
    int i = 0;
Packit Service a31ea6
Packit Service a31ea6
    while (htmlBooleanAttrs[i] != NULL) {
Packit Service a31ea6
        if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0)
Packit Service a31ea6
            return 1;
Packit Service a31ea6
        i++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return 0;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
#ifdef LIBXML_OUTPUT_ENABLED
Packit Service a31ea6
/*
Packit Service a31ea6
 * private routine exported from xmlIO.c
Packit Service a31ea6
 */
Packit Service a31ea6
xmlOutputBufferPtr
Packit Service a31ea6
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *			Output error handlers				*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlSaveErrMemory:
Packit Service a31ea6
 * @extra:  extra informations
Packit Service a31ea6
 *
Packit Service a31ea6
 * Handle an out of memory condition
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
htmlSaveErrMemory(const char *extra)
Packit Service a31ea6
{
Packit Service a31ea6
    __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL, NULL, extra);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlSaveErr:
Packit Service a31ea6
 * @code:  the error number
Packit Service a31ea6
 * @node:  the location of the error.
Packit Service a31ea6
 * @extra:  extra informations
Packit Service a31ea6
 *
Packit Service a31ea6
 * Handle an out of memory condition
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
htmlSaveErr(int code, xmlNodePtr node, const char *extra)
Packit Service a31ea6
{
Packit Service a31ea6
    const char *msg = NULL;
Packit Service a31ea6
Packit Service a31ea6
    switch(code) {
Packit Service a31ea6
        case XML_SAVE_NOT_UTF8:
Packit Service a31ea6
	    msg = "string is not in UTF-8\n";
Packit Service a31ea6
	    break;
Packit Service a31ea6
	case XML_SAVE_CHAR_INVALID:
Packit Service a31ea6
	    msg = "invalid character value\n";
Packit Service a31ea6
	    break;
Packit Service a31ea6
	case XML_SAVE_UNKNOWN_ENCODING:
Packit Service a31ea6
	    msg = "unknown encoding %s\n";
Packit Service a31ea6
	    break;
Packit Service a31ea6
	case XML_SAVE_NO_DOCTYPE:
Packit Service a31ea6
	    msg = "HTML has no DOCTYPE\n";
Packit Service a31ea6
	    break;
Packit Service a31ea6
	default:
Packit Service a31ea6
	    msg = "unexpected error number\n";
Packit Service a31ea6
    }
Packit Service a31ea6
    __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Dumping HTML tree content to a simple buffer		*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlBufNodeDumpFormat:
Packit Service a31ea6
 * @buf:  the xmlBufPtr output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the current node
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node, recursive behaviour,children are printed too.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of byte written or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
static size_t
Packit Service a31ea6
htmlBufNodeDumpFormat(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur,
Packit Service a31ea6
	           int format) {
Packit Service a31ea6
    size_t use;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
    xmlOutputBufferPtr outbuf;
Packit Service a31ea6
Packit Service a31ea6
    if (cur == NULL) {
Packit Service a31ea6
	return (-1);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (buf == NULL) {
Packit Service a31ea6
	return (-1);
Packit Service a31ea6
    }
Packit Service a31ea6
    outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
Packit Service a31ea6
    if (outbuf == NULL) {
Packit Service a31ea6
        htmlSaveErrMemory("allocating HTML output buffer");
Packit Service a31ea6
	return (-1);
Packit Service a31ea6
    }
Packit Service a31ea6
    memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
Packit Service a31ea6
    outbuf->buffer = buf;
Packit Service a31ea6
    outbuf->encoder = NULL;
Packit Service a31ea6
    outbuf->writecallback = NULL;
Packit Service a31ea6
    outbuf->closecallback = NULL;
Packit Service a31ea6
    outbuf->context = NULL;
Packit Service a31ea6
    outbuf->written = 0;
Packit Service a31ea6
Packit Service a31ea6
    use = xmlBufUse(buf);
Packit Service a31ea6
    htmlNodeDumpFormatOutput(outbuf, doc, cur, NULL, format);
Packit Service a31ea6
    xmlFree(outbuf);
Packit Service a31ea6
    ret = xmlBufUse(buf) - use;
Packit Service a31ea6
    return (ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlNodeDump:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the current node
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node, recursive behaviour,children are printed too,
Packit Service a31ea6
 * and formatting returns are added.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of byte written or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
Packit Service a31ea6
    xmlBufPtr buffer;
Packit Service a31ea6
    size_t ret;
Packit Service a31ea6
Packit Service a31ea6
    if ((buf == NULL) || (cur == NULL))
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
    buffer = xmlBufFromBuffer(buf);
Packit Service a31ea6
    if (buffer == NULL)
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
Packit Service a31ea6
    ret = htmlBufNodeDumpFormat(buffer, doc, cur, 1);
Packit Service a31ea6
Packit Service a31ea6
    xmlBufBackToBuffer(buffer);
Packit Service a31ea6
Packit Service a31ea6
    if (ret > INT_MAX)
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
    return((int) ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlNodeDumpFileFormat:
Packit Service a31ea6
 * @out:  the FILE pointer
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the current node
Packit Service a31ea6
 * @encoding: the document encoding
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node, recursive behaviour,children are printed too.
Packit Service a31ea6
 *
Packit Service a31ea6
 * TODO: if encoding == NULL try to save in the doc encoding
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns: the number of byte written or -1 in case of failure.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
Packit Service a31ea6
	               xmlNodePtr cur, const char *encoding, int format) {
Packit Service a31ea6
    xmlOutputBufferPtr buf;
Packit Service a31ea6
    xmlCharEncodingHandlerPtr handler = NULL;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	xmlCharEncoding enc;
Packit Service a31ea6
Packit Service a31ea6
	enc = xmlParseCharEncoding(encoding);
Packit Service a31ea6
	if (enc != XML_CHAR_ENCODING_UTF8) {
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	    if (handler == NULL)
Packit Service a31ea6
		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
Packit Service a31ea6
	}
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Fallback to HTML or ASCII when the encoding is unspecified
Packit Service a31ea6
     */
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("HTML");
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("ascii");
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * save the content to a temp buffer.
Packit Service a31ea6
     */
Packit Service a31ea6
    buf = xmlOutputBufferCreateFile(out, handler);
Packit Service a31ea6
    if (buf == NULL) return(0);
Packit Service a31ea6
Packit Service a31ea6
    htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
Packit Service a31ea6
Packit Service a31ea6
    ret = xmlOutputBufferClose(buf);
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlNodeDumpFile:
Packit Service a31ea6
 * @out:  the FILE pointer
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the current node
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node, recursive behaviour,children are printed too,
Packit Service a31ea6
 * and formatting returns are added.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
Packit Service a31ea6
    htmlNodeDumpFileFormat(out, doc, cur, NULL, 1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlDocDumpMemoryFormat:
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 * @mem:  OUT: the memory pointer
Packit Service a31ea6
 * @size:  OUT: the memory length
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document in memory and return the xmlChar * and it's size.
Packit Service a31ea6
 * It's up to the caller to free the memory.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
Packit Service a31ea6
    xmlOutputBufferPtr buf;
Packit Service a31ea6
    xmlCharEncodingHandlerPtr handler = NULL;
Packit Service a31ea6
    const char *encoding;
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    if ((mem == NULL) || (size == NULL))
Packit Service a31ea6
        return;
Packit Service a31ea6
    if (cur == NULL) {
Packit Service a31ea6
	*mem = NULL;
Packit Service a31ea6
	*size = 0;
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    encoding = (const char *) htmlGetMetaEncoding(cur);
Packit Service a31ea6
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	xmlCharEncoding enc;
Packit Service a31ea6
Packit Service a31ea6
	enc = xmlParseCharEncoding(encoding);
Packit Service a31ea6
	if (enc != cur->charset) {
Packit Service a31ea6
	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
Packit Service a31ea6
		/*
Packit Service a31ea6
		 * Not supported yet
Packit Service a31ea6
		 */
Packit Service a31ea6
		*mem = NULL;
Packit Service a31ea6
		*size = 0;
Packit Service a31ea6
		return;
Packit Service a31ea6
	    }
Packit Service a31ea6
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	    if (handler == NULL)
Packit Service a31ea6
                htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
Packit Service a31ea6
Packit Service a31ea6
	} else {
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	}
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Fallback to HTML or ASCII when the encoding is unspecified
Packit Service a31ea6
     */
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("HTML");
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("ascii");
Packit Service a31ea6
Packit Service a31ea6
    buf = xmlAllocOutputBufferInternal(handler);
Packit Service a31ea6
    if (buf == NULL) {
Packit Service a31ea6
	*mem = NULL;
Packit Service a31ea6
	*size = 0;
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
Packit Service a31ea6
Packit Service a31ea6
    xmlOutputBufferFlush(buf);
Packit Service a31ea6
    if (buf->conv != NULL) {
Packit Service a31ea6
	*size = xmlBufUse(buf->conv);
Packit Service a31ea6
	*mem = xmlStrndup(xmlBufContent(buf->conv), *size);
Packit Service a31ea6
    } else {
Packit Service a31ea6
	*size = xmlBufUse(buf->buffer);
Packit Service a31ea6
	*mem = xmlStrndup(xmlBufContent(buf->buffer), *size);
Packit Service a31ea6
    }
Packit Service a31ea6
    (void)xmlOutputBufferClose(buf);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlDocDumpMemory:
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 * @mem:  OUT: the memory pointer
Packit Service a31ea6
 * @size:  OUT: the memory length
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document in memory and return the xmlChar * and it's size.
Packit Service a31ea6
 * It's up to the caller to free the memory.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
Packit Service a31ea6
	htmlDocDumpMemoryFormat(cur, mem, size, 1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Dumping HTML tree content to an I/O output buffer	*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlDtdDumpOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 *
Packit Service a31ea6
 * TODO: check whether encoding is needed
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump the HTML document DTD, if any.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
Packit Service a31ea6
	          const char *encoding ATTRIBUTE_UNUSED) {
Packit Service a31ea6
    xmlDtdPtr cur = doc->intSubset;
Packit Service a31ea6
Packit Service a31ea6
    if (cur == NULL) {
Packit Service a31ea6
	htmlSaveErr(XML_SAVE_NO_DOCTYPE, (xmlNodePtr) doc, NULL);
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, "
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
    if (cur->ExternalID != NULL) {
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, " PUBLIC ");
Packit Service a31ea6
	xmlBufWriteQuotedString(buf->buffer, cur->ExternalID);
Packit Service a31ea6
	if (cur->SystemID != NULL) {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, " ");
Packit Service a31ea6
	    xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
Packit Service a31ea6
	}
Packit Service a31ea6
    } else if (cur->SystemID != NULL &&
Packit Service a31ea6
	       xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, " SYSTEM ");
Packit Service a31ea6
	xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, ">\n");
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlAttrDumpOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the attribute pointer
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML attribute
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
Packit Service a31ea6
	           const char *encoding ATTRIBUTE_UNUSED) {
Packit Service a31ea6
    xmlChar *value;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * The html output method should not escape a & character
Packit Service a31ea6
     * occurring in an attribute value immediately followed by
Packit Service a31ea6
     * a { character (see Section B.7.1 of the HTML 4.0 Recommendation).
Packit Service a31ea6
     * This is implemented in xmlEncodeEntitiesReentrant
Packit Service a31ea6
     */
Packit Service a31ea6
Packit Service a31ea6
    if (cur == NULL) {
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, " ");
Packit Service a31ea6
    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
Packit Service a31ea6
        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, ":");
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
    if ((cur->children != NULL) && (!htmlIsBooleanAttr(cur->name))) {
Packit Service a31ea6
	value = xmlNodeListGetString(doc, cur->children, 0);
Packit Service a31ea6
	if (value) {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "=");
Packit Service a31ea6
	    if ((cur->ns == NULL) && (cur->parent != NULL) &&
Packit Service a31ea6
		(cur->parent->ns == NULL) &&
Packit Service a31ea6
		((!xmlStrcasecmp(cur->name, BAD_CAST "href")) ||
Packit Service a31ea6
	         (!xmlStrcasecmp(cur->name, BAD_CAST "action")) ||
Packit Service a31ea6
		 (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
Packit Service a31ea6
		 ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
Packit Service a31ea6
		  (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
Packit Service a31ea6
		xmlChar *tmp = value;
Packit Service a31ea6
		/* xmlURIEscapeStr() escapes '"' so it can be safely used. */
Packit Service a31ea6
		xmlBufCCat(buf->buffer, "\"");
Packit Service a31ea6
Packit Service a31ea6
		while (IS_BLANK_CH(*tmp)) tmp++;
Packit Service a31ea6
Packit Service a31ea6
		/* URI Escape everything, except server side includes. */
Packit Service a31ea6
		for ( ; ; ) {
Packit Service a31ea6
		    xmlChar *escaped;
Packit Service a31ea6
		    xmlChar endChar;
Packit Service a31ea6
		    xmlChar *end = NULL;
Packit Service a31ea6
		    xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST "
Packit Service a31ea6
		    if (start != NULL) {
Packit Service a31ea6
			end = (xmlChar *)xmlStrstr(tmp, BAD_CAST "-->");
Packit Service a31ea6
			if (end != NULL) {
Packit Service a31ea6
			    *start = '\0';
Packit Service a31ea6
			}
Packit Service a31ea6
		    }
Packit Service a31ea6
Packit Service a31ea6
		    /* Escape the whole string, or until start (set to '\0'). */
Packit Service a31ea6
		    escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+");
Packit Service a31ea6
		    if (escaped != NULL) {
Packit Service a31ea6
		        xmlBufCat(buf->buffer, escaped);
Packit Service a31ea6
		        xmlFree(escaped);
Packit Service a31ea6
		    } else {
Packit Service a31ea6
		        xmlBufCat(buf->buffer, tmp);
Packit Service a31ea6
		    }
Packit Service a31ea6
Packit Service a31ea6
		    if (end == NULL) { /* Everything has been written. */
Packit Service a31ea6
			break;
Packit Service a31ea6
		    }
Packit Service a31ea6
Packit Service a31ea6
		    /* Do not escape anything within server side includes. */
Packit Service a31ea6
		    *start = '<'; /* Restore the first character of "
Packit Service a31ea6
		    end += 3; /* strlen("-->") */
Packit Service a31ea6
		    endChar = *end;
Packit Service a31ea6
		    *end = '\0';
Packit Service a31ea6
		    xmlBufCat(buf->buffer, start);
Packit Service a31ea6
		    *end = endChar;
Packit Service a31ea6
		    tmp = end;
Packit Service a31ea6
		}
Packit Service a31ea6
Packit Service a31ea6
		xmlBufCCat(buf->buffer, "\"");
Packit Service a31ea6
	    } else {
Packit Service a31ea6
		xmlBufWriteQuotedString(buf->buffer, value);
Packit Service a31ea6
	    }
Packit Service a31ea6
	    xmlFree(value);
Packit Service a31ea6
	} else  {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "=\"\"");
Packit Service a31ea6
	}
Packit Service a31ea6
    }
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlAttrListDumpOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the first attribute pointer
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump a list of HTML attributes
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
htmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
Packit Service a31ea6
    if (cur == NULL) {
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
        htmlAttrDumpOutput(buf, doc, cur, encoding);
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlNodeListDumpOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the first node
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node list, recursive behaviour,children are printed too.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
htmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
Packit Service a31ea6
	               xmlNodePtr cur, const char *encoding, int format) {
Packit Service a31ea6
    if (cur == NULL) {
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    while (cur != NULL) {
Packit Service a31ea6
        htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
Packit Service a31ea6
	cur = cur->next;
Packit Service a31ea6
    }
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlNodeDumpFormatOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the current node
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node, recursive behaviour,children are printed too.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
Packit Service a31ea6
	                 xmlNodePtr cur, const char *encoding, int format) {
Packit Service a31ea6
    const htmlElemDesc * info;
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    if ((cur == NULL) || (buf == NULL)) {
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Special cases.
Packit Service a31ea6
     */
Packit Service a31ea6
    if (cur->type == XML_DTD_NODE)
Packit Service a31ea6
	return;
Packit Service a31ea6
    if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
Packit Service a31ea6
        (cur->type == XML_DOCUMENT_NODE)){
Packit Service a31ea6
	htmlDocContentDumpOutput(buf, (xmlDocPtr) cur, encoding);
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->type == XML_ATTRIBUTE_NODE) {
Packit Service a31ea6
        htmlAttrDumpOutput(buf, doc, (xmlAttrPtr) cur, encoding);
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->type == HTML_TEXT_NODE) {
Packit Service a31ea6
	if (cur->content != NULL) {
Packit Service a31ea6
	    if (((cur->name == (const xmlChar *)xmlStringText) ||
Packit Service a31ea6
		 (cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
Packit Service a31ea6
		((cur->parent == NULL) ||
Packit Service a31ea6
		 ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) &&
Packit Service a31ea6
		  (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) {
Packit Service a31ea6
		xmlChar *buffer;
Packit Service a31ea6
Packit Service a31ea6
		buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
Packit Service a31ea6
		if (buffer != NULL) {
Packit Service a31ea6
		    xmlOutputBufferWriteString(buf, (const char *)buffer);
Packit Service a31ea6
		    xmlFree(buffer);
Packit Service a31ea6
		}
Packit Service a31ea6
	    } else {
Packit Service a31ea6
		xmlOutputBufferWriteString(buf, (const char *)cur->content);
Packit Service a31ea6
	    }
Packit Service a31ea6
	}
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->type == HTML_COMMENT_NODE) {
Packit Service a31ea6
	if (cur->content != NULL) {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "-->");
Packit Service a31ea6
	}
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->type == HTML_PI_NODE) {
Packit Service a31ea6
	if (cur->name == NULL)
Packit Service a31ea6
	    return;
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, "
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
	if (cur->content != NULL) {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, " ");
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
Packit Service a31ea6
	}
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, ">");
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->type == HTML_ENTITY_REF_NODE) {
Packit Service a31ea6
        xmlOutputBufferWriteString(buf, "&";;
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
        xmlOutputBufferWriteString(buf, ";");
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->type == HTML_PRESERVE_NODE) {
Packit Service a31ea6
	if (cur->content != NULL) {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
Packit Service a31ea6
	}
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Get specific HTML info for that node.
Packit Service a31ea6
     */
Packit Service a31ea6
    if (cur->ns == NULL)
Packit Service a31ea6
	info = htmlTagLookup(cur->name);
Packit Service a31ea6
    else
Packit Service a31ea6
	info = NULL;
Packit Service a31ea6
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, "<");
Packit Service a31ea6
    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
Packit Service a31ea6
        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, ":");
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
    if (cur->nsDef)
Packit Service a31ea6
	xmlNsListDumpOutput(buf, cur->nsDef);
Packit Service a31ea6
    if (cur->properties != NULL)
Packit Service a31ea6
        htmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
Packit Service a31ea6
Packit Service a31ea6
    if ((info != NULL) && (info->empty)) {
Packit Service a31ea6
        xmlOutputBufferWriteString(buf, ">");
Packit Service a31ea6
	if ((format) && (!info->isinline) && (cur->next != NULL)) {
Packit Service a31ea6
	    if ((cur->next->type != HTML_TEXT_NODE) &&
Packit Service a31ea6
		(cur->next->type != HTML_ENTITY_REF_NODE) &&
Packit Service a31ea6
		(cur->parent != NULL) &&
Packit Service a31ea6
		(cur->parent->name != NULL) &&
Packit Service a31ea6
		(cur->parent->name[0] != 'p')) /* p, pre, param */
Packit Service a31ea6
		xmlOutputBufferWriteString(buf, "\n");
Packit Service a31ea6
	}
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
Packit Service a31ea6
	(cur->children == NULL)) {
Packit Service a31ea6
        if ((info != NULL) && (info->saveEndTag != 0) &&
Packit Service a31ea6
	    (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) &&
Packit Service a31ea6
	    (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, ">");
Packit Service a31ea6
	} else {
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "></");
Packit Service a31ea6
            if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
Packit Service a31ea6
                xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
Packit Service a31ea6
                xmlOutputBufferWriteString(buf, ":");
Packit Service a31ea6
            }
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, ">");
Packit Service a31ea6
	}
Packit Service a31ea6
	if ((format) && (cur->next != NULL) &&
Packit Service a31ea6
            (info != NULL) && (!info->isinline)) {
Packit Service a31ea6
	    if ((cur->next->type != HTML_TEXT_NODE) &&
Packit Service a31ea6
		(cur->next->type != HTML_ENTITY_REF_NODE) &&
Packit Service a31ea6
		(cur->parent != NULL) &&
Packit Service a31ea6
		(cur->parent->name != NULL) &&
Packit Service a31ea6
		(cur->parent->name[0] != 'p')) /* p, pre, param */
Packit Service a31ea6
		xmlOutputBufferWriteString(buf, "\n");
Packit Service a31ea6
	}
Packit Service a31ea6
	return;
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, ">");
Packit Service a31ea6
    if ((cur->type != XML_ELEMENT_NODE) &&
Packit Service a31ea6
	(cur->content != NULL)) {
Packit Service a31ea6
	    /*
Packit Service a31ea6
	     * Uses the OutputBuffer property to automatically convert
Packit Service a31ea6
	     * invalids to charrefs
Packit Service a31ea6
	     */
Packit Service a31ea6
Packit Service a31ea6
            xmlOutputBufferWriteString(buf, (const char *) cur->content);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->children != NULL) {
Packit Service a31ea6
        if ((format) && (info != NULL) && (!info->isinline) &&
Packit Service a31ea6
	    (cur->children->type != HTML_TEXT_NODE) &&
Packit Service a31ea6
	    (cur->children->type != HTML_ENTITY_REF_NODE) &&
Packit Service a31ea6
	    (cur->children != cur->last) &&
Packit Service a31ea6
	    (cur->name != NULL) &&
Packit Service a31ea6
	    (cur->name[0] != 'p')) /* p, pre, param */
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "\n");
Packit Service a31ea6
	htmlNodeListDumpOutput(buf, doc, cur->children, encoding, format);
Packit Service a31ea6
        if ((format) && (info != NULL) && (!info->isinline) &&
Packit Service a31ea6
	    (cur->last->type != HTML_TEXT_NODE) &&
Packit Service a31ea6
	    (cur->last->type != HTML_ENTITY_REF_NODE) &&
Packit Service a31ea6
	    (cur->children != cur->last) &&
Packit Service a31ea6
	    (cur->name != NULL) &&
Packit Service a31ea6
	    (cur->name[0] != 'p')) /* p, pre, param */
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "\n");
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, "</");
Packit Service a31ea6
    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
Packit Service a31ea6
        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
Packit Service a31ea6
	xmlOutputBufferWriteString(buf, ":");
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, (const char *)cur->name);
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, ">");
Packit Service a31ea6
    if ((format) && (info != NULL) && (!info->isinline) &&
Packit Service a31ea6
	(cur->next != NULL)) {
Packit Service a31ea6
        if ((cur->next->type != HTML_TEXT_NODE) &&
Packit Service a31ea6
	    (cur->next->type != HTML_ENTITY_REF_NODE) &&
Packit Service a31ea6
	    (cur->parent != NULL) &&
Packit Service a31ea6
	    (cur->parent->name != NULL) &&
Packit Service a31ea6
	    (cur->parent->name[0] != 'p')) /* p, pre, param */
Packit Service a31ea6
	    xmlOutputBufferWriteString(buf, "\n");
Packit Service a31ea6
    }
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlNodeDumpOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @doc:  the document
Packit Service a31ea6
 * @cur:  the current node
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML node, recursive behaviour,children are printed too,
Packit Service a31ea6
 * and formatting returns/spaces are added.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
Packit Service a31ea6
	           xmlNodePtr cur, const char *encoding) {
Packit Service a31ea6
    htmlNodeDumpFormatOutput(buf, doc, cur, encoding, 1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlDocContentDumpFormatOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
Packit Service a31ea6
	                       const char *encoding, int format) {
Packit Service a31ea6
    int type;
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    if ((buf == NULL) || (cur == NULL))
Packit Service a31ea6
        return;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * force to output the stuff as HTML, especially for entities
Packit Service a31ea6
     */
Packit Service a31ea6
    type = cur->type;
Packit Service a31ea6
    cur->type = XML_HTML_DOCUMENT_NODE;
Packit Service a31ea6
    if (cur->intSubset != NULL) {
Packit Service a31ea6
        htmlDtdDumpOutput(buf, cur, NULL);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (cur->children != NULL) {
Packit Service a31ea6
        htmlNodeListDumpOutput(buf, cur, cur->children, encoding, format);
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlOutputBufferWriteString(buf, "\n");
Packit Service a31ea6
    cur->type = (xmlElementType) type;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlDocContentDumpOutput:
Packit Service a31ea6
 * @buf:  the HTML buffer output
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 * @encoding:  the encoding string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document. Formating return/spaces are added.
Packit Service a31ea6
 */
Packit Service a31ea6
void
Packit Service a31ea6
htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
Packit Service a31ea6
	                 const char *encoding) {
Packit Service a31ea6
    htmlDocContentDumpFormatOutput(buf, cur, encoding, 1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Saving functions front-ends				*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlDocDump:
Packit Service a31ea6
 * @f:  the FILE*
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document to an open FILE.
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns: the number of byte written or -1 in case of failure.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlDocDump(FILE *f, xmlDocPtr cur) {
Packit Service a31ea6
    xmlOutputBufferPtr buf;
Packit Service a31ea6
    xmlCharEncodingHandlerPtr handler = NULL;
Packit Service a31ea6
    const char *encoding;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    if ((cur == NULL) || (f == NULL)) {
Packit Service a31ea6
	return(-1);
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    encoding = (const char *) htmlGetMetaEncoding(cur);
Packit Service a31ea6
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	xmlCharEncoding enc;
Packit Service a31ea6
Packit Service a31ea6
	enc = xmlParseCharEncoding(encoding);
Packit Service a31ea6
	if (enc != cur->charset) {
Packit Service a31ea6
	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
Packit Service a31ea6
		/*
Packit Service a31ea6
		 * Not supported yet
Packit Service a31ea6
		 */
Packit Service a31ea6
		return(-1);
Packit Service a31ea6
	    }
Packit Service a31ea6
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	    if (handler == NULL)
Packit Service a31ea6
		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
Packit Service a31ea6
	} else {
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	}
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Fallback to HTML or ASCII when the encoding is unspecified
Packit Service a31ea6
     */
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("HTML");
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("ascii");
Packit Service a31ea6
Packit Service a31ea6
    buf = xmlOutputBufferCreateFile(f, handler);
Packit Service a31ea6
    if (buf == NULL) return(-1);
Packit Service a31ea6
    htmlDocContentDumpOutput(buf, cur, NULL);
Packit Service a31ea6
Packit Service a31ea6
    ret = xmlOutputBufferClose(buf);
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlSaveFile:
Packit Service a31ea6
 * @filename:  the filename (or URL)
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document to a file. If @filename is "-" the stdout file is
Packit Service a31ea6
 * used.
Packit Service a31ea6
 * returns: the number of byte written or -1 in case of failure.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlSaveFile(const char *filename, xmlDocPtr cur) {
Packit Service a31ea6
    xmlOutputBufferPtr buf;
Packit Service a31ea6
    xmlCharEncodingHandlerPtr handler = NULL;
Packit Service a31ea6
    const char *encoding;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    if ((cur == NULL) || (filename == NULL))
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    encoding = (const char *) htmlGetMetaEncoding(cur);
Packit Service a31ea6
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	xmlCharEncoding enc;
Packit Service a31ea6
Packit Service a31ea6
	enc = xmlParseCharEncoding(encoding);
Packit Service a31ea6
	if (enc != cur->charset) {
Packit Service a31ea6
	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
Packit Service a31ea6
		/*
Packit Service a31ea6
		 * Not supported yet
Packit Service a31ea6
		 */
Packit Service a31ea6
		return(-1);
Packit Service a31ea6
	    }
Packit Service a31ea6
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	    if (handler == NULL)
Packit Service a31ea6
		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
Packit Service a31ea6
	}
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Fallback to HTML or ASCII when the encoding is unspecified
Packit Service a31ea6
     */
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("HTML");
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("ascii");
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * save the content to a temp buffer.
Packit Service a31ea6
     */
Packit Service a31ea6
    buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
Packit Service a31ea6
    if (buf == NULL) return(0);
Packit Service a31ea6
Packit Service a31ea6
    htmlDocContentDumpOutput(buf, cur, NULL);
Packit Service a31ea6
Packit Service a31ea6
    ret = xmlOutputBufferClose(buf);
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlSaveFileFormat:
Packit Service a31ea6
 * @filename:  the filename
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 * @format:  should formatting spaces been added
Packit Service a31ea6
 * @encoding: the document encoding
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document to a file using a given encoding.
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns: the number of byte written or -1 in case of failure.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
Packit Service a31ea6
	           const char *encoding, int format) {
Packit Service a31ea6
    xmlOutputBufferPtr buf;
Packit Service a31ea6
    xmlCharEncodingHandlerPtr handler = NULL;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    if ((cur == NULL) || (filename == NULL))
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
Packit Service a31ea6
    if (encoding != NULL) {
Packit Service a31ea6
	xmlCharEncoding enc;
Packit Service a31ea6
Packit Service a31ea6
	enc = xmlParseCharEncoding(encoding);
Packit Service a31ea6
	if (enc != cur->charset) {
Packit Service a31ea6
	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
Packit Service a31ea6
		/*
Packit Service a31ea6
		 * Not supported yet
Packit Service a31ea6
		 */
Packit Service a31ea6
		return(-1);
Packit Service a31ea6
	    }
Packit Service a31ea6
Packit Service a31ea6
	    handler = xmlFindCharEncodingHandler(encoding);
Packit Service a31ea6
	    if (handler == NULL)
Packit Service a31ea6
		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
Packit Service a31ea6
	}
Packit Service a31ea6
        htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
Packit Service a31ea6
    } else {
Packit Service a31ea6
	htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Fallback to HTML or ASCII when the encoding is unspecified
Packit Service a31ea6
     */
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("HTML");
Packit Service a31ea6
    if (handler == NULL)
Packit Service a31ea6
	handler = xmlFindCharEncodingHandler("ascii");
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * save the content to a temp buffer.
Packit Service a31ea6
     */
Packit Service a31ea6
    buf = xmlOutputBufferCreateFilename(filename, handler, 0);
Packit Service a31ea6
    if (buf == NULL) return(0);
Packit Service a31ea6
Packit Service a31ea6
    htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
Packit Service a31ea6
Packit Service a31ea6
    ret = xmlOutputBufferClose(buf);
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * htmlSaveFileEnc:
Packit Service a31ea6
 * @filename:  the filename
Packit Service a31ea6
 * @cur:  the document
Packit Service a31ea6
 * @encoding: the document encoding
Packit Service a31ea6
 *
Packit Service a31ea6
 * Dump an HTML document to a file using a given encoding
Packit Service a31ea6
 * and formatting returns/spaces are added.
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns: the number of byte written or -1 in case of failure.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
Packit Service a31ea6
    return(htmlSaveFileFormat(filename, cur, encoding, 1));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
#endif /* LIBXML_OUTPUT_ENABLED */
Packit Service a31ea6
Packit Service a31ea6
#define bottom_HTMLtree
Packit Service a31ea6
#include "elfgcchack.h"
Packit Service a31ea6
#endif /* LIBXML_HTML_ENABLED */