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

#include "private/error.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;

/**
 * _xmlSchematronLet:
 *
 * A Schematron let variable
 */
typedef struct _xmlSchematronLet xmlSchematronLet;
typedef xmlSchematronLet *xmlSchematronLetPtr;
struct _xmlSchematronLet {
    xmlSchematronLetPtr next; /* the next let variable in the list */
    xmlChar *name;            /* the name of the variable */
    xmlXPathCompExprPtr comp; /* the compiled expression */
};

/**
 * _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 */
    xmlSchematronLetPtr lets;   /* the list of let variables */
};

/**
 * _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;
    }
}

/**
 * xmlSchematronFreeLets:
 * @lets:  a list of let variables
 *
 * Free a list of let variables.
 */
static void
xmlSchematronFreeLets(xmlSchematronLetPtr lets) {
    xmlSchematronLetPtr next;

    while (lets != NULL) {
        next = lets->next;
        if (lets->name != NULL)
            xmlFree(lets->name);
        if (lets->comp != NULL)
            xmlXPathFreeCompExpr(lets->comp);
        xmlFree(lets);
        lets = 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;
    ret->lets = 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);
        if (rules->lets != NULL)
            xmlSchematronFreeLets(rules->lets);
        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;

}

/**
 * xmlSchematronParseTestReportMsg:
 * @ctxt:  the schema parser context
 * @con:  the assert or report node
 *
 * Format the message content of the assert or report test
 */
static void
xmlSchematronParseTestReportMsg(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr con)
{
    xmlNodePtr child;
    xmlXPathCompExprPtr comp;

    child = con->children;
    while (child != NULL) {
        if ((child->type == XML_TEXT_NODE) ||
            (child->type == XML_CDATA_SECTION_NODE))
            /* Do Nothing */
            {}
        else if (IS_SCHEMATRON(child, "name")) {
            /* Do Nothing */
        } else if (IS_SCHEMATRON(child, "value-of")) {
            xmlChar *select;

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

            if (select == NULL) {
                xmlSchematronPErr(ctxt, child,
                                  XML_SCHEMAV_ATTRINVALID,
                                  "value-of has no select attribute",
                                  NULL, NULL);
            } else {
                /*
                 * try first to compile the test expression
                 */
                comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
                if (comp == NULL) {
                    xmlSchematronPErr(ctxt, child,
                                      XML_SCHEMAV_ATTRINVALID,
                                      "Failed to compile select expression %s",
                                      select, NULL);
                }
                xmlXPathFreeCompExpr(comp);
            }
            xmlFree(select);
        }
        child = child->next;
        continue;
    }
}

