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

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

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