completed the simple checks for Relax-NG suites back to the same 11 errors
* runsuite.c: completed the simple checks for Relax-NG suites
back to the same 11 errors as in the Python runs.
Daniel
diff --git a/runsuite.c b/runsuite.c
index fefbafd..bab8735 100644
--- a/runsuite.c
+++ b/runsuite.c
@@ -16,6 +16,7 @@
#include <unistd.h>
#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#include <libxml/xmlreader.h>
@@ -44,6 +45,15 @@
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));
+}
/************************************************************************
* *
@@ -64,6 +74,35 @@
}
/*
+ * that's needed to implement <resource>
+ */
+#define MAX_ENTITIES 20
+char *testEntitiesName[MAX_ENTITIES];
+char *testEntitiesValue[MAX_ENTITIES];
+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.
@@ -72,7 +111,19 @@
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 {
@@ -80,6 +131,9 @@
ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
extraMemoryFromResolver += xmlMemUsed() - memused;
}
+ if (ret == NULL) {
+ fprintf(stderr, "Failed to find resource %s\n", URL);
+ }
return(ret);
}
@@ -252,6 +306,65 @@
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]");
+ }
+}
+
static int
xsdTestCase(int verbose, xmlNodePtr tst) {
xmlNodePtr test, tmp, cur;
@@ -261,6 +374,18 @@
xmlRelaxNGValidCtxtPtr ctxt;
xmlRelaxNGPtr rng = NULL;
int ret = 0, mem, memt;
+ xmlChar *dtd;
+
+ resetEntities();
+
+ 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) {
@@ -307,6 +432,7 @@
*/
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",
@@ -314,6 +440,8 @@
} else {
xmlBufferEmpty(buf);
+ if (dtd != NULL)
+ xmlBufferAdd(buf, dtd, -1);
xmlNodeDump(buf, test->doc, test, 0, 0);
/*
@@ -358,6 +486,8 @@
nb_leaks++;
}
}
+ if (dtd != NULL)
+ xmlFree(dtd);
tmp = getNext(tmp, "following-sibling::valid[1]");
}
/*
@@ -527,7 +657,7 @@
fprintf(stderr, "Failed to parse %s\n", filename);
return(-1);
}
- printf("## Relax NG test suite 1 from James Clark\n");
+ printf("## Relax NG test suite from James Clark\n");
cur = xmlDocGetRootElement(doc);
if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
@@ -553,6 +683,44 @@
return(ret);
}
+static int
+rngTest2(int verbose) {
+ 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(verbose, cur);
+ cur = getNext(cur, "following-sibling::testSuite[1]");
+ }
+
+done:
+ if (doc != NULL)
+ xmlFreeDoc(doc);
+ return(ret);
+}
+
/************************************************************************
* *
* Libxml2 specific routines *
@@ -571,6 +739,9 @@
verbose = 1;
+ old_errors = nb_errors;
+ old_tests = nb_tests;
+ old_leaks = nb_leaks;
res = xsdTest(verbose);
if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
printf("Ran %d tests, no errors\n", nb_tests - old_tests);
@@ -593,6 +764,17 @@
old_errors = nb_errors;
old_tests = nb_tests;
old_leaks = nb_leaks;
+ res = rngTest2(verbose);
+ 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;
if ((nb_errors == 0) && (nb_leaks == 0)) {
ret = 0;