Work on the W3C/NIST regression tests for XInclude, improved the script,

* check-xinclude-test-suite.py xinclude.c: Work on the W3C/NIST
  regression tests for XInclude, improved the script, improving
  XInclude error reporting mechanism
Daniel
diff --git a/ChangeLog b/ChangeLog
index ab33e05..f49b925 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Feb 11 19:01:02 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xinclude-test-suite.py xinclude.c: Work on the W3C/NIST
+	  regression tests for XInclude, improved the script, improving
+	  XInclude error reporting mechanism
+
 Mon Feb 10 17:19:14 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* NEWS doc/* configure.in: preparing release 2.5.3
diff --git a/check-xinclude-test-suite.py b/check-xinclude-test-suite.py
index 11a3375..6a1d3ca 100755
--- a/check-xinclude-test-suite.py
+++ b/check-xinclude-test-suite.py
@@ -14,11 +14,16 @@
 
 log = open(LOG, "w")
 
+test_nr = 0
+test_succeed = 0
+test_failed = 0
+test_error = 0
 #
 # Error and warning handlers
 #
 error_nr = 0
 error_msg = ''
+
 def errorHandler(ctx, str):
     global error_nr
     global error_msg
@@ -44,10 +49,6 @@
     print "testXInclude(%s, %s)" % (filename, id)
     return 1
 
-test_nr = 0
-test_succeed = 0
-test_failed = 0
-test_error = 0
 def runTest(test, basedir):
     global test_nr
     global test_failed
@@ -56,6 +57,7 @@
     global error_msg
     global log
 
+    fatal_error = 0
     uri = test.prop('href')
     id = test.prop('id')
     if uri == None:
@@ -72,26 +74,76 @@
         print "Test %s missing: base %s uri %s" % (URI, basedir, uri)
 	return -1
 
-    # output =
+    output = test.xpathEval('string(output)')
+    expected = None
+    if output == 'No output file.':
+        output = None
+    if output == '':
+        output = None
+    if output != None:
+        if basedir != None:
+	    output = basedir + "/" + output
+	if os.access(output, os.R_OK) == 0:
+	    print "Result for %s missing: %s" % (id, output)
+	    output = None
+	else:
+	    try:
+		f = open(output)
+		expected = f.read()
+	    except:
+	        print "Result for %s unreadable: %s" % (id, output)
+
+    description = test.xpathEval('string(description)')
+    if string.find(description, 'fatal error') != -1:
+        fatal_error = 1
+
+    try:
+        # print "testing %s" % (URI)
+	doc = libxml2.parseFile(URI)
+    except:
+        doc = None
+    if doc != None:
+        res = doc.xincludeProcess()
+	if expected != None and fatal_error != 0:
+	    result = doc.serialize()
+	    if result != expected:
+	        print "Result for %s differs" % (id)
+
+	doc.freeDoc()
+    else:
+        print "Failed to parse %s" % (URI)
+	res = -1
+
+    
 
     test_nr = test_nr + 1
-    if res > 0:
-	test_succeed = test_succeed + 1
-    elif res == 0:
-	test_failed = test_failed + 1
-    elif res < 0:
-	test_error = test_error + 1
+    if fatal_error == 0 and output != None:
+	if res > 0:
+	    test_succeed = test_succeed + 1
+	elif res == 0:
+	    test_failed = test_failed + 1
+	    print "Test %s: no substitution done ???" % (id)
+	elif res < 0:
+	    test_error = test_error + 1
+	    print "Test %s: failed valid XInclude processing" % (id)
+    else:
+	if res > 0:
+	    test_error = test_error + 1
+	    print "Test %s: failed to detect invalid XInclude processing" % (id)
+	elif res == 0:
+	    test_failed = test_failed + 1
+	    print "Test %s: Invalid but no substitution done" % (id)
+	elif res < 0:
+	    test_succeed = test_succeed + 1
 
     # Log the ontext
     if res != 1:
+	log.write("Test ID %s\n" % (id))
 	log.write("   File: %s\n" % (URI))
 	content = string.strip(test.content)
 	while content[-1] == '\n':
 	    content = content[0:-1]
-	if extra != None:
-	    log.write("   %s:%s:%s\n" % (type, extra, content))
-	else:
-	    log.write("   %s:%s\n\n" % (type, content))
+	log.write("   %s:%s\n\n" % (type, content))
 	if error_msg != '':
 	    log.write("   ----\n%s   ----\n" % (error_msg))
 	    error_msg = ''
@@ -134,11 +186,6 @@
 
 case = testsuite.children
 while case != None:
-    global test_nr
-    global test_succeed
-    global test_failed
-    global test_error
-
     if case.name == 'testcases':
 	old_test_nr = test_nr
 	old_test_succeed = test_succeed
diff --git a/xinclude.c b/xinclude.c
index a9a1e3c..d0d125f 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -83,6 +83,8 @@
     int                txtMax; /* size of unparsed documents tab */
     xmlNodePtr        *txtTab; /* array of unparsed text nodes */
     xmlURL         *txturlTab; /* array of unparsed txtuments URLs */
