excluded content string check for XML_ELEMENT_DECL in

* debugXML.c: excluded content string check for XML_ELEMENT_DECL
  in xmlCtxtGenericNodeCheck
* runtest.c: changed "open" calls to include O_BINARY for Windows
diff --git a/ChangeLog b/ChangeLog
index ba4c85e..91ecee9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Jul  6 10:38:02 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* debugXML.c: excluded content string check for XML_ELEMENT_DECL
+	  in xmlCtxtGenericNodeCheck
+	* runtest.c: changed "open" calls to include O_BINARY for Windows
+
 Wed Jul  6 17:14:03 CEST 2005 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c: fixing bug #166777 (and #169838), it was an heuristic
diff --git a/debugXML.c b/debugXML.c
index 35e0ad1..3cb2848 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -347,6 +347,7 @@
 	(node->type != XML_ELEMENT_DECL) &&
 	(node->type != XML_ATTRIBUTE_DECL) &&
 	(node->type != XML_DTD_NODE) &&
+	(node->type != XML_ELEMENT_DECL) &&
 	(node->type != XML_HTML_DOCUMENT_NODE) &&
 	(node->type != XML_DOCUMENT_NODE)) {
 	if (node->content != NULL)
diff --git a/runtest.c b/runtest.c
index 63cf0d5..88c39b8 100644
--- a/runtest.c
+++ b/runtest.c
@@ -1,4207 +1,4212 @@
-/*
- * runtest.c: C program to run libxml2 regression tests without
- *            requiring make or Python, and reducing platform dependancies
- *            to a strict minimum.
- *
- * To compile on Unixes:
- * cc -o runtest `xml2-config --cflags` runtest.c `xml2-config --libs` -lpthread
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#include <unistd.h>
-#endif
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/uri.h>
-
-#ifdef LIBXML_OUTPUT_ENABLED
-#ifdef LIBXML_READER_ENABLED
-#include <libxml/xmlreader.h>
-#endif
-
-#ifdef LIBXML_XINCLUDE_ENABLED
-#include <libxml/xinclude.h>
-#endif
-
-#ifdef LIBXML_XPATH_ENABLED
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#ifdef LIBXML_XPTR_ENABLED
-#include <libxml/xpointer.h>
-#endif
-#endif
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-#include <libxml/relaxng.h>
-#include <libxml/xmlschemas.h>
-#include <libxml/xmlschemastypes.h>
-#endif
-
-#ifdef LIBXML_PATTERN_ENABLED
-#include <libxml/pattern.h>
-#endif
-
-#ifdef LIBXML_C14N_ENABLED
-#include <libxml/c14n.h>
-#endif
-
-#ifdef LIBXML_HTML_ENABLED
-#include <libxml/HTMLparser.h>
-#include <libxml/HTMLtree.h>
-
-/*
- * pseudo flag for the unification of HTML and XML tests
- */
-#define XML_PARSE_HTML 1 << 24
-#endif
-
-#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
-#include <libxml/globals.h>
-#include <libxml/threads.h>
-#include <libxml/parser.h>
-#include <libxml/catalog.h>
-#include <string.h>
-#endif
-
-typedef int (*functest) (const char *filename, const char *result,
-                         const char *error, int options);
-
-typedef struct testDesc testDesc;
-typedef testDesc *testDescPtr;
-struct testDesc {
-    const char *desc; /* descripton of the test */
-    functest    func; /* function implementing the test */
-    const char *in;   /* glob to path for input files */
-    const char *out;  /* output directory */
-    const char *suffix;/* suffix for output files */
-    const char *err;  /* suffix for error output files */
-    int     options;  /* parser options for the test */
-};
-
-static int checkTestFile(const char *filename);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-#include <windows.h>
-#include <io.h>
-
-typedef struct
-{
-      size_t gl_pathc;    /* Count of paths matched so far  */
-      char **gl_pathv;    /* List of matched pathnames.  */
-      size_t gl_offs;     /* Slots to reserve in 'gl_pathv'.  */
-} glob_t;
-
-#define GLOB_DOOFFS 0
-static int glob(const char *pattern, int flags,
-                int errfunc(const char *epath, int eerrno),
-                glob_t *pglob) {
-    glob_t *ret;
-    WIN32_FIND_DATA FindFileData;
-    HANDLE hFind;
-    unsigned int nb_paths = 0;
-    char directory[500];
-    int len;
-
-    if ((pattern == NULL) || (pglob == NULL)) return(-1);
-    
-    strncpy(directory, pattern, 499);
-    for (len = strlen(directory);len >= 0;len--) {
-        if (directory[len] == '/') {
-	    len++;
-	    directory[len] = 0;
-	    break;
-	}
-    }
-    if (len <= 0)
-        len = 0;
-
-    
-    ret = pglob;
-    memset(ret, 0, sizeof(glob_t));
-    
-    hFind = FindFirstFileA(pattern, &FindFileData);
-    if (hFind == INVALID_HANDLE_VALUE) 
-        return(0);
-    nb_paths = 20;
-    ret->gl_pathv = (char **) malloc(nb_paths * sizeof(char *));
-    if (ret->gl_pathv == NULL) {
-	FindClose(hFind);
-        return(-1);
-    }
-    strncpy(directory + len, FindFileData.cFileName, 499 - len);
-    ret->gl_pathv[ret->gl_pathc] = strdup(directory);
-    if (ret->gl_pathv[ret->gl_pathc] == NULL)
-        goto done;
-    ret->gl_pathc++;
-    while(FindNextFileA(hFind, &FindFileData)) {
-        if (FindFileData.cFileName[0] == '.')
-	    continue;
-        if (ret->gl_pathc + 2 > nb_paths) {
-            char **tmp = realloc(ret->gl_pathv, nb_paths * 2 * sizeof(char *));
-            if (tmp == NULL)
-                break;
-            ret->gl_pathv = tmp;
-            nb_paths *= 2;
-	}
-	strncpy(directory + len, FindFileData.cFileName, 499 - len);
-	ret->gl_pathv[ret->gl_pathc] = strdup(directory);
-        if (ret->gl_pathv[ret->gl_pathc] == NULL)
-            break;
-        ret->gl_pathc++;
-    }
-    ret->gl_pathv[ret->gl_pathc] = NULL;
-
-done:
-    FindClose(hFind);
-    return(0);
-}
- 
-
-
-static void globfree(glob_t *pglob) {
-    unsigned int i;
-    if (pglob == NULL)
-        return;
-    
-    for (i = 0;i < pglob->gl_pathc;i++) {
-         if (pglob->gl_pathv[i] != NULL)
-             free(pglob->gl_pathv[i]);
-    }
-}
-#define vsnprintf _vsnprintf
-#define snprintf _snprintf
-#else
-#include <glob.h>
-#endif
-
-/************************************************************************
- *									*
- *		Libxml2 specific routines				*
- *									*
- ************************************************************************/
-
-static int nb_tests = 0;
-static int nb_errors = 0;
-static int nb_leaks = 0;
-static long libxmlMemoryAllocatedBase = 0;
-static int extraMemoryFromResolver = 0;
-
-static int
-fatalError(void) {
-    fprintf(stderr, "Exitting tests on fatal error\n");
-    exit(1);
-}
-
-/*
- * 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;
-
-    if (checkTestFile(URL)) {
-	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
-    } else {
-	int memused = xmlMemUsed();
-	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
-	extraMemoryFromResolver += xmlMemUsed() - memused;
-    }
-      
-    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
-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 void
-channel(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;
-}
-
-/**
- * xmlParserPrintFileContext:
- * @input:  an xmlParserInputPtr input
- * 
- * Displays current context within the input content for error tracking
- */
-
-static void
-xmlParserPrintFileContextInternal(xmlParserInputPtr input , 
-		xmlGenericErrorFunc chanl, void *data ) {
-    const xmlChar *cur, *base;
-    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
-    xmlChar  content[81]; /* space for 80 chars + line terminator */
-    xmlChar *ctnt;
-
-    if (input == NULL) return;
-    cur = input->cur;
-    base = input->base;
-    /* skip backwards over any end-of-lines */
-    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
-	cur--;
-    }
-    n = 0;
-    /* search backwards for beginning-of-line (to max buff size) */
-    while ((n++ < (sizeof(content)-1)) && (cur > base) && 
-    	   (*(cur) != '\n') && (*(cur) != '\r'))
-        cur--;
-    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
-    /* calculate the error position in terms of the current position */
-    col = input->cur - cur;
-    /* search forward for end-of-line (to max buff size) */
-    n = 0;
-    ctnt = content;
-    /* copy selected text to our buffer */
-    while ((*cur != 0) && (*(cur) != '\n') && 
-    	   (*(cur) != '\r') && (n < sizeof(content)-1)) {
-		*ctnt++ = *cur++;
-	n++;
-    }
-    *ctnt = 0;
-    /* print out the selected text */
-    chanl(data ,"%s\n", content);
-    /* create blank line with problem pointer */
-    n = 0;
-    ctnt = content;
-    /* (leave buffer space for pointer + line terminator) */
-    while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
-	if (*(ctnt) != '\t')
-	    *(ctnt) = ' ';
-	ctnt++;
-    }
-    *ctnt++ = '^';
-    *ctnt = 0;
-    chanl(data ,"%s\n", content);
-}
-
-static void
-testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
-    char *file = NULL;
-    int line = 0;
-    int code = -1;
-    int domain;
-    void *data = NULL;
-    const char *str;
-    const xmlChar *name = NULL;
-    xmlNodePtr node;
-    xmlErrorLevel level;
-    xmlParserInputPtr input = NULL;
-    xmlParserInputPtr cur = NULL;
-    xmlParserCtxtPtr ctxt = NULL;
-
-    if (err == NULL)
-        return;
-
-    file = err->file;
-    line = err->line;
-    code = err->code;
-    domain = err->domain;
-    level = err->level;
-    node = err->node;
-    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
-        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
-	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
-	ctxt = err->ctxt;
-    }
-    str = err->message;
-
-    if (code == XML_ERR_OK)
-        return;
-
-    if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
-        name = node->name;
-
-    /*
-     * Maintain the compatibility with the legacy error handling
-     */
-    if (ctxt != NULL) {
-        input = ctxt->input;
-        if ((input != NULL) && (input->filename == NULL) &&
-            (ctxt->inputNr > 1)) {
-            cur = input;
-            input = ctxt->inputTab[ctxt->inputNr - 2];
-        }
-        if (input != NULL) {
-            if (input->filename)
-                channel(data, "%s:%d: ", input->filename, input->line);
-            else if ((line != 0) && (domain == XML_FROM_PARSER))
-                channel(data, "Entity: line %d: ", input->line);
-        }
-    } else {
-        if (file != NULL)
-            channel(data, "%s:%d: ", file, line);
-        else if ((line != 0) && (domain == XML_FROM_PARSER))
-            channel(data, "Entity: line %d: ", line);
-    }
-    if (name != NULL) {
-        channel(data, "element %s: ", name);
-    }
-    if (code == XML_ERR_OK)
-        return;
-    switch (domain) {
-        case XML_FROM_PARSER:
-            channel(data, "parser ");
-            break;
-        case XML_FROM_NAMESPACE:
-            channel(data, "namespace ");
-            break;
-        case XML_FROM_DTD:
-        case XML_FROM_VALID:
-            channel(data, "validity ");
-            break;
-        case XML_FROM_HTML:
-            channel(data, "HTML parser ");
-            break;
-        case XML_FROM_MEMORY:
-            channel(data, "memory ");
-            break;
-        case XML_FROM_OUTPUT:
-            channel(data, "output ");
-            break;
-        case XML_FROM_IO:
-            channel(data, "I/O ");
-            break;
-        case XML_FROM_XINCLUDE:
-            channel(data, "XInclude ");
-            break;
-        case XML_FROM_XPATH:
-            channel(data, "XPath ");
-            break;
-        case XML_FROM_XPOINTER:
-            channel(data, "parser ");
-            break;
-        case XML_FROM_REGEXP:
-            channel(data, "regexp ");
-            break;
-        case XML_FROM_MODULE:
-            channel(data, "module ");
-            break;
-        case XML_FROM_SCHEMASV:
-            channel(data, "Schemas validity ");
-            break;
-        case XML_FROM_SCHEMASP:
-            channel(data, "Schemas parser ");
-            break;
-        case XML_FROM_RELAXNGP:
-            channel(data, "Relax-NG parser ");
-            break;
-        case XML_FROM_RELAXNGV:
-            channel(data, "Relax-NG validity ");
-            break;
-        case XML_FROM_CATALOG:
-            channel(data, "Catalog ");
-            break;
-        case XML_FROM_C14N:
-            channel(data, "C14N ");
-            break;
-        case XML_FROM_XSLT:
-            channel(data, "XSLT ");
-            break;
-        default:
-            break;
-    }
-    if (code == XML_ERR_OK)
-        return;
-    switch (level) {
-        case XML_ERR_NONE:
-            channel(data, ": ");
-            break;
-        case XML_ERR_WARNING:
-            channel(data, "warning : ");
-            break;
-        case XML_ERR_ERROR:
-            channel(data, "error : ");
-            break;
-        case XML_ERR_FATAL:
-            channel(data, "error : ");
-            break;
-    }
-    if (code == XML_ERR_OK)
-        return;
-    if (str != NULL) {
-        int len;
-	len = xmlStrlen((const xmlChar *)str);
-	if ((len > 0) && (str[len - 1] != '\n'))
-	    channel(data, "%s\n", str);
-	else
-	    channel(data, "%s", str);
-    } else {
-        channel(data, "%s\n", "out of memory error");
-    }
-    if (code == XML_ERR_OK)
-        return;
-
-    if (ctxt != NULL) {
-        xmlParserPrintFileContextInternal(input, channel, data);
-        if (cur != NULL) {
-            if (cur->filename)
-                channel(data, "%s:%d: \n", cur->filename, cur->line);
-            else if ((line != 0) && (domain == XML_FROM_PARSER))
-                channel(data, "Entity: line %d: \n", cur->line);
-            xmlParserPrintFileContextInternal(cur, channel, data);
-        }
-    }
-    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
-        (err->int1 < 100) &&
-	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
-	xmlChar buf[150];
-	int i;
-
-	channel(data, "%s\n", err->str1);
-	for (i=0;i < err->int1;i++)
-	     buf[i] = ' ';
-	buf[i++] = '^';
-	buf[i] = 0;
-	channel(data, "%s\n", buf);
-    }
-}
-
-static void
-initializeLibxml2(void) {
-    xmlGetWarningsDefaultValue = 0;
-    xmlPedanticParserDefault(0);
-
-    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
-    xmlInitParser();
-    xmlSetExternalEntityLoader(testExternalEntityLoader);
-    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
-#ifdef LIBXML_SCHEMAS_ENABLED
-    xmlSchemaInitTypes();
-    xmlRelaxNGInitTypes();
-#endif
-    libxmlMemoryAllocatedBase = xmlMemUsed();
-}
-
-
-/************************************************************************
- *									*
- *		File name and path utilities				*
- *									*
- ************************************************************************/
-
-static const char *baseFilename(const char *filename) {
-    const char *cur;
-    if (filename == NULL)
-        return(NULL);
-    cur = &filename[strlen(filename)];
-    while ((cur > filename) && (*cur != '/'))
-        cur--;
-    if (*cur == '/')
-        return(cur + 1);
-    return(cur);
-}
-
-static char *resultFilename(const char *filename, const char *out,
-                            const char *suffix) {
-    const char *base;
-    char res[500];
-
-/*************
-    if ((filename[0] == 't') && (filename[1] == 'e') &&
-        (filename[2] == 's') && (filename[3] == 't') &&
-	(filename[4] == '/'))
-	filename = &filename[5];
- *************/
-    
-    base = baseFilename(filename);
-    if (suffix == NULL)
-        suffix = ".tmp";
-    if (out == NULL)
-        out = "";
-    snprintf(res, 499, "%s%s%s", out, base, suffix);
-    res[499] = 0;
-    return(strdup(res));
-}
-
-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 int compareFiles(const char *r1, const char *r2) {
-    int res1, res2;
-    int fd1, fd2;
-    char bytes1[4096];
-    char bytes2[4096];
-
-    fd1 = open(r1, O_RDONLY);
-    if (fd1 < 0)
-        return(-1);
-    fd2 = open(r2, O_RDONLY);
-    if (fd2 < 0) {
-        close(fd1);
-        return(-1);
-    }
-    while (1) {
-        res1 = read(fd1, bytes1, 4096);
-        res2 = read(fd2, bytes2, 4096);
-	if (res1 != res2) {
-	    close(fd1);
-	    close(fd2);
-	    return(1);
-	}
-	if (res1 == 0)
-	    break;
-	if (memcmp(bytes1, bytes2, res1) != 0) {
-	    close(fd1);
-	    close(fd2);
-	    return(1);
-	}
-    }
-    close(fd1);
-    close(fd2);
-    return(0);
-}
-
-static int compareFileMem(const char *filename, const char *mem, int size) {
-    int res;
-    int fd;
-    char bytes[4096];
-    int idx = 0;
-    struct stat info;
-
-    if (stat(filename, &info) < 0) 
-	return(-1);
-    if (info.st_size != size)
-        return(-1);
-    fd = open(filename, O_RDONLY);
-    if (fd < 0)
-        return(-1);
-    while (idx < size) {
-        res = read(fd, bytes, 4096);
-	if (res <= 0)
-	    break;
-	if (res + idx > size) 
-	    break;
-	if (memcmp(bytes, &mem[idx], res) != 0) {
-	    close(fd);
-	    return(1);
-	}
-	idx += res;
-    }
-    close(fd);
-    return(idx != size);
-}
-
-static int loadMem(const char *filename, const char **mem, int *size) {
-    int fd, res;
-    struct stat info;
-    char *base;
-    int siz = 0;
-    if (stat(filename, &info) < 0) 
-	return(-1);
-    base = malloc(info.st_size + 1);
-    if (base == NULL)
-	return(-1);
-    if ((fd = open(filename, O_RDONLY)) < 0) {
-        free(base);
-	return(-1);
-    }
-    while ((res = read(fd, &base[siz], info.st_size - siz)) > 0) {
-        siz += res;
-    }
-    close(fd);

-#if !defined(_WIN32)
-    if (siz != info.st_size) {
-        free(base);
-	return(-1);
+/*

+ * runtest.c: C program to run libxml2 regression tests without

+ *            requiring make or Python, and reducing platform dependancies

+ *            to a strict minimum.

+ *

+ * To compile on Unixes:

+ * cc -o runtest `xml2-config --cflags` runtest.c `xml2-config --libs` -lpthread

+ *

+ * See Copyright for the status of this software.

+ *

+ * daniel@veillard.com

+ */

+

+#if !defined(_WIN32) || defined(__CYGWIN__)

+#include <unistd.h>

+#endif

+#include <string.h>

+#include <stdio.h>

+#include <sys/types.h>

+#include <sys/stat.h>

+#include <fcntl.h>

+

+#include <libxml/parser.h>

+#include <libxml/tree.h>

+#include <libxml/uri.h>

+

+#ifdef LIBXML_OUTPUT_ENABLED

+#ifdef LIBXML_READER_ENABLED

+#include <libxml/xmlreader.h>

+#endif

+

+#ifdef LIBXML_XINCLUDE_ENABLED

+#include <libxml/xinclude.h>

+#endif

+

+#ifdef LIBXML_XPATH_ENABLED

+#include <libxml/xpath.h>

+#include <libxml/xpathInternals.h>

+#ifdef LIBXML_XPTR_ENABLED

+#include <libxml/xpointer.h>

+#endif

+#endif

+

+#ifdef LIBXML_SCHEMAS_ENABLED

+#include <libxml/relaxng.h>

+#include <libxml/xmlschemas.h>

+#include <libxml/xmlschemastypes.h>

+#endif

+

+#ifdef LIBXML_PATTERN_ENABLED

+#include <libxml/pattern.h>

+#endif

+

+#ifdef LIBXML_C14N_ENABLED

+#include <libxml/c14n.h>

+#endif

+

+#ifdef LIBXML_HTML_ENABLED

+#include <libxml/HTMLparser.h>

+#include <libxml/HTMLtree.h>

+

+/*

+ * pseudo flag for the unification of HTML and XML tests

+ */

+#define XML_PARSE_HTML 1 << 24

+#endif

+

+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)

+#include <libxml/globals.h>

+#include <libxml/threads.h>

+#include <libxml/parser.h>

+#include <libxml/catalog.h>

+#include <string.h>

+#endif

+

+typedef int (*functest) (const char *filename, const char *result,

+                         const char *error, int options);

+

+typedef struct testDesc testDesc;

+typedef testDesc *testDescPtr;

+struct testDesc {

+    const char *desc; /* descripton of the test */

+    functest    func; /* function implementing the test */

+    const char *in;   /* glob to path for input files */

+    const char *out;  /* output directory */

+    const char *suffix;/* suffix for output files */

+    const char *err;  /* suffix for error output files */

+    int     options;  /* parser options for the test */

+};

+

+static int checkTestFile(const char *filename);

+

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

+

+#include <windows.h>

+#include <io.h>

+

+typedef struct

+{

+      size_t gl_pathc;    /* Count of paths matched so far  */

+      char **gl_pathv;    /* List of matched pathnames.  */

+      size_t gl_offs;     /* Slots to reserve in 'gl_pathv'.  */

+} glob_t;

+

+#define GLOB_DOOFFS 0

+static int glob(const char *pattern, int flags,

+                int errfunc(const char *epath, int eerrno),

+                glob_t *pglob) {

+    glob_t *ret;

+    WIN32_FIND_DATA FindFileData;

+    HANDLE hFind;

+    unsigned int nb_paths = 0;

+    char directory[500];

+    int len;

+

+    if ((pattern == NULL) || (pglob == NULL)) return(-1);

+    

+    strncpy(directory, pattern, 499);

+    for (len = strlen(directory);len >= 0;len--) {

+        if (directory[len] == '/') {

+	    len++;

+	    directory[len] = 0;

+	    break;

+	}

     }

-#endif
-    base[siz] = 0;
-    *mem = base;
-    *size = siz;
-    return(0);
-}
-
-static int unloadMem(const char *mem) {
-    free((char *)mem);
-    return(0);
-}
-
-/************************************************************************
- *									*
- *		Tests implementations					*
- *									*
- ************************************************************************/
-
-/************************************************************************
- *									*
- *		Parse to SAX based tests				*
- *									*
- ************************************************************************/
-
-FILE *SAXdebug = NULL;
-
-/*
- * empty SAX block
- */
-xmlSAXHandler emptySAXHandlerStruct = {
-    NULL, /* internalSubset */
-    NULL, /* isStandalone */
-    NULL, /* hasInternalSubset */
-    NULL, /* hasExternalSubset */
-    NULL, /* resolveEntity */
-    NULL, /* getEntity */
-    NULL, /* entityDecl */
-    NULL, /* notationDecl */
-    NULL, /* attributeDecl */
-    NULL, /* elementDecl */
-    NULL, /* unparsedEntityDecl */
-    NULL, /* setDocumentLocator */
-    NULL, /* startDocument */
-    NULL, /* endDocument */
-    NULL, /* startElement */
-    NULL, /* endElement */
-    NULL, /* reference */
-    NULL, /* characters */
-    NULL, /* ignorableWhitespace */
-    NULL, /* processingInstruction */
-    NULL, /* comment */
-    NULL, /* xmlParserWarning */
-    NULL, /* xmlParserError */
-    NULL, /* xmlParserError */
-    NULL, /* getParameterEntity */
-    NULL, /* cdataBlock; */
-    NULL, /* externalSubset; */
-    1,
-    NULL,
-    NULL, /* startElementNs */
-    NULL, /* endElementNs */
-    NULL  /* xmlStructuredErrorFunc */
-};
-
-static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
-int callbacks = 0;
-int quiet = 0;
-
-/**
- * isStandaloneDebug:
- * @ctxt:  An XML parser context
- *
- * Is this document tagged standalone ?
- *
- * Returns 1 if true
- */
-static int
-isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return(0);
-    fprintf(SAXdebug, "SAX.isStandalone()\n");
-    return(0);
-}
-
-/**
- * hasInternalSubsetDebug:
- * @ctxt:  An XML parser context
- *
- * Does this document has an internal subset
- *
- * Returns 1 if true
- */
-static int
-hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return(0);
-    fprintf(SAXdebug, "SAX.hasInternalSubset()\n");
-    return(0);
-}
-
-/**
- * hasExternalSubsetDebug:
- * @ctxt:  An XML parser context
- *
- * Does this document has an external subset
- *
- * Returns 1 if true
- */
-static int
-hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return(0);
-    fprintf(SAXdebug, "SAX.hasExternalSubset()\n");
-    return(0);
-}
-
-/**
- * internalSubsetDebug:
- * @ctxt:  An XML parser context
- *
- * Does this document has an internal subset
- */
-static void
-internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
-	       const xmlChar *ExternalID, const xmlChar *SystemID)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.internalSubset(%s,", name);
-    if (ExternalID == NULL)
-	fprintf(SAXdebug, " ,");
-    else
-	fprintf(SAXdebug, " %s,", ExternalID);
-    if (SystemID == NULL)
-	fprintf(SAXdebug, " )\n");
-    else
-	fprintf(SAXdebug, " %s)\n", SystemID);
-}
-
-/**
- * externalSubsetDebug:
- * @ctxt:  An XML parser context
- *
- * Does this document has an external subset
- */
-static void
-externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
-	       const xmlChar *ExternalID, const xmlChar *SystemID)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.externalSubset(%s,", name);
-    if (ExternalID == NULL)
-	fprintf(SAXdebug, " ,");
-    else
-	fprintf(SAXdebug, " %s,", ExternalID);
-    if (SystemID == NULL)
-	fprintf(SAXdebug, " )\n");
-    else
-	fprintf(SAXdebug, " %s)\n", SystemID);
-}
-
-/**
- * resolveEntityDebug:
- * @ctxt:  An XML parser context
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- *
- * Special entity resolver, better left to the parser, it has
- * more context than the application layer.
- * The default behaviour is to NOT resolve the entities, in that case
- * the ENTITY_REF nodes are built in the structure (and the parameter
- * values).
- *
- * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
- */
-static xmlParserInputPtr
-resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
-{
-    callbacks++;
-    if (quiet)
-	return(NULL);
-    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-
-    
-    fprintf(SAXdebug, "SAX.resolveEntity(");
-    if (publicId != NULL)
-	fprintf(SAXdebug, "%s", (char *)publicId);
-    else
-	fprintf(SAXdebug, " ");
-    if (systemId != NULL)
-	fprintf(SAXdebug, ", %s)\n", (char *)systemId);
-    else
-	fprintf(SAXdebug, ", )\n");
-/*********
-    if (systemId != NULL) {
-        return(xmlNewInputFromFile(ctxt, (char *) systemId));
-    }
- *********/
-    return(NULL);
-}
-
-/**
- * getEntityDebug:
- * @ctxt:  An XML parser context
- * @name: The entity name
- *
- * Get an entity by name
- *
- * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
- */
-static xmlEntityPtr
-getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
-{
-    callbacks++;
-    if (quiet)
-	return(NULL);
-    fprintf(SAXdebug, "SAX.getEntity(%s)\n", name);
-    return(NULL);
-}
-
-/**
- * getParameterEntityDebug:
- * @ctxt:  An XML parser context
- * @name: The entity name
- *
- * Get a parameter entity by name
- *
- * Returns the xmlParserInputPtr
- */
-static xmlEntityPtr
-getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
-{
-    callbacks++;
-    if (quiet)
-	return(NULL);
-    fprintf(SAXdebug, "SAX.getParameterEntity(%s)\n", name);
-    return(NULL);
-}
-
-
-/**
- * entityDeclDebug:
- * @ctxt:  An XML parser context
- * @name:  the entity name 
- * @type:  the entity type 
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- * @content: the entity value (without processing).
- *
- * An entity definition has been parsed
- */
-static void
-entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
-          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
-{
-const xmlChar *nullstr = BAD_CAST "(null)";
-    /* not all libraries handle printing null pointers nicely */
-    if (publicId == NULL)
-        publicId = nullstr;
-    if (systemId == NULL)
-        systemId = nullstr;
-    if (content == NULL)
-        content = (xmlChar *)nullstr;
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
-            name, type, publicId, systemId, content);
-}
-
-/**
- * attributeDeclDebug:
- * @ctxt:  An XML parser context
- * @name:  the attribute name 
- * @type:  the attribute type 
- *
- * An attribute definition has been parsed
- */
-static void
-attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
-                   const xmlChar * name, int type, int def,
-                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
-{
-    callbacks++;
-    if (quiet)
-        return;
-    if (defaultValue == NULL)
-        fprintf(SAXdebug, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
-                elem, name, type, def);
-    else
-        fprintf(SAXdebug, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
-                elem, name, type, def, defaultValue);
-    xmlFreeEnumeration(tree);
-}
-
-/**
- * elementDeclDebug:
- * @ctxt:  An XML parser context
- * @name:  the element name 
- * @type:  the element type 
- * @content: the element value (without processing).
- *
- * An element definition has been parsed
- */
-static void
-elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
-	    xmlElementContentPtr content ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.elementDecl(%s, %d, ...)\n",
-            name, type);
-}
-
-/**
- * notationDeclDebug:
- * @ctxt:  An XML parser context
- * @name: The name of the notation
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- *
- * What to do when a notation declaration has been parsed.
- */
-static void
-notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
-	     const xmlChar *publicId, const xmlChar *systemId)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.notationDecl(%s, %s, %s)\n",
-            (char *) name, (char *) publicId, (char *) systemId);
-}
-
-/**
- * unparsedEntityDeclDebug:
- * @ctxt:  An XML parser context
- * @name: The name of the entity
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- * @notationName: the name of the notation
- *
- * What to do when an unparsed entity declaration is parsed
- */
-static void
-unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
-		   const xmlChar *publicId, const xmlChar *systemId,
-		   const xmlChar *notationName)
-{
-const xmlChar *nullstr = BAD_CAST "(null)";
-
-    if (publicId == NULL)
-        publicId = nullstr;
-    if (systemId == NULL)
-        systemId = nullstr;
-    if (notationName == NULL)
-        notationName = nullstr;
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
-            (char *) name, (char *) publicId, (char *) systemId,
-	    (char *) notationName);
-}
-
-/**
- * setDocumentLocatorDebug:
- * @ctxt:  An XML parser context
- * @loc: A SAX Locator
- *
- * Receive the document locator at startup, actually xmlDefaultSAXLocator
- * Everything is available on the context, so this is useless in our case.
- */
-static void
-setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.setDocumentLocator()\n");
-}
-
-/**
- * startDocumentDebug:
- * @ctxt:  An XML parser context
- *
- * called when the document start being processed.
- */
-static void
-startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.startDocument()\n");
-}
-
-/**
- * endDocumentDebug:
- * @ctxt:  An XML parser context
- *
- * called when the document end has been detected.
- */
-static void
-endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.endDocument()\n");
-}
-
-/**
- * startElementDebug:
- * @ctxt:  An XML parser context
- * @name:  The element name
- *
- * called when an opening tag has been processed.
- */
-static void
-startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
-{
-    int i;
-
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.startElement(%s", (char *) name);
-    if (atts != NULL) {
-        for (i = 0;(atts[i] != NULL);i++) {
-	    fprintf(SAXdebug, ", %s='", atts[i++]);
-	    if (atts[i] != NULL)
-	        fprintf(SAXdebug, "%s'", atts[i]);
-	}
-    }
-    fprintf(SAXdebug, ")\n");
-}
-
-/**
- * endElementDebug:
- * @ctxt:  An XML parser context
- * @name:  The element name
- *
- * called when the end of an element has been detected.
- */
-static void
-endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.endElement(%s)\n", (char *) name);
-}
-
-/**
- * charactersDebug:
- * @ctxt:  An XML parser context
- * @ch:  a xmlChar string
- * @len: the number of xmlChar
- *
- * receiving some chars from the parser.
- * Question: how much at a time ???
- */
-static void
-charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
-{
-    char output[40];
-    int i;
-
-    callbacks++;
-    if (quiet)
-	return;
-    for (i = 0;(i<len) && (i < 30);i++)
-	output[i] = ch[i];
-    output[i] = 0;
-
-    fprintf(SAXdebug, "SAX.characters(%s, %d)\n", output, len);
-}
-
-/**
- * referenceDebug:
- * @ctxt:  An XML parser context
- * @name:  The entity name
- *
- * called when an entity reference is detected. 
- */
-static void
-referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.reference(%s)\n", name);
-}
-
-/**
- * ignorableWhitespaceDebug:
- * @ctxt:  An XML parser context
- * @ch:  a xmlChar string
- * @start: the first char in the string
- * @len: the number of xmlChar
- *
- * receiving some ignorable whitespaces from the parser.
- * Question: how much at a time ???
- */
-static void
-ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
-{
-    char output[40];
-    int i;
-
-    callbacks++;
-    if (quiet)
-	return;
-    for (i = 0;(i<len) && (i < 30);i++)
-	output[i] = ch[i];
-    output[i] = 0;
-    fprintf(SAXdebug, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
-}
-
-/**
- * processingInstructionDebug:
- * @ctxt:  An XML parser context
- * @target:  the target name
- * @data: the PI data's
- * @len: the number of xmlChar
- *
- * A processing instruction has been parsed.
- */
-static void
-processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
-                      const xmlChar *data)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    if (data != NULL)
-	fprintf(SAXdebug, "SAX.processingInstruction(%s, %s)\n",
-		(char *) target, (char *) data);
-    else
-	fprintf(SAXdebug, "SAX.processingInstruction(%s, NULL)\n",
-		(char *) target);
-}
-
-/**
- * cdataBlockDebug:
- * @ctx: the user data (XML parser context)
- * @value:  The pcdata content
- * @len:  the block length
- *
- * called when a pcdata block has been parsed
- */
-static void
-cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.pcdata(%.20s, %d)\n",
-	    (char *) value, len);
-}
-
-/**
- * commentDebug:
- * @ctxt:  An XML parser context
- * @value:  the comment content
- *
- * A comment has been parsed.
- */
-static void
-commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.comment(%s)\n", value);
-}
-
-/**
- * warningDebug:
- * @ctxt:  An XML parser context
- * @msg:  the message to display/transmit
- * @...:  extra parameters for the message display
- *
- * Display and format a warning messages, gives file, line, position and
- * extra parameters.
- */
-static void
-warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
-{
-    va_list args;
-
-    callbacks++;
-    if (quiet)
-	return;
-    va_start(args, msg);
-    fprintf(SAXdebug, "SAX.warning: ");
-    vfprintf(SAXdebug, msg, args);
-    va_end(args);
-}
-
-/**
- * errorDebug:
- * @ctxt:  An XML parser context
- * @msg:  the message to display/transmit
- * @...:  extra parameters for the message display
- *
- * Display and format a error messages, gives file, line, position and
- * extra parameters.
- */
-static void
-errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
-{
-    va_list args;
-
-    callbacks++;
-    if (quiet)
-	return;
-    va_start(args, msg);
-    fprintf(SAXdebug, "SAX.error: ");
-    vfprintf(SAXdebug, msg, args);
-    va_end(args);
-}
-
-/**
- * fatalErrorDebug:
- * @ctxt:  An XML parser context
- * @msg:  the message to display/transmit
- * @...:  extra parameters for the message display
- *
- * Display and format a fatalError messages, gives file, line, position and
- * extra parameters.
- */
-static void
-fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
-{
-    va_list args;
-
-    callbacks++;
-    if (quiet)
-	return;
-    va_start(args, msg);
-    fprintf(SAXdebug, "SAX.fatalError: ");
-    vfprintf(SAXdebug, msg, args);
-    va_end(args);
-}
-
-xmlSAXHandler debugSAXHandlerStruct = {
-    internalSubsetDebug,
-    isStandaloneDebug,
-    hasInternalSubsetDebug,
-    hasExternalSubsetDebug,
-    resolveEntityDebug,
-    getEntityDebug,
-    entityDeclDebug,
-    notationDeclDebug,
-    attributeDeclDebug,
-    elementDeclDebug,
-    unparsedEntityDeclDebug,
-    setDocumentLocatorDebug,
-    startDocumentDebug,
-    endDocumentDebug,
-    startElementDebug,
-    endElementDebug,
-    referenceDebug,
-    charactersDebug,
-    ignorableWhitespaceDebug,
-    processingInstructionDebug,
-    commentDebug,
-    warningDebug,
-    errorDebug,
-    fatalErrorDebug,
-    getParameterEntityDebug,
-    cdataBlockDebug,
-    externalSubsetDebug,
-    1,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
-
-xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
-
-/*
- * SAX2 specific callbacks
- */
-/**
- * startElementNsDebug:
- * @ctxt:  An XML parser context
- * @name:  The element name
- *
- * called when an opening tag has been processed.
- */
-static void
-startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
-                    const xmlChar *localname,
-                    const xmlChar *prefix,
-                    const xmlChar *URI,
-		    int nb_namespaces,
-		    const xmlChar **namespaces,
-		    int nb_attributes,
-		    int nb_defaulted,
-		    const xmlChar **attributes)
-{
-    int i;
-
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.startElementNs(%s", (char *) localname);
-    if (prefix == NULL)
-	fprintf(SAXdebug, ", NULL");
-    else
-	fprintf(SAXdebug, ", %s", (char *) prefix);
-    if (URI == NULL)
-	fprintf(SAXdebug, ", NULL");
-    else
-	fprintf(SAXdebug, ", '%s'", (char *) URI);
-    fprintf(SAXdebug, ", %d", nb_namespaces);
-    
-    if (namespaces != NULL) {
-        for (i = 0;i < nb_namespaces * 2;i++) {
-	    fprintf(SAXdebug, ", xmlns");
-	    if (namespaces[i] != NULL)
-	        fprintf(SAXdebug, ":%s", namespaces[i]);
-	    i++;
-	    fprintf(SAXdebug, "='%s'", namespaces[i]);
-	}
-    }
-    fprintf(SAXdebug, ", %d, %d", nb_attributes, nb_defaulted);
-    if (attributes != NULL) {
-        for (i = 0;i < nb_attributes * 5;i += 5) {
-	    if (attributes[i + 1] != NULL)
-		fprintf(SAXdebug, ", %s:%s='", attributes[i + 1], attributes[i]);
-	    else
-		fprintf(SAXdebug, ", %s='", attributes[i]);
-	    fprintf(SAXdebug, "%.4s...', %d", attributes[i + 3],
-		    (int)(attributes[i + 4] - attributes[i + 3]));
-	}
-    }
-    fprintf(SAXdebug, ")\n");
-}
-
-/**
- * endElementDebug:
- * @ctxt:  An XML parser context
- * @name:  The element name
- *
- * called when the end of an element has been detected.
- */
-static void
-endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
-                  const xmlChar *localname,
-                  const xmlChar *prefix,
-                  const xmlChar *URI)
-{
-    callbacks++;
-    if (quiet)
-	return;
-    fprintf(SAXdebug, "SAX.endElementNs(%s", (char *) localname);
-    if (prefix == NULL)
-	fprintf(SAXdebug, ", NULL");
-    else
-	fprintf(SAXdebug, ", %s", (char *) prefix);
-    if (URI == NULL)
-	fprintf(SAXdebug, ", NULL)\n");
-    else
-	fprintf(SAXdebug, ", '%s')\n", (char *) URI);
-}
-
-xmlSAXHandler debugSAX2HandlerStruct = {
-    internalSubsetDebug,
-    isStandaloneDebug,
-    hasInternalSubsetDebug,
-    hasExternalSubsetDebug,
-    resolveEntityDebug,
-    getEntityDebug,
-    entityDeclDebug,
-    notationDeclDebug,
-    attributeDeclDebug,
-    elementDeclDebug,
-    unparsedEntityDeclDebug,
-    setDocumentLocatorDebug,
-    startDocumentDebug,
-    endDocumentDebug,
-    NULL,
-    NULL,
-    referenceDebug,
-    charactersDebug,
-    ignorableWhitespaceDebug,
-    processingInstructionDebug,
-    commentDebug,
-    warningDebug,
-    errorDebug,
-    fatalErrorDebug,
-    getParameterEntityDebug,
-    cdataBlockDebug,
-    externalSubsetDebug,
-    XML_SAX2_MAGIC,
-    NULL,
-    startElementNsDebug,
-    endElementNsDebug,
-    NULL
-};
-
-xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
-
-#ifdef LIBXML_HTML_ENABLED
-/**
- * htmlstartElementDebug:
- * @ctxt:  An XML parser context
- * @name:  The element name
- *
- * called when an opening tag has been processed.
- */
-static void
-htmlstartElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
-{
-    int i;
-
-    fprintf(SAXdebug, "SAX.startElement(%s", (char *) name);
-    if (atts != NULL) {
-        for (i = 0;(atts[i] != NULL);i++) {
-	    fprintf(SAXdebug, ", %s", atts[i++]);
-	    if (atts[i] != NULL) {
-		unsigned char output[40];
-		const unsigned char *att = atts[i];
-		int outlen, attlen;
-	        fprintf(SAXdebug, "='");
-		while ((attlen = strlen((char*)att)) > 0) {
-		    outlen = sizeof output - 1;
-		    htmlEncodeEntities(output, &outlen, att, &attlen, '\'');
-		    output[outlen] = 0;
-		    fprintf(SAXdebug, "%s", (char *) output);
-		    att += attlen;
-		}
-		fprintf(SAXdebug, "'");
-	    }
-	}
-    }
-    fprintf(SAXdebug, ")\n");
-}
-
-/**
- * htmlcharactersDebug:
- * @ctxt:  An XML parser context
- * @ch:  a xmlChar string
- * @len: the number of xmlChar
- *
- * receiving some chars from the parser.
- * Question: how much at a time ???
- */
-static void
-htmlcharactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
-{
-    unsigned char output[40];
-    int inlen = len, outlen = 30;
-
-    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
-    output[outlen] = 0;
-
-    fprintf(SAXdebug, "SAX.characters(%s, %d)\n", output, len);
-}
-
-/**
- * htmlcdataDebug:
- * @ctxt:  An XML parser context
- * @ch:  a xmlChar string
- * @len: the number of xmlChar
- *
- * receiving some cdata chars from the parser.
- * Question: how much at a time ???
- */
-static void
-htmlcdataDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
-{
-    unsigned char output[40];
-    int inlen = len, outlen = 30;
-
-    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
-    output[outlen] = 0;
-
-    fprintf(SAXdebug, "SAX.cdata(%s, %d)\n", output, len);
-}
-
-xmlSAXHandler debugHTMLSAXHandlerStruct = {
-    internalSubsetDebug,
-    isStandaloneDebug,
-    hasInternalSubsetDebug,
-    hasExternalSubsetDebug,
-    resolveEntityDebug,
-    getEntityDebug,
-    entityDeclDebug,
-    notationDeclDebug,
-    attributeDeclDebug,
-    elementDeclDebug,
-    unparsedEntityDeclDebug,
-    setDocumentLocatorDebug,
-    startDocumentDebug,
-    endDocumentDebug,
-    htmlstartElementDebug,
-    endElementDebug,
-    referenceDebug,
-    htmlcharactersDebug,
-    ignorableWhitespaceDebug,
-    processingInstructionDebug,
-    commentDebug,
-    warningDebug,
-    errorDebug,
-    fatalErrorDebug,
-    getParameterEntityDebug,
-    htmlcdataDebug,
-    externalSubsetDebug,
-    1,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
-
-xmlSAXHandlerPtr debugHTMLSAXHandler = &debugHTMLSAXHandlerStruct;
-#endif /* LIBXML_HTML_ENABLED */
-
-#ifdef LIBXML_SAX1_ENABLED
-/**
- * saxParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file using the SAX API and check for errors.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-saxParseTest(const char *filename, const char *result,
-             const char *err ATTRIBUTE_UNUSED,
-             int options) {
-    int ret;
-    char *temp;
-
-    nb_tests++;
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "out of memory\n");
-        fatalError();
-    }
-    SAXdebug = fopen(temp, "wb");
-    if (SAXdebug == NULL) {
-        fprintf(stderr, "Failed to write to %s\n", temp);
-	free(temp);
-	return(-1);
-    }
-
-    /* for SAX we really want the callbacks though the context handlers */
-    xmlSetStructuredErrorFunc(NULL, NULL);
-    xmlSetGenericErrorFunc(NULL, testErrorHandler);
-
-#ifdef LIBXML_HTML_ENABLED
-    if (options & XML_PARSE_HTML) {
-	htmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);
-	ret = 0;
-    } else
-#endif
-    ret = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
-    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);
-    }
-#ifdef LIBXML_HTML_ENABLED
-    if (options & XML_PARSE_HTML) {
-	htmlSAXParseFile(filename, NULL, debugHTMLSAXHandler, NULL);
-	ret = 0;
-    } else
-#endif
-    if (options & XML_PARSE_SAX1) {
-	ret = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
-    } else {
-	ret = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
-    }
-    if (ret == XML_WAR_UNDECLARED_ENTITY) {
-        fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
-        ret = 0;
-    }
-    fclose(SAXdebug);
-    if (compareFiles(temp, result)) {
-        fprintf(stderr, "Got a difference for %s\n", filename);
-        ret = 1;
-    } else
-    unlink(temp);
-    free(temp);
-    
-    /* switch back to structured error handling */
-    xmlSetGenericErrorFunc(NULL, NULL);
-    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
-
-    return(ret);
-}
-#endif
-
-/************************************************************************
- *									*
- *		Parse to tree based tests				*
- *									*
- ************************************************************************/
-/**
- * oldParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages: unused
- *
- * Parse a file using the old xmlParseFile API, then serialize back
- * reparse the result and serialize again, then check for deviation
- * in serialization.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-oldParseTest(const char *filename, const char *result,
-             const char *err ATTRIBUTE_UNUSED,
-	     int options ATTRIBUTE_UNUSED) {
-    xmlDocPtr doc;
-    char *temp;
-    int res = 0;
-
-    nb_tests++;
-    /*
-     * base of the test, parse with the old API
-     */
-#ifdef LIBXML_SAX1_ENABLED
-    doc = xmlParseFile(filename);
-#else
-    doc = xmlReadFile(filename, NULL, 0);
-#endif
-    if (doc == NULL)
-        return(1);
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "out of memory\n");
-        fatalError();
-    }
-    xmlSaveFile(temp, doc);
-    if (compareFiles(temp, result)) {
-        res = 1;
-    }
-    xmlFreeDoc(doc);
-
-    /*
-     * Parse the saved result to make sure the round trip is okay
-     */
-#ifdef LIBXML_SAX1_ENABLED
-    doc = xmlParseFile(temp);
-#else
-    doc = xmlReadFile(temp, NULL, 0);
-#endif
-    if (doc == NULL)
-        return(1);
-    xmlSaveFile(temp, doc);
-    if (compareFiles(temp, result)) {
-        res = 1;
-    }
-    xmlFreeDoc(doc);
-
-    unlink(temp);
-    free(temp);
-    return(res);
-}
-
-#ifdef LIBXML_PUSH_ENABLED
-/**
- * pushParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages: unused
- *
- * Parse a file using the Push API, then serialize back
- * to check for content.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-pushParseTest(const char *filename, const char *result,
-             const char *err ATTRIBUTE_UNUSED,
-	     int options) {
-    xmlParserCtxtPtr ctxt;
-    xmlDocPtr doc;
-    const char *base;
-    int size, res;
-    int cur = 0;
-
-    nb_tests++;
-    /*
-     * load the document in memory and work from there.
-     */
-    if (loadMem(filename, &base, &size) != 0) {
-        fprintf(stderr, "Failed to load %s\n", filename);
-	return(-1);
-    }
-    
-#ifdef LIBXML_HTML_ENABLED
-    if (options & XML_PARSE_HTML)
-	ctxt = htmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename,
-	                                XML_CHAR_ENCODING_NONE);
-    else
-#endif
-    ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename);
-    xmlCtxtUseOptions(ctxt, options);
-    cur += 4;
-    while (cur < size) {
-        if (cur + 1024 >= size) {
-#ifdef LIBXML_HTML_ENABLED
-	    if (options & XML_PARSE_HTML)
-		htmlParseChunk(ctxt, base + cur, size - cur, 1);
-	    else
-#endif
-	    xmlParseChunk(ctxt, base + cur, size - cur, 1);
-	    break;
-	} else {
-#ifdef LIBXML_HTML_ENABLED
-	    if (options & XML_PARSE_HTML)
-		htmlParseChunk(ctxt, base + cur, 1024, 0);
-	    else
-#endif
-	    xmlParseChunk(ctxt, base + cur, 1024, 0);
-	    cur += 1024;
-	}
-    }
-    doc = ctxt->myDoc;
-#ifdef LIBXML_HTML_ENABLED
-    if (options & XML_PARSE_HTML)
-        res = 1;
-    else
-#endif
-    res = ctxt->wellFormed;
-    xmlFreeParserCtxt(ctxt);
-    free((char *)base);
-    if (!res) {
-	xmlFreeDoc(doc);
-	fprintf(stderr, "Failed to parse %s\n", filename);
-	return(-1);
-    }
-#ifdef LIBXML_HTML_ENABLED
-    if (options & XML_PARSE_HTML)
-	htmlDocDumpMemory(doc, (xmlChar **) &base, &size);
-    else
-#endif
-    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
-    xmlFreeDoc(doc);
-    res = compareFileMem(result, base, size);
-    if ((base == NULL) || (res != 0)) {
-	if (base != NULL)
-	    xmlFree((char *)base);
-        fprintf(stderr, "Result for %s failed\n", filename);
-	return(-1);
-    }
-    xmlFree((char *)base);
-    if (err != NULL) {
-	res = compareFileMem(err, testErrors, testErrorsSize);
-	if (res != 0) {
-	    fprintf(stderr, "Error for %s failed\n", filename);
-	    return(-1);
-	}
-    }
-    return(0);
-}
-#endif
-
-/**
- * memParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages: unused
- *
- * Parse a file using the old xmlReadMemory API, then serialize back
- * reparse the result and serialize again, then check for deviation
- * in serialization.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-memParseTest(const char *filename, const char *result,
-             const char *err ATTRIBUTE_UNUSED,
-	     int options ATTRIBUTE_UNUSED) {
-    xmlDocPtr doc;
-    const char *base;
-    int size, res;
-
-    nb_tests++;
-    /*
-     * load and parse the memory
-     */
-    if (loadMem(filename, &base, &size) != 0) {
-        fprintf(stderr, "Failed to load %s\n", filename);
-	return(-1);
-    }
-    
-    doc = xmlReadMemory(base, size, filename, NULL, 0);
-    unloadMem(base);
-    if (doc == NULL) {
-        return(1);
-    }
-    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
-    xmlFreeDoc(doc);
-    res = compareFileMem(result, base, size);
-    if ((base == NULL) || (res != 0)) {
-	if (base != NULL)
-	    xmlFree((char *)base);
-        fprintf(stderr, "Result for %s failed\n", filename);
-	return(-1);
-    }
-    xmlFree((char *)base);
-    return(0);
-}
-
-/**
- * noentParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages: unused
- *
- * Parse a file with entity resolution, then serialize back
- * reparse the result and serialize again, then check for deviation
- * in serialization.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-noentParseTest(const char *filename, const char *result,
-               const char *err  ATTRIBUTE_UNUSED,
-	       int options) {
-    xmlDocPtr doc;
-    char *temp;
-    int res = 0;
-
-    nb_tests++;
-    /*
-     * base of the test, parse with the old API
-     */
-    doc = xmlReadFile(filename, NULL, options);
-    if (doc == NULL)
-        return(1);
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    xmlSaveFile(temp, doc);
-    if (compareFiles(temp, result)) {
-        res = 1;
-    }
-    xmlFreeDoc(doc);
-
-    /*
-     * Parse the saved result to make sure the round trip is okay
-     */
-    doc = xmlReadFile(filename, NULL, options);
-    if (doc == NULL)
-        return(1);
-    xmlSaveFile(temp, doc);
-    if (compareFiles(temp, result)) {
-        res = 1;
-    }
-    xmlFreeDoc(doc);
-
-    unlink(temp);
-    free(temp);
-    return(res);
-}
-
-/**
- * errParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file using the xmlReadFile API and check for errors.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-errParseTest(const char *filename, const char *result, const char *err,
-             int options) {
-    xmlDocPtr doc;
-    const char *base = NULL;
-    int size, res = 0;
-
-    nb_tests++;
-#ifdef LIBXML_HTML_ENABLED
-    if (options & XML_PARSE_HTML) {
-        doc = htmlReadFile(filename, NULL, options);
-    } else
-#endif
-#ifdef LIBXML_XINCLUDE_ENABLED
-    if (options & XML_PARSE_XINCLUDE) {
-	doc = xmlReadFile(filename, NULL, options);
-	xmlXIncludeProcessFlags(doc, options);
-    } else
-#endif
-    {
-	xmlGetWarningsDefaultValue = 1;
-	doc = xmlReadFile(filename, NULL, options);
-    }
-    xmlGetWarningsDefaultValue = 0;
-    if (result) {
-	if (doc == NULL) {
-	    base = "";
-	    size = 0;
-	} else {
-#ifdef LIBXML_HTML_ENABLED
-	    if (options & XML_PARSE_HTML) {
-		htmlDocDumpMemory(doc, (xmlChar **) &base, &size);
-	    } else
-#endif
-	    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
-	}
-	res = compareFileMem(result, base, size);
-    }
-    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) {
-	    fprintf(stderr, "Error for %s failed\n", filename);
-	    return(-1);
-	}
-    } else if (options & XML_PARSE_DTDVALID) {
-        if (testErrorsSize != 0)
-	    fprintf(stderr, "Validation for %s failed\n", filename);
-    }
-
-    return(0);
-}
-
-#ifdef LIBXML_READER_ENABLED
-/************************************************************************
- *									*
- *		Reader based tests					*
- *									*
- ************************************************************************/
-
-static void processNode(FILE *out, xmlTextReaderPtr reader) {
-    const xmlChar *name, *value;
-    int type, empty;
-
-    type = xmlTextReaderNodeType(reader);
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    name = xmlTextReaderConstName(reader);
-    if (name == NULL)
-	name = BAD_CAST "--";
-
-    value = xmlTextReaderConstValue(reader);
-
-    
-    fprintf(out, "%d %d %s %d %d", 
-	    xmlTextReaderDepth(reader),
-	    type,
-	    name,
-	    empty,
-	    xmlTextReaderHasValue(reader));
-    if (value == NULL)
-	fprintf(out, "\n");
-    else {
-	fprintf(out, " %s\n", value);
-    }
-}
-static int
-streamProcessTest(const char *filename, const char *result, const char *err,
-                  xmlTextReaderPtr reader, const char *rng) {
-    int ret;
-    char *temp = NULL;
-    FILE *t = NULL;
-
-    if (reader == NULL)
-        return(-1);
-
-    nb_tests++;
-    if (result != NULL) {
-	temp = resultFilename(filename, "", ".res");
-	if (temp == NULL) {
-	    fprintf(stderr, "Out of memory\n");
-	    fatalError();
-	}
-	t = fopen(temp, "wb");
-	if (t == NULL) {
-	    fprintf(stderr, "Can't open temp file %s\n", temp);
-	    free(temp);
-	    return(-1);
-	}
-    }
-#ifdef LIBXML_SCHEMAS_ENABLED
-    if (rng != NULL) {
-	ret = xmlTextReaderRelaxNGValidate(reader, rng);
-	if (ret < 0) {
-	    testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n",
-	                     rng);
-	    fclose(t);
-	    unlink(temp);
-	    free(temp);
-	    return(0);
-	}
-    }
-#endif
-    xmlGetWarningsDefaultValue = 1;
-    ret = xmlTextReaderRead(reader);
-    while (ret == 1) {
-	if ((t != NULL) && (rng == NULL))
-	    processNode(t, reader);
-        ret = xmlTextReaderRead(reader);
-    }
-    if (ret != 0) {
-        testErrorHandler(NULL, "%s : failed to parse\n", filename);
-    }
-    if (rng != NULL) {
-        if (xmlTextReaderIsValid(reader) != 1) {
-	    testErrorHandler(NULL, "%s fails to validate\n", filename);
-	} else {
-	    testErrorHandler(NULL, "%s validates\n", filename);
-	}
-    }
-    xmlGetWarningsDefaultValue = 0;
-    if (t != NULL) {
-        fclose(t);
-	ret = compareFiles(temp, result);
-	unlink(temp);
-	free(temp);
-	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
-	    return(-1);
-	}
-    }
-    if (err != NULL) {
-	ret = compareFileMem(err, testErrors, testErrorsSize);
-	if (ret != 0) {
-	    fprintf(stderr, "Error for %s failed\n", filename);
-	    printf("%s", testErrors);
-	    return(-1);
-	}
-    }
-
-    return(0);
-}
-
-/**
- * streamParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file using the reader API and check for errors.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-streamParseTest(const char *filename, const char *result, const char *err,
-                int options) {
-    xmlTextReaderPtr reader;
-    int ret;
-
-    reader = xmlReaderForFile(filename, NULL, options);
-    ret = streamProcessTest(filename, result, err, reader, NULL);
-    xmlFreeTextReader(reader);
-    return(ret);
-}
-
-/**
- * walkerParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file using the walker, i.e. a reader built from a atree.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-walkerParseTest(const char *filename, const char *result, const char *err,
-                int options) {
-    xmlDocPtr doc;
-    xmlTextReaderPtr reader;
-    int ret;
-
-    doc = xmlReadFile(filename, NULL, options);
-    if (doc == NULL) {
-        fprintf(stderr, "Failed to parse %s\n", filename);
-	return(-1);
-    }
-    reader = xmlReaderWalker(doc);
-    ret = streamProcessTest(filename, result, err, reader, NULL);
-    xmlFreeTextReader(reader);
-    xmlFreeDoc(doc);
-    return(ret);
-}
-
-/**
- * streamMemParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file using the reader API from memory and check for errors.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-streamMemParseTest(const char *filename, const char *result, const char *err,
-                   int options) {
-    xmlTextReaderPtr reader;
-    int ret;
-    const char *base;
-    int size;
-
-    /*
-     * load and parse the memory
-     */
-    if (loadMem(filename, &base, &size) != 0) {
-        fprintf(stderr, "Failed to load %s\n", filename);
-	return(-1);
-    }
-    reader = xmlReaderForMemory(base, size, filename, NULL, options);
-    ret = streamProcessTest(filename, result, err, reader, NULL);
-    free((char *)base);
-    xmlFreeTextReader(reader);
-    return(ret);
-}
-#endif
-
-#ifdef LIBXML_XPATH_ENABLED
-#ifdef LIBXML_DEBUG_ENABLED
-/************************************************************************
- *									*
- *		XPath and XPointer based tests				*
- *									*
- ************************************************************************/
-
-FILE *xpathOutput;
-xmlDocPtr xpathDocument;
-
-static void
-testXPath(const char *str, int xptr, int expr) {
-    xmlXPathObjectPtr res;
-    xmlXPathContextPtr ctxt;
-    
-    nb_tests++;
-#if defined(LIBXML_XPTR_ENABLED)
-    if (xptr) {
-	ctxt = xmlXPtrNewContext(xpathDocument, NULL, NULL);
-	res = xmlXPtrEval(BAD_CAST str, ctxt);
-    } else {
-#endif
-	ctxt = xmlXPathNewContext(xpathDocument);
-	ctxt->node = xmlDocGetRootElement(xpathDocument);
-	if (expr)
-	    res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
-	else {
-	    /* res = xmlXPathEval(BAD_CAST str, ctxt); */
-	    xmlXPathCompExprPtr comp;
-
-	    comp = xmlXPathCompile(BAD_CAST str);
-	    if (comp != NULL) {
-		res = xmlXPathCompiledEval(comp, ctxt);
-		xmlXPathFreeCompExpr(comp);
-	    } else
-		res = NULL;
-	}
-#if defined(LIBXML_XPTR_ENABLED)
-    }
-#endif
-    xmlXPathDebugDumpObject(xpathOutput, res, 0);
-    xmlXPathFreeObject(res);
-    xmlXPathFreeContext(ctxt);
-}
-
-/**
- * xpathExprTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing XPath standalone expressions and evaluate them
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-xpathCommonTest(const char *filename, const char *result,
-                int xptr, int expr) {
-    FILE *input;
-    char expression[5000];
-    int len, ret = 0;
-    char *temp;
-
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    xpathOutput = fopen(temp, "wb");
-    if (xpathOutput == NULL) {
-	fprintf(stderr, "failed to open output file %s\n", temp);
-        free(temp);
-	return(-1);
-    }
-
-    input = fopen(filename, "rb");
-    if (input == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"Cannot open %s for reading\n", filename);
-        free(temp);
-	return(-1);
-    }
-    while (fgets(expression, 4500, input) != NULL) {
-	len = strlen(expression);
-	len--;
-	while ((len >= 0) && 
-	       ((expression[len] == '\n') || (expression[len] == '\t') ||
-		(expression[len] == '\r') || (expression[len] == ' '))) len--;
-	expression[len + 1] = 0;      
-	if (len >= 0) {
-	    fprintf(xpathOutput,
-	            "\n========================\nExpression: %s\n",
-		    expression) ;
-	    testXPath(expression, xptr, expr);
-	}
-    }
-
-    fclose(input);
-    fclose(xpathOutput);
-    if (result != NULL) {
-	ret = compareFiles(temp, result);
-	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
-	}
-    }
-
-    unlink(temp);
-    free(temp);
-    return(ret);
-}
-
-/**
- * xpathExprTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing XPath standalone expressions and evaluate them
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-xpathExprTest(const char *filename, const char *result,
-              const char *err ATTRIBUTE_UNUSED,
-              int options ATTRIBUTE_UNUSED) {
-    return(xpathCommonTest(filename, result, 0, 1));
-}
-
-/**
- * xpathDocTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing XPath expressions and evaluate them against
- * a set of corresponding documents.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-xpathDocTest(const char *filename,
-             const char *resul ATTRIBUTE_UNUSED,
-             const char *err ATTRIBUTE_UNUSED,
-             int options) {
-
-    char pattern[500];
-    char result[500];
-    glob_t globbuf;
-    size_t i;
-    int ret = 0, res;
-
-    xpathDocument = xmlReadFile(filename, NULL,
-                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
-    if (xpathDocument == NULL) {
-        fprintf(stderr, "Failed to load %s\n", filename);
-	return(-1);
-    }
-
-    snprintf(pattern, 499, "./test/XPath/tests/%s*", baseFilename(filename));
-    pattern[499] = 0;
-    globbuf.gl_offs = 0;
-    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
-    for (i = 0;i < globbuf.gl_pathc;i++) {
-        snprintf(result, 499, "result/XPath/tests/%s",
-	         baseFilename(globbuf.gl_pathv[i]));
-	res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 0, 0);
-	if (res != 0)
-	    ret = res;
-    }
-    globfree(&globbuf);
-
-    xmlFreeDoc(xpathDocument);
-    return(ret);
-}
-
-#ifdef LIBXML_XPTR_ENABLED
-/**
- * xptrDocTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing XPath expressions and evaluate them against
- * a set of corresponding documents.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-xptrDocTest(const char *filename,
-            const char *resul ATTRIBUTE_UNUSED,
-            const char *err ATTRIBUTE_UNUSED,
-            int options) {
-
-    char pattern[500];
-    char result[500];
-    glob_t globbuf;
-    size_t i;
-    int ret = 0, res;
-
-    xpathDocument = xmlReadFile(filename, NULL,
-                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
-    if (xpathDocument == NULL) {
-        fprintf(stderr, "Failed to load %s\n", filename);
-	return(-1);
-    }
-
-    snprintf(pattern, 499, "./test/XPath/xptr/%s*", baseFilename(filename));
-    pattern[499] = 0;
-    globbuf.gl_offs = 0;
-    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
-    for (i = 0;i < globbuf.gl_pathc;i++) {
-        snprintf(result, 499, "result/XPath/xptr/%s",
-	         baseFilename(globbuf.gl_pathv[i]));
-	res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 1, 0);
-	if (res != 0)
-	    ret = res;
-    }
-    globfree(&globbuf);
-
-    xmlFreeDoc(xpathDocument);
-    return(ret);
-}
-#endif /* LIBXML_XPTR_ENABLED */
-
-/**
- * xmlidDocTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing xml:id and check for errors and verify
- * that XPath queries will work on them as expected.
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-xmlidDocTest(const char *filename,
-             const char *result,
-             const char *err,
-             int options) {
-
-    int res = 0;
-    int ret = 0;
-    char *temp;
-
-    xpathDocument = xmlReadFile(filename, NULL,
-                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
-    if (xpathDocument == NULL) {
-        fprintf(stderr, "Failed to load %s\n", filename);
-	return(-1);
-    }
-
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    xpathOutput = fopen(temp, "wb");
-    if (xpathOutput == NULL) {
-	fprintf(stderr, "failed to open output file %s\n", temp);
-        xmlFreeDoc(xpathDocument);
-        free(temp);
-	return(-1);
-    }
-
-    testXPath("id('bar')", 0, 0);
-
-    fclose(xpathOutput);
-    if (result != NULL) {
-	ret = compareFiles(temp, result);
-	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
-	    res = 1;
-	}
-    }
-
-    unlink(temp);
-    free(temp);
-    xmlFreeDoc(xpathDocument);
-
-    if (err != NULL) {
-	ret = compareFileMem(err, testErrors, testErrorsSize);
-	if (ret != 0) {
-	    fprintf(stderr, "Error for %s failed\n", filename);
-	    res = 1;
-	}
-    }
-    return(res);
-}
-
-#endif /* LIBXML_DEBUG_ENABLED */
-#endif /* XPATH */
-/************************************************************************
- *									*
- *			URI based tests					*
- *									*
- ************************************************************************/
-
-static void
-handleURI(const char *str, const char *base, FILE *o) {
-    int ret;
-    xmlURIPtr uri;
-    xmlChar *res = NULL, *parsed = NULL;
-
-    uri = xmlCreateURI();
-
-    if (base == NULL) {
-	ret = xmlParseURIReference(uri, str);
-	if (ret != 0)
-	    fprintf(o, "%s : error %d\n", str, ret);
-	else {
-	    xmlNormalizeURIPath(uri->path);
-	    xmlPrintURI(o, uri);
-	    fprintf(o, "\n");
-	}
-    } else {
-	res = xmlBuildURI((xmlChar *)str, (xmlChar *) base);
-	if (res != NULL) {
-	    fprintf(o, "%s\n", (char *) res);
-	}
-	else
-	    fprintf(o, "::ERROR::\n");
-    }
-    if (res != NULL)
-	xmlFree(res);
-    if (parsed != NULL)
-	xmlFree(parsed);
-    xmlFreeURI(uri);
-}
-
-/**
- * uriCommonTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing URI and check for errors
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-uriCommonTest(const char *filename,
-             const char *result,
-             const char *err,
-             const char *base) {
-    char *temp;
-    FILE *o, *f;
-    char str[1024];
-    int res = 0, i, ret;
-
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    o = fopen(temp, "wb");
-    if (o == NULL) {
-	fprintf(stderr, "failed to open output file %s\n", temp);
-        free(temp);
-	return(-1);
-    }
-    f = fopen(filename, "rb");
-    if (f == NULL) {
-	fprintf(stderr, "failed to open input file %s\n", filename);
-	fclose(o);
-	unlink(temp);
-        free(temp);
-	return(-1);
-    }
-
-    while (1) {
-	/*
-	 * read one line in string buffer.
-	 */
-	if (fgets (&str[0], sizeof (str) - 1, f) == NULL)
-	   break;
-
-	/*
-	 * remove the ending spaces
-	 */
-	i = strlen(str);
-	while ((i > 0) &&
-	       ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||
-		(str[i - 1] == ' ') || (str[i - 1] == '\t'))) {
-	    i--;
-	    str[i] = 0;
-	}
-	nb_tests++;
-	handleURI(str, base, o);
-    }
-
-    fclose(f);
-    fclose(o);
-
-    if (result != NULL) {
-	ret = compareFiles(temp, result);
-	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
-	    res = 1;
-	}
-    }
-    if (err != NULL) {
-	ret = compareFileMem(err, testErrors, testErrorsSize);
-	if (ret != 0) {
-	    fprintf(stderr, "Error for %s failed\n", filename);
-	    res = 1;
-	}
-    }
-
-    unlink(temp);
-    free(temp);
-    return(res);
-}
-
-/**
- * uriParseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing URI and check for errors
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-uriParseTest(const char *filename,
-             const char *result,
-             const char *err,
-             int options ATTRIBUTE_UNUSED) {
-    return(uriCommonTest(filename, result, err, NULL));
-}
-
-/**
- * uriBaseTest:
- * @filename: the file to parse
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing URI, compose them against a fixed base and
- * check for errors
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-uriBaseTest(const char *filename,
-             const char *result,
-             const char *err,
-             int options ATTRIBUTE_UNUSED) {
-    return(uriCommonTest(filename, result, err,
-                         "http://foo.com/path/to/index.html?orig#help"));
-}
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-/************************************************************************
- *									*
- *			Schemas tests					*
- *									*
- ************************************************************************/
-static int
-schemasOneTest(const char *sch,
-               const char *filename,
-               const char *result,
-	       const char *err,
-	       int options,
-	       xmlSchemaPtr schemas) {
-    xmlDocPtr doc;
-    xmlSchemaValidCtxtPtr ctxt;
-    int ret = 0;
-    char *temp;
-    FILE *schemasOutput;
-
-    doc = xmlReadFile(filename, NULL, options);
-    if (doc == NULL) {
-        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
-	return(-1);
-    }
-
-    temp = resultFilename(result, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    schemasOutput = fopen(temp, "wb");
-    if (schemasOutput == NULL) {
-	fprintf(stderr, "failed to open output file %s\n", temp);
-	xmlFreeDoc(doc);
-        free(temp);
-	return(-1);
-    }
-
-    ctxt = xmlSchemaNewValidCtxt(schemas);
-    xmlSchemaSetValidErrors(ctxt,
-         (xmlSchemaValidityErrorFunc) testErrorHandler,
-         (xmlSchemaValidityWarningFunc) testErrorHandler,
-	 ctxt);
-    ret = xmlSchemaValidateDoc(ctxt, doc);
-    if (ret == 0) {
-	fprintf(schemasOutput, "%s validates\n", filename);
-    } else if (ret > 0) {
-	fprintf(schemasOutput, "%s fails to validate\n", filename);
-    } else {
-	fprintf(schemasOutput, "%s validation generated an internal error\n",
-	       filename);
-    }
-    fclose(schemasOutput);
-    if (result) {
-	if (compareFiles(temp, result)) {
-	    fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
-	    ret = 1;
-	}
-    }
-    unlink(temp);
-    free(temp);
-
-    if (err != NULL) {
-	if (compareFileMem(err, testErrors, testErrorsSize)) {
-	    fprintf(stderr, "Error for %s on %s failed\n", filename, sch);
-	    ret = 1;
-	}
-    }
-
-
-    xmlSchemaFreeValidCtxt(ctxt);
-    xmlFreeDoc(doc);
-    return(ret);
-}
-/**
- * schemasTest:
- * @filename: the schemas file
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a file containing URI, compose them against a fixed base and
- * check for errors
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-schemasTest(const char *filename,
-            const char *resul ATTRIBUTE_UNUSED,
-            const char *errr ATTRIBUTE_UNUSED,
-            int options) {
-    const char *base = baseFilename(filename);
-    const char *base2;
-    const char *instance;
-    xmlSchemaParserCtxtPtr ctxt;
-    xmlSchemaPtr schemas;
-    int res = 0, len, ret;
-    char pattern[500];
-    char prefix[500];
-    char result[500];
-    char err[500];
-    glob_t globbuf;
-    size_t i;
-    char count = 0;
-
-    /* first compile the schemas if possible */
-    ctxt = xmlSchemaNewParserCtxt(filename);
-    xmlSchemaSetParserErrors(ctxt,
-         (xmlSchemaValidityErrorFunc) testErrorHandler,
-         (xmlSchemaValidityWarningFunc) testErrorHandler,
-	 ctxt);
-    schemas = xmlSchemaParse(ctxt);
-    xmlSchemaFreeParserCtxt(ctxt);
-
-    /*
-     * most of the mess is about the output filenames generated by the Makefile
-     */
-    len = strlen(base);
-    if ((len > 499) || (len < 5)) {
-        xmlSchemaFree(schemas);
-	return(-1);
-    }
-    len -= 4; /* remove trailing .xsd */
-    if (base[len - 2] == '_') {
-        len -= 2; /* remove subtest number */
-    }
-    if (base[len - 2] == '_') {
-        len -= 2; /* remove subtest number */
-    }
-    memcpy(prefix, base, len);
-    prefix[len] = 0;
-
-    snprintf(pattern, 499, "./test/schemas/%s_?.xml", prefix);
-    pattern[499] = 0;
-
-    if (base[len] == '_') {
-        len += 2;
-	memcpy(prefix, base, len);
-	prefix[len] = 0;
-    }
-
-    globbuf.gl_offs = 0;
-    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
-    for (i = 0;i < globbuf.gl_pathc;i++) {
-        testErrorsSize = 0;
-	testErrors[0] = 0;
-        instance = globbuf.gl_pathv[i];
-	base2 = baseFilename(instance);
-	len = strlen(base2);
-	if ((len > 6) && (base2[len - 6] == '_')) {
-	    count = base2[len - 5];
-	    snprintf(result, 499, "result/schemas/%s_%c",
-		     prefix, count);
-	    result[499] = 0;
-	    snprintf(err, 499, "result/schemas/%s_%c.err",
-		     prefix, count);
-	    err[499] = 0;
-	} else {
-	    fprintf(stderr, "don't know how to process %s\n", instance);
-	    continue;
-	}
-	if (schemas == NULL) {
-	} else {
-	    nb_tests++;
-	    ret = schemasOneTest(filename, instance, result, err,
-	                         options, schemas);
-	    if (res != 0)
-		ret = res;
-	}
-    }
-    globfree(&globbuf);
-    xmlSchemaFree(schemas);
-
-    return(res);
-}
-
-/************************************************************************
- *									*
- *			Schemas tests					*
- *									*
- ************************************************************************/
-static int
-rngOneTest(const char *sch,
-               const char *filename,
-               const char *result,
-	       const char *err,
-	       int options,
-	       xmlRelaxNGPtr schemas) {
-    xmlDocPtr doc;
-    xmlRelaxNGValidCtxtPtr ctxt;
-    int ret = 0;
-    char *temp;
-    FILE *schemasOutput;
-
-    doc = xmlReadFile(filename, NULL, options);
-    if (doc == NULL) {
-        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
-	return(-1);
-    }
-
-    temp = resultFilename(result, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    schemasOutput = fopen(temp, "wb");
-    if (schemasOutput == NULL) {
-	fprintf(stderr, "failed to open output file %s\n", temp);
-	xmlFreeDoc(doc);
-        free(temp);
-	return(-1);
-    }
-
-    ctxt = xmlRelaxNGNewValidCtxt(schemas);
-    xmlRelaxNGSetValidErrors(ctxt,
-         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
-         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
-	 ctxt);
-    ret = xmlRelaxNGValidateDoc(ctxt, doc);
-    if (ret == 0) {
-	testErrorHandler(NULL, "%s validates\n", filename);
-    } else if (ret > 0) {
-	testErrorHandler(NULL, "%s fails to validate\n", filename);
-    } else {
-	testErrorHandler(NULL, "%s validation generated an internal error\n",
-	       filename);
-    }
-    fclose(schemasOutput);
-    if (result) {
-	if (compareFiles(temp, result)) {
-	    fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
-	    ret = 1;
-	}
-    }
-    unlink(temp);
-    free(temp);
-
-    if (err != NULL) {
-	if (compareFileMem(err, testErrors, testErrorsSize)) {
-	    fprintf(stderr, "Error for %s on %s failed\n", filename, sch);
-	    ret = 1;
-	    printf("%s", testErrors);
-	}
-    }
-
-
-    xmlRelaxNGFreeValidCtxt(ctxt);
-    xmlFreeDoc(doc);
-    return(ret);
-}
-/**
- * rngTest:
- * @filename: the schemas file
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse an RNG schemas and then apply it to the related .xml
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-rngTest(const char *filename,
-            const char *resul ATTRIBUTE_UNUSED,
-            const char *errr ATTRIBUTE_UNUSED,
-            int options) {
-    const char *base = baseFilename(filename);
-    const char *base2;
-    const char *instance;
-    xmlRelaxNGParserCtxtPtr ctxt;
-    xmlRelaxNGPtr schemas;
-    int res = 0, len, ret;
-    char pattern[500];
-    char prefix[500];
-    char result[500];
-    char err[500];
-    glob_t globbuf;
-    size_t i;
-    char count = 0;
-
-    /* first compile the schemas if possible */
-    ctxt = xmlRelaxNGNewParserCtxt(filename);
-    xmlRelaxNGSetParserErrors(ctxt,
-         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
-         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
-	 ctxt);
-    schemas = xmlRelaxNGParse(ctxt);
-    xmlRelaxNGFreeParserCtxt(ctxt);
-
-    /*
-     * most of the mess is about the output filenames generated by the Makefile
-     */
-    len = strlen(base);
-    if ((len > 499) || (len < 5)) {
-        xmlRelaxNGFree(schemas);
-	return(-1);
-    }
-    len -= 4; /* remove trailing .rng */
-    memcpy(prefix, base, len);
-    prefix[len] = 0;
-
-    snprintf(pattern, 499, "./test/relaxng/%s_?.xml", prefix);
-    pattern[499] = 0;
-
-    globbuf.gl_offs = 0;
-    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
-    for (i = 0;i < globbuf.gl_pathc;i++) {
-        testErrorsSize = 0;
-	testErrors[0] = 0;
-        instance = globbuf.gl_pathv[i];
-	base2 = baseFilename(instance);
-	len = strlen(base2);
-	if ((len > 6) && (base2[len - 6] == '_')) {
-	    count = base2[len - 5];
-	    snprintf(result, 499, "result/relaxng/%s_%c",
-		     prefix, count);
-	    result[499] = 0;
-	    snprintf(err, 499, "result/relaxng/%s_%c.err",
-		     prefix, count);
-	    err[499] = 0;
-	} else {
-	    fprintf(stderr, "don't know how to process %s\n", instance);
-	    continue;
-	}
-	if (schemas == NULL) {
-	} else {
-	    nb_tests++;
-	    ret = rngOneTest(filename, instance, result, err,
-	                         options, schemas);
-	    if (res != 0)
-		ret = res;
-	}
-    }
-    globfree(&globbuf);
-    xmlRelaxNGFree(schemas);
-
-    return(res);
-}
-
-#ifdef LIBXML_READER_ENABLED
-/**
- * rngStreamTest:
- * @filename: the schemas file
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a set of files with streaming, applying an RNG schemas 
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-rngStreamTest(const char *filename,
-            const char *resul ATTRIBUTE_UNUSED,
-            const char *errr ATTRIBUTE_UNUSED,
-            int options) {
-    const char *base = baseFilename(filename);
-    const char *base2;
-    const char *instance;
-    int res = 0, len, ret;
-    char pattern[500];
-    char prefix[500];
-    char result[500];
-    char err[500];
-    glob_t globbuf;
-    size_t i;
-    char count = 0;
-    xmlTextReaderPtr reader;
-    int disable_err = 0;
-
-    /*
-     * most of the mess is about the output filenames generated by the Makefile
-     */
-    len = strlen(base);
-    if ((len > 499) || (len < 5)) {
-	fprintf(stderr, "len(base) == %d !\n", len);
-	return(-1);
-    }
-    len -= 4; /* remove trailing .rng */
-    memcpy(prefix, base, len);
-    prefix[len] = 0;
-
-    /*
-     * strictly unifying the error messages is nearly impossible this
-     * hack is also done in the Makefile
-     */
-    if ((!strcmp(prefix, "tutor10_1")) || (!strcmp(prefix, "tutor10_2")) ||
-        (!strcmp(prefix, "tutor3_2"))) 
-	disable_err = 1;
-
-    snprintf(pattern, 499, "./test/relaxng/%s_?.xml", prefix);
-    pattern[499] = 0;
-
-    globbuf.gl_offs = 0;
-    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
-    for (i = 0;i < globbuf.gl_pathc;i++) {
-        testErrorsSize = 0;
-	testErrors[0] = 0;
-        instance = globbuf.gl_pathv[i];
-	base2 = baseFilename(instance);
-	len = strlen(base2);
-	if ((len > 6) && (base2[len - 6] == '_')) {
-	    count = base2[len - 5];
-	    snprintf(result, 499, "result/relaxng/%s_%c",
-		     prefix, count);
-	    result[499] = 0;
-	    snprintf(err, 499, "result/relaxng/%s_%c.err",
-		     prefix, count);
-	    err[499] = 0;
-	} else {
-	    fprintf(stderr, "don't know how to process %s\n", instance);
-	    continue;
-	}
-	reader = xmlReaderForFile(instance, NULL, options);
-	if (reader == NULL) {
-	    fprintf(stderr, "Failed to build reder for %s\n", instance);
-	}
-	if (disable_err == 1)
-	    ret = streamProcessTest(instance, result, NULL, reader, filename);
-	else
-	    ret = streamProcessTest(instance, result, err, reader, filename);
-	xmlFreeTextReader(reader);
-	if (ret != 0) {
-	    fprintf(stderr, "instance %s failed\n", instance);
-	    res = ret;
-	}
-    }
-    globfree(&globbuf);
-
-    return(res);
-}
-#endif /* READER */
-
-#endif
-
-#ifdef LIBXML_PATTERN_ENABLED
-#ifdef LIBXML_READER_ENABLED
-/************************************************************************
- *									*
- *			Patterns tests					*
- *									*
- ************************************************************************/
-static void patternNode(FILE *out, xmlTextReaderPtr reader,
-                        const char *pattern, xmlPatternPtr patternc,
-			xmlStreamCtxtPtr patstream) {
-    xmlChar *path = NULL;
-    int match = -1;
-    int type, empty;
-
-    type = xmlTextReaderNodeType(reader);
-    empty = xmlTextReaderIsEmptyElement(reader);
-	
-    if (type == XML_READER_TYPE_ELEMENT) {
-	/* do the check only on element start */
-	match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
-
-	if (match) {
-	    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
-	    fprintf(out, "Node %s matches pattern %s\n", path, pattern);
-	}
-    }
-    if (patstream != NULL) {
-	int ret;
-
-	if (type == XML_READER_TYPE_ELEMENT) {
-	    ret = xmlStreamPush(patstream,
-				xmlTextReaderConstLocalName(reader),
-				xmlTextReaderConstNamespaceUri(reader));
-	    if (ret < 0) {
-		fprintf(out, "xmlStreamPush() failure\n");
-		xmlFreeStreamCtxt(patstream);
-		patstream = NULL;
-	    } else if (ret != match) {
-		if (path == NULL) {
-		    path = xmlGetNodePath(
-				   xmlTextReaderCurrentNode(reader));
-		}
-		fprintf(out,
-			"xmlPatternMatch and xmlStreamPush disagree\n");
-		fprintf(out,
-			"  pattern %s node %s\n",
-			pattern, path);
-	    }
-	    
-
-	} 
-	if ((type == XML_READER_TYPE_END_ELEMENT) ||
-	    ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
-	    ret = xmlStreamPop(patstream);
-	    if (ret < 0) {
-		fprintf(out, "xmlStreamPop() failure\n");
-		xmlFreeStreamCtxt(patstream);
-		patstream = NULL;
-	    }
-	}
-    }
-    if (path != NULL)
-	xmlFree(path);
-}
-
-/**
- * patternTest:
- * @filename: the schemas file
- * @result: the file with expected result
- * @err: the file with error messages
- *
- * Parse a set of files with streaming, applying an RNG schemas 
- *
- * Returns 0 in case of success, an error code otherwise
- */
-static int
-patternTest(const char *filename,
-            const char *resul ATTRIBUTE_UNUSED,
-            const char *err ATTRIBUTE_UNUSED,
-            int options) {
-    xmlPatternPtr patternc = NULL;
-    xmlStreamCtxtPtr patstream = NULL;
-    FILE *o, *f;
-    char str[1024];
-    char xml[500];
-    char result[500];
-    int len, i;
-    int ret = 0, res;
-    char *temp;
-    xmlTextReaderPtr reader;
-    xmlDocPtr doc;
-
-    len = strlen(filename);
-    len -= 4;
-    memcpy(xml, filename, len);
-    xml[len] = 0;
-    snprintf(result, 499, "result/pattern/%s", baseFilename(xml));
-    result[499] = 0;
-    memcpy(xml + len, ".xml", 5);
-
-    if (!checkTestFile(xml)) {
-	fprintf(stderr, "Missing xml file %s\n", xml);
-	return(-1);
-    }
-    if (!checkTestFile(result)) {
-	fprintf(stderr, "Missing result file %s\n", result);
-	return(-1);
-    }
-    f = fopen(filename, "rb");
-    if (f == NULL) {
-        fprintf(stderr, "Failed to open %s\n", filename);
-	return(-1);
-    }
-    temp = resultFilename(filename, "", ".res");
-    if (temp == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        fatalError();
-    }
-    o = fopen(temp, "wb");
-    if (o == NULL) {
-	fprintf(stderr, "failed to open output file %s\n", temp);
-	fclose(f);
-        free(temp);
-	return(-1);
-    }
-    while (1) {
-	/*
-	 * read one line in string buffer.
-	 */
-	if (fgets (&str[0], sizeof (str) - 1, f) == NULL)
-	   break;
-
-	/*
-	 * remove the ending spaces
-	 */
-	i = strlen(str);
-	while ((i > 0) &&
-	       ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||
-		(str[i - 1] == ' ') || (str[i - 1] == '\t'))) {
-	    i--;
-	    str[i] = 0;
-	}
-	doc = xmlReadFile(xml, NULL, options);
-	if (doc == NULL) {
-	    fprintf(stderr, "Failed to parse %s\n", xml);
-	    ret = 1;
-	} else {
-	    xmlNodePtr root;
-	    const xmlChar *namespaces[22];
-	    int j;
-	    xmlNsPtr ns;
-
-	    root = xmlDocGetRootElement(doc);
-	    for (ns = root->nsDef, j = 0;ns != NULL && j < 20;ns=ns->next) {
-		namespaces[j++] = ns->href;
-		namespaces[j++] = ns->prefix;
-	    }
-	    namespaces[j++] = NULL;
-	    namespaces[j++] = NULL;
-
-	    patternc = xmlPatterncompile((const xmlChar *) str, doc->dict,
-					 0, &namespaces[0]);
-	    if (patternc == NULL) {
-		testErrorHandler(NULL,
-			"Pattern %s failed to compile\n", str);
-		xmlFreeDoc(doc);
-		ret = 1;
-		continue;
-	    }
-	    patstream = xmlPatternGetStreamCtxt(patternc);
-	    if (patstream != NULL) {
-		ret = xmlStreamPush(patstream, NULL, NULL);
-		if (ret < 0) {
-		    fprintf(stderr, "xmlStreamPush() failure\n");
-		    xmlFreeStreamCtxt(patstream);
-		    patstream = NULL;
-		}
-	    }
-	    nb_tests++;
-
-	    reader = xmlReaderWalker(doc);
-	    res = xmlTextReaderRead(reader);
-	    while (res == 1) {
-		patternNode(o, reader, str, patternc, patstream);
-		res = xmlTextReaderRead(reader);
-	    }
-	    if (res != 0) {
-		fprintf(o, "%s : failed to parse\n", filename);
-	    }
-	    xmlFreeTextReader(reader);
-	    xmlFreeDoc(doc);
-	    xmlFreeStreamCtxt(patstream);
-	    patstream = NULL;
-	    xmlFreePattern(patternc);
-
-	}
-    }
-
-    fclose(f);
-    fclose(o);
-
-    ret = compareFiles(temp, result);
-    if (ret) {
-	fprintf(stderr, "Result for %s failed\n", filename);
-	ret = 1;
-    }
-    unlink(temp);
-    free(temp);
-    return(ret);
-}
-#endif /* READER */
-#endif /* PATTERN */
-#ifdef LIBXML_C14N_ENABLED
-/************************************************************************
- *									*
- *			Canonicalization tests				*
- *									*
- ************************************************************************/
-static xmlXPathObjectPtr
-load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {
-    xmlXPathObjectPtr xpath; 
-    xmlDocPtr doc;
-    xmlChar *expr;
-    xmlXPathContextPtr ctx; 
-    xmlNodePtr node;
-    xmlNsPtr ns;
-    
-    /*
-     * load XPath expr as a file
-     */
-    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
-    xmlSubstituteEntitiesDefault(1);
-
-    doc = xmlParseFile(filename);
-    if (doc == NULL) {
-	fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
-	return(NULL);
-    }
-    
-    /*
-     * Check the document is of the right kind
-     */    
-    if(xmlDocGetRootElement(doc) == NULL) {
-        fprintf(stderr,"Error: empty document for file \"%s\"\n", filename);
-	xmlFreeDoc(doc);
-	return(NULL);
-    }
-
-    node = doc->children;
-    while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) {
-	node = node->next;
-    }
-    
-    if(node == NULL) {   
-        fprintf(stderr,"Error: XPath element expected in the file  \"%s\"\n", filename);
-	xmlFreeDoc(doc);
-	return(NULL);
-    }
-
-    expr = xmlNodeGetContent(node);
-    if(expr == NULL) {
-        fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename);
-	xmlFreeDoc(doc);
-	return(NULL);
-    }
-
-    ctx = xmlXPathNewContext(parent_doc);
-    if(ctx == NULL) {
-        fprintf(stderr,"Error: unable to create new context\n");
-        xmlFree(expr); 
-        xmlFreeDoc(doc); 
-        return(NULL);
-    }
-
-    /*
-     * Register namespaces
-     */
-    ns = node->nsDef;
-    while(ns != NULL) {
-	if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) {
-	    fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href);
-    	    xmlFree(expr); 
-	    xmlXPathFreeContext(ctx); 
-	    xmlFreeDoc(doc); 
-	    return(NULL);
-	}
-	ns = ns->next;
-    }
-
-    /*  
-     * Evaluate xpath
-     */
-    xpath = xmlXPathEvalExpression(expr, ctx);
-    if(xpath == NULL) {
-        fprintf(stderr,"Error: unable to evaluate xpath expression\n");
-    	xmlFree(expr); 
-        xmlXPathFreeContext(ctx); 
-        xmlFreeDoc(doc); 
-        return(NULL);
-    }
-
-    /* print_xpath_nodes(xpath->nodesetval); */
-
-    xmlFree(expr); 
-    xmlXPathFreeContext(ctx); 
-    xmlFreeDoc(doc); 
-    return(xpath);
-}
-
-/*
- * Macro used to grow the current buffer.
- */
-#define xxx_growBufferReentrant() {						\
-    buffer_size *= 2;							\
-    buffer = (xmlChar **)						\
-    		xmlRealloc(buffer, buffer_size * sizeof(xmlChar*));	\
-    if (buffer == NULL) {						\
-	perror("realloc failed");					\
-	return(NULL);							\
-    }									\
-}
-
-static xmlChar **
-parse_list(xmlChar *str) {
-    xmlChar **buffer;
-    xmlChar **out = NULL;
-    int buffer_size = 0;
-    int len;
-
-    if(str == NULL) {
-	return(NULL);
-    }
-
-    len = xmlStrlen(str);
-    if((str[0] == '\'') && (str[len - 1] == '\'')) {
-	str[len - 1] = '\0';
-	str++;
-	len -= 2;
-    }
-    /*
-     * allocate an translation buffer.
-     */
-    buffer_size = 1000;
-    buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*));
-    if (buffer == NULL) {
-	perror("malloc failed");
-	return(NULL);
-    }
-    out = buffer;
-    
-    while(*str != '\0') {
-	if (out - buffer > buffer_size - 10) {
-	    int indx = out - buffer;
-
-	    xxx_growBufferReentrant();
-	    out = &buffer[indx];
-	}
-	(*out++) = str;
-	while(*str != ',' && *str != '\0') ++str;
-	if(*str == ',') *(str++) = '\0';
-    }
-    (*out) = NULL;
-    return buffer;
-}
-
-static int 
-c14nRunTest(const char* xml_filename, int with_comments, int exclusive,
-	    const char* xpath_filename, const char *ns_filename,
-	    const char* result_file) {
-    xmlDocPtr doc;
-    xmlXPathObjectPtr xpath = NULL; 
-    xmlChar *result = NULL;
-    int ret;
-    xmlChar **inclusive_namespaces = NULL;
-    const char *nslist = NULL;
-    int nssize;
-
-
-    /*
-     * build an XML tree from a the file; we need to add default
-     * attributes and resolve all character and entities references
-     */
-    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
-    xmlSubstituteEntitiesDefault(1);
-
-    doc = xmlParseFile(xml_filename);
-    if (doc == NULL) {
-	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
-	return(-1);
-    }
-    
-    /*
-     * Check the document is of the right kind
-     */    
-    if(xmlDocGetRootElement(doc) == NULL) {
-        fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename);
-	xmlFreeDoc(doc);
-	return(-1);
-    }
-
-    /* 
-     * load xpath file if specified 
-     */
-    if(xpath_filename) {
-	xpath = load_xpath_expr(doc, xpath_filename);
-	if(xpath == NULL) {
-	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");
-	    xmlFreeDoc(doc); 
-	    return(-1);
-	}
-    }
-
-    if (ns_filename != NULL) {
-        if (loadMem(ns_filename, &nslist, &nssize)) {
-	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");
-	    if(xpath != NULL) xmlXPathFreeObject(xpath);
-	    xmlFreeDoc(doc); 
-	    return(-1);
-	}
-        inclusive_namespaces = parse_list((xmlChar *) nslist);
-    }
-
-    /*
-     * Canonical form
-     */      
-    /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
-    ret = xmlC14NDocDumpMemory(doc, 
-	    (xpath) ? xpath->nodesetval : NULL, 
-	    exclusive, inclusive_namespaces,
-	    with_comments, &result);
-    if (ret >= 0) {
-	if(result != NULL) {
-	    if (compareFileMem(result_file, (const char *) result, ret)) {
-		fprintf(stderr, "Result mismatch for %s\n", xml_filename);
-	        ret = -1;
-	    }
-	}
-    } else {
-	fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret);
-	ret = -1;
-    }
-        
-    /*
-     * Cleanup
-     */ 
-    if (result != NULL) xmlFree(result);
-    if(xpath != NULL) xmlXPathFreeObject(xpath);
-    if (inclusive_namespaces != NULL) xmlFree(inclusive_namespaces);
-    if (nslist != NULL) free((char *) nslist);
-    xmlFreeDoc(doc);    
-
-    return(ret);
-}
-
-static int
-c14nCommonTest(const char *filename, int with_comments, int exclusive,
-               const char *subdir) {
-    char buf[500];
-    char prefix[500];
-    const char *base;
-    int len;
-    char *result = NULL;
-    char *xpath = NULL;
-    char *ns = NULL;
-    int ret = 0;
-
-    base = baseFilename(filename);
-    len = strlen(base);
-    len -= 4;
-    memcpy(prefix, base, len);
-    prefix[len] = 0;
-
-    snprintf(buf, 499, "result/c14n/%s/%s", subdir,prefix);
-    if (!checkTestFile(buf)) {
-        fprintf(stderr, "Missing result file %s", buf);
-	return(-1);
-    }
-    result = strdup(buf);
-    snprintf(buf, 499, "test/c14n/%s/%s.xpath", subdir,prefix);
-    if (checkTestFile(buf)) {
-	xpath = strdup(buf);
-    }
-    snprintf(buf, 499, "test/c14n/%s/%s.ns", subdir,prefix);
-    if (checkTestFile(buf)) {
-	ns = strdup(buf);
-    }
-
-    nb_tests++;
-    if (c14nRunTest(filename, with_comments, exclusive,
-                    xpath, ns, result) < 0)
-        ret = 1;
-
-    if (result != NULL) free(result);
-    if (xpath != NULL) free(xpath);
-    if (ns != NULL) free(ns);
-    return(ret);
-}
-
-static int
-c14nWithCommentTest(const char *filename,
-                    const char *resul ATTRIBUTE_UNUSED,
-		    const char *err ATTRIBUTE_UNUSED,
-		    int options ATTRIBUTE_UNUSED) {
-    return(c14nCommonTest(filename, 1, 0, "with-comments"));
-}
-static int
-c14nWithoutCommentTest(const char *filename,
-                    const char *resul ATTRIBUTE_UNUSED,
-		    const char *err ATTRIBUTE_UNUSED,
-		    int options ATTRIBUTE_UNUSED) {
-    return(c14nCommonTest(filename, 0, 0, "without-comments"));
-}
-static int
-c14nExcWithoutCommentTest(const char *filename,
-                    const char *resul ATTRIBUTE_UNUSED,
-		    const char *err ATTRIBUTE_UNUSED,
-		    int options ATTRIBUTE_UNUSED) {
-    return(c14nCommonTest(filename, 0, 1, "exc-without-comments"));
-}
-#endif
-#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
-/************************************************************************
- *									*
- *			Catalog and threads test			*
- *									*
- ************************************************************************/
-
-/*
- * mostly a cut and paste from testThreads.c
- */
-#define	MAX_ARGC	20
-
-static const char *catalog = "test/threads/complex.xml";
-static const char *testfiles[] = {
-    "test/threads/abc.xml",
-    "test/threads/acb.xml",
-    "test/threads/bac.xml",
-    "test/threads/bca.xml",
-    "test/threads/cab.xml",
-    "test/threads/cba.xml",
-    "test/threads/invalid.xml",
-};
-
-const char *Okay = "OK";
-const char *Failed = "Failed";
-
-#ifndef xmlDoValidityCheckingDefaultValue
-#error xmlDoValidityCheckingDefaultValue is not a macro
-#endif
-#ifndef xmlGenericErrorContext
-#error xmlGenericErrorContext is not a macro
-#endif
-
-static void *
-thread_specific_data(void *private_data)
-{
-    xmlDocPtr myDoc;
-    const char *filename = (const char *) private_data;
-    int okay = 1;
-
-    if (!strcmp(filename, "test/threads/invalid.xml")) {
-        xmlDoValidityCheckingDefaultValue = 0;
-        xmlGenericErrorContext = stdout;
-    } else {
-        xmlDoValidityCheckingDefaultValue = 1;
-        xmlGenericErrorContext = stderr;
-    }
-    myDoc = xmlParseFile(filename);
-    if (myDoc) {
-        xmlFreeDoc(myDoc);
-    } else {
-        printf("parse failed\n");
-        okay = 0;
-    }
-    if (!strcmp(filename, "test/threads/invalid.xml")) {
-        if (xmlDoValidityCheckingDefaultValue != 0) {
-            printf("ValidityCheckingDefaultValue override failed\n");
-            okay = 0;
-        }
-        if (xmlGenericErrorContext != stdout) {
-            printf("xmlGenericErrorContext override failed\n");
-            okay = 0;
-        }
-    } else {
-        if (xmlDoValidityCheckingDefaultValue != 1) {
-            printf("ValidityCheckingDefaultValue override failed\n");
-            okay = 0;
-        }
-        if (xmlGenericErrorContext != stderr) {
-            printf("xmlGenericErrorContext override failed\n");
-            okay = 0;
-        }
-    }
-    if (okay == 0)
-        return ((void *) Failed);
-    return ((void *) Okay);
-}
-
-#if defined(linux) || defined(solaris)
-
-#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
-#include <windows.h>
-#include <string.h>
-
-#define TEST_REPEAT_COUNT 500
-
-static HANDLE tid[MAX_ARGC];
-
-static DWORD WINAPI
-win32_thread_specific_data(void *private_data)
-{
-    return((DWORD) thread_specific_data(private_data));
-}
-
-static int
-testThread(void)
-{
-    unsigned int i, repeat;
-    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
-    DWORD results[MAX_ARGC];
-    BOOL ret;
-    int res = 0;
-
-    xmlInitParser();
-    for (repeat = 0; repeat < TEST_REPEAT_COUNT; repeat++) {
-        xmlLoadCatalog(catalog);
-        nb_tests++;
-
-        for (i = 0; i < num_threads; i++) {
-            results[i] = 0;
-            tid[i] = (HANDLE) - 1;
-        }
-
-        for (i = 0; i < num_threads; i++) {
-            DWORD useless;
-
-            tid[i] = CreateThread(NULL, 0,
-                                  win32_thread_specific_data, 
-				  (void *) testfiles[i], 0,
-                                  &useless);
-            if (tid[i] == NULL) {
-                fprintf(stderr, "CreateThread failed\n");
-                return(1);
-            }
-        }
-
-        if (WaitForMultipleObjects(num_threads, tid, TRUE, INFINITE) ==
-            WAIT_FAILED) {
-            fprintf(stderr, "WaitForMultipleObjects failed\n");
-	    return(1);
-	}
-
-        for (i = 0; i < num_threads; i++) {
-            ret = GetExitCodeThread(tid[i], &results[i]);
-            if (ret == 0) {
-                fprintf(stderr, "GetExitCodeThread failed\n");
-                return(1);
-            }
-            CloseHandle(tid[i]);
-        }
-
-        xmlCatalogCleanup();
-        for (i = 0; i < num_threads; i++) {
-            if (results[i] != (DWORD) Okay) {
-                fprintf(stderr, "Thread %d handling %s failed\n",
-		        i, testfiles[i]);
-	        res = 1;
-	    }
-        }
-    }
-
-    return (res);
-}
-
-#elif defined __BEOS__
-#include <OS.h>
-
-static thread_id tid[MAX_ARGC];
-
-static int
-testThread(void)
-{
-    unsigned int i, repeat;
-    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
-    void *results[MAX_ARGC];
-    status_t ret;
-    int res = 0;
-
-    xmlInitParser();
-    for (repeat = 0; repeat < 500; repeat++) {
-        xmlLoadCatalog(catalog);
-        for (i = 0; i < num_threads; i++) {
-            results[i] = NULL;
-            tid[i] = (thread_id) - 1;
-        }
-        for (i = 0; i < num_threads; i++) {
-            tid[i] =
-                spawn_thread(thread_specific_data, "xmlTestThread",
-                             B_NORMAL_PRIORITY, (void *) testfiles[i]);
-            if (tid[i] < B_OK) {
-                fprintf(stderr, "beos_thread_create failed\n");
-                return (1);
-            }
-            printf("beos_thread_create %d -> %d\n", i, tid[i]);
-        }
-        for (i = 0; i < num_threads; i++) {
-            ret = wait_for_thread(tid[i], &results[i]);
-            printf("beos_thread_wait %d -> %d\n", i, ret);
-            if (ret != B_OK) {
-                fprintf(stderr, "beos_thread_wait failed\n");
-                return (1);
-            }
-        }
-
-        xmlCatalogCleanup();
-        ret = B_OK;
-        for (i = 0; i < num_threads; i++)
-            if (results[i] != (void *) Okay) {
-                printf("Thread %d handling %s failed\n", i, testfiles[i]);
-                ret = B_ERROR;
-            }
-    }
-    if (ret != B_OK)
-        return(1);
-    return (0);
-}
-#else
-static int
-testThread(void)
-{
-    fprintf(stderr,
-            "Specific platform thread support not detected\n");
-    return (-1);
-}
-#endif
-static int 
-threadsTest(const char *filename ATTRIBUTE_UNUSED,
-	    const char *resul ATTRIBUTE_UNUSED,
-	    const char *err ATTRIBUTE_UNUSED,
-	    int options ATTRIBUTE_UNUSED) {
-    return(testThread());
-}
-#endif
-/************************************************************************
- *									*
- *			Tests Descriptions				*
- *									*
- ************************************************************************/
-
-static
-testDesc testDescriptions[] = {
-    { "XML regression tests" ,
-      oldParseTest, "./test/*", "result/", "", NULL,
-      0 },
-    { "XML regression tests on memory" ,
-      memParseTest, "./test/*", "result/", "", NULL,
-      0 },
-    { "XML entity subst regression tests" ,
-      noentParseTest, "./test/*", "result/noent/", "", NULL,
-      XML_PARSE_NOENT },
-    { "XML Namespaces regression tests",
-      errParseTest, "./test/namespaces/*", "result/namespaces/", "", ".err",
-      0 },
-    { "Error cases regression tests",
-      errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",
-      0 },
-#ifdef LIBXML_READER_ENABLED
-    { "Error cases stream regression tests",
-      streamParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".str",
-      0 },
-    { "Reader regression tests",
-      streamParseTest, "./test/*", "result/", ".rdr", NULL,
-      0 },
-    { "Reader entities substitution regression tests",
-      streamParseTest, "./test/*", "result/", ".rde", NULL,
-      XML_PARSE_NOENT },
-    { "Reader on memory regression tests",
-      streamMemParseTest, "./test/*", "result/", ".rdr", NULL,
-      0 },
-    { "Walker regression tests",
-      walkerParseTest, "./test/*", "result/", ".rdr", NULL,
-      0 },
-#endif
-#ifdef LIBXML_SAX1_ENABLED
-    { "SAX1 callbacks regression tests" ,
-      saxParseTest, "./test/*", "result/", ".sax", NULL,
-      XML_PARSE_SAX1 },
-    { "SAX2 callbacks regression tests" ,
-      saxParseTest, "./test/*", "result/", ".sax2", NULL,
-      0 },
-#endif
-#ifdef LIBXML_PUSH_ENABLED
-    { "XML push regression tests" ,
-      pushParseTest, "./test/*", "result/", "", NULL,
-      0 },
-#endif
-#ifdef LIBXML_HTML_ENABLED
-    { "HTML regression tests" ,
-      errParseTest, "./test/HTML/*", "result/HTML/", "", ".err",
-      XML_PARSE_HTML },
-#ifdef LIBXML_PUSH_ENABLED
-    { "Push HTML regression tests" ,
-      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,
-      XML_PARSE_DTDVALID },
-    { "Validity checking regression tests" ,
-      errParseTest, "./test/VC/*", "result/VC/", NULL, "",
-      XML_PARSE_DTDVALID },
-    { "General documents valid regression tests" ,
-      errParseTest, "./test/valid/*", "result/valid/", "", ".err",
-      XML_PARSE_DTDVALID },
-#endif
-#ifdef LIBXML_XINCLUDE_ENABLED
-    { "XInclude regression tests" ,
-      errParseTest, "./test/XInclude/docs/*", "result/XInclude/", "", NULL,
-      /* Ignore errors at this point ".err", */
-      XML_PARSE_XINCLUDE },
-    { "XInclude xmlReader regression tests",
-      streamParseTest, "./test/XInclude/docs/*", "result/XInclude/", ".rdr",
-      /* Ignore errors at this point ".err", */
-      NULL, XML_PARSE_XINCLUDE },
-    { "XInclude regression tests stripping include nodes" ,
-      errParseTest, "./test/XInclude/docs/*", "result/XInclude/", "", NULL,
-      /* Ignore errors at this point ".err", */
-      XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE },
-    { "XInclude xmlReader regression tests stripping include nodes",
-      streamParseTest, "./test/XInclude/docs/*", "result/XInclude/", ".rdr",
-      /* Ignore errors at this point ".err", */
-      NULL, XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE },
-#endif
-#ifdef LIBXML_XPATH_ENABLED
-#ifdef LIBXML_DEBUG_ENABLED
-    { "XPath expressions regression tests" ,
-      xpathExprTest, "./test/XPath/expr/*", "result/XPath/expr/", "", NULL,
-      0 },
-    { "XPath document queries regression tests" ,
-      xpathDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
-      0 },
-#ifdef LIBXML_XPTR_ENABLED
-    { "XPointer document queries regression tests" ,
-      xptrDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
-      0 },
-#endif
-    { "xml:id regression tests" ,
-      xmlidDocTest, "./test/xmlid/*", "result/xmlid/", "", ".err",
-      0 },
-#endif
-#endif
-    { "URI parsing tests" ,
-      uriParseTest, "./test/URI/*.uri", "result/URI/", "", NULL,
-      0 },
-    { "URI base composition tests" ,
-      uriBaseTest, "./test/URI/*.data", "result/URI/", "", NULL,
-      0 },
-#ifdef LIBXML_SCHEMAS_ENABLED
-    { "Schemas regression tests" ,
-      schemasTest, "./test/schemas/*_*.xsd", NULL, NULL, NULL,
-      0 },
-    { "Relax-NG regression tests" ,
-      rngTest, "./test/relaxng/*.rng", NULL, NULL, NULL,
-      XML_PARSE_DTDATTR | XML_PARSE_NOENT },
-#ifdef LIBXML_READER_ENABLED
-    { "Relax-NG streaming regression tests" ,
-      rngStreamTest, "./test/relaxng/*.rng", NULL, NULL, NULL,
-      XML_PARSE_DTDATTR | XML_PARSE_NOENT },
-#endif
-#endif
-#ifdef LIBXML_PATTERN_ENABLED
-#ifdef LIBXML_READER_ENABLED
-    { "Pattern regression tests" ,
-      patternTest, "./test/pattern/*.pat", "result/pattern/", NULL, NULL,
-      0 },
-#endif
-#endif
-#ifdef LIBXML_C14N_ENABLED
-    { "C14N with comments regression tests" ,
-      c14nWithCommentTest, "./test/c14n/with-comments/*.xml", NULL, NULL, NULL,
-      0 },
-    { "C14N without comments regression tests" ,
-      c14nWithoutCommentTest, "./test/c14n/without-comments/*.xml", NULL, NULL, NULL,
-      0 },
-    { "C14N exclusive without comments regression tests" ,
-      c14nExcWithoutCommentTest, "./test/c14n/exc-without-comments/*.xml", NULL, NULL, NULL,
-      0 },
-#endif
-#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
-    { "Catalog and Threads regression tests" ,
-      threadsTest, NULL, NULL, NULL, NULL,
-      0 },
-#endif
-    {NULL, NULL, NULL, NULL, NULL, NULL, 0}
-};
-
-/************************************************************************
- *									*
- *		The main code driving the tests				*
- *									*
- ************************************************************************/
-
-static int
-launchTests(testDescPtr tst) {
-    int res = 0, err = 0;
-    size_t i;
-    char *result;
-    char *error;
-    int mem;
-
-    if (tst == NULL) return(-1);
-    if (tst->in != NULL) {
-	glob_t globbuf;
-
-	globbuf.gl_offs = 0;
-	glob(tst->in, GLOB_DOOFFS, NULL, &globbuf);
-	for (i = 0;i < globbuf.gl_pathc;i++) {
-	    if (!checkTestFile(globbuf.gl_pathv[i]))
-	        continue;
-	    if (tst->suffix != NULL) {
-		result = resultFilename(globbuf.gl_pathv[i], tst->out,
-					tst->suffix);
-		if (result == NULL) {
-		    fprintf(stderr, "Out of memory !\n");
-		    fatalError();
-		}
-	    } else {
-	        result = NULL;
-	    }
-	    if (tst->err != NULL) {
-		error = resultFilename(globbuf.gl_pathv[i], tst->out,
-		                        tst->err);
-		if (error == NULL) {
-		    fprintf(stderr, "Out of memory !\n");
-		    fatalError();
-		}
-	    } else {
-	        error = NULL;
-	    }
-	    if ((result) &&(!checkTestFile(result))) {
-	        fprintf(stderr, "Missing result file %s\n", result);
-	    } else if ((error) &&(!checkTestFile(error))) {
-	        fprintf(stderr, "Missing error file %s\n", error);
-	    } else {
-		mem = xmlMemUsed();
-		extraMemoryFromResolver = 0;
-		testErrorsSize = 0;
-		testErrors[0] = 0;
-		res = tst->func(globbuf.gl_pathv[i], result, error,
-		                tst->options);
-		xmlResetLastError();
-		if (res != 0) {
-		    fprintf(stderr, "File %s generated an error\n",
-		            globbuf.gl_pathv[i]);
-		    nb_errors++;
-		    err++;
-		}
-		else if (xmlMemUsed() != mem) {
-		    if ((xmlMemUsed() != mem) &&
-		        (extraMemoryFromResolver == 0)) {
-			fprintf(stderr, "File %s leaked %d bytes\n",
-				globbuf.gl_pathv[i], xmlMemUsed() - mem);
-			nb_leaks++;
-			err++;
-		    }
-		}
-		testErrorsSize = 0;
-	    }
-	    if (result)
-		free(result);
-	    if (error)
-		free(error);
-	}
-	globfree(&globbuf);
-    } else {
-        testErrorsSize = 0;
-	testErrors[0] = 0;
-	extraMemoryFromResolver = 0;
-        res = tst->func(NULL, NULL, NULL, tst->options);
-	if (res != 0) {
-	    nb_errors++;
-	    err++;
-	}
-    }
-    return(err);
-}
-
-int
-main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
-    int i = 0, res, ret = 0;
-    int verbose = 0;
-    int old_errors, old_tests, old_leaks;
-
-    initializeLibxml2();
-
-    if ((argc >= 2) && (!strcmp(argv[1], "-v")))
-        verbose = 1;
-    for (i = 0; testDescriptions[i].func != NULL; i++) {
-        old_errors = nb_errors;
-        old_tests = nb_tests;
-        old_leaks = nb_leaks;
-        if (testDescriptions[i].desc != NULL)
-	    printf("## %s\n", testDescriptions[i].desc);
-	res = launchTests(&testDescriptions[i]);
-	if (res != 0)
-	    ret++;
-	if (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);
-	}
-    }
-    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);
-    }
-    xmlCleanupParser();
-    xmlMemoryDump();
-
-    return(ret);
-}
-
-#else /* ! LIBXML_OUTPUT_ENABLED */
-int
-main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
-    fprintf(stderr, "runtest requires output to be enabled in libxml2\n");
-    return(1);
-}
-#endif
+    if (len <= 0)

