/*
 * debugXML.c : This is a set of routines used for debugging the tree
 *              produced by the XML parser.
 *
 * See Copyright for the status of this software.
 *
 * Daniel Veillard <daniel@veillard.com>
 */

#define IN_LIBXML
#include "libxml.h"
#ifdef LIBXML_DEBUG_ENABLED

#include <string.h>
#include <stdlib.h>

#include <libxml/debugXML.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/HTMLtree.h>
#include <libxml/HTMLparser.h>
#include <libxml/xmlerror.h>

#include "private/error.h"
#include "private/parser.h"

#define DUMP_TEXT_TYPE 1

typedef struct _xmlDebugCtxt xmlDebugCtxt;
typedef xmlDebugCtxt *xmlDebugCtxtPtr;
struct _xmlDebugCtxt {
    FILE *output;               /* the output file */
    char shift[101];            /* used for indenting */
    int depth;                  /* current depth */
    xmlDocPtr doc;              /* current document */
    xmlNodePtr node;		/* current node */
    xmlDictPtr dict;		/* the doc dictionary */
    int check;                  /* do just checkings */
    int errors;                 /* number of errors found */
    int nodict;			/* if the document has no dictionary */
    int options;		/* options */
};

static void xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node);

static void
xmlCtxtDumpInitCtxt(xmlDebugCtxtPtr ctxt)
{
    int i;

    ctxt->depth = 0;
    ctxt->check = 0;
    ctxt->errors = 0;
    ctxt->output = stdout;
    ctxt->doc = NULL;
    ctxt->node = NULL;
    ctxt->dict = NULL;
    ctxt->nodict = 0;
    ctxt->options = 0;
    for (i = 0; i < 100; i++)
        ctxt->shift[i] = ' ';
    ctxt->shift[100] = 0;
}

static void
xmlCtxtDumpCleanCtxt(xmlDebugCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
 /* remove the ATTRIBUTE_UNUSED when this is added */
}

/**
 * xmlNsCheckScope:
 * @node: the node
 * @ns: the namespace node
 *
 * Check that a given namespace is in scope on a node.
 *
 * Returns 1 if in scope, -1 in case of argument error,
 *         -2 if the namespace is not in scope, and -3 if not on
 *         an ancestor node.
 */
static int
xmlNsCheckScope(xmlNodePtr node, xmlNsPtr ns)
{
    xmlNsPtr cur;

    if ((node == NULL) || (ns == NULL))
        return(-1);

    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE) &&
	(node->type != XML_DOCUMENT_NODE) &&
	(node->type != XML_TEXT_NODE) &&
	(node->type != XML_HTML_DOCUMENT_NODE) &&
	(node->type != XML_XINCLUDE_START))
	return(-2);

    while ((node != NULL) &&
           ((node->type == XML_ELEMENT_NODE) ||
            (node->type == XML_ATTRIBUTE_NODE) ||
            (node->type == XML_TEXT_NODE) ||
	    (node->type == XML_XINCLUDE_START))) {
	if ((node->type == XML_ELEMENT_NODE) ||
	    (node->type == XML_XINCLUDE_START)) {
	    cur = node->nsDef;
	    while (cur != NULL) {
	        if (cur == ns)
		    return(1);
		if (xmlStrEqual(cur->prefix, ns->prefix))
		    return(-2);
		cur = cur->next;
	    }
	}
	node = node->parent;
    }
    /* the xml namespace may be declared on the document node */
    if ((node != NULL) &&
        ((node->type == XML_DOCUMENT_NODE) ||
	 (node->type == XML_HTML_DOCUMENT_NODE))) {
	 xmlNsPtr oldNs = ((xmlDocPtr) node)->oldNs;
	 if (oldNs == ns)
	     return(1);
    }
    return(-3);
}

static void
xmlCtxtDumpSpaces(xmlDebugCtxtPtr ctxt)
{
    if (ctxt->check)
        return;
    if ((ctxt->output != NULL) && (ctxt->depth > 0)) {
        if (ctxt->depth < 50)
            fprintf(ctxt->output, "%s", &ctxt->shift[100 - 2 * ctxt->depth]);
        else
            fprintf(ctxt->output, "%s", ctxt->shift);
    }
}

/**
 * xmlDebugErr:
 * @ctxt:  a debug context
 * @error:  the error code
 *
 * Handle a debug error.
 */
static void
xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg)
{
    ctxt->errors++;
    fprintf(ctxt->output, "ERROR %d: %s", error, msg);
}
static void LIBXML_ATTR_FORMAT(3,0)
xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
{
    ctxt->errors++;
    fprintf(ctxt->output, "ERROR %d: ", error);
    fprintf(ctxt->output, msg, extra);
}
static void LIBXML_ATTR_FORMAT(3,0)
xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
{
    ctxt->errors++;
    fprintf(ctxt->output, "ERROR %d: ", error);
    fprintf(ctxt->output, msg, extra);
}

/**
 * xmlCtxtNsCheckScope:
 * @ctxt: the debugging context
 * @node: the node
 * @ns: the namespace node
 *
 * Report if a given namespace is is not in scope.
 */