+
+    int              nbErrors; /* the number of errors detected */
 };
 
 static int
@@ -152,6 +154,7 @@
         if (ctxt->incTab == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "malloc failed !\n");
+	    ctxt->nbErrors++;
 	    xmlXIncludeFreeRef(ret);
 	    return(NULL);
 	}
@@ -197,6 +200,7 @@
     ret->incBase = 0;
     ret->incMax = 0;
     ret->incTab = NULL;
+    ret->nbErrors = 0;
     return(ret);
 }
 
@@ -268,6 +272,7 @@
 	href = xmlGetProp(cur, XINCLUDE_HREF);
 	if (href == NULL) {
 	    xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
+	    ctxt->nbErrors++;
 	    return(-1);
 	}
     }
@@ -284,6 +289,7 @@
 	    xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value %s for %s\n",
 		            parse, XINCLUDE_PARSE);
+	    ctxt->nbErrors++;
 	    if (href != NULL)
 		xmlFree(href);
 	    if (parse != NULL)
@@ -323,6 +329,7 @@
 	xmlFree(base);
     if (URI == NULL) {
 	xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
+	ctxt->nbErrors++;
 	return(-1);
     }
 
@@ -333,6 +340,7 @@
     if (uri == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", URI);
+	ctxt->nbErrors++;
 	return(-1);
     }
     if (uri->fragment != NULL) {
@@ -345,6 +353,7 @@
     if (URL == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", URI);
+	ctxt->nbErrors++;
 	if (fragment != NULL)
 	    xmlFree(fragment);
 	return(-1);
@@ -395,6 +404,7 @@
         if (newctxt->incTab == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "malloc failed !\n");
+	    ctxt->nbErrors++;
 	    xmlFree(newctxt);
 	    return;
 	}
@@ -440,6 +450,7 @@
         if (ctxt->txtTab == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "malloc failed !\n");
+	    ctxt->nbErrors++;
 	    return;
 	}
         ctxt->txturlTab = (xmlURL *) xmlMalloc(ctxt->txtMax *
@@ -447,6 +458,7 @@
         if (ctxt->txturlTab == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "malloc failed !\n");
+	    ctxt->nbErrors++;
 	    return;
 	}
     }
@@ -457,6 +469,7 @@
         if (ctxt->txtTab == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "realloc failed !\n");
+	    ctxt->nbErrors++;
 	    return;
 	}
         ctxt->txturlTab = (xmlURL *) xmlRealloc(ctxt->txturlTab,
@@ -464,6 +477,7 @@
         if (ctxt->txturlTab == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "realloc failed !\n");
+	    ctxt->nbErrors++;
 	    return;
 	}
     }
