Annotation of embedaddon/libxml2/runsuite.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * runsuite.c: C program to run libxml2 againts published testsuites 
        !             3:  *
        !             4:  * See Copyright for the status of this software.
        !             5:  *
        !             6:  * daniel@veillard.com
        !             7:  */
        !             8: 
        !             9: #ifdef HAVE_CONFIG_H
        !            10: #include "libxml.h"
        !            11: #else
        !            12: #include <stdio.h>
        !            13: #endif
        !            14: 
        !            15: #if !defined(_WIN32) || defined(__CYGWIN__)
        !            16: #include <unistd.h>
        !            17: #endif
        !            18: #include <string.h>
        !            19: #include <sys/types.h>
        !            20: #include <sys/stat.h>
        !            21: #include <fcntl.h>
        !            22: 
        !            23: #include <libxml/parser.h>
        !            24: #include <libxml/parserInternals.h>
        !            25: #include <libxml/tree.h>
        !            26: #include <libxml/uri.h>
        !            27: #if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
        !            28: #include <libxml/xmlreader.h>
        !            29: 
        !            30: #include <libxml/xpath.h>
        !            31: #include <libxml/xpathInternals.h>
        !            32: 
        !            33: #include <libxml/relaxng.h>
        !            34: #include <libxml/xmlschemas.h>
        !            35: #include <libxml/xmlschemastypes.h>
        !            36: 
        !            37: #define LOGFILE "runsuite.log"
        !            38: static FILE *logfile = NULL;
        !            39: static int verbose = 0;
        !            40: 
        !            41: 
        !            42: 
        !            43: #if defined(_WIN32) && !defined(__CYGWIN__)
        !            44: 
        !            45: #define vsnprintf _vsnprintf
        !            46: 
        !            47: #define snprintf _snprintf
        !            48: 
        !            49: #endif
        !            50: 
        !            51: /************************************************************************
        !            52:  *                                                                     *
        !            53:  *             File name and path utilities                            *
        !            54:  *                                                                     *
        !            55:  ************************************************************************/
        !            56: 
        !            57: static int checkTestFile(const char *filename) {
        !            58:     struct stat buf;
        !            59: 
        !            60:     if (stat(filename, &buf) == -1)
        !            61:         return(0);
        !            62: 
        !            63: #if defined(_WIN32) && !defined(__CYGWIN__)
        !            64:     if (!(buf.st_mode & _S_IFREG))
        !            65:         return(0);
        !            66: #else
        !            67:     if (!S_ISREG(buf.st_mode))
        !            68:         return(0);
        !            69: #endif
        !            70: 
        !            71:     return(1);
        !            72: }
        !            73: 
        !            74: static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
        !            75:     char buf[500];
        !            76: 
        !            77:     if (dir == NULL) return(xmlStrdup(path));
        !            78:     if (path == NULL) return(NULL);
        !            79: 
        !            80:     snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
        !            81:     return(xmlStrdup((const xmlChar *) buf));
        !            82: }
        !            83: 
        !            84: /************************************************************************
        !            85:  *                                                                     *
        !            86:  *             Libxml2 specific routines                               *
        !            87:  *                                                                     *
        !            88:  ************************************************************************/
        !            89: 
        !            90: static int nb_tests = 0;
        !            91: static int nb_errors = 0;
        !            92: static int nb_internals = 0;
        !            93: static int nb_schematas = 0;
        !            94: static int nb_unimplemented = 0;
        !            95: static int nb_leaks = 0;
        !            96: static int extraMemoryFromResolver = 0;
        !            97: 
        !            98: static int
        !            99: fatalError(void) {
        !           100:     fprintf(stderr, "Exitting tests on fatal error\n");
        !           101:     exit(1);
        !           102: }
        !           103: 
        !           104: /*
        !           105:  * that's needed to implement <resource>
        !           106:  */
        !           107: #define MAX_ENTITIES 20
        !           108: static char *testEntitiesName[MAX_ENTITIES];
        !           109: static char *testEntitiesValue[MAX_ENTITIES];
        !           110: static int nb_entities = 0;
        !           111: static void resetEntities(void) {
        !           112:     int i;
        !           113: 
        !           114:     for (i = 0;i < nb_entities;i++) {
        !           115:         if (testEntitiesName[i] != NULL)
        !           116:            xmlFree(testEntitiesName[i]);
        !           117:         if (testEntitiesValue[i] != NULL)
        !           118:            xmlFree(testEntitiesValue[i]);
        !           119:     }
        !           120:     nb_entities = 0;
        !           121: }
        !           122: static int addEntity(char *name, char *content) {
        !           123:     if (nb_entities >= MAX_ENTITIES) {
        !           124:        fprintf(stderr, "Too many entities defined\n");
        !           125:        return(-1);
        !           126:     }
        !           127:     testEntitiesName[nb_entities] = name;
        !           128:     testEntitiesValue[nb_entities] = content;
        !           129:     nb_entities++;
        !           130:     return(0);
        !           131: }
        !           132: 
        !           133: /*
        !           134:  * We need to trap calls to the resolver to not account memory for the catalog
        !           135:  * which is shared to the current running test. We also don't want to have
        !           136:  * network downloads modifying tests.
        !           137:  */
        !           138: static xmlParserInputPtr 
        !           139: testExternalEntityLoader(const char *URL, const char *ID,
        !           140:                         xmlParserCtxtPtr ctxt) {
        !           141:     xmlParserInputPtr ret;
        !           142:     int i;
        !           143: 
        !           144:     for (i = 0;i < nb_entities;i++) {
        !           145:         if (!strcmp(testEntitiesName[i], URL)) {
        !           146:            ret = xmlNewStringInputStream(ctxt,
        !           147:                        (const xmlChar *) testEntitiesValue[i]);
        !           148:            if (ret != NULL) {
        !           149:                ret->filename = (const char *)
        !           150:                                xmlStrdup((xmlChar *)testEntitiesName[i]);
        !           151:            }
        !           152:            return(ret);
        !           153:        }
        !           154:     }
        !           155:     if (checkTestFile(URL)) {
        !           156:        ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
        !           157:     } else {
        !           158:        int memused = xmlMemUsed();
        !           159:        ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
        !           160:        extraMemoryFromResolver += xmlMemUsed() - memused;
        !           161:     }
        !           162: #if 0
        !           163:     if (ret == NULL) {
        !           164:         fprintf(stderr, "Failed to find resource %s\n", URL);
        !           165:     }
        !           166: #endif
        !           167:       
        !           168:     return(ret);
        !           169: }
        !           170: 
        !           171: /*
        !           172:  * Trapping the error messages at the generic level to grab the equivalent of
        !           173:  * stderr messages on CLI tools.
        !           174:  */
        !           175: static char testErrors[32769];
        !           176: static int testErrorsSize = 0;
        !           177: 
        !           178: static void test_log(const char *msg, ...) {
        !           179:     va_list args;
        !           180:     if (logfile != NULL) {
        !           181:         fprintf(logfile, "\n------------\n");
        !           182:        va_start(args, msg);
        !           183:        vfprintf(logfile, msg, args);
        !           184:        va_end(args);
        !           185:        fprintf(logfile, "%s", testErrors);
        !           186:        testErrorsSize = 0; testErrors[0] = 0;
        !           187:     }
        !           188:     if (verbose) {
        !           189:        va_start(args, msg);
        !           190:        vfprintf(stderr, msg, args);
        !           191:        va_end(args);
        !           192:     }
        !           193: }
        !           194: 
        !           195: static void
        !           196: testErrorHandler(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
        !           197:     va_list args;
        !           198:     int res;
        !           199: 
        !           200:     if (testErrorsSize >= 32768)
        !           201:         return;
        !           202:     va_start(args, msg);
        !           203:     res = vsnprintf(&testErrors[testErrorsSize],
        !           204:                     32768 - testErrorsSize,
        !           205:                    msg, args);
        !           206:     va_end(args);
        !           207:     if (testErrorsSize + res >= 32768) {
        !           208:         /* buffer is full */
        !           209:        testErrorsSize = 32768;
        !           210:        testErrors[testErrorsSize] = 0;
        !           211:     } else {
        !           212:         testErrorsSize += res;
        !           213:     }
        !           214:     testErrors[testErrorsSize] = 0;
        !           215: }
        !           216: 
        !           217: static xmlXPathContextPtr ctxtXPath;
        !           218: 
        !           219: static void
        !           220: initializeLibxml2(void) {
        !           221:     xmlGetWarningsDefaultValue = 0;
        !           222:     xmlPedanticParserDefault(0);
        !           223: 
        !           224:     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
        !           225:     xmlInitParser();
        !           226:     xmlSetExternalEntityLoader(testExternalEntityLoader);
        !           227:     ctxtXPath = xmlXPathNewContext(NULL);
        !           228:     /*
        !           229:     * Deactivate the cache if created; otherwise we have to create/free it
        !           230:     * for every test, since it will confuse the memory leak detection.
        !           231:     * Note that normally this need not be done, since the cache is not
        !           232:     * created until set explicitely with xmlXPathContextSetCache();
        !           233:     * but for test purposes it is sometimes usefull to activate the
        !           234:     * cache by default for the whole library.
        !           235:     */
        !           236:     if (ctxtXPath->cache != NULL)
        !           237:        xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
        !           238:     /* used as default nanemspace in xstc tests */
        !           239:     xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
        !           240:     xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
        !           241:                        BAD_CAST "http://www.w3.org/1999/xlink");
        !           242:     xmlSetGenericErrorFunc(NULL, testErrorHandler);
        !           243: #ifdef LIBXML_SCHEMAS_ENABLED
        !           244:     xmlSchemaInitTypes();
        !           245:     xmlRelaxNGInitTypes();
        !           246: #endif
        !           247: }
        !           248: 
        !           249: static xmlNodePtr
        !           250: getNext(xmlNodePtr cur, const char *xpath) {
        !           251:     xmlNodePtr ret = NULL;
        !           252:     xmlXPathObjectPtr res;
        !           253:     xmlXPathCompExprPtr comp;
        !           254: 
        !           255:     if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
        !           256:         return(NULL);
        !           257:     ctxtXPath->doc = cur->doc;
        !           258:     ctxtXPath->node = cur;
        !           259:     comp = xmlXPathCompile(BAD_CAST xpath);
        !           260:     if (comp == NULL) {
        !           261:         fprintf(stderr, "Failed to compile %s\n", xpath);
        !           262:        return(NULL);
        !           263:     }
        !           264:     res = xmlXPathCompiledEval(comp, ctxtXPath);
        !           265:     xmlXPathFreeCompExpr(comp);
        !           266:     if (res == NULL)
        !           267:         return(NULL);
        !           268:     if ((res->type == XPATH_NODESET) &&
        !           269:         (res->nodesetval != NULL) &&
        !           270:        (res->nodesetval->nodeNr > 0) &&
        !           271:        (res->nodesetval->nodeTab != NULL))
        !           272:        ret = res->nodesetval->nodeTab[0];
        !           273:     xmlXPathFreeObject(res);
        !           274:     return(ret);
        !           275: }
        !           276: 
        !           277: static xmlChar *
        !           278: getString(xmlNodePtr cur, const char *xpath) {
        !           279:     xmlChar *ret = NULL;
        !           280:     xmlXPathObjectPtr res;
        !           281:     xmlXPathCompExprPtr comp;
        !           282: 
        !           283:     if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
        !           284:         return(NULL);
        !           285:     ctxtXPath->doc = cur->doc;
        !           286:     ctxtXPath->node = cur;
        !           287:     comp = xmlXPathCompile(BAD_CAST xpath);
        !           288:     if (comp == NULL) {
        !           289:         fprintf(stderr, "Failed to compile %s\n", xpath);
        !           290:        return(NULL);
        !           291:     }
        !           292:     res = xmlXPathCompiledEval(comp, ctxtXPath);
        !           293:     xmlXPathFreeCompExpr(comp);
        !           294:     if (res == NULL)
        !           295:         return(NULL);
        !           296:     if (res->type == XPATH_STRING) {
        !           297:         ret = res->stringval;
        !           298:        res->stringval = NULL;
        !           299:     }
        !           300:     xmlXPathFreeObject(res);
        !           301:     return(ret);
        !           302: }
        !           303: 
        !           304: /************************************************************************
        !           305:  *                                                                     *
        !           306:  *             Test test/xsdtest/xsdtestsuite.xml                      *
        !           307:  *                                                                     *
        !           308:  ************************************************************************/
        !           309: 
        !           310: static int
        !           311: xsdIncorectTestCase(xmlNodePtr cur) {
        !           312:     xmlNodePtr test;
        !           313:     xmlBufferPtr buf;
        !           314:     xmlRelaxNGParserCtxtPtr pctxt;
        !           315:     xmlRelaxNGPtr rng = NULL;
        !           316:     int ret = 0, memt;
        !           317: 
        !           318:     cur = getNext(cur, "./incorrect[1]");
        !           319:     if (cur == NULL) {
        !           320:         return(0);
        !           321:     }
        !           322: 
        !           323:     test = getNext(cur, "./*");
        !           324:     if (test == NULL) {
        !           325:         test_log("Failed to find test in correct line %ld\n",
        !           326:                xmlGetLineNo(cur));
        !           327:         return(1);
        !           328:     }
        !           329: 
        !           330:     memt = xmlMemUsed();
        !           331:     extraMemoryFromResolver = 0;
        !           332:     /*
        !           333:      * dump the schemas to a buffer, then reparse it and compile the schemas
        !           334:      */
        !           335:     buf = xmlBufferCreate();
        !           336:     if (buf == NULL) {
        !           337:         fprintf(stderr, "out of memory !\n");
        !           338:        fatalError();
        !           339:     }
        !           340:     xmlNodeDump(buf, test->doc, test, 0, 0);
        !           341:     pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
        !           342:     xmlRelaxNGSetParserErrors(pctxt,
        !           343:          (xmlRelaxNGValidityErrorFunc) testErrorHandler,
        !           344:          (xmlRelaxNGValidityWarningFunc) testErrorHandler,
        !           345:         pctxt);
        !           346:     rng = xmlRelaxNGParse(pctxt);
        !           347:     xmlRelaxNGFreeParserCtxt(pctxt);
        !           348:     if (rng != NULL) {
        !           349:        test_log("Failed to detect incorect RNG line %ld\n",
        !           350:                    xmlGetLineNo(test));
        !           351:         ret = 1;
        !           352:        goto done;
        !           353:     }
        !           354: 
        !           355: done:
        !           356:     if (buf != NULL)
        !           357:        xmlBufferFree(buf);
        !           358:     if (rng != NULL)
        !           359:         xmlRelaxNGFree(rng);
        !           360:     xmlResetLastError();
        !           361:     if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
        !           362:        test_log("Validation of tests starting line %ld leaked %d\n",
        !           363:                xmlGetLineNo(cur), xmlMemUsed() - memt);
        !           364:        nb_leaks++;
        !           365:     }
        !           366:     return(ret);
        !           367: }
        !           368: 
        !           369: static void
        !           370: installResources(xmlNodePtr tst, const xmlChar *base) {
        !           371:     xmlNodePtr test;
        !           372:     xmlBufferPtr buf;
        !           373:     xmlChar *name, *content, *res;
        !           374: 
        !           375:     buf = xmlBufferCreate();
        !           376:     if (buf == NULL) {
        !           377:         fprintf(stderr, "out of memory !\n");
        !           378:        fatalError();
        !           379:     }
        !           380:     xmlNodeDump(buf, tst->doc, tst, 0, 0);
        !           381: 
        !           382:     while (tst != NULL) {
        !           383:        test = getNext(tst, "./*");
        !           384:        if (test != NULL) {
        !           385:            xmlBufferEmpty(buf);
        !           386:            xmlNodeDump(buf, test->doc, test, 0, 0);
        !           387:            name = getString(tst, "string(@name)");
        !           388:            content = xmlStrdup(buf->content);
        !           389:            if ((name != NULL) && (content != NULL)) {
        !           390:                res = composeDir(base, name);
        !           391:                xmlFree(name);
        !           392:                addEntity((char *) res, (char *) content);
        !           393:            } else {
        !           394:                if (name != NULL) xmlFree(name);
        !           395:                if (content != NULL) xmlFree(content);
        !           396:            }
        !           397:        }
        !           398:        tst = getNext(tst, "following-sibling::resource[1]");
        !           399:     }
        !           400:     if (buf != NULL)
        !           401:        xmlBufferFree(buf);
        !           402: }
        !           403: 
        !           404: static void
        !           405: installDirs(xmlNodePtr tst, const xmlChar *base) {
        !           406:     xmlNodePtr test;
        !           407:     xmlChar *name, *res;
        !           408: 
        !           409:     name = getString(tst, "string(@name)");
        !           410:     if (name == NULL)
        !           411:         return;
        !           412:     res = composeDir(base, name);
        !           413:     xmlFree(name);
        !           414:     if (res == NULL) {
        !           415:        return;
        !           416:     }
        !           417:     /* Now process resources and subdir recursively */
        !           418:     test = getNext(tst, "./resource[1]");
        !           419:     if (test != NULL) {
        !           420:         installResources(test, res);
        !           421:     }
        !           422:     test = getNext(tst, "./dir[1]");
        !           423:     while (test != NULL) {
        !           424:         installDirs(test, res);
        !           425:        test = getNext(test, "following-sibling::dir[1]");
        !           426:     }
        !           427:     xmlFree(res);
        !           428: }
        !           429: 
        !           430: static int 
        !           431: xsdTestCase(xmlNodePtr tst) {
        !           432:     xmlNodePtr test, tmp, cur;
        !           433:     xmlBufferPtr buf;
        !           434:     xmlDocPtr doc = NULL;
        !           435:     xmlRelaxNGParserCtxtPtr pctxt;
        !           436:     xmlRelaxNGValidCtxtPtr ctxt;
        !           437:     xmlRelaxNGPtr rng = NULL;
        !           438:     int ret = 0, mem, memt;
        !           439:     xmlChar *dtd;
        !           440: 
        !           441:     resetEntities();
        !           442:     testErrorsSize = 0; testErrors[0] = 0;
        !           443: 
        !           444:     tmp = getNext(tst, "./dir[1]");
        !           445:     if (tmp != NULL) {
        !           446:         installDirs(tmp, NULL);
        !           447:     }
        !           448:     tmp = getNext(tst, "./resource[1]");
        !           449:     if (tmp != NULL) {
        !           450:         installResources(tmp, NULL);
        !           451:     }
        !           452: 
        !           453:     cur = getNext(tst, "./correct[1]");
        !           454:     if (cur == NULL) {
        !           455:         return(xsdIncorectTestCase(tst));
        !           456:     }
        !           457:     
        !           458:     test = getNext(cur, "./*");
        !           459:     if (test == NULL) {
        !           460:         fprintf(stderr, "Failed to find test in correct line %ld\n",
        !           461:                xmlGetLineNo(cur));
        !           462:         return(1);
        !           463:     }
        !           464: 
        !           465:     memt = xmlMemUsed();
        !           466:     extraMemoryFromResolver = 0;
        !           467:     /*
        !           468:      * dump the schemas to a buffer, then reparse it and compile the schemas
        !           469:      */
        !           470:     buf = xmlBufferCreate();
        !           471:     if (buf == NULL) {
        !           472:         fprintf(stderr, "out of memory !\n");
        !           473:        fatalError();
        !           474:     }
        !           475:     xmlNodeDump(buf, test->doc, test, 0, 0);
        !           476:     pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
        !           477:     xmlRelaxNGSetParserErrors(pctxt,
        !           478:          (xmlRelaxNGValidityErrorFunc) testErrorHandler,
        !           479:          (xmlRelaxNGValidityWarningFunc) testErrorHandler,
        !           480:         pctxt);
        !           481:     rng = xmlRelaxNGParse(pctxt);
        !           482:     xmlRelaxNGFreeParserCtxt(pctxt);
        !           483:     if (extraMemoryFromResolver)
        !           484:         memt = 0;
        !           485: 
        !           486:     if (rng == NULL) {
        !           487:         test_log("Failed to parse RNGtest line %ld\n",
        !           488:                xmlGetLineNo(test));
        !           489:        nb_errors++;
        !           490:         ret = 1;
        !           491:        goto done;
        !           492:     }
        !           493:     /*
        !           494:      * now scan all the siblings of correct to process the <valid> tests
        !           495:      */
        !           496:     tmp = getNext(cur, "following-sibling::valid[1]");
        !           497:     while (tmp != NULL) {
        !           498:        dtd = xmlGetProp(tmp, BAD_CAST "dtd");
        !           499:        test = getNext(tmp, "./*");
        !           500:        if (test == NULL) {
        !           501:            fprintf(stderr, "Failed to find test in <valid> line %ld\n",
        !           502:                    xmlGetLineNo(tmp));
        !           503:            
        !           504:        } else {
        !           505:            xmlBufferEmpty(buf);
        !           506:            if (dtd != NULL)
        !           507:                xmlBufferAdd(buf, dtd, -1);
        !           508:            xmlNodeDump(buf, test->doc, test, 0, 0);
        !           509: 
        !           510:            /*
        !           511:             * We are ready to run the test
        !           512:             */
        !           513:            mem = xmlMemUsed();
        !           514:            extraMemoryFromResolver = 0;
        !           515:             doc = xmlReadMemory((const char *)buf->content, buf->use,
        !           516:                                "test", NULL, 0);
        !           517:            if (doc == NULL) {
        !           518:                test_log("Failed to parse valid instance line %ld\n",
        !           519:                        xmlGetLineNo(tmp));
        !           520:                nb_errors++;
        !           521:            } else {
        !           522:                nb_tests++;
        !           523:                ctxt = xmlRelaxNGNewValidCtxt(rng);
        !           524:                xmlRelaxNGSetValidErrors(ctxt,
        !           525:                     (xmlRelaxNGValidityErrorFunc) testErrorHandler,
        !           526:                     (xmlRelaxNGValidityWarningFunc) testErrorHandler,
        !           527:                     ctxt);
        !           528:                ret = xmlRelaxNGValidateDoc(ctxt, doc);
        !           529:                xmlRelaxNGFreeValidCtxt(ctxt);
        !           530:                if (ret > 0) {
        !           531:                    test_log("Failed to validate valid instance line %ld\n",
        !           532:                                xmlGetLineNo(tmp));
        !           533:                    nb_errors++;
        !           534:                } else if (ret < 0) {
        !           535:                    test_log("Internal error validating instance line %ld\n",
        !           536:                            xmlGetLineNo(tmp));
        !           537:                    nb_errors++;
        !           538:                }
        !           539:                xmlFreeDoc(doc);
        !           540:            }
        !           541:            xmlResetLastError();
        !           542:            if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
        !           543:                test_log("Validation of instance line %ld leaked %d\n",
        !           544:                        xmlGetLineNo(tmp), xmlMemUsed() - mem);
        !           545:                xmlMemoryDump();
        !           546:                nb_leaks++;
        !           547:            }
        !           548:        }
        !           549:        if (dtd != NULL)
        !           550:            xmlFree(dtd);
        !           551:        tmp = getNext(tmp, "following-sibling::valid[1]");
        !           552:     }
        !           553:     /*
        !           554:      * now scan all the siblings of correct to process the <invalid> tests
        !           555:      */
        !           556:     tmp = getNext(cur, "following-sibling::invalid[1]");
        !           557:     while (tmp != NULL) {
        !           558:        test = getNext(tmp, "./*");
        !           559:        if (test == NULL) {
        !           560:            fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
        !           561:                    xmlGetLineNo(tmp));
        !           562:            
        !           563:        } else {
        !           564:            xmlBufferEmpty(buf);
        !           565:            xmlNodeDump(buf, test->doc, test, 0, 0);
        !           566: 
        !           567:            /*
        !           568:             * We are ready to run the test
        !           569:             */
        !           570:            mem = xmlMemUsed();
        !           571:            extraMemoryFromResolver = 0;
        !           572:             doc = xmlReadMemory((const char *)buf->content, buf->use,
        !           573:                                "test", NULL, 0);
        !           574:            if (doc == NULL) {
        !           575:                test_log("Failed to parse valid instance line %ld\n",
        !           576:                        xmlGetLineNo(tmp));
        !           577:                nb_errors++;
        !           578:            } else {
        !           579:                nb_tests++;
        !           580:                ctxt = xmlRelaxNGNewValidCtxt(rng);
        !           581:                xmlRelaxNGSetValidErrors(ctxt,
        !           582:                     (xmlRelaxNGValidityErrorFunc) testErrorHandler,
        !           583:                     (xmlRelaxNGValidityWarningFunc) testErrorHandler,
        !           584:                     ctxt);
        !           585:                ret = xmlRelaxNGValidateDoc(ctxt, doc);
        !           586:                xmlRelaxNGFreeValidCtxt(ctxt);
        !           587:                if (ret == 0) {
        !           588:                    test_log("Failed to detect invalid instance line %ld\n",
        !           589:                                xmlGetLineNo(tmp));
        !           590:                    nb_errors++;
        !           591:                } else if (ret < 0) {
        !           592:                    test_log("Internal error validating instance line %ld\n",
        !           593:                            xmlGetLineNo(tmp));
        !           594:                    nb_errors++;
        !           595:                }
        !           596:                xmlFreeDoc(doc);
        !           597:            }
        !           598:            xmlResetLastError();
        !           599:            if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
        !           600:                test_log("Validation of instance line %ld leaked %d\n",
        !           601:                        xmlGetLineNo(tmp), xmlMemUsed() - mem);
        !           602:                xmlMemoryDump();
        !           603:                nb_leaks++;
        !           604:            }
        !           605:        }
        !           606:        tmp = getNext(tmp, "following-sibling::invalid[1]");
        !           607:     }
        !           608: 
        !           609: done:
        !           610:     if (buf != NULL)
        !           611:        xmlBufferFree(buf);
        !           612:     if (rng != NULL)
        !           613:         xmlRelaxNGFree(rng);
        !           614:     xmlResetLastError();
        !           615:     if ((memt != xmlMemUsed()) && (memt != 0)) {
        !           616:        test_log("Validation of tests starting line %ld leaked %d\n",
        !           617:                xmlGetLineNo(cur), xmlMemUsed() - memt);
        !           618:        nb_leaks++;
        !           619:     }
        !           620:     return(ret);
        !           621: }
        !           622: 
        !           623: static int 
        !           624: xsdTestSuite(xmlNodePtr cur) {
        !           625:     if (verbose) {
        !           626:        xmlChar *doc = getString(cur, "string(documentation)");
        !           627: 
        !           628:        if (doc != NULL) {
        !           629:            printf("Suite %s\n", doc);
        !           630:            xmlFree(doc);
        !           631:        }
        !           632:     }
        !           633:     cur = getNext(cur, "./testCase[1]");
        !           634:     while (cur != NULL) {
        !           635:         xsdTestCase(cur);
        !           636:        cur = getNext(cur, "following-sibling::testCase[1]");
        !           637:     }
        !           638:         
        !           639:     return(0);
        !           640: }
        !           641: 
        !           642: static int 
        !           643: xsdTest(void) {
        !           644:     xmlDocPtr doc;
        !           645:     xmlNodePtr cur;
        !           646:     const char *filename = "test/xsdtest/xsdtestsuite.xml";
        !           647:     int ret = 0;
        !           648: 
        !           649:     doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
        !           650:     if (doc == NULL) {
        !           651:         fprintf(stderr, "Failed to parse %s\n", filename);
        !           652:        return(-1);
        !           653:     }
        !           654:     printf("## XML Schemas datatypes test suite from James Clark\n");
        !           655: 
        !           656:     cur = xmlDocGetRootElement(doc);
        !           657:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        !           658:         fprintf(stderr, "Unexpected format %s\n", filename);
        !           659:        ret = -1;
        !           660:        goto done;
        !           661:     }
        !           662: 
        !           663:     cur = getNext(cur, "./testSuite[1]");
        !           664:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        !           665:         fprintf(stderr, "Unexpected format %s\n", filename);
        !           666:        ret = -1;
        !           667:        goto done;
        !           668:     }
        !           669:     while (cur != NULL) {
        !           670:         xsdTestSuite(cur);
        !           671:        cur = getNext(cur, "following-sibling::testSuite[1]");
        !           672:     }
        !           673: 
        !           674: done:
        !           675:     if (doc != NULL)
        !           676:        xmlFreeDoc(doc);
        !           677:     return(ret);
        !           678: }
        !           679: 
        !           680: static int 
        !           681: rngTestSuite(xmlNodePtr cur) {
        !           682:     if (verbose) {
        !           683:        xmlChar *doc = getString(cur, "string(documentation)");
        !           684: 
        !           685:        if (doc != NULL) {
        !           686:            printf("Suite %s\n", doc);
        !           687:            xmlFree(doc);
        !           688:        } else {
        !           689:            doc = getString(cur, "string(section)");
        !           690:            if (doc != NULL) {
        !           691:                printf("Section %s\n", doc);
        !           692:                xmlFree(doc);
        !           693:            }
        !           694:        }
        !           695:     }
        !           696:     cur = getNext(cur, "./testSuite[1]");
        !           697:     while (cur != NULL) {
        !           698:         xsdTestSuite(cur);
        !           699:        cur = getNext(cur, "following-sibling::testSuite[1]");
        !           700:     }
        !           701:         
        !           702:     return(0);
        !           703: }
        !           704: 
        !           705: static int 
        !           706: rngTest1(void) {
        !           707:     xmlDocPtr doc;
        !           708:     xmlNodePtr cur;
        !           709:     const char *filename = "test/relaxng/OASIS/spectest.xml";
        !           710:     int ret = 0;
        !           711: 
        !           712:     doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
        !           713:     if (doc == NULL) {
        !           714:         fprintf(stderr, "Failed to parse %s\n", filename);
        !           715:        return(-1);
        !           716:     }
        !           717:     printf("## Relax NG test suite from James Clark\n");
        !           718: 
        !           719:     cur = xmlDocGetRootElement(doc);
        !           720:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        !           721:         fprintf(stderr, "Unexpected format %s\n", filename);
        !           722:        ret = -1;
        !           723:        goto done;
        !           724:     }
        !           725: 
        !           726:     cur = getNext(cur, "./testSuite[1]");
        !           727:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        !           728:         fprintf(stderr, "Unexpected format %s\n", filename);
        !           729:        ret = -1;
        !           730:        goto done;
        !           731:     }
        !           732:     while (cur != NULL) {
        !           733:         rngTestSuite(cur);
        !           734:        cur = getNext(cur, "following-sibling::testSuite[1]");
        !           735:     }
        !           736: 
        !           737: done:
        !           738:     if (doc != NULL)
        !           739:        xmlFreeDoc(doc);
        !           740:     return(ret);
        !           741: }
        !           742: 
        !           743: static int 
        !           744: rngTest2(void) {
        !           745:     xmlDocPtr doc;
        !           746:     xmlNodePtr cur;
        !           747:     const char *filename = "test/relaxng/testsuite.xml";
        !           748:     int ret = 0;
        !           749: 
        !           750:     doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
        !           751:     if (doc == NULL) {
        !           752:         fprintf(stderr, "Failed to parse %s\n", filename);
        !           753:        return(-1);
        !           754:     }
        !           755:     printf("## Relax NG test suite for libxml2\n");
        !           756: 
        !           757:     cur = xmlDocGetRootElement(doc);
        !           758:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        !           759:         fprintf(stderr, "Unexpected format %s\n", filename);
        !           760:        ret = -1;
        !           761:        goto done;
        !           762:     }
        !           763: 
        !           764:     cur = getNext(cur, "./testSuite[1]");
        !           765:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
        !           766:         fprintf(stderr, "Unexpected format %s\n", filename);
        !           767:        ret = -1;
        !           768:        goto done;
        !           769:     }
        !           770:     while (cur != NULL) {
        !           771:         xsdTestSuite(cur);
        !           772:        cur = getNext(cur, "following-sibling::testSuite[1]");
        !           773:     }
        !           774: 
        !           775: done:
        !           776:     if (doc != NULL)
        !           777:        xmlFreeDoc(doc);
        !           778:     return(ret);
        !           779: }
        !           780: 
        !           781: /************************************************************************
        !           782:  *                                                                     *
        !           783:  *             Schemas test suites from W3C/NIST/MS/Sun                *
        !           784:  *                                                                     *
        !           785:  ************************************************************************/
        !           786: 
        !           787: static int
        !           788: xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
        !           789:                  const xmlChar *spath, const char *base) {
        !           790:     xmlChar *href = NULL;
        !           791:     xmlChar *path = NULL;
        !           792:     xmlChar *validity = NULL;
        !           793:     xmlSchemaValidCtxtPtr ctxt = NULL;
        !           794:     xmlDocPtr doc = NULL;
        !           795:     int ret = 0, mem;
        !           796: 
        !           797:     xmlResetLastError();
        !           798:     testErrorsSize = 0; testErrors[0] = 0;
        !           799:     mem = xmlMemUsed();
        !           800:     href = getString(cur,
        !           801:                      "string(ts:instanceDocument/@xlink:href)");
        !           802:     if ((href == NULL) || (href[0] == 0)) {
        !           803:        test_log("testGroup line %ld misses href for schemaDocument\n",
        !           804:                    xmlGetLineNo(cur));
        !           805:        ret = -1;
        !           806:        goto done;
        !           807:     }
        !           808:     path = xmlBuildURI(href, BAD_CAST base);
        !           809:     if (path == NULL) {
        !           810:        fprintf(stderr,
        !           811:                "Failed to build path to schemas testGroup line %ld : %s\n",
        !           812:                xmlGetLineNo(cur), href);
        !           813:        ret = -1;
        !           814:        goto done;
        !           815:     }
        !           816:     if (checkTestFile((const char *) path) <= 0) {
        !           817:        test_log("schemas for testGroup line %ld is missing: %s\n",
        !           818:                xmlGetLineNo(cur), path);
        !           819:        ret = -1;
        !           820:        goto done;
        !           821:     }
        !           822:     validity = getString(cur,
        !           823:                          "string(ts:expected/@validity)");
        !           824:     if (validity == NULL) {
        !           825:         fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
        !           826:                xmlGetLineNo(cur));
        !           827:        ret = -1;
        !           828:        goto done;
        !           829:     }
        !           830:     nb_tests++;
        !           831:     doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
        !           832:     if (doc == NULL) {
        !           833:         fprintf(stderr, "instance %s fails to parse\n", path);
        !           834:        ret = -1;
        !           835:        nb_errors++;
        !           836:        goto done;
        !           837:     }
        !           838: 
        !           839:     ctxt = xmlSchemaNewValidCtxt(schemas);
        !           840:     xmlSchemaSetValidErrors(ctxt,
        !           841:          (xmlSchemaValidityErrorFunc) testErrorHandler,
        !           842:          (xmlSchemaValidityWarningFunc) testErrorHandler,
        !           843:         ctxt);
        !           844:     ret = xmlSchemaValidateDoc(ctxt, doc);
        !           845: 
        !           846:     if (xmlStrEqual(validity, BAD_CAST "valid")) {
        !           847:        if (ret > 0) {
        !           848:            test_log("valid instance %s failed to validate against %s\n",
        !           849:                        path, spath);
        !           850:            nb_errors++;
        !           851:        } else if (ret < 0) {
        !           852:            test_log("valid instance %s got internal error validating %s\n",
        !           853:                        path, spath);
        !           854:            nb_internals++;
        !           855:            nb_errors++;
        !           856:        }
        !           857:     } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
        !           858:        if (ret == 0) {
        !           859:            test_log("Failed to detect invalid instance %s against %s\n",
        !           860:                        path, spath);
        !           861:            nb_errors++;
        !           862:        }
        !           863:     } else {
        !           864:         test_log("instanceDocument line %ld has unexpected validity value%s\n",
        !           865:                xmlGetLineNo(cur), validity);
        !           866:        ret = -1;
        !           867:        goto done;
        !           868:     }
        !           869: 
        !           870: done:
        !           871:     if (href != NULL) xmlFree(href);
        !           872:     if (path != NULL) xmlFree(path);
        !           873:     if (validity != NULL) xmlFree(validity);
        !           874:     if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
        !           875:     if (doc != NULL) xmlFreeDoc(doc);
        !           876:     xmlResetLastError();
        !           877:     if (mem != xmlMemUsed()) {
        !           878:        test_log("Validation of tests starting line %ld leaked %d\n",
        !           879:                xmlGetLineNo(cur), xmlMemUsed() - mem);
        !           880:        nb_leaks++;
        !           881:     }
        !           882:     return(ret);
        !           883: }
        !           884: 
        !           885: static int
        !           886: xstcTestGroup(xmlNodePtr cur, const char *base) {
        !           887:     xmlChar *href = NULL;
        !           888:     xmlChar *path = NULL;
        !           889:     xmlChar *validity = NULL;
        !           890:     xmlSchemaPtr schemas = NULL;
        !           891:     xmlSchemaParserCtxtPtr ctxt;
        !           892:     xmlNodePtr instance;
        !           893:     int ret = 0, mem;
        !           894: 
        !           895:     xmlResetLastError();
        !           896:     testErrorsSize = 0; testErrors[0] = 0;
        !           897:     mem = xmlMemUsed();
        !           898:     href = getString(cur,
        !           899:                      "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
        !           900:     if ((href == NULL) || (href[0] == 0)) {
        !           901:         test_log("testGroup line %ld misses href for schemaDocument\n",
        !           902:                    xmlGetLineNo(cur));
        !           903:        ret = -1;
        !           904:        goto done;
        !           905:     }
        !           906:     path = xmlBuildURI(href, BAD_CAST base);
        !           907:     if (path == NULL) {
        !           908:        test_log("Failed to build path to schemas testGroup line %ld : %s\n",
        !           909:                xmlGetLineNo(cur), href);
        !           910:        ret = -1;
        !           911:        goto done;
        !           912:     }
        !           913:     if (checkTestFile((const char *) path) <= 0) {
        !           914:        test_log("schemas for testGroup line %ld is missing: %s\n",
        !           915:                xmlGetLineNo(cur), path);
        !           916:        ret = -1;
        !           917:        goto done;
        !           918:     }
        !           919:     validity = getString(cur,
        !           920:                          "string(ts:schemaTest/ts:expected/@validity)");
        !           921:     if (validity == NULL) {
        !           922:         test_log("testGroup line %ld misses expected validity\n",
        !           923:                xmlGetLineNo(cur));
        !           924:        ret = -1;
        !           925:        goto done;
        !           926:     }
        !           927:     nb_tests++;
        !           928:     if (xmlStrEqual(validity, BAD_CAST "valid")) {
        !           929:         nb_schematas++;
        !           930:        ctxt = xmlSchemaNewParserCtxt((const char *) path);
        !           931:        xmlSchemaSetParserErrors(ctxt,
        !           932:             (xmlSchemaValidityErrorFunc) testErrorHandler,
        !           933:             (xmlSchemaValidityWarningFunc) testErrorHandler,
        !           934:             ctxt);
        !           935:        schemas = xmlSchemaParse(ctxt);
        !           936:        xmlSchemaFreeParserCtxt(ctxt);
        !           937:        if (schemas == NULL) {
        !           938:            test_log("valid schemas %s failed to parse\n",
        !           939:                        path);
        !           940:            ret = 1;
        !           941:            nb_errors++;
        !           942:        }
        !           943:        if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
        !           944:            test_log("valid schemas %s hit an unimplemented block\n",
        !           945:                        path);
        !           946:            ret = 1;
        !           947:            nb_unimplemented++;
        !           948:            nb_errors++;
        !           949:        }
        !           950:        instance = getNext(cur, "./ts:instanceTest[1]");
        !           951:        while (instance != NULL) {
        !           952:            if (schemas != NULL) {
        !           953:                xstcTestInstance(instance, schemas, path, base);                
        !           954:            } else {
        !           955:                /*
        !           956:                * We'll automatically mark the instances as failed
        !           957:                * if the schema was broken.
        !           958:                */
        !           959:                nb_errors++;
        !           960:            }
        !           961:            instance = getNext(instance,
        !           962:                "following-sibling::ts:instanceTest[1]");
        !           963:        }
        !           964:     } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
        !           965:         nb_schematas++;
        !           966:        ctxt = xmlSchemaNewParserCtxt((const char *) path);
        !           967:        xmlSchemaSetParserErrors(ctxt,
        !           968:             (xmlSchemaValidityErrorFunc) testErrorHandler,
        !           969:             (xmlSchemaValidityWarningFunc) testErrorHandler,
        !           970:             ctxt);
        !           971:        schemas = xmlSchemaParse(ctxt);
        !           972:        xmlSchemaFreeParserCtxt(ctxt);
        !           973:        if (schemas != NULL) {
        !           974:            test_log("Failed to detect error in schemas %s\n",
        !           975:                        path);
        !           976:            nb_errors++;
        !           977:            ret = 1;
        !           978:        }
        !           979:        if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
        !           980:            nb_unimplemented++;
        !           981:            test_log("invalid schemas %s hit an unimplemented block\n",
        !           982:                        path);
        !           983:            ret = 1;
        !           984:            nb_errors++;
        !           985:        }
        !           986:     } else {
        !           987:         test_log("testGroup line %ld misses unexpected validity value%s\n",
        !           988:                xmlGetLineNo(cur), validity);
        !           989:        ret = -1;
        !           990:        goto done;
        !           991:     }
        !           992: 
        !           993: done:
        !           994:     if (href != NULL) xmlFree(href);
        !           995:     if (path != NULL) xmlFree(path);
        !           996:     if (validity != NULL) xmlFree(validity);
        !           997:     if (schemas != NULL) xmlSchemaFree(schemas);
        !           998:     xmlResetLastError();
        !           999:     if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
        !          1000:        test_log("Processing test line %ld %s leaked %d\n",
        !          1001:                xmlGetLineNo(cur), path, xmlMemUsed() - mem);
        !          1002:        nb_leaks++;
        !          1003:     }
        !          1004:     return(ret);
        !          1005: }
        !          1006: 
        !          1007: static int
        !          1008: xstcMetadata(const char *metadata, const char *base) {
        !          1009:     xmlDocPtr doc;
        !          1010:     xmlNodePtr cur;
        !          1011:     xmlChar *contributor;
        !          1012:     xmlChar *name;
        !          1013:     int ret = 0;
        !          1014: 
        !          1015:     doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
        !          1016:     if (doc == NULL) {
        !          1017:         fprintf(stderr, "Failed to parse %s\n", metadata);
        !          1018:        return(-1);
        !          1019:     }
        !          1020: 
        !          1021:     cur = xmlDocGetRootElement(doc);
        !          1022:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
        !          1023:         fprintf(stderr, "Unexpected format %s\n", metadata);
        !          1024:        return(-1);
        !          1025:     }
        !          1026:     contributor = xmlGetProp(cur, BAD_CAST "contributor");
        !          1027:     if (contributor == NULL) {
        !          1028:         contributor = xmlStrdup(BAD_CAST "Unknown");
        !          1029:     }
        !          1030:     name = xmlGetProp(cur, BAD_CAST "name");
        !          1031:     if (name == NULL) {
        !          1032:         name = xmlStrdup(BAD_CAST "Unknown");
        !          1033:     }
        !          1034:     printf("## %s test suite for Schemas version %s\n", contributor, name);
        !          1035:     xmlFree(contributor);
        !          1036:     xmlFree(name);
        !          1037: 
        !          1038:     cur = getNext(cur, "./ts:testGroup[1]");
        !          1039:     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
        !          1040:         fprintf(stderr, "Unexpected format %s\n", metadata);
        !          1041:        ret = -1;
        !          1042:        goto done;
        !          1043:     }
        !          1044:     while (cur != NULL) {
        !          1045:         xstcTestGroup(cur, base);
        !          1046:        cur = getNext(cur, "following-sibling::ts:testGroup[1]");
        !          1047:     }
        !          1048: 
        !          1049: done:
        !          1050:     xmlFreeDoc(doc);
        !          1051:     return(ret);
        !          1052: }
        !          1053: 
        !          1054: /************************************************************************
        !          1055:  *                                                                     *
        !          1056:  *             The driver for the tests                                *
        !          1057:  *                                                                     *
        !          1058:  ************************************************************************/
        !          1059: 
        !          1060: int
        !          1061: main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
        !          1062:     int ret = 0;
        !          1063:     int old_errors, old_tests, old_leaks;
        !          1064: 
        !          1065:     logfile = fopen(LOGFILE, "w");
        !          1066:     if (logfile == NULL) {
        !          1067:         fprintf(stderr,
        !          1068:                "Could not open the log file, running in verbose mode\n");
        !          1069:        verbose = 1;
        !          1070:     }
        !          1071:     initializeLibxml2();
        !          1072: 
        !          1073:     if ((argc >= 2) && (!strcmp(argv[1], "-v")))
        !          1074:         verbose = 1;
        !          1075: 
        !          1076: 
        !          1077:     old_errors = nb_errors;
        !          1078:     old_tests = nb_tests;
        !          1079:     old_leaks = nb_leaks;
        !          1080:     xsdTest();
        !          1081:     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
        !          1082:        printf("Ran %d tests, no errors\n", nb_tests - old_tests);
        !          1083:     else
        !          1084:        printf("Ran %d tests, %d errors, %d leaks\n",
        !          1085:               nb_tests - old_tests,
        !          1086:               nb_errors - old_errors,
        !          1087:               nb_leaks - old_leaks);
        !          1088:     old_errors = nb_errors;
        !          1089:     old_tests = nb_tests;
        !          1090:     old_leaks = nb_leaks;
        !          1091:     rngTest1();
        !          1092:     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
        !          1093:        printf("Ran %d tests, no errors\n", nb_tests - old_tests);
        !          1094:     else
        !          1095:        printf("Ran %d tests, %d errors, %d leaks\n",
        !          1096:               nb_tests - old_tests,
        !          1097:               nb_errors - old_errors,
        !          1098:               nb_leaks - old_leaks);
        !          1099:     old_errors = nb_errors;
        !          1100:     old_tests = nb_tests;
        !          1101:     old_leaks = nb_leaks;
        !          1102:     rngTest2();
        !          1103:     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
        !          1104:        printf("Ran %d tests, no errors\n", nb_tests - old_tests);
        !          1105:     else
        !          1106:        printf("Ran %d tests, %d errors, %d leaks\n",
        !          1107:               nb_tests - old_tests,
        !          1108:               nb_errors - old_errors,
        !          1109:               nb_leaks - old_leaks);
        !          1110:     old_errors = nb_errors;
        !          1111:     old_tests = nb_tests;
        !          1112:     old_leaks = nb_leaks;
        !          1113:     nb_internals = 0;
        !          1114:     nb_schematas = 0;
        !          1115:     xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
        !          1116:                 "xstc/Tests/Metadata/");
        !          1117:     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
        !          1118:        printf("Ran %d tests (%d schemata), no errors\n",
        !          1119:               nb_tests - old_tests, nb_schematas);
        !          1120:     else
        !          1121:        printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
        !          1122:               nb_tests - old_tests,
        !          1123:               nb_schematas,
        !          1124:               nb_errors - old_errors,
        !          1125:               nb_internals,
        !          1126:               nb_leaks - old_leaks);
        !          1127:     old_errors = nb_errors;
        !          1128:     old_tests = nb_tests;
        !          1129:     old_leaks = nb_leaks;
        !          1130:     nb_internals = 0;
        !          1131:     nb_schematas = 0;
        !          1132:     xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
        !          1133:                 "xstc/Tests/");
        !          1134:     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
        !          1135:        printf("Ran %d tests (%d schemata), no errors\n",
        !          1136:               nb_tests - old_tests, nb_schematas);
        !          1137:     else
        !          1138:        printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
        !          1139:               nb_tests - old_tests,
        !          1140:               nb_schematas,
        !          1141:               nb_errors - old_errors,
        !          1142:               nb_internals,
        !          1143:               nb_leaks - old_leaks);
        !          1144:     old_errors = nb_errors;
        !          1145:     old_tests = nb_tests;
        !          1146:     old_leaks = nb_leaks;
        !          1147:     nb_internals = 0;
        !          1148:     nb_schematas = 0;
        !          1149:     xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
        !          1150:                 "xstc/Tests/");
        !          1151:     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
        !          1152:        printf("Ran %d tests (%d schemata), no errors\n",
        !          1153:               nb_tests - old_tests, nb_schematas);
        !          1154:     else
        !          1155:        printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
        !          1156:               nb_tests - old_tests,
        !          1157:               nb_schematas,
        !          1158:               nb_errors - old_errors,
        !          1159:               nb_internals,
        !          1160:               nb_leaks - old_leaks);
        !          1161: 
        !          1162:     if ((nb_errors == 0) && (nb_leaks == 0)) {
        !          1163:         ret = 0;
        !          1164:        printf("Total %d tests, no errors\n",
        !          1165:               nb_tests);
        !          1166:     } else {
        !          1167:         ret = 1;
        !          1168:        printf("Total %d tests, %d errors, %d leaks\n",
        !          1169:               nb_tests, nb_errors, nb_leaks);
        !          1170:     }
        !          1171:     xmlXPathFreeContext(ctxtXPath);
        !          1172:     xmlCleanupParser();
        !          1173:     xmlMemoryDump();
        !          1174: 
        !          1175:     if (logfile != NULL)
        !          1176:         fclose(logfile);
        !          1177:     return(ret);
        !          1178: }
        !          1179: #else /* !SCHEMAS */
        !          1180: int
        !          1181: main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
        !          1182:     fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
        !          1183: }
        !          1184: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>