/*
 * runsuite.c: C program to run libxml2 againts published testsuites 
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

#ifdef HAVE_CONFIG_H
#include "libxml.h"
#else
#include <stdio.h>
#endif

#if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
#include <libxml/xmlreader.h>

#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

#include <libxml/relaxng.h>
#include <libxml/xmlschemas.h>
#include <libxml/xmlschemastypes.h>

#define LOGFILE "runsuite.log"
static FILE *logfile = NULL;
static int verbose = 0;



#if defined(_WIN32) && !defined(__CYGWIN__)

#define vsnprintf _vsnprintf

#define snprintf _snprintf

#endif

/************************************************************************
 *									*
 *		File name and path utilities				*
 *									*
 ************************************************************************/

static int checkTestFile(const char *filename) {
    struct stat buf;

    if (stat(filename, &buf) == -1)
        return(0);

#if defined(_WIN32) && !defined(__CYGWIN__)
    if (!(buf.st_mode & _S_IFREG))
        return(0);
#else
    if (!S_ISREG(buf.st_mode))
        return(0);
#endif

    return(1);
}

static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
    char buf[500];

    if (dir == NULL) return(xmlStrdup(path));
    if (path == NULL) return(NULL);

    snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
    return(xmlStrdup((const xmlChar *) buf));
}

/************************************************************************
 *									*
 *		Libxml2 specific routines				*
 *									*
 ************************************************************************/

static int nb_tests = 0;
static int nb_errors = 0;
static int nb_internals = 0;
static int nb_schematas = 0;
static int nb_unimplemented = 0;
static int nb_leaks = 0;
static int extraMemoryFromResolver = 0;

static int
fatalError(void) {
    fprintf(stderr, "Exitting tests on fatal error\n");
    exit(1);
}

/*
 * that's needed to implement <resource>
 */
#define MAX_ENTITIES 20
static char *testEntitiesName[MAX_ENTITIES];
static char *testEntitiesValue[MAX_ENTITIES];
static int nb_entities = 0;
static void resetEntities(void) {
    int i;

    for (i = 0;i < nb_entities;i++) {
        if (testEntitiesName[i] != NULL)
	    xmlFree(testEntitiesName[i]);
        if (testEntitiesValue[i] != NULL)
	    xmlFree(testEntitiesValue[i]);
    }
    nb_entities = 0;
}
static int addEntity(char *name, char *content) {
    if (nb_entities >= MAX_ENTITIES) {
	fprintf(stderr, "Too many entities defined\n");
	return(-1);
    }
    testEntitiesName[nb_entities] = name;
    testEntitiesValue[nb_entities] = content;
    nb_entities++;
    return(0);
}

/*
 * We need to trap calls to the resolver to not account memory for the catalog
 * which is shared to the current running test. We also don't want to have
 * network downloads modifying tests.
 */
static xmlParserInputPtr 
testExternalEntityLoader(const char *URL, const char *ID,
			 xmlParserCtxtPtr ctxt) {
    xmlParserInputPtr ret;
    int i;

    for (i = 0;i < nb_entities;i++) {
        if (!strcmp(testEntitiesName[i], URL)) {
	    ret = xmlNewStringInputStream(ctxt,
	                (const xmlChar *) testEntitiesValue[i]);
	    if (ret != NULL) {
	        ret->filename = (const char *)
		                xmlStrdup((xmlChar *)testEntitiesName[i]);
	    }
	    return(ret);
	}
    }
    if (checkTestFile(URL)) {
	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
    } else {
	int memused = xmlMemUsed();
	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
	extraMemoryFromResolver += xmlMemUsed() - memused;
    }
#if 0
    if (ret == NULL) {
        fprintf(stderr, "Failed to find resource %s\n", URL);
    }
#endif
      
    return(ret);
}

/*
 * Trapping the error messages at the generic level to grab the equivalent of
 * stderr messages on CLI tools.
 */
static char testErrors[32769];
static int testErrorsSize = 0;

static void test_log(const char *msg, ...) {
    va_list args;
    if (logfile != NULL) {
        fprintf(logfile, "\n------------\n");
	va_start(args, msg);
	vfprintf(logfile, msg, args);
	va_end(args);
	fprintf(logfile, "%s", testErrors);
	testErrorsSize = 0; testErrors[0] = 0;
    }
    if (verbose) {
	va_start(args, msg);
	vfprintf(stderr, msg, args);
	va_end(args);
    }
}