+        len = 0;

+

+    

+    ret = pglob;

+    memset(ret, 0, sizeof(glob_t));

+    

+    hFind = FindFirstFileA(pattern, &FindFileData);

+    if (hFind == INVALID_HANDLE_VALUE) 

+        return(0);

+    nb_paths = 20;

+    ret->gl_pathv = (char **) malloc(nb_paths * sizeof(char *));

+    if (ret->gl_pathv == NULL) {

+	FindClose(hFind);

+        return(-1);

+    }

+    strncpy(directory + len, FindFileData.cFileName, 499 - len);

+    ret->gl_pathv[ret->gl_pathc] = strdup(directory);

+    if (ret->gl_pathv[ret->gl_pathc] == NULL)

+        goto done;

+    ret->gl_pathc++;

+    while(FindNextFileA(hFind, &FindFileData)) {

+        if (FindFileData.cFileName[0] == '.')

+	    continue;

+        if (ret->gl_pathc + 2 > nb_paths) {

+            char **tmp = realloc(ret->gl_pathv, nb_paths * 2 * sizeof(char *));

+            if (tmp == NULL)

+                break;

+            ret->gl_pathv = tmp;

+            nb_paths *= 2;

+	}

+	strncpy(directory + len, FindFileData.cFileName, 499 - len);

+	ret->gl_pathv[ret->gl_pathc] = strdup(directory);

+        if (ret->gl_pathv[ret->gl_pathc] == NULL)

+            break;

+        ret->gl_pathc++;

+    }

