Annotation of XML/xmllint.c, revision 1.19

1.1       daniel      1: /*
                      2:  * xmllint.c : a small tester program for XML input.
                      3:  *
                      4:  * See Copyright for the status of this software.
                      5:  *
                      6:  * Daniel.Veillard@w3.org
                      7:  */
                      8: 
                      9: #ifdef WIN32
                     10: #include "win32config.h"
                     11: #else
                     12: #include "config.h"
                     13: #endif
                     14: 
                     15: #include <stdio.h>
                     16: #include <string.h>
                     17: #include <stdio.h>
                     18: #include <stdarg.h>
                     19: 
                     20: #ifdef HAVE_SYS_TYPES_H
                     21: #include <sys/types.h>
                     22: #endif
                     23: #ifdef HAVE_SYS_STAT_H
                     24: #include <sys/stat.h>
                     25: #endif
                     26: #ifdef HAVE_FCNTL_H
                     27: #include <fcntl.h>
                     28: #endif
                     29: #ifdef HAVE_UNISTD_H
                     30: #include <unistd.h>
                     31: #endif
1.7       veillard   32: #ifdef HAVE_SYS_MMAN_H
                     33: #include <sys/mman.h>
1.8       veillard   34: /* seems needed for Solaris */
1.9       veillard   35: #ifndef MAP_FAILED
                     36: #define MAP_FAILED ((void *) -1)
1.8       veillard   37: #endif
1.7       veillard   38: #endif
1.1       daniel     39: #ifdef HAVE_STDLIB_H
                     40: #include <stdlib.h>
                     41: #endif
                     42: #ifdef HAVE_LIBREADLINE
                     43: #include <readline/readline.h>
                     44: #ifdef HAVE_LIBHISTORY
                     45: #include <readline/history.h>
                     46: #endif
                     47: #endif
                     48: 
                     49: #include <libxml/xmlmemory.h>
                     50: #include <libxml/parser.h>
                     51: #include <libxml/parserInternals.h>
                     52: #include <libxml/HTMLparser.h>
                     53: #include <libxml/HTMLtree.h>
                     54: #include <libxml/tree.h>
                     55: #include <libxml/xpath.h>
                     56: #include <libxml/debugXML.h>
1.18      veillard   57: #include <libxml/xmlerror.h>
1.19    ! veillard   58: #ifdef LIBXML_XINCLUDE_ENABLED
        !            59: #include <libxml/xinclude.h>
        !            60: #endif
1.1       daniel     61: 
                     62: #ifdef LIBXML_DEBUG_ENABLED
                     63: static int debug = 0;
                     64: static int shell = 0;
                     65: static int debugent = 0;
                     66: #endif
                     67: static int copy = 0;
                     68: static int recovery = 0;
                     69: static int noent = 0;
                     70: static int noout = 0;
                     71: static int nowrap = 0;
                     72: static int valid = 0;
                     73: static int postvalid = 0;
1.16      veillard   74: static char * dtdvalid = NULL;
1.1       daniel     75: static int repeat = 0;
                     76: static int insert = 0;
                     77: static int compress = 0;
                     78: static int html = 0;
                     79: static int htmlout = 0;
                     80: static int push = 0;
1.7       veillard   81: #ifdef HAVE_SYS_MMAN_H
                     82: static int memory = 0;
                     83: #endif
1.1       daniel     84: static int noblanks = 0;
1.2       daniel     85: static int testIO = 0;
1.3       daniel     86: static char *encoding = NULL;
1.19    ! veillard   87: #ifdef LIBXML_XINCLUDE_ENABLED
        !            88: static int xinclude = 0;
        !            89: #endif
1.1       daniel     90: 
                     91: extern int xmlDoValidityCheckingDefaultValue;
                     92: extern int xmlGetWarningsDefaultValue;
                     93: 
                     94: /************************************************************************
                     95:  *                                                                     *
                     96:  *                     HTML ouput                                      *
                     97:  *                                                                     *
                     98:  ************************************************************************/
                     99: char buffer[50000];
                    100: 
                    101: void
                    102: xmlHTMLEncodeSend(void) {
                    103:     char *result;
                    104: 
                    105:     result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
                    106:     if (result) {
1.18      veillard  107:        xmlGenericError(xmlGenericErrorContext, "%s", result);
1.1       daniel    108:        xmlFree(result);
                    109:     }
                    110:     buffer[0] = 0;
                    111: }
                    112: 
                    113: /**
                    114:  * xmlHTMLPrintFileInfo:
                    115:  * @input:  an xmlParserInputPtr input
                    116:  * 
                    117:  * Displays the associated file and line informations for the current input
                    118:  */
                    119: 
                    120: void
                    121: xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