static void
testErrorHandler(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
    va_list args;
    int res;

    if (testErrorsSize >= 32768)
        return;
    va_start(args, msg);
    res = vsnprintf(&testErrors[testErrorsSize],
                    32768 - testErrorsSize,
		    msg, args);
    va_end(args);
    if (testErrorsSize + res >= 32768) {
        /* buffer is full */
	testErrorsSize = 32768;
	testErrors[testErrorsSize] = 0;
    } else {
        testErrorsSize += res;
    }
    testErrors[testErrorsSize] = 0;
}

static xmlXPathContextPtr ctxtXPath;

static void
initializeLibxml2(void) {
    xmlGetWarningsDefaultValue = 0;
    xmlPedanticParserDefault(0);

    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
    xmlInitParser();
    xmlSetExternalEntityLoader(testExternalEntityLoader);
    ctxtXPath = xmlXPathNewContext(NULL);
    /*
    * Deactivate the cache if created; otherwise we have to create/free it
    * for every test, since it will confuse the memory leak detection.
    * Note that normally this need not be done, since the cache is not
    * created until set explicitely with xmlXPathContextSetCache();
    * but for test purposes it is sometimes usefull to activate the
    * cache by default for the whole library.
    */
    if (ctxtXPath->cache != NULL)
	xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
    /* used as default nanemspace in xstc tests */
    xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
    xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
                       BAD_CAST "http://www.w3.org/1999/xlink");
    xmlSetGenericErrorFunc(NULL, testErrorHandler);
#ifdef LIBXML_SCHEMAS_ENABLED
    xmlSchemaInitTypes();
    xmlRelaxNGInitTypes();
#endif
}

static xmlNodePtr
getNext(xmlNodePtr cur, const char *xpath) {
    xmlNodePtr ret = NULL;
    xmlXPathObjectPtr res;
    xmlXPathCompExprPtr comp;

    if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
        return(NULL);
    ctxtXPath->doc = cur->doc;
    ctxtXPath->node = cur;
    comp = xmlXPathCompile(BAD_CAST xpath);
    if (comp == NULL) {
        fprintf(stderr, "Failed to compile %s\n", xpath);
	return(NULL);
    }
    res = xmlXPathCompiledEval(comp, ctxtXPath);
    xmlXPathFreeCompExpr(comp);
    if (res == NULL)
        return(NULL);
    if ((res->type == XPATH_NODESET) &&
        (res->nodesetval != NULL) &&
	(res->nodesetval->nodeNr > 0) &&
	(res->nodesetval->nodeTab != NULL))
	ret = res->nodesetval->nodeTab[0];
    xmlXPathFreeObject(res);
    return(ret);
}

static xmlChar *
getString(xmlNodePtr cur, const char *xpath) {
    xmlChar *ret = NULL;
    xmlXPathObjectPtr res;
    xmlXPathCompExprPtr comp;

    if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
        return(NULL);
    ctxtXPath->doc = cur->doc;
    ctxtXPath->node = cur;
    comp = xmlXPathCompile(BAD_CAST xpath);
    if (comp == NULL) {
        fprintf(stderr, "Failed to compile %s\n", xpath);
	return(NULL);
    }
    res = xmlXPathCompiledEval(comp, ctxtXPath);
    xmlXPathFreeCompExpr(comp);
    if (res == NULL)
        return(NULL);
    if (res->type == XPATH_STRING) {
        ret = res->stringval;
	res->stringval = NULL;
    }
    xmlXPathFreeObject(res);
    return(ret);
}

/************************************************************************
 *									*
 *		Test test/xsdtest/xsdtestsuite.xml			*
 *									*
 ************************************************************************/

