Imported Upstream version 2.9.6_rc1
[platform/upstream/libxml2.git] / runtest.c
index dd74c88..714de27 100644 (file)
--- a/runtest.c
+++ b/runtest.c
  * daniel@veillard.com
  */
 
-#ifdef HAVE_CONFIG_H
 #include "libxml.h"
-#else
 #include <stdio.h>
-#endif
 
 #if !defined(_WIN32) || defined(__CYGWIN__)
 #include <unistd.h>
@@ -26,6 +23,7 @@
 #include <fcntl.h>
 
 #include <libxml/parser.h>
+#include <libxml/parserInternals.h>
 #include <libxml/tree.h>
 #include <libxml/uri.h>
 
  */
 #ifdef O_BINARY
 #define RD_FLAGS       O_RDONLY | O_BINARY
+#define WR_FLAGS       O_WRONLY | O_CREAT | O_TRUNC | O_BINARY
 #else
-#define        RD_FLAGS        O_RDONLY
+#define RD_FLAGS       O_RDONLY
+#define WR_FLAGS       O_WRONLY | O_CREAT | O_TRUNC
 #endif
 
 typedef int (*functest) (const char *filename, const char *result,
@@ -103,6 +103,7 @@ struct testDesc {
     int     options;  /* parser options for the test */
 };
 
+static int update_results = 0;
 static int checkTestFile(const char *filename);
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -195,10 +196,6 @@ static void globfree(glob_t *pglob) {
     }
 }
 
-#if !defined(__MINGW32__)
-#define vsnprintf _vsnprintf
-#define snprintf _snprintf
-#endif
 #else
 #include <glob.h>
 #endif
@@ -611,12 +608,34 @@ static int checkTestFile(const char *filename) {
     return(1);
 }
 