1.18      veillard  122:     xmlGenericError(xmlGenericErrorContext, "<p>");
1.1       daniel    123:     if (input != NULL) {
                    124:        if (input->filename) {
                    125:            sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
                    126:                    input->line);
                    127:        } else {
                    128:            sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
                    129:        }
                    130:     }
                    131:     xmlHTMLEncodeSend();
                    132: }
                    133: 
                    134: /**
                    135:  * xmlHTMLPrintFileContext:
                    136:  * @input:  an xmlParserInputPtr input
                    137:  * 
                    138:  * Displays current context within the input content for error tracking
                    139:  */
                    140: 
                    141: void
                    142: xmlHTMLPrintFileContext(xmlParserInputPtr input) {
                    143:     const xmlChar *cur, *base;
                    144:     int n;
                    145: 
                    146:     if (input == NULL) return;
1.18      veillard  147:     xmlGenericError(xmlGenericErrorContext, "<pre>\n");
1.1       daniel    148:     cur = input->cur;
                    149:     base = input->base;
                    150:     while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
                    151:        cur--;
                    152:     }
                    153:     n = 0;
                    154:     while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
                    155:         cur--;
                    156:     if ((*cur == '\n') || (*cur == '\r')) cur++;
                    157:     base = cur;
                    158:     n = 0;
                    159:     while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
                    160:         sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
                    161:        n++;
                    162:     }
                    163:     sprintf(&buffer[strlen(buffer)], "\n");
                    164:     cur = input->cur;
                    165:     while ((*cur == '\n') || (*cur == '\r'))
                    166:        cur--;
                    167:     n = 0;
                    168:     while ((cur != base) && (n++ < 80)) {
                    169:         sprintf(&buffer[strlen(buffer)], " ");
                    170:         base++;
                    171:     }
                    172:     sprintf(&buffer[strlen(buffer)],"^\n");
                    173:     xmlHTMLEncodeSend();
1.18      veillard  174:     xmlGenericError(xmlGenericErrorContext, "</pre>");
1.1       daniel    175: }
                    176: 
                    177: /**
                    178:  * xmlHTMLError:
                    179:  * @ctx:  an XML parser context
                    180:  * @msg:  the message to display/transmit
                    181:  * @...:  extra parameters for the message display
                    182:  * 
                    183:  * Display and format an error messages, gives file, line, position and
                    184:  * extra parameters.
                    185:  */
                    186: void
                    187: xmlHTMLError(void *ctx, const char *msg, ...)
                    188: {
                    189:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    190:     xmlParserInputPtr input;
                    191:     xmlParserInputPtr cur = NULL;
                    192:     va_list args;
                    193: 
                    194:     buffer[0] = 0;
                    195:     input = ctxt->input;
                    196:     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
                    197:        cur = input;
                    198:         input = ctxt->inputTab[ctxt->inputNr - 2];
                    199:     }
                    200:         
                    201:     xmlHTMLPrintFileInfo(input);
                    202: 
1.18      veillard  203:     xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
1.1       daniel    204:     va_start(args, msg);
                    205:     vsprintf(&buffer[strlen(buffer)], msg, args);
                    206:     va_end(args);
                    207:     xmlHTMLEncodeSend();
1.18      veillard  208:     xmlGenericError(xmlGenericErrorContext, "</p>\n");
1.1       daniel    209: 
                    210:     xmlHTMLPrintFileContext(input);
                    211:     xmlHTMLEncodeSend();
                    212: }
                    213: 
                    214: /**
                    215:  * xmlHTMLWarning:
                    216:  * @ctx:  an XML parser context
                    217:  * @msg:  the message to display/transmit
                    218:  * @...:  extra parameters for the message display
                    219:  * 
                    220:  * Display and format a warning messages, gives file, line, position and
                    221:  * extra parameters.
                    222:  */
                    223: void
                    224: xmlHTMLWarning(void *ctx, const char *msg, ...)
                    225: {
                    226:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    227:     xmlParserInputPtr input;
                    228:     xmlParserInputPtr cur = NULL;
                    229:     va_list args;
                    230: 
                    231:     buffer[0] = 0;
                    232:     input = ctxt->input;
                    233:     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
                    234:        cur = input;
                    235:         input = ctxt->inputTab[ctxt->inputNr - 2];
                    236:     }
                    237:         
                    238: 
                    239:     xmlHTMLPrintFileInfo(input);
                    240:         