+    ret->gl_pathv[ret->gl_pathc] = NULL;

+

+done:

+    FindClose(hFind);

+    return(0);

+}

+ 

+

+

+static void globfree(glob_t *pglob) {

+    unsigned int i;

+    if (pglob == NULL)

+        return;

+    

+    for (i = 0;i < pglob->gl_pathc;i++) {

+         if (pglob->gl_pathv[i] != NULL)

+             free(pglob->gl_pathv[i]);

+    }

+}

+#define vsnprintf _vsnprintf

+#define snprintf _snprintf

+#else

+#include <glob.h>

+#endif

+

+/************************************************************************

+ *									*

+ *		Libxml2 specific routines				*

+ *									*

+ ************************************************************************/

+

+static int nb_tests = 0;

+static int nb_errors = 0;

+static int nb_leaks = 0;

+static long libxmlMemoryAllocatedBase = 0;

+static int extraMemoryFromResolver = 0;

+

+static int

+fatalError(void) {

+    fprintf(stderr, "Exitting tests on fatal error\n");

+    exit(1);

+}

+

+/*

+ * 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;

+

+    if (checkTestFile(URL)) {

+	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);

+    } else {

+	int memused = xmlMemUsed();

+	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);

+	extraMemoryFromResolver += xmlMemUsed() - memused;

+    }

+      

+    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

+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 void

+channel(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;

+}

+

+/**

+ * xmlParserPrintFileContext:

+ * @input:  an xmlParserInputPtr input

+ * 

+ * Displays current context within the input content for error tracking

+ */