static void
xmlCtxtNsCheckScope(xmlDebugCtxtPtr ctxt, xmlNodePtr node, xmlNsPtr ns)
{
    int ret;

    ret = xmlNsCheckScope(node, ns);
    if (ret == -2) {
        if (ns->prefix == NULL)
	    xmlDebugErr(ctxt, XML_CHECK_NS_SCOPE,
			"Reference to default namespace not in scope\n");
	else
	    xmlDebugErr3(ctxt, XML_CHECK_NS_SCOPE,
			 "Reference to namespace '%s' not in scope\n",
			 (char *) ns->prefix);
    }
    if (ret == -3) {
        if (ns->prefix == NULL)
	    xmlDebugErr(ctxt, XML_CHECK_NS_ANCESTOR,
			"Reference to default namespace not on ancestor\n");
	else
	    xmlDebugErr3(ctxt, XML_CHECK_NS_ANCESTOR,
			 "Reference to namespace '%s' not on ancestor\n",
			 (char *) ns->prefix);
    }
}

/**
 * xmlCtxtCheckString:
 * @ctxt: the debug context
 * @str: the string
 *
 * Do debugging on the string, currently it just checks the UTF-8 content
 */
static void
xmlCtxtCheckString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
{
    if (str == NULL) return;
    if (ctxt->check) {
        if (!xmlCheckUTF8(str)) {
	    xmlDebugErr3(ctxt, XML_CHECK_NOT_UTF8,
			 "String is not UTF-8 %s", (const char *) str);
	}
    }
}

/**
 * xmlCtxtCheckName:
 * @ctxt: the debug context
 * @name: the name
 *
 * Do debugging on the name, for example the dictionary status and
 * conformance to the Name production.
 */
static void
xmlCtxtCheckName(xmlDebugCtxtPtr ctxt, const xmlChar * name)
{
    if (ctxt->check) {
	if (name == NULL) {
	    xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL");
	    return;
	}
        if (xmlValidateName(name, 0)) {
	    xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
			 "Name is not an NCName '%s'", (const char *) name);
	}
	if ((ctxt->dict != NULL) &&
	    (!xmlDictOwns(ctxt->dict, name)) &&
            ((ctxt->doc == NULL) ||
             ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) {
	    xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT,
			 "Name is not from the document dictionary '%s'",
			 (const char *) name);
	}
    }
}

static void
xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) {
    xmlDocPtr doc;
    xmlDictPtr dict;

    doc = node->doc;

    if (node->parent == NULL)
        xmlDebugErr(ctxt, XML_CHECK_NO_PARENT,
	            "Node has no parent\n");
    if (node->doc == NULL) {
        xmlDebugErr(ctxt, XML_CHECK_NO_DOC,
	            "Node has no doc\n");
        dict = NULL;
    } else {
	dict = doc->dict;
	if ((dict == NULL) && (ctxt->nodict == 0)) {
	    ctxt->nodict = 1;
	}
	if (ctxt->doc == NULL)
	    ctxt->doc = doc;

	if (ctxt->dict == NULL) {
	    ctxt->dict = dict;
	}
    }
    if ((node->parent != NULL) && (node->doc != node->parent->doc) &&
        (!xmlStrEqual(node->name, BAD_CAST "pseudoroot")))
        xmlDebugErr(ctxt, XML_CHECK_WRONG_DOC,
	            "Node doc differs from parent's one\n");
    if (node->prev == NULL) {
        if (node->type == XML_ATTRIBUTE_NODE) {
	    if ((node->parent != NULL) &&
	        (node != (xmlNodePtr) node->parent->properties))
		xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
                    "Attr has no prev and not first of attr list\n");

        } else if ((node->parent != NULL) && (node->parent->children != node))
	    xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
                    "Node has no prev and not first of parent list\n");
    } else {
        if (node->prev->next != node)
	    xmlDebugErr(ctxt, XML_CHECK_WRONG_PREV,
                        "Node prev->next : back link wrong\n");
    }
    if (node->next == NULL) {
	if ((node->parent != NULL) && (node->type != XML_ATTRIBUTE_NODE) &&
	    (node->parent->last != node) &&
	    (node->parent->type == XML_ELEMENT_NODE))
	    xmlDebugErr(ctxt, XML_CHECK_NO_NEXT,
                    "Node has no next and not last of parent list\n");
    } else {
        if (node->next->prev != node)
	    xmlDebugErr(ctxt, XML_CHECK_WRONG_NEXT,
                    "Node next->prev : forward link wrong\n");
        if (node->next->parent != node->parent)
	    xmlDebugErr(ctxt, XML_CHECK_WRONG_PARENT,
                    "Node next->prev : forward link wrong\n");
    }
    if (node->type == XML_ELEMENT_NODE) {
        xmlNsPtr ns;

	ns = node->nsDef;
	while (ns != NULL) {
	    xmlCtxtNsCheckScope(ctxt, node, ns);
	    ns = ns->next;
	}
	if (node->ns != NULL)
	    xmlCtxtNsCheckScope(ctxt, node, node->ns);
    } else if (node->type == XML_ATTRIBUTE_NODE) {
	if (node->ns != NULL)
	    xmlCtxtNsCheckScope(ctxt, node, node->ns);
    }

    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE) &&
	(node->type != XML_ELEMENT_DECL) &&
	(node->type != XML_ATTRIBUTE_DECL) &&
	(node->type != XML_DTD_NODE) &&
	(node->type != XML_HTML_DOCUMENT_NODE) &&
	(node->type != XML_DOCUMENT_NODE)) {
	if (node->content != NULL)
	    xmlCtxtCheckString(ctxt, (const xmlChar *) node->content);
    }
    switch (node->type) {
        case XML_ELEMENT_NODE:
        case XML_ATTRIBUTE_NODE:
	    xmlCtxtCheckName(ctxt, node->name);
	    break;
        case XML_TEXT_NODE:
	    if ((node->name == xmlStringText) ||
	        (node->name == xmlStringTextNoenc))
		break;
	    /* some case of entity substitution can lead to this */
	    if ((ctxt->dict != NULL) &&
	        (node->name == xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
		                             7)))
		break;

	    xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
			 "Text node has wrong name '%s'",
			 (const char *) node->name);
	    break;
        case XML_COMMENT_NODE:
	    if (node->name == xmlStringComment)
		break;
	    xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
			 "Comment node has wrong name '%s'",
			 (const char *) node->name);
	    break;
        case XML_PI_NODE:
	    xmlCtxtCheckName(ctxt, node->name);
	    break;
        case XML_CDATA_SECTION_NODE:
	    if (node->name == NULL)
		break;
	    xmlDebugErr3(ctxt, XML_CHECK_NAME_NOT_NULL,
			 "CData section has non NULL name '%s'",
			 (const char *) node->name);
	    break;
        case XML_ENTITY_REF_NODE:
        case XML_ENTITY_NODE:
        case XML_DOCUMENT_TYPE_NODE:
        case XML_DOCUMENT_FRAG_NODE:
        case XML_NOTATION_NODE:
        case XML_DTD_NODE:
        case XML_ELEMENT_DECL:
        case XML_ATTRIBUTE_DECL:
        case XML_ENTITY_DECL:
        case XML_NAMESPACE_DECL:
        case XML_XINCLUDE_START:
        case XML_XINCLUDE_END:
        case XML_DOCUMENT_NODE:
        case XML_HTML_DOCUMENT_NODE:
	    break;
    }
}

