/*
 * 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 <stdlib.h>
#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 *) xmlMalloc(size + 1);
                if (buf != NULL) {
                    snprintf((char *) buf, size + 1, "%0g", eval->floatval);
                    ret = xmlStrcat(ret, buf);
                    xmlFree(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();

    return (0);
}
#endif

#endif /* LIBXML_SCHEMATRON_ENABLED */