+

+static void

+xmlParserPrintFileContextInternal(xmlParserInputPtr input , 

+		xmlGenericErrorFunc chanl, void *data ) {

+    const xmlChar *cur, *base;

+    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */

+    xmlChar  content[81]; /* space for 80 chars + line terminator */

+    xmlChar *ctnt;

+

+    if (input == NULL) return;

+    cur = input->cur;

+    base = input->base;

+    /* skip backwards over any end-of-lines */

+    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {

+	cur--;

+    }

+    n = 0;

+    /* search backwards for beginning-of-line (to max buff size) */

+    while ((n++ < (sizeof(content)-1)) && (cur > base) && 

+    	   (*(cur) != '\n') && (*(cur) != '\r'))

+        cur--;

+    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;

+    /* calculate the error position in terms of the current position */

+    col = input->cur - cur;

+    /* search forward for end-of-line (to max buff size) */

+    n = 0;

+    ctnt = content;

+    /* copy selected text to our buffer */

+    while ((*cur != 0) && (*(cur) != '\n') && 

+    	   (*(cur) != '\r') && (n < sizeof(content)-1)) {

+		*ctnt++ = *cur++;

+	n++;

+    }

+    *ctnt = 0;

+    /* print out the selected text */

+    chanl(data ,"%s\n", content);

+    /* create blank line with problem pointer */

+    n = 0;

+    ctnt = content;

+    /* (leave buffer space for pointer + line terminator) */

+    while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {

+	if (*(ctnt) != '\t')

+	    *(ctnt) = ' ';

+	ctnt++;

+    }

+    *ctnt++ = '^';

+    *ctnt = 0;

+    chanl(data ,"%s\n", content);

+}