static void
xmlCtxtDumpString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
{
    int i;

    if (ctxt->check) {
        return;
    }
    /* TODO: check UTF8 content of the string */
    if (str == NULL) {
        fprintf(ctxt->output, "(NULL)");
        return;
    }
    for (i = 0; i < 40; i++)
        if (str[i] == 0)
            return;
        else if (IS_BLANK_CH(str[i]))
            fputc(' ', ctxt->output);
        else if (str[i] >= 0x80)
            fprintf(ctxt->output, "#%X", str[i]);
        else
            fputc(str[i], ctxt->output);
    fprintf(ctxt->output, "...");
}

static void
xmlCtxtDumpDtdNode(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
{
    xmlCtxtDumpSpaces(ctxt);

    if (dtd == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "DTD node is NULL\n");
        return;
    }

    if (dtd->type != XML_DTD_NODE) {
	xmlDebugErr(ctxt, XML_CHECK_NOT_DTD,
	            "Node is not a DTD");
        return;
    }
    if (!ctxt->check) {
        if (dtd->name != NULL)
            fprintf(ctxt->output, "DTD(%s)", (char *) dtd->name);
        else
            fprintf(ctxt->output, "DTD");
        if (dtd->ExternalID != NULL)
            fprintf(ctxt->output, ", PUBLIC %s", (char *) dtd->ExternalID);
        if (dtd->SystemID != NULL)
            fprintf(ctxt->output, ", SYSTEM %s", (char *) dtd->SystemID);
        fprintf(ctxt->output, "\n");
    }
    /*
     * Do a bit of checking
     */
    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) dtd);
}

static void
xmlCtxtDumpAttrDecl(xmlDebugCtxtPtr ctxt, xmlAttributePtr attr)
{
    xmlCtxtDumpSpaces(ctxt);

    if (attr == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "Attribute declaration is NULL\n");
        return;
    }
    if (attr->type != XML_ATTRIBUTE_DECL) {
	xmlDebugErr(ctxt, XML_CHECK_NOT_ATTR_DECL,
	            "Node is not an attribute declaration");
        return;
    }
    if (attr->name != NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name);
    } else
	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
	            "Node attribute declaration has no name");
    if (attr->elem != NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, " for %s", (char *) attr->elem);
    } else
	xmlDebugErr(ctxt, XML_CHECK_NO_ELEM,
	            "Node attribute declaration has no element name");
    if (!ctxt->check) {
        switch (attr->atype) {
            case XML_ATTRIBUTE_CDATA:
                fprintf(ctxt->output, " CDATA");
                break;
            case XML_ATTRIBUTE_ID:
                fprintf(ctxt->output, " ID");
                break;
            case XML_ATTRIBUTE_IDREF:
                fprintf(ctxt->output, " IDREF");
                break;
            case XML_ATTRIBUTE_IDREFS:
                fprintf(ctxt->output, " IDREFS");
                break;
            case XML_ATTRIBUTE_ENTITY:
                fprintf(ctxt->output, " ENTITY");
                break;
            case XML_ATTRIBUTE_ENTITIES:
                fprintf(ctxt->output, " ENTITIES");
                break;
            case XML_ATTRIBUTE_NMTOKEN:
                fprintf(ctxt->output, " NMTOKEN");
                break;
            case XML_ATTRIBUTE_NMTOKENS:
                fprintf(ctxt->output, " NMTOKENS");
                break;
            case XML_ATTRIBUTE_ENUMERATION:
                fprintf(ctxt->output, " ENUMERATION");
                break;
            case XML_ATTRIBUTE_NOTATION:
                fprintf(ctxt->output, " NOTATION ");
                break;
        }
        if (attr->tree != NULL) {
            int indx;
            xmlEnumerationPtr cur = attr->tree;

            for (indx = 0; indx < 5; indx++) {
                if (indx != 0)
                    fprintf(ctxt->output, "|%s", (char *) cur->name);
                else
                    fprintf(ctxt->output, " (%s", (char *) cur->name);
                cur = cur->next;
                if (cur == NULL)
                    break;
            }
            if (cur == NULL)
                fprintf(ctxt->output, ")");
            else
                fprintf(ctxt->output, "...)");
        }
        switch (attr->def) {
            case XML_ATTRIBUTE_NONE:
                break;
            case XML_ATTRIBUTE_REQUIRED:
                fprintf(ctxt->output, " REQUIRED");
                break;
            case XML_ATTRIBUTE_IMPLIED:
                fprintf(ctxt->output, " IMPLIED");
                break;
            case XML_ATTRIBUTE_FIXED:
                fprintf(ctxt->output, " FIXED");
                break;
        }
        if (attr->defaultValue != NULL) {
            fprintf(ctxt->output, "\"");
            xmlCtxtDumpString(ctxt, attr->defaultValue);
            fprintf(ctxt->output, "\"");
        }
        fprintf(ctxt->output, "\n");
    }

    /*
     * Do a bit of checking
     */
    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
}

