/*
 * schematron.c : implementation of the Schematron schema validity checking
 *
 * See Copyright for the status of this software.
 *
 * Daniel Veillard <daniel@veillard.com>
 */

/*
 * TODO:
 * + double check the semantic, especially
 *        - multiple rules applying in a single pattern/node
 *        - the semantic of libxml2 patterns vs. XSLT production referenced
 *          by the spec.
 * + export of results in SVRL
 * + full parsing and coverage of the spec, conformance of the input to the
 *   spec
 * + divergences between the draft and the ISO proposed standard :-(
 * + hook and test include
 * + try and compare with the XSLT version
 */

#define IN_LIBXML
#include "libxml.h"

#ifdef LIBXML_SCHEMATRON_ENABLED

#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxml/pattern.h>
#include <libxml/schematron.h>

#define SCHEMATRON_PARSE_OPTIONS XML_PARSE_NOENT

#define SCT_OLD_NS BAD_CAST "http://www.ascc.net/xml/schematron"

#define XML_SCHEMATRON_NS BAD_CAST "http://purl.oclc.org/dsdl/schematron"


static const xmlChar *xmlSchematronNs = XML_SCHEMATRON_NS;
static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS;

#define IS_SCHEMATRON(node, elem)					\
   ((node != NULL) && (node->type == XML_ELEMENT_NODE ) &&		\
    (node->ns != NULL) &&						\
    (xmlStrEqual(node->name, (const xmlChar *) elem)) &&		\
    ((xmlStrEqual(node->ns->href, xmlSchematronNs)) ||			\
     (xmlStrEqual(node->ns->href, xmlOldSchematronNs))))

#define NEXT_SCHEMATRON(node)						\
   while (node != NULL) {						\
       if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) &&	\
           ((xmlStrEqual(node->ns->href, xmlSchematronNs)) ||		\
	    (xmlStrEqual(node->ns->href, xmlOldSchematronNs))))		\
	   break;							\
       node = node->next;						\
   }

/**
 * TODO:
 *
 * macro to flag unimplemented blocks
 */
#define TODO								\
    xmlGenericError(xmlGenericErrorContext,				\
	    "Unimplemented block at %s:%d\n",				\
            __FILE__, __LINE__);

typedef enum {
    XML_SCHEMATRON_ASSERT=1,
    XML_SCHEMATRON_REPORT=2
} xmlSchematronTestType;

/**
 * _xmlSchematronTest:
 *
 * A Schematrons test, either an assert or a report
 */
typedef struct _xmlSchematronTest xmlSchematronTest;
typedef xmlSchematronTest *xmlSchematronTestPtr;
struct _xmlSchematronTest {
    xmlSchematronTestPtr next;	/* the next test in the list */
    xmlSchematronTestType type;	/* the test type */
    xmlNodePtr node;		/* the node in the tree */
    xmlChar *test;		/* the expression to test */
    xmlXPathCompExprPtr comp;	/* the compiled expression */
    xmlChar *report;		/* the message to report */
};

/**
 * _xmlSchematronRule:
 *
 * A Schematrons rule
 */
typedef struct _xmlSchematronRule xmlSchematronRule;
typedef xmlSchematronRule *xmlSchematronRulePtr;
struct _xmlSchematronRule {
    xmlSchematronRulePtr next;	/* the next rule in the list */
    xmlSchematronRulePtr patnext;/* the next rule in the pattern list */
    xmlNodePtr node;		/* the node in the tree */
    xmlChar *context;		/* the context evaluation rule */
    xmlSchematronTestPtr tests;	/* the list of tests */
    xmlPatternPtr pattern;	/* the compiled pattern associated */
    xmlChar *report;		/* the message to report */
};

/**
 * _xmlSchematronPattern:
 *
 * A Schematrons pattern
 */
typedef struct _xmlSchematronPattern xmlSchematronPattern;
typedef xmlSchematronPattern *xmlSchematronPatternPtr;
struct _xmlSchematronPattern {
    xmlSchematronPatternPtr next;/* the next pattern in the list */
    xmlSchematronRulePtr rules;	/* the list of rules */
    xmlChar *name;		/* the name of the pattern */
};

/**
 * _xmlSchematron:
 *
 * A Schematrons definition
 */
struct _xmlSchematron {
    const xmlChar *name;	/* schema name */
    int preserve;		/* was the document passed by the user */
    xmlDocPtr doc;		/* pointer to the parsed document */
    int flags;			/* specific to this schematron */

    void *_private;		/* unused by the library */
    xmlDictPtr dict;		/* the dictionary used internally */

    const xmlChar *title;	/* the title if any */

    int nbNs;			/* the number of namespaces */

    int nbPattern;		/* the number of patterns */
    xmlSchematronPatternPtr patterns;/* the patterns found */
    xmlSchematronRulePtr rules;	/* the rules gathered */
    int nbNamespaces;		/* number of namespaces in the array */
    int maxNamespaces;		/* size of the array */
    const xmlChar **namespaces;	/* the array of namespaces */
};

/**
 * xmlSchematronValidCtxt:
 *
 * A Schematrons validation context
 */
struct _xmlSchematronValidCtxt {
    int type;
    int flags;			/* an or of xmlSchematronValidOptions */

    xmlDictPtr dict;
    int nberrors;
    int err;

    xmlSchematronPtr schema;
    xmlXPathContextPtr xctxt;

    FILE *outputFile;		/* if using XML_SCHEMATRON_OUT_FILE */
    xmlBufferPtr outputBuffer;	/* if using XML_SCHEMATRON_OUT_BUFFER */
#ifdef LIBXML_OUTPUT_ENABLED
    xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
    xmlOutputCloseCallback  ioclose;
#endif
    void *ioctx;

    /* error reporting data */
    void *userData;                      /* user specific data block */
    xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
    xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
    xmlStructuredErrorFunc serror;       /* the structured function */
};

struct _xmlSchematronParserCtxt {
    int type;
    const xmlChar *URL;
    xmlDocPtr doc;
    int preserve;               /* Whether the doc should be freed  */
    const char *buffer;
    int size;

    xmlDictPtr dict;            /* dictionary for interned string names */

    int nberrors;
    int err;
    xmlXPathContextPtr xctxt;	/* the XPath context used for compilation */
    xmlSchematronPtr schema;