+

+static void

+testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {

+    char *file = NULL;

+    int line = 0;

+    int code = -1;

+    int domain;

+    void *data = NULL;

+    const char *str;

+    const xmlChar *name = NULL;

+    xmlNodePtr node;

+    xmlErrorLevel level;

+    xmlParserInputPtr input = NULL;

+    xmlParserInputPtr cur = NULL;

+    xmlParserCtxtPtr ctxt = NULL;

+

+    if (err == NULL)

+        return;

+

+    file = err->file;

+    line = err->line;

+    code = err->code;

+    domain = err->domain;

+    level = err->level;

+    node = err->node;

+    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||

+        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||

+	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {

+	ctxt = err->ctxt;

+    }

+    str = err->message;

+

+    if (code == XML_ERR_OK)

+        return;

+

+    if ((node != NULL) && (node->type == XML_ELEMENT_NODE))

+        name = node->name;

+

+    /*

+     * Maintain the compatibility with the legacy error handling

+     */

+    if (ctxt != NULL) {

+        input = ctxt->input;

+        if ((input != NULL) && (input->filename == NULL) &&

+            (ctxt->inputNr > 1)) {

+            cur = input;

+            input = ctxt->inputTab[ctxt->inputNr - 2];

+        }

+        if (input != NULL) {

+            if (input->filename)

+                channel(data, "%s:%d: ", input->filename, input->line);

+            else if ((line != 0) && (domain == XML_FROM_PARSER))

+                channel(data, "Entity: line %d: ", input->line);

+        }

+    } else {

+        if (file != NULL)

+            channel(data, "%s:%d: ", file, line);

+        else if ((line != 0) && (domain == XML_FROM_PARSER))

+            channel(data, "Entity: line %d: ", line);

+    }

+    if (name != NULL) {

+        channel(data, "element %s: ", name);

+    }

+    if (code == XML_ERR_OK)

+        return;

+    switch (domain) {

+        case XML_FROM_PARSER:

+            channel(data, "parser ");

+            break;

+        case XML_FROM_NAMESPACE:

+            channel(data, "namespace ");

+            break;

+        case XML_FROM_DTD:

+        case XML_FROM_VALID:

+            channel(data, "validity ");

+            break;

+        case XML_FROM_HTML:

+            channel(data, "HTML parser ");

+            break;

+        case XML_FROM_MEMORY:

+            channel(data, "memory ");

+            break;

+        case XML_FROM_OUTPUT:

+            channel(data, "output ");

+            break;

+        case XML_FROM_IO:

+            channel(data, "I/O ");

+            break;

+        case XML_FROM_XINCLUDE:

+            channel(data, "XInclude ");

+            break;

+        case XML_FROM_XPATH:

+            channel(data, "XPath ");

+            break;

+        case XML_FROM_XPOINTER:

+            channel(data, "parser ");

+            break;

+        case XML_FROM_REGEXP:

+            channel(data, "regexp ");

+            break;

+        case XML_FROM_MODULE:

+            channel(data, "module ");

+            break;

+        case XML_FROM_SCHEMASV:

+            channel(data, "Schemas validity ");

+            break;

+        case XML_FROM_SCHEMASP:

+            channel(data, "Schemas parser ");

+            break;

+        case XML_FROM_RELAXNGP:

+            channel(data, "Relax-NG parser ");

+            break;

+        case XML_FROM_RELAXNGV:

+            channel(data, "Relax-NG validity ");

+            break;

+        case XML_FROM_CATALOG:

+            channel(data, "Catalog ");

+            break;

+        case XML_FROM_C14N:

+            channel(data, "C14N ");

+            break;

+        case XML_FROM_XSLT:

+            channel(data, "XSLT ");

+            break;

+        default:

+            break;

+    }

+    if (code == XML_ERR_OK)

+        return;

+    switch (level) {

+        case XML_ERR_NONE:

+            channel(data, ": ");

+            break;

+        case XML_ERR_WARNING:

+            channel(data, "warning : ");

+            break;

+        case XML_ERR_ERROR:

+            channel(data, "error : ");

+            break;

+        case XML_ERR_FATAL:

+            channel(data, "error : ");

+            break;

+    }

+    if (code == XML_ERR_OK)

+        return;

+    if (str != NULL) {

+        int len;

+	len = xmlStrlen((const xmlChar *)str);

+	if ((len > 0) && (str[len - 1] != '\n'))

+	    channel(data, "%s\n", str);

+	else

+	    channel(data, "%s", str);

+    } else {

+        channel(data, "%s\n", "out of memory error");

+    }

+    if (code == XML_ERR_OK)

+        return;

+

+    if (ctxt != NULL) {

+        xmlParserPrintFileContextInternal(input, channel, data);

+        if (cur != NULL) {

+            if (cur->filename)

+                channel(data, "%s:%d: \n", cur->filename, cur->line);

+            else if ((line != 0) && (domain == XML_FROM_PARSER))

+                channel(data, "Entity: line %d: \n", cur->line);

+            xmlParserPrintFileContextInternal(cur, channel, data);

+        }

+    }

+    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&

+        (err->int1 < 100) &&

+	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {

+	xmlChar buf[150];

+	int i;

+

+	channel(data, "%s\n", err->str1);

+	for (i=0;i < err->int1;i++)

+	     buf[i] = ' ';

+	buf[i++] = '^';

+	buf[i] = 0;

+	channel(data, "%s\n", buf);

+    }

+}

+

+static void

+initializeLibxml2(void) {

+    xmlGetWarningsDefaultValue = 0;

+    xmlPedanticParserDefault(0);

+

+    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);

+    xmlInitParser();

+    xmlSetExternalEntityLoader(testExternalEntityLoader);

+    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);

+#ifdef LIBXML_SCHEMAS_ENABLED

+    xmlSchemaInitTypes();

+    xmlRelaxNGInitTypes();

+#endif

+    libxmlMemoryAllocatedBase = xmlMemUsed();

+}

+

+

+/************************************************************************

+ *									*

+ *		File name and path utilities				*

+ *									*

+ ************************************************************************/

+

+static const char *baseFilename(const char *filename) {

+    const char *cur;

+    if (filename == NULL)

+        return(NULL);

+    cur = &filename[strlen(filename)];

+    while ((cur > filename) && (*cur != '/'))

+        cur--;

+    if (*cur == '/')

+        return(cur + 1);

+    return(cur);

+}

+

+static char *resultFilename(const char *filename, const char *out,

+                            const char *suffix) {

+    const char *base;

+    char res[500];

+

+/*************

+    if ((filename[0] == 't') && (filename[1] == 'e') &&

+        (filename[2] == 's') && (filename[3] == 't') &&

+	(filename[4] == '/'))

+	filename = &filename[5];

+ *************/

+    

+    base = baseFilename(filename);

+    if (suffix == NULL)

+        suffix = ".tmp";

+    if (out == NULL)

+        out = "";

+    snprintf(res, 499, "%s%s%s", out, base, suffix);

+    res[499] = 0;

+    return(strdup(res));

+}

+

+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 int compareFiles(const char *r1, const char *r2) {

+    int res1, res2;

+    int fd1, fd2;

+    char bytes1[4096];

+    char bytes2[4096];

+

+    fd1 = open(r1, O_RDONLY | O_BINARY);

+    if (fd1 < 0)

+        return(-1);

+    fd2 = open(r2, O_RDONLY | O_BINARY);

+    if (fd2 < 0) {

+        close(fd1);

+        return(-1);

+    }

+    while (1) {

+        res1 = read(fd1, bytes1, 4096);

+        res2 = read(fd2, bytes2, 4096);

+	if (res1 != res2) {

+	    close(fd1);

+	    close(fd2);

+	    return(1);

+	}

+	if (res1 == 0)

+	    break;

+	if (memcmp(bytes1, bytes2, res1) != 0) {

+	    close(fd1);

+	    close(fd2);

+	    return(1);

+	}

+    }

+    close(fd1);

+    close(fd2);

+    return(0);

+}

+

+static int compareFileMem(const char *filename, const char *mem, int size) {

+    int res;

+    int fd;

+    char bytes[4096];

+    int idx = 0;

+    struct stat info;

+

+    if (stat(filename, &info) < 0) 

+	return(-1);

+    if (info.st_size != size)

+        return(-1);

+    fd = open(filename, O_RDONLY | O_BINARY);

+    if (fd < 0)

+        return(-1);

+    while (idx < size) {

+        res = read(fd, bytes, 4096);

+	if (res <= 0)

+	    break;

+	if (res + idx > size) 

+	    break;

+	if (memcmp(bytes, &mem[idx], res) != 0) {

+	    int ix;

+	    for (ix=0; ix<res; ix++)

+		if (bytes[ix] != mem[idx+ix])

+			break;

+	    fprintf(stderr,"Compare error at position %d\n", idx+ix);

+	    close(fd);

+	    return(1);

+	}

+	idx += res;

+    }

+    close(fd);

+    return(idx != size);

+}

+

+static int loadMem(const char *filename, const char **mem, int *size) {

+    int fd, res;

+    struct stat info;

+    char *base;

+    int siz = 0;

+    if (stat(filename, &info) < 0) 

+	return(-1);

+    base = malloc(info.st_size + 1);

+    if (base == NULL)

+	return(-1);

+    if ((fd = open(filename, O_RDONLY | O_BINARY)) < 0) {

+        free(base);

+	return(-1);

+    }

+    while ((res = read(fd, &base[siz], info.st_size - siz)) > 0) {

+        siz += res;

+    }

+    close(fd);

+#if !defined(_WIN32)

+    if (siz != info.st_size) {

+        free(base);

+	return(-1);

+    }

+#endif

+    base[siz] = 0;

+    *mem = base;

+    *size = siz;

+    return(0);

+}

+

+static int unloadMem(const char *mem) {

+    free((char *)mem);

+    return(0);

+}

+

+/************************************************************************

+ *									*

+ *		Tests implementations					*

+ *									*

+ ************************************************************************/

+

+/************************************************************************

+ *									*

+ *		Parse to SAX based tests				*

+ *									*

+ ************************************************************************/

+

+FILE *SAXdebug = NULL;

+

+/*

+ * empty SAX block

+ */

+xmlSAXHandler emptySAXHandlerStruct = {

+    NULL, /* internalSubset */

+    NULL, /* isStandalone */

+    NULL, /* hasInternalSubset */

+    NULL, /* hasExternalSubset */

+    NULL, /* resolveEntity */

+    NULL, /* getEntity */

+    NULL, /* entityDecl */

+    NULL, /* notationDecl */

+    NULL, /* attributeDecl */

+    NULL, /* elementDecl */

+    NULL, /* unparsedEntityDecl */

+    NULL, /* setDocumentLocator */

+    NULL, /* startDocument */

+    NULL, /* endDocument */

+    NULL, /* startElement */

+    NULL, /* endElement */

+    NULL, /* reference */

+    NULL, /* characters */

+    NULL, /* ignorableWhitespace */

+    NULL, /* processingInstruction */

+    NULL, /* comment */

+    NULL, /* xmlParserWarning */

+    NULL, /* xmlParserError */

+    NULL, /* xmlParserError */

+    NULL, /* getParameterEntity */

+    NULL, /* cdataBlock; */

+    NULL, /* externalSubset; */

+    1,

+    NULL,

+    NULL, /* startElementNs */

+    NULL, /* endElementNs */

+    NULL  /* xmlStructuredErrorFunc */

+};

+

+static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;

+int callbacks = 0;

+int quiet = 0;

+

+/**

+ * isStandaloneDebug:

+ * @ctxt:  An XML parser context

+ *

+ * Is this document tagged standalone ?

+ *

+ * Returns 1 if true

+ */

+static int

+isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return(0);

+    fprintf(SAXdebug, "SAX.isStandalone()\n");

+    return(0);

+}

+

+/**

+ * hasInternalSubsetDebug:

+ * @ctxt:  An XML parser context

+ *

+ * Does this document has an internal subset

+ *

+ * Returns 1 if true

+ */

+static int

+hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return(0);

+    fprintf(SAXdebug, "SAX.hasInternalSubset()\n");

+    return(0);

+}

+

+/**

+ * hasExternalSubsetDebug:

+ * @ctxt:  An XML parser context

+ *

+ * Does this document has an external subset

+ *

+ * Returns 1 if true

+ */

+static int

+hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return(0);

+    fprintf(SAXdebug, "SAX.hasExternalSubset()\n");

+    return(0);

+}

+

+/**

+ * internalSubsetDebug:

+ * @ctxt:  An XML parser context

+ *

+ * Does this document has an internal subset

+ */

+static void

+internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,

+	       const xmlChar *ExternalID, const xmlChar *SystemID)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.internalSubset(%s,", name);

+    if (ExternalID == NULL)

+	fprintf(SAXdebug, " ,");

+    else

+	fprintf(SAXdebug, " %s,", ExternalID);

+    if (SystemID == NULL)

+	fprintf(SAXdebug, " )\n");

+    else

+	fprintf(SAXdebug, " %s)\n", SystemID);

+}

+

+/**

+ * externalSubsetDebug:

+ * @ctxt:  An XML parser context

+ *

+ * Does this document has an external subset

+ */

+static void

+externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,

+	       const xmlChar *ExternalID, const xmlChar *SystemID)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.externalSubset(%s,", name);

+    if (ExternalID == NULL)

+	fprintf(SAXdebug, " ,");

+    else

+	fprintf(SAXdebug, " %s,", ExternalID);

+    if (SystemID == NULL)

+	fprintf(SAXdebug, " )\n");

+    else

+	fprintf(SAXdebug, " %s)\n", SystemID);

+}

+

+/**

+ * resolveEntityDebug:

+ * @ctxt:  An XML parser context

+ * @publicId: The public ID of the entity

+ * @systemId: The system ID of the entity

+ *

+ * Special entity resolver, better left to the parser, it has

+ * more context than the application layer.

+ * The default behaviour is to NOT resolve the entities, in that case

+ * the ENTITY_REF nodes are built in the structure (and the parameter

+ * values).

+ *

+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.

+ */

+static xmlParserInputPtr

+resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)

+{

+    callbacks++;

+    if (quiet)

+	return(NULL);

+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */

+

+    

+    fprintf(SAXdebug, "SAX.resolveEntity(");

+    if (publicId != NULL)

+	fprintf(SAXdebug, "%s", (char *)publicId);

+    else

+	fprintf(SAXdebug, " ");

+    if (systemId != NULL)

+	fprintf(SAXdebug, ", %s)\n", (char *)systemId);

+    else

+	fprintf(SAXdebug, ", )\n");

+/*********

+    if (systemId != NULL) {

+        return(xmlNewInputFromFile(ctxt, (char *) systemId));

+    }

+ *********/

+    return(NULL);

+}

+

+/**

+ * getEntityDebug:

+ * @ctxt:  An XML parser context

+ * @name: The entity name

+ *

+ * Get an entity by name

+ *

+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.

+ */

+static xmlEntityPtr

+getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)

+{

+    callbacks++;

+    if (quiet)

+	return(NULL);

+    fprintf(SAXdebug, "SAX.getEntity(%s)\n", name);

+    return(NULL);

+}

+

+/**

+ * getParameterEntityDebug:

+ * @ctxt:  An XML parser context

+ * @name: The entity name

+ *

+ * Get a parameter entity by name

+ *

+ * Returns the xmlParserInputPtr

+ */

+static xmlEntityPtr

+getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)

+{

+    callbacks++;

+    if (quiet)

+	return(NULL);

+    fprintf(SAXdebug, "SAX.getParameterEntity(%s)\n", name);

+    return(NULL);

+}

+

+

+/**

+ * entityDeclDebug:

+ * @ctxt:  An XML parser context

+ * @name:  the entity name 

+ * @type:  the entity type 

+ * @publicId: The public ID of the entity

+ * @systemId: The system ID of the entity

+ * @content: the entity value (without processing).

+ *

+ * An entity definition has been parsed

+ */

+static void

+entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,

+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)

+{

+const xmlChar *nullstr = BAD_CAST "(null)";

+    /* not all libraries handle printing null pointers nicely */

+    if (publicId == NULL)

+        publicId = nullstr;

+    if (systemId == NULL)

+        systemId = nullstr;

+    if (content == NULL)

+        content = (xmlChar *)nullstr;

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",

+            name, type, publicId, systemId, content);

+}

+

+/**

+ * attributeDeclDebug:

+ * @ctxt:  An XML parser context

+ * @name:  the attribute name 

+ * @type:  the attribute type 

+ *

+ * An attribute definition has been parsed

+ */

+static void

+attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,

+                   const xmlChar * name, int type, int def,

+                   const xmlChar * defaultValue, xmlEnumerationPtr tree)

+{

+    callbacks++;

+    if (quiet)

+        return;

+    if (defaultValue == NULL)

+        fprintf(SAXdebug, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",

+                elem, name, type, def);

+    else

+        fprintf(SAXdebug, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",

+                elem, name, type, def, defaultValue);

+    xmlFreeEnumeration(tree);

+}

+

+/**

+ * elementDeclDebug:

+ * @ctxt:  An XML parser context

+ * @name:  the element name 

+ * @type:  the element type 

+ * @content: the element value (without processing).

+ *

+ * An element definition has been parsed

+ */

+static void

+elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,

+	    xmlElementContentPtr content ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.elementDecl(%s, %d, ...)\n",

+            name, type);

+}

+

+/**

+ * notationDeclDebug:

+ * @ctxt:  An XML parser context

+ * @name: The name of the notation

+ * @publicId: The public ID of the entity

+ * @systemId: The system ID of the entity

+ *

+ * What to do when a notation declaration has been parsed.

+ */

+static void

+notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,

+	     const xmlChar *publicId, const xmlChar *systemId)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.notationDecl(%s, %s, %s)\n",

+            (char *) name, (char *) publicId, (char *) systemId);

+}

+

+/**

+ * unparsedEntityDeclDebug:

+ * @ctxt:  An XML parser context

+ * @name: The name of the entity

+ * @publicId: The public ID of the entity

+ * @systemId: The system ID of the entity

+ * @notationName: the name of the notation

+ *

+ * What to do when an unparsed entity declaration is parsed

+ */

+static void

+unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,

+		   const xmlChar *publicId, const xmlChar *systemId,

+		   const xmlChar *notationName)

+{

+const xmlChar *nullstr = BAD_CAST "(null)";

+

+    if (publicId == NULL)

+        publicId = nullstr;

+    if (systemId == NULL)

+        systemId = nullstr;

+    if (notationName == NULL)

+        notationName = nullstr;

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",

+            (char *) name, (char *) publicId, (char *) systemId,

+	    (char *) notationName);

+}

+

+/**

+ * setDocumentLocatorDebug:

+ * @ctxt:  An XML parser context

+ * @loc: A SAX Locator

+ *

+ * Receive the document locator at startup, actually xmlDefaultSAXLocator

+ * Everything is available on the context, so this is useless in our case.

+ */

+static void

+setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.setDocumentLocator()\n");

+}

+

+/**

+ * startDocumentDebug:

+ * @ctxt:  An XML parser context

+ *

+ * called when the document start being processed.

+ */

+static void

+startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.startDocument()\n");

+}

+

+/**

+ * endDocumentDebug:

+ * @ctxt:  An XML parser context

+ *

+ * called when the document end has been detected.

+ */

+static void

+endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.endDocument()\n");

+}

+

+/**

+ * startElementDebug:

+ * @ctxt:  An XML parser context

+ * @name:  The element name

+ *

+ * called when an opening tag has been processed.

+ */

+static void

+startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)

+{

+    int i;

+

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.startElement(%s", (char *) name);

+    if (atts != NULL) {

+        for (i = 0;(atts[i] != NULL);i++) {

+	    fprintf(SAXdebug, ", %s='", atts[i++]);

+	    if (atts[i] != NULL)

+	        fprintf(SAXdebug, "%s'", atts[i]);

+	}

+    }

+    fprintf(SAXdebug, ")\n");

+}

+

+/**

+ * endElementDebug:

+ * @ctxt:  An XML parser context

+ * @name:  The element name

+ *

+ * called when the end of an element has been detected.

+ */

+static void

+endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.endElement(%s)\n", (char *) name);

+}

+

+/**

+ * charactersDebug:

+ * @ctxt:  An XML parser context

+ * @ch:  a xmlChar string

+ * @len: the number of xmlChar

+ *

+ * receiving some chars from the parser.

+ * Question: how much at a time ???

+ */

+static void

+charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)

+{

+    char output[40];

+    int i;

+

+    callbacks++;

+    if (quiet)

+	return;

+    for (i = 0;(i<len) && (i < 30);i++)

+	output[i] = ch[i];

+    output[i] = 0;

+

+    fprintf(SAXdebug, "SAX.characters(%s, %d)\n", output, len);

+}

+