static void
xmlCtxtDumpElemDecl(xmlDebugCtxtPtr ctxt, xmlElementPtr elem)
{
    xmlCtxtDumpSpaces(ctxt);

    if (elem == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "Element declaration is NULL\n");
        return;
    }
    if (elem->type != XML_ELEMENT_DECL) {
	xmlDebugErr(ctxt, XML_CHECK_NOT_ELEM_DECL,
	            "Node is not an element declaration");
        return;
    }
    if (elem->name != NULL) {
        if (!ctxt->check) {
            fprintf(ctxt->output, "ELEMDECL(");
            xmlCtxtDumpString(ctxt, elem->name);
            fprintf(ctxt->output, ")");
        }
    } else
	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
	            "Element declaration has no name");
    if (!ctxt->check) {
        switch (elem->etype) {
            case XML_ELEMENT_TYPE_UNDEFINED:
                fprintf(ctxt->output, ", UNDEFINED");
                break;
            case XML_ELEMENT_TYPE_EMPTY:
                fprintf(ctxt->output, ", EMPTY");
                break;
            case XML_ELEMENT_TYPE_ANY:
                fprintf(ctxt->output, ", ANY");
                break;
            case XML_ELEMENT_TYPE_MIXED:
                fprintf(ctxt->output, ", MIXED ");
                break;
            case XML_ELEMENT_TYPE_ELEMENT:
                fprintf(ctxt->output, ", MIXED ");
                break;
        }
        if ((elem->type != XML_ELEMENT_NODE) && (elem->content != NULL)) {
            char buf[5001];

            buf[0] = 0;
            xmlSnprintfElementContent(buf, 5000, elem->content, 1);
            buf[5000] = 0;
            fprintf(ctxt->output, "%s", buf);
        }
        fprintf(ctxt->output, "\n");
    }

    /*
     * Do a bit of checking
     */
    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) elem);
}

static void
xmlCtxtDumpEntityDecl(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
{
    xmlCtxtDumpSpaces(ctxt);

    if (ent == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "Entity declaration is NULL\n");
        return;
    }
    if (ent->type != XML_ENTITY_DECL) {
	xmlDebugErr(ctxt, XML_CHECK_NOT_ENTITY_DECL,
	            "Node is not an entity declaration");
        return;
    }
    if (ent->name != NULL) {
        if (!ctxt->check) {
            fprintf(ctxt->output, "ENTITYDECL(");
            xmlCtxtDumpString(ctxt, ent->name);
            fprintf(ctxt->output, ")");
        }
    } else
	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
	            "Entity declaration has no name");
    if (!ctxt->check) {
        switch (ent->etype) {
            case XML_INTERNAL_GENERAL_ENTITY:
                fprintf(ctxt->output, ", internal\n");
                break;
            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
                fprintf(ctxt->output, ", external parsed\n");
                break;
            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
                fprintf(ctxt->output, ", unparsed\n");
                break;
            case XML_INTERNAL_PARAMETER_ENTITY:
                fprintf(ctxt->output, ", parameter\n");
                break;
            case XML_EXTERNAL_PARAMETER_ENTITY:
                fprintf(ctxt->output, ", external parameter\n");
                break;
            case XML_INTERNAL_PREDEFINED_ENTITY:
                fprintf(ctxt->output, ", predefined\n");
                break;
        }
        if (ent->ExternalID) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, " ExternalID=%s\n",
                    (char *) ent->ExternalID);
        }
        if (ent->SystemID) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, " SystemID=%s\n",
                    (char *) ent->SystemID);
        }
        if (ent->URI != NULL) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, " URI=%s\n", (char *) ent->URI);
        }
        if (ent->content) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, " content=");
            xmlCtxtDumpString(ctxt, ent->content);
            fprintf(ctxt->output, "\n");
        }
    }

    /*
     * Do a bit of checking
     */
    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) ent);
}