static int
xsdIncorectTestCase(xmlNodePtr cur) {
    xmlNodePtr test;
    xmlBufferPtr buf;
    xmlRelaxNGParserCtxtPtr pctxt;
    xmlRelaxNGPtr rng = NULL;
    int ret = 0, memt;

    cur = getNext(cur, "./incorrect[1]");
    if (cur == NULL) {
        return(0);
    }

    test = getNext(cur, "./*");
    if (test == NULL) {
        test_log("Failed to find test in correct line %ld\n",
	        xmlGetLineNo(cur));
        return(1);
    }

    memt = xmlMemUsed();
    extraMemoryFromResolver = 0;
    /*
     * dump the schemas to a buffer, then reparse it and compile the schemas
     */
    buf = xmlBufferCreate();
    if (buf == NULL) {
        fprintf(stderr, "out of memory !\n");
	fatalError();
    }
    xmlNodeDump(buf, test->doc, test, 0, 0);
    pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
    xmlRelaxNGSetParserErrors(pctxt,
         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
	 pctxt);
    rng = xmlRelaxNGParse(pctxt);
    xmlRelaxNGFreeParserCtxt(pctxt);
    if (rng != NULL) {
	test_log("Failed to detect incorect RNG line %ld\n",
		    xmlGetLineNo(test));
        ret = 1;
	goto done;
    }

done:
    if (buf != NULL)
	xmlBufferFree(buf);
    if (rng != NULL)
        xmlRelaxNGFree(rng);
    xmlResetLastError();
    if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
	test_log("Validation of tests starting line %ld leaked %d\n",
		xmlGetLineNo(cur), xmlMemUsed() - memt);
	nb_leaks++;
    }
    return(ret);
}

static void
installResources(xmlNodePtr tst, const xmlChar *base) {
    xmlNodePtr test;
    xmlBufferPtr buf;
    xmlChar *name, *content, *res;

    buf = xmlBufferCreate();
    if (buf == NULL) {
        fprintf(stderr, "out of memory !\n");
	fatalError();
    }
    xmlNodeDump(buf, tst->doc, tst, 0, 0);

    while (tst != NULL) {
	test = getNext(tst, "./*");
	if (test != NULL) {
	    xmlBufferEmpty(buf);
	    xmlNodeDump(buf, test->doc, test, 0, 0);
	    name = getString(tst, "string(@name)");
	    content = xmlStrdup(buf->content);
	    if ((name != NULL) && (content != NULL)) {
	        res = composeDir(base, name);
		xmlFree(name);
	        addEntity((char *) res, (char *) content);
	    } else {
	        if (name != NULL) xmlFree(name);
	        if (content != NULL) xmlFree(content);
	    }
	}
	tst = getNext(tst, "following-sibling::resource[1]");
    }
    if (buf != NULL)
	xmlBufferFree(buf);
}

static void
installDirs(xmlNodePtr tst, const xmlChar *base) {
    xmlNodePtr test;
    xmlChar *name, *res;

    name = getString(tst, "string(@name)");
    if (name == NULL)
        return;
    res = composeDir(base, name);
    xmlFree(name);
    if (res == NULL) {
	return;
    }
    /* Now process resources and subdir recursively */
    test = getNext(tst, "./resource[1]");
    if (test != NULL) {
        installResources(test, res);
    }
    test = getNext(tst, "./dir[1]");
    while (test != NULL) {
        installDirs(test, res);
	test = getNext(test, "following-sibling::dir[1]");
    }
    xmlFree(res);
}