    int nbNamespaces;		/* number of namespaces in the array */
    int maxNamespaces;		/* size of the array */
    const xmlChar **namespaces;	/* the array of namespaces */

    int nbIncludes;		/* number of includes in the array */
    int maxIncludes;		/* size of the array */
    xmlNodePtr *includes;	/* the array of includes */

    /* error reporting data */
    void *userData;                      /* user specific data block */
    xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
    xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
    xmlStructuredErrorFunc serror;       /* the structured function */
};

#define XML_STRON_CTXT_PARSER 1
#define XML_STRON_CTXT_VALIDATOR 2

/************************************************************************
 *									*
 *			Error reporting					*
 *									*
 ************************************************************************/

/**
 * xmlSchematronPErrMemory:
 * @node: a context node
 * @extra:  extra information
 *
 * Handle an out of memory condition
 */
static void
xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt,
                        const char *extra, xmlNodePtr node)
{
    if (ctxt != NULL)
        ctxt->nberrors++;
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
                     extra);
}

/**
 * xmlSchematronPErr:
 * @ctxt: the parsing context
 * @node: the context node
 * @error: the error code
 * @msg: the error message
 * @str1: extra data
 * @str2: extra data
 *
 * Handle a parser error
 */
static void LIBXML_ATTR_FORMAT(4,0)
xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
              const char *msg, const xmlChar * str1, const xmlChar * str2)
{
    xmlGenericErrorFunc channel = NULL;
    xmlStructuredErrorFunc schannel = NULL;
    void *data = NULL;

    if (ctxt != NULL) {
        ctxt->nberrors++;
        channel = ctxt->error;
        data = ctxt->userData;
	schannel = ctxt->serror;
    }
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
                    error, XML_ERR_ERROR, NULL, 0,
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    msg, str1, str2);
}

/**
 * xmlSchematronVTypeErrMemory:
 * @node: a context node
 * @extra:  extra information
 *
 * Handle an out of memory condition
 */
static void
xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
                        const char *extra, xmlNodePtr node)
{
    if (ctxt != NULL) {
        ctxt->nberrors++;
        ctxt->err = XML_SCHEMAV_INTERNAL;
    }
    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
                     extra);
}

/************************************************************************
 *									*
 *		Parsing and compilation of the Schematrontrons		*
 *									*
 ************************************************************************/

/**
 * xmlSchematronAddTest:
 * @ctxt: the schema parsing context
 * @type:  the type of test
 * @rule:  the parent rule
 * @node:  the node hosting the test
 * @test: the associated test
 * @report: the associated report string
 *
 * Add a test to a schematron
 *
 * Returns the new pointer or NULL in case of error
 */
static xmlSchematronTestPtr
xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt,
                     xmlSchematronTestType type,
                     xmlSchematronRulePtr rule,
                     xmlNodePtr node, xmlChar *test, xmlChar *report)
{
    xmlSchematronTestPtr ret;
    xmlXPathCompExprPtr comp;

    if ((ctxt == NULL) || (rule == NULL) || (node == NULL) ||
        (test == NULL))
        return(NULL);

    /*
     * try first to compile the test expression
     */
    comp = xmlXPathCtxtCompile(ctxt->xctxt, test);
    if (comp == NULL) {
	xmlSchematronPErr(ctxt, node,
	    XML_SCHEMAP_NOROOT,
	    "Failed to compile test expression %s",
	    test, NULL);
	return(NULL);
    }

    ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest));
    if (ret == NULL) {
        xmlSchematronPErrMemory(ctxt, "allocating schema test", node);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronTest));
    ret->type = type;
    ret->node = node;
    ret->test = test;
    ret->comp = comp;
    ret->report = report;
    ret->next = NULL;
    if (rule->tests == NULL) {
	rule->tests = ret;
    } else {
        xmlSchematronTestPtr prev = rule->tests;

	while (prev->next != NULL)
	     prev = prev->next;
        prev->next = ret;
    }
    return (ret);
}

/**
 * xmlSchematronFreeTests:
 * @tests:  a list of tests
 *
 * Free a list of tests.
 */
static void
xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
    xmlSchematronTestPtr next;

    while (tests != NULL) {
        next = tests->next;
	if (tests->test != NULL)
	    xmlFree(tests->test);
	if (tests->comp != NULL)
	    xmlXPathFreeCompExpr(tests->comp);
	if (tests->report != NULL)
	    xmlFree(tests->report);
	xmlFree(tests);
	tests = next;
    }
}

/**
 * xmlSchematronAddRule:
 * @ctxt: the schema parsing context
 * @schema:  a schema structure
 * @node:  the node hosting the rule
 * @context: the associated context string
 * @report: the associated report string
 *
 * Add a rule to a schematron
 *
 * Returns the new pointer or NULL in case of error
 */
static xmlSchematronRulePtr
xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
                     xmlSchematronPatternPtr pat, xmlNodePtr node,
		     xmlChar *context, xmlChar *report)
{
    xmlSchematronRulePtr ret;
    xmlPatternPtr pattern;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
        (context == NULL))
        return(NULL);

    /*
     * Try first to compile the pattern
     */
    pattern = xmlPatterncompile(context, ctxt->dict, XML_PATTERN_XPATH,
                                ctxt->namespaces);
    if (pattern == NULL) {
	xmlSchematronPErr(ctxt, node,
	    XML_SCHEMAP_NOROOT,
	    "Failed to compile context expression %s",
	    context, NULL);
    }

    ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule));
    if (ret == NULL) {
        xmlSchematronPErrMemory(ctxt, "allocating schema rule", node);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronRule));
    ret->node = node;
    ret->context = context;
    ret->pattern = pattern;
    ret->report = report;
    ret->next = NULL;
    if (schema->rules == NULL) {
	schema->rules = ret;
    } else {
        xmlSchematronRulePtr prev = schema->rules;

	while (prev->next != NULL)
	     prev = prev->next;
        prev->next = ret;
    }
    ret->patnext = NULL;
    if (pat->rules == NULL) {
	pat->rules = ret;
    } else {
        xmlSchematronRulePtr prev = pat->rules;

	while (prev->patnext != NULL)
	     prev = prev->patnext;
        prev->patnext = ret;
    }
    return (ret);
}

/**
 * xmlSchematronFreeRules:
 * @rules:  a list of rules
 *
 * Free a list of rules.
 */