static void
xmlCtxtDumpNamespace(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
{
    xmlCtxtDumpSpaces(ctxt);

    if (ns == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "namespace node is NULL\n");
        return;
    }
    if (ns->type != XML_NAMESPACE_DECL) {
	xmlDebugErr(ctxt, XML_CHECK_NOT_NS_DECL,
	            "Node is not a namespace declaration");
        return;
    }
    if (ns->href == NULL) {
        if (ns->prefix != NULL)
	    xmlDebugErr3(ctxt, XML_CHECK_NO_HREF,
                    "Incomplete namespace %s href=NULL\n",
                    (char *) ns->prefix);
        else
	    xmlDebugErr(ctxt, XML_CHECK_NO_HREF,
                    "Incomplete default namespace href=NULL\n");
    } else {
        if (!ctxt->check) {
            if (ns->prefix != NULL)
                fprintf(ctxt->output, "namespace %s href=",
                        (char *) ns->prefix);
            else
                fprintf(ctxt->output, "default namespace href=");

            xmlCtxtDumpString(ctxt, ns->href);
            fprintf(ctxt->output, "\n");
        }
    }
}

static void
xmlCtxtDumpNamespaceList(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
{
    while (ns != NULL) {
        xmlCtxtDumpNamespace(ctxt, ns);
        ns = ns->next;
    }
}

static void
xmlCtxtDumpEntity(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
{
    xmlCtxtDumpSpaces(ctxt);

    if (ent == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "Entity is NULL\n");
        return;
    }
    if (!ctxt->check) {
        switch (ent->etype) {
            case XML_INTERNAL_GENERAL_ENTITY:
                fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY ");
                break;
            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
                fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
                break;
            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
                fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
                break;
            case XML_INTERNAL_PARAMETER_ENTITY:
                fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY ");
                break;
            case XML_EXTERNAL_PARAMETER_ENTITY:
                fprintf(ctxt->output, "EXTERNAL_PARAMETER_ENTITY ");
                break;
            default:
                fprintf(ctxt->output, "ENTITY_%d ! ", (int) ent->etype);
        }
        fprintf(ctxt->output, "%s\n", ent->name);
        if (ent->ExternalID) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "ExternalID=%s\n",
                    (char *) ent->ExternalID);
        }
        if (ent->SystemID) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "SystemID=%s\n", (char *) ent->SystemID);
        }
        if (ent->URI) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "URI=%s\n", (char *) ent->URI);
        }
        if (ent->content) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "content=");
            xmlCtxtDumpString(ctxt, ent->content);
            fprintf(ctxt->output, "\n");
        }
    }
}

/**
 * xmlCtxtDumpAttr:
 * @output:  the FILE * for the output
 * @attr:  the attribute
 * @depth:  the indentation level.
 *
 * Dumps debug information for the attribute
 */
static void
xmlCtxtDumpAttr(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
{
    xmlCtxtDumpSpaces(ctxt);

    if (attr == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "Attr is NULL");
        return;
    }
    if (!ctxt->check) {
        fprintf(ctxt->output, "ATTRIBUTE ");
	xmlCtxtDumpString(ctxt, attr->name);
        fprintf(ctxt->output, "\n");
        if (attr->children != NULL) {
            ctxt->depth++;
            xmlCtxtDumpNodeList(ctxt, attr->children);
            ctxt->depth--;
        }
    }
    if (attr->name == NULL)
	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
	            "Attribute has no name");

    /*
     * Do a bit of checking
     */
    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
}

/**
 * xmlCtxtDumpAttrList:
 * @output:  the FILE * for the output
 * @attr:  the attribute list
 * @depth:  the indentation level.
 *
 * Dumps debug information for the attribute list
 */