1.18      veillard  241:     xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
1.1       daniel    242:     va_start(args, msg);
                    243:     vsprintf(&buffer[strlen(buffer)], msg, args);
                    244:     va_end(args);
                    245:     xmlHTMLEncodeSend();
1.18      veillard  246:     xmlGenericError(xmlGenericErrorContext, "</p>\n");
1.1       daniel    247: 
                    248:     xmlHTMLPrintFileContext(input);
                    249:     xmlHTMLEncodeSend();
                    250: }
                    251: 
                    252: /**
                    253:  * xmlHTMLValidityError:
                    254:  * @ctx:  an XML parser context
                    255:  * @msg:  the message to display/transmit
                    256:  * @...:  extra parameters for the message display
                    257:  * 
                    258:  * Display and format an validity error messages, gives file,
                    259:  * line, position and extra parameters.
                    260:  */
                    261: void
                    262: xmlHTMLValidityError(void *ctx, const char *msg, ...)
                    263: {
                    264:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    265:     xmlParserInputPtr input;
                    266:     va_list args;
                    267: 
                    268:     buffer[0] = 0;
                    269:     input = ctxt->input;
                    270:     if ((input->filename == NULL) && (ctxt->inputNr > 1))
                    271:         input = ctxt->inputTab[ctxt->inputNr - 2];
                    272:         
                    273:     xmlHTMLPrintFileInfo(input);
                    274: 
1.18      veillard  275:     xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
1.1       daniel    276:     va_start(args, msg);
                    277:     vsprintf(&buffer[strlen(buffer)], msg, args);
                    278:     va_end(args);
                    279:     xmlHTMLEncodeSend();
1.18      veillard  280:     xmlGenericError(xmlGenericErrorContext, "</p>\n");
1.1       daniel    281: 
                    282:     xmlHTMLPrintFileContext(input);
                    283:     xmlHTMLEncodeSend();
                    284: }
                    285: 
                    286: /**
                    287:  * xmlHTMLValidityWarning:
                    288:  * @ctx:  an XML parser context
                    289:  * @msg:  the message to display/transmit
                    290:  * @...:  extra parameters for the message display
                    291:  * 
                    292:  * Display and format a validity warning messages, gives file, line,
                    293:  * position and extra parameters.
                    294:  */
                    295: void
                    296: xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
                    297: {
                    298:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    299:     xmlParserInputPtr input;
                    300:     va_list args;
                    301: 
                    302:     buffer[0] = 0;
                    303:     input = ctxt->input;
                    304:     if ((input->filename == NULL) && (ctxt->inputNr > 1))
                    305:         input = ctxt->inputTab[ctxt->inputNr - 2];
                    306: 
                    307:     xmlHTMLPrintFileInfo(input);
                    308:         
1.18      veillard  309:     xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
1.1       daniel    310:     va_start(args, msg);
                    311:     vsprintf(&buffer[strlen(buffer)], msg, args);
                    312:     va_end(args);
                    313:     xmlHTMLEncodeSend();
1.18      veillard  314:     xmlGenericError(xmlGenericErrorContext, "</p>\n");
1.1       daniel    315: 
                    316:     xmlHTMLPrintFileContext(input);
                    317:     xmlHTMLEncodeSend();
                    318: }
                    319: 
                    320: /************************************************************************
                    321:  *                                                                     *
                    322:  *                     Shell Interface                                 *
                    323:  *                                                                     *
                    324:  ************************************************************************/
                    325: /**
                    326:  * xmlShellReadline:
                    327:  * @prompt:  the prompt value
                    328:  *
                    329:  * Read a string
                    330:  * 
                    331:  * Returns a pointer to it or NULL on EOF the caller is expected to
                    332:  *     free the returned string.
                    333:  */
                    334: char *
                    335: xmlShellReadline(char *prompt) {
                    336: #ifdef HAVE_LIBREADLINE
                    337:     char *line_read;
                    338: 
                    339:     /* Get a line from the user. */
                    340:     line_read = readline (prompt);
                    341: 
                    342:     /* If the line has any text in it, save it on the history. */
                    343:     if (line_read && *line_read)
                    344:        add_history (line_read);
                    345: 
                    346:     return (line_read);
                    347: #else
                    348:     char line_read[501];
                    349: 
                    350:     if (prompt != NULL)
                    351:        fprintf(stdout, "%s", prompt);
                    352:     if (!fgets(line_read, 500, stdin))
                    353:         return(NULL);
                    354:     line_read[500] = 0;
                    355:     return(strdup(line_read));
                    356: #endif
                    357: }
                    358: 
                    359: /************************************************************************
                    360:  *                                                                     *
1.2       daniel    361:  *                     I/O Interfaces                                  *
                    362:  *                                                                     *
                    363:  ************************************************************************/
                    364: 
                    365: int myRead(FILE *f, char * buffer, int len) {
                    366:     return(fread(buffer, 1, len, f));
                    367: }
                    368: void myClose(FILE *f) {
                    369:     fclose(f);
                    370: }
                    371: 
                    372: /************************************************************************
                    373:  *                                                                     *
1.1       daniel    374:  *                     Test processing                                 *
                    375:  *                                                                     *
                    376:  ************************************************************************/
                    377: void parseAndPrintFile(char *filename) {
                    378:     xmlDocPtr doc = NULL, tmp;
                    379: 
                    380: #ifdef LIBXML_HTML_ENABLED
                    381:     if (html) {
                    382:        doc = htmlParseFile(filename, NULL);
                    383:     } else {
                    384: #endif /* LIBXML_HTML_ENABLED */
                    385:        /*
                    386:         * build an XML tree from a string;
                    387:         */
                    388:        if (push) {
                    389:            FILE *f;
                    390: 
                    391:            f = fopen(filename, "r");
                    392:            if (f != NULL) {
1.14      veillard  393:                int ret;
1.1       daniel    394:                int res, size = 3;
                    395:                char chars[1024];
                    396:                 xmlParserCtxtPtr ctxt;
                    397: 
                    398:                if (repeat)
                    399:                    size = 1024;
                    400:                res = fread(chars, 1, 4, f);
                    401:                if (res > 0) {
                    402:                    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
                    403:                                chars, res, filename);
                    404:                    while ((res = fread(chars, 1, size, f)) > 0) {
                    405:                        xmlParseChunk(ctxt, chars, res, 0);
                    406:                    }
                    407:                    xmlParseChunk(ctxt, chars, 0, 1);
                    408:                    doc = ctxt->myDoc;
1.14      veillard  409:                    ret = ctxt->wellFormed;
1.1       daniel    410:                    xmlFreeParserCtxt(ctxt);
1.14      veillard  411:                    if (!ret) {
                    412:                        xmlFreeDoc(doc);
                    413:                        doc = NULL;
                    414:                    }
1.1       daniel    415:                }
                    416:            }
1.2       daniel    417:        } else if (testIO) {
                    418:            int ret;
                    419:            FILE *f;
                    420: 
                    421:            f = fopen(filename, "r");
                    422:            if (f != NULL) {
                    423:                 xmlParserCtxtPtr ctxt;
                    424: 
                    425:                ctxt = xmlCreateIOParserCtxt(NULL, NULL,
                    426:                            (xmlInputReadCallback) myRead,
                    427:                            (xmlInputCloseCallback) myClose,
                    428:                            f, XML_CHAR_ENCODING_NONE);
                    429:                xmlParseDocument(ctxt);
                    430: 
                    431:                ret = ctxt->wellFormed;
                    432:                doc = ctxt->myDoc;
                    433:                xmlFreeParserCtxt(ctxt);
                    434:                if (!ret) {
                    435:                    xmlFreeDoc(doc);
                    436:                    doc = NULL;
                    437:                }
                    438:            }
1.1       daniel    439:        } else if (recovery) {
                    440:            doc = xmlRecoverFile(filename);
                    441:        } else if (htmlout) {
                    442:            int ret;
                    443:            xmlParserCtxtPtr ctxt;
                    444:            xmlSAXHandler silent, *old;
                    445: 
                    446:            ctxt = xmlCreateFileParserCtxt(filename);
1.10      veillard  447: 
                    448:            if (ctxt == NULL) {       
                    449:              /* If xmlCreateFileParseCtxt() return NULL something
                    450:                 strange happened so we don't want to do anything.  Do
                    451:                 we want to print an error message here?
                    452:                 <sven@zen.org> */
                    453:              doc = NULL;
                    454:            } else {
                    455:              memcpy(&silent, ctxt->sax, sizeof(silent));
                    456:              old = ctxt->sax;
                    457:              silent.error = xmlHTMLError;
                    458:              if (xmlGetWarningsDefaultValue)
1.1       daniel    459:                silent.warning = xmlHTMLWarning;
1.10      veillard  460:              else 
1.1       daniel    461:                silent.warning = NULL;
1.10      veillard  462:              silent.fatalError = xmlHTMLError;
                    463:              ctxt->sax = &silent;
                    464:              ctxt->vctxt.error = xmlHTMLValidityError;
                    465:              if (xmlGetWarningsDefaultValue)
1.1       daniel    466:                ctxt->vctxt.warning = xmlHTMLValidityWarning;
1.10      veillard  467:              else 
1.1       daniel    468:                ctxt->vctxt.warning = NULL;
                    469: 
1.10      veillard  470:              xmlParseDocument(ctxt);
1.1       daniel    471: 
1.10      veillard  472:              ret = ctxt->wellFormed;
                    473:              doc = ctxt->myDoc;
                    474:              ctxt->sax = old;
                    475:              xmlFreeParserCtxt(ctxt);
                    476:              if (!ret) {
1.1       daniel    477:                xmlFreeDoc(doc);
                    478:                doc = NULL;
1.10      veillard  479:              }
1.1       daniel    480:            }
1.7       veillard  481: #ifdef HAVE_SYS_MMAN_H
                    482:        } else if (memory) {
                    483:            int fd;
                    484:            struct stat info;
                    485:            const char *base;
                    486:            if (stat(filename, &info) < 0) 
                    487:                return;
                    488:            if ((fd = open(filename, O_RDONLY)) < 0)
                    489:                return;
                    490:            base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1.11      veillard  491:            if (base == (void *) MAP_FAILED)
1.7       veillard  492:                return;
                    493: 
                    494:            doc = xmlParseMemory((char *) base, info.st_size);
                    495:            munmap((char *) base, info.st_size);
                    496: #endif
1.1       daniel    497:        } else
                    498:            doc = xmlParseFile(filename);
                    499: #ifdef LIBXML_HTML_ENABLED
                    500:     }
                    501: #endif
                    502: 