static void
xmlSchematronFreeRules(xmlSchematronRulePtr rules) {
    xmlSchematronRulePtr next;

    while (rules != NULL) {
        next = rules->next;
	if (rules->tests)
	    xmlSchematronFreeTests(rules->tests);
	if (rules->context != NULL)
	    xmlFree(rules->context);
	if (rules->pattern)
	    xmlFreePattern(rules->pattern);
	if (rules->report != NULL)
	    xmlFree(rules->report);
	xmlFree(rules);
	rules = next;
    }
}

/**
 * xmlSchematronAddPattern:
 * @ctxt: the schema parsing context
 * @schema:  a schema structure
 * @node:  the node hosting the pattern
 * @id: the id or name of the pattern
 *
 * Add a pattern to a schematron
 *
 * Returns the new pointer or NULL in case of error
 */
static xmlSchematronPatternPtr
xmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt,
                     xmlSchematronPtr schema, xmlNodePtr node, xmlChar *name)
{
    xmlSchematronPatternPtr ret;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || (name == NULL))
        return(NULL);

    ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern));
    if (ret == NULL) {
        xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronPattern));
    ret->name = name;
    ret->next = NULL;
    if (schema->patterns == NULL) {
	schema->patterns = ret;
    } else {
        xmlSchematronPatternPtr prev = schema->patterns;

	while (prev->next != NULL)
	     prev = prev->next;
        prev->next = ret;
    }
    return (ret);
}

/**
 * xmlSchematronFreePatterns:
 * @patterns:  a list of patterns
 *
 * Free a list of patterns.
 */
static void
xmlSchematronFreePatterns(xmlSchematronPatternPtr patterns) {
    xmlSchematronPatternPtr next;

    while (patterns != NULL) {
        next = patterns->next;
	if (patterns->name != NULL)
	    xmlFree(patterns->name);
	xmlFree(patterns);
	patterns = next;
    }
}

/**
 * xmlSchematronNewSchematron:
 * @ctxt:  a schema validation context
 *
 * Allocate a new Schematron structure.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlSchematronPtr
xmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt)
{
    xmlSchematronPtr ret;

    ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron));
    if (ret == NULL) {
        xmlSchematronPErrMemory(ctxt, "allocating schema", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematron));
    ret->dict = ctxt->dict;
    xmlDictReference(ret->dict);

    return (ret);
}

/**
 * xmlSchematronFree:
 * @schema:  a schema structure
 *
 * Deallocate a Schematron structure.
 */
void
xmlSchematronFree(xmlSchematronPtr schema)
{
    if (schema == NULL)
        return;

    if ((schema->doc != NULL) && (!(schema->preserve)))
        xmlFreeDoc(schema->doc);

    if (schema->namespaces != NULL)
        xmlFree((char **) schema->namespaces);

    xmlSchematronFreeRules(schema->rules);
    xmlSchematronFreePatterns(schema->patterns);
    xmlDictFree(schema->dict);
    xmlFree(schema);
}

/**
 * xmlSchematronNewParserCtxt:
 * @URL:  the location of the schema
 *
 * Create an XML Schematrons parse context for that file/resource expected
 * to contain an XML Schematrons file.
 *
 * Returns the parser context or NULL in case of error
 */
xmlSchematronParserCtxtPtr
xmlSchematronNewParserCtxt(const char *URL)
{
    xmlSchematronParserCtxtPtr ret;

    if (URL == NULL)
        return (NULL);

    ret =
        (xmlSchematronParserCtxtPtr)
        xmlMalloc(sizeof(xmlSchematronParserCtxt));
    if (ret == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser context",
                                NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronParserCtxt));
    ret->type = XML_STRON_CTXT_PARSER;
    ret->dict = xmlDictCreate();
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
    ret->includes = NULL;
    ret->xctxt = xmlXPathNewContext(NULL);
    if (ret->xctxt == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
                                NULL);
	xmlSchematronFreeParserCtxt(ret);
        return (NULL);
    }
    ret->xctxt->flags = XML_XPATH_CHECKNS;
    return (ret);
}

/**
 * xmlSchematronNewMemParserCtxt:
 * @buffer:  a pointer to a char array containing the schemas
 * @size:  the size of the array
 *
 * Create an XML Schematrons parse context for that memory buffer expected
 * to contain an XML Schematrons file.
 *
 * Returns the parser context or NULL in case of error
 */
xmlSchematronParserCtxtPtr
xmlSchematronNewMemParserCtxt(const char *buffer, int size)
{
    xmlSchematronParserCtxtPtr ret;

    if ((buffer == NULL) || (size <= 0))
        return (NULL);

    ret =
        (xmlSchematronParserCtxtPtr)
        xmlMalloc(sizeof(xmlSchematronParserCtxt));
    if (ret == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser context",
                                NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronParserCtxt));
    ret->buffer = buffer;
    ret->size = size;
    ret->dict = xmlDictCreate();
    ret->xctxt = xmlXPathNewContext(NULL);
    if (ret->xctxt == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
                                NULL);
	xmlSchematronFreeParserCtxt(ret);
        return (NULL);
    }
    return (ret);
}

/**
 * xmlSchematronNewDocParserCtxt:
 * @doc:  a preparsed document tree
 *
 * Create an XML Schematrons parse context for that document.
 * NB. The document may be modified during the parsing process.
 *
 * Returns the parser context or NULL in case of error
 */
xmlSchematronParserCtxtPtr
xmlSchematronNewDocParserCtxt(xmlDocPtr doc)
{
    xmlSchematronParserCtxtPtr ret;

    if (doc == NULL)
        return (NULL);

    ret =
        (xmlSchematronParserCtxtPtr)
        xmlMalloc(sizeof(xmlSchematronParserCtxt));
    if (ret == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser context",
                                NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronParserCtxt));
    ret->doc = doc;
    ret->dict = xmlDictCreate();
    /* The application has responsibility for the document */
    ret->preserve = 1;
    ret->xctxt = xmlXPathNewContext(doc);
    if (ret->xctxt == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
                                NULL);
	xmlSchematronFreeParserCtxt(ret);
        return (NULL);
    }

    return (ret);
}

/**
 * xmlSchematronFreeParserCtxt:
 * @ctxt:  the schema parser context
 *
 * Free the resources associated to the schema parser context
 */