static int 
xsdTestCase(xmlNodePtr tst) {
    xmlNodePtr test, tmp, cur;
    xmlBufferPtr buf;
    xmlDocPtr doc = NULL;
    xmlRelaxNGParserCtxtPtr pctxt;
    xmlRelaxNGValidCtxtPtr ctxt;
    xmlRelaxNGPtr rng = NULL;
    int ret = 0, mem, memt;
    xmlChar *dtd;

    resetEntities();
    testErrorsSize = 0; testErrors[0] = 0;

    tmp = getNext(tst, "./dir[1]");
    if (tmp != NULL) {
        installDirs(tmp, NULL);
    }
    tmp = getNext(tst, "./resource[1]");
    if (tmp != NULL) {
        installResources(tmp, NULL);
    }

    cur = getNext(tst, "./correct[1]");
    if (cur == NULL) {
        return(xsdIncorectTestCase(tst));
    }
    
    test = getNext(cur, "./*");
    if (test == NULL) {
        fprintf(stderr, "Failed to find test in correct line %ld\n",
	        xmlGetLineNo(cur));
        return(1);
    }

    memt = xmlMemUsed();
    extraMemoryFromResolver = 0;
    /*
     * dump the schemas to a buffer, then reparse it and compile the schemas
     */
    buf = xmlBufferCreate();
    if (buf == NULL) {
        fprintf(stderr, "out of memory !\n");
	fatalError();
    }
    xmlNodeDump(buf, test->doc, test, 0, 0);
    pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
    xmlRelaxNGSetParserErrors(pctxt,
         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
	 pctxt);
    rng = xmlRelaxNGParse(pctxt);
    xmlRelaxNGFreeParserCtxt(pctxt);
    if (extraMemoryFromResolver)
        memt = 0;

    if (rng == NULL) {
        test_log("Failed to parse RNGtest line %ld\n",
	        xmlGetLineNo(test));
	nb_errors++;
        ret = 1;
	goto done;
    }
    /*
     * now scan all the siblings of correct to process the <valid> tests
     */
    tmp = getNext(cur, "following-sibling::valid[1]");
    while (tmp != NULL) {
	dtd = xmlGetProp(tmp, BAD_CAST "dtd");
	test = getNext(tmp, "./*");
	if (test == NULL) {
	    fprintf(stderr, "Failed to find test in <valid> line %ld\n",
		    xmlGetLineNo(tmp));
	    
	} else {
	    xmlBufferEmpty(buf);
	    if (dtd != NULL)
		xmlBufferAdd(buf, dtd, -1);
	    xmlNodeDump(buf, test->doc, test, 0, 0);

	    /*
	     * We are ready to run the test
	     */
	    mem = xmlMemUsed();
	    extraMemoryFromResolver = 0;
            doc = xmlReadMemory((const char *)buf->content, buf->use,
	                        "test", NULL, 0);
	    if (doc == NULL) {
		test_log("Failed to parse valid instance line %ld\n",
			xmlGetLineNo(tmp));
		nb_errors++;
	    } else {
		nb_tests++;
	        ctxt = xmlRelaxNGNewValidCtxt(rng);
		xmlRelaxNGSetValidErrors(ctxt,
		     (xmlRelaxNGValidityErrorFunc) testErrorHandler,
		     (xmlRelaxNGValidityWarningFunc) testErrorHandler,
		     ctxt);
		ret = xmlRelaxNGValidateDoc(ctxt, doc);
		xmlRelaxNGFreeValidCtxt(ctxt);
		if (ret > 0) {
		    test_log("Failed to validate valid instance line %ld\n",
				xmlGetLineNo(tmp));
		    nb_errors++;
		} else if (ret < 0) {
		    test_log("Internal error validating instance line %ld\n",
			    xmlGetLineNo(tmp));
		    nb_errors++;
		}
		xmlFreeDoc(doc);
	    }
	    xmlResetLastError();
	    if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
	        test_log("Validation of instance line %ld leaked %d\n",
		        xmlGetLineNo(tmp), xmlMemUsed() - mem);
		xmlMemoryDump();
	        nb_leaks++;
	    }
	}
	if (dtd != NULL)
	    xmlFree(dtd);
	tmp = getNext(tmp, "following-sibling::valid[1]");
    }
    /*
     * now scan all the siblings of correct to process the <invalid> tests
     */
    tmp = getNext(cur, "following-sibling::invalid[1]");
    while (tmp != NULL) {
	test = getNext(tmp, "./*");
	if (test == NULL) {
	    fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
		    xmlGetLineNo(tmp));
	    
	} else {
	    xmlBufferEmpty(buf);
	    xmlNodeDump(buf, test->doc, test, 0, 0);

	    /*
	     * We are ready to run the test
	     */
	    mem = xmlMemUsed();
	    extraMemoryFromResolver = 0;
            doc = xmlReadMemory((const char *)buf->content, buf->use,
	                        "test", NULL, 0);
	    if (doc == NULL) {
		test_log("Failed to parse valid instance line %ld\n",
			xmlGetLineNo(tmp));
		nb_errors++;
	    } else {
		nb_tests++;
	        ctxt = xmlRelaxNGNewValidCtxt(rng);
		xmlRelaxNGSetValidErrors(ctxt,
		     (xmlRelaxNGValidityErrorFunc) testErrorHandler,
		     (xmlRelaxNGValidityWarningFunc) testErrorHandler,
		     ctxt);
		ret = xmlRelaxNGValidateDoc(ctxt, doc);
		xmlRelaxNGFreeValidCtxt(ctxt);
		if (ret == 0) {
		    test_log("Failed to detect invalid instance line %ld\n",
				xmlGetLineNo(tmp));
		    nb_errors++;
		} else if (ret < 0) {
		    test_log("Internal error validating instance line %ld\n",
			    xmlGetLineNo(tmp));
		    nb_errors++;
		}
		xmlFreeDoc(doc);
	    }
	    xmlResetLastError();
	    if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
	        test_log("Validation of instance line %ld leaked %d\n",
		        xmlGetLineNo(tmp), xmlMemUsed() - mem);
		xmlMemoryDump();
	        nb_leaks++;
	    }
	}
	tmp = getNext(tmp, "following-sibling::invalid[1]");
    }