static void
xmlCtxtDumpAttrList(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
{
    while (attr != NULL) {
        xmlCtxtDumpAttr(ctxt, attr);
        attr = attr->next;
    }
}

/**
 * xmlCtxtDumpOneNode:
 * @output:  the FILE * for the output
 * @node:  the node
 * @depth:  the indentation level.
 *
 * Dumps debug information for the element node, it is not recursive
 */
static void
xmlCtxtDumpOneNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
{
    if (node == NULL) {
        if (!ctxt->check) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "node is NULL\n");
        }
        return;
    }
    ctxt->node = node;

    switch (node->type) {
        case XML_ELEMENT_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "ELEMENT ");
                if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
                    xmlCtxtDumpString(ctxt, node->ns->prefix);
                    fprintf(ctxt->output, ":");
                }
                xmlCtxtDumpString(ctxt, node->name);
                fprintf(ctxt->output, "\n");
            }
            break;
        case XML_ATTRIBUTE_NODE:
            if (!ctxt->check)
                xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
            xmlCtxtGenericNodeCheck(ctxt, node);
            return;
        case XML_TEXT_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                if (node->name == (const xmlChar *) xmlStringTextNoenc)
                    fprintf(ctxt->output, "TEXT no enc");
                else
                    fprintf(ctxt->output, "TEXT");
		if (ctxt->options & DUMP_TEXT_TYPE) {
		    if (node->content == (xmlChar *) &(node->properties))
			fprintf(ctxt->output, " compact\n");
		    else if (xmlDictOwns(ctxt->dict, node->content) == 1)
			fprintf(ctxt->output, " interned\n");
		    else
			fprintf(ctxt->output, "\n");
		} else
		    fprintf(ctxt->output, "\n");
            }
            break;
        case XML_CDATA_SECTION_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "CDATA_SECTION\n");
            }
            break;
        case XML_ENTITY_REF_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "ENTITY_REF(%s)\n",
                        (char *) node->name);
            }
            break;
        case XML_ENTITY_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "ENTITY\n");
            }
            break;
        case XML_PI_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "PI %s\n", (char *) node->name);
            }
            break;
        case XML_COMMENT_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "COMMENT\n");
            }
            break;
        case XML_DOCUMENT_NODE:
        case XML_HTML_DOCUMENT_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
            }
            fprintf(ctxt->output, "Error, DOCUMENT found here\n");
            xmlCtxtGenericNodeCheck(ctxt, node);
            return;
        case XML_DOCUMENT_TYPE_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "DOCUMENT_TYPE\n");
            }
            break;
        case XML_DOCUMENT_FRAG_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "DOCUMENT_FRAG\n");
            }
            break;
        case XML_NOTATION_NODE:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "NOTATION\n");
            }
            break;
        case XML_DTD_NODE:
            xmlCtxtDumpDtdNode(ctxt, (xmlDtdPtr) node);
            return;
        case XML_ELEMENT_DECL:
            xmlCtxtDumpElemDecl(ctxt, (xmlElementPtr) node);
            return;
        case XML_ATTRIBUTE_DECL:
            xmlCtxtDumpAttrDecl(ctxt, (xmlAttributePtr) node);
            return;
        case XML_ENTITY_DECL:
            xmlCtxtDumpEntityDecl(ctxt, (xmlEntityPtr) node);
            return;
        case XML_NAMESPACE_DECL:
            xmlCtxtDumpNamespace(ctxt, (xmlNsPtr) node);
            return;
        case XML_XINCLUDE_START:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "INCLUDE START\n");
            }
            return;
        case XML_XINCLUDE_END:
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "INCLUDE END\n");
            }
            return;
        default:
            if (!ctxt->check)
                xmlCtxtDumpSpaces(ctxt);
	    xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
	                "Unknown node type %d\n", node->type);
            return;
    }
    if (node->doc == NULL) {
        if (!ctxt->check) {
            xmlCtxtDumpSpaces(ctxt);
        }
        fprintf(ctxt->output, "PBM: doc == NULL !!!\n");
    }
    ctxt->depth++;
    if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
        xmlCtxtDumpNamespaceList(ctxt, node->nsDef);
    if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
        xmlCtxtDumpAttrList(ctxt, node->properties);
    if (node->type != XML_ENTITY_REF_NODE) {
        if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
            if (!ctxt->check) {
                xmlCtxtDumpSpaces(ctxt);
                fprintf(ctxt->output, "content=");
                xmlCtxtDumpString(ctxt, node->content);
                fprintf(ctxt->output, "\n");
            }
        }
    } else {
        xmlEntityPtr ent;

        ent = xmlGetDocEntity(node->doc, node->name);
        if (ent != NULL)
            xmlCtxtDumpEntity(ctxt, ent);
    }
    ctxt->depth--;

    /*
     * Do a bit of checking
     */
    xmlCtxtGenericNodeCheck(ctxt, node);
}

/**
 * xmlCtxtDumpNode:
 * @output:  the FILE * for the output
 * @node:  the node
 * @depth:  the indentation level.
 *
 * Dumps debug information for the element node, it is recursive
 */
static void
xmlCtxtDumpNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
{
    if (node == NULL) {
        if (!ctxt->check) {
            xmlCtxtDumpSpaces(ctxt);
            fprintf(ctxt->output, "node is NULL\n");
        }
        return;
    }
    xmlCtxtDumpOneNode(ctxt, node);
    if ((node->type != XML_NAMESPACE_DECL) &&
        (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
        ctxt->depth++;
        xmlCtxtDumpNodeList(ctxt, node->children);
        ctxt->depth--;
    }
}

/**
 * xmlCtxtDumpNodeList:
 * @output:  the FILE * for the output
 * @node:  the node list
 * @depth:  the indentation level.
 *
 * Dumps debug information for the list of element node, it is recursive
 */
static void
xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
{
    while (node != NULL) {
        xmlCtxtDumpNode(ctxt, node);
        node = node->next;
    }
}

static void
xmlCtxtDumpDocHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
{
    if (doc == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "DOCUMENT == NULL !\n");
        return;
    }
    ctxt->node = (xmlNodePtr) doc;

    switch (doc->type) {
        case XML_ELEMENT_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ELEMENT,
	                "Misplaced ELEMENT node\n");
            break;
        case XML_ATTRIBUTE_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ATTRIBUTE,
	                "Misplaced ATTRIBUTE node\n");
            break;
        case XML_TEXT_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_TEXT,
	                "Misplaced TEXT node\n");
            break;
        case XML_CDATA_SECTION_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_CDATA,
	                "Misplaced CDATA node\n");
            break;
        case XML_ENTITY_REF_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITYREF,
	                "Misplaced ENTITYREF node\n");
            break;
        case XML_ENTITY_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITY,
	                "Misplaced ENTITY node\n");
            break;
        case XML_PI_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_PI,
	                "Misplaced PI node\n");
            break;
        case XML_COMMENT_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_COMMENT,
	                "Misplaced COMMENT node\n");
            break;
        case XML_DOCUMENT_NODE:
	    if (!ctxt->check)
		fprintf(ctxt->output, "DOCUMENT\n");
            break;
        case XML_HTML_DOCUMENT_NODE:
	    if (!ctxt->check)
		fprintf(ctxt->output, "HTML DOCUMENT\n");
            break;
        case XML_DOCUMENT_TYPE_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE,
	                "Misplaced DOCTYPE node\n");
            break;
        case XML_DOCUMENT_FRAG_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_FRAGMENT,
	                "Misplaced FRAGMENT node\n");
            break;
        case XML_NOTATION_NODE:
	    xmlDebugErr(ctxt, XML_CHECK_FOUND_NOTATION,
	                "Misplaced NOTATION node\n");
            break;
        default:
	    xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
	                "Unknown node type %d\n", doc->type);
    }
}

