/*
 * 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

#ifdef HAVE_STRING_H
#include <string.h>
#endif
#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 dictionnary 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;

#ifndef STARBOARD
    FILE *outputFile;		/* if using XML_SCHEMATRON_OUT_FILE */
#endif
    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;            /* dictionnary 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 informations
 *
 * 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
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 informations
 *
 * 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);
    }
    XML_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);
    }
    XML_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);
    }
    XML_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);
    }
    XML_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);
    }
    XML_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);
    }
    XML_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);
    }
    XML_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 Shema struture 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 */
#ifndef STARBOARD
    fprintf(stderr, "%s", msg);
#else
    SbLogFormatF("%s", msg);
#endif
}

/**
 * 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 teh 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");
	    }
	    }
	    XML_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;
	XML_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);
    }
    XML_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 instace 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 instace 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 */