@@ -945,6 +959,7 @@
     if (uri == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
+	ctxt->nbErrors++;
 	return(-1);
     }
     if (uri->fragment != NULL) {
@@ -956,6 +971,7 @@
     if (URL == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
+	ctxt->nbErrors++;
 	if (fragment != NULL)
 	    xmlFree(fragment);
 	return(-1);
@@ -1051,6 +1067,7 @@
 	if (xptrctxt == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 			"XInclude: could create XPointer context\n");
+	    ctxt->nbErrors++;
 	    xmlFree(URL);
 	    xmlFree(fragment);
 	    return(-1);
@@ -1060,6 +1077,7 @@
 	    xmlGenericError(xmlGenericErrorContext,
 			"XInclude: XPointer evaluation failed: #%s\n",
 			fragment);
+	    ctxt->nbErrors++;
 	    xmlXPathFreeContext(xptrctxt);
 	    xmlFree(URL);
 	    xmlFree(fragment);
@@ -1076,6 +1094,7 @@
 		xmlGenericError(xmlGenericErrorContext,
 			"XInclude: XPointer is not a range: #%s\n",
 			        fragment);
+		ctxt->nbErrors++;
 		xmlXPathFreeContext(xptrctxt);
 		xmlFree(URL);
 		xmlFree(fragment);
@@ -1108,12 +1127,14 @@
 			xmlGenericError(xmlGenericErrorContext,
 			"XInclude: XPointer selects an attribute: #%s\n",
 					fragment);
+			ctxt->nbErrors++;
 			set->nodeTab[i] = NULL;
 			continue;
 		    case XML_NAMESPACE_DECL:
 			xmlGenericError(xmlGenericErrorContext,
 			"XInclude: XPointer selects a namespace: #%s\n",
 					fragment);
+			ctxt->nbErrors++;
 			set->nodeTab[i] = NULL;
 			continue;
 		    case XML_DOCUMENT_TYPE_NODE:
@@ -1128,6 +1149,7 @@
 			xmlGenericError(xmlGenericErrorContext,
 			"XInclude: XPointer selects unexpected nodes: #%s\n",
 					fragment);
+			ctxt->nbErrors++;
 			set->nodeTab[i] = NULL;
 			set->nodeTab[i] = NULL;
 			continue; /* for */
@@ -1193,12 +1215,14 @@
     if (uri == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
+	ctxt->nbErrors++;
 	return(-1);
     }
     if (uri->fragment != NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		"XInclude: fragment identifier forbidden for text: %s\n",
 		uri->fragment);
+	ctxt->nbErrors++;
 	xmlFreeURI(uri);
 	return(-1);
     }
@@ -1207,6 +1231,7 @@
     if (URL == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
+	ctxt->nbErrors++;
 	return(-1);
     }
 
@@ -1217,6 +1242,7 @@
     if (URL[0] == 0) {
 	xmlGenericError(xmlGenericErrorContext,
 		"XInclude: text serialization of document not available\n");
+	ctxt->nbErrors++;
 	xmlFree(URL);
 	return(-1);
     }
@@ -1247,6 +1273,7 @@
 	if (enc == XML_CHAR_ENCODING_ERROR) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: encoding %s not supported\n", encoding);
+	    ctxt->nbErrors++;
 	    xmlFree(encoding);
 	    xmlFree(URL);
 	    return(-1);
@@ -1281,6 +1308,7 @@
 	    if (!IS_CHAR(cur)) {
 		xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: %s contains invalid char %d\n", URL, cur);
+		ctxt->nbErrors++;
 	    } else {
 		xmlNodeAddContentLen(node, &content[i], l);
 	    }
@@ -1437,6 +1465,7 @@
 	xmlFree(base);
     if (URI == NULL) {
 	xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
+	ctxt->nbErrors++;
 	return(-1);
     }
 
@@ -1447,6 +1476,7 @@
     if (uri == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", URI);
+	ctxt->nbErrors++;
 	xmlFree(URI);
 	return(-1);
     }
@@ -1459,6 +1489,7 @@
     if (URL == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", URI);
+	ctxt->nbErrors++;
 	if (fragment != NULL)
 	    xmlFree(fragment);
 	xmlFree(URI);
@@ -1517,6 +1548,7 @@
 	href = xmlGetProp(cur, XINCLUDE_HREF);
 	if (href == NULL) {
 	    xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
+	    ctxt->nbErrors++;
 	    return(-1);
 	}
     }
@@ -1533,6 +1565,7 @@
 	    xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value %s for %s\n",
 		            parse, XINCLUDE_PARSE);
+	    ctxt->nbErrors++;
 	    if (href != NULL)
 		xmlFree(href);
 	    if (parse != NULL)
@@ -1566,6 +1599,7 @@
     }
     if (URI == NULL) {
 	xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
+	ctxt->nbErrors++;
 	if (parse != NULL)
 	    xmlFree(parse);
 	if (href != NULL)
@@ -1615,6 +1649,7 @@
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: could not load %s, and no fallback was found\n",
 		        URI);
+	ctxt->nbErrors++;
     }
 
     /*
@@ -1661,6 +1696,7 @@
     if (end == NULL) {
 	xmlGenericError(xmlGenericErrorContext, 
 		"XInclude: failed to build node\n");
+	ctxt->nbErrors++;
 	return(-1);
     }
     end->type = XML_XINCLUDE_END;
@@ -1791,6 +1827,8 @@
     if (ctxt == NULL)
 	return(-1);
     ret = xmlXIncludeDoProcess(ctxt, doc);
+    if ((ret >= 0) && (ctxt->nbErrors > 0))
+	ret = -1;
 
     xmlXIncludeFreeContext(ctxt);
     return(ret);