/**
 * 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;
    xmlChar *name;
    xmlChar *value;
    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, "let")) {
            xmlXPathCompExprPtr var_comp;
            xmlSchematronLetPtr let;

            name = xmlGetNoNsProp(cur, BAD_CAST "name");
            if (name == NULL) {
                xmlSchematronPErr(ctxt, cur,
                                  XML_SCHEMAP_NOROOT,
                                  "let has no name attribute",
                                  NULL, NULL);
                return;
            } else if (name[0] == 0) {
                xmlSchematronPErr(ctxt, cur,
                                  XML_SCHEMAP_NOROOT,
                                  "let has an empty name attribute",
                                  NULL, NULL);
                xmlFree(name);
                return;
            }
            value = xmlGetNoNsProp(cur, BAD_CAST "value");
            if (value == NULL) {
                xmlSchematronPErr(ctxt, cur,
                                  XML_SCHEMAP_NOROOT,
                                  "let has no value attribute",
                                  NULL, NULL);
                return;
            } else if (value[0] == 0) {
                xmlSchematronPErr(ctxt, cur,
                                  XML_SCHEMAP_NOROOT,
                                  "let has an empty value attribute",
                                  NULL, NULL);
                xmlFree(value);
                return;
            }

            var_comp = xmlXPathCtxtCompile(ctxt->xctxt, value);
            if (var_comp == NULL) {
                xmlSchematronPErr(ctxt, cur,
                                  XML_SCHEMAP_NOROOT,
                                  "Failed to compile let expression %s",
                                  value, NULL);
                return;
            }

            let = (xmlSchematronLetPtr) malloc(sizeof(xmlSchematronLet));
            let->name = name;
            let->comp = var_comp;
            let->next = NULL;

            /* add new let variable to the beginning of the list */
            if (ruleptr->lets != NULL) {
                let->next = ruleptr->lets;
            }
            ruleptr->lets = let;

            xmlFree(value);
        } else 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 {
                xmlSchematronParseTestReportMsg(ctxt, cur);
                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 {
                xmlSchematronParseTestReportMsg(ctxt, cur);
                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;
    xmlXPathCompExprPtr comp;

    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 if (IS_SCHEMATRON(child, "value-of")) {
            xmlChar *select;
            xmlXPathObjectPtr eval;

            select = xmlGetNoNsProp(child, BAD_CAST "select");
            comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
            eval = xmlXPathCompiledEval(comp, ctxt->xctxt);

            switch (eval->type) {
            case XPATH_NODESET: {
                int indx;
                xmlChar *spacer = BAD_CAST " ";

                if (eval->nodesetval) {
                    for (indx = 0; indx < eval->nodesetval->nodeNr; indx++) {
                        if (indx > 0)
                            ret = xmlStrcat(ret, spacer);
                        ret = xmlStrcat(ret, eval->nodesetval->nodeTab[indx]->name);
                    }
                } else {
                    xmlGenericError(xmlGenericErrorContext,
                                    "Empty node set\n");
                }
                break;
            }
            case XPATH_BOOLEAN: {
                const char *str = eval->boolval ? "True" : "False";
                ret = xmlStrcat(ret, BAD_CAST str);
                break;
            }
            case XPATH_NUMBER: {
                xmlChar *buf;
                int size;

                size = snprintf(NULL, 0, "%0g", eval->floatval);
                buf = (xmlChar*) malloc(size);
                /* xmlStrPrintf(buf, size, "%0g", eval->floatval); // doesn't work */
                sprintf((char*) buf, "%0g", eval->floatval);
                ret = xmlStrcat(ret, buf);
                free(buf);
                break;
            }
            case XPATH_STRING:
                ret = xmlStrcat(ret, eval->stringval);
                break;
            default:
                xmlGenericError(xmlGenericErrorContext,
                                "Unsupported XPATH Type: %d\n", eval->type);
            }
            xmlXPathFreeObject(eval);
            xmlXPathFreeCompExpr(comp);
            xmlFree(select);
        } 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:
#ifdef LIBXML_XPTR_LOCS_ENABLED
            case XPATH_POINT:
            case XPATH_RANGE:
            case XPATH_LOCATIONSET:
#endif
            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);
}

/**
 * xmlSchematronRegisterVariables:
 * @ctxt:  the schema validation context
 * @let:  the list of let variables
 * @instance:  the document instance tree
 * @cur:  the current node
 *
 * Registers a list of let variables to the current context of @cur
 *
 * Returns -1 in case of errors, otherwise 0
 */
static int
xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let,
                               xmlDocPtr instance, xmlNodePtr cur)
{
    xmlXPathObjectPtr let_eval;

    ctxt->doc = instance;
    ctxt->node = cur;
    while (let != NULL) {
        let_eval = xmlXPathCompiledEval(let->comp, ctxt);
        if (let_eval == NULL) {
            xmlGenericError(xmlGenericErrorContext,
                            "Evaluation of compiled expression failed\n");
            return -1;
        }
        if(xmlXPathRegisterVariableNS(ctxt, let->name, NULL, let_eval)) {
            xmlGenericError(xmlGenericErrorContext,
                            "Registering a let variable failed\n");
            return -1;
        }
        let = let->next;
    }
    return 0;
}

/**
 * xmlSchematronUnregisterVariables:
 * @ctxt:  the schema validation context
 * @let:  the list of let variables
 *
 * Unregisters a list of let variables from the context
 *
 * Returns -1 in case of errors, otherwise 0
 */
static int
xmlSchematronUnregisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let)
{
    while (let != NULL) {
        if (xmlXPathRegisterVariableNS(ctxt, let->name, NULL, NULL)) {
            xmlGenericError(xmlGenericErrorContext,
                            "Unregistering a let variable failed\n");
            return -1;
        }
        let = let->next;
    }
    return 0;
}

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

                    if (xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets, instance, cur))
                        return -1;

                    while (test != NULL) {
                        xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
                        test = test->next;
                    }

                    if (xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets))
                        return -1;

                }
                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;
                        xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets,
                                                       instance, cur);

                        while (test != NULL) {
                            xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
                            test = test->next;
                        }

                        xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets);
                    }
                    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

#endif /* LIBXML_SCHEMATRON_ENABLED */