+/**

+ * referenceDebug:

+ * @ctxt:  An XML parser context

+ * @name:  The entity name

+ *

+ * called when an entity reference is detected. 

+ */

+static void

+referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.reference(%s)\n", name);

+}

+

+/**

+ * ignorableWhitespaceDebug:

+ * @ctxt:  An XML parser context

+ * @ch:  a xmlChar string

+ * @start: the first char in the string

+ * @len: the number of xmlChar

+ *

+ * receiving some ignorable whitespaces from the parser.

+ * Question: how much at a time ???

+ */

+static void

+ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)

+{

+    char output[40];

+    int i;

+

+    callbacks++;

+    if (quiet)

+	return;

+    for (i = 0;(i<len) && (i < 30);i++)

+	output[i] = ch[i];

+    output[i] = 0;

+    fprintf(SAXdebug, "SAX.ignorableWhitespace(%s, %d)\n", output, len);

+}

+

+/**

+ * processingInstructionDebug:

+ * @ctxt:  An XML parser context

+ * @target:  the target name

+ * @data: the PI data's

+ * @len: the number of xmlChar

+ *

+ * A processing instruction has been parsed.

+ */

+static void

+processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,

+                      const xmlChar *data)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    if (data != NULL)

+	fprintf(SAXdebug, "SAX.processingInstruction(%s, %s)\n",

+		(char *) target, (char *) data);

+    else

+	fprintf(SAXdebug, "SAX.processingInstruction(%s, NULL)\n",

+		(char *) target);

+}

+

+/**

+ * cdataBlockDebug:

+ * @ctx: the user data (XML parser context)

+ * @value:  The pcdata content

+ * @len:  the block length

+ *

+ * called when a pcdata block has been parsed

+ */

+static void

+cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.pcdata(%.20s, %d)\n",

+	    (char *) value, len);

+}

+

+/**

+ * commentDebug:

+ * @ctxt:  An XML parser context

+ * @value:  the comment content

+ *

+ * A comment has been parsed.

+ */

+static void

+commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.comment(%s)\n", value);

+}

+

+/**

+ * warningDebug:

+ * @ctxt:  An XML parser context

+ * @msg:  the message to display/transmit

+ * @...:  extra parameters for the message display

+ *

+ * Display and format a warning messages, gives file, line, position and

+ * extra parameters.

+ */

+static void

+warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)

+{

+    va_list args;

+

+    callbacks++;

+    if (quiet)

+	return;

+    va_start(args, msg);

+    fprintf(SAXdebug, "SAX.warning: ");

+    vfprintf(SAXdebug, msg, args);

+    va_end(args);

+}

+

+/**

+ * errorDebug:

+ * @ctxt:  An XML parser context

+ * @msg:  the message to display/transmit

+ * @...:  extra parameters for the message display

+ *

+ * Display and format a error messages, gives file, line, position and

+ * extra parameters.

+ */

+static void

+errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)

+{

+    va_list args;

+

+    callbacks++;

+    if (quiet)

+	return;

+    va_start(args, msg);

+    fprintf(SAXdebug, "SAX.error: ");

+    vfprintf(SAXdebug, msg, args);

+    va_end(args);

+}

+

+/**

+ * fatalErrorDebug:

+ * @ctxt:  An XML parser context

+ * @msg:  the message to display/transmit

+ * @...:  extra parameters for the message display

+ *

+ * Display and format a fatalError messages, gives file, line, position and

+ * extra parameters.

+ */

+static void

+fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)

+{

+    va_list args;

+

+    callbacks++;

+    if (quiet)

+	return;

+    va_start(args, msg);

+    fprintf(SAXdebug, "SAX.fatalError: ");

+    vfprintf(SAXdebug, msg, args);

+    va_end(args);

+}

+

+xmlSAXHandler debugSAXHandlerStruct = {

+    internalSubsetDebug,

+    isStandaloneDebug,

+    hasInternalSubsetDebug,

+    hasExternalSubsetDebug,

+    resolveEntityDebug,

+    getEntityDebug,

+    entityDeclDebug,

+    notationDeclDebug,

+    attributeDeclDebug,

+    elementDeclDebug,

+    unparsedEntityDeclDebug,

+    setDocumentLocatorDebug,

+    startDocumentDebug,

+    endDocumentDebug,

+    startElementDebug,

+    endElementDebug,

+    referenceDebug,

+    charactersDebug,

+    ignorableWhitespaceDebug,

+    processingInstructionDebug,

+    commentDebug,

+    warningDebug,

+    errorDebug,

+    fatalErrorDebug,

+    getParameterEntityDebug,

+    cdataBlockDebug,

+    externalSubsetDebug,

+    1,

+    NULL,

+    NULL,

+    NULL,

+    NULL

+};

+

+xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;

+

+/*

+ * SAX2 specific callbacks

+ */

+/**

+ * startElementNsDebug:

+ * @ctxt:  An XML parser context

+ * @name:  The element name

+ *

+ * called when an opening tag has been processed.

+ */

+static void

+startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,

+                    const xmlChar *localname,

+                    const xmlChar *prefix,

+                    const xmlChar *URI,

+		    int nb_namespaces,

+		    const xmlChar **namespaces,

+		    int nb_attributes,

+		    int nb_defaulted,

+		    const xmlChar **attributes)

+{

+    int i;

+

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.startElementNs(%s", (char *) localname);

+    if (prefix == NULL)

+	fprintf(SAXdebug, ", NULL");

+    else

+	fprintf(SAXdebug, ", %s", (char *) prefix);

+    if (URI == NULL)

+	fprintf(SAXdebug, ", NULL");

+    else

+	fprintf(SAXdebug, ", '%s'", (char *) URI);

+    fprintf(SAXdebug, ", %d", nb_namespaces);

+    

+    if (namespaces != NULL) {

+        for (i = 0;i < nb_namespaces * 2;i++) {

+	    fprintf(SAXdebug, ", xmlns");

+	    if (namespaces[i] != NULL)

+	        fprintf(SAXdebug, ":%s", namespaces[i]);

+	    i++;

+	    fprintf(SAXdebug, "='%s'", namespaces[i]);

+	}

+    }

+    fprintf(SAXdebug, ", %d, %d", nb_attributes, nb_defaulted);

+    if (attributes != NULL) {

+        for (i = 0;i < nb_attributes * 5;i += 5) {

+	    if (attributes[i + 1] != NULL)

+		fprintf(SAXdebug, ", %s:%s='", attributes[i + 1], attributes[i]);

+	    else

+		fprintf(SAXdebug, ", %s='", attributes[i]);

+	    fprintf(SAXdebug, "%.4s...', %d", attributes[i + 3],

+		    (int)(attributes[i + 4] - attributes[i + 3]));

+	}

+    }

+    fprintf(SAXdebug, ")\n");

+}

+

+/**

+ * endElementDebug:

+ * @ctxt:  An XML parser context

+ * @name:  The element name

+ *

+ * called when the end of an element has been detected.

+ */

+static void

+endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,

+                  const xmlChar *localname,

+                  const xmlChar *prefix,

+                  const xmlChar *URI)

+{

+    callbacks++;

+    if (quiet)

+	return;

+    fprintf(SAXdebug, "SAX.endElementNs(%s", (char *) localname);

+    if (prefix == NULL)

+	fprintf(SAXdebug, ", NULL");

+    else

+	fprintf(SAXdebug, ", %s", (char *) prefix);

+    if (URI == NULL)

+	fprintf(SAXdebug, ", NULL)\n");

+    else

+	fprintf(SAXdebug, ", '%s')\n", (char *) URI);

+}

+

+xmlSAXHandler debugSAX2HandlerStruct = {

+    internalSubsetDebug,

+    isStandaloneDebug,

+    hasInternalSubsetDebug,

+    hasExternalSubsetDebug,

+    resolveEntityDebug,

+    getEntityDebug,

+    entityDeclDebug,

+    notationDeclDebug,

+    attributeDeclDebug,

+    elementDeclDebug,

+    unparsedEntityDeclDebug,

+    setDocumentLocatorDebug,

+    startDocumentDebug,

+    endDocumentDebug,

+    NULL,

+    NULL,

+    referenceDebug,

+    charactersDebug,

+    ignorableWhitespaceDebug,

+    processingInstructionDebug,

+    commentDebug,

+    warningDebug,

+    errorDebug,

+    fatalErrorDebug,

+    getParameterEntityDebug,

+    cdataBlockDebug,

+    externalSubsetDebug,

+    XML_SAX2_MAGIC,

+    NULL,

+    startElementNsDebug,

+    endElementNsDebug,

+    NULL

+};

+

+xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;

+

+#ifdef LIBXML_HTML_ENABLED

+/**

+ * htmlstartElementDebug:

+ * @ctxt:  An XML parser context

+ * @name:  The element name

+ *

+ * called when an opening tag has been processed.

+ */

+static void

+htmlstartElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)

+{

+    int i;

+

+    fprintf(SAXdebug, "SAX.startElement(%s", (char *) name);

+    if (atts != NULL) {

+        for (i = 0;(atts[i] != NULL);i++) {

+	    fprintf(SAXdebug, ", %s", atts[i++]);

+	    if (atts[i] != NULL) {

+		unsigned char output[40];

+		const unsigned char *att = atts[i];

+		int outlen, attlen;

+	        fprintf(SAXdebug, "='");

+		while ((attlen = strlen((char*)att)) > 0) {

+		    outlen = sizeof output - 1;

+		    htmlEncodeEntities(output, &outlen, att, &attlen, '\'');

+		    output[outlen] = 0;

+		    fprintf(SAXdebug, "%s", (char *) output);

+		    att += attlen;

+		}

+		fprintf(SAXdebug, "'");

+	    }

+	}

+    }

+    fprintf(SAXdebug, ")\n");

+}

+

+/**

+ * htmlcharactersDebug:

+ * @ctxt:  An XML parser context

+ * @ch:  a xmlChar string

+ * @len: the number of xmlChar

+ *

+ * receiving some chars from the parser.

+ * Question: how much at a time ???

+ */

+static void

+htmlcharactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)

+{

+    unsigned char output[40];

+    int inlen = len, outlen = 30;

+

+    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);

+    output[outlen] = 0;

+

+    fprintf(SAXdebug, "SAX.characters(%s, %d)\n", output, len);

+}

+

+/**

+ * htmlcdataDebug:

+ * @ctxt:  An XML parser context

+ * @ch:  a xmlChar string

+ * @len: the number of xmlChar

+ *

+ * receiving some cdata chars from the parser.

+ * Question: how much at a time ???

+ */

+static void

+htmlcdataDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)

+{

+    unsigned char output[40];

+    int inlen = len, outlen = 30;

+

+    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);

+    output[outlen] = 0;

+

+    fprintf(SAXdebug, "SAX.cdata(%s, %d)\n", output, len);

+}

+

+xmlSAXHandler debugHTMLSAXHandlerStruct = {

+    internalSubsetDebug,

+    isStandaloneDebug,

+    hasInternalSubsetDebug,

+    hasExternalSubsetDebug,

+    resolveEntityDebug,

+    getEntityDebug,

+    entityDeclDebug,

+    notationDeclDebug,

+    attributeDeclDebug,

+    elementDeclDebug,

+    unparsedEntityDeclDebug,

+    setDocumentLocatorDebug,

+    startDocumentDebug,

+    endDocumentDebug,

+    htmlstartElementDebug,

+    endElementDebug,

+    referenceDebug,

+    htmlcharactersDebug,

+    ignorableWhitespaceDebug,

+    processingInstructionDebug,

+    commentDebug,

+    warningDebug,

+    errorDebug,

+    fatalErrorDebug,

+    getParameterEntityDebug,

+    htmlcdataDebug,

+    externalSubsetDebug,

+    1,

+    NULL,

+    NULL,

+    NULL,

+    NULL

+};

+

+xmlSAXHandlerPtr debugHTMLSAXHandler = &debugHTMLSAXHandlerStruct;

+#endif /* LIBXML_HTML_ENABLED */

+

+#ifdef LIBXML_SAX1_ENABLED

+/**

+ * saxParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file using the SAX API and check for errors.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+saxParseTest(const char *filename, const char *result,

+             const char *err ATTRIBUTE_UNUSED,

+             int options) {

+    int ret;

+    char *temp;

+

+    nb_tests++;

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "out of memory\n");

+        fatalError();

+    }

+    SAXdebug = fopen(temp, "wb");

+    if (SAXdebug == NULL) {

+        fprintf(stderr, "Failed to write to %s\n", temp);

+	free(temp);

+	return(-1);

+    }

+

+    /* for SAX we really want the callbacks though the context handlers */

+    xmlSetStructuredErrorFunc(NULL, NULL);

+    xmlSetGenericErrorFunc(NULL, testErrorHandler);

+

+#ifdef LIBXML_HTML_ENABLED

+    if (options & XML_PARSE_HTML) {

+	htmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);

+	ret = 0;

+    } else

+#endif

+    ret = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);

+    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);

+    }

+#ifdef LIBXML_HTML_ENABLED

+    if (options & XML_PARSE_HTML) {

+	htmlSAXParseFile(filename, NULL, debugHTMLSAXHandler, NULL);

+	ret = 0;

+    } else

+#endif

+    if (options & XML_PARSE_SAX1) {

+	ret = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);

+    } else {

+	ret = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);

+    }

+    if (ret == XML_WAR_UNDECLARED_ENTITY) {

+        fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);

+        ret = 0;

+    }

+    fclose(SAXdebug);

+    if (compareFiles(temp, result)) {

+        fprintf(stderr, "Got a difference for %s\n", filename);

+        ret = 1;

+    } else

+    unlink(temp);

+    free(temp);

+    

+    /* switch back to structured error handling */

+    xmlSetGenericErrorFunc(NULL, NULL);

+    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);

+

+    return(ret);

+}

+#endif

+

+/************************************************************************

+ *									*

+ *		Parse to tree based tests				*

+ *									*

+ ************************************************************************/

+/**

+ * oldParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages: unused

+ *

+ * Parse a file using the old xmlParseFile API, then serialize back

+ * reparse the result and serialize again, then check for deviation

+ * in serialization.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+oldParseTest(const char *filename, const char *result,

+             const char *err ATTRIBUTE_UNUSED,

+	     int options ATTRIBUTE_UNUSED) {

+    xmlDocPtr doc;

+    char *temp;

+    int res = 0;

+

+    nb_tests++;

+    /*

+     * base of the test, parse with the old API

+     */

+#ifdef LIBXML_SAX1_ENABLED

+    doc = xmlParseFile(filename);

+#else

+    doc = xmlReadFile(filename, NULL, 0);

+#endif

+    if (doc == NULL)

+        return(1);

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "out of memory\n");

+        fatalError();

+    }

+    xmlSaveFile(temp, doc);

+    if (compareFiles(temp, result)) {

+        res = 1;

+    }

+    xmlFreeDoc(doc);

+

+    /*

+     * Parse the saved result to make sure the round trip is okay

+     */

+#ifdef LIBXML_SAX1_ENABLED

+    doc = xmlParseFile(temp);

+#else

+    doc = xmlReadFile(temp, NULL, 0);

+#endif

+    if (doc == NULL)

+        return(1);

+    xmlSaveFile(temp, doc);

+    if (compareFiles(temp, result)) {

+        res = 1;

+    }

+    xmlFreeDoc(doc);

+

+    unlink(temp);

+    free(temp);

+    return(res);

+}

+

+#ifdef LIBXML_PUSH_ENABLED

+/**

+ * pushParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages: unused

+ *

+ * Parse a file using the Push API, then serialize back

+ * to check for content.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+pushParseTest(const char *filename, const char *result,

+             const char *err ATTRIBUTE_UNUSED,

+	     int options) {

+    xmlParserCtxtPtr ctxt;

+    xmlDocPtr doc;

+    const char *base;

+    int size, res;

+    int cur = 0;

+

+    nb_tests++;

+    /*

+     * load the document in memory and work from there.

+     */

+    if (loadMem(filename, &base, &size) != 0) {

+        fprintf(stderr, "Failed to load %s\n", filename);

+	return(-1);

+    }

+    

+#ifdef LIBXML_HTML_ENABLED

+    if (options & XML_PARSE_HTML)

+	ctxt = htmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename,

+	                                XML_CHAR_ENCODING_NONE);

+    else

+#endif

+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename);

+    xmlCtxtUseOptions(ctxt, options);

+    cur += 4;

+    while (cur < size) {

+        if (cur + 1024 >= size) {

+#ifdef LIBXML_HTML_ENABLED

+	    if (options & XML_PARSE_HTML)

+		htmlParseChunk(ctxt, base + cur, size - cur, 1);

+	    else

+#endif

+	    xmlParseChunk(ctxt, base + cur, size - cur, 1);

+	    break;

+	} else {

+#ifdef LIBXML_HTML_ENABLED

+	    if (options & XML_PARSE_HTML)

+		htmlParseChunk(ctxt, base + cur, 1024, 0);

+	    else

+#endif

+	    xmlParseChunk(ctxt, base + cur, 1024, 0);

+	    cur += 1024;

+	}

+    }

+    doc = ctxt->myDoc;

+#ifdef LIBXML_HTML_ENABLED

+    if (options & XML_PARSE_HTML)

+        res = 1;

+    else

+#endif

+    res = ctxt->wellFormed;

+    xmlFreeParserCtxt(ctxt);

+    free((char *)base);

+    if (!res) {

+	xmlFreeDoc(doc);

+	fprintf(stderr, "Failed to parse %s\n", filename);

+	return(-1);

+    }

+#ifdef LIBXML_HTML_ENABLED

+    if (options & XML_PARSE_HTML)

+	htmlDocDumpMemory(doc, (xmlChar **) &base, &size);

+    else

+#endif

+    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);

+    xmlFreeDoc(doc);

+    res = compareFileMem(result, base, size);

+    if ((base == NULL) || (res != 0)) {

+	if (base != NULL)

+	    xmlFree((char *)base);

+        fprintf(stderr, "Result for %s failed\n", filename);

+	return(-1);

+    }

+    xmlFree((char *)base);

+    if (err != NULL) {

+	res = compareFileMem(err, testErrors, testErrorsSize);

+	if (res != 0) {

+	    fprintf(stderr, "Error for %s failed\n", filename);

+	    return(-1);

+	}

+    }

+    return(0);

+}

+#endif

+

+/**

+ * memParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages: unused

+ *

+ * Parse a file using the old xmlReadMemory API, then serialize back

+ * reparse the result and serialize again, then check for deviation

+ * in serialization.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+memParseTest(const char *filename, const char *result,

+             const char *err ATTRIBUTE_UNUSED,

+	     int options ATTRIBUTE_UNUSED) {

+    xmlDocPtr doc;

+    const char *base;

+    int size, res;

+

+    nb_tests++;

+    /*

+     * load and parse the memory

+     */

+    if (loadMem(filename, &base, &size) != 0) {

+        fprintf(stderr, "Failed to load %s\n", filename);

+	return(-1);

+    }

+    

+    doc = xmlReadMemory(base, size, filename, NULL, 0);

+    unloadMem(base);

+    if (doc == NULL) {

+        return(1);

+    }

+    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);

+    xmlFreeDoc(doc);

+    res = compareFileMem(result, base, size);

+    if ((base == NULL) || (res != 0)) {

+	if (base != NULL)

+	    xmlFree((char *)base);

+        fprintf(stderr, "Result for %s failed\n", filename);

+	return(-1);

+    }

+    xmlFree((char *)base);

+    return(0);

+}

+

+/**

+ * noentParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages: unused

+ *

+ * Parse a file with entity resolution, then serialize back

+ * reparse the result and serialize again, then check for deviation

+ * in serialization.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+noentParseTest(const char *filename, const char *result,

+               const char *err  ATTRIBUTE_UNUSED,

+	       int options) {

+    xmlDocPtr doc;

+    char *temp;

+    int res = 0;

+

+    nb_tests++;

+    /*

+     * base of the test, parse with the old API

+     */

+    doc = xmlReadFile(filename, NULL, options);

+    if (doc == NULL)

+        return(1);

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    xmlSaveFile(temp, doc);

+    if (compareFiles(temp, result)) {

+        res = 1;

+    }

+    xmlFreeDoc(doc);

+

+    /*

+     * Parse the saved result to make sure the round trip is okay

+     */

+    doc = xmlReadFile(filename, NULL, options);

+    if (doc == NULL)

+        return(1);

+    xmlSaveFile(temp, doc);

+    if (compareFiles(temp, result)) {

+        res = 1;

+    }

+    xmlFreeDoc(doc);

+

+    unlink(temp);

+    free(temp);

+    return(res);

+}

+

+/**

+ * errParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file using the xmlReadFile API and check for errors.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+errParseTest(const char *filename, const char *result, const char *err,

+             int options) {

+    xmlDocPtr doc;

+    const char *base = NULL;

+    int size, res = 0;

+

+    nb_tests++;

+#ifdef LIBXML_HTML_ENABLED

+    if (options & XML_PARSE_HTML) {

+        doc = htmlReadFile(filename, NULL, options);

+    } else

+#endif

+#ifdef LIBXML_XINCLUDE_ENABLED

+    if (options & XML_PARSE_XINCLUDE) {

+	doc = xmlReadFile(filename, NULL, options);

+	xmlXIncludeProcessFlags(doc, options);

+    } else

+#endif

+    {

+	xmlGetWarningsDefaultValue = 1;

+	doc = xmlReadFile(filename, NULL, options);

+    }

+    xmlGetWarningsDefaultValue = 0;

+    if (result) {

+	if (doc == NULL) {

+	    base = "";

+	    size = 0;

+	} else {

+#ifdef LIBXML_HTML_ENABLED

+	    if (options & XML_PARSE_HTML) {

+		htmlDocDumpMemory(doc, (xmlChar **) &base, &size);

+	    } else

+#endif

+	    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);

+	}

+	res = compareFileMem(result, base, size);

+    }

+    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) {

+	    fprintf(stderr, "Error for %s failed\n", filename);

+	    return(-1);

+	}

+    } else if (options & XML_PARSE_DTDVALID) {

+        if (testErrorsSize != 0)

+	    fprintf(stderr, "Validation for %s failed\n", filename);

+    }

+

+    return(0);

+}

+

+#ifdef LIBXML_READER_ENABLED

+/************************************************************************

+ *									*

+ *		Reader based tests					*

+ *									*

+ ************************************************************************/

+

+static void processNode(FILE *out, xmlTextReaderPtr reader) {

+    const xmlChar *name, *value;

+    int type, empty;

+

+    type = xmlTextReaderNodeType(reader);

+    empty = xmlTextReaderIsEmptyElement(reader);

+

+    name = xmlTextReaderConstName(reader);

+    if (name == NULL)

+	name = BAD_CAST "--";

+

+    value = xmlTextReaderConstValue(reader);

+

+    

+    fprintf(out, "%d %d %s %d %d", 

+	    xmlTextReaderDepth(reader),

+	    type,

+	    name,

+	    empty,

+	    xmlTextReaderHasValue(reader));

+    if (value == NULL)

+	fprintf(out, "\n");

+    else {

+	fprintf(out, " %s\n", value);

+    }

+}

+static int

+streamProcessTest(const char *filename, const char *result, const char *err,

+                  xmlTextReaderPtr reader, const char *rng) {

+    int ret;

+    char *temp = NULL;

+    FILE *t = NULL;

+

+    if (reader == NULL)

+        return(-1);

+

+    nb_tests++;

+    if (result != NULL) {

+	temp = resultFilename(filename, "", ".res");

+	if (temp == NULL) {

+	    fprintf(stderr, "Out of memory\n");

+	    fatalError();

+	}

+	t = fopen(temp, "wb");

+	if (t == NULL) {

+	    fprintf(stderr, "Can't open temp file %s\n", temp);

+	    free(temp);

+	    return(-1);

+	}

+    }

+#ifdef LIBXML_SCHEMAS_ENABLED

+    if (rng != NULL) {

+	ret = xmlTextReaderRelaxNGValidate(reader, rng);

+	if (ret < 0) {

+	    testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n",

+	                     rng);

+	    fclose(t);

+	    unlink(temp);

+	    free(temp);

+	    return(0);

+	}

+    }

+#endif

+    xmlGetWarningsDefaultValue = 1;

+    ret = xmlTextReaderRead(reader);

+    while (ret == 1) {

+	if ((t != NULL) && (rng == NULL))

+	    processNode(t, reader);

+        ret = xmlTextReaderRead(reader);

+    }

+    if (ret != 0) {

+        testErrorHandler(NULL, "%s : failed to parse\n", filename);

+    }

+    if (rng != NULL) {

+        if (xmlTextReaderIsValid(reader) != 1) {

+	    testErrorHandler(NULL, "%s fails to validate\n", filename);

+	} else {

+	    testErrorHandler(NULL, "%s validates\n", filename);

+	}

+    }

+    xmlGetWarningsDefaultValue = 0;

+    if (t != NULL) {

+        fclose(t);

+	ret = compareFiles(temp, result);

+	unlink(temp);

+	free(temp);

+	if (ret) {

+	    fprintf(stderr, "Result for %s failed\n", filename);

+	    return(-1);

+	}

+    }

+    if (err != NULL) {

+	ret = compareFileMem(err, testErrors, testErrorsSize);

+	if (ret != 0) {

+	    fprintf(stderr, "Error for %s failed\n", filename);

+	    printf("%s", testErrors);

+	    return(-1);

+	}

+    }

+

+    return(0);

+}

+

+/**

+ * streamParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file using the reader API and check for errors.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+streamParseTest(const char *filename, const char *result, const char *err,

+                int options) {

+    xmlTextReaderPtr reader;

+    int ret;

+

+    reader = xmlReaderForFile(filename, NULL, options);

+    ret = streamProcessTest(filename, result, err, reader, NULL);

+    xmlFreeTextReader(reader);

+    return(ret);

+}

+

+/**

+ * walkerParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file using the walker, i.e. a reader built from a atree.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+walkerParseTest(const char *filename, const char *result, const char *err,

+                int options) {

+    xmlDocPtr doc;

+    xmlTextReaderPtr reader;

+    int ret;

+

+    doc = xmlReadFile(filename, NULL, options);

+    if (doc == NULL) {

+        fprintf(stderr, "Failed to parse %s\n", filename);

+	return(-1);

+    }

+    reader = xmlReaderWalker(doc);

+    ret = streamProcessTest(filename, result, err, reader, NULL);

+    xmlFreeTextReader(reader);

+    xmlFreeDoc(doc);

+    return(ret);

+}

+

+/**

+ * streamMemParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file using the reader API from memory and check for errors.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+streamMemParseTest(const char *filename, const char *result, const char *err,

+                   int options) {

+    xmlTextReaderPtr reader;

+    int ret;

+    const char *base;

+    int size;

+

+    /*

+     * load and parse the memory

+     */

+    if (loadMem(filename, &base, &size) != 0) {

+        fprintf(stderr, "Failed to load %s\n", filename);

+	return(-1);

+    }

+    reader = xmlReaderForMemory(base, size, filename, NULL, options);

+    ret = streamProcessTest(filename, result, err, reader, NULL);

+    free((char *)base);

+    xmlFreeTextReader(reader);

+    return(ret);

+}

+#endif

+

+#ifdef LIBXML_XPATH_ENABLED

+#ifdef LIBXML_DEBUG_ENABLED

+/************************************************************************

+ *									*

+ *		XPath and XPointer based tests				*

+ *									*

+ ************************************************************************/

+

+FILE *xpathOutput;

+xmlDocPtr xpathDocument;

+

+static void

