Annotation of embedaddon/libxml2/runsuite.c, revision 1.1.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>