* daniel@veillard.com
*/
-#ifdef HAVE_CONFIG_H
#include "libxml.h"
-#else
#include <stdio.h>
-#endif
#if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h>
#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,
int options; /* parser options for the test */
};
+static int update_results = 0;
static int checkTestFile(const char *filename);
#if defined(_WIN32) && !defined(__CYGWIN__)
}
}
-#if !defined(__MINGW32__)
-#define vsnprintf _vsnprintf
-#define snprintf _snprintf
-#endif
#else
#include <glob.h>
#endif
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);
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)
idx += res;
}
close(fd);
+ if (idx != size) {
+ fprintf(stderr,"Compare error index %d, size %d\n", idx, size);
+ }
return(idx != size);
}
static xmlSAXHandlerPtr debugHTMLSAXHandler = &debugHTMLSAXHandlerStruct;
#endif /* LIBXML_HTML_ENABLED */
-#ifdef LIBXML_SAX1_ENABLED
/**
* saxParseTest:
* @filename: the file to parse
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) {
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);
fprintf(stderr, "Got a difference for %s\n", filename);
ret = 1;
}
+
+done:
if (temp != NULL) {
unlink(temp);
free(temp);
return(ret);
}
-#endif
/************************************************************************
* *
const char *base;
int size, res;
int cur = 0;
+ int chunkSize = 4;
nb_tests++;
/*
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);
} 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)
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);
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);
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) {
}
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;
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);
}
}
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);
}
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);
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);
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) {
xmlXPathDebugDumpObject(xpathOutput, res, 0);
xmlXPathFreeObject(res);
xmlXPathFreeContext(ctxt);
+
+ /* Reset generic error handler. */
+ initGenericErrorDefaultFunc(NULL);
}
/**
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);
}
}
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;
}
}
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;
}
}
"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
};
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);
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);
}
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) {
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);
}
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 *
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 {
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>
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)
{ "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",
{ "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,
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,
{ "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 },
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 },
} 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();
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 {