source: trunk/third/libxml2/xmllint.c @ 18536

Revision 18536, 36.0 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18535, which included commits to RCS files with non-trunk default branches.
Line 
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.com
7 */
8
9#include "libxml.h"
10
11#include <string.h>
12#include <stdarg.h>
13
14#include <assert.h>
15
16#if defined (_WIN32) && !defined(__CYGWIN__)
17#ifdef _MSC_VER
18#include <winsock2.h>
19#pragma comment(lib, "ws2_32.lib")
20#define gettimeofday(p1,p2)
21#include <time.h>
22#else /* _MSC_VER */
23#include <sys/time.h>
24#endif /* _MSC_VER */
25#else /* _WIN32 */
26#ifdef HAVE_SYS_TIME_H
27#include <sys/time.h>
28#endif
29#ifdef HAVE_TIME_H
30#include <time.h>
31#endif
32#endif /* _WIN32 */
33
34#ifdef HAVE_SYS_TIMEB_H
35#include <sys/timeb.h>
36#endif
37
38#ifdef HAVE_SYS_TYPES_H
39#include <sys/types.h>
40#endif
41#ifdef HAVE_SYS_STAT_H
42#include <sys/stat.h>
43#endif
44#ifdef HAVE_FCNTL_H
45#include <fcntl.h>
46#endif
47#ifdef HAVE_UNISTD_H
48#include <unistd.h>
49#endif
50#ifdef HAVE_SYS_MMAN_H
51#include <sys/mman.h>
52/* seems needed for Solaris */
53#ifndef MAP_FAILED
54#define MAP_FAILED ((void *) -1)
55#endif
56#endif
57#ifdef HAVE_STDLIB_H
58#include <stdlib.h>
59#endif
60#ifdef HAVE_LIBREADLINE
61#include <readline/readline.h>
62#ifdef HAVE_LIBHISTORY
63#include <readline/history.h>
64#endif
65#endif
66
67#include <libxml/xmlmemory.h>
68#include <libxml/parser.h>
69#include <libxml/parserInternals.h>
70#include <libxml/HTMLparser.h>
71#include <libxml/HTMLtree.h>
72#include <libxml/tree.h>
73#include <libxml/xpath.h>
74#include <libxml/debugXML.h>
75#include <libxml/xmlerror.h>
76#ifdef LIBXML_XINCLUDE_ENABLED
77#include <libxml/xinclude.h>
78#endif
79#ifdef LIBXML_CATALOG_ENABLED
80#include <libxml/catalog.h>
81#endif
82#ifdef LIBXML_DOCB_ENABLED
83#include <libxml/DOCBparser.h>
84#endif
85#include <libxml/globals.h>
86#include <libxml/xmlreader.h>
87
88#ifdef LIBXML_DEBUG_ENABLED
89static int shell = 0;
90static int debugent = 0;
91#endif
92static int debug = 0;
93static int copy = 0;
94static int recovery = 0;
95static int noent = 0;
96static int noout = 0;
97static int nowrap = 0;
98static int valid = 0;
99static int postvalid = 0;
100static char * dtdvalid = NULL;
101static int repeat = 0;
102static int insert = 0;
103static int compress = 0;
104#ifdef LIBXML_DOCB_ENABLED
105static int sgml = 0;
106#endif
107static int html = 0;
108static int htmlout = 0;
109static int push = 0;
110#ifdef HAVE_SYS_MMAN_H
111static int memory = 0;
112#endif
113static int noblanks = 0;
114static int format = 0;
115static int testIO = 0;
116static char *encoding = NULL;
117#ifdef LIBXML_XINCLUDE_ENABLED
118static int xinclude = 0;
119#endif
120static int dtdattrs = 0;
121static int loaddtd = 0;
122static int progresult = 0;
123static int timing = 0;
124static int generate = 0;
125static int dropdtd = 0;
126#ifdef LIBXML_CATALOG_ENABLED
127static int catalogs = 0;
128static int nocatalogs = 0;
129#endif
130static int stream = 0;
131static int chkregister = 0;
132static const char *output = NULL;
133
134
135/*
136 * Internal timing routines to remove the necessity to have unix-specific
137 * function calls
138 */
139
140#ifndef HAVE_GETTIMEOFDAY
141#ifdef HAVE_SYS_TIMEB_H
142#ifdef HAVE_SYS_TIME_H
143#ifdef HAVE_FTIME
144
145static int
146my_gettimeofday(struct timeval *tvp, void *tzp)
147{
148        struct timeb timebuffer;
149
150        ftime(&timebuffer);
151        if (tvp) {
152                tvp->tv_sec = timebuffer.time;
153                tvp->tv_usec = timebuffer.millitm * 1000L;
154        }
155        return (0);
156}
157#define HAVE_GETTIMEOFDAY 1
158#define gettimeofday my_gettimeofday
159
160#endif /* HAVE_FTIME */
161#endif /* HAVE_SYS_TIME_H */
162#endif /* HAVE_SYS_TIMEB_H */
163#endif /* !HAVE_GETTIMEOFDAY */
164
165#if defined(HAVE_GETTIMEOFDAY)
166static struct timeval begin, end;
167
168/*
169 * startTimer: call where you want to start timing
170 */
171static void
172startTimer(void)
173{
174    gettimeofday(&begin, NULL);
175}
176
177/*
178 * endTimer: call where you want to stop timing and to print out a
179 *           message about the timing performed; format is a printf
180 *           type argument
181 */
182static void
183endTimer(const char *fmt, ...)
184{
185    long msec;
186    va_list ap;
187
188    gettimeofday(&end, NULL);
189    msec = end.tv_sec - begin.tv_sec;
190    msec *= 1000;
191    msec += (end.tv_usec - begin.tv_usec) / 1000;
192
193#ifndef HAVE_STDARG_H
194#error "endTimer required stdarg functions"
195#endif
196    va_start(ap, fmt);
197    vfprintf(stderr, fmt, ap);
198    va_end(ap);
199
200    fprintf(stderr, " took %ld ms\n", msec);
201}
202#elif defined(HAVE_TIME_H)
203/*
204 * No gettimeofday function, so we have to make do with calling clock.
205 * This is obviously less accurate, but there's little we can do about
206 * that.
207 */
208#ifndef CLOCKS_PER_SEC
209#define CLOCKS_PER_SEC 100
210#endif
211
212static clock_t begin, end;
213static void
214startTimer(void)
215{
216    begin = clock();
217}
218static void
219endTimer(const char *fmt, ...)
220{
221    long msec;
222    va_list ap;
223
224    end = clock();
225    msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
226
227#ifndef HAVE_STDARG_H
228#error "endTimer required stdarg functions"
229#endif
230    va_start(ap, fmt);
231    vfprintf(stderr, fmt, ap);
232    va_end(ap);
233    fprintf(stderr, " took %ld ms\n", msec);
234}
235#else
236
237/*
238 * We don't have a gettimeofday or time.h, so we just don't do timing
239 */
240static void
241startTimer(void)
242{
243    /*
244     * Do nothing
245     */
246}
247static void
248endTimer(char *format, ...)
249{
250    /*
251     * We cannot do anything because we don't have a timing function
252     */
253#ifdef HAVE_STDARG_H
254    va_start(ap, format);
255    vfprintf(stderr, format, ap);
256    va_end(ap);
257    fprintf(stderr, " was not timed\n", msec);
258#else
259    /* We don't have gettimeofday, time or stdarg.h, what crazy world is
260     * this ?!
261     */
262#endif
263}
264#endif
265/************************************************************************
266 *                                                                      *
267 *                      HTML ouput                                      *
268 *                                                                      *
269 ************************************************************************/
270char buffer[50000];
271
272static void
273xmlHTMLEncodeSend(void) {
274    char *result;
275
276    result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
277    if (result) {
278        xmlGenericError(xmlGenericErrorContext, "%s", result);
279        xmlFree(result);
280    }
281    buffer[0] = 0;
282}
283
284/**
285 * xmlHTMLPrintFileInfo:
286 * @input:  an xmlParserInputPtr input
287 *
288 * Displays the associated file and line informations for the current input
289 */
290
291static void
292xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
293    int len;
294    xmlGenericError(xmlGenericErrorContext, "<p>");
295
296    len = strlen(buffer);
297    if (input != NULL) {
298        if (input->filename) {
299            snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
300                    input->line);
301        } else {
302            snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
303        }
304    }
305    xmlHTMLEncodeSend();
306}
307
308/**
309 * xmlHTMLPrintFileContext:
310 * @input:  an xmlParserInputPtr input
311 *
312 * Displays current context within the input content for error tracking
313 */
314
315static void
316xmlHTMLPrintFileContext(xmlParserInputPtr input) {
317    const xmlChar *cur, *base;
318    int len;
319    int n;
320
321    if (input == NULL) return;
322    xmlGenericError(xmlGenericErrorContext, "<pre>\n");
323    cur = input->cur;
324    base = input->base;
325    while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
326        cur--;
327    }
328    n = 0;
329    while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
330        cur--;
331    if ((*cur == '\n') || (*cur == '\r')) cur++;
332    base = cur;
333    n = 0;
334    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
335        len = strlen(buffer);
336        snprintf(&buffer[len], sizeof(buffer) - len, "%c",
337                    (unsigned char) *cur++);
338        n++;
339    }
340    len = strlen(buffer);
341    snprintf(&buffer[len], sizeof(buffer) - len, "\n");
342    cur = input->cur;
343    while ((*cur == '\n') || (*cur == '\r'))
344        cur--;
345    n = 0;
346    while ((cur != base) && (n++ < 80)) {
347        len = strlen(buffer);
348        snprintf(&buffer[len], sizeof(buffer) - len, " ");
349        base++;
350    }
351    len = strlen(buffer);
352    snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
353    xmlHTMLEncodeSend();
354    xmlGenericError(xmlGenericErrorContext, "</pre>");
355}
356
357/**
358 * xmlHTMLError:
359 * @ctx:  an XML parser context
360 * @msg:  the message to display/transmit
361 * @...:  extra parameters for the message display
362 *
363 * Display and format an error messages, gives file, line, position and
364 * extra parameters.
365 */
366static void
367xmlHTMLError(void *ctx, const char *msg, ...)
368{
369    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
370    xmlParserInputPtr input;
371    xmlParserInputPtr cur = NULL;
372    va_list args;
373    int len;
374
375    buffer[0] = 0;
376    input = ctxt->input;
377    if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
378        cur = input;
379        input = ctxt->inputTab[ctxt->inputNr - 2];
380    }
381       
382    xmlHTMLPrintFileInfo(input);
383
384    xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
385    va_start(args, msg);
386    len = strlen(buffer);
387    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
388    va_end(args);
389    xmlHTMLEncodeSend();
390    xmlGenericError(xmlGenericErrorContext, "</p>\n");
391
392    xmlHTMLPrintFileContext(input);
393    xmlHTMLEncodeSend();
394}
395
396/**
397 * xmlHTMLWarning:
398 * @ctx:  an XML parser context
399 * @msg:  the message to display/transmit
400 * @...:  extra parameters for the message display
401 *
402 * Display and format a warning messages, gives file, line, position and
403 * extra parameters.
404 */
405static void
406xmlHTMLWarning(void *ctx, const char *msg, ...)
407{
408    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
409    xmlParserInputPtr input;
410    xmlParserInputPtr cur = NULL;
411    va_list args;
412    int len;
413
414    buffer[0] = 0;
415    input = ctxt->input;
416    if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
417        cur = input;
418        input = ctxt->inputTab[ctxt->inputNr - 2];
419    }
420       
421
422    xmlHTMLPrintFileInfo(input);
423       
424    xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
425    va_start(args, msg);
426    len = strlen(buffer);   
427    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
428    va_end(args);
429    xmlHTMLEncodeSend();
430    xmlGenericError(xmlGenericErrorContext, "</p>\n");
431
432    xmlHTMLPrintFileContext(input);
433    xmlHTMLEncodeSend();
434}
435
436/**
437 * xmlHTMLValidityError:
438 * @ctx:  an XML parser context
439 * @msg:  the message to display/transmit
440 * @...:  extra parameters for the message display
441 *
442 * Display and format an validity error messages, gives file,
443 * line, position and extra parameters.
444 */
445static void
446xmlHTMLValidityError(void *ctx, const char *msg, ...)
447{
448    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
449    xmlParserInputPtr input;
450    va_list args;
451    int len;
452
453    buffer[0] = 0;
454    input = ctxt->input;
455    if ((input->filename == NULL) && (ctxt->inputNr > 1))
456        input = ctxt->inputTab[ctxt->inputNr - 2];
457       
458    xmlHTMLPrintFileInfo(input);
459
460    xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
461    len = strlen(buffer);
462    va_start(args, msg);
463    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
464    va_end(args);
465    xmlHTMLEncodeSend();
466    xmlGenericError(xmlGenericErrorContext, "</p>\n");
467
468    xmlHTMLPrintFileContext(input);
469    xmlHTMLEncodeSend();
470}
471
472/**
473 * xmlHTMLValidityWarning:
474 * @ctx:  an XML parser context
475 * @msg:  the message to display/transmit
476 * @...:  extra parameters for the message display
477 *
478 * Display and format a validity warning messages, gives file, line,
479 * position and extra parameters.
480 */
481static void
482xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
483{
484    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
485    xmlParserInputPtr input;
486    va_list args;
487    int len;
488
489    buffer[0] = 0;
490    input = ctxt->input;
491    if ((input->filename == NULL) && (ctxt->inputNr > 1))
492        input = ctxt->inputTab[ctxt->inputNr - 2];
493
494    xmlHTMLPrintFileInfo(input);
495       
496    xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
497    va_start(args, msg);
498    len = strlen(buffer);
499    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
500    va_end(args);
501    xmlHTMLEncodeSend();
502    xmlGenericError(xmlGenericErrorContext, "</p>\n");
503
504    xmlHTMLPrintFileContext(input);
505    xmlHTMLEncodeSend();
506}
507
508/************************************************************************
509 *                                                                      *
510 *                      Shell Interface                                 *
511 *                                                                      *
512 ************************************************************************/
513#ifdef LIBXML_DEBUG_ENABLED
514/**
515 * xmlShellReadline:
516 * @prompt:  the prompt value
517 *
518 * Read a string
519 *
520 * Returns a pointer to it or NULL on EOF the caller is expected to
521 *     free the returned string.
522 */
523static char *
524xmlShellReadline(char *prompt) {
525#ifdef HAVE_LIBREADLINE
526    char *line_read;
527
528    /* Get a line from the user. */
529    line_read = readline (prompt);
530
531    /* If the line has any text in it, save it on the history. */
532    if (line_read && *line_read)
533        add_history (line_read);
534
535    return (line_read);
536#else
537    char line_read[501];
538    char *ret;
539    int len;
540
541    if (prompt != NULL)
542        fprintf(stdout, "%s", prompt);
543    if (!fgets(line_read, 500, stdin))
544        return(NULL);
545    line_read[500] = 0;
546    len = strlen(line_read);
547    ret = (char *) malloc(len + 1);
548    if (ret != NULL) {
549        memcpy (ret, line_read, len + 1);
550    }
551    return(ret);
552#endif
553}
554#endif /* LIBXML_DEBUG_ENABLED */
555
556/************************************************************************
557 *                                                                      *
558 *                      I/O Interfaces                                  *
559 *                                                                      *
560 ************************************************************************/
561
562static int myRead(FILE *f, char * buf, int len) {
563    return(fread(buf, 1, len, f));
564}
565static void myClose(FILE *f) {
566  if (f != stdin) {
567    fclose(f);
568  }
569}
570
571/************************************************************************
572 *                                                                      *
573 *                      Stream Test processing                          *
574 *                                                                      *
575 ************************************************************************/
576static int count = 0;
577static int elem, attrs;
578
579static void processNode(xmlTextReaderPtr reader) {
580    xmlChar *name, *value;
581
582    name = xmlTextReaderName(reader);
583    if (name == NULL)
584        name = xmlStrdup(BAD_CAST "--");
585    value = xmlTextReaderValue(reader);
586
587    printf("%d %d %s %d",
588            xmlTextReaderDepth(reader),
589            xmlTextReaderNodeType(reader),
590            name,
591            xmlTextReaderIsEmptyElement(reader));
592    xmlFree(name);
593    if (value == NULL)
594        printf("\n");
595    else {
596        printf(" %s\n", value);
597        xmlFree(value);
598    }
599}
600
601static void streamFile(char *filename) {
602    xmlTextReaderPtr reader;
603    int ret;
604
605    if (count) {
606        elem = 0;
607        attrs = 0;
608    }
609
610    reader = xmlNewTextReaderFilename(filename);
611    if (reader != NULL) {
612        if (valid)
613            xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
614
615        /*
616         * Process all nodes in sequence
617         */
618        ret = xmlTextReaderRead(reader);
619        while (ret == 1) {
620            if (debug)
621                processNode(reader);
622            ret = xmlTextReaderRead(reader);
623        }
624
625        /*
626         * Done, cleanup and status
627         */
628        xmlFreeTextReader(reader);
629        if (ret != 0) {
630            printf("%s : failed to parse\n", filename);
631        }
632    } else {
633        fprintf(stderr, "Unable to open %s\n", filename);
634    }
635}
636
637/************************************************************************
638 *                                                                      *
639 *                      Tree Test processing                            *
640 *                                                                      *
641 ************************************************************************/
642static void parseAndPrintFile(char *filename) {
643    xmlDocPtr doc = NULL, tmp;
644
645    if ((timing) && (!repeat))
646        startTimer();
647   
648
649    if (filename == NULL) {
650        if (generate) {
651            xmlNodePtr n;
652
653            doc = xmlNewDoc(BAD_CAST "1.0");
654            n = xmlNewNode(NULL, BAD_CAST "info");
655            xmlNodeSetContent(n, BAD_CAST "abc");
656            xmlDocSetRootElement(doc, n);
657        }
658    }
659#ifdef LIBXML_DOCB_ENABLED
660    /*
661     * build an SGML tree from a string;
662     */
663    else if ((sgml) && (push)) {
664        FILE *f;
665
666        f = fopen(filename, "r");
667        if (f != NULL) {
668            int res, size = 3;
669            char chars[4096];
670            docbParserCtxtPtr ctxt;
671
672            /* if (repeat) */
673                size = 4096;
674            res = fread(chars, 1, 4, f);
675            if (res > 0) {
676                ctxt = docbCreatePushParserCtxt(NULL, NULL,
677                            chars, res, filename, 0);
678                while ((res = fread(chars, 1, size, f)) > 0) {
679                    docbParseChunk(ctxt, chars, res, 0);
680                }
681                docbParseChunk(ctxt, chars, 0, 1);
682                doc = ctxt->myDoc;
683                docbFreeParserCtxt(ctxt);
684            }
685            fclose(f);
686        }
687    } else if (sgml) { 
688        doc = docbParseFile(filename, NULL);
689    }
690#endif
691#ifdef LIBXML_HTML_ENABLED
692    else if (html) {
693        doc = htmlParseFile(filename, NULL);
694    }
695#endif /* LIBXML_HTML_ENABLED */
696    else {
697        /*
698         * build an XML tree from a string;
699         */
700        if (push) {
701            FILE *f;
702
703            /* '-' Usually means stdin -<sven@zen.org> */
704            if ((filename[0] == '-') && (filename[1] == 0)) {
705              f = stdin;
706            } else {
707              f = fopen(filename, "r");
708            }
709            if (f != NULL) {
710                int ret;
711                int res, size = 3;
712                char chars[1024];
713                xmlParserCtxtPtr ctxt;
714
715                if (repeat)
716                    size = 1024;
717                res = fread(chars, 1, 4, f);
718                if (res > 0) {
719                    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
720                                chars, res, filename);
721                    while ((res = fread(chars, 1, size, f)) > 0) {
722                        xmlParseChunk(ctxt, chars, res, 0);
723                    }
724                    xmlParseChunk(ctxt, chars, 0, 1);
725                    doc = ctxt->myDoc;
726                    ret = ctxt->wellFormed;
727                    xmlFreeParserCtxt(ctxt);
728                    if (!ret) {
729                        xmlFreeDoc(doc);
730                        doc = NULL;
731                    }
732                }
733            }
734        } else if (testIO) {
735            int ret;
736            FILE *f;
737
738            /* '-' Usually means stdin -<sven@zen.org> */
739            if ((filename[0] == '-') && (filename[1] == 0)) {
740              f = stdin;
741            } else {
742              f = fopen(filename, "r");
743            }
744            if (f != NULL) {
745                xmlParserCtxtPtr ctxt;
746
747                ctxt = xmlCreateIOParserCtxt(NULL, NULL,
748                            (xmlInputReadCallback) myRead,
749                            (xmlInputCloseCallback) myClose,
750                            f, XML_CHAR_ENCODING_NONE);
751                xmlParseDocument(ctxt);
752
753                ret = ctxt->wellFormed;
754                doc = ctxt->myDoc;
755                xmlFreeParserCtxt(ctxt);
756                if (!ret) {
757                    xmlFreeDoc(doc);
758                    doc = NULL;
759                }
760            }
761        } else if (recovery) {
762            doc = xmlRecoverFile(filename);
763        } else if (htmlout) {
764            int ret;
765            xmlParserCtxtPtr ctxt;
766            xmlSAXHandler silent, *old;
767
768            ctxt = xmlCreateFileParserCtxt(filename);
769
770            if (ctxt == NULL) {       
771              /* If xmlCreateFileParserCtxt() return NULL something
772                 strange happened so we don't want to do anything.  Do
773                 we want to print an error message here?
774                 <sven@zen.org> */
775              doc = NULL;
776            } else {
777              memcpy(&silent, ctxt->sax, sizeof(silent));
778              old = ctxt->sax;
779              silent.error = xmlHTMLError;
780              if (xmlGetWarningsDefaultValue)
781                silent.warning = xmlHTMLWarning;
782              else
783                silent.warning = NULL;
784              silent.fatalError = xmlHTMLError;
785              ctxt->sax = &silent;
786              ctxt->vctxt.error = xmlHTMLValidityError;
787              if (xmlGetWarningsDefaultValue)
788                ctxt->vctxt.warning = xmlHTMLValidityWarning;
789              else
790                ctxt->vctxt.warning = NULL;
791
792              xmlParseDocument(ctxt);
793
794              ret = ctxt->wellFormed;
795              doc = ctxt->myDoc;
796              ctxt->sax = old;
797              xmlFreeParserCtxt(ctxt);
798              if (!ret) {
799                xmlFreeDoc(doc);
800                doc = NULL;
801              }
802            }
803#ifdef HAVE_SYS_MMAN_H
804        } else if (memory) {
805            int fd;
806            struct stat info;
807            const char *base;
808            if (stat(filename, &info) < 0)
809                return;
810            if ((fd = open(filename, O_RDONLY)) < 0)
811                return;
812            base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
813            if (base == (void *) MAP_FAILED)
814                return;
815
816            doc = xmlParseMemory((char *) base, info.st_size);
817            munmap((char *) base, info.st_size);
818#endif
819        } else if (valid) {
820            int ret;
821            xmlParserCtxtPtr ctxt;
822
823            ctxt = xmlCreateFileParserCtxt(filename);
824
825            if (ctxt == NULL) {       
826              doc = NULL;
827            } else {
828              xmlParseDocument(ctxt);
829              if (ctxt->valid == 0)
830                  progresult = 4;
831              ret = ctxt->wellFormed;
832              doc = ctxt->myDoc;
833              xmlFreeParserCtxt(ctxt);
834              if (!ret) {
835                xmlFreeDoc(doc);
836                doc = NULL;
837              }
838            }
839        } else {
840            doc = xmlParseFile(filename);
841        }
842    }
843
844    /*
845     * If we don't have a document we might as well give up.  Do we
846     * want an error message here?  <sven@zen.org> */
847    if (doc == NULL) {
848        progresult = 1;
849        return;
850    }
851
852    if ((timing) && (!repeat)) {
853        endTimer("Parsing");
854    }
855
856    /*
857     * Remove DOCTYPE nodes
858     */
859    if (dropdtd) {
860        xmlDtdPtr dtd;
861
862        dtd = xmlGetIntSubset(doc);
863        if (dtd != NULL) {
864            xmlUnlinkNode((xmlNodePtr)dtd);
865            xmlFreeDtd(dtd);
866        }
867    }
868
869#ifdef LIBXML_XINCLUDE_ENABLED
870    if (xinclude) {
871        if ((timing) && (!repeat)) {
872            startTimer();
873        }
874        xmlXIncludeProcess(doc);
875        if ((timing) && (!repeat)) {
876            endTimer("Xinclude processing");
877        }
878    }
879#endif
880
881#ifdef LIBXML_DEBUG_ENABLED
882    /*
883     * shell interaction
884     */
885    if (shell) 
886        xmlShell(doc, filename, xmlShellReadline, stdout);
887#endif
888
889    /*
890     * test intermediate copy if needed.
891     */
892    if (copy) {
893        tmp = doc;
894        doc = xmlCopyDoc(doc, 1);
895        xmlFreeDoc(tmp);
896    }
897
898    if ((insert) && (!html)) {
899        const xmlChar* list[256];
900        int nb, i;
901        xmlNodePtr node;
902
903        if (doc->children != NULL) {
904            node = doc->children;
905            while ((node != NULL) && (node->last == NULL)) node = node->next;
906            if (node != NULL) {
907                nb = xmlValidGetValidElements(node->last, NULL, list, 256);
908                if (nb < 0) {
909                    printf("could not get valid list of elements\n");
910                } else if (nb == 0) {
911                    printf("No element can be inserted under root\n");
912                } else {
913                    printf("%d element types can be inserted under root:\n",
914                           nb);
915                    for (i = 0;i < nb;i++) {
916                         printf("%s\n", (char *) list[i]);
917                    }
918                }
919            }
920        }   
921    }else if (noout == 0) {
922        /*
923         * print it.
924         */
925#ifdef LIBXML_DEBUG_ENABLED
926        if (!debug) {
927#endif
928            if ((timing) && (!repeat)) {
929                startTimer();
930            }
931#ifdef HAVE_SYS_MMAN_H
932            if (memory) {
933                xmlChar *result;
934                int len;
935
936                if (encoding != NULL) {
937                    if ( format ) {
938                        xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
939                    } else {
940                        xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
941                    }
942                } else {
943                    if (format)
944                        xmlDocDumpFormatMemory(doc, &result, &len, 1);
945                    else
946                        xmlDocDumpMemory(doc, &result, &len);
947                }
948                if (result == NULL) {
949                    fprintf(stderr, "Failed to save\n");
950                } else {
951                    write(1, result, len);
952                    xmlFree(result);
953                }
954            } else
955#endif /* HAVE_SYS_MMAN_H */
956            if (compress) {
957                xmlSaveFile(output ? output : "-", doc);
958            }
959            else if (encoding != NULL) {
960                if ( format ) {
961                    xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
962                }
963                else {
964                    xmlSaveFileEnc(output ? output : "-", doc, encoding);
965                }
966            }
967            else if (format) {
968                xmlSaveFormatFile(output ? output : "-", doc, 1);
969            }
970            else {
971                FILE *out;
972                if (output == NULL)
973                    out = stdout;
974                else {
975                    out = fopen(output,"wb");
976                }
977                xmlDocDump(out, doc);
978
979                if (output)
980                    fclose(out);
981            }
982            if ((timing) && (!repeat)) {
983                endTimer("Saving");
984            }
985#ifdef LIBXML_DEBUG_ENABLED
986        } else {
987            FILE *out;
988            if (output == NULL)
989                out = stdout;
990            else {
991                out = fopen(output,"wb");
992            }
993            xmlDebugDumpDocument(out, doc);
994
995            if (output)
996                fclose(out);
997        }
998#endif
999    }
1000
1001    /*
1002     * A posteriori validation test
1003     */
1004    if (dtdvalid != NULL) {
1005        xmlDtdPtr dtd;
1006
1007        if ((timing) && (!repeat)) {
1008            startTimer();
1009        }
1010        dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
1011        if ((timing) && (!repeat)) {
1012            endTimer("Parsing DTD");
1013        }
1014        if (dtd == NULL) {
1015            xmlGenericError(xmlGenericErrorContext,
1016                    "Could not parse DTD %s\n", dtdvalid);
1017            progresult = 2;
1018        } else {
1019            xmlValidCtxt cvp;
1020            if ((timing) && (!repeat)) {
1021                startTimer();
1022            }
1023            cvp.userData = (void *) stderr;
1024            cvp.error    = (xmlValidityErrorFunc) fprintf;
1025            cvp.warning  = (xmlValidityWarningFunc) fprintf;
1026            if (!xmlValidateDtd(&cvp, doc, dtd)) {
1027                xmlGenericError(xmlGenericErrorContext,
1028                        "Document %s does not validate against %s\n",
1029                        filename, dtdvalid);
1030                progresult = 3;
1031            }
1032            if ((timing) && (!repeat)) {
1033                endTimer("Validating against DTD");
1034            }
1035            xmlFreeDtd(dtd);
1036        }
1037    } else if (postvalid) {
1038        xmlValidCtxt cvp;
1039        if ((timing) && (!repeat)) {
1040            startTimer();
1041        }
1042        cvp.userData = (void *) stderr;
1043        cvp.error    = (xmlValidityErrorFunc) fprintf;
1044        cvp.warning  = (xmlValidityWarningFunc) fprintf;
1045        if (!xmlValidateDocument(&cvp, doc)) {
1046            xmlGenericError(xmlGenericErrorContext,
1047                    "Document %s does not validate\n", filename);
1048            progresult = 3;
1049        }
1050        if ((timing) && (!repeat)) {
1051            endTimer("Validating");
1052        }
1053    }
1054
1055#ifdef LIBXML_DEBUG_ENABLED
1056    if ((debugent) && (!html))
1057        xmlDebugDumpEntities(stderr, doc);
1058#endif
1059
1060    /*
1061     * free it.
1062     */
1063    if ((timing) && (!repeat)) {
1064        startTimer();
1065    }
1066    xmlFreeDoc(doc);
1067    if ((timing) && (!repeat)) {
1068        endTimer("Freeing");
1069    }
1070}
1071
1072/************************************************************************
1073 *                                                                      *
1074 *                      Usage and Main                                  *
1075 *                                                                      *
1076 ************************************************************************/
1077
1078static void showVersion(const char *name) {
1079    fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1080    fprintf(stderr, "   compiled with: ");
1081#ifdef LIBXML_FTP_ENABLED
1082    fprintf(stderr, "FTP ");
1083#endif
1084#ifdef LIBXML_HTTP_ENABLED
1085    fprintf(stderr, "HTTP ");
1086#endif
1087#ifdef LIBXML_HTML_ENABLED
1088    fprintf(stderr, "HTML ");
1089#endif
1090#ifdef LIBXML_C14N_ENABLED
1091    fprintf(stderr, "C14N ");
1092#endif
1093#ifdef LIBXML_CATALOG_ENABLED
1094    fprintf(stderr, "Catalog ");
1095#endif
1096#ifdef LIBXML_DOCB_ENABLED
1097    fprintf(stderr, "DocBook ");
1098#endif
1099#ifdef LIBXML_XPATH_ENABLED
1100    fprintf(stderr, "XPath ");
1101#endif
1102#ifdef LIBXML_XPTR_ENABLED
1103    fprintf(stderr, "XPointer ");
1104#endif
1105#ifdef LIBXML_XINCLUDE_ENABLED
1106    fprintf(stderr, "XInclude ");
1107#endif
1108#ifdef LIBXML_ICONV_ENABLED
1109    fprintf(stderr, "Iconv ");
1110#endif
1111#ifdef DEBUG_MEMORY_LOCATION
1112    fprintf(stderr, "MemDebug ");
1113#endif
1114#ifdef LIBXML_UNICODE_ENABLED
1115    fprintf(stderr, "Unicode ");
1116#endif
1117#ifdef LIBXML_REGEXP_ENABLED
1118    fprintf(stderr, "Regexps ");
1119#endif
1120#ifdef LIBXML_AUTOMATA_ENABLED
1121    fprintf(stderr, "Automata ");
1122#endif
1123#ifdef LIBXML_SCHEMAS_ENABLED
1124    fprintf(stderr, "Schemas ");
1125#endif
1126    fprintf(stderr, "\n");
1127}
1128
1129static void usage(const char *name) {
1130    printf("Usage : %s [options] XMLfiles ...\n", name);
1131    printf("\tParse the XML files and output the result of the parsing\n");
1132    printf("\t--version : display the version of the XML library used\n");
1133#ifdef LIBXML_DEBUG_ENABLED
1134    printf("\t--debug : dump a debug tree of the in-memory document\n");
1135    printf("\t--shell : run a navigating shell\n");
1136    printf("\t--debugent : debug the entities defined in the document\n");
1137#else
1138    printf("\t--debug : dump the nodes content when using --stream\n");
1139#endif
1140    printf("\t--copy : used to test the internal copy implementation\n");
1141    printf("\t--recover : output what was parsable on broken XML documents\n");
1142    printf("\t--noent : substitute entity references by their value\n");
1143    printf("\t--noout : don't output the result tree\n");
1144    printf("\t--htmlout : output results as HTML\n");
1145    printf("\t--nowrap : do not put HTML doc wrapper\n");
1146    printf("\t--valid : validate the document in addition to std well-formed check\n");
1147    printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1148    printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
1149    printf("\t--timing : print some timings\n");
1150    printf("\t--output file or -o file: save to a given file\n");
1151    printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1152    printf("\t--insert : ad-hoc test for valid insertions\n");
1153#ifdef HAVE_ZLIB_H
1154    printf("\t--compress : turn on gzip compression of output\n");
1155#endif
1156#ifdef LIBXML_DOCB_ENABLED
1157    printf("\t--sgml : use the DocBook SGML parser\n");
1158#endif
1159#ifdef LIBXML_HTML_ENABLED
1160    printf("\t--html : use the HTML parser\n");
1161#endif
1162    printf("\t--push : use the push mode of the parser\n");
1163#ifdef HAVE_SYS_MMAN_H
1164    printf("\t--memory : parse from memory\n");
1165#endif
1166    printf("\t--nowarning : do not emit warnings from parser/validator\n");
1167    printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
1168    printf("\t--format : reformat/reindent the input\n");
1169    printf("\t--testIO : test user I/O support\n");
1170    printf("\t--encode encoding : output in the given encoding\n");
1171#ifdef LIBXML_CATALOG_ENABLED
1172    printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1173    printf("\t             otherwise XML Catalogs starting from \n");
1174    printf("\t         file:///etc/xml/catalog are activated by default\n");
1175    printf("\t--nocatalogs: deactivate all catalogs\n");
1176#endif
1177    printf("\t--auto : generate a small doc on the fly\n");
1178#ifdef LIBXML_XINCLUDE_ENABLED
1179    printf("\t--xinclude : do XInclude processing\n");
1180#endif
1181    printf("\t--loaddtd : fetch external DTD\n");
1182    printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
1183    printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
1184    printf("\t--stream : use the streaming interface to process very large files\n");
1185    printf("\t--chkregister : verify the node registration code\n");
1186    printf("\nLibxml project home page: http://xmlsoft.org/\n");
1187    printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
1188}
1189
1190static void registerNode(xmlNodePtr node)
1191{
1192    node->_private = malloc(sizeof(long));
1193    *(long*)node->_private = (long) 0x81726354;
1194}
1195
1196static void deregisterNode(xmlNodePtr node)
1197{
1198    assert(node->_private != NULL);
1199    assert(*(long*)node->_private == (long) 0x81726354);
1200    free(node->_private);
1201}
1202
1203int
1204main(int argc, char **argv) {
1205    int i, acount;
1206    int files = 0;
1207    int version = 0;
1208
1209    if (argc <= 1) {
1210        usage(argv[0]);
1211        return(1);
1212    }
1213    LIBXML_TEST_VERSION
1214    for (i = 1; i < argc ; i++) {
1215        if (!strcmp(argv[i], "-"))
1216            break;
1217
1218        if (argv[i][0] != '-')
1219            continue;
1220        if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1221            debug++;
1222        else
1223#ifdef LIBXML_DEBUG_ENABLED
1224        if ((!strcmp(argv[i], "-shell")) ||
1225                 (!strcmp(argv[i], "--shell"))) {
1226            shell++;
1227            noout = 1;
1228        } else
1229#endif
1230        if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1231            copy++;
1232        else if ((!strcmp(argv[i], "-recover")) ||
1233                 (!strcmp(argv[i], "--recover")))
1234            recovery++;
1235        else if ((!strcmp(argv[i], "-noent")) ||
1236                 (!strcmp(argv[i], "--noent")))
1237            noent++;
1238        else if ((!strcmp(argv[i], "-version")) ||
1239                 (!strcmp(argv[i], "--version"))) {
1240            showVersion(argv[0]);
1241            version = 1;
1242        } else if ((!strcmp(argv[i], "-noout")) ||
1243                 (!strcmp(argv[i], "--noout")))
1244            noout++;
1245        else if ((!strcmp(argv[i], "-o")) ||
1246                 (!strcmp(argv[i], "-output")) ||
1247                 (!strcmp(argv[i], "--output"))) {
1248            i++;
1249            output = argv[i];
1250        }
1251        else if ((!strcmp(argv[i], "-htmlout")) ||
1252                 (!strcmp(argv[i], "--htmlout")))
1253            htmlout++;
1254#ifdef LIBXML_DOCB_ENABLED
1255        else if ((!strcmp(argv[i], "-sgml")) ||
1256                 (!strcmp(argv[i], "--sgml"))) {
1257            sgml++;
1258        }
1259#endif
1260#ifdef LIBXML_HTML_ENABLED
1261        else if ((!strcmp(argv[i], "-html")) ||
1262                 (!strcmp(argv[i], "--html"))) {
1263            html++;
1264        }
1265#endif /* LIBXML_HTML_ENABLED */
1266        else if ((!strcmp(argv[i], "-nowrap")) ||
1267                 (!strcmp(argv[i], "--nowrap")))
1268            nowrap++;
1269        else if ((!strcmp(argv[i], "-loaddtd")) ||
1270                 (!strcmp(argv[i], "--loaddtd")))
1271            loaddtd++;
1272        else if ((!strcmp(argv[i], "-dtdattr")) ||
1273                 (!strcmp(argv[i], "--dtdattr"))) {
1274            loaddtd++;
1275            dtdattrs++;
1276        } else if ((!strcmp(argv[i], "-valid")) ||
1277                 (!strcmp(argv[i], "--valid")))
1278            valid++;
1279        else if ((!strcmp(argv[i], "-postvalid")) ||
1280                 (!strcmp(argv[i], "--postvalid"))) {
1281            postvalid++;
1282            loaddtd++;
1283        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
1284                 (!strcmp(argv[i], "--dtdvalid"))) {
1285            i++;
1286            dtdvalid = argv[i];
1287            loaddtd++;
1288        }
1289        else if ((!strcmp(argv[i], "-dropdtd")) ||
1290                 (!strcmp(argv[i], "--dropdtd")))
1291            dropdtd++;
1292        else if ((!strcmp(argv[i], "-insert")) ||
1293                 (!strcmp(argv[i], "--insert")))
1294            insert++;
1295        else if ((!strcmp(argv[i], "-timing")) ||
1296                 (!strcmp(argv[i], "--timing")))
1297            timing++;
1298        else if ((!strcmp(argv[i], "-auto")) ||
1299                 (!strcmp(argv[i], "--auto")))
1300            generate++;
1301        else if ((!strcmp(argv[i], "-repeat")) ||
1302                 (!strcmp(argv[i], "--repeat")))
1303            repeat++;
1304        else if ((!strcmp(argv[i], "-push")) ||
1305                 (!strcmp(argv[i], "--push")))
1306            push++;
1307#ifdef HAVE_SYS_MMAN_H
1308        else if ((!strcmp(argv[i], "-memory")) ||
1309                 (!strcmp(argv[i], "--memory")))
1310            memory++;
1311#endif
1312        else if ((!strcmp(argv[i], "-testIO")) ||
1313                 (!strcmp(argv[i], "--testIO")))
1314            testIO++;
1315#ifdef LIBXML_XINCLUDE_ENABLED
1316        else if ((!strcmp(argv[i], "-xinclude")) ||
1317                 (!strcmp(argv[i], "--xinclude")))
1318            xinclude++;
1319#endif
1320#ifdef HAVE_ZLIB_H
1321        else if ((!strcmp(argv[i], "-compress")) ||
1322                 (!strcmp(argv[i], "--compress"))) {
1323            compress++;
1324            xmlSetCompressMode(9);
1325        }
1326#endif
1327        else if ((!strcmp(argv[i], "-nowarning")) ||
1328                 (!strcmp(argv[i], "--nowarning"))) {
1329            xmlGetWarningsDefaultValue = 0;
1330            xmlPedanticParserDefault(0);
1331        }
1332        else if ((!strcmp(argv[i], "-pedantic")) ||
1333                 (!strcmp(argv[i], "--pedantic"))) {
1334            xmlGetWarningsDefaultValue = 1;
1335            xmlPedanticParserDefault(1);
1336        }
1337#ifdef LIBXML_DEBUG_ENABLED
1338        else if ((!strcmp(argv[i], "-debugent")) ||
1339                 (!strcmp(argv[i], "--debugent"))) {
1340            debugent++;
1341            xmlParserDebugEntities = 1;
1342        }
1343#endif
1344#ifdef LIBXML_CATALOG_ENABLED
1345        else if ((!strcmp(argv[i], "-catalogs")) ||
1346                 (!strcmp(argv[i], "--catalogs"))) {
1347            catalogs++;
1348        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1349                 (!strcmp(argv[i], "--nocatalogs"))) {
1350            nocatalogs++;
1351        }
1352#endif
1353        else if ((!strcmp(argv[i], "-encode")) ||
1354                 (!strcmp(argv[i], "--encode"))) {
1355            i++;
1356            encoding = argv[i];
1357            /*
1358             * OK it's for testing purposes
1359             */
1360            xmlAddEncodingAlias("UTF-8", "DVEnc");
1361        }
1362        else if ((!strcmp(argv[i], "-noblanks")) ||
1363                 (!strcmp(argv[i], "--noblanks"))) {
1364             noblanks++;
1365             xmlKeepBlanksDefault(0);
1366        }
1367        else if ((!strcmp(argv[i], "-format")) ||
1368                 (!strcmp(argv[i], "--format"))) {
1369             noblanks++;
1370             format++;
1371             xmlKeepBlanksDefault(0);
1372        }
1373        else if ((!strcmp(argv[i], "-stream")) ||
1374                 (!strcmp(argv[i], "--stream"))) {
1375             stream++;
1376        }
1377        else if ((!strcmp(argv[i], "-chkregister")) ||
1378                 (!strcmp(argv[i], "--chkregister"))) {
1379             chkregister++;
1380        } else {
1381            fprintf(stderr, "Unknown option %s\n", argv[i]);
1382            usage(argv[0]);
1383            return(1);
1384        }
1385    }
1386
1387#ifdef LIBXML_CATALOG_ENABLED
1388    if (nocatalogs == 0) {
1389        if (catalogs) {
1390            const char *catal;
1391
1392            catal = getenv("SGML_CATALOG_FILES");
1393            if (catal != NULL) {
1394                xmlLoadCatalogs(catal);
1395            } else {
1396                fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1397            }
1398        }
1399    }
1400#endif
1401
1402    if (chkregister) {
1403        xmlRegisterNodeDefault(registerNode);
1404        xmlDeregisterNodeDefault(deregisterNode);
1405    }
1406
1407    xmlLineNumbersDefault(1);
1408    if (loaddtd != 0)
1409        xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1410    if (dtdattrs)
1411        xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
1412    if (noent != 0) xmlSubstituteEntitiesDefault(1);
1413    if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1414    if ((htmlout) && (!nowrap)) {
1415        xmlGenericError(xmlGenericErrorContext,
1416         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
1417        xmlGenericError(xmlGenericErrorContext,
1418                "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1419        xmlGenericError(xmlGenericErrorContext,
1420         "<html><head><title>%s output</title></head>\n",
1421                argv[0]);
1422        xmlGenericError(xmlGenericErrorContext,
1423         "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1424                argv[0]);
1425    }
1426    for (i = 1; i < argc ; i++) {
1427        if ((!strcmp(argv[i], "-encode")) ||
1428                 (!strcmp(argv[i], "--encode"))) {
1429            i++;
1430            continue;
1431        } else if ((!strcmp(argv[i], "-o")) ||
1432                   (!strcmp(argv[i], "-output")) ||
1433                   (!strcmp(argv[i], "--output"))) {
1434            i++;
1435            continue;
1436        }
1437        if ((!strcmp(argv[i], "-dtdvalid")) ||
1438                 (!strcmp(argv[i], "--dtdvalid"))) {
1439            i++;
1440            continue;
1441        }
1442        if ((timing) && (repeat))
1443            startTimer();
1444        /* Remember file names.  "-" means stdin.  <sven@zen.org> */
1445        if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
1446            if (repeat) {
1447                for (acount = 0;acount < 100 * repeat;acount++)
1448                    if (stream != 0)
1449                        streamFile(argv[i]);
1450                    else
1451                        parseAndPrintFile(argv[i]);
1452            } else {
1453                if (stream != 0)
1454                    streamFile(argv[i]);
1455                else
1456                    parseAndPrintFile(argv[i]);
1457            }
1458            files ++;
1459            if ((timing) && (repeat)) {
1460                endTimer("100 iterations");
1461            }
1462        }
1463    }
1464    if (generate)
1465        parseAndPrintFile(NULL);
1466    if ((htmlout) && (!nowrap)) {
1467        xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
1468    }
1469    if ((files == 0) && (!generate) && (version == 0)) {
1470        usage(argv[0]);
1471    }
1472    xmlCleanupParser();
1473    xmlMemoryDump();
1474
1475    return(progresult);
1476}
1477
Note: See TracBrowser for help on using the repository browser.