done:
    if (buf != NULL)
	xmlBufferFree(buf);
    if (rng != NULL)
        xmlRelaxNGFree(rng);
    xmlResetLastError();
    if ((memt != xmlMemUsed()) && (memt != 0)) {
	test_log("Validation of tests starting line %ld leaked %d\n",
		xmlGetLineNo(cur), xmlMemUsed() - memt);
	nb_leaks++;
    }
    return(ret);
}

static int 
xsdTestSuite(xmlNodePtr cur) {
    if (verbose) {
	xmlChar *doc = getString(cur, "string(documentation)");

	if (doc != NULL) {
	    printf("Suite %s\n", doc);
	    xmlFree(doc);
	}
    }
    cur = getNext(cur, "./testCase[1]");
    while (cur != NULL) {
        xsdTestCase(cur);
	cur = getNext(cur, "following-sibling::testCase[1]");
    }
        
    return(0);
}

static int 
xsdTest(void) {
    xmlDocPtr doc;
    xmlNodePtr cur;
    const char *filename = "test/xsdtest/xsdtestsuite.xml";
    int ret = 0;

    doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", filename);
	return(-1);
    }
    printf("## XML Schemas datatypes test suite from James Clark\n");

    cur = xmlDocGetRootElement(doc);
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        fprintf(stderr, "Unexpected format %s\n", filename);
	ret = -1;
	goto done;
    }

    cur = getNext(cur, "./testSuite[1]");
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        fprintf(stderr, "Unexpected format %s\n", filename);
	ret = -1;
	goto done;
    }
    while (cur != NULL) {
        xsdTestSuite(cur);
	cur = getNext(cur, "following-sibling::testSuite[1]");
    }

done:
    if (doc != NULL)
	xmlFreeDoc(doc);
    return(ret);
}

static int 
rngTestSuite(xmlNodePtr cur) {
    if (verbose) {
	xmlChar *doc = getString(cur, "string(documentation)");

	if (doc != NULL) {
	    printf("Suite %s\n", doc);
	    xmlFree(doc);
	} else {
	    doc = getString(cur, "string(section)");
	    if (doc != NULL) {
		printf("Section %s\n", doc);
		xmlFree(doc);
	    }
	}
    }
    cur = getNext(cur, "./testSuite[1]");
    while (cur != NULL) {
        xsdTestSuite(cur);
	cur = getNext(cur, "following-sibling::testSuite[1]");
    }
        
    return(0);
}

static int 
rngTest1(void) {
    xmlDocPtr doc;
    xmlNodePtr cur;
    const char *filename = "test/relaxng/OASIS/spectest.xml";
    int ret = 0;

    doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", filename);
	return(-1);
    }
    printf("## Relax NG test suite from James Clark\n");

    cur = xmlDocGetRootElement(doc);
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        fprintf(stderr, "Unexpected format %s\n", filename);
	ret = -1;
	goto done;
    }

    cur = getNext(cur, "./testSuite[1]");
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        fprintf(stderr, "Unexpected format %s\n", filename);
	ret = -1;
	goto done;
    }
    while (cur != NULL) {
        rngTestSuite(cur);
	cur = getNext(cur, "following-sibling::testSuite[1]");
    }

done:
    if (doc != NULL)
	xmlFreeDoc(doc);
    return(ret);
}