+testXPath(const char *str, int xptr, int expr) {

+    xmlXPathObjectPtr res;

+    xmlXPathContextPtr ctxt;

+    

+    nb_tests++;

+#if defined(LIBXML_XPTR_ENABLED)

+    if (xptr) {

+	ctxt = xmlXPtrNewContext(xpathDocument, NULL, NULL);

+	res = xmlXPtrEval(BAD_CAST str, ctxt);

+    } else {

+#endif

+	ctxt = xmlXPathNewContext(xpathDocument);

+	ctxt->node = xmlDocGetRootElement(xpathDocument);

+	if (expr)

+	    res = xmlXPathEvalExpression(BAD_CAST str, ctxt);

+	else {

+	    /* res = xmlXPathEval(BAD_CAST str, ctxt); */

+	    xmlXPathCompExprPtr comp;

+

+	    comp = xmlXPathCompile(BAD_CAST str);

+	    if (comp != NULL) {

+		res = xmlXPathCompiledEval(comp, ctxt);

+		xmlXPathFreeCompExpr(comp);

+	    } else

+		res = NULL;

+	}

+#if defined(LIBXML_XPTR_ENABLED)

+    }

+#endif

+    xmlXPathDebugDumpObject(xpathOutput, res, 0);

+    xmlXPathFreeObject(res);

+    xmlXPathFreeContext(ctxt);

+}

+

+/**

+ * xpathExprTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing XPath standalone expressions and evaluate them

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+xpathCommonTest(const char *filename, const char *result,

+                int xptr, int expr) {

+    FILE *input;

+    char expression[5000];

+    int len, ret = 0;

+    char *temp;

+

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    xpathOutput = fopen(temp, "wb");

+    if (xpathOutput == NULL) {

+	fprintf(stderr, "failed to open output file %s\n", temp);

+        free(temp);

+	return(-1);

+    }

+

+    input = fopen(filename, "rb");

+    if (input == NULL) {

+        xmlGenericError(xmlGenericErrorContext,

+		"Cannot open %s for reading\n", filename);

+        free(temp);

+	return(-1);

+    }

+    while (fgets(expression, 4500, input) != NULL) {

+	len = strlen(expression);

+	len--;

+	while ((len >= 0) && 

+	       ((expression[len] == '\n') || (expression[len] == '\t') ||

+		(expression[len] == '\r') || (expression[len] == ' '))) len--;

+	expression[len + 1] = 0;      

+	if (len >= 0) {

+	    fprintf(xpathOutput,

+	            "\n========================\nExpression: %s\n",

+		    expression) ;

+	    testXPath(expression, xptr, expr);

+	}

+    }

+

+    fclose(input);

+    fclose(xpathOutput);

+    if (result != NULL) {

+	ret = compareFiles(temp, result);

+	if (ret) {

+	    fprintf(stderr, "Result for %s failed\n", filename);

+	}

+    }

+

+    unlink(temp);

+    free(temp);

+    return(ret);

+}

+

+/**

+ * xpathExprTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing XPath standalone expressions and evaluate them

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+xpathExprTest(const char *filename, const char *result,

+              const char *err ATTRIBUTE_UNUSED,

+              int options ATTRIBUTE_UNUSED) {

+    return(xpathCommonTest(filename, result, 0, 1));

+}

+

+/**

+ * xpathDocTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing XPath expressions and evaluate them against

+ * a set of corresponding documents.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+xpathDocTest(const char *filename,

+             const char *resul ATTRIBUTE_UNUSED,

+             const char *err ATTRIBUTE_UNUSED,

+             int options) {

+

+    char pattern[500];

+    char result[500];

+    glob_t globbuf;

+    size_t i;

+    int ret = 0, res;

+

+    xpathDocument = xmlReadFile(filename, NULL,

+                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);

+    if (xpathDocument == NULL) {

+        fprintf(stderr, "Failed to load %s\n", filename);

+	return(-1);

+    }

+

+    snprintf(pattern, 499, "./test/XPath/tests/%s*", baseFilename(filename));

+    pattern[499] = 0;

+    globbuf.gl_offs = 0;

+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);

+    for (i = 0;i < globbuf.gl_pathc;i++) {

+        snprintf(result, 499, "result/XPath/tests/%s",

+	         baseFilename(globbuf.gl_pathv[i]));

+	res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 0, 0);

+	if (res != 0)

+	    ret = res;

+    }

+    globfree(&globbuf);

+

+    xmlFreeDoc(xpathDocument);

+    return(ret);

+}

+

+#ifdef LIBXML_XPTR_ENABLED

+/**

+ * xptrDocTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing XPath expressions and evaluate them against

+ * a set of corresponding documents.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+xptrDocTest(const char *filename,

+            const char *resul ATTRIBUTE_UNUSED,

+            const char *err ATTRIBUTE_UNUSED,

+            int options) {

+

+    char pattern[500];

+    char result[500];

+    glob_t globbuf;

+    size_t i;

+    int ret = 0, res;

+

+    xpathDocument = xmlReadFile(filename, NULL,

+                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);

+    if (xpathDocument == NULL) {

+        fprintf(stderr, "Failed to load %s\n", filename);

+	return(-1);

+    }

+

+    snprintf(pattern, 499, "./test/XPath/xptr/%s*", baseFilename(filename));

+    pattern[499] = 0;

+    globbuf.gl_offs = 0;

+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);

+    for (i = 0;i < globbuf.gl_pathc;i++) {

+        snprintf(result, 499, "result/XPath/xptr/%s",

+	         baseFilename(globbuf.gl_pathv[i]));

+	res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 1, 0);

+	if (res != 0)

+	    ret = res;

+    }

+    globfree(&globbuf);

+

+    xmlFreeDoc(xpathDocument);

+    return(ret);

+}

+#endif /* LIBXML_XPTR_ENABLED */

+

+/**

+ * xmlidDocTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing xml:id and check for errors and verify

+ * that XPath queries will work on them as expected.

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+xmlidDocTest(const char *filename,

+             const char *result,

+             const char *err,

+             int options) {

+

+    int res = 0;

+    int ret = 0;

+    char *temp;

+

+    xpathDocument = xmlReadFile(filename, NULL,

+                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);

+    if (xpathDocument == NULL) {

+        fprintf(stderr, "Failed to load %s\n", filename);

+	return(-1);

+    }

+

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    xpathOutput = fopen(temp, "wb");

+    if (xpathOutput == NULL) {

+	fprintf(stderr, "failed to open output file %s\n", temp);

+        xmlFreeDoc(xpathDocument);

+        free(temp);

+	return(-1);

+    }

+

+    testXPath("id('bar')", 0, 0);

+

+    fclose(xpathOutput);

+    if (result != NULL) {

+	ret = compareFiles(temp, result);

+	if (ret) {

+	    fprintf(stderr, "Result for %s failed\n", filename);

+	    res = 1;

+	}

+    }

+

+    unlink(temp);

+    free(temp);

+    xmlFreeDoc(xpathDocument);

+

+    if (err != NULL) {

+	ret = compareFileMem(err, testErrors, testErrorsSize);

+	if (ret != 0) {

+	    fprintf(stderr, "Error for %s failed\n", filename);

+	    res = 1;

+	}

+    }

+    return(res);

+}

+

+#endif /* LIBXML_DEBUG_ENABLED */

+#endif /* XPATH */

+/************************************************************************

+ *									*

+ *			URI based tests					*

+ *									*

+ ************************************************************************/

+

+static void

+handleURI(const char *str, const char *base, FILE *o) {

+    int ret;

+    xmlURIPtr uri;

+    xmlChar *res = NULL, *parsed = NULL;

+

+    uri = xmlCreateURI();

+

+    if (base == NULL) {

+	ret = xmlParseURIReference(uri, str);

+	if (ret != 0)

+	    fprintf(o, "%s : error %d\n", str, ret);

+	else {

+	    xmlNormalizeURIPath(uri->path);

+	    xmlPrintURI(o, uri);

+	    fprintf(o, "\n");

+	}

+    } else {

+	res = xmlBuildURI((xmlChar *)str, (xmlChar *) base);

+	if (res != NULL) {

+	    fprintf(o, "%s\n", (char *) res);

+	}

+	else

+	    fprintf(o, "::ERROR::\n");

+    }

+    if (res != NULL)

+	xmlFree(res);

+    if (parsed != NULL)

+	xmlFree(parsed);

+    xmlFreeURI(uri);

+}

+

+/**

+ * uriCommonTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing URI and check for errors

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+uriCommonTest(const char *filename,

+             const char *result,

+             const char *err,

+             const char *base) {

+    char *temp;

+    FILE *o, *f;

+    char str[1024];

+    int res = 0, i, ret;

+

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    o = fopen(temp, "wb");

+    if (o == NULL) {

+	fprintf(stderr, "failed to open output file %s\n", temp);

+        free(temp);

+	return(-1);

+    }

+    f = fopen(filename, "rb");

+    if (f == NULL) {

+	fprintf(stderr, "failed to open input file %s\n", filename);

+	fclose(o);

+	unlink(temp);

+        free(temp);

+	return(-1);

+    }

+

+    while (1) {

+	/*

+	 * read one line in string buffer.

+	 */

+	if (fgets (&str[0], sizeof (str) - 1, f) == NULL)

+	   break;

+

+	/*

+	 * remove the ending spaces

+	 */

+	i = strlen(str);

+	while ((i > 0) &&

+	       ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||

+		(str[i - 1] == ' ') || (str[i - 1] == '\t'))) {

+	    i--;

+	    str[i] = 0;

+	}

+	nb_tests++;

+	handleURI(str, base, o);

+    }

+

+    fclose(f);

+    fclose(o);

+

+    if (result != NULL) {

+	ret = compareFiles(temp, result);

+	if (ret) {

+	    fprintf(stderr, "Result for %s failed\n", filename);

+	    res = 1;

+	}

+    }

+    if (err != NULL) {

+	ret = compareFileMem(err, testErrors, testErrorsSize);

+	if (ret != 0) {

+	    fprintf(stderr, "Error for %s failed\n", filename);

+	    res = 1;

+	}

+    }

+

+    unlink(temp);

+    free(temp);

+    return(res);

+}

+

+/**

+ * uriParseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing URI and check for errors

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+uriParseTest(const char *filename,

+             const char *result,

+             const char *err,

+             int options ATTRIBUTE_UNUSED) {

+    return(uriCommonTest(filename, result, err, NULL));

+}

+

+/**

+ * uriBaseTest:

+ * @filename: the file to parse

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing URI, compose them against a fixed base and

+ * check for errors

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+uriBaseTest(const char *filename,

+             const char *result,

+             const char *err,

+             int options ATTRIBUTE_UNUSED) {

+    return(uriCommonTest(filename, result, err,

+                         "http://foo.com/path/to/index.html?orig#help"));

+}

+

+#ifdef LIBXML_SCHEMAS_ENABLED

+/************************************************************************

+ *									*

+ *			Schemas tests					*

+ *									*

+ ************************************************************************/

+static int

+schemasOneTest(const char *sch,

+               const char *filename,

+               const char *result,

+	       const char *err,

+	       int options,

+	       xmlSchemaPtr schemas) {

+    xmlDocPtr doc;

+    xmlSchemaValidCtxtPtr ctxt;

+    int ret = 0;

+    char *temp;

+    FILE *schemasOutput;

+

+    doc = xmlReadFile(filename, NULL, options);

+    if (doc == NULL) {

+        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);

+	return(-1);

+    }

+

+    temp = resultFilename(result, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    schemasOutput = fopen(temp, "wb");

+    if (schemasOutput == NULL) {

+	fprintf(stderr, "failed to open output file %s\n", temp);

+	xmlFreeDoc(doc);

+        free(temp);

+	return(-1);

+    }

+

+    ctxt = xmlSchemaNewValidCtxt(schemas);

+    xmlSchemaSetValidErrors(ctxt,

+         (xmlSchemaValidityErrorFunc) testErrorHandler,

+         (xmlSchemaValidityWarningFunc) testErrorHandler,

+	 ctxt);

+    ret = xmlSchemaValidateDoc(ctxt, doc);

+    if (ret == 0) {

+	fprintf(schemasOutput, "%s validates\n", filename);

+    } else if (ret > 0) {

+	fprintf(schemasOutput, "%s fails to validate\n", filename);

+    } else {

+	fprintf(schemasOutput, "%s validation generated an internal error\n",

+	       filename);

+    }

+    fclose(schemasOutput);

+    if (result) {

+	if (compareFiles(temp, result)) {

+	    fprintf(stderr, "Result for %s on %s failed\n", filename, sch);

+	    ret = 1;

+	}

+    }

+    unlink(temp);

+    free(temp);

+

+    if (err != NULL) {

+	if (compareFileMem(err, testErrors, testErrorsSize)) {

+	    fprintf(stderr, "Error for %s on %s failed\n", filename, sch);

+	    ret = 1;

+	}

+    }

+

+

+    xmlSchemaFreeValidCtxt(ctxt);

+    xmlFreeDoc(doc);

+    return(ret);

+}

+/**

+ * schemasTest:

+ * @filename: the schemas file

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a file containing URI, compose them against a fixed base and

+ * check for errors

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+schemasTest(const char *filename,

+            const char *resul ATTRIBUTE_UNUSED,

+            const char *errr ATTRIBUTE_UNUSED,

+            int options) {

+    const char *base = baseFilename(filename);

+    const char *base2;

+    const char *instance;

+    xmlSchemaParserCtxtPtr ctxt;

+    xmlSchemaPtr schemas;

+    int res = 0, len, ret;

+    char pattern[500];

+    char prefix[500];

+    char result[500];

+    char err[500];

+    glob_t globbuf;

+    size_t i;

+    char count = 0;

+

+    /* first compile the schemas if possible */

+    ctxt = xmlSchemaNewParserCtxt(filename);

+    xmlSchemaSetParserErrors(ctxt,

+         (xmlSchemaValidityErrorFunc) testErrorHandler,

+         (xmlSchemaValidityWarningFunc) testErrorHandler,

+	 ctxt);

+    schemas = xmlSchemaParse(ctxt);

+    xmlSchemaFreeParserCtxt(ctxt);

+

+    /*

+     * most of the mess is about the output filenames generated by the Makefile

+     */

+    len = strlen(base);

+    if ((len > 499) || (len < 5)) {

+        xmlSchemaFree(schemas);

+	return(-1);

+    }

+    len -= 4; /* remove trailing .xsd */

+    if (base[len - 2] == '_') {

+        len -= 2; /* remove subtest number */

+    }

+    if (base[len - 2] == '_') {

+        len -= 2; /* remove subtest number */

+    }

+    memcpy(prefix, base, len);

+    prefix[len] = 0;

+

+    snprintf(pattern, 499, "./test/schemas/%s_?.xml", prefix);

+    pattern[499] = 0;

+

+    if (base[len] == '_') {

+        len += 2;

+	memcpy(prefix, base, len);

+	prefix[len] = 0;

+    }

+

+    globbuf.gl_offs = 0;

+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);

+    for (i = 0;i < globbuf.gl_pathc;i++) {

+        testErrorsSize = 0;

+	testErrors[0] = 0;

+        instance = globbuf.gl_pathv[i];

+	base2 = baseFilename(instance);

+	len = strlen(base2);

+	if ((len > 6) && (base2[len - 6] == '_')) {

+	    count = base2[len - 5];

+	    snprintf(result, 499, "result/schemas/%s_%c",

+		     prefix, count);

+	    result[499] = 0;

+	    snprintf(err, 499, "result/schemas/%s_%c.err",

+		     prefix, count);

+	    err[499] = 0;

+	} else {

+	    fprintf(stderr, "don't know how to process %s\n", instance);

+	    continue;

+	}

+	if (schemas == NULL) {

+	} else {

+	    nb_tests++;

+	    ret = schemasOneTest(filename, instance, result, err,

+	                         options, schemas);

+	    if (res != 0)

+		ret = res;

+	}

+    }

+    globfree(&globbuf);

+    xmlSchemaFree(schemas);

+

+    return(res);

+}

+

+/************************************************************************

+ *									*

+ *			Schemas tests					*

+ *									*

+ ************************************************************************/

+static int

+rngOneTest(const char *sch,

+               const char *filename,

+               const char *result,

+	       const char *err,

+	       int options,

+	       xmlRelaxNGPtr schemas) {

+    xmlDocPtr doc;

+    xmlRelaxNGValidCtxtPtr ctxt;

+    int ret = 0;

+    char *temp;

+    FILE *schemasOutput;

+

+    doc = xmlReadFile(filename, NULL, options);

+    if (doc == NULL) {

+        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);

+	return(-1);

+    }

+

+    temp = resultFilename(result, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    schemasOutput = fopen(temp, "wb");

+    if (schemasOutput == NULL) {

+	fprintf(stderr, "failed to open output file %s\n", temp);

+	xmlFreeDoc(doc);

+        free(temp);

+	return(-1);

+    }

+

+    ctxt = xmlRelaxNGNewValidCtxt(schemas);

+    xmlRelaxNGSetValidErrors(ctxt,

+         (xmlRelaxNGValidityErrorFunc) testErrorHandler,

+         (xmlRelaxNGValidityWarningFunc) testErrorHandler,

+	 ctxt);

+    ret = xmlRelaxNGValidateDoc(ctxt, doc);

+    if (ret == 0) {

+	testErrorHandler(NULL, "%s validates\n", filename);

+    } else if (ret > 0) {

+	testErrorHandler(NULL, "%s fails to validate\n", filename);

+    } else {

+	testErrorHandler(NULL, "%s validation generated an internal error\n",

+	       filename);

+    }

+    fclose(schemasOutput);

+    if (result) {

+	if (compareFiles(temp, result)) {

+	    fprintf(stderr, "Result for %s on %s failed\n", filename, sch);

+	    ret = 1;

+	}

+    }

+    unlink(temp);

+    free(temp);

+

+    if (err != NULL) {

+	if (compareFileMem(err, testErrors, testErrorsSize)) {

+	    fprintf(stderr, "Error for %s on %s failed\n", filename, sch);

+	    ret = 1;

+	    printf("%s", testErrors);

+	}

+    }

+

+

+    xmlRelaxNGFreeValidCtxt(ctxt);

+    xmlFreeDoc(doc);

+    return(ret);

+}

+/**

+ * rngTest:

+ * @filename: the schemas file

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse an RNG schemas and then apply it to the related .xml

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+rngTest(const char *filename,

+            const char *resul ATTRIBUTE_UNUSED,

+            const char *errr ATTRIBUTE_UNUSED,

+            int options) {

+    const char *base = baseFilename(filename);

+    const char *base2;

+    const char *instance;

+    xmlRelaxNGParserCtxtPtr ctxt;

+    xmlRelaxNGPtr schemas;

+    int res = 0, len, ret;

+    char pattern[500];

+    char prefix[500];

+    char result[500];

+    char err[500];

+    glob_t globbuf;

+    size_t i;

+    char count = 0;

+

+    /* first compile the schemas if possible */

+    ctxt = xmlRelaxNGNewParserCtxt(filename);

+    xmlRelaxNGSetParserErrors(ctxt,

+         (xmlRelaxNGValidityErrorFunc) testErrorHandler,

+         (xmlRelaxNGValidityWarningFunc) testErrorHandler,

+	 ctxt);

+    schemas = xmlRelaxNGParse(ctxt);

+    xmlRelaxNGFreeParserCtxt(ctxt);

+

+    /*

+     * most of the mess is about the output filenames generated by the Makefile

+     */

+    len = strlen(base);

+    if ((len > 499) || (len < 5)) {

+        xmlRelaxNGFree(schemas);

+	return(-1);

+    }

+    len -= 4; /* remove trailing .rng */

+    memcpy(prefix, base, len);

+    prefix[len] = 0;

+

+    snprintf(pattern, 499, "./test/relaxng/%s_?.xml", prefix);

+    pattern[499] = 0;

+

+    globbuf.gl_offs = 0;

+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);

+    for (i = 0;i < globbuf.gl_pathc;i++) {

+        testErrorsSize = 0;

+	testErrors[0] = 0;

+        instance = globbuf.gl_pathv[i];

+	base2 = baseFilename(instance);

+	len = strlen(base2);

+	if ((len > 6) && (base2[len - 6] == '_')) {

+	    count = base2[len - 5];

+	    snprintf(result, 499, "result/relaxng/%s_%c",

+		     prefix, count);

+	    result[499] = 0;

+	    snprintf(err, 499, "result/relaxng/%s_%c.err",

+		     prefix, count);

+	    err[499] = 0;

+	} else {

+	    fprintf(stderr, "don't know how to process %s\n", instance);

+	    continue;

+	}

+	if (schemas == NULL) {

+	} else {

+	    nb_tests++;

+	    ret = rngOneTest(filename, instance, result, err,

+	                         options, schemas);

+	    if (res != 0)

+		ret = res;

+	}

+    }

+    globfree(&globbuf);

+    xmlRelaxNGFree(schemas);

+

+    return(res);

+}

+

+#ifdef LIBXML_READER_ENABLED

+/**

+ * rngStreamTest:

+ * @filename: the schemas file

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a set of files with streaming, applying an RNG schemas 

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+rngStreamTest(const char *filename,

+            const char *resul ATTRIBUTE_UNUSED,

+            const char *errr ATTRIBUTE_UNUSED,

+            int options) {

+    const char *base = baseFilename(filename);

+    const char *base2;

+    const char *instance;

+    int res = 0, len, ret;

+    char pattern[500];

+    char prefix[500];

+    char result[500];

+    char err[500];

+    glob_t globbuf;

+    size_t i;

+    char count = 0;

+    xmlTextReaderPtr reader;

+    int disable_err = 0;

+

+    /*

+     * most of the mess is about the output filenames generated by the Makefile

+     */

+    len = strlen(base);

+    if ((len > 499) || (len < 5)) {

+	fprintf(stderr, "len(base) == %d !\n", len);

+	return(-1);

+    }

+    len -= 4; /* remove trailing .rng */

+    memcpy(prefix, base, len);

+    prefix[len] = 0;

+

+    /*

+     * strictly unifying the error messages is nearly impossible this

+     * hack is also done in the Makefile

+     */

+    if ((!strcmp(prefix, "tutor10_1")) || (!strcmp(prefix, "tutor10_2")) ||

+        (!strcmp(prefix, "tutor3_2"))) 

+	disable_err = 1;

+

+    snprintf(pattern, 499, "./test/relaxng/%s_?.xml", prefix);

+    pattern[499] = 0;

+

+    globbuf.gl_offs = 0;

+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);

+    for (i = 0;i < globbuf.gl_pathc;i++) {

+        testErrorsSize = 0;

+	testErrors[0] = 0;

+        instance = globbuf.gl_pathv[i];

+	base2 = baseFilename(instance);

+	len = strlen(base2);

+	if ((len > 6) && (base2[len - 6] == '_')) {

+	    count = base2[len - 5];

+	    snprintf(result, 499, "result/relaxng/%s_%c",

+		     prefix, count);

+	    result[499] = 0;

+	    snprintf(err, 499, "result/relaxng/%s_%c.err",

+		     prefix, count);

+	    err[499] = 0;

+	} else {

+	    fprintf(stderr, "don't know how to process %s\n", instance);

+	    continue;

+	}

+	reader = xmlReaderForFile(instance, NULL, options);

+	if (reader == NULL) {

+	    fprintf(stderr, "Failed to build reder for %s\n", instance);

+	}

+	if (disable_err == 1)

+	    ret = streamProcessTest(instance, result, NULL, reader, filename);

+	else

+	    ret = streamProcessTest(instance, result, err, reader, filename);

+	xmlFreeTextReader(reader);

+	if (ret != 0) {

+	    fprintf(stderr, "instance %s failed\n", instance);

+	    res = ret;

+	}

+    }

+    globfree(&globbuf);

+

+    return(res);

+}

+#endif /* READER */

+

+#endif

+

+#ifdef LIBXML_PATTERN_ENABLED

+#ifdef LIBXML_READER_ENABLED

+/************************************************************************

+ *									*

+ *			Patterns tests					*

+ *									*

+ ************************************************************************/

+static void patternNode(FILE *out, xmlTextReaderPtr reader,

+                        const char *pattern, xmlPatternPtr patternc,

+			xmlStreamCtxtPtr patstream) {

+    xmlChar *path = NULL;

+    int match = -1;

+    int type, empty;

+

+    type = xmlTextReaderNodeType(reader);

+    empty = xmlTextReaderIsEmptyElement(reader);

+	

+    if (type == XML_READER_TYPE_ELEMENT) {

+	/* do the check only on element start */

+	match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));

+

+	if (match) {

+	    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));

+	    fprintf(out, "Node %s matches pattern %s\n", path, pattern);

+	}

+    }

+    if (patstream != NULL) {

+	int ret;

+

+	if (type == XML_READER_TYPE_ELEMENT) {

+	    ret = xmlStreamPush(patstream,

+				xmlTextReaderConstLocalName(reader),

+				xmlTextReaderConstNamespaceUri(reader));

+	    if (ret < 0) {

+		fprintf(out, "xmlStreamPush() failure\n");

+		xmlFreeStreamCtxt(patstream);

+		patstream = NULL;

+	    } else if (ret != match) {

+		if (path == NULL) {

+		    path = xmlGetNodePath(

+				   xmlTextReaderCurrentNode(reader));

+		}

+		fprintf(out,

+			"xmlPatternMatch and xmlStreamPush disagree\n");

+		fprintf(out,

+			"  pattern %s node %s\n",

+			pattern, path);

+	    }

+	    

+

+	} 

+	if ((type == XML_READER_TYPE_END_ELEMENT) ||

+	    ((type == XML_READER_TYPE_ELEMENT) && (empty))) {

+	    ret = xmlStreamPop(patstream);

+	    if (ret < 0) {

+		fprintf(out, "xmlStreamPop() failure\n");

+		xmlFreeStreamCtxt(patstream);

+		patstream = NULL;

+	    }

+	}

+    }

+    if (path != NULL)

+	xmlFree(path);

+}

+

+/**

+ * patternTest:

+ * @filename: the schemas file

+ * @result: the file with expected result

+ * @err: the file with error messages

+ *

+ * Parse a set of files with streaming, applying an RNG schemas 

+ *

+ * Returns 0 in case of success, an error code otherwise

+ */

+static int

+patternTest(const char *filename,

+            const char *resul ATTRIBUTE_UNUSED,

+            const char *err ATTRIBUTE_UNUSED,

+            int options) {

+    xmlPatternPtr patternc = NULL;

+    xmlStreamCtxtPtr patstream = NULL;

+    FILE *o, *f;

+    char str[1024];

+    char xml[500];

+    char result[500];

+    int len, i;

+    int ret = 0, res;

+    char *temp;

+    xmlTextReaderPtr reader;

+    xmlDocPtr doc;

+

+    len = strlen(filename);

+    len -= 4;

+    memcpy(xml, filename, len);

+    xml[len] = 0;

+    snprintf(result, 499, "result/pattern/%s", baseFilename(xml));

+    result[499] = 0;

+    memcpy(xml + len, ".xml", 5);

+

+    if (!checkTestFile(xml)) {

+	fprintf(stderr, "Missing xml file %s\n", xml);

+	return(-1);

+    }

+    if (!checkTestFile(result)) {

+	fprintf(stderr, "Missing result file %s\n", result);

+	return(-1);

+    }

+    f = fopen(filename, "rb");

+    if (f == NULL) {

+        fprintf(stderr, "Failed to open %s\n", filename);

+	return(-1);

+    }

+    temp = resultFilename(filename, "", ".res");

+    if (temp == NULL) {

+        fprintf(stderr, "Out of memory\n");

+        fatalError();

+    }

+    o = fopen(temp, "wb");

+    if (o == NULL) {

+	fprintf(stderr, "failed to open output file %s\n", temp);

+	fclose(f);

+        free(temp);

+	return(-1);

+    }

+    while (1) {

+	/*

+	 * read one line in string buffer.

+	 */

+	if (fgets (&str[0], sizeof (str) - 1, f) == NULL)

+	   break;

+

+	/*

+	 * remove the ending spaces

+	 */

+	i = strlen(str);

+	while ((i > 0) &&

+	       ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||

+		(str[i - 1] == ' ') || (str[i - 1] == '\t'))) {

+	    i--;

+	    str[i] = 0;

+	}

+	doc = xmlReadFile(xml, NULL, options);

+	if (doc == NULL) {

+	    fprintf(stderr, "Failed to parse %s\n", xml);

+	    ret = 1;

+	} else {

+	    xmlNodePtr root;

+	    const xmlChar *namespaces[22];

+	    int j;

+	    xmlNsPtr ns;

+

+	    root = xmlDocGetRootElement(doc);

+	    for (ns = root->nsDef, j = 0;ns != NULL && j < 20;ns=ns->next) {

+		namespaces[j++] = ns->href;

+		namespaces[j++] = ns->prefix;

+	    }

+	    namespaces[j++] = NULL;

+	    namespaces[j++] = NULL;

+

+	    patternc = xmlPatterncompile((const xmlChar *) str, doc->dict,

+					 0, &namespaces[0]);

+	    if (patternc == NULL) {

+		testErrorHandler(NULL,

+			"Pattern %s failed to compile\n", str);

+		xmlFreeDoc(doc);

+		ret = 1;

+		continue;

+	    }

+	    patstream = xmlPatternGetStreamCtxt(patternc);

+	    if (patstream != NULL) {

+		ret = xmlStreamPush(patstream, NULL, NULL);

+		if (ret < 0) {

+		    fprintf(stderr, "xmlStreamPush() failure\n");

+		    xmlFreeStreamCtxt(patstream);

+		    patstream = NULL;

+		}

+	    }

+	    nb_tests++;

+

+	    reader = xmlReaderWalker(doc);

+	    res = xmlTextReaderRead(reader);

+	    while (res == 1) {

+		patternNode(o, reader, str, patternc, patstream);

+		res = xmlTextReaderRead(reader);

+	    }

+	    if (res != 0) {

+		fprintf(o, "%s : failed to parse\n", filename);

+	    }

+	    xmlFreeTextReader(reader);

+	    xmlFreeDoc(doc);

+	    xmlFreeStreamCtxt(patstream);

+	    patstream = NULL;

+	    xmlFreePattern(patternc);

+

+	}

+    }