-static int compareFiles(const char *r1, const char *r2) {
+static int compareFiles(const char *r1 /* temp */, const char *r2 /* result */) {
     int res1, res2;
     int fd1, fd2;
     char bytes1[4096];
     char bytes2[4096];
 
+    if (update_results) {
+        fd1 = open(r1, RD_FLAGS);
+        if (fd1 < 0)
+            return(-1);
+        fd2 = open(r2, WR_FLAGS, 0644);
+        if (fd2 < 0) {
+            close(fd1);
+            return(-1);
+        }
+        do {
+            res1 = read(fd1, bytes1, 4096);
+            if (res1 <= 0)
+                break;
+            res2 = write(fd2, bytes1, res1);
+            if (res2 <= 0 || res2 != res1)
+                break;
+        } while (1);
+        close(fd2);
+        close(fd1);
+        return(res1 != 0);
+    }
+
     fd1 = open(r1, RD_FLAGS);
     if (fd1 < 0)
         return(-1);
@@ -653,13 +672,31 @@ static int compareFileMem(const char *filename, const char *mem, int size) {
     int idx = 0;
     struct stat info;
 
-    if (stat(filename, &info) < 0)
+    if (update_results) {
+        fd = open(filename, WR_FLAGS, 0644);
+        if (fd < 0) {
+           fprintf(stderr, "failed to open %s for writing", filename);
+            return(-1);
+       }
+        res = write(fd, mem, size);
+        close(fd);
+        return(res != size);
+    }
+
+    if (stat(filename, &info) < 0) {
+        fprintf(stderr, "failed to stat %s\n", filename);
        return(-1);
-    if (info.st_size != size)
+    }
+    if (info.st_size != size) {
+        fprintf(stderr, "file %s is %ld bytes, result is %d bytes\n",
+               filename, (long) info.st_size, size);
         return(-1);
+    }
     fd = open(filename, RD_FLAGS);
-    if (fd < 0)
+    if (fd < 0) {
+       fprintf(stderr, "failed to open %s for reading", filename);
         return(-1);
+    }
     while (idx < size) {
         res = read(fd, bytes, 4096);
        if (res <= 0)
@@ -678,6 +715,9 @@ static int compareFileMem(const char *filename, const char *mem, int size) {
        idx += res;
     }
     close(fd);
+    if (idx != size) {
+       fprintf(stderr,"Compare error index %d, size %d\n", idx, size);
+    }
     return(idx != size);
 }
 
@@ -1638,7 +1678,6 @@ static xmlSAXHandler debugHTMLSAXHandlerStruct = {
 static xmlSAXHandlerPtr debugHTMLSAXHandler = &debugHTMLSAXHandlerStruct;
 #endif /* LIBXML_HTML_ENABLED */
 
-#ifdef LIBXML_SAX1_ENABLED
 /**
  * saxParseTest:
  * @filename: the file to parse
@@ -1679,14 +1718,23 @@ saxParseTest(const char *filename, const char *result,
        ret = 0;
     } else
 #endif
-    ret = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
+    {
+        xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename);
+        memcpy(ctxt->sax, emptySAXHandler, sizeof(xmlSAXHandler));
+        xmlCtxtUseOptions(ctxt, options);
+        xmlParseDocument(ctxt);
+        ret = ctxt->wellFormed ? 0 : ctxt->errNo;
+        xmlFreeDoc(ctxt->myDoc);
+        xmlFreeParserCtxt(ctxt);
+    }
     if (ret == XML_WAR_UNDECLARED_ENTITY) {
         fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
         ret = 0;
     }
     if (ret != 0) {
         fprintf(stderr, "Failed to parse %s\n", filename);
-       return(1);
+       ret = 1;
+       goto done;
     }
 #ifdef LIBXML_HTML_ENABLED
     if (options & XML_PARSE_HTML) {
@@ -1694,10 +1742,19 @@ saxParseTest(const char *filename, const char *result,
        ret = 0;
     } else
 #endif
-    if (options & XML_PARSE_SAX1) {
-       ret = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
-    } else {
-       ret = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
+    {
+        xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename);
+        if (options & XML_PARSE_SAX1) {
+            memcpy(ctxt->sax, debugSAXHandler, sizeof(xmlSAXHandler));
+            options -= XML_PARSE_SAX1;
+        } else {
+            memcpy(ctxt->sax, debugSAX2Handler, sizeof(xmlSAXHandler));
+        }
+        xmlCtxtUseOptions(ctxt, options);
+        xmlParseDocument(ctxt);
+        ret = ctxt->wellFormed ? 0 : ctxt->errNo;
+        xmlFreeDoc(ctxt->myDoc);
+        xmlFreeParserCtxt(ctxt);
     }
     if (ret == XML_WAR_UNDECLARED_ENTITY) {
         fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
@@ -1708,6 +1765,8 @@ saxParseTest(const char *filename, const char *result,
         fprintf(stderr, "Got a difference for %s\n", filename);
         ret = 1;
     }
+
+done:
     if (temp != NULL) {
         unlink(temp);
         free(temp);
@@ -1719,7 +1778,6 @@ saxParseTest(const char *filename, const char *result,
 
     return(ret);
 }
-#endif
 
 /************************************************************************
  *                                                                     *
@@ -1812,6 +1870,7 @@ pushParseTest(const char *filename, const char *result,
     const char *base;
     int size, res;
     int cur = 0;
+    int chunkSize = 4;
 
     nb_tests++;
     /*
@@ -1822,17 +1881,21 @@ pushParseTest(const char *filename, const char *result,
        return(-1);
     }
 
+    if (chunkSize > size)
+        chunkSize = size;
+
 #ifdef LIBXML_HTML_ENABLED
     if (options & XML_PARSE_HTML)
-       ctxt = htmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename,
+       ctxt = htmlCreatePushParserCtxt(NULL, NULL, base + cur, chunkSize, filename,
                                        XML_CHAR_ENCODING_NONE);
     else
 #endif
-    ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename);
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, chunkSize, filename);
     xmlCtxtUseOptions(ctxt, options);
-    cur += 4;
-    while (cur < size) {
-        if (cur + 1024 >= size) {
+    cur += chunkSize;
+    chunkSize = 1024;
+    do {
+        if (cur + chunkSize >= size) {
 #ifdef LIBXML_HTML_ENABLED
            if (options & XML_PARSE_HTML)
                htmlParseChunk(ctxt, base + cur, size - cur, 1);
@@ -1843,13 +1906,13 @@ pushParseTest(const char *filename, const char *result,
        } else {
 #ifdef LIBXML_HTML_ENABLED
            if (options & XML_PARSE_HTML)
-               htmlParseChunk(ctxt, base + cur, 1024, 0);
+               htmlParseChunk(ctxt, base + cur, chunkSize, 0);
            else
 #endif
-           xmlParseChunk(ctxt, base + cur, 1024, 0);
-           cur += 1024;
+           xmlParseChunk(ctxt, base + cur, chunkSize, 0);
+           cur += chunkSize;
        }
-    }
+    } while (cur < size);
     doc = ctxt->myDoc;
 #ifdef LIBXML_HTML_ENABLED
     if (options & XML_PARSE_HTML)
@@ -1875,7 +1938,7 @@ pushParseTest(const char *filename, const char *result,
     if ((base == NULL) || (res != 0)) {
        if (base != NULL)
            xmlFree((char *)base);
-        fprintf(stderr, "Result for %s failed\n", filename);
+        fprintf(stderr, "Result for %s failed in %s\n", filename, result);
        return(-1);
     }
     xmlFree((char *)base);
@@ -1930,7 +1993,7 @@ memParseTest(const char *filename, const char *result,
     if ((base == NULL) || (res != 0)) {
        if (base != NULL)
            xmlFree((char *)base);
-        fprintf(stderr, "Result for %s failed\n", filename);
+        fprintf(stderr, "Result for %s failed in %s\n", filename, result);
        return(-1);
     }
     xmlFree((char *)base);
@@ -2041,16 +2104,16 @@ errParseTest(const char *filename, const char *result, const char *err,
            xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
        }
        res = compareFileMem(result, base, size);
+       if (res != 0) {
+           fprintf(stderr, "Result for %s failed in %s\n", filename, result);
+           return(-1);
+       }
     }
     if (doc != NULL) {
        if (base != NULL)
            xmlFree((char *)base);
        xmlFreeDoc(doc);
     }
-    if (res != 0) {
-        fprintf(stderr, "Result for %s failed\n", filename);
-       return(-1);
-    }
     if (err != NULL) {
        res = compareFileMem(err, testErrors, testErrorsSize);
        if (res != 0) {
@@ -2100,7 +2163,8 @@ static void processNode(FILE *out, xmlTextReaderPtr reader) {
 }
 static int
 streamProcessTest(const char *filename, const char *result, const char *err,
-                  xmlTextReaderPtr reader, const char *rng) {
+                  xmlTextReaderPtr reader, const char *rng,
+                  int options ATTRIBUTE_UNUSED) {
     int ret;
     char *temp = NULL;
     FILE *t = NULL;
@@ -2163,7 +2227,7 @@ streamProcessTest(const char *filename, const char *result, const char *err,
             free(temp);
         }
        if (ret) {
-           fprintf(stderr, "Result for %s failed\n", filename);
+           fprintf(stderr, "Result for %s failed in %s\n", filename, result);
            return(-1);
        }
     }
@@ -2196,7 +2260,7 @@ streamParseTest(const char *filename, const char *result, const char *err,
     int ret;
 
     reader = xmlReaderForFile(filename, NULL, options);
-    ret = streamProcessTest(filename, result, err, reader, NULL);
+    ret = streamProcessTest(filename, result, err, reader, NULL, options);
     xmlFreeTextReader(reader);
     return(ret);
 }
@@ -2224,7 +2288,7 @@ walkerParseTest(const char *filename, const char *result, const char *err,
        return(-1);
     }
     reader = xmlReaderWalker(doc);
-    ret = streamProcessTest(filename, result, err, reader, NULL);
+    ret = streamProcessTest(filename, result, err, reader, NULL, options);
     xmlFreeTextReader(reader);
     xmlFreeDoc(doc);
     return(ret);
@@ -2256,7 +2320,7 @@ streamMemParseTest(const char *filename, const char *result, const char *err,
        return(-1);
     }
     reader = xmlReaderForMemory(base, size, filename, NULL, options);
-    ret = streamProcessTest(filename, result, err, reader, NULL);
+    ret = streamProcessTest(filename, result, err, reader, NULL, options);
     free((char *)base);
     xmlFreeTextReader(reader);
     return(ret);
@@ -2275,10 +2339,19 @@ static FILE *xpathOutput;
 static xmlDocPtr xpathDocument;
 
 static void
+ignoreGenericError(void *ctx ATTRIBUTE_UNUSED,
+        const char *msg ATTRIBUTE_UNUSED, ...) {
+}
+
+static void
 testXPath(const char *str, int xptr, int expr) {
+    xmlGenericErrorFunc handler = ignoreGenericError;
     xmlXPathObjectPtr res;
     xmlXPathContextPtr ctxt;
 
+    /* Don't print generic errors to stderr. */
+    initGenericErrorDefaultFunc(&handler);
+
     nb_tests++;
 #if defined(LIBXML_XPTR_ENABLED)
     if (xptr) {
@@ -2307,6 +2380,9 @@ testXPath(const char *str, int xptr, int expr) {
     xmlXPathDebugDumpObject(xpathOutput, res, 0);
     xmlXPathFreeObject(res);
     xmlXPathFreeContext(ctxt);
+
+    /* Reset generic error handler. */
+    initGenericErrorDefaultFunc(NULL);
 }
 
 /**
@@ -2366,7 +2442,7 @@ xpathCommonTest(const char *filename, const char *result,
     if (result != NULL) {
        ret = compareFiles(temp, result);
        if (ret) {
-           fprintf(stderr, "Result for %s failed\n", filename);
+           fprintf(stderr, "Result for %s failed in %s\n", filename, result);
        }
     }
 
@@ -2537,7 +2613,7 @@ xmlidDocTest(const char *filename,
     if (result != NULL) {
        ret = compareFiles(temp, result);
        if (ret) {
-           fprintf(stderr, "Result for %s failed\n", filename);
+           fprintf(stderr, "Result for %s failed in %s\n", filename, result);
            res = 1;
        }
     }
@@ -2665,7 +2741,7 @@ uriCommonTest(const char *filename,
     if (result != NULL) {
        ret = compareFiles(temp, result);
        if (ret) {
-           fprintf(stderr, "Result for %s failed\n", filename);
+           fprintf(stderr, "Result for %s failed in %s\n", filename, result);
            res = 1;
        }
     }
@@ -2731,7 +2807,7 @@ static const char *urip_testURLs[] = {
     "file:///path/to/a%20b.html",
     "/path/to/a b.html",
     "/path/to/a%20b.html",
-    "urip://example.com/résumé.html",
+    "urip://example.com/r" "\xe9" "sum" "\xe9" ".html",
     "urip://example.com/test?a=1&b=2%263&c=4#foo",
     NULL
 };
@@ -3315,9 +3391,11 @@ rngStreamTest(const char *filename,
            fprintf(stderr, "Failed to build reder for %s\n", instance);
        }
        if (disable_err == 1)
-           ret = streamProcessTest(instance, result, NULL, reader, filename);
+           ret = streamProcessTest(instance, result, NULL, reader, filename,
+                                   options);
        else
-           ret = streamProcessTest(instance, result, err, reader, filename);
+           ret = streamProcessTest(instance, result, err, reader, filename,
+                                   options);
        xmlFreeTextReader(reader);
        if (ret != 0) {
            fprintf(stderr, "instance %s failed\n", instance);
@@ -3432,11 +3510,11 @@ patternTest(const char *filename,
     result[499] = 0;
     memcpy(xml + len, ".xml", 5);
 
-    if (!checkTestFile(xml)) {
+    if (!checkTestFile(xml) && !update_results) {
        fprintf(stderr, "Missing xml file %s\n", xml);
        return(-1);
     }
-    if (!checkTestFile(result)) {
+    if (!checkTestFile(result) && !update_results) {
        fprintf(stderr, "Missing result file %s\n", result);
        return(-1);
     }
@@ -3535,7 +3613,7 @@ patternTest(const char *filename,
 
     ret = compareFiles(temp, result);
     if (ret) {
-       fprintf(stderr, "Result for %s failed\n", filename);
+       fprintf(stderr, "Result for %s failed in %s\n", filename, result);
        ret = 1;
     }
     if (temp != NULL) {
@@ -3807,7 +3885,7 @@ c14nCommonTest(const char *filename, int with_comments, int mode,
     prefix[len] = 0;
 
     snprintf(buf, 499, "result/c14n/%s/%s", subdir,prefix);
-    if (!checkTestFile(buf)) {
+    if (!checkTestFile(buf) && !update_results) {
         fprintf(stderr, "Missing result file %s", buf);
        return(-1);
     }
@@ -3861,7 +3939,7 @@ c14n11WithoutCommentTest(const char *filename,
     return(c14nCommonTest(filename, 0, XML_C14N_1_1, "1-1-without-comments"));
 }
 #endif
-#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined (LIBXML_SAX1_ENABLED)
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
 /************************************************************************
  *                                                                     *
  *                     Catalog and threads test                        *
@@ -3908,7 +3986,11 @@ thread_specific_data(void *private_data)
         xmlDoValidityCheckingDefaultValue = 1;
         xmlGenericErrorContext = stderr;
     }
+#ifdef LIBXML_SAX1_ENABLED
     myDoc = xmlParseFile(filename);
+#else
+    myDoc = xmlReadFile(filename, NULL, XML_WITH_CATALOG);
+#endif
     if (myDoc) {
         xmlFreeDoc(myDoc);
     } else {
@@ -3939,60 +4021,7 @@ thread_specific_data(void *private_data)
     return ((void *) Okay);
 }
 
-#if defined(linux) || defined(__sun) || defined(__APPLE_CC__)
-
-#include <pthread.h>
-
-static pthread_t tid[MAX_ARGC];
-
-static int
-testThread(void)
-{
-    unsigned int i, repeat;
-    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
-    void *results[MAX_ARGC];
-    int ret;
-    int res = 0;
-
-    xmlInitParser();
-
-    for (repeat = 0; repeat < 500; repeat++) {
-        xmlLoadCatalog(catalog);
-        nb_tests++;
-
-        for (i = 0; i < num_threads; i++) {
-            results[i] = NULL;
-            tid[i] = (pthread_t) - 1;
-        }
-
-        for (i = 0; i < num_threads; i++) {
-            ret = pthread_create(&tid[i], 0, thread_specific_data,
-                                 (void *) testfiles[i]);
-            if (ret != 0) {
-                fprintf(stderr, "pthread_create failed\n");
-                return (1);
-            }
-        }
-        for (i = 0; i < num_threads; i++) {
-            ret = pthread_join(tid[i], &results[i]);
-            if (ret != 0) {
-                fprintf(stderr, "pthread_join failed\n");
-                return (1);
-            }
-        }
-
-        xmlCatalogCleanup();
-        for (i = 0; i < num_threads; i++)
-            if (results[i] != (void *) Okay) {
-                fprintf(stderr, "Thread %d handling %s failed\n",
-                        i, testfiles[i]);
-                res = 1;
-            }
-    }
-    return (res);
-}
-
-#elif defined WIN32
+#if defined WIN32
 #include <windows.h>
 #include <string.h>
 
@@ -4118,6 +4147,59 @@ testThread(void)
         return(1);
     return (0);
 }
+
+#elif defined HAVE_PTHREAD_H
+#include <pthread.h>
+
+static pthread_t tid[MAX_ARGC];
+
+static int
+testThread(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    int ret;
+    int res = 0;
+
+    xmlInitParser();
+
+    for (repeat = 0; repeat < 500; repeat++) {
+        xmlLoadCatalog(catalog);
+        nb_tests++;
+
+        for (i = 0; i < num_threads; i++) {
+            results[i] = NULL;
+            tid[i] = (pthread_t) - 1;
+        }
+
+        for (i = 0; i < num_threads; i++) {
+            ret = pthread_create(&tid[i], 0, thread_specific_data,
+                                 (void *) testfiles[i]);
+            if (ret != 0) {
+                fprintf(stderr, "pthread_create failed\n");
+                return (1);
+            }
+        }
+        for (i = 0; i < num_threads; i++) {
+            ret = pthread_join(tid[i], &results[i]);
+            if (ret != 0) {
+                fprintf(stderr, "pthread_join failed\n");
+                return (1);
+            }
+        }
+
+        xmlCatalogCleanup();
+        for (i = 0; i < num_threads; i++)
+            if (results[i] != (void *) Okay) {
+                fprintf(stderr, "Thread %d handling %s failed\n",
+                        i, testfiles[i]);
+                res = 1;
+            }
+    }
+    return (res);
+}
+
 #else
 static int
 testThread(void)
@@ -4158,6 +4240,9 @@ testDesc testDescriptions[] = {
     { "Error cases regression tests",
       errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",
       0 },
+    { "Error cases regression tests (old 1.0)",
+      errParseTest, "./test/errors10/*.xml", "result/errors10/", "", ".err",
+      XML_PARSE_OLD10 },
 #ifdef LIBXML_READER_ENABLED
     { "Error cases stream regression tests",
       streamParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".str",
@@ -4179,10 +4264,13 @@ testDesc testDescriptions[] = {
     { "SAX1 callbacks regression tests" ,
       saxParseTest, "./test/*", "result/", ".sax", NULL,
       XML_PARSE_SAX1 },
+#endif
     { "SAX2 callbacks regression tests" ,
       saxParseTest, "./test/*", "result/", ".sax2", NULL,
       0 },
-#endif
+    { "SAX2 callbacks regression tests with entity substitution" ,
+      saxParseTest, "./test/*", "result/noent/", ".sax2", NULL,
+      XML_PARSE_NOENT },
 #ifdef LIBXML_PUSH_ENABLED
     { "XML push regression tests" ,
       pushParseTest, "./test/*", "result/", "", NULL,
@@ -4197,12 +4285,10 @@ testDesc testDescriptions[] = {
       pushParseTest, "./test/HTML/*", "result/HTML/", "", ".err",
       XML_PARSE_HTML },
 #endif
-#ifdef LIBXML_SAX1_ENABLED
     { "HTML SAX regression tests" ,
       saxParseTest, "./test/HTML/*", "result/HTML/", ".sax", NULL,
       XML_PARSE_HTML },
 #endif
-#endif
 #ifdef LIBXML_VALID_ENABLED
     { "Valid documents regression tests" ,
       errParseTest, "./test/VCM/*", NULL, NULL, NULL,
@@ -4210,6 +4296,14 @@ testDesc testDescriptions[] = {
     { "Validity checking regression tests" ,
       errParseTest, "./test/VC/*", "result/VC/", NULL, "",
       XML_PARSE_DTDVALID },
+#ifdef LIBXML_READER_ENABLED
+    { "Streaming validity checking regression tests" ,
+      streamParseTest, "./test/valid/*.xml", "result/valid/", NULL, ".err.rdr",
+      XML_PARSE_DTDVALID },
+    { "Streaming validity error checking regression tests" ,
+      streamParseTest, "./test/VC/*", "result/VC/", NULL, ".rdr",
+      XML_PARSE_DTDVALID },
+#endif
     { "General documents valid regression tests" ,
       errParseTest, "./test/valid/*", "result/valid/", "", ".err",
       XML_PARSE_DTDVALID },
@@ -4297,7 +4391,7 @@ testDesc testDescriptions[] = {
       c14n11WithoutCommentTest, "./test/c14n/1-1-without-comments/*.xml", NULL, NULL, NULL,
       0 },
 #endif
-#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_SAX1_ENABLED)
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
     { "Catalog and Threads regression tests" ,
       threadsTest, NULL, NULL, NULL, NULL,
       0 },
@@ -4348,9 +4442,9 @@ launchTests(testDescPtr tst) {
            } else {
                error = NULL;
            }
-           if ((result) &&(!checkTestFile(result))) {
+           if ((result) &&(!checkTestFile(result)) && !update_results) {
                fprintf(stderr, "Missing result file %s\n", result);
-           } else if ((error) &&(!checkTestFile(error))) {
+           } else if ((error) &&(!checkTestFile(error)) && !update_results) {
                fprintf(stderr, "Missing error file %s\n", error);
            } else {
                mem = xmlMemUsed();
@@ -4434,6 +4528,8 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
     for (a = 1; a < argc;a++) {
         if (!strcmp(argv[a], "-v"))
            verbose = 1;
+        else if (!strcmp(argv[a], "-u"))
+           update_results = 1;
         else if (!strcmp(argv[a], "-quiet"))
            tests_quiet = 1;
        else {