/**
 * xmlCtxtDumpDocumentHead:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Dumps debug information concerning the document, not recursive
 */
static void
xmlCtxtDumpDocumentHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
{
    if (doc == NULL) return;
    xmlCtxtDumpDocHead(ctxt, doc);
    if (!ctxt->check) {
        if (doc->name != NULL) {
            fprintf(ctxt->output, "name=");
            xmlCtxtDumpString(ctxt, BAD_CAST doc->name);
            fprintf(ctxt->output, "\n");
        }
        if (doc->version != NULL) {
            fprintf(ctxt->output, "version=");
            xmlCtxtDumpString(ctxt, doc->version);
            fprintf(ctxt->output, "\n");
        }
        if (doc->encoding != NULL) {
            fprintf(ctxt->output, "encoding=");
            xmlCtxtDumpString(ctxt, doc->encoding);
            fprintf(ctxt->output, "\n");
        }
        if (doc->URL != NULL) {
            fprintf(ctxt->output, "URL=");
            xmlCtxtDumpString(ctxt, doc->URL);
            fprintf(ctxt->output, "\n");
        }
        if (doc->standalone)
            fprintf(ctxt->output, "standalone=true\n");
    }
    if (doc->oldNs != NULL)
        xmlCtxtDumpNamespaceList(ctxt, doc->oldNs);
}

/**
 * xmlCtxtDumpDocument:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Dumps debug information for the document, it's recursive
 */
static void
xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
{
    if (doc == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "DOCUMENT == NULL !\n");
        return;
    }
    xmlCtxtDumpDocumentHead(ctxt, doc);
    if (((doc->type == XML_DOCUMENT_NODE) ||
         (doc->type == XML_HTML_DOCUMENT_NODE))
        && (doc->children != NULL)) {
        ctxt->depth++;
        xmlCtxtDumpNodeList(ctxt, doc->children);
        ctxt->depth--;
    }
}

static void
xmlCtxtDumpEntityCallback(void *payload, void *data,
                          const xmlChar *name ATTRIBUTE_UNUSED)
{
    xmlEntityPtr cur = (xmlEntityPtr) payload;
    xmlDebugCtxtPtr ctxt = (xmlDebugCtxtPtr) data;
    if (cur == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "Entity is NULL");
        return;
    }
    if (!ctxt->check) {
        fprintf(ctxt->output, "%s : ", (char *) cur->name);
        switch (cur->etype) {
            case XML_INTERNAL_GENERAL_ENTITY:
                fprintf(ctxt->output, "INTERNAL GENERAL, ");
                break;
            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
                fprintf(ctxt->output, "EXTERNAL PARSED, ");
                break;
            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
                fprintf(ctxt->output, "EXTERNAL UNPARSED, ");
                break;
            case XML_INTERNAL_PARAMETER_ENTITY:
                fprintf(ctxt->output, "INTERNAL PARAMETER, ");
                break;
            case XML_EXTERNAL_PARAMETER_ENTITY:
                fprintf(ctxt->output, "EXTERNAL PARAMETER, ");
                break;
            default:
		xmlDebugErr2(ctxt, XML_CHECK_ENTITY_TYPE,
			     "Unknown entity type %d\n", cur->etype);
        }
        if (cur->ExternalID != NULL)
            fprintf(ctxt->output, "ID \"%s\"", (char *) cur->ExternalID);
        if (cur->SystemID != NULL)
            fprintf(ctxt->output, "SYSTEM \"%s\"", (char *) cur->SystemID);
        if (cur->orig != NULL)
            fprintf(ctxt->output, "\n orig \"%s\"", (char *) cur->orig);
        if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL))
            fprintf(ctxt->output, "\n content \"%s\"",
                    (char *) cur->content);
        fprintf(ctxt->output, "\n");
    }
}

/**
 * xmlCtxtDumpEntities:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Dumps debug information for all the entities in use by the document
 */
static void
xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
{
    if (doc == NULL) return;
    xmlCtxtDumpDocHead(ctxt, doc);
    if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
        xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
            doc->intSubset->entities;

        if (!ctxt->check)
            fprintf(ctxt->output, "Entities in internal subset\n");
        xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt);
    } else
        fprintf(ctxt->output, "No entities in internal subset\n");
    if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
        xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
            doc->extSubset->entities;

        if (!ctxt->check)
            fprintf(ctxt->output, "Entities in external subset\n");
        xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt);
    } else if (!ctxt->check)
        fprintf(ctxt->output, "No entities in external subset\n");
}

/**
 * xmlCtxtDumpDTD:
 * @output:  the FILE * for the output
 * @dtd:  the DTD
 *
 * Dumps debug information for the DTD
 */
