17e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/*
27e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard * runsuite.c: C program to run libxml2 againts published testsuites
37e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *
47e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard * See Copyright for the status of this software.
57e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *
67e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard * daniel@veillard.com
77e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard */
87e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
97e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include "libxml.h"
107e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <stdio.h>
117e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
122e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard#ifdef LIBXML_XPATH_ENABLED
132e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard
147e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#if !defined(_WIN32) || defined(__CYGWIN__)
157e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <unistd.h>
167e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#endif
177e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <string.h>
187e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <sys/types.h>
197e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <sys/stat.h>
207e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <fcntl.h>
217e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
227e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/parser.h>
237e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/parserInternals.h>
247e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/tree.h>
257e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/uri.h>
267e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/xmlreader.h>
277e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
287e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/xpath.h>
297e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#include <libxml/xpathInternals.h>
307e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
31051d52cb6166cb8d7064d185820366943177a561Daniel Veillard#define LOGFILE "runxmlconf.log"
327e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic FILE *logfile = NULL;
337e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int verbose = 0;
347e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
35da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard#define NB_EXPECTED_ERRORS 15
367e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
377e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
38373345764b92c5959154ec233163a2a64a775863Daniel Veillardconst char *skipped_tests[] = {
39373345764b92c5959154ec233163a2a64a775863Daniel Veillard/* http://lists.w3.org/Archives/Public/public-xml-testsuite/2008Jul/0000.html */
40373345764b92c5959154ec233163a2a64a775863Daniel Veillard    "rmt-ns10-035",
41373345764b92c5959154ec233163a2a64a775863Daniel Veillard    NULL
42373345764b92c5959154ec233163a2a64a775863Daniel Veillard};
43373345764b92c5959154ec233163a2a64a775863Daniel Veillard
447e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/************************************************************************
457e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
467e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *		File name and path utilities				*
477e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
487e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard ************************************************************************/
497e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
507e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int checkTestFile(const char *filename) {
517e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    struct stat buf;
527e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
537e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (stat(filename, &buf) == -1)
547e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        return(0);
557e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
567e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__)
577e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (!(buf.st_mode & _S_IFREG))
587e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        return(0);
597e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#else
607e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (!S_ISREG(buf.st_mode))
617e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        return(0);
627e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard#endif
637e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
647e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(1);
657e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
667e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
677e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
687e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    char buf[500];
697e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
707e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (dir == NULL) return(xmlStrdup(path));
717e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (path == NULL) return(NULL);
727e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
737e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
747e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(xmlStrdup((const xmlChar *) buf));
757e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
767e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
777e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/************************************************************************
787e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
797e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *		Libxml2 specific routines				*
807e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
817e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard ************************************************************************/
827e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
837e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int nb_skipped = 0;
847e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int nb_tests = 0;
857e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int nb_errors = 0;
867e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int nb_leaks = 0;
877e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
887e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/*
897e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard * We need to trap calls to the resolver to not account memory for the catalog
9009459bf1078992a5dea8c1bbef4919b90bc25218Daniel Veillard * and not rely on any external resources.
917e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard */
927e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic xmlParserInputPtr
93ae0765b6819c77aae2638b40735f354b05b9c150Daniel VeillardtestExternalEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED,
947e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard			 xmlParserCtxtPtr ctxt) {
957e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlParserInputPtr ret;
967e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
9709459bf1078992a5dea8c1bbef4919b90bc25218Daniel Veillard    ret = xmlNewInputFromFile(ctxt, (const char *) URL);
987e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
997e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
1007e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
1017e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1027e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/*
1037e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard * Trapping the error messages at the generic level to grab the equivalent of
1047e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard * stderr messages on CLI tools.
1057e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard */
1067e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic char testErrors[32769];
1077e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int testErrorsSize = 0;
108ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillardstatic int nbError = 0;
109ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillardstatic int nbFatal = 0;
1107e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1117e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic void test_log(const char *msg, ...) {
1127e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    va_list args;
1137e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (logfile != NULL) {
1147e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        fprintf(logfile, "\n------------\n");
1157e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	va_start(args, msg);
1167e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	vfprintf(logfile, msg, args);
1177e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	va_end(args);
1187e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	fprintf(logfile, "%s", testErrors);
1197e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	testErrorsSize = 0; testErrors[0] = 0;
1207e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
1217e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (verbose) {
1227e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	va_start(args, msg);
1237e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	vfprintf(stderr, msg, args);
1247e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	va_end(args);
1257e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
1267e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
1277e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1287e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic void
129ae0765b6819c77aae2638b40735f354b05b9c150Daniel VeillardtestErrorHandler(void *userData ATTRIBUTE_UNUSED, xmlErrorPtr error) {
1307e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int res;
1317e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1327e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (testErrorsSize >= 32768)
1337e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        return;
134ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    res = snprintf(&testErrors[testErrorsSize],
1357e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard                    32768 - testErrorsSize,
136ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard		   "%s:%d: %s\n", (error->file ? error->file : "entity"),
137ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard		   error->line, error->message);
138ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    if (error->level == XML_ERR_FATAL)
139ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        nbFatal++;
140ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    else if (error->level == XML_ERR_ERROR)
141ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        nbError++;
1427e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (testErrorsSize + res >= 32768) {
1437e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        /* buffer is full */
1447e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	testErrorsSize = 32768;
1457e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	testErrors[testErrorsSize] = 0;
1467e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else {
1477e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        testErrorsSize += res;
1487e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
1497e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    testErrors[testErrorsSize] = 0;
1507e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
1517e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1527e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic xmlXPathContextPtr ctxtXPath;
1537e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1547e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic void
1557e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardinitializeLibxml2(void) {
1567e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlGetWarningsDefaultValue = 0;
1577e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlPedanticParserDefault(0);
1587e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1597e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
1607e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlInitParser();
1617e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlSetExternalEntityLoader(testExternalEntityLoader);
1627e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    ctxtXPath = xmlXPathNewContext(NULL);
1637e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    /*
1647e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    * Deactivate the cache if created; otherwise we have to create/free it
1657e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    * for every test, since it will confuse the memory leak detection.
1667e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    * Note that normally this need not be done, since the cache is not
1677e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    * created until set explicitely with xmlXPathContextSetCache();
1687e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    * but for test purposes it is sometimes usefull to activate the
1697e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    * cache by default for the whole library.
1707e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    */
1717e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (ctxtXPath->cache != NULL)
1727e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
173ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlSetStructuredErrorFunc(NULL, testErrorHandler);
1747e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
1757e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1767e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/************************************************************************
1777e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
1787e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *		Run the xmlconf test if found				*
1797e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
1807e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard ************************************************************************/
1817e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
1827e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int
183ae0765b6819c77aae2638b40735f354b05b9c150Daniel VeillardxmlconfTestInvalid(const char *id, const char *filename, int options) {
184ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlDocPtr doc;
185ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlParserCtxtPtr ctxt;
186ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    int ret = 1;
187ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard
188ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    ctxt = xmlNewParserCtxt();
189ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    if (ctxt == NULL) {
190ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        test_log("test %s : %s out of memory\n",
191ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	         id, filename);
192ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        return(0);
193ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    }
194ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
195ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    if (doc == NULL) {
196ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        test_log("test %s : %s invalid document turned not well-formed too\n",
197ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	         id, filename);
198ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    } else {
199ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    /* invalidity should be reported both in the context and in the document */
200ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        if ((ctxt->valid != 0) || (doc->properties & XML_DOC_DTDVALID)) {
201ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    test_log("test %s : %s failed to detect invalid document\n",
202ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard		     id, filename);
203ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    nb_errors++;
204ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    ret = 0;
205ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	}
206ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	xmlFreeDoc(doc);
207ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    }
208ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlFreeParserCtxt(ctxt);
209ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    return(ret);
210ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard}
211ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard
212ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillardstatic int
213ae0765b6819c77aae2638b40735f354b05b9c150Daniel VeillardxmlconfTestValid(const char *id, const char *filename, int options) {
214ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlDocPtr doc;
215ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlParserCtxtPtr ctxt;
216ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    int ret = 1;
217ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard
218ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    ctxt = xmlNewParserCtxt();
219ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    if (ctxt == NULL) {
220ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        test_log("test %s : %s out of memory\n",
221ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	         id, filename);
222ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        return(0);
223ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    }
224ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
225ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    if (doc == NULL) {
226ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        test_log("test %s : %s failed to parse a valid document\n",
227ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	         id, filename);
228ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        nb_errors++;
229ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	ret = 0;
230ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    } else {
231ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    /* validity should be reported both in the context and in the document */
232ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        if ((ctxt->valid == 0) || ((doc->properties & XML_DOC_DTDVALID) == 0)) {
233ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    test_log("test %s : %s failed to validate a valid document\n",
234ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard		     id, filename);
235ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    nb_errors++;
236ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    ret = 0;
237ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	}
238ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	xmlFreeDoc(doc);
239ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    }
240ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlFreeParserCtxt(ctxt);
241ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    return(ret);
242ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard}
243ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard
244ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillardstatic int
2457e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardxmlconfTestNotNSWF(const char *id, const char *filename, int options) {
2467e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlDocPtr doc;
2477e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = 1;
2487e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
2497e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    /*
2507e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     * In case of Namespace errors, libxml2 will still parse the document
2517e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     * but log a Namesapce error.
2527e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     */
2537e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    doc = xmlReadFile(filename, NULL, options);
2547e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (doc == NULL) {
2557e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s : %s failed to parse the XML\n",
2567e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	         id, filename);
2577e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        nb_errors++;
2587e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = 0;
2597e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else {
2607e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	if ((xmlLastError.code == XML_ERR_OK) ||
2617e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    (xmlLastError.domain != XML_FROM_NAMESPACE)) {
2627e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    test_log("test %s : %s failed to detect namespace error\n",
2637e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard		     id, filename);
2647e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    nb_errors++;
2657e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    ret = 0;
2667e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	}
2677e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlFreeDoc(doc);
2687e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
2697e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
2707e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
2717e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
2727e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int
2737e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardxmlconfTestNotWF(const char *id, const char *filename, int options) {
2747e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlDocPtr doc;
2757e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = 1;
2767e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
2777e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    doc = xmlReadFile(filename, NULL, options);
2787e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (doc != NULL) {
2797e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s : %s failed to detect not well formedness\n",
2807e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	         id, filename);
2817e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        nb_errors++;
2827e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlFreeDoc(doc);
2837e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = 0;
2847e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
2857e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
2867e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
2877e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
2887e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int
2897e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardxmlconfTestItem(xmlDocPtr doc, xmlNodePtr cur) {
2907e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = -1;
2917e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *type = NULL;
2927e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *filename = NULL;
2937e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *uri = NULL;
2947e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *base = NULL;
2957e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *id = NULL;
2967e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *rec = NULL;
297ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    xmlChar *version = NULL;
2987e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *entities = NULL;
2997e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *edition = NULL;
3007e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int options = 0;
3017e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int nstest = 0;
3027e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int mem, final;
303373345764b92c5959154ec233163a2a64a775863Daniel Veillard    int i;
3047e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
305373345764b92c5959154ec233163a2a64a775863Daniel Veillard    testErrorsSize = 0; testErrors[0] = 0;
306ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    nbError = 0;
307ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    nbFatal = 0;
3087e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    id = xmlGetProp(cur, BAD_CAST "ID");
3097e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (id == NULL) {
3107e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test missing ID, line %ld\n", xmlGetLineNo(cur));
3117e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	goto error;
3127e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
313373345764b92c5959154ec233163a2a64a775863Daniel Veillard    for (i = 0;skipped_tests[i] != NULL;i++) {
314373345764b92c5959154ec233163a2a64a775863Daniel Veillard        if (!strcmp(skipped_tests[i], (char *) id)) {
315373345764b92c5959154ec233163a2a64a775863Daniel Veillard	    test_log("Skipping test %s from skipped list\n", (char *) id);
316373345764b92c5959154ec233163a2a64a775863Daniel Veillard	    ret = 0;
317373345764b92c5959154ec233163a2a64a775863Daniel Veillard	    nb_skipped++;
318373345764b92c5959154ec233163a2a64a775863Daniel Veillard	    goto error;
319373345764b92c5959154ec233163a2a64a775863Daniel Veillard	}
320373345764b92c5959154ec233163a2a64a775863Daniel Veillard    }
3217e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    type = xmlGetProp(cur, BAD_CAST "TYPE");
3227e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (type == NULL) {
3237e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s missing TYPE\n", (char *) id);
3247e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	goto error;
3257e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
3267e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    uri = xmlGetProp(cur, BAD_CAST "URI");
3277e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (uri == NULL) {
3287e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s missing URI\n", (char *) id);
3297e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	goto error;
3307e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
3317e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    base = xmlNodeGetBase(doc, cur);
3327e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    filename = composeDir(base, uri);
3337e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (!checkTestFile((char *) filename)) {
3347e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s missing file %s \n", id,
3357e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	         (filename ? (char *)filename : "NULL"));
3367e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	goto error;
3377e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
3387e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
339ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    version = xmlGetProp(cur, BAD_CAST "VERSION");
340ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard
3417e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    entities = xmlGetProp(cur, BAD_CAST "ENTITIES");
3427e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (!xmlStrEqual(entities, BAD_CAST "none")) {
3437e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        options |= XML_PARSE_DTDLOAD;
34440ec29a56f4f03a8b4628b46fbc3582ade156bbdDaniel Veillard        options |= XML_PARSE_NOENT;
3457e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
3467e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    rec = xmlGetProp(cur, BAD_CAST "RECOMMENDATION");
3477e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if ((rec == NULL) ||
3487e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        (xmlStrEqual(rec, BAD_CAST "XML1.0")) ||
3497e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	(xmlStrEqual(rec, BAD_CAST "XML1.0-errata2e")) ||
3507e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	(xmlStrEqual(rec, BAD_CAST "XML1.0-errata3e")) ||
3517e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	(xmlStrEqual(rec, BAD_CAST "XML1.0-errata4e"))) {
352ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	if ((version != NULL) && (!xmlStrEqual(version, BAD_CAST "1.0"))) {
353ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    test_log("Skipping test %s for %s\n", (char *) id,
354ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	             (char *) version);
355ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    ret = 0;
356ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    nb_skipped++;
357ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	    goto error;
358ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	}
3597e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = 1;
3607e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else if ((xmlStrEqual(rec, BAD_CAST "NS1.0")) ||
3617e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	       (xmlStrEqual(rec, BAD_CAST "NS1.0-errata1e"))) {
3627e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = 1;
3637e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	nstest = 1;
3647e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else {
3657e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("Skipping test %s for REC %s\n", (char *) id, (char *) rec);
3667e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = 0;
3677e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	nb_skipped++;
3687e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	goto error;
3697e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
3707e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    edition = xmlGetProp(cur, BAD_CAST "EDITION");
3717e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if ((edition != NULL) && (xmlStrchr(edition, '5') == NULL)) {
3727e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        /* test limited to all versions before 5th */
3737e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	options |= XML_PARSE_OLD10;
3747e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
3757e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
3767e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    /*
3777e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     * Reset errors and check memory usage before the test
3787e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     */
3797e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlResetLastError();
3807e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    testErrorsSize = 0; testErrors[0] = 0;
3817e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    mem = xmlMemUsed();
3827e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
3837e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (xmlStrEqual(type, BAD_CAST "not-wf")) {
3847e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        if (nstest == 0)
3857e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    xmlconfTestNotWF((char *) id, (char *) filename, options);
386f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        else
3877e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    xmlconfTestNotNSWF((char *) id, (char *) filename, options);
3887e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else if (xmlStrEqual(type, BAD_CAST "valid")) {
389ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        options |= XML_PARSE_DTDVALID;
390ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	xmlconfTestValid((char *) id, (char *) filename, options);
3917e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else if (xmlStrEqual(type, BAD_CAST "invalid")) {
392ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        options |= XML_PARSE_DTDVALID;
393ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	xmlconfTestInvalid((char *) id, (char *) filename, options);
3947e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else if (xmlStrEqual(type, BAD_CAST "error")) {
395ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        test_log("Skipping error test %s \n", (char *) id);
396ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	ret = 0;
397ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	nb_skipped++;
398ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard	goto error;
3997e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else {
4007e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s unknown TYPE value %s\n", (char *) id, (char *)type);
4017e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = -1;
4027e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	goto error;
4037e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
4047e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
4057e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    /*
4067e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     * Reset errors and check memory usage after the test
4077e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard     */
4087e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlResetLastError();
4097e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    final = xmlMemUsed();
4107e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (final > mem) {
4117e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        test_log("test %s : %s leaked %d bytes\n",
4127e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	         id, filename, final - mem);
4137e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        nb_leaks++;
41409459bf1078992a5dea8c1bbef4919b90bc25218Daniel Veillard	xmlMemDisplayLast(logfile, final - mem);
4157e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
4167e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    nb_tests++;
4177e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
4187e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillarderror:
4197e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (type != NULL)
4207e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(type);
4217e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (entities != NULL)
4227e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(entities);
4237e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (edition != NULL)
4247e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(edition);
425ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard    if (version != NULL)
426ae0765b6819c77aae2638b40735f354b05b9c150Daniel Veillard        xmlFree(version);
4277e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (filename != NULL)
4287e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(filename);
4297e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (uri != NULL)
4307e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(uri);
4317e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (base != NULL)
4327e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(base);
4337e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (id != NULL)
4347e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(id);
4357e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (rec != NULL)
4367e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        xmlFree(rec);
4377e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
4387e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
4397e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
4407e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int
441aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel VeillardxmlconfTestCases(xmlDocPtr doc, xmlNodePtr cur, int level) {
4427e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *profile;
4437e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = 0;
4447e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int tests = 0;
445aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard    int output = 0;
446aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard
447aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard    if (level == 1) {
448aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	profile = xmlGetProp(cur, BAD_CAST "PROFILE");
449aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	if (profile != NULL) {
450aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	    output = 1;
451aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	    level++;
452aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	    printf("Test cases: %s\n", (char *) profile);
453aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	    xmlFree(profile);
454aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	}
4557e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
4567e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    cur = cur->children;
4577e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    while (cur != NULL) {
4587e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        /* look only at elements we ignore everything else */
4597e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        if (cur->type == XML_ELEMENT_NODE) {
4607e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    if (xmlStrEqual(cur->name, BAD_CAST "TESTCASES")) {
461aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	        ret += xmlconfTestCases(doc, cur, level);
4627e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    } else if (xmlStrEqual(cur->name, BAD_CAST "TEST")) {
4637e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	        if (xmlconfTestItem(doc, cur) >= 0)
4647e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard		    ret++;
4657e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard		tests++;
4667e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    } else {
4677e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	        fprintf(stderr, "Unhandled element %s\n", (char *)cur->name);
4687e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    }
4697e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	}
4707e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        cur = cur->next;
4717e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
472aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard    if (output == 1) {
473aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	if (tests > 0)
474aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	    printf("Test cases: %d tests\n", tests);
475aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard    }
4767e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
4777e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
4787e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
4797e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int
4807e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardxmlconfTestSuite(xmlDocPtr doc, xmlNodePtr cur) {
4817e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlChar *profile;
4827e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = 0;
4837e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
4847e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    profile = xmlGetProp(cur, BAD_CAST "PROFILE");
4857e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (profile != NULL) {
4867e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        printf("Test suite: %s\n", (char *) profile);
4877e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlFree(profile);
4887e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else
4897e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        printf("Test suite\n");
4907e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    cur = cur->children;
4917e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    while (cur != NULL) {
4927e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        /* look only at elements we ignore everything else */
4937e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        if (cur->type == XML_ELEMENT_NODE) {
4947e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    if (xmlStrEqual(cur->name, BAD_CAST "TESTCASES")) {
495aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	        ret += xmlconfTestCases(doc, cur, 1);
4967e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    } else {
4977e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	        fprintf(stderr, "Unhandled element %s\n", (char *)cur->name);
4987e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	    }
4997e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	}
5007e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        cur = cur->next;
5017e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
5027e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
5037e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
5047e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5057e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic void
5067e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardxmlconfInfo(void) {
5077e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    fprintf(stderr, "  you need to fetch and extract the\n");
5087e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    fprintf(stderr, "  latest XML Conformance Test Suites\n");
509851ef9489eb62f2293f17b08218075dd3b54764fStefan Kost    fprintf(stderr, "  http://www.w3.org/XML/Test/xmlts20080827.tar.gz\n");
5107e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    fprintf(stderr, "  see http://www.w3.org/XML/Test/ for informations\n");
5117e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
5127e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5137e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardstatic int
5147e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel VeillardxmlconfTest(void) {
5157e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    const char *confxml = "xmlconf/xmlconf.xml";
5167e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlDocPtr doc;
5177e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlNodePtr cur;
5187e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = 0;
5197e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5207e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (!checkTestFile(confxml)) {
5217e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        fprintf(stderr, "%s is missing \n", confxml);
5227e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlconfInfo();
5237e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	return(-1);
5247e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
5257e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    doc = xmlReadFile(confxml, NULL, XML_PARSE_NOENT);
5267e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (doc == NULL) {
5277e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        fprintf(stderr, "%s is corrupted \n", confxml);
5287e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlconfInfo();
5297e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	return(-1);
5307e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
5317e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5327e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    cur = xmlDocGetRootElement(doc);
5337e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "TESTSUITE"))) {
5347e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        fprintf(stderr, "Unexpected format %s\n", confxml);
5357e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	xmlconfInfo();
5367e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	ret = -1;
5377e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else {
5387e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        ret = xmlconfTestSuite(doc, cur);
5397e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
5407e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlFreeDoc(doc);
5417e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
5427e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
5437e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5447e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard/************************************************************************
5457e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
5467e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *		The driver for the tests				*
5477e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard *									*
5487e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard ************************************************************************/
5497e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5507e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardint
5517e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillardmain(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
5527e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int ret = 0;
5537e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    int old_errors, old_tests, old_leaks;
5547e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5557e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    logfile = fopen(LOGFILE, "w");
5567e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (logfile == NULL) {
5577e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        fprintf(stderr,
5587e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	        "Could not open the log file, running in verbose mode\n");
5597e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	verbose = 1;
5607e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
5617e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    initializeLibxml2();
5627e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5637e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if ((argc >= 2) && (!strcmp(argv[1], "-v")))
5647e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        verbose = 1;
5657e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5667e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5677e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    old_errors = nb_errors;
5687e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    old_tests = nb_tests;
5697e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    old_leaks = nb_leaks;
5707e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlconfTest();
5717e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
5727e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
5737e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    else
5747e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	printf("Ran %d tests, %d errors, %d leaks\n",
5757e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	       nb_tests - old_tests,
5767e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	       nb_errors - old_errors,
5777e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	       nb_leaks - old_leaks);
5787e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if ((nb_errors == 0) && (nb_leaks == 0)) {
5797e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        ret = 0;
5807e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	printf("Total %d tests, no errors\n",
5817e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	       nb_tests);
5827e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    } else {
583da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	ret = 1;
5847e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	printf("Total %d tests, %d errors, %d leaks\n",
5857e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard	       nb_tests, nb_errors, nb_leaks);
586aa6de47ebf0d4f96ed83e06c79a870a4e9b5dd0eDaniel Veillard	printf("See %s for detailed output\n", LOGFILE);
587da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	if ((nb_leaks == 0) && (nb_errors == NB_EXPECTED_ERRORS)) {
588da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	    printf("%d errors were expected\n", nb_errors);
589da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	    ret = 0;
590da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	}
5917e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    }
5927e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlXPathFreeContext(ctxtXPath);
5937e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlCleanupParser();
5947e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    xmlMemoryDump();
5957e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard
5967e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    if (logfile != NULL)
5977e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard        fclose(logfile);
5987e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard    return(ret);
5997e5c3f481f5e8c8eb2b038cb24a9b3d77e3806abDaniel Veillard}
6002e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard
6012e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard#else /* ! LIBXML_XPATH_ENABLED */
6022e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard#include <stdio.h>
6032e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillardint
6042e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillardmain(int argc, char **argv) {
6052e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard    fprintf(stderr, "%s need XPath support\n", argv[0]);
6062e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard}
6072e36da9f6fe66e092384b2794d4e973389e32fdbDaniel Veillard#endif
608