+

+    fclose(f);

+    fclose(o);

+

+    ret = compareFiles(temp, result);

+    if (ret) {

+	fprintf(stderr, "Result for %s failed\n", filename);

+	ret = 1;

+    }

+    unlink(temp);

+    free(temp);

+    return(ret);

+}

+#endif /* READER */

+#endif /* PATTERN */

+#ifdef LIBXML_C14N_ENABLED

+/************************************************************************

+ *									*

+ *			Canonicalization tests				*

+ *									*

+ ************************************************************************/

+static xmlXPathObjectPtr

+load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {

+    xmlXPathObjectPtr xpath; 

+    xmlDocPtr doc;

+    xmlChar *expr;

+    xmlXPathContextPtr ctx; 

+    xmlNodePtr node;

+    xmlNsPtr ns;

+    

+    /*

+     * load XPath expr as a file

+     */

+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;

+    xmlSubstituteEntitiesDefault(1);

+

+    doc = xmlParseFile(filename);

+    if (doc == NULL) {

+	fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);

+	return(NULL);

+    }

+    

+    /*

+     * Check the document is of the right kind

+     */    

+    if(xmlDocGetRootElement(doc) == NULL) {

+        fprintf(stderr,"Error: empty document for file \"%s\"\n", filename);

+	xmlFreeDoc(doc);

+	return(NULL);

+    }

+

+    node = doc->children;

+    while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) {

+	node = node->next;

+    }

+    

+    if(node == NULL) {   

+        fprintf(stderr,"Error: XPath element expected in the file  \"%s\"\n", filename);

+	xmlFreeDoc(doc);

+	return(NULL);

+    }

+

+    expr = xmlNodeGetContent(node);

+    if(expr == NULL) {

+        fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename);

+	xmlFreeDoc(doc);

+	return(NULL);

+    }

+

+    ctx = xmlXPathNewContext(parent_doc);

+    if(ctx == NULL) {

+        fprintf(stderr,"Error: unable to create new context\n");

+        xmlFree(expr); 

+        xmlFreeDoc(doc); 

+        return(NULL);

+    }

+

+    /*

+     * Register namespaces

+     */

+    ns = node->nsDef;

+    while(ns != NULL) {

+	if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) {

+	    fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href);

+    	    xmlFree(expr); 

+	    xmlXPathFreeContext(ctx); 

+	    xmlFreeDoc(doc); 

+	    return(NULL);

+	}

+	ns = ns->next;

+    }

+

+    /*  

+     * Evaluate xpath

+     */

+    xpath = xmlXPathEvalExpression(expr, ctx);

+    if(xpath == NULL) {

+        fprintf(stderr,"Error: unable to evaluate xpath expression\n");

+    	xmlFree(expr); 

+        xmlXPathFreeContext(ctx); 

+        xmlFreeDoc(doc); 

+        return(NULL);

+    }

+

+    /* print_xpath_nodes(xpath->nodesetval); */

+

+    xmlFree(expr); 

+    xmlXPathFreeContext(ctx); 

+    xmlFreeDoc(doc); 

+    return(xpath);

+}

+

+/*

+ * Macro used to grow the current buffer.

+ */

+#define xxx_growBufferReentrant() {						\

+    buffer_size *= 2;							\

+    buffer = (xmlChar **)						\

+    		xmlRealloc(buffer, buffer_size * sizeof(xmlChar*));	\

+    if (buffer == NULL) {						\

+	perror("realloc failed");					\

+	return(NULL);							\

+    }									\

+}

+

+static xmlChar **

+parse_list(xmlChar *str) {

+    xmlChar **buffer;

+    xmlChar **out = NULL;

+    int buffer_size = 0;

+    int len;

+

+    if(str == NULL) {

+	return(NULL);

+    }

+

+    len = xmlStrlen(str);

+    if((str[0] == '\'') && (str[len - 1] == '\'')) {

+	str[len - 1] = '\0';

+	str++;

+	len -= 2;

+    }

+    /*

+     * allocate an translation buffer.

+     */

+    buffer_size = 1000;

+    buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*));

+    if (buffer == NULL) {

+	perror("malloc failed");

+	return(NULL);

+    }

+    out = buffer;

+    

+    while(*str != '\0') {

+	if (out - buffer > buffer_size - 10) {

+	    int indx = out - buffer;

+

+	    xxx_growBufferReentrant();

+	    out = &buffer[indx];

+	}

+	(*out++) = str;

+	while(*str != ',' && *str != '\0') ++str;

+	if(*str == ',') *(str++) = '\0';

+    }

+    (*out) = NULL;

+    return buffer;

+}

+

+static int 

+c14nRunTest(const char* xml_filename, int with_comments, int exclusive,

+	    const char* xpath_filename, const char *ns_filename,

+	    const char* result_file) {

+    xmlDocPtr doc;

+    xmlXPathObjectPtr xpath = NULL; 

+    xmlChar *result = NULL;

+    int ret;

+    xmlChar **inclusive_namespaces = NULL;

+    const char *nslist = NULL;

+    int nssize;

+

+

+    /*

+     * build an XML tree from a the file; we need to add default

+     * attributes and resolve all character and entities references

+     */

+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;

+    xmlSubstituteEntitiesDefault(1);

+

+    doc = xmlParseFile(xml_filename);

+    if (doc == NULL) {

+	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);

+	return(-1);

+    }

+    

+    /*

+     * Check the document is of the right kind

+     */    

+    if(xmlDocGetRootElement(doc) == NULL) {

+        fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename);

+	xmlFreeDoc(doc);

+	return(-1);

+    }

+

+    /* 

+     * load xpath file if specified 

+     */

+    if(xpath_filename) {

+	xpath = load_xpath_expr(doc, xpath_filename);

+	if(xpath == NULL) {

+	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");

+	    xmlFreeDoc(doc); 

+	    return(-1);

+	}

+    }

+

+    if (ns_filename != NULL) {

+        if (loadMem(ns_filename, &nslist, &nssize)) {

+	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");

+	    if(xpath != NULL) xmlXPathFreeObject(xpath);

+	    xmlFreeDoc(doc); 

+	    return(-1);

+	}

+        inclusive_namespaces = parse_list((xmlChar *) nslist);

+    }

+

+    /*

+     * Canonical form

+     */      

+    /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */

+    ret = xmlC14NDocDumpMemory(doc, 

+	    (xpath) ? xpath->nodesetval : NULL, 

+	    exclusive, inclusive_namespaces,

+	    with_comments, &result);

+    if (ret >= 0) {

+	if(result != NULL) {

+	    if (compareFileMem(result_file, (const char *) result, ret)) {

+		fprintf(stderr, "Result mismatch for %s\n", xml_filename);

+	        ret = -1;

+	    }

+	}

+    } else {

+	fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret);

+	ret = -1;

+    }

+        

+    /*

+     * Cleanup

+     */ 

+    if (result != NULL) xmlFree(result);

+    if(xpath != NULL) xmlXPathFreeObject(xpath);

+    if (inclusive_namespaces != NULL) xmlFree(inclusive_namespaces);

+    if (nslist != NULL) free((char *) nslist);

+    xmlFreeDoc(doc);    

+

+    return(ret);

+}

+

+static int

+c14nCommonTest(const char *filename, int with_comments, int exclusive,

+               const char *subdir) {

+    char buf[500];

+    char prefix[500];

+    const char *base;

+    int len;

+    char *result = NULL;

+    char *xpath = NULL;

+    char *ns = NULL;

+    int ret = 0;

+

+    base = baseFilename(filename);

+    len = strlen(base);

+    len -= 4;

+    memcpy(prefix, base, len);

+    prefix[len] = 0;

+

+    snprintf(buf, 499, "result/c14n/%s/%s", subdir,prefix);

+    if (!checkTestFile(buf)) {

+        fprintf(stderr, "Missing result file %s", buf);

+	return(-1);

+    }

+    result = strdup(buf);

+    snprintf(buf, 499, "test/c14n/%s/%s.xpath", subdir,prefix);

+    if (checkTestFile(buf)) {

+	xpath = strdup(buf);

+    }

+    snprintf(buf, 499, "test/c14n/%s/%s.ns", subdir,prefix);

+    if (checkTestFile(buf)) {

+	ns = strdup(buf);

+    }

+

+    nb_tests++;

+    if (c14nRunTest(filename, with_comments, exclusive,

+                    xpath, ns, result) < 0)

+        ret = 1;

+

+    if (result != NULL) free(result);

+    if (xpath != NULL) free(xpath);

+    if (ns != NULL) free(ns);

+    return(ret);

+}

+

+static int

+c14nWithCommentTest(const char *filename,

+                    const char *resul ATTRIBUTE_UNUSED,

+		    const char *err ATTRIBUTE_UNUSED,

+		    int options ATTRIBUTE_UNUSED) {

+    return(c14nCommonTest(filename, 1, 0, "with-comments"));

+}

+static int

+c14nWithoutCommentTest(const char *filename,

+                    const char *resul ATTRIBUTE_UNUSED,

+		    const char *err ATTRIBUTE_UNUSED,

+		    int options ATTRIBUTE_UNUSED) {

+    return(c14nCommonTest(filename, 0, 0, "without-comments"));

+}

+static int

+c14nExcWithoutCommentTest(const char *filename,

+                    const char *resul ATTRIBUTE_UNUSED,

+		    const char *err ATTRIBUTE_UNUSED,

+		    int options ATTRIBUTE_UNUSED) {

+    return(c14nCommonTest(filename, 0, 1, "exc-without-comments"));

+}

+#endif

+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)

+/************************************************************************

+ *									*

+ *			Catalog and threads test			*

+ *									*

+ ************************************************************************/

+

+/*

+ * mostly a cut and paste from testThreads.c

+ */

+#define	MAX_ARGC	20

+

+static const char *catalog = "test/threads/complex.xml";

+static const char *testfiles[] = {

+    "test/threads/abc.xml",

+    "test/threads/acb.xml",

+    "test/threads/bac.xml",

+    "test/threads/bca.xml",

+    "test/threads/cab.xml",

+    "test/threads/cba.xml",

+    "test/threads/invalid.xml",

+};

+

+const char *Okay = "OK";

+const char *Failed = "Failed";

+

+#ifndef xmlDoValidityCheckingDefaultValue

+#error xmlDoValidityCheckingDefaultValue is not a macro

+#endif

+#ifndef xmlGenericErrorContext

+#error xmlGenericErrorContext is not a macro

+#endif

+

+static void *

+thread_specific_data(void *private_data)

+{

+    xmlDocPtr myDoc;

+    const char *filename = (const char *) private_data;

+    int okay = 1;

+

+    if (!strcmp(filename, "test/threads/invalid.xml")) {

+        xmlDoValidityCheckingDefaultValue = 0;

+        xmlGenericErrorContext = stdout;

+    } else {

+        xmlDoValidityCheckingDefaultValue = 1;

+        xmlGenericErrorContext = stderr;

+    }

+    myDoc = xmlParseFile(filename);

+    if (myDoc) {

+        xmlFreeDoc(myDoc);

+    } else {

+        printf("parse failed\n");

+        okay = 0;

+    }

+    if (!strcmp(filename, "test/threads/invalid.xml")) {

+        if (xmlDoValidityCheckingDefaultValue != 0) {

+            printf("ValidityCheckingDefaultValue override failed\n");

+            okay = 0;

+        }

+        if (xmlGenericErrorContext != stdout) {

+            printf("xmlGenericErrorContext override failed\n");

+            okay = 0;

+        }

+    } else {

+        if (xmlDoValidityCheckingDefaultValue != 1) {

+            printf("ValidityCheckingDefaultValue override failed\n");

+            okay = 0;

+        }

+        if (xmlGenericErrorContext != stderr) {

+            printf("xmlGenericErrorContext override failed\n");

+            okay = 0;

+        }

+    }

+    if (okay == 0)

+        return ((void *) Failed);

+    return ((void *) Okay);

+}

+

+#if defined(linux) || defined(solaris)

+

+#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

+#include <windows.h>

+#include <string.h>

+

+#define TEST_REPEAT_COUNT 500

+

+static HANDLE tid[MAX_ARGC];

+

+static DWORD WINAPI

+win32_thread_specific_data(void *private_data)

+{

+    return((DWORD) thread_specific_data(private_data));

+}

+

+static int

+testThread(void)

+{

+    unsigned int i, repeat;

+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);

+    DWORD results[MAX_ARGC];

+    BOOL ret;

+    int res = 0;

+

+    xmlInitParser();

+    for (repeat = 0; repeat < TEST_REPEAT_COUNT; repeat++) {

+        xmlLoadCatalog(catalog);

+        nb_tests++;

+

+        for (i = 0; i < num_threads; i++) {

+            results[i] = 0;

+            tid[i] = (HANDLE) - 1;

+        }

+

+        for (i = 0; i < num_threads; i++) {

+            DWORD useless;

+

+            tid[i] = CreateThread(NULL, 0,

+                                  win32_thread_specific_data, 

+				  (void *) testfiles[i], 0,

+                                  &useless);

+            if (tid[i] == NULL) {

+                fprintf(stderr, "CreateThread failed\n");

+                return(1);

+            }

+        }

+

+        if (WaitForMultipleObjects(num_threads, tid, TRUE, INFINITE) ==

+            WAIT_FAILED) {

+            fprintf(stderr, "WaitForMultipleObjects failed\n");

+	    return(1);

+	}

+

+        for (i = 0; i < num_threads; i++) {

+            ret = GetExitCodeThread(tid[i], &results[i]);

+            if (ret == 0) {

+                fprintf(stderr, "GetExitCodeThread failed\n");

+                return(1);

+            }

+            CloseHandle(tid[i]);

+        }

+

+        xmlCatalogCleanup();

+        for (i = 0; i < num_threads; i++) {

+            if (results[i] != (DWORD) Okay) {

+                fprintf(stderr, "Thread %d handling %s failed\n",

+		        i, testfiles[i]);

+	        res = 1;

+	    }

+        }

+    }

+

+    return (res);

+}

+

+#elif defined __BEOS__

+#include <OS.h>

+

+static thread_id tid[MAX_ARGC];

+

+static int

+testThread(void)

+{

+    unsigned int i, repeat;

+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);

+    void *results[MAX_ARGC];

+    status_t ret;

+    int res = 0;

+

+    xmlInitParser();

+    for (repeat = 0; repeat < 500; repeat++) {

+        xmlLoadCatalog(catalog);

+        for (i = 0; i < num_threads; i++) {

+            results[i] = NULL;

+            tid[i] = (thread_id) - 1;

+        }

+        for (i = 0; i < num_threads; i++) {

+            tid[i] =

+                spawn_thread(thread_specific_data, "xmlTestThread",

+                             B_NORMAL_PRIORITY, (void *) testfiles[i]);

+            if (tid[i] < B_OK) {

+                fprintf(stderr, "beos_thread_create failed\n");

+                return (1);

+            }

+            printf("beos_thread_create %d -> %d\n", i, tid[i]);

+        }

+        for (i = 0; i < num_threads; i++) {

+            ret = wait_for_thread(tid[i], &results[i]);

+            printf("beos_thread_wait %d -> %d\n", i, ret);

+            if (ret != B_OK) {

+                fprintf(stderr, "beos_thread_wait failed\n");

+                return (1);

+            }

+        }

+

+        xmlCatalogCleanup();

+        ret = B_OK;

+        for (i = 0; i < num_threads; i++)

+            if (results[i] != (void *) Okay) {

+                printf("Thread %d handling %s failed\n", i, testfiles[i]);

+                ret = B_ERROR;

+            }

+    }

+    if (ret != B_OK)

+        return(1);

+    return (0);

+}

+#else

+static int

+testThread(void)

+{

+    fprintf(stderr,

+            "Specific platform thread support not detected\n");

+    return (-1);

+}

+#endif

+static int 

+threadsTest(const char *filename ATTRIBUTE_UNUSED,

+	    const char *resul ATTRIBUTE_UNUSED,

+	    const char *err ATTRIBUTE_UNUSED,

+	    int options ATTRIBUTE_UNUSED) {

+    return(testThread());

+}

+#endif

+/************************************************************************

+ *									*

+ *			Tests Descriptions				*

+ *									*

+ ************************************************************************/

+

+static

+testDesc testDescriptions[] = {

+    { "XML regression tests" ,

+      oldParseTest, "./test/*", "result/", "", NULL,

+      0 },

+    { "XML regression tests on memory" ,

+      memParseTest, "./test/*", "result/", "", NULL,

+      0 },

+    { "XML entity subst regression tests" ,

+      noentParseTest, "./test/*", "result/noent/", "", NULL,

+      XML_PARSE_NOENT },

+    { "XML Namespaces regression tests",

+      errParseTest, "./test/namespaces/*", "result/namespaces/", "", ".err",

+      0 },

+    { "Error cases regression tests",

+      errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",

+      0 },

+#ifdef LIBXML_READER_ENABLED

+    { "Error cases stream regression tests",

+      streamParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".str",

+      0 },

+    { "Reader regression tests",

+      streamParseTest, "./test/*", "result/", ".rdr", NULL,

+      0 },

+    { "Reader entities substitution regression tests",

+      streamParseTest, "./test/*", "result/", ".rde", NULL,

+      XML_PARSE_NOENT },

+    { "Reader on memory regression tests",

+      streamMemParseTest, "./test/*", "result/", ".rdr", NULL,

+      0 },

+    { "Walker regression tests",

+      walkerParseTest, "./test/*", "result/", ".rdr", NULL,

+      0 },

+#endif

+#ifdef LIBXML_SAX1_ENABLED

+    { "SAX1 callbacks regression tests" ,

+      saxParseTest, "./test/*", "result/", ".sax", NULL,

+      XML_PARSE_SAX1 },

+    { "SAX2 callbacks regression tests" ,

+      saxParseTest, "./test/*", "result/", ".sax2", NULL,

+      0 },

+#endif

+#ifdef LIBXML_PUSH_ENABLED

+    { "XML push regression tests" ,

+      pushParseTest, "./test/*", "result/", "", NULL,

+      0 },

+#endif

+#ifdef LIBXML_HTML_ENABLED

+    { "HTML regression tests" ,

+      errParseTest, "./test/HTML/*", "result/HTML/", "", ".err",

+      XML_PARSE_HTML },

+#ifdef LIBXML_PUSH_ENABLED

+    { "Push HTML regression tests" ,

+      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,

+      XML_PARSE_DTDVALID },

+    { "Validity checking regression tests" ,

+      errParseTest, "./test/VC/*", "result/VC/", NULL, "",

+      XML_PARSE_DTDVALID },

+    { "General documents valid regression tests" ,

+      errParseTest, "./test/valid/*", "result/valid/", "", ".err",

+      XML_PARSE_DTDVALID },

+#endif

+#ifdef LIBXML_XINCLUDE_ENABLED

+    { "XInclude regression tests" ,

+      errParseTest, "./test/XInclude/docs/*", "result/XInclude/", "", NULL,

+      /* Ignore errors at this point ".err", */

+      XML_PARSE_XINCLUDE },

+    { "XInclude xmlReader regression tests",

+      streamParseTest, "./test/XInclude/docs/*", "result/XInclude/", ".rdr",

+      /* Ignore errors at this point ".err", */

+      NULL, XML_PARSE_XINCLUDE },

+    { "XInclude regression tests stripping include nodes" ,

+      errParseTest, "./test/XInclude/docs/*", "result/XInclude/", "", NULL,

+      /* Ignore errors at this point ".err", */

+      XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE },

+    { "XInclude xmlReader regression tests stripping include nodes",

+      streamParseTest, "./test/XInclude/docs/*", "result/XInclude/", ".rdr",

+      /* Ignore errors at this point ".err", */

+      NULL, XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE },

+#endif

+#ifdef LIBXML_XPATH_ENABLED

+#ifdef LIBXML_DEBUG_ENABLED

+    { "XPath expressions regression tests" ,

+      xpathExprTest, "./test/XPath/expr/*", "result/XPath/expr/", "", NULL,

+      0 },

+    { "XPath document queries regression tests" ,

+      xpathDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,

+      0 },

+#ifdef LIBXML_XPTR_ENABLED

+    { "XPointer document queries regression tests" ,

+      xptrDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,

+      0 },

+#endif

+    { "xml:id regression tests" ,

+      xmlidDocTest, "./test/xmlid/*", "result/xmlid/", "", ".err",

+      0 },

+#endif

+#endif

+    { "URI parsing tests" ,

+      uriParseTest, "./test/URI/*.uri", "result/URI/", "", NULL,

+      0 },

+    { "URI base composition tests" ,

+      uriBaseTest, "./test/URI/*.data", "result/URI/", "", NULL,

+      0 },

+#ifdef LIBXML_SCHEMAS_ENABLED

+    { "Schemas regression tests" ,

+      schemasTest, "./test/schemas/*_*.xsd", NULL, NULL, NULL,

+      0 },

+    { "Relax-NG regression tests" ,

+      rngTest, "./test/relaxng/*.rng", NULL, NULL, NULL,

+      XML_PARSE_DTDATTR | XML_PARSE_NOENT },

+#ifdef LIBXML_READER_ENABLED

+    { "Relax-NG streaming regression tests" ,

+      rngStreamTest, "./test/relaxng/*.rng", NULL, NULL, NULL,

+      XML_PARSE_DTDATTR | XML_PARSE_NOENT },

+#endif

+#endif

+#ifdef LIBXML_PATTERN_ENABLED

+#ifdef LIBXML_READER_ENABLED

+    { "Pattern regression tests" ,

+      patternTest, "./test/pattern/*.pat", "result/pattern/", NULL, NULL,

+      0 },

+#endif

+#endif

+#ifdef LIBXML_C14N_ENABLED

+    { "C14N with comments regression tests" ,

+      c14nWithCommentTest, "./test/c14n/with-comments/*.xml", NULL, NULL, NULL,

+      0 },

+    { "C14N without comments regression tests" ,

+      c14nWithoutCommentTest, "./test/c14n/without-comments/*.xml", NULL, NULL, NULL,

+      0 },

+    { "C14N exclusive without comments regression tests" ,

+      c14nExcWithoutCommentTest, "./test/c14n/exc-without-comments/*.xml", NULL, NULL, NULL,

+      0 },

+#endif

+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)

+    { "Catalog and Threads regression tests" ,

+      threadsTest, NULL, NULL, NULL, NULL,

+      0 },

+#endif

+    {NULL, NULL, NULL, NULL, NULL, NULL, 0}

+};

+

+/************************************************************************

+ *									*

+ *		The main code driving the tests				*

+ *									*

+ ************************************************************************/

+

+static int

+launchTests(testDescPtr tst) {

+    int res = 0, err = 0;

+    size_t i;

+    char *result;

+    char *error;

+    int mem;

+

+    if (tst == NULL) return(-1);

+    if (tst->in != NULL) {

+	glob_t globbuf;

+

+	globbuf.gl_offs = 0;

+	glob(tst->in, GLOB_DOOFFS, NULL, &globbuf);

+	for (i = 0;i < globbuf.gl_pathc;i++) {

+	    if (!checkTestFile(globbuf.gl_pathv[i]))

+	        continue;

+	    if (tst->suffix != NULL) {

+		result = resultFilename(globbuf.gl_pathv[i], tst->out,

+					tst->suffix);

+		if (result == NULL) {

+		    fprintf(stderr, "Out of memory !\n");

+		    fatalError();

+		}

+	    } else {

+	        result = NULL;

+	    }

+	    if (tst->err != NULL) {

+		error = resultFilename(globbuf.gl_pathv[i], tst->out,

+		                        tst->err);

+		if (error == NULL) {

+		    fprintf(stderr, "Out of memory !\n");

+		    fatalError();

+		}

+	    } else {

+	        error = NULL;

+	    }

+	    if ((result) &&(!checkTestFile(result))) {

+	        fprintf(stderr, "Missing result file %s\n", result);

+	    } else if ((error) &&(!checkTestFile(error))) {

+	        fprintf(stderr, "Missing error file %s\n", error);

+	    } else {

+		mem = xmlMemUsed();

+		extraMemoryFromResolver = 0;

+		testErrorsSize = 0;

+		testErrors[0] = 0;

+		res = tst->func(globbuf.gl_pathv[i], result, error,

+		                tst->options);

+		xmlResetLastError();

+		if (res != 0) {

+		    fprintf(stderr, "File %s generated an error\n",

+		            globbuf.gl_pathv[i]);

+		    nb_errors++;

+		    err++;

+		}

+		else if (xmlMemUsed() != mem) {

+		    if ((xmlMemUsed() != mem) &&

+		        (extraMemoryFromResolver == 0)) {

+			fprintf(stderr, "File %s leaked %d bytes\n",

+				globbuf.gl_pathv[i], xmlMemUsed() - mem);

+			nb_leaks++;

+			err++;

+		    }

+		}

+		testErrorsSize = 0;

+	    }

+	    if (result)

+		free(result);

+	    if (error)

+		free(error);

+	}

+	globfree(&globbuf);

+    } else {

+        testErrorsSize = 0;

+	testErrors[0] = 0;

+	extraMemoryFromResolver = 0;

+        res = tst->func(NULL, NULL, NULL, tst->options);

+	if (res != 0) {

+	    nb_errors++;

+	    err++;

+	}

+    }

+    return(err);

+}

+

+int

+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {

+    int i = 0, res, ret = 0;

+    int verbose = 0;

+    int old_errors, old_tests, old_leaks;

+

+    initializeLibxml2();

+

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

+        verbose = 1;

+    for (i = 0; testDescriptions[i].func != NULL; i++) {

+        old_errors = nb_errors;

+        old_tests = nb_tests;

+        old_leaks = nb_leaks;

+        if (testDescriptions[i].desc != NULL)

+	    printf("## %s\n", testDescriptions[i].desc);

+	res = launchTests(&testDescriptions[i]);

+	if (res != 0)

+	    ret++;

+	if (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);

+	}

+    }

+    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);

+    }

+    xmlCleanupParser();

+    xmlMemoryDump();

+

+    return(ret);

+}

+

+#else /* ! LIBXML_OUTPUT_ENABLED */

+int

+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {

+    fprintf(stderr, "runtest requires output to be enabled in libxml2\n");

+    return(1);

+}

+#endif