1.10      veillard  503:     /*
                    504:      * If we don't have a document we might as well give up.  Do we
                    505:      * want an error message here?  <sven@zen.org> */
                    506:     if (doc == NULL)
                    507:       {
                    508:        return;
                    509:       }
                    510: 
1.19    ! veillard  511: #ifdef LIBXML_XINCLUDE_ENABLED
        !           512:     xmlXIncludeProcess(doc);
        !           513: #endif
        !           514: 
1.1       daniel    515: #ifdef LIBXML_DEBUG_ENABLED
                    516:     /*
                    517:      * shell interraction
                    518:      */
                    519:     if (shell)  
                    520:         xmlShell(doc, filename, xmlShellReadline, stdout);
                    521: #endif
                    522: 
                    523:     /*
                    524:      * test intermediate copy if needed.
                    525:      */
                    526:     if (copy) {
                    527:         tmp = doc;
                    528:        doc = xmlCopyDoc(doc, 1);
                    529:        xmlFreeDoc(tmp);
                    530:     }
                    531: 
                    532:     if ((insert) && (!html)) {
                    533:         const xmlChar* list[256];
                    534:        int nb, i;
                    535:        xmlNodePtr node;
                    536: 
                    537:        if (doc->children != NULL) {
                    538:            node = doc->children;
                    539:            while ((node != NULL) && (node->last == NULL)) node = node->next;
                    540:            if (node != NULL) {
                    541:                nb = xmlValidGetValidElements(node->last, NULL, list, 256);
                    542:                if (nb < 0) {
                    543:                    printf("could not get valid list of elements\n");
                    544:                } else if (nb == 0) {
                    545:                    printf("No element can be indersted under root\n");
                    546:                } else {
                    547:                    printf("%d element types can be indersted under root:\n",
                    548:                           nb);
                    549:                    for (i = 0;i < nb;i++) {
                    550:                         printf("%s\n", list[i]);
                    551:                    }
                    552:                }
                    553:            }
                    554:        }    
                    555:     }else if (noout == 0) {
                    556:        /*
                    557:         * print it.
                    558:         */
                    559: #ifdef LIBXML_DEBUG_ENABLED
                    560:        if (!debug) {
                    561: #endif
                    562:            if (compress)
                    563:                xmlSaveFile("-", doc);
1.3       daniel    564:            else if (encoding != NULL)
                    565:                xmlSaveFileEnc("-", doc, encoding);
1.1       daniel    566:            else
                    567:                xmlDocDump(stdout, doc);
                    568: #ifdef LIBXML_DEBUG_ENABLED
                    569:        } else
                    570:            xmlDebugDumpDocument(stdout, doc);
                    571: #endif
                    572:     }
                    573: 
                    574:     /*
                    575:      * A posteriori validation test
                    576:      */