void
xmlSchematronFreeParserCtxt(xmlSchematronParserCtxtPtr ctxt)
{
    if (ctxt == NULL)
        return;
    if (ctxt->doc != NULL && !ctxt->preserve)
        xmlFreeDoc(ctxt->doc);
    if (ctxt->xctxt != NULL) {
        xmlXPathFreeContext(ctxt->xctxt);
    }
    if (ctxt->namespaces != NULL)
        xmlFree((char **) ctxt->namespaces);
    xmlDictFree(ctxt->dict);
    xmlFree(ctxt);
}

#if 0
/**
 * xmlSchematronPushInclude:
 * @ctxt:  the schema parser context
 * @doc:  the included document
 * @cur:  the current include node
 *
 * Add an included document
 */
static void
xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt,
                        xmlDocPtr doc, xmlNodePtr cur)
{
    if (ctxt->includes == NULL) {
        ctxt->maxIncludes = 10;
        ctxt->includes = (xmlNodePtr *)
	    xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
	if (ctxt->includes == NULL) {
	    xmlSchematronPErrMemory(NULL, "allocating parser includes",
				    NULL);
	    return;
	}
        ctxt->nbIncludes = 0;
    } else if (ctxt->nbIncludes + 2 >= ctxt->maxIncludes) {
        xmlNodePtr *tmp;

	tmp = (xmlNodePtr *)
	    xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
	               sizeof(xmlNodePtr));
	if (tmp == NULL) {
	    xmlSchematronPErrMemory(NULL, "allocating parser includes",
				    NULL);
	    return;
	}
        ctxt->includes = tmp;
	ctxt->maxIncludes *= 2;
    }
    ctxt->includes[2 * ctxt->nbIncludes] = cur;
    ctxt->includes[2 * ctxt->nbIncludes + 1] = (xmlNodePtr) doc;
    ctxt->nbIncludes++;
}

/**
 * xmlSchematronPopInclude:
 * @ctxt:  the schema parser context
 *
 * Pop an include level. The included document is being freed
 *
 * Returns the node immediately following the include or NULL if the
 *         include list was empty.
 */
static xmlNodePtr
xmlSchematronPopInclude(xmlSchematronParserCtxtPtr ctxt)
{
    xmlDocPtr doc;
    xmlNodePtr ret;

    if (ctxt->nbIncludes <= 0)
        return(NULL);
    ctxt->nbIncludes--;
    doc = (xmlDocPtr) ctxt->includes[2 * ctxt->nbIncludes + 1];
    ret = ctxt->includes[2 * ctxt->nbIncludes];
    xmlFreeDoc(doc);
    if (ret != NULL)
	ret = ret->next;
    if (ret == NULL)
        return(xmlSchematronPopInclude(ctxt));
    return(ret);
}
#endif

/**
 * xmlSchematronAddNamespace:
 * @ctxt:  the schema parser context
 * @prefix:  the namespace prefix
 * @ns:  the namespace name
 *
 * Add a namespace definition in the context
 */
static void
xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
                          const xmlChar *prefix, const xmlChar *ns)
{
    if (ctxt->namespaces == NULL) {
        ctxt->maxNamespaces = 10;
        ctxt->namespaces = (const xmlChar **)
	    xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
	if (ctxt->namespaces == NULL) {
	    xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
				    NULL);
	    return;
	}
        ctxt->nbNamespaces = 0;
    } else if (ctxt->nbNamespaces + 2 >= ctxt->maxNamespaces) {
        const xmlChar **tmp;

	tmp = (const xmlChar **)
	    xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
	               sizeof(const xmlChar *));
	if (tmp == NULL) {
	    xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
				    NULL);
	    return;
	}
        ctxt->namespaces = tmp;
	ctxt->maxNamespaces *= 2;
    }
    ctxt->namespaces[2 * ctxt->nbNamespaces] =
        xmlDictLookup(ctxt->dict, ns, -1);
    ctxt->namespaces[2 * ctxt->nbNamespaces + 1] =
        xmlDictLookup(ctxt->dict, prefix, -1);
    ctxt->nbNamespaces++;
    ctxt->namespaces[2 * ctxt->nbNamespaces] = NULL;
    ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = NULL;

}

/**
 * xmlSchematronParseRule:
 * @ctxt:  a schema validation context
 * @rule:  the rule node
 *
 * parse a rule element
 */
static void
xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
                       xmlSchematronPatternPtr pattern,
		       xmlNodePtr rule)
{
    xmlNodePtr cur;
    int nbChecks = 0;
    xmlChar *test;
    xmlChar *context;
    xmlChar *report;
    xmlSchematronRulePtr ruleptr;
    xmlSchematronTestPtr testptr;

    if ((ctxt == NULL) || (rule == NULL)) return;

    context = xmlGetNoNsProp(rule, BAD_CAST "context");
    if (context == NULL) {
	xmlSchematronPErr(ctxt, rule,
	    XML_SCHEMAP_NOROOT,
	    "rule has no context attribute",
	    NULL, NULL);
	return;
    } else if (context[0] == 0) {
	xmlSchematronPErr(ctxt, rule,
	    XML_SCHEMAP_NOROOT,
	    "rule has an empty context attribute",
	    NULL, NULL);
	xmlFree(context);
	return;
    } else {
	ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern,
	                               rule, context, NULL);
	if (ruleptr == NULL) {
	    xmlFree(context);
	    return;
	}
    }

    cur = rule->children;
    NEXT_SCHEMATRON(cur);
    while (cur != NULL) {
	if (IS_SCHEMATRON(cur, "assert")) {
	    nbChecks++;
	    test = xmlGetNoNsProp(cur, BAD_CAST "test");
	    if (test == NULL) {
		xmlSchematronPErr(ctxt, cur,
		    XML_SCHEMAP_NOROOT,
		    "assert has no test attribute",
		    NULL, NULL);
	    } else if (test[0] == 0) {
		xmlSchematronPErr(ctxt, cur,
		    XML_SCHEMAP_NOROOT,
		    "assert has an empty test attribute",
		    NULL, NULL);
		xmlFree(test);
	    } else {
		/* TODO will need dynamic processing instead */
		report = xmlNodeGetContent(cur);

		testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
		                               ruleptr, cur, test, report);
		if (testptr == NULL)
		    xmlFree(test);
	    }
	} else if (IS_SCHEMATRON(cur, "report")) {
	    nbChecks++;
	    test = xmlGetNoNsProp(cur, BAD_CAST "test");
	    if (test == NULL) {
		xmlSchematronPErr(ctxt, cur,
		    XML_SCHEMAP_NOROOT,
		    "assert has no test attribute",
		    NULL, NULL);
	    } else if (test[0] == 0) {
		xmlSchematronPErr(ctxt, cur,
		    XML_SCHEMAP_NOROOT,
		    "assert has an empty test attribute",
		    NULL, NULL);
		xmlFree(test);
	    } else {
		/* TODO will need dynamic processing instead */
		report = xmlNodeGetContent(cur);

		testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
		                               ruleptr, cur, test, report);
		if (testptr == NULL)
		    xmlFree(test);
	    }
	} else {
	    xmlSchematronPErr(ctxt, cur,
		XML_SCHEMAP_NOROOT,
		"Expecting an assert or a report element instead of %s",
		cur->name, NULL);
	}
	cur = cur->next;
	NEXT_SCHEMATRON(cur);
    }
    if (nbChecks == 0) {
	xmlSchematronPErr(ctxt, rule,
	    XML_SCHEMAP_NOROOT,
	    "rule has no assert nor report element", NULL, NULL);
    }
}