static void
xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
{
    if (dtd == NULL) {
        if (!ctxt->check)
            fprintf(ctxt->output, "DTD is NULL\n");
        return;
    }
    xmlCtxtDumpDtdNode(ctxt, dtd);
    if (dtd->children == NULL)
        fprintf(ctxt->output, "    DTD is empty\n");
    else {
        ctxt->depth++;
        xmlCtxtDumpNodeList(ctxt, dtd->children);
        ctxt->depth--;
    }
}

/************************************************************************
 *									*
 *			Public entry points for dump			*
 *									*
 ************************************************************************/

/**
 * xmlDebugDumpString:
 * @output:  the FILE * for the output
 * @str:  the string
 *
 * Dumps information about the string, shorten it if necessary
 */
void
xmlDebugDumpString(FILE * output, const xmlChar * str)
{
    int i;

    if (output == NULL)
	output = stdout;
    if (str == NULL) {
        fprintf(output, "(NULL)");
        return;
    }
    for (i = 0; i < 40; i++)
        if (str[i] == 0)
            return;
        else if (IS_BLANK_CH(str[i]))
            fputc(' ', output);
        else if (str[i] >= 0x80)
            fprintf(output, "#%X", str[i]);
        else
            fputc(str[i], output);
    fprintf(output, "...");
}

/**
 * xmlDebugDumpAttr:
 * @output:  the FILE * for the output
 * @attr:  the attribute
 * @depth:  the indentation level.
 *
 * Dumps debug information for the attribute
 */
void
xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
    xmlDebugCtxt ctxt;

    if (output == NULL) return;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    ctxt.depth = depth;
    xmlCtxtDumpAttr(&ctxt, attr);
    xmlCtxtDumpCleanCtxt(&ctxt);
}


/**
 * xmlDebugDumpEntities:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Dumps debug information for all the entities in use by the document
 */
void
xmlDebugDumpEntities(FILE * output, xmlDocPtr doc)
{
    xmlDebugCtxt ctxt;

    if (output == NULL) return;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    xmlCtxtDumpEntities(&ctxt, doc);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpAttrList:
 * @output:  the FILE * for the output
 * @attr:  the attribute list
 * @depth:  the indentation level.
 *
 * Dumps debug information for the attribute list
 */
void
xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
{
    xmlDebugCtxt ctxt;

    if (output == NULL) return;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    ctxt.depth = depth;
    xmlCtxtDumpAttrList(&ctxt, attr);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpOneNode:
 * @output:  the FILE * for the output
 * @node:  the node
 * @depth:  the indentation level.
 *
 * Dumps debug information for the element node, it is not recursive
 */
void
xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
{
    xmlDebugCtxt ctxt;

    if (output == NULL) return;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    ctxt.depth = depth;
    xmlCtxtDumpOneNode(&ctxt, node);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpNode:
 * @output:  the FILE * for the output
 * @node:  the node
 * @depth:  the indentation level.
 *
 * Dumps debug information for the element node, it is recursive
 */
void
xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
{
    xmlDebugCtxt ctxt;

    if (output == NULL)
	output = stdout;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    ctxt.depth = depth;
    xmlCtxtDumpNode(&ctxt, node);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpNodeList:
 * @output:  the FILE * for the output
 * @node:  the node list
 * @depth:  the indentation level.
 *
 * Dumps debug information for the list of element node, it is recursive
 */
void
xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
{
    xmlDebugCtxt ctxt;

    if (output == NULL)
	output = stdout;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    ctxt.depth = depth;
    xmlCtxtDumpNodeList(&ctxt, node);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpDocumentHead:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Dumps debug information concerning the document, not recursive
 */
void
xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
{
    xmlDebugCtxt ctxt;

    if (output == NULL)
	output = stdout;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.options |= DUMP_TEXT_TYPE;
    ctxt.output = output;
    xmlCtxtDumpDocumentHead(&ctxt, doc);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpDocument:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Dumps debug information for the document, it's recursive
 */
void
xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
{
    xmlDebugCtxt ctxt;

    if (output == NULL)
	output = stdout;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.options |= DUMP_TEXT_TYPE;
    ctxt.output = output;
    xmlCtxtDumpDocument(&ctxt, doc);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/**
 * xmlDebugDumpDTD:
 * @output:  the FILE * for the output
 * @dtd:  the DTD
 *
 * Dumps debug information for the DTD
 */
void
xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
{
    xmlDebugCtxt ctxt;

    if (output == NULL)
	output = stdout;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.options |= DUMP_TEXT_TYPE;
    ctxt.output = output;
    xmlCtxtDumpDTD(&ctxt, dtd);
    xmlCtxtDumpCleanCtxt(&ctxt);
}

/************************************************************************
 *									*
 *			Public entry points for checkings		*
 *									*
 ************************************************************************/

/**
 * xmlDebugCheckDocument:
 * @output:  the FILE * for the output
 * @doc:  the document
 *
 * Check the document for potential content problems, and output
 * the errors to @output
 *
 * Returns the number of errors found
 */
int
xmlDebugCheckDocument(FILE * output, xmlDocPtr doc)
{
    xmlDebugCtxt ctxt;

    if (output == NULL)
	output = stdout;
    xmlCtxtDumpInitCtxt(&ctxt);
    ctxt.output = output;
    ctxt.check = 1;
    xmlCtxtDumpDocument(&ctxt, doc);
    xmlCtxtDumpCleanCtxt(&ctxt);
    return(ctxt.errors);
}

#endif /* LIBXML_DEBUG_ENABLED */