1.16      veillard  577:     if (dtdvalid != NULL) {
                    578:        xmlDtdPtr dtd;
                    579: 
                    580:        dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid); 
                    581:        if (dtd == NULL) {
1.18      veillard  582:            xmlGenericError(xmlGenericErrorContext,
                    583:                    "Could not parse DTD %s\n", dtdvalid);
1.16      veillard  584:        } else {
                    585:            xmlValidCtxt cvp;
                    586:            cvp.userData = (void *) stderr;                                                 cvp.error    = (xmlValidityErrorFunc) fprintf;                                  cvp.warning  = (xmlValidityWarningFunc) fprintf;
1.17      veillard  587:            if (!xmlValidateDtd(&cvp, doc, dtd)) {
1.18      veillard  588:                xmlGenericError(xmlGenericErrorContext,
                    589:                        "Document %s does not validate against %s\n",
1.17      veillard  590:                        filename, dtdvalid);
                    591:            }
                    592:            xmlFreeDtd(dtd);
1.16      veillard  593:        }
                    594:     } else if (postvalid) {
1.1       daniel    595:        xmlValidCtxt cvp;
                    596:        cvp.userData = (void *) stderr;                                                 cvp.error    = (xmlValidityErrorFunc) fprintf;                                  cvp.warning  = (xmlValidityWarningFunc) fprintf;
1.17      veillard  597:        if (!xmlValidateDocument(&cvp, doc)) {
1.18      veillard  598:            xmlGenericError(xmlGenericErrorContext,
                    599:                    "Document %s does not validate\n", filename);
1.17      veillard  600:        }
1.1       daniel    601:     }
                    602: 
                    603: #ifdef LIBXML_DEBUG_ENABLED
                    604:     if ((debugent) && (!html))