/**
 * xmlSchematronParsePattern:
 * @ctxt:  a schema validation context
 * @pat:  the pattern node
 *
 * parse a pattern element
 */
static void
xmlSchematronParsePattern(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr pat)
{
    xmlNodePtr cur;
    xmlSchematronPatternPtr pattern;
    int nbRules = 0;
    xmlChar *id;

    if ((ctxt == NULL) || (pat == NULL)) return;

    id = xmlGetNoNsProp(pat, BAD_CAST "id");
    if (id == NULL) {
	id = xmlGetNoNsProp(pat, BAD_CAST "name");
    }
    pattern = xmlSchematronAddPattern(ctxt, ctxt->schema, pat, id);
    if (pattern == NULL) {
	if (id != NULL)
	    xmlFree(id);
        return;
    }
    cur = pat->children;
    NEXT_SCHEMATRON(cur);
    while (cur != NULL) {
	if (IS_SCHEMATRON(cur, "rule")) {
	    xmlSchematronParseRule(ctxt, pattern, cur);
	    nbRules++;
	} else {
	    xmlSchematronPErr(ctxt, cur,
		XML_SCHEMAP_NOROOT,
		"Expecting a rule element instead of %s", cur->name, NULL);
	}
	cur = cur->next;
	NEXT_SCHEMATRON(cur);
    }
    if (nbRules == 0) {
	xmlSchematronPErr(ctxt, pat,
	    XML_SCHEMAP_NOROOT,
	    "Pattern has no rule element", NULL, NULL);
    }
}

#if 0
/**
 * xmlSchematronLoadInclude:
 * @ctxt:  a schema validation context
 * @cur:  the include element
 *
 * Load the include document, Push the current pointer
 *
 * Returns the updated node pointer
 */
static xmlNodePtr
xmlSchematronLoadInclude(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr cur)
{
    xmlNodePtr ret = NULL;
    xmlDocPtr doc = NULL;
    xmlChar *href = NULL;
    xmlChar *base = NULL;
    xmlChar *URI = NULL;

    if ((ctxt == NULL) || (cur == NULL))
        return(NULL);

    href = xmlGetNoNsProp(cur, BAD_CAST "href");
    if (href == NULL) {
	xmlSchematronPErr(ctxt, cur,
	    XML_SCHEMAP_NOROOT,
	    "Include has no href attribute", NULL, NULL);
	return(cur->next);
    }

    /* do the URI base composition, load and find the root */
    base = xmlNodeGetBase(cur->doc, cur);
    URI = xmlBuildURI(href, base);
    doc = xmlReadFile((const char *) URI, NULL, SCHEMATRON_PARSE_OPTIONS);
    if (doc == NULL) {
	xmlSchematronPErr(ctxt, cur,
		      XML_SCHEMAP_FAILED_LOAD,
		      "could not load include '%s'.\n",
		      URI, NULL);
	goto done;
    }
    ret = xmlDocGetRootElement(doc);
    if (ret == NULL) {
	xmlSchematronPErr(ctxt, cur,
		      XML_SCHEMAP_FAILED_LOAD,
		      "could not find root from include '%s'.\n",
		      URI, NULL);
	goto done;
    }

    /* Success, push the include for rollback on exit */
    xmlSchematronPushInclude(ctxt, doc, cur);

done:
    if (ret == NULL) {
        if (doc != NULL)
	    xmlFreeDoc(doc);
    }
    xmlFree(href);
    if (base != NULL)
        xmlFree(base);
    if (URI != NULL)
        xmlFree(URI);
    return(ret);
}
#endif

/**
 * xmlSchematronParse:
 * @ctxt:  a schema validation context
 *
 * parse a schema definition resource and build an internal
 * XML Schema structure which can be used to validate instances.
 *
 * Returns the internal XML Schematron structure built from the resource or
 *         NULL in case of error
 */
