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

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

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