1.13      veillard  605:        xmlDebugDumpEntities(stderr, doc);
1.1       daniel    606: #endif
                    607: 
                    608:     /*
                    609:      * free it.
                    610:      */
                    611:     xmlFreeDoc(doc);
                    612: }
                    613: 
                    614: int main(int argc, char **argv) {
                    615:     int i, count;
                    616:     int files = 0;
                    617: 
1.4       daniel    618:     LIBXML_TEST_VERSION
1.1       daniel    619:     for (i = 1; i < argc ; i++) {
                    620: #ifdef LIBXML_DEBUG_ENABLED
                    621:        if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
                    622:            debug++;
                    623:        else if ((!strcmp(argv[i], "-shell")) ||
                    624:                 (!strcmp(argv[i], "--shell"))) {
                    625:            shell++;
                    626:             noout = 1;
                    627:         } else 
                    628: #endif
                    629:        if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
                    630:            copy++;
                    631:        else if ((!strcmp(argv[i], "-recover")) ||
                    632:                 (!strcmp(argv[i], "--recover")))
                    633:            recovery++;
                    634:        else if ((!strcmp(argv[i], "-noent")) ||
                    635:                 (!strcmp(argv[i], "--noent")))
                    636:            noent++;
                    637:        else if ((!strcmp(argv[i], "-noout")) ||
                    638:                 (!strcmp(argv[i], "--noout")))
                    639:            noout++;
                    640:        else if ((!strcmp(argv[i], "-htmlout")) ||
                    641:                 (!strcmp(argv[i], "--htmlout")))
                    642:            htmlout++;
                    643: #ifdef LIBXML_HTML_ENABLED
                    644:        else if ((!strcmp(argv[i], "-html")) ||
                    645:                 (!strcmp(argv[i], "--html"))) {
                    646:            html++;
                    647:         }
                    648: #endif /* LIBXML_HTML_ENABLED */
                    649:        else if ((!strcmp(argv[i], "-nowrap")) ||
                    650:                 (!strcmp(argv[i], "--nowrap")))
                    651:            nowrap++;
                    652:        else if ((!strcmp(argv[i], "-valid")) ||
                    653:                 (!strcmp(argv[i], "--valid")))
                    654:            valid++;
                    655:        else if ((!strcmp(argv[i], "-postvalid")) ||
                    656:                 (!strcmp(argv[i], "--postvalid")))
                    657:            postvalid++;
1.16      veillard  658:        else if ((!strcmp(argv[i], "-dtdvalid")) ||
                    659:                 (!strcmp(argv[i], "--dtdvalid"))) {
                    660:            i++;
                    661:            dtdvalid = argv[i];
                    662:         }
1.1       daniel    663:        else if ((!strcmp(argv[i], "-insert")) ||
                    664:                 (!strcmp(argv[i], "--insert")))
                    665:            insert++;
                    666:        else if ((!strcmp(argv[i], "-repeat")) ||
                    667:                 (!strcmp(argv[i], "--repeat")))
                    668:            repeat++;
                    669:        else if ((!strcmp(argv[i], "-push")) ||
                    670:                 (!strcmp(argv[i], "--push")))
                    671:            push++;
1.7       veillard  672: #ifdef HAVE_SYS_MMAN_H
                    673:        else if ((!strcmp(argv[i], "-memory")) ||
                    674:                 (!strcmp(argv[i], "--memory")))
                    675:            memory++;
                    676: #endif
1.2       daniel    677:        else if ((!strcmp(argv[i], "-testIO")) ||
                    678:                 (!strcmp(argv[i], "--testIO")))
                    679:            testIO++;
1.19    ! veillard  680: #ifdef LIBXML_XINCLUDE_ENABLED
        !           681:        else if ((!strcmp(argv[i], "-xinclude")) ||
        !           682:                 (!strcmp(argv[i], "--xinclude")))
        !           683:            xinclude++;
        !           684: #endif
1.1       daniel    685:        else if ((!strcmp(argv[i], "-compress")) ||
                    686:                 (!strcmp(argv[i], "--compress"))) {
                    687:            compress++;
                    688:            xmlSetCompressMode(9);
                    689:         }
                    690:        else if ((!strcmp(argv[i], "-nowarning")) ||
                    691:                 (!strcmp(argv[i], "--nowarning"))) {
                    692:            xmlGetWarningsDefaultValue = 0;
1.13      veillard  693:            xmlPedanticParserDefault(0);
                    694:         }
                    695:        else if ((!strcmp(argv[i], "-pedantic")) ||
                    696:                 (!strcmp(argv[i], "--pedantic"))) {
                    697:            xmlGetWarningsDefaultValue = 1;
                    698:            xmlPedanticParserDefault(1);
1.1       daniel    699:         }
1.15      veillard  700: #ifdef LIBXML_DEBUG_ENABLED
1.13      veillard  701:        else if ((!strcmp(argv[i], "-debugent")) ||
                    702:                 (!strcmp(argv[i], "--debugent"))) {
                    703:            debugent++;
                    704:            xmlParserDebugEntities = 1;
                    705:        } 
1.15      veillard  706: #endif
1.3       daniel    707:        else if ((!strcmp(argv[i], "-encode")) ||
                    708:                 (!strcmp(argv[i], "--encode"))) {
                    709:            i++;
                    710:            encoding = argv[i];
1.12      veillard  711:            /*
                    712:             * OK it's for testing purposes
                    713:             */
                    714:            xmlAddEncodingAlias("UTF-8", "DVEnc");
1.3       daniel    715:         }
1.1       daniel    716:        else if ((!strcmp(argv[i], "-noblanks")) ||
                    717:                 (!strcmp(argv[i], "--noblanks"))) {
                    718:             noblanks++;
                    719:             xmlKeepBlanksDefault(0);
                    720:         }
                    721:     }
                    722:     if (noent != 0) xmlSubstituteEntitiesDefault(1);
                    723:     if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
                    724:     if ((htmlout) && (!nowrap)) {
1.18      veillard  725:        xmlGenericError(xmlGenericErrorContext,
1.1       daniel    726:          "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
1.18      veillard  727:        xmlGenericError(xmlGenericErrorContext,
                    728:                "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
                    729:        xmlGenericError(xmlGenericErrorContext,
1.1       daniel    730:         "<html><head><title>%s output</title></head>\n",
                    731:                argv[0]);
1.18      veillard  732:        xmlGenericError(xmlGenericErrorContext, 
1.1       daniel    733:         "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
                    734:                argv[0]);
                    735:     }
                    736:     for (i = 1; i < argc ; i++) {
1.3       daniel    737:        if ((!strcmp(argv[i], "-encode")) ||
                    738:                 (!strcmp(argv[i], "--encode"))) {
1.17      veillard  739:            i++;
                    740:            continue;
                    741:         }
                    742:        if ((!strcmp(argv[i], "-dtdvalid")) ||
                    743:                 (!strcmp(argv[i], "--dtdvalid"))) {
1.3       daniel    744:            i++;
                    745:            continue;
                    746:         }
1.1       daniel    747:        if (argv[i][0] != '-') {
                    748:            if (repeat) {
                    749:                for (count = 0;count < 100 * repeat;count++)
                    750:                    parseAndPrintFile(argv[i]);
                    751:            } else
                    752:                parseAndPrintFile(argv[i]);
                    753:            files ++;
                    754:        }
                    755:     }
                    756:     if ((htmlout) && (!nowrap)) {
1.18      veillard  757:        xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
1.1       daniel    758:     }
                    759:     if (files == 0) {
                    760:        printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...\n",
                    761:               argv[0]);
                    762:        printf("\tParse the XML files and output the result of the parsing\n");
                    763: #ifdef LIBXML_DEBUG_ENABLED
                    764:        printf("\t--debug : dump a debug tree of the in-memory document\n");
                    765:        printf("\t--shell : run a navigating shell\n");
                    766:        printf("\t--debugent : debug the entities defined in the document\n");
                    767: #endif
                    768:        printf("\t--copy : used to test the internal copy implementation\n");
                    769:        printf("\t--recover : output what was parsable on broken XML documents\n");
                    770:        printf("\t--noent : substitute entity references by their value\n");
                    771:        printf("\t--noout : don't output the result tree\n");
                    772:        printf("\t--htmlout : output results as HTML\n");
                    773:        printf("\t--nowarp : do not put HTML doc wrapper\n");
                    774:        printf("\t--valid : validate the document in addition to std well-formed check\n");
                    775:        printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1.16      veillard  776:        printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
1.1       daniel    777:        printf("\t--repeat : repeat 100 times, for timing or profiling\n");
                    778:        printf("\t--insert : ad-hoc test for valid insertions\n");
                    779:        printf("\t--compress : turn on gzip compression of output\n");
                    780: #ifdef LIBXML_HTML_ENABLED
                    781:        printf("\t--html : use the HTML parser\n");
                    782: #endif
                    783:        printf("\t--push : use the push mode of the parser\n");
1.7       veillard  784: #ifdef HAVE_SYS_MMAN_H
                    785:        printf("\t--memory : parse from memory\n");
                    786: #endif
1.1       daniel    787:        printf("\t--nowarning : do not emit warnings from parser/validator\n");
                    788:        printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
1.2       daniel    789:        printf("\t--testIO : test user I/O support\n");
1.6       veillard  790:        printf("\t--encode encoding : output in the given encoding\n");
1.19    ! veillard  791: #ifdef LIBXML_XINCLUDE_ENABLED
        !           792:        printf("\t--xinclude : do XInclude processing\n");
        !           793: #endif
1.1       daniel    794:     }
                    795:     xmlCleanupParser();
                    796:     xmlMemoryDump();
                    797: 
                    798:     return(0);
                    799: }
1.10      veillard  800: 

Webmaster