static int 
rngTest2(void) {
    xmlDocPtr doc;
    xmlNodePtr cur;
    const char *filename = "test/relaxng/testsuite.xml";
    int ret = 0;

    doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", filename);
	return(-1);
    }
    printf("## Relax NG test suite for libxml2\n");

    cur = xmlDocGetRootElement(doc);
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        fprintf(stderr, "Unexpected format %s\n", filename);
	ret = -1;
	goto done;
    }

    cur = getNext(cur, "./testSuite[1]");
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        fprintf(stderr, "Unexpected format %s\n", filename);
	ret = -1;
	goto done;
    }
    while (cur != NULL) {
        xsdTestSuite(cur);
	cur = getNext(cur, "following-sibling::testSuite[1]");
    }

done:
    if (doc != NULL)
	xmlFreeDoc(doc);
    return(ret);
}

/************************************************************************
 *									*
 *		Schemas test suites from W3C/NIST/MS/Sun		*
 *									*
 ************************************************************************/

static int
xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
                 const xmlChar *spath, const char *base) {
    xmlChar *href = NULL;
    xmlChar *path = NULL;
    xmlChar *validity = NULL;
    xmlSchemaValidCtxtPtr ctxt = NULL;
    xmlDocPtr doc = NULL;
    int ret = 0, mem;

    xmlResetLastError();
    testErrorsSize = 0; testErrors[0] = 0;
    mem = xmlMemUsed();
    href = getString(cur,
                     "string(ts:instanceDocument/@xlink:href)");
    if ((href == NULL) || (href[0] == 0)) {
	test_log("testGroup line %ld misses href for schemaDocument\n",
		    xmlGetLineNo(cur));
	ret = -1;
	goto done;
    }
    path = xmlBuildURI(href, BAD_CAST base);
    if (path == NULL) {
	fprintf(stderr,
	        "Failed to build path to schemas testGroup line %ld : %s\n",
		xmlGetLineNo(cur), href);
	ret = -1;
	goto done;
    }
    if (checkTestFile((const char *) path) <= 0) {
	test_log("schemas for testGroup line %ld is missing: %s\n",
		xmlGetLineNo(cur), path);
	ret = -1;
	goto done;
    }
    validity = getString(cur,
                         "string(ts:expected/@validity)");
    if (validity == NULL) {
        fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
	        xmlGetLineNo(cur));
	ret = -1;
	goto done;
    }
    nb_tests++;
    doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
    if (doc == NULL) {
        fprintf(stderr, "instance %s fails to parse\n", path);
	ret = -1;
	nb_errors++;
	goto done;
    }

    ctxt = xmlSchemaNewValidCtxt(schemas);
    xmlSchemaSetValidErrors(ctxt,
         (xmlSchemaValidityErrorFunc) testErrorHandler,
         (xmlSchemaValidityWarningFunc) testErrorHandler,
	 ctxt);
    ret = xmlSchemaValidateDoc(ctxt, doc);

    if (xmlStrEqual(validity, BAD_CAST "valid")) {
	if (ret > 0) {
	    test_log("valid instance %s failed to validate against %s\n",
			path, spath);
	    nb_errors++;
	} else if (ret < 0) {
	    test_log("valid instance %s got internal error validating %s\n",
			path, spath);
	    nb_internals++;
	    nb_errors++;
	}
    } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
	if (ret == 0) {
	    test_log("Failed to detect invalid instance %s against %s\n",
			path, spath);
	    nb_errors++;
	}
    } else {
        test_log("instanceDocument line %ld has unexpected validity value%s\n",
	        xmlGetLineNo(cur), validity);
	ret = -1;
	goto done;
    }

done:
    if (href != NULL) xmlFree(href);
    if (path != NULL) xmlFree(path);
    if (validity != NULL) xmlFree(validity);
    if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
    if (doc != NULL) xmlFreeDoc(doc);
    xmlResetLastError();
    if (mem != xmlMemUsed()) {
	test_log("Validation of tests starting line %ld leaked %d\n",
		xmlGetLineNo(cur), xmlMemUsed() - mem);
	nb_leaks++;
    }
    return(ret);
}

