Annotation of XML/xmllint.c, revision 1.18

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

Webmaster