xmlSchematronPtr
xmlSchematronParse(xmlSchematronParserCtxtPtr ctxt)
{
    xmlSchematronPtr ret = NULL;
    xmlDocPtr doc;
    xmlNodePtr root, cur;
    int preserve = 0;

    if (ctxt == NULL)
        return (NULL);

    ctxt->nberrors = 0;

    /*
     * First step is to parse the input document into an DOM/Infoset
     */
    if (ctxt->URL != NULL) {
        doc = xmlReadFile((const char *) ctxt->URL, NULL,
	                  SCHEMATRON_PARSE_OPTIONS);
        if (doc == NULL) {
	    xmlSchematronPErr(ctxt, NULL,
			  XML_SCHEMAP_FAILED_LOAD,
                          "xmlSchematronParse: could not load '%s'.\n",
                          ctxt->URL, NULL);
            return (NULL);
        }
	ctxt->preserve = 0;
    } else if (ctxt->buffer != NULL) {
        doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
	                    SCHEMATRON_PARSE_OPTIONS);
        if (doc == NULL) {
	    xmlSchematronPErr(ctxt, NULL,
			  XML_SCHEMAP_FAILED_PARSE,
                          "xmlSchematronParse: could not parse.\n",
                          NULL, NULL);
            return (NULL);
        }
        doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
        ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
	ctxt->preserve = 0;
    } else if (ctxt->doc != NULL) {
        doc = ctxt->doc;
	preserve = 1;
	ctxt->preserve = 1;
    } else {
	xmlSchematronPErr(ctxt, NULL,
		      XML_SCHEMAP_NOTHING_TO_PARSE,
		      "xmlSchematronParse: could not parse.\n",
		      NULL, NULL);
        return (NULL);
    }

    /*
     * Then extract the root and Schematron parse it
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
	xmlSchematronPErr(ctxt, (xmlNodePtr) doc,
		      XML_SCHEMAP_NOROOT,
		      "The schema has no document element.\n", NULL, NULL);
	if (!preserve) {
	    xmlFreeDoc(doc);
	}
        return (NULL);
    }

    if (!IS_SCHEMATRON(root, "schema")) {
	xmlSchematronPErr(ctxt, root,
	    XML_SCHEMAP_NOROOT,
	    "The XML document '%s' is not a XML schematron document",
	    ctxt->URL, NULL);
	goto exit;
    }
    ret = xmlSchematronNewSchematron(ctxt);
    if (ret == NULL)
        goto exit;
    ctxt->schema = ret;

    /*
     * scan the schema elements
     */
    cur = root->children;
    NEXT_SCHEMATRON(cur);
    if (IS_SCHEMATRON(cur, "title")) {
        xmlChar *title = xmlNodeGetContent(cur);
	if (title != NULL) {
	    ret->title = xmlDictLookup(ret->dict, title, -1);
	    xmlFree(title);
	}
	cur = cur->next;
	NEXT_SCHEMATRON(cur);
    }
    while (IS_SCHEMATRON(cur, "ns")) {
        xmlChar *prefix = xmlGetNoNsProp(cur, BAD_CAST "prefix");
        xmlChar *uri = xmlGetNoNsProp(cur, BAD_CAST "uri");
	if ((uri == NULL) || (uri[0] == 0)) {
	    xmlSchematronPErr(ctxt, cur,
		XML_SCHEMAP_NOROOT,
		"ns element has no uri", NULL, NULL);
	}
	if ((prefix == NULL) || (prefix[0] == 0)) {
	    xmlSchematronPErr(ctxt, cur,
		XML_SCHEMAP_NOROOT,
		"ns element has no prefix", NULL, NULL);
	}
	if ((prefix) && (uri)) {
	    xmlXPathRegisterNs(ctxt->xctxt, prefix, uri);
	    xmlSchematronAddNamespace(ctxt, prefix, uri);
	    ret->nbNs++;
	}
	if (uri)
	    xmlFree(uri);
	if (prefix)
	    xmlFree(prefix);
	cur = cur->next;
	NEXT_SCHEMATRON(cur);
    }
    while (cur != NULL) {
	if (IS_SCHEMATRON(cur, "pattern")) {
	    xmlSchematronParsePattern(ctxt, cur);
	    ret->nbPattern++;
	} else {
	    xmlSchematronPErr(ctxt, cur,
		XML_SCHEMAP_NOROOT,
		"Expecting a pattern element instead of %s", cur->name, NULL);
	}
	cur = cur->next;
	NEXT_SCHEMATRON(cur);
    }
    if (ret->nbPattern == 0) {
	xmlSchematronPErr(ctxt, root,
	    XML_SCHEMAP_NOROOT,
	    "The schematron document '%s' has no pattern",
	    ctxt->URL, NULL);
	goto exit;
    }
    /* the original document must be kept for reporting */
    ret->doc = doc;
    if (preserve) {
	    ret->preserve = 1;
    }
    preserve = 1;

exit:
    if (!preserve) {
	xmlFreeDoc(doc);
    }
    if (ret != NULL) {
	if (ctxt->nberrors != 0) {
	    xmlSchematronFree(ret);
	    ret = NULL;
	} else {
	    ret->namespaces = ctxt->namespaces;
	    ret->nbNamespaces = ctxt->nbNamespaces;
	    ctxt->namespaces = NULL;
	}
    }
    return (ret);
}

/************************************************************************
 *									*
 *		Schematrontron Reports handler				*
 *									*
 ************************************************************************/

static xmlNodePtr
xmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt,
                     xmlNodePtr cur, const xmlChar *xpath) {
    xmlNodePtr node = NULL;
    xmlXPathObjectPtr ret;

    if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL))
        return(NULL);

    ctxt->xctxt->doc = cur->doc;
    ctxt->xctxt->node = cur;
    ret = xmlXPathEval(xpath, ctxt->xctxt);
    if (ret == NULL)
        return(NULL);

    if ((ret->type == XPATH_NODESET) &&
        (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
	node = ret->nodesetval->nodeTab[0];

    xmlXPathFreeObject(ret);
    return(node);
}

/**
 * xmlSchematronReportOutput:
 * @ctxt: the validation context
 * @cur: the current node tested
 * @msg: the message output
 *
 * Output part of the report to whatever channel the user selected
 */
static void
xmlSchematronReportOutput(xmlSchematronValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
                          xmlNodePtr cur ATTRIBUTE_UNUSED,
                          const char *msg) {
    /* TODO */
    fprintf(stderr, "%s", msg);
}

/**
 * xmlSchematronFormatReport:
 * @ctxt:  the validation context
 * @test: the test node
 * @cur: the current node tested
 *
 * Build the string being reported to the user.
 *
 * Returns a report string or NULL in case of error. The string needs
 *         to be deallocated by the caller
 */
static xmlChar *
xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
			  xmlNodePtr test, xmlNodePtr cur) {
    xmlChar *ret = NULL;
    xmlNodePtr child, node;

    if ((test == NULL) || (cur == NULL))
        return(ret);

    child = test->children;
    while (child != NULL) {
        if ((child->type == XML_TEXT_NODE) ||
	    (child->type == XML_CDATA_SECTION_NODE))
	    ret = xmlStrcat(ret, child->content);
	else if (IS_SCHEMATRON(child, "name")) {
	    xmlChar *path;

	    path = xmlGetNoNsProp(child, BAD_CAST "path");

            node = cur;
	    if (path != NULL) {
	        node = xmlSchematronGetNode(ctxt, cur, path);
		if (node == NULL)
		    node = cur;
		xmlFree(path);
	    }

	    if ((node->ns == NULL) || (node->ns->prefix == NULL))
	        ret = xmlStrcat(ret, node->name);
	    else {
	        ret = xmlStrcat(ret, node->ns->prefix);
	        ret = xmlStrcat(ret, BAD_CAST ":");
	        ret = xmlStrcat(ret, node->name);
	    }
	} else {
	    child = child->next;
	    continue;
	}

	/*
	 * remove superfluous \n
	 */
	if (ret != NULL) {
	    int len = xmlStrlen(ret);
	    xmlChar c;

	    if (len > 0) {
		c = ret[len - 1];
		if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) {
		    while ((c == ' ') || (c == '\n') ||
		           (c == '\r') || (c == '\t')) {
			len--;
			if (len == 0)
			    break;
			c = ret[len - 1];
		    }
		    ret[len] = ' ';
		    ret[len + 1] = 0;
		}
	    }
	}

        child = child->next;
    }
    return(ret);
}

/**
 * xmlSchematronReportSuccess:
 * @ctxt:  the validation context
 * @test: the compiled test
 * @cur: the current node tested
 * @success: boolean value for the result
 *
 * called from the validation engine when an assert or report test have
 * been done.
 */
static void
xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
		   xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, int success) {
    if ((ctxt == NULL) || (cur == NULL) || (test == NULL))
        return;
    /* if quiet and not SVRL report only failures */
    if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) &&
        ((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) &&
	(test->type == XML_SCHEMATRON_REPORT))
        return;
    if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
        TODO
    } else {
        xmlChar *path;
	char msg[1000];
	long line;
	const xmlChar *report = NULL;

        if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) ||
	    ((test->type == XML_SCHEMATRON_ASSERT) & (success)))
	    return;
	line = xmlGetLineNo(cur);
	path = xmlGetNodePath(cur);
	if (path == NULL)
	    path = (xmlChar *) cur->name;
#if 0
	if ((test->report != NULL) && (test->report[0] != 0))
	    report = test->report;
#endif
	if (test->node != NULL)
            report = xmlSchematronFormatReport(ctxt, test->node, cur);
	if (report == NULL) {
	    if (test->type == XML_SCHEMATRON_ASSERT) {
            report = xmlStrdup((const xmlChar *) "node failed assert");
	    } else {
            report = xmlStrdup((const xmlChar *) "node failed report");
	    }
	    }
	    snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
		     line, (const char *) report);

    if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) {
        xmlStructuredErrorFunc schannel = NULL;
        xmlGenericErrorFunc channel = NULL;
        void *data = NULL;

        if (ctxt != NULL) {
            if (ctxt->serror != NULL)
                schannel = ctxt->serror;
            else
                channel = ctxt->error;
            data = ctxt->userData;
	}

        __xmlRaiseError(schannel, channel, data,
                        NULL, cur, XML_FROM_SCHEMATRONV,
                        (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT,
                        XML_ERR_ERROR, NULL, line,
                        (pattern == NULL)?NULL:((const char *) pattern->name),
                        (const char *) path,
                        (const char *) report, 0, 0,
                        "%s", msg);
    } else {
	xmlSchematronReportOutput(ctxt, cur, &msg[0]);
    }

    xmlFree((char *) report);

	if ((path != NULL) && (path != (xmlChar *) cur->name))
	    xmlFree(path);
    }
}

/**
 * xmlSchematronReportPattern:
 * @ctxt:  the validation context
 * @pattern: the current pattern
 *
 * called from the validation engine when starting to check a pattern
 */
static void
xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
			   xmlSchematronPatternPtr pattern) {
    if ((ctxt == NULL) || (pattern == NULL))
        return;
    if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */
        return;
    if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
        TODO
    } else {
	char msg[1000];

	if (pattern->name == NULL)
	    return;
	snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name);
	xmlSchematronReportOutput(ctxt, NULL, &msg[0]);
    }
}


/************************************************************************
 *									*
 *		Validation against a Schematrontron				*
 *									*
 ************************************************************************/

/**
 * xmlSchematronSetValidStructuredErrors:
 * @ctxt:  a Schematron validation context
 * @serror:  the structured error function
 * @ctx: the functions context
 *
 * Set the structured error callback
 */
void
xmlSchematronSetValidStructuredErrors(xmlSchematronValidCtxtPtr ctxt,
                                      xmlStructuredErrorFunc serror, void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->serror = serror;
    ctxt->error = NULL;
    ctxt->warning = NULL;
    ctxt->userData = ctx;
}

/**
 * xmlSchematronNewValidCtxt:
 * @schema:  a precompiled XML Schematrons
 * @options: a set of xmlSchematronValidOptions
 *
 * Create an XML Schematrons validation context based on the given schema.
 *
 * Returns the validation context or NULL in case of error
 */
xmlSchematronValidCtxtPtr
xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
{
    int i;
    xmlSchematronValidCtxtPtr ret;

    ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt));
    if (ret == NULL) {
        xmlSchematronVErrMemory(NULL, "allocating validation context",
                                NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchematronValidCtxt));
    ret->type = XML_STRON_CTXT_VALIDATOR;
    ret->schema = schema;
    ret->xctxt = xmlXPathNewContext(NULL);
    ret->flags = options;
    if (ret->xctxt == NULL) {
        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
                                NULL);
	xmlSchematronFreeValidCtxt(ret);
        return (NULL);
    }
    for (i = 0;i < schema->nbNamespaces;i++) {
        if ((schema->namespaces[2 * i] == NULL) ||
            (schema->namespaces[2 * i + 1] == NULL))
	    break;
	xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1],
	                   schema->namespaces[2 * i]);
    }
    return (ret);
}

/**
 * xmlSchematronFreeValidCtxt:
 * @ctxt:  the schema validation context
 *
 * Free the resources associated to the schema validation context
 */
void
xmlSchematronFreeValidCtxt(xmlSchematronValidCtxtPtr ctxt)
{
    if (ctxt == NULL)
        return;
    if (ctxt->xctxt != NULL)
        xmlXPathFreeContext(ctxt->xctxt);
    if (ctxt->dict != NULL)
        xmlDictFree(ctxt->dict);
    xmlFree(ctxt);
}

static xmlNodePtr
xmlSchematronNextNode(xmlNodePtr cur) {
    if (cur->children != NULL) {
	/*
	 * Do not descend on entities declarations
	 */
	if (cur->children->type != XML_ENTITY_DECL) {
	    cur = cur->children;
	    /*
	     * Skip DTDs
	     */
	    if (cur->type != XML_DTD_NODE)
		return(cur);
	}
    }

    while (cur->next != NULL) {
	cur = cur->next;
	if ((cur->type != XML_ENTITY_DECL) &&
	    (cur->type != XML_DTD_NODE))
	    return(cur);
    }

    do {
	cur = cur->parent;
	if (cur == NULL) break;
	if (cur->type == XML_DOCUMENT_NODE) return(NULL);
	if (cur->next != NULL) {
	    cur = cur->next;
	    return(cur);
	}
    } while (cur != NULL);
    return(cur);
}

/**
 * xmlSchematronRunTest:
 * @ctxt:  the schema validation context
 * @test:  the current test
 * @instance:  the document instance tree
 * @cur:  the current node in the instance
 *
 * Validate a rule against a tree instance at a given position
 *
 * Returns 1 in case of success, 0 if error and -1 in case of internal error
 */
static int
xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
     xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur, xmlSchematronPatternPtr pattern)
{
    xmlXPathObjectPtr ret;
    int failed;

    failed = 0;
    ctxt->xctxt->doc = instance;
    ctxt->xctxt->node = cur;
    ret = xmlXPathCompiledEval(test->comp, ctxt->xctxt);
    if (ret == NULL) {
	failed = 1;
    } else {
        switch (ret->type) {
	    case XPATH_XSLT_TREE:
	    case XPATH_NODESET:
		if ((ret->nodesetval == NULL) ||
		    (ret->nodesetval->nodeNr == 0))
		    failed = 1;
		break;
	    case XPATH_BOOLEAN:
		failed = !ret->boolval;
		break;
	    case XPATH_NUMBER:
		if ((xmlXPathIsNaN(ret->floatval)) ||
		    (ret->floatval == 0.0))
		    failed = 1;
		break;
	    case XPATH_STRING:
		if ((ret->stringval == NULL) ||
		    (ret->stringval[0] == 0))
		    failed = 1;
		break;
	    case XPATH_UNDEFINED:
	    case XPATH_POINT:
	    case XPATH_RANGE:
	    case XPATH_LOCATIONSET:
	    case XPATH_USERS:
		failed = 1;
		break;
	}
	xmlXPathFreeObject(ret);
    }
    if ((failed) && (test->type == XML_SCHEMATRON_ASSERT))
        ctxt->nberrors++;
    else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT))
        ctxt->nberrors++;

    xmlSchematronReportSuccess(ctxt, test, cur, pattern, !failed);

    return(!failed);
}

/**
 * xmlSchematronValidateDoc:
 * @ctxt:  the schema validation context
 * @instance:  the document instance tree
 *
 * Validate a tree instance against the schematron
 *
 * Returns 0 in case of success, -1 in case of internal error
 *         and an error count otherwise.
 */
int
xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
{
    xmlNodePtr cur, root;
    xmlSchematronPatternPtr pattern;
    xmlSchematronRulePtr rule;
    xmlSchematronTestPtr test;

    if ((ctxt == NULL) || (ctxt->schema == NULL) ||
        (ctxt->schema->rules == NULL) || (instance == NULL))
        return(-1);
    ctxt->nberrors = 0;
    root = xmlDocGetRootElement(instance);
    if (root == NULL) {
        TODO
	ctxt->nberrors++;
	return(1);
    }
    if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) ||
        (ctxt->flags == 0)) {
	/*
	 * we are just trying to assert the validity of the document,
	 * speed primes over the output, run in a single pass
	 */
	cur = root;
	while (cur != NULL) {
	    rule = ctxt->schema->rules;
	    while (rule != NULL) {
		if (xmlPatternMatch(rule->pattern, cur) == 1) {
		    test = rule->tests;
		    while (test != NULL) {
			xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
			test = test->next;
		    }
		}
		rule = rule->next;
	    }

	    cur = xmlSchematronNextNode(cur);
	}
    } else {
        /*
	 * Process all contexts one at a time
	 */
	pattern = ctxt->schema->patterns;

	while (pattern != NULL) {
	    xmlSchematronReportPattern(ctxt, pattern);

	    /*
	     * TODO convert the pattern rule to a direct XPath and
	     * compute directly instead of using the pattern matching
	     * over the full document...
	     * Check the exact semantic
	     */
	    cur = root;
	    while (cur != NULL) {
		rule = pattern->rules;
		while (rule != NULL) {
		    if (xmlPatternMatch(rule->pattern, cur) == 1) {
			test = rule->tests;
			while (test != NULL) {
			    xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
			    test = test->next;
			}
		    }
		    rule = rule->patnext;
		}

		cur = xmlSchematronNextNode(cur);
	    }
	    pattern = pattern->next;
	}
    }
    return(ctxt->nberrors);
}

#ifdef STANDALONE
int
main(void)
{
    int ret;
    xmlDocPtr instance;
    xmlSchematronParserCtxtPtr pctxt;
    xmlSchematronValidCtxtPtr vctxt;
    xmlSchematronPtr schema = NULL;

    pctxt = xmlSchematronNewParserCtxt("tst.sct");
    if (pctxt == NULL) {
        fprintf(stderr, "failed to build schematron parser\n");
    } else {
        schema = xmlSchematronParse(pctxt);
	if (schema == NULL) {
	    fprintf(stderr, "failed to compile schematron\n");
	}
	xmlSchematronFreeParserCtxt(pctxt);
    }
    instance = xmlReadFile("tst.sct", NULL,
                           XML_PARSE_NOENT | XML_PARSE_NOCDATA);
    if (instance == NULL) {
	fprintf(stderr, "failed to parse instance\n");
    }
    if ((schema != NULL) && (instance != NULL)) {
        vctxt = xmlSchematronNewValidCtxt(schema);
	if (vctxt == NULL) {
	    fprintf(stderr, "failed to build schematron validator\n");
	} else {
	    ret = xmlSchematronValidateDoc(vctxt, instance);
	    xmlSchematronFreeValidCtxt(vctxt);
	}
    }
    xmlSchematronFree(schema);
    xmlFreeDoc(instance);

    xmlCleanupParser();
    xmlMemoryDump();

    return (0);
}
#endif
#define bottom_schematron
#include "elfgcchack.h"
#endif /* LIBXML_SCHEMATRON_ENABLED */