static int
xstcTestGroup(xmlNodePtr cur, const char *base) {
    xmlChar *href = NULL;
    xmlChar *path = NULL;
    xmlChar *validity = NULL;
    xmlSchemaPtr schemas = NULL;
    xmlSchemaParserCtxtPtr ctxt;
    xmlNodePtr instance;
    int ret = 0, mem;

    xmlResetLastError();
    testErrorsSize = 0; testErrors[0] = 0;
    mem = xmlMemUsed();
    href = getString(cur,
                     "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
    if ((href == NULL) || (href[0] == 0)) {
        test_log("testGroup line %ld misses href for schemaDocument\n",
		    xmlGetLineNo(cur));
	ret = -1;
	goto done;
    }
    path = xmlBuildURI(href, BAD_CAST base);
    if (path == NULL) {
	test_log("Failed to build path to schemas testGroup line %ld : %s\n",
		xmlGetLineNo(cur), href);
	ret = -1;
	goto done;
    }
    if (checkTestFile((const char *) path) <= 0) {
	test_log("schemas for testGroup line %ld is missing: %s\n",
		xmlGetLineNo(cur), path);
	ret = -1;
	goto done;
    }
    validity = getString(cur,
                         "string(ts:schemaTest/ts:expected/@validity)");
    if (validity == NULL) {
        test_log("testGroup line %ld misses expected validity\n",
	        xmlGetLineNo(cur));
	ret = -1;
	goto done;
    }
    nb_tests++;
    if (xmlStrEqual(validity, BAD_CAST "valid")) {
        nb_schematas++;
	ctxt = xmlSchemaNewParserCtxt((const char *) path);
	xmlSchemaSetParserErrors(ctxt,
	     (xmlSchemaValidityErrorFunc) testErrorHandler,
	     (xmlSchemaValidityWarningFunc) testErrorHandler,
	     ctxt);
	schemas = xmlSchemaParse(ctxt);
	xmlSchemaFreeParserCtxt(ctxt);
	if (schemas == NULL) {
	    test_log("valid schemas %s failed to parse\n",
			path);
	    ret = 1;
	    nb_errors++;
	}
	if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
	    test_log("valid schemas %s hit an unimplemented block\n",
			path);
	    ret = 1;
	    nb_unimplemented++;
	    nb_errors++;
	}
	instance = getNext(cur, "./ts:instanceTest[1]");
	while (instance != NULL) {
	    if (schemas != NULL) {
		xstcTestInstance(instance, schemas, path, base);		
	    } else {
		/*
		* We'll automatically mark the instances as failed
		* if the schema was broken.
		*/
		nb_errors++;
	    }
	    instance = getNext(instance,
		"following-sibling::ts:instanceTest[1]");
	}
    } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
        nb_schematas++;
	ctxt = xmlSchemaNewParserCtxt((const char *) path);
	xmlSchemaSetParserErrors(ctxt,
	     (xmlSchemaValidityErrorFunc) testErrorHandler,
	     (xmlSchemaValidityWarningFunc) testErrorHandler,
	     ctxt);
	schemas = xmlSchemaParse(ctxt);
	xmlSchemaFreeParserCtxt(ctxt);
	if (schemas != NULL) {
	    test_log("Failed to detect error in schemas %s\n",
			path);
	    nb_errors++;
	    ret = 1;
	}
	if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
	    nb_unimplemented++;
	    test_log("invalid schemas %s hit an unimplemented block\n",
			path);
	    ret = 1;
	    nb_errors++;
	}
    } else {
        test_log("testGroup line %ld misses unexpected validity value%s\n",
	        xmlGetLineNo(cur), validity);
	ret = -1;
	goto done;
    }

done:
    if (href != NULL) xmlFree(href);
    if (path != NULL) xmlFree(path);
    if (validity != NULL) xmlFree(validity);
    if (schemas != NULL) xmlSchemaFree(schemas);
    xmlResetLastError();
    if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
	test_log("Processing test line %ld %s leaked %d\n",
		xmlGetLineNo(cur), path, xmlMemUsed() - mem);
	nb_leaks++;
    }
    return(ret);
}

static int
xstcMetadata(const char *metadata, const char *base) {
    xmlDocPtr doc;
    xmlNodePtr cur;
    xmlChar *contributor;
    xmlChar *name;
    int ret = 0;

    doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", metadata);
	return(-1);
    }

    cur = xmlDocGetRootElement(doc);
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
        fprintf(stderr, "Unexpected format %s\n", metadata);
	return(-1);
    }
    contributor = xmlGetProp(cur, BAD_CAST "contributor");
    if (contributor == NULL) {
        contributor = xmlStrdup(BAD_CAST "Unknown");
    }
    name = xmlGetProp(cur, BAD_CAST "name");
    if (name == NULL) {
        name = xmlStrdup(BAD_CAST "Unknown");
    }
    printf("## %s test suite for Schemas version %s\n", contributor, name);
    xmlFree(contributor);
    xmlFree(name);

    cur = getNext(cur, "./ts:testGroup[1]");
    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
        fprintf(stderr, "Unexpected format %s\n", metadata);
	ret = -1;
	goto done;
    }
    while (cur != NULL) {
        xstcTestGroup(cur, base);
	cur = getNext(cur, "following-sibling::ts:testGroup[1]");
    }

done:
    xmlFreeDoc(doc);
    return(ret);
}

/************************************************************************
 *									*
 *		The driver for the tests				*
 *									*
 ************************************************************************/

int
main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
    int ret = 0;
    int old_errors, old_tests, old_leaks;

    logfile = fopen(LOGFILE, "w");
    if (logfile == NULL) {
        fprintf(stderr,
	        "Could not open the log file, running in verbose mode\n");
	verbose = 1;
    }
    initializeLibxml2();

    if ((argc >= 2) && (!strcmp(argv[1], "-v")))
        verbose = 1;


    old_errors = nb_errors;
    old_tests = nb_tests;
    old_leaks = nb_leaks;
    xsdTest();
    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
    else
	printf("Ran %d tests, %d errors, %d leaks\n",
	       nb_tests - old_tests,
	       nb_errors - old_errors,
	       nb_leaks - old_leaks);
    old_errors = nb_errors;
    old_tests = nb_tests;
    old_leaks = nb_leaks;
    rngTest1();
    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
    else
	printf("Ran %d tests, %d errors, %d leaks\n",
	       nb_tests - old_tests,
	       nb_errors - old_errors,
	       nb_leaks - old_leaks);
    old_errors = nb_errors;
    old_tests = nb_tests;
    old_leaks = nb_leaks;
    rngTest2();
    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
    else
	printf("Ran %d tests, %d errors, %d leaks\n",
	       nb_tests - old_tests,
	       nb_errors - old_errors,
	       nb_leaks - old_leaks);
    old_errors = nb_errors;
    old_tests = nb_tests;
    old_leaks = nb_leaks;
    nb_internals = 0;
    nb_schematas = 0;
    xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
		 "xstc/Tests/Metadata/");
    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
	printf("Ran %d tests (%d schemata), no errors\n",
	       nb_tests - old_tests, nb_schematas);
    else
	printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
	       nb_tests - old_tests,
	       nb_schematas,
	       nb_errors - old_errors,
	       nb_internals,
	       nb_leaks - old_leaks);
    old_errors = nb_errors;
    old_tests = nb_tests;
    old_leaks = nb_leaks;
    nb_internals = 0;
    nb_schematas = 0;
    xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
		 "xstc/Tests/");
    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
	printf("Ran %d tests (%d schemata), no errors\n",
	       nb_tests - old_tests, nb_schematas);
    else
	printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
	       nb_tests - old_tests,
	       nb_schematas,
	       nb_errors - old_errors,
	       nb_internals,
	       nb_leaks - old_leaks);
    old_errors = nb_errors;
    old_tests = nb_tests;
    old_leaks = nb_leaks;
    nb_internals = 0;
    nb_schematas = 0;
    xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
		 "xstc/Tests/");
    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
	printf("Ran %d tests (%d schemata), no errors\n",
	       nb_tests - old_tests, nb_schematas);
    else
	printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
	       nb_tests - old_tests,
	       nb_schematas,
	       nb_errors - old_errors,
	       nb_internals,
	       nb_leaks - old_leaks);

    if ((nb_errors == 0) && (nb_leaks == 0)) {
        ret = 0;
	printf("Total %d tests, no errors\n",
	       nb_tests);
    } else {
        ret = 1;
	printf("Total %d tests, %d errors, %d leaks\n",
	       nb_tests, nb_errors, nb_leaks);
    }
    xmlXPathFreeContext(ctxtXPath);
    xmlCleanupParser();
    xmlMemoryDump();

    if (logfile != NULL)
        fclose(logfile);
    return(ret);
}
#else /* !SCHEMAS */
int
main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
    fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
}
#endif
