resetting manifest requested domain to floor
[platform/upstream/libxml2.git] / xmllint.c
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 #include <assert.h>
14
15 #if defined (_WIN32) && !defined(__CYGWIN__)
16 #if defined (_MSC_VER) || defined(__BORLANDC__)
17 #include <winsock2.h>
18 #pragma comment(lib, "ws2_32.lib")
19 #define gettimeofday(p1,p2)
20 #endif /* _MSC_VER */
21 #endif /* _WIN32 */
22
23 #ifdef HAVE_SYS_TIME_H
24 #include <sys/time.h>
25 #endif
26 #ifdef HAVE_TIME_H
27 #include <time.h>
28 #endif
29
30 #ifdef __MINGW32__
31 #define _WINSOCKAPI_
32 #include <wsockcompat.h>
33 #include <winsock2.h>
34 #undef XML_SOCKLEN_T
35 #define XML_SOCKLEN_T unsigned int
36 #endif
37
38 #ifdef HAVE_SYS_TIMEB_H
39 #include <sys/timeb.h>
40 #endif
41
42 #ifdef HAVE_SYS_TYPES_H
43 #include <sys/types.h>
44 #endif
45 #ifdef HAVE_SYS_STAT_H
46 #include <sys/stat.h>
47 #endif
48 #ifdef HAVE_FCNTL_H
49 #include <fcntl.h>
50 #endif
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 #ifdef HAVE_SYS_MMAN_H
55 #include <sys/mman.h>
56 /* seems needed for Solaris */
57 #ifndef MAP_FAILED
58 #define MAP_FAILED ((void *) -1)
59 #endif
60 #endif
61 #ifdef HAVE_STDLIB_H
62 #include <stdlib.h>
63 #endif
64 #ifdef HAVE_LIBREADLINE
65 #include <readline/readline.h>
66 #ifdef HAVE_LIBHISTORY
67 #include <readline/history.h>
68 #endif
69 #endif
70
71 #include <libxml/xmlmemory.h>
72 #include <libxml/parser.h>
73 #include <libxml/parserInternals.h>
74 #include <libxml/HTMLparser.h>
75 #include <libxml/HTMLtree.h>
76 #include <libxml/tree.h>
77 #include <libxml/xpath.h>
78 #include <libxml/debugXML.h>
79 #include <libxml/xmlerror.h>
80 #ifdef LIBXML_XINCLUDE_ENABLED
81 #include <libxml/xinclude.h>
82 #endif
83 #ifdef LIBXML_CATALOG_ENABLED
84 #include <libxml/catalog.h>
85 #endif
86 #include <libxml/globals.h>
87 #include <libxml/xmlreader.h>
88 #ifdef LIBXML_SCHEMATRON_ENABLED
89 #include <libxml/schematron.h>
90 #endif
91 #ifdef LIBXML_SCHEMAS_ENABLED
92 #include <libxml/relaxng.h>
93 #include <libxml/xmlschemas.h>
94 #endif
95 #ifdef LIBXML_PATTERN_ENABLED
96 #include <libxml/pattern.h>
97 #endif
98 #ifdef LIBXML_C14N_ENABLED
99 #include <libxml/c14n.h>
100 #endif
101 #ifdef LIBXML_OUTPUT_ENABLED
102 #include <libxml/xmlsave.h>
103 #endif
104
105 #ifndef XML_XML_DEFAULT_CATALOG
106 #define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
107 #endif
108
109 typedef enum {
110     XMLLINT_RETURN_OK = 0,      /* No error */
111     XMLLINT_ERR_UNCLASS = 1,    /* Unclassified */
112     XMLLINT_ERR_DTD = 2,        /* Error in DTD */
113     XMLLINT_ERR_VALID = 3,      /* Validation error */
114     XMLLINT_ERR_RDFILE = 4,     /* CtxtReadFile error */
115     XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
116     XMLLINT_ERR_OUT = 6,        /* Error writing output */
117     XMLLINT_ERR_SCHEMAPAT = 7,  /* Error in schema pattern */
118     XMLLINT_ERR_RDREGIS = 8,    /* Error in Reader registration */
119     XMLLINT_ERR_MEM = 9,        /* Out of memory error */
120     XMLLINT_ERR_XPATH = 10      /* XPath evaluation error */
121 } xmllintReturnCode;
122 #ifdef LIBXML_DEBUG_ENABLED
123 static int shell = 0;
124 static int debugent = 0;
125 #endif
126 static int debug = 0;
127 static int maxmem = 0;
128 #ifdef LIBXML_TREE_ENABLED
129 static int copy = 0;
130 #endif /* LIBXML_TREE_ENABLED */
131 static int recovery = 0;
132 static int noent = 0;
133 static int noenc = 0;
134 static int noblanks = 0;
135 static int noout = 0;
136 static int nowrap = 0;
137 #ifdef LIBXML_OUTPUT_ENABLED
138 static int format = 0;
139 static const char *output = NULL;
140 static int compress = 0;
141 static int oldout = 0;
142 #endif /* LIBXML_OUTPUT_ENABLED */
143 #ifdef LIBXML_VALID_ENABLED
144 static int valid = 0;
145 static int postvalid = 0;
146 static char * dtdvalid = NULL;
147 static char * dtdvalidfpi = NULL;
148 #endif
149 #ifdef LIBXML_SCHEMAS_ENABLED
150 static char * relaxng = NULL;
151 static xmlRelaxNGPtr relaxngschemas = NULL;
152 static char * schema = NULL;
153 static xmlSchemaPtr wxschemas = NULL;
154 #endif
155 #ifdef LIBXML_SCHEMATRON_ENABLED
156 static char * schematron = NULL;
157 static xmlSchematronPtr wxschematron = NULL;
158 #endif
159 static int repeat = 0;
160 static int insert = 0;
161 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
162 static int html = 0;
163 static int xmlout = 0;
164 #endif
165 static int htmlout = 0;
166 #if defined(LIBXML_HTML_ENABLED)
167 static int nodefdtd = 0;
168 #endif
169 #ifdef LIBXML_PUSH_ENABLED
170 static int push = 0;
171 #endif /* LIBXML_PUSH_ENABLED */
172 #ifdef HAVE_SYS_MMAN_H
173 static int memory = 0;
174 #endif
175 static int testIO = 0;
176 static char *encoding = NULL;
177 #ifdef LIBXML_XINCLUDE_ENABLED
178 static int xinclude = 0;
179 #endif
180 static int dtdattrs = 0;
181 static int loaddtd = 0;
182 static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
183 static int timing = 0;
184 static int generate = 0;
185 static int dropdtd = 0;
186 #ifdef LIBXML_CATALOG_ENABLED
187 static int catalogs = 0;
188 static int nocatalogs = 0;
189 #endif
190 #ifdef LIBXML_C14N_ENABLED
191 static int canonical = 0;
192 static int canonical_11 = 0;
193 static int exc_canonical = 0;
194 #endif
195 #ifdef LIBXML_READER_ENABLED
196 static int stream = 0;
197 static int walker = 0;
198 #endif /* LIBXML_READER_ENABLED */
199 static int chkregister = 0;
200 static int nbregister = 0;
201 #ifdef LIBXML_SAX1_ENABLED
202 static int sax1 = 0;
203 #endif /* LIBXML_SAX1_ENABLED */
204 #ifdef LIBXML_PATTERN_ENABLED
205 static const char *pattern = NULL;
206 static xmlPatternPtr patternc = NULL;
207 static xmlStreamCtxtPtr patstream = NULL;
208 #endif
209 #ifdef LIBXML_XPATH_ENABLED
210 static const char *xpathquery = NULL;
211 #endif
212 static int options = XML_PARSE_COMPACT;
213 static int sax = 0;
214 static int oldxml10 = 0;
215
216 /************************************************************************
217  *                                                                      *
218  *               Entity loading control and customization.              *
219  *                                                                      *
220  ************************************************************************/
221 #define MAX_PATHS 64
222 #ifdef _WIN32
223 # define PATH_SEPARATOR ';'
224 #else
225 # define PATH_SEPARATOR ':'
226 #endif
227 static xmlChar *paths[MAX_PATHS + 1];
228 static int nbpaths = 0;
229 static int load_trace = 0;
230
231 static
232 void parsePath(const xmlChar *path) {
233     const xmlChar *cur;
234
235     if (path == NULL)
236         return;
237     while (*path != 0) {
238         if (nbpaths >= MAX_PATHS) {
239             fprintf(stderr, "MAX_PATHS reached: too many paths\n");
240             return;
241         }
242         cur = path;
243         while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
244             cur++;
245         path = cur;
246         while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
247             cur++;
248         if (cur != path) {
249             paths[nbpaths] = xmlStrndup(path, cur - path);
250             if (paths[nbpaths] != NULL)
251                 nbpaths++;
252             path = cur;
253         }
254     }
255 }
256
257 static xmlExternalEntityLoader defaultEntityLoader = NULL;
258
259 static xmlParserInputPtr
260 xmllintExternalEntityLoader(const char *URL, const char *ID,
261                              xmlParserCtxtPtr ctxt) {
262     xmlParserInputPtr ret;
263     warningSAXFunc warning = NULL;
264     errorSAXFunc err = NULL;
265
266     int i;
267     const char *lastsegment = URL;
268     const char *iter = URL;
269
270     if ((nbpaths > 0) && (iter != NULL)) {
271         while (*iter != 0) {
272             if (*iter == '/')
273                 lastsegment = iter + 1;
274             iter++;
275         }
276     }
277
278     if ((ctxt != NULL) && (ctxt->sax != NULL)) {
279         warning = ctxt->sax->warning;
280         err = ctxt->sax->error;
281         ctxt->sax->warning = NULL;
282         ctxt->sax->error = NULL;
283     }
284
285     if (defaultEntityLoader != NULL) {
286         ret = defaultEntityLoader(URL, ID, ctxt);
287         if (ret != NULL) {
288             if (warning != NULL)
289                 ctxt->sax->warning = warning;
290             if (err != NULL)
291                 ctxt->sax->error = err;
292             if (load_trace) {
293                 fprintf \
294                         (stderr,
295                          "Loaded URL=\"%s\" ID=\"%s\"\n",
296                          URL ? URL : "(null)",
297                          ID ? ID : "(null)");
298             }
299             return(ret);
300         }
301     }
302     for (i = 0;i < nbpaths;i++) {
303         xmlChar *newURL;
304
305         newURL = xmlStrdup((const xmlChar *) paths[i]);
306         newURL = xmlStrcat(newURL, (const xmlChar *) "/");
307         newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
308         if (newURL != NULL) {
309             ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
310             if (ret != NULL) {
311                 if (warning != NULL)
312                     ctxt->sax->warning = warning;
313                 if (err != NULL)
314                     ctxt->sax->error = err;
315                 if (load_trace) {
316                     fprintf \
317                         (stderr,
318                          "Loaded URL=\"%s\" ID=\"%s\"\n",
319                          newURL,
320                          ID ? ID : "(null)");
321                 }
322                 xmlFree(newURL);
323                 return(ret);
324             }
325             xmlFree(newURL);
326         }
327     }
328     if (err != NULL)
329         ctxt->sax->error = err;
330     if (warning != NULL) {
331         ctxt->sax->warning = warning;
332         if (URL != NULL)
333             warning(ctxt, "failed to load external entity \"%s\"\n", URL);
334         else if (ID != NULL)
335             warning(ctxt, "failed to load external entity \"%s\"\n", ID);
336     }
337     return(NULL);
338 }
339 /************************************************************************
340  *                                                                      *
341  * Memory allocation consumption debugging                              *
342  *                                                                      *
343  ************************************************************************/
344
345 static void
346 OOM(void)
347 {
348     fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
349     progresult = XMLLINT_ERR_MEM;
350 }
351
352 static void
353 myFreeFunc(void *mem)
354 {
355     xmlMemFree(mem);
356 }
357 static void *
358 myMallocFunc(size_t size)
359 {
360     void *ret;
361
362     ret = xmlMemMalloc(size);
363     if (ret != NULL) {
364         if (xmlMemUsed() > maxmem) {
365             OOM();
366             xmlMemFree(ret);
367             return (NULL);
368         }
369     }
370     return (ret);
371 }
372 static void *
373 myReallocFunc(void *mem, size_t size)
374 {
375     void *ret;
376
377     ret = xmlMemRealloc(mem, size);
378     if (ret != NULL) {
379         if (xmlMemUsed() > maxmem) {
380             OOM();
381             xmlMemFree(ret);
382             return (NULL);
383         }
384     }
385     return (ret);
386 }
387 static char *
388 myStrdupFunc(const char *str)
389 {
390     char *ret;
391
392     ret = xmlMemoryStrdup(str);
393     if (ret != NULL) {
394         if (xmlMemUsed() > maxmem) {
395             OOM();
396             xmlFree(ret);
397             return (NULL);
398         }
399     }
400     return (ret);
401 }
402 /************************************************************************
403  *                                                                      *
404  * Internal timing routines to remove the necessity to have             *
405  * unix-specific function calls.                                        *
406  *                                                                      *
407  ************************************************************************/
408
409 #ifndef HAVE_GETTIMEOFDAY
410 #ifdef HAVE_SYS_TIMEB_H
411 #ifdef HAVE_SYS_TIME_H
412 #ifdef HAVE_FTIME
413
414 static int
415 my_gettimeofday(struct timeval *tvp, void *tzp)
416 {
417         struct timeb timebuffer;
418
419         ftime(&timebuffer);
420         if (tvp) {
421                 tvp->tv_sec = timebuffer.time;
422                 tvp->tv_usec = timebuffer.millitm * 1000L;
423         }
424         return (0);
425 }
426 #define HAVE_GETTIMEOFDAY 1
427 #define gettimeofday my_gettimeofday
428
429 #endif /* HAVE_FTIME */
430 #endif /* HAVE_SYS_TIME_H */
431 #endif /* HAVE_SYS_TIMEB_H */
432 #endif /* !HAVE_GETTIMEOFDAY */
433
434 #if defined(HAVE_GETTIMEOFDAY)
435 static struct timeval begin, end;
436
437 /*
438  * startTimer: call where you want to start timing
439  */
440 static void
441 startTimer(void)
442 {
443     gettimeofday(&begin, NULL);
444 }
445
446 /*
447  * endTimer: call where you want to stop timing and to print out a
448  *           message about the timing performed; format is a printf
449  *           type argument
450  */
451 static void XMLCDECL
452 endTimer(const char *fmt, ...)
453 {
454     long msec;
455     va_list ap;
456
457     gettimeofday(&end, NULL);
458     msec = end.tv_sec - begin.tv_sec;
459     msec *= 1000;
460     msec += (end.tv_usec - begin.tv_usec) / 1000;
461
462 #ifndef HAVE_STDARG_H
463 #error "endTimer required stdarg functions"
464 #endif
465     va_start(ap, fmt);
466     vfprintf(stderr, fmt, ap);
467     va_end(ap);
468
469     fprintf(stderr, " took %ld ms\n", msec);
470 }
471 #elif defined(HAVE_TIME_H)
472 /*
473  * No gettimeofday function, so we have to make do with calling clock.
474  * This is obviously less accurate, but there's little we can do about
475  * that.
476  */
477 #ifndef CLOCKS_PER_SEC
478 #define CLOCKS_PER_SEC 100
479 #endif
480
481 static clock_t begin, end;
482 static void
483 startTimer(void)
484 {
485     begin = clock();
486 }
487 static void XMLCDECL
488 endTimer(const char *fmt, ...)
489 {
490     long msec;
491     va_list ap;
492
493     end = clock();
494     msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
495
496 #ifndef HAVE_STDARG_H
497 #error "endTimer required stdarg functions"
498 #endif
499     va_start(ap, fmt);
500     vfprintf(stderr, fmt, ap);
501     va_end(ap);
502     fprintf(stderr, " took %ld ms\n", msec);
503 }
504 #else
505
506 /*
507  * We don't have a gettimeofday or time.h, so we just don't do timing
508  */
509 static void
510 startTimer(void)
511 {
512     /*
513      * Do nothing
514      */
515 }
516 static void XMLCDECL
517 endTimer(char *format, ...)
518 {
519     /*
520      * We cannot do anything because we don't have a timing function
521      */
522 #ifdef HAVE_STDARG_H
523     va_list ap;
524     va_start(ap, format);
525     vfprintf(stderr, format, ap);
526     va_end(ap);
527     fprintf(stderr, " was not timed\n");
528 #else
529     /* We don't have gettimeofday, time or stdarg.h, what crazy world is
530      * this ?!
531      */
532 #endif
533 }
534 #endif
535 /************************************************************************
536  *                                                                      *
537  *                      HTML ouput                                      *
538  *                                                                      *
539  ************************************************************************/
540 static char buffer[50000];
541
542 static void
543 xmlHTMLEncodeSend(void) {
544     char *result;
545
546     result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
547     if (result) {
548         xmlGenericError(xmlGenericErrorContext, "%s", result);
549         xmlFree(result);
550     }
551     buffer[0] = 0;
552 }
553
554 /**
555  * xmlHTMLPrintFileInfo:
556  * @input:  an xmlParserInputPtr input
557  *
558  * Displays the associated file and line informations for the current input
559  */
560
561 static void
562 xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
563     int len;
564     xmlGenericError(xmlGenericErrorContext, "<p>");
565
566     len = strlen(buffer);
567     if (input != NULL) {
568         if (input->filename) {
569             snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
570                     input->line);
571         } else {
572             snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
573         }
574     }
575     xmlHTMLEncodeSend();
576 }
577
578 /**
579  * xmlHTMLPrintFileContext:
580  * @input:  an xmlParserInputPtr input
581  *
582  * Displays current context within the input content for error tracking
583  */
584
585 static void
586 xmlHTMLPrintFileContext(xmlParserInputPtr input) {
587     const xmlChar *cur, *base;
588     int len;
589     int n;
590
591     if (input == NULL) return;
592     xmlGenericError(xmlGenericErrorContext, "<pre>\n");
593     cur = input->cur;
594     base = input->base;
595     while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
596         cur--;
597     }
598     n = 0;
599     while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
600         cur--;
601     if ((*cur == '\n') || (*cur == '\r')) cur++;
602     base = cur;
603     n = 0;
604     while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
605         len = strlen(buffer);
606         snprintf(&buffer[len], sizeof(buffer) - len, "%c",
607                     (unsigned char) *cur++);
608         n++;
609     }
610     len = strlen(buffer);
611     snprintf(&buffer[len], sizeof(buffer) - len, "\n");
612     cur = input->cur;
613     while ((*cur == '\n') || (*cur == '\r'))
614         cur--;
615     n = 0;
616     while ((cur != base) && (n++ < 80)) {
617         len = strlen(buffer);
618         snprintf(&buffer[len], sizeof(buffer) - len, " ");
619         base++;
620     }
621     len = strlen(buffer);
622     snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
623     xmlHTMLEncodeSend();
624     xmlGenericError(xmlGenericErrorContext, "</pre>");
625 }
626
627 /**
628  * xmlHTMLError:
629  * @ctx:  an XML parser context
630  * @msg:  the message to display/transmit
631  * @...:  extra parameters for the message display
632  *
633  * Display and format an error messages, gives file, line, position and
634  * extra parameters.
635  */
636 static void XMLCDECL
637 xmlHTMLError(void *ctx, const char *msg, ...)
638 {
639     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
640     xmlParserInputPtr input;
641     va_list args;
642     int len;
643
644     buffer[0] = 0;
645     input = ctxt->input;
646     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
647         input = ctxt->inputTab[ctxt->inputNr - 2];
648     }
649
650     xmlHTMLPrintFileInfo(input);
651
652     xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
653     va_start(args, msg);
654     len = strlen(buffer);
655     vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
656     va_end(args);
657     xmlHTMLEncodeSend();
658     xmlGenericError(xmlGenericErrorContext, "</p>\n");
659
660     xmlHTMLPrintFileContext(input);
661     xmlHTMLEncodeSend();
662 }
663
664 /**
665  * xmlHTMLWarning:
666  * @ctx:  an XML parser context
667  * @msg:  the message to display/transmit
668  * @...:  extra parameters for the message display
669  *
670  * Display and format a warning messages, gives file, line, position and
671  * extra parameters.
672  */
673 static void XMLCDECL
674 xmlHTMLWarning(void *ctx, const char *msg, ...)
675 {
676     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
677     xmlParserInputPtr input;
678     va_list args;
679     int len;
680
681     buffer[0] = 0;
682     input = ctxt->input;
683     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
684         input = ctxt->inputTab[ctxt->inputNr - 2];
685     }
686
687
688     xmlHTMLPrintFileInfo(input);
689
690     xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
691     va_start(args, msg);
692     len = strlen(buffer);
693     vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
694     va_end(args);
695     xmlHTMLEncodeSend();
696     xmlGenericError(xmlGenericErrorContext, "</p>\n");
697
698     xmlHTMLPrintFileContext(input);
699     xmlHTMLEncodeSend();
700 }
701
702 /**
703  * xmlHTMLValidityError:
704  * @ctx:  an XML parser context
705  * @msg:  the message to display/transmit
706  * @...:  extra parameters for the message display
707  *
708  * Display and format an validity error messages, gives file,
709  * line, position and extra parameters.
710  */
711 static void XMLCDECL
712 xmlHTMLValidityError(void *ctx, const char *msg, ...)
713 {
714     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
715     xmlParserInputPtr input;
716     va_list args;
717     int len;
718
719     buffer[0] = 0;
720     input = ctxt->input;
721     if ((input->filename == NULL) && (ctxt->inputNr > 1))
722         input = ctxt->inputTab[ctxt->inputNr - 2];
723
724     xmlHTMLPrintFileInfo(input);
725
726     xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
727     len = strlen(buffer);
728     va_start(args, msg);
729     vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
730     va_end(args);
731     xmlHTMLEncodeSend();
732     xmlGenericError(xmlGenericErrorContext, "</p>\n");
733
734     xmlHTMLPrintFileContext(input);
735     xmlHTMLEncodeSend();
736     progresult = XMLLINT_ERR_VALID;
737 }
738
739 /**
740  * xmlHTMLValidityWarning:
741  * @ctx:  an XML parser context
742  * @msg:  the message to display/transmit
743  * @...:  extra parameters for the message display
744  *
745  * Display and format a validity warning messages, gives file, line,
746  * position and extra parameters.
747  */
748 static void XMLCDECL
749 xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
750 {
751     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
752     xmlParserInputPtr input;
753     va_list args;
754     int len;
755
756     buffer[0] = 0;
757     input = ctxt->input;
758     if ((input->filename == NULL) && (ctxt->inputNr > 1))
759         input = ctxt->inputTab[ctxt->inputNr - 2];
760
761     xmlHTMLPrintFileInfo(input);
762
763     xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
764     va_start(args, msg);
765     len = strlen(buffer);
766     vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
767     va_end(args);
768     xmlHTMLEncodeSend();
769     xmlGenericError(xmlGenericErrorContext, "</p>\n");
770
771     xmlHTMLPrintFileContext(input);
772     xmlHTMLEncodeSend();
773 }
774
775 /************************************************************************
776  *                                                                      *
777  *                      Shell Interface                                 *
778  *                                                                      *
779  ************************************************************************/
780 #ifdef LIBXML_DEBUG_ENABLED
781 #ifdef LIBXML_XPATH_ENABLED
782 /**
783  * xmlShellReadline:
784  * @prompt:  the prompt value
785  *
786  * Read a string
787  *
788  * Returns a pointer to it or NULL on EOF the caller is expected to
789  *     free the returned string.
790  */
791 static char *
792 xmlShellReadline(char *prompt) {
793 #ifdef HAVE_LIBREADLINE
794     char *line_read;
795
796     /* Get a line from the user. */
797     line_read = readline (prompt);
798
799     /* If the line has any text in it, save it on the history. */
800     if (line_read && *line_read)
801         add_history (line_read);
802
803     return (line_read);
804 #else
805     char line_read[501];
806     char *ret;
807     int len;
808
809     if (prompt != NULL)
810         fprintf(stdout, "%s", prompt);
811     if (!fgets(line_read, 500, stdin))
812         return(NULL);
813     line_read[500] = 0;
814     len = strlen(line_read);
815     ret = (char *) malloc(len + 1);
816     if (ret != NULL) {
817         memcpy (ret, line_read, len + 1);
818     }
819     return(ret);
820 #endif
821 }
822 #endif /* LIBXML_XPATH_ENABLED */
823 #endif /* LIBXML_DEBUG_ENABLED */
824
825 /************************************************************************
826  *                                                                      *
827  *                      I/O Interfaces                                  *
828  *                                                                      *
829  ************************************************************************/
830
831 static int myRead(FILE *f, char * buf, int len) {
832     return(fread(buf, 1, len, f));
833 }
834 static void myClose(FILE *f) {
835   if (f != stdin) {
836     fclose(f);
837   }
838 }
839
840 /************************************************************************
841  *                                                                      *
842  *                      SAX based tests                                 *
843  *                                                                      *
844  ************************************************************************/
845
846 /*
847  * empty SAX block
848  */
849 static xmlSAXHandler emptySAXHandlerStruct = {
850     NULL, /* internalSubset */
851     NULL, /* isStandalone */
852     NULL, /* hasInternalSubset */
853     NULL, /* hasExternalSubset */
854     NULL, /* resolveEntity */
855     NULL, /* getEntity */
856     NULL, /* entityDecl */
857     NULL, /* notationDecl */
858     NULL, /* attributeDecl */
859     NULL, /* elementDecl */
860     NULL, /* unparsedEntityDecl */
861     NULL, /* setDocumentLocator */
862     NULL, /* startDocument */
863     NULL, /* endDocument */
864     NULL, /* startElement */
865     NULL, /* endElement */
866     NULL, /* reference */
867     NULL, /* characters */
868     NULL, /* ignorableWhitespace */
869     NULL, /* processingInstruction */
870     NULL, /* comment */
871     NULL, /* xmlParserWarning */
872     NULL, /* xmlParserError */
873     NULL, /* xmlParserError */
874     NULL, /* getParameterEntity */
875     NULL, /* cdataBlock; */
876     NULL, /* externalSubset; */
877     XML_SAX2_MAGIC,
878     NULL,
879     NULL, /* startElementNs */
880     NULL, /* endElementNs */
881     NULL  /* xmlStructuredErrorFunc */
882 };
883
884 static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
885 extern xmlSAXHandlerPtr debugSAXHandler;
886 static int callbacks;
887
888 /**
889  * isStandaloneDebug:
890  * @ctxt:  An XML parser context
891  *
892  * Is this document tagged standalone ?
893  *
894  * Returns 1 if true
895  */
896 static int
897 isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
898 {
899     callbacks++;
900     if (noout)
901         return(0);
902     fprintf(stdout, "SAX.isStandalone()\n");
903     return(0);
904 }
905
906 /**
907  * hasInternalSubsetDebug:
908  * @ctxt:  An XML parser context
909  *
910  * Does this document has an internal subset
911  *
912  * Returns 1 if true
913  */
914 static int
915 hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
916 {
917     callbacks++;
918     if (noout)
919         return(0);
920     fprintf(stdout, "SAX.hasInternalSubset()\n");
921     return(0);
922 }
923
924 /**
925  * hasExternalSubsetDebug:
926  * @ctxt:  An XML parser context
927  *
928  * Does this document has an external subset
929  *
930  * Returns 1 if true
931  */
932 static int
933 hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
934 {
935     callbacks++;
936     if (noout)
937         return(0);
938     fprintf(stdout, "SAX.hasExternalSubset()\n");
939     return(0);
940 }
941
942 /**
943  * internalSubsetDebug:
944  * @ctxt:  An XML parser context
945  *
946  * Does this document has an internal subset
947  */
948 static void
949 internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
950                const xmlChar *ExternalID, const xmlChar *SystemID)
951 {
952     callbacks++;
953     if (noout)
954         return;
955     fprintf(stdout, "SAX.internalSubset(%s,", name);
956     if (ExternalID == NULL)
957         fprintf(stdout, " ,");
958     else
959         fprintf(stdout, " %s,", ExternalID);
960     if (SystemID == NULL)
961         fprintf(stdout, " )\n");
962     else
963         fprintf(stdout, " %s)\n", SystemID);
964 }
965
966 /**
967  * externalSubsetDebug:
968  * @ctxt:  An XML parser context
969  *
970  * Does this document has an external subset
971  */
972 static void
973 externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
974                const xmlChar *ExternalID, const xmlChar *SystemID)
975 {
976     callbacks++;
977     if (noout)
978         return;
979     fprintf(stdout, "SAX.externalSubset(%s,", name);
980     if (ExternalID == NULL)
981         fprintf(stdout, " ,");
982     else
983         fprintf(stdout, " %s,", ExternalID);
984     if (SystemID == NULL)
985         fprintf(stdout, " )\n");
986     else
987         fprintf(stdout, " %s)\n", SystemID);
988 }
989
990 /**
991  * resolveEntityDebug:
992  * @ctxt:  An XML parser context
993  * @publicId: The public ID of the entity
994  * @systemId: The system ID of the entity
995  *
996  * Special entity resolver, better left to the parser, it has
997  * more context than the application layer.
998  * The default behaviour is to NOT resolve the entities, in that case
999  * the ENTITY_REF nodes are built in the structure (and the parameter
1000  * values).
1001  *
1002  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1003  */
1004 static xmlParserInputPtr
1005 resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1006 {
1007     callbacks++;
1008     if (noout)
1009         return(NULL);
1010     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1011
1012
1013     fprintf(stdout, "SAX.resolveEntity(");
1014     if (publicId != NULL)
1015         fprintf(stdout, "%s", (char *)publicId);
1016     else
1017         fprintf(stdout, " ");
1018     if (systemId != NULL)
1019         fprintf(stdout, ", %s)\n", (char *)systemId);
1020     else
1021         fprintf(stdout, ", )\n");
1022     return(NULL);
1023 }
1024
1025 /**
1026  * getEntityDebug:
1027  * @ctxt:  An XML parser context
1028  * @name: The entity name
1029  *
1030  * Get an entity by name
1031  *
1032  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1033  */
1034 static xmlEntityPtr
1035 getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1036 {
1037     callbacks++;
1038     if (noout)
1039         return(NULL);
1040     fprintf(stdout, "SAX.getEntity(%s)\n", name);
1041     return(NULL);
1042 }
1043
1044 /**
1045  * getParameterEntityDebug:
1046  * @ctxt:  An XML parser context
1047  * @name: The entity name
1048  *
1049  * Get a parameter entity by name
1050  *
1051  * Returns the xmlParserInputPtr
1052  */
1053 static xmlEntityPtr
1054 getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1055 {
1056     callbacks++;
1057     if (noout)
1058         return(NULL);
1059     fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1060     return(NULL);
1061 }
1062
1063
1064 /**
1065  * entityDeclDebug:
1066  * @ctxt:  An XML parser context
1067  * @name:  the entity name
1068  * @type:  the entity type
1069  * @publicId: The public ID of the entity
1070  * @systemId: The system ID of the entity
1071  * @content: the entity value (without processing).
1072  *
1073  * An entity definition has been parsed
1074  */
1075 static void
1076 entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1077           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1078 {
1079 const xmlChar *nullstr = BAD_CAST "(null)";
1080     /* not all libraries handle printing null pointers nicely */
1081     if (publicId == NULL)
1082         publicId = nullstr;
1083     if (systemId == NULL)
1084         systemId = nullstr;
1085     if (content == NULL)
1086         content = (xmlChar *)nullstr;
1087     callbacks++;
1088     if (noout)
1089         return;
1090     fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1091             name, type, publicId, systemId, content);
1092 }
1093
1094 /**
1095  * attributeDeclDebug:
1096  * @ctxt:  An XML parser context
1097  * @name:  the attribute name
1098  * @type:  the attribute type
1099  *
1100  * An attribute definition has been parsed
1101  */
1102 static void
1103 attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1104                    const xmlChar * name, int type, int def,
1105                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
1106 {
1107     callbacks++;
1108     if (noout)
1109         return;
1110     if (defaultValue == NULL)
1111         fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1112                 elem, name, type, def);
1113     else
1114         fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1115                 elem, name, type, def, defaultValue);
1116     xmlFreeEnumeration(tree);
1117 }
1118
1119 /**
1120  * elementDeclDebug:
1121  * @ctxt:  An XML parser context
1122  * @name:  the element name
1123  * @type:  the element type
1124  * @content: the element value (without processing).
1125  *
1126  * An element definition has been parsed
1127  */
1128 static void
1129 elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1130             xmlElementContentPtr content ATTRIBUTE_UNUSED)
1131 {
1132     callbacks++;
1133     if (noout)
1134         return;
1135     fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1136             name, type);
1137 }
1138
1139 /**
1140  * notationDeclDebug:
1141  * @ctxt:  An XML parser context
1142  * @name: The name of the notation
1143  * @publicId: The public ID of the entity
1144  * @systemId: The system ID of the entity
1145  *
1146  * What to do when a notation declaration has been parsed.
1147  */
1148 static void
1149 notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1150              const xmlChar *publicId, const xmlChar *systemId)
1151 {
1152     callbacks++;
1153     if (noout)
1154         return;
1155     fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1156             (char *) name, (char *) publicId, (char *) systemId);
1157 }
1158
1159 /**
1160  * unparsedEntityDeclDebug:
1161  * @ctxt:  An XML parser context
1162  * @name: The name of the entity
1163  * @publicId: The public ID of the entity
1164  * @systemId: The system ID of the entity
1165  * @notationName: the name of the notation
1166  *
1167  * What to do when an unparsed entity declaration is parsed
1168  */
1169 static void
1170 unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1171                    const xmlChar *publicId, const xmlChar *systemId,
1172                    const xmlChar *notationName)
1173 {
1174 const xmlChar *nullstr = BAD_CAST "(null)";
1175
1176     if (publicId == NULL)
1177         publicId = nullstr;
1178     if (systemId == NULL)
1179         systemId = nullstr;
1180     if (notationName == NULL)
1181         notationName = nullstr;
1182     callbacks++;
1183     if (noout)
1184         return;
1185     fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1186             (char *) name, (char *) publicId, (char *) systemId,
1187             (char *) notationName);
1188 }
1189
1190 /**
1191  * setDocumentLocatorDebug:
1192  * @ctxt:  An XML parser context
1193  * @loc: A SAX Locator
1194  *
1195  * Receive the document locator at startup, actually xmlDefaultSAXLocator
1196  * Everything is available on the context, so this is useless in our case.
1197  */
1198 static void
1199 setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1200 {
1201     callbacks++;
1202     if (noout)
1203         return;
1204     fprintf(stdout, "SAX.setDocumentLocator()\n");
1205 }
1206
1207 /**
1208  * startDocumentDebug:
1209  * @ctxt:  An XML parser context
1210  *
1211  * called when the document start being processed.
1212  */
1213 static void
1214 startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1215 {
1216     callbacks++;
1217     if (noout)
1218         return;
1219     fprintf(stdout, "SAX.startDocument()\n");
1220 }
1221
1222 /**
1223  * endDocumentDebug:
1224  * @ctxt:  An XML parser context
1225  *
1226  * called when the document end has been detected.
1227  */
1228 static void
1229 endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1230 {
1231     callbacks++;
1232     if (noout)
1233         return;
1234     fprintf(stdout, "SAX.endDocument()\n");
1235 }
1236
1237 /**
1238  * startElementDebug:
1239  * @ctxt:  An XML parser context
1240  * @name:  The element name
1241  *
1242  * called when an opening tag has been processed.
1243  */
1244 static void
1245 startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1246 {
1247     int i;
1248
1249     callbacks++;
1250     if (noout)
1251         return;
1252     fprintf(stdout, "SAX.startElement(%s", (char *) name);
1253     if (atts != NULL) {
1254         for (i = 0;(atts[i] != NULL);i++) {
1255             fprintf(stdout, ", %s='", atts[i++]);
1256             if (atts[i] != NULL)
1257                 fprintf(stdout, "%s'", atts[i]);
1258         }
1259     }
1260     fprintf(stdout, ")\n");
1261 }
1262
1263 /**
1264  * endElementDebug:
1265  * @ctxt:  An XML parser context
1266  * @name:  The element name
1267  *
1268  * called when the end of an element has been detected.
1269  */
1270 static void
1271 endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1272 {
1273     callbacks++;
1274     if (noout)
1275         return;
1276     fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1277 }
1278
1279 /**
1280  * charactersDebug:
1281  * @ctxt:  An XML parser context
1282  * @ch:  a xmlChar string
1283  * @len: the number of xmlChar
1284  *
1285  * receiving some chars from the parser.
1286  * Question: how much at a time ???
1287  */
1288 static void
1289 charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1290 {
1291     char out[40];
1292     int i;
1293
1294     callbacks++;
1295     if (noout)
1296         return;
1297     for (i = 0;(i<len) && (i < 30);i++)
1298         out[i] = ch[i];
1299     out[i] = 0;
1300
1301     fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1302 }
1303
1304 /**
1305  * referenceDebug:
1306  * @ctxt:  An XML parser context
1307  * @name:  The entity name
1308  *
1309  * called when an entity reference is detected.
1310  */
1311 static void
1312 referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1313 {
1314     callbacks++;
1315     if (noout)
1316         return;
1317     fprintf(stdout, "SAX.reference(%s)\n", name);
1318 }
1319
1320 /**
1321  * ignorableWhitespaceDebug:
1322  * @ctxt:  An XML parser context
1323  * @ch:  a xmlChar string
1324  * @start: the first char in the string
1325  * @len: the number of xmlChar
1326  *
1327  * receiving some ignorable whitespaces from the parser.
1328  * Question: how much at a time ???
1329  */
1330 static void
1331 ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1332 {
1333     char out[40];
1334     int i;
1335
1336     callbacks++;
1337     if (noout)
1338         return;
1339     for (i = 0;(i<len) && (i < 30);i++)
1340         out[i] = ch[i];
1341     out[i] = 0;
1342     fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1343 }
1344
1345 /**
1346  * processingInstructionDebug:
1347  * @ctxt:  An XML parser context
1348  * @target:  the target name
1349  * @data: the PI data's
1350  * @len: the number of xmlChar
1351  *
1352  * A processing instruction has been parsed.
1353  */
1354 static void
1355 processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1356                       const xmlChar *data)
1357 {
1358     callbacks++;
1359     if (noout)
1360         return;
1361     if (data != NULL)
1362         fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1363                 (char *) target, (char *) data);
1364     else
1365         fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1366                 (char *) target);
1367 }
1368
1369 /**
1370  * cdataBlockDebug:
1371  * @ctx: the user data (XML parser context)
1372  * @value:  The pcdata content
1373  * @len:  the block length
1374  *
1375  * called when a pcdata block has been parsed
1376  */
1377 static void
1378 cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1379 {
1380     callbacks++;
1381     if (noout)
1382         return;
1383     fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1384             (char *) value, len);
1385 }
1386
1387 /**
1388  * commentDebug:
1389  * @ctxt:  An XML parser context
1390  * @value:  the comment content
1391  *
1392  * A comment has been parsed.
1393  */
1394 static void
1395 commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1396 {
1397     callbacks++;
1398     if (noout)
1399         return;
1400     fprintf(stdout, "SAX.comment(%s)\n", value);
1401 }
1402
1403 /**
1404  * warningDebug:
1405  * @ctxt:  An XML parser context
1406  * @msg:  the message to display/transmit
1407  * @...:  extra parameters for the message display
1408  *
1409  * Display and format a warning messages, gives file, line, position and
1410  * extra parameters.
1411  */
1412 static void XMLCDECL
1413 warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1414 {
1415     va_list args;
1416
1417     callbacks++;
1418     if (noout)
1419         return;
1420     va_start(args, msg);
1421     fprintf(stdout, "SAX.warning: ");
1422     vfprintf(stdout, msg, args);
1423     va_end(args);
1424 }
1425
1426 /**
1427  * errorDebug:
1428  * @ctxt:  An XML parser context
1429  * @msg:  the message to display/transmit
1430  * @...:  extra parameters for the message display
1431  *
1432  * Display and format a error messages, gives file, line, position and
1433  * extra parameters.
1434  */
1435 static void XMLCDECL
1436 errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1437 {
1438     va_list args;
1439
1440     callbacks++;
1441     if (noout)
1442         return;
1443     va_start(args, msg);
1444     fprintf(stdout, "SAX.error: ");
1445     vfprintf(stdout, msg, args);
1446     va_end(args);
1447 }
1448
1449 /**
1450  * fatalErrorDebug:
1451  * @ctxt:  An XML parser context
1452  * @msg:  the message to display/transmit
1453  * @...:  extra parameters for the message display
1454  *
1455  * Display and format a fatalError messages, gives file, line, position and
1456  * extra parameters.
1457  */
1458 static void XMLCDECL
1459 fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1460 {
1461     va_list args;
1462
1463     callbacks++;
1464     if (noout)
1465         return;
1466     va_start(args, msg);
1467     fprintf(stdout, "SAX.fatalError: ");
1468     vfprintf(stdout, msg, args);
1469     va_end(args);
1470 }
1471
1472 static xmlSAXHandler debugSAXHandlerStruct = {
1473     internalSubsetDebug,
1474     isStandaloneDebug,
1475     hasInternalSubsetDebug,
1476     hasExternalSubsetDebug,
1477     resolveEntityDebug,
1478     getEntityDebug,
1479     entityDeclDebug,
1480     notationDeclDebug,
1481     attributeDeclDebug,
1482     elementDeclDebug,
1483     unparsedEntityDeclDebug,
1484     setDocumentLocatorDebug,
1485     startDocumentDebug,
1486     endDocumentDebug,
1487     startElementDebug,
1488     endElementDebug,
1489     referenceDebug,
1490     charactersDebug,
1491     ignorableWhitespaceDebug,
1492     processingInstructionDebug,
1493     commentDebug,
1494     warningDebug,
1495     errorDebug,
1496     fatalErrorDebug,
1497     getParameterEntityDebug,
1498     cdataBlockDebug,
1499     externalSubsetDebug,
1500     1,
1501     NULL,
1502     NULL,
1503     NULL,
1504     NULL
1505 };
1506
1507 xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1508
1509 /*
1510  * SAX2 specific callbacks
1511  */
1512 /**
1513  * startElementNsDebug:
1514  * @ctxt:  An XML parser context
1515  * @name:  The element name
1516  *
1517  * called when an opening tag has been processed.
1518  */
1519 static void
1520 startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1521                     const xmlChar *localname,
1522                     const xmlChar *prefix,
1523                     const xmlChar *URI,
1524                     int nb_namespaces,
1525                     const xmlChar **namespaces,
1526                     int nb_attributes,
1527                     int nb_defaulted,
1528                     const xmlChar **attributes)
1529 {
1530     int i;
1531
1532     callbacks++;
1533     if (noout)
1534         return;
1535     fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1536     if (prefix == NULL)
1537         fprintf(stdout, ", NULL");
1538     else
1539         fprintf(stdout, ", %s", (char *) prefix);
1540     if (URI == NULL)
1541         fprintf(stdout, ", NULL");
1542     else
1543         fprintf(stdout, ", '%s'", (char *) URI);
1544     fprintf(stdout, ", %d", nb_namespaces);
1545
1546     if (namespaces != NULL) {
1547         for (i = 0;i < nb_namespaces * 2;i++) {
1548             fprintf(stdout, ", xmlns");
1549             if (namespaces[i] != NULL)
1550                 fprintf(stdout, ":%s", namespaces[i]);
1551             i++;
1552             fprintf(stdout, "='%s'", namespaces[i]);
1553         }
1554     }
1555     fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1556     if (attributes != NULL) {
1557         for (i = 0;i < nb_attributes * 5;i += 5) {
1558             if (attributes[i + 1] != NULL)
1559                 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1560             else
1561                 fprintf(stdout, ", %s='", attributes[i]);
1562             fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1563                     (int)(attributes[i + 4] - attributes[i + 3]));
1564         }
1565     }
1566     fprintf(stdout, ")\n");
1567 }
1568
1569 /**
1570  * endElementDebug:
1571  * @ctxt:  An XML parser context
1572  * @name:  The element name
1573  *
1574  * called when the end of an element has been detected.
1575  */
1576 static void
1577 endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1578                   const xmlChar *localname,
1579                   const xmlChar *prefix,
1580                   const xmlChar *URI)
1581 {
1582     callbacks++;
1583     if (noout)
1584         return;
1585     fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1586     if (prefix == NULL)
1587         fprintf(stdout, ", NULL");
1588     else
1589         fprintf(stdout, ", %s", (char *) prefix);
1590     if (URI == NULL)
1591         fprintf(stdout, ", NULL)\n");
1592     else
1593         fprintf(stdout, ", '%s')\n", (char *) URI);
1594 }
1595
1596 static xmlSAXHandler debugSAX2HandlerStruct = {
1597     internalSubsetDebug,
1598     isStandaloneDebug,
1599     hasInternalSubsetDebug,
1600     hasExternalSubsetDebug,
1601     resolveEntityDebug,
1602     getEntityDebug,
1603     entityDeclDebug,
1604     notationDeclDebug,
1605     attributeDeclDebug,
1606     elementDeclDebug,
1607     unparsedEntityDeclDebug,
1608     setDocumentLocatorDebug,
1609     startDocumentDebug,
1610     endDocumentDebug,
1611     NULL,
1612     NULL,
1613     referenceDebug,
1614     charactersDebug,
1615     ignorableWhitespaceDebug,
1616     processingInstructionDebug,
1617     commentDebug,
1618     warningDebug,
1619     errorDebug,
1620     fatalErrorDebug,
1621     getParameterEntityDebug,
1622     cdataBlockDebug,
1623     externalSubsetDebug,
1624     XML_SAX2_MAGIC,
1625     NULL,
1626     startElementNsDebug,
1627     endElementNsDebug,
1628     NULL
1629 };
1630
1631 static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
1632
1633 static void
1634 testSAX(const char *filename) {
1635     xmlSAXHandlerPtr handler;
1636     const char *user_data = "user_data"; /* mostly for debugging */
1637     xmlParserInputBufferPtr buf = NULL;
1638     xmlParserInputPtr inputStream;
1639     xmlParserCtxtPtr ctxt = NULL;
1640     xmlSAXHandlerPtr old_sax = NULL;
1641
1642     callbacks = 0;
1643
1644     if (noout) {
1645         handler = emptySAXHandler;
1646 #ifdef LIBXML_SAX1_ENABLED
1647     } else if (sax1) {
1648         handler = debugSAXHandler;
1649 #endif
1650     } else {
1651         handler = debugSAX2Handler;
1652     }
1653
1654     /*
1655      * it's not the simplest code but the most generic in term of I/O
1656      */
1657     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1658     if (buf == NULL) {
1659         goto error;
1660     }
1661
1662 #ifdef LIBXML_SCHEMAS_ENABLED
1663     if (wxschemas != NULL) {
1664         int ret;
1665         xmlSchemaValidCtxtPtr vctxt;
1666
1667         vctxt = xmlSchemaNewValidCtxt(wxschemas);
1668         xmlSchemaSetValidErrors(vctxt,
1669                 (xmlSchemaValidityErrorFunc) fprintf,
1670                 (xmlSchemaValidityWarningFunc) fprintf,
1671                 stderr);
1672
1673         ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1674                                       (void *)user_data);
1675         if (repeat == 0) {
1676             if (ret == 0) {
1677                 fprintf(stderr, "%s validates\n", filename);
1678             } else if (ret > 0) {
1679                 fprintf(stderr, "%s fails to validate\n", filename);
1680                 progresult = XMLLINT_ERR_VALID;
1681             } else {
1682                 fprintf(stderr, "%s validation generated an internal error\n",
1683                        filename);
1684                 progresult = XMLLINT_ERR_VALID;
1685             }
1686         }
1687         xmlSchemaFreeValidCtxt(vctxt);
1688     } else
1689 #endif
1690     {
1691         /*
1692          * Create the parser context amd hook the input
1693          */
1694         ctxt = xmlNewParserCtxt();
1695         if (ctxt == NULL) {
1696             xmlFreeParserInputBuffer(buf);
1697             goto error;
1698         }
1699         old_sax = ctxt->sax;
1700         ctxt->sax = handler;
1701         ctxt->userData = (void *) user_data;
1702         inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1703         if (inputStream == NULL) {
1704             xmlFreeParserInputBuffer(buf);
1705             goto error;
1706         }
1707         inputPush(ctxt, inputStream);
1708
1709         /* do the parsing */
1710         xmlParseDocument(ctxt);
1711
1712         if (ctxt->myDoc != NULL) {
1713             fprintf(stderr, "SAX generated a doc !\n");
1714             xmlFreeDoc(ctxt->myDoc);
1715             ctxt->myDoc = NULL;
1716         }
1717     }
1718
1719 error:
1720     if (ctxt != NULL) {
1721         ctxt->sax = old_sax;
1722         xmlFreeParserCtxt(ctxt);
1723     }
1724 }
1725
1726 /************************************************************************
1727  *                                                                      *
1728  *                      Stream Test processing                          *
1729  *                                                                      *
1730  ************************************************************************/
1731 #ifdef LIBXML_READER_ENABLED
1732 static void processNode(xmlTextReaderPtr reader) {
1733     const xmlChar *name, *value;
1734     int type, empty;
1735
1736     type = xmlTextReaderNodeType(reader);
1737     empty = xmlTextReaderIsEmptyElement(reader);
1738
1739     if (debug) {
1740         name = xmlTextReaderConstName(reader);
1741         if (name == NULL)
1742             name = BAD_CAST "--";
1743
1744         value = xmlTextReaderConstValue(reader);
1745
1746
1747         printf("%d %d %s %d %d",
1748                 xmlTextReaderDepth(reader),
1749                 type,
1750                 name,
1751                 empty,
1752                 xmlTextReaderHasValue(reader));
1753         if (value == NULL)
1754             printf("\n");
1755         else {
1756             printf(" %s\n", value);
1757         }
1758     }
1759 #ifdef LIBXML_PATTERN_ENABLED
1760     if (patternc) {
1761         xmlChar *path = NULL;
1762         int match = -1;
1763
1764         if (type == XML_READER_TYPE_ELEMENT) {
1765             /* do the check only on element start */
1766             match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1767
1768             if (match) {
1769 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
1770                 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1771                 printf("Node %s matches pattern %s\n", path, pattern);
1772 #else
1773                 printf("Node %s matches pattern %s\n",
1774                        xmlTextReaderConstName(reader), pattern);
1775 #endif
1776             }
1777         }
1778         if (patstream != NULL) {
1779             int ret;
1780
1781             if (type == XML_READER_TYPE_ELEMENT) {
1782                 ret = xmlStreamPush(patstream,
1783                                     xmlTextReaderConstLocalName(reader),
1784                                     xmlTextReaderConstNamespaceUri(reader));
1785                 if (ret < 0) {
1786                     fprintf(stderr, "xmlStreamPush() failure\n");
1787                     xmlFreeStreamCtxt(patstream);
1788                     patstream = NULL;
1789                 } else if (ret != match) {
1790 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
1791                     if (path == NULL) {
1792                         path = xmlGetNodePath(
1793                                        xmlTextReaderCurrentNode(reader));
1794                     }
1795 #endif
1796                     fprintf(stderr,
1797                             "xmlPatternMatch and xmlStreamPush disagree\n");
1798                     if (path != NULL)
1799                         fprintf(stderr, "  pattern %s node %s\n",
1800                                 pattern, path);
1801                     else
1802                         fprintf(stderr, "  pattern %s node %s\n",
1803                             pattern, xmlTextReaderConstName(reader));
1804                 }
1805
1806             }
1807             if ((type == XML_READER_TYPE_END_ELEMENT) ||
1808                 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1809                 ret = xmlStreamPop(patstream);
1810                 if (ret < 0) {
1811                     fprintf(stderr, "xmlStreamPop() failure\n");
1812                     xmlFreeStreamCtxt(patstream);
1813                     patstream = NULL;
1814                 }
1815             }
1816         }
1817         if (path != NULL)
1818             xmlFree(path);
1819     }
1820 #endif
1821 }
1822
1823 static void streamFile(char *filename) {
1824     xmlTextReaderPtr reader;
1825     int ret;
1826 #ifdef HAVE_SYS_MMAN_H
1827     int fd = -1;
1828     struct stat info;
1829     const char *base = NULL;
1830     xmlParserInputBufferPtr input = NULL;
1831
1832     if (memory) {
1833         if (stat(filename, &info) < 0)
1834             return;
1835         if ((fd = open(filename, O_RDONLY)) < 0)
1836             return;
1837         base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1838         if (base == (void *) MAP_FAILED)
1839             return;
1840
1841         reader = xmlReaderForMemory(base, info.st_size, filename,
1842                                     NULL, options);
1843     } else
1844 #endif
1845         reader = xmlReaderForFile(filename, NULL, options);
1846 #ifdef LIBXML_PATTERN_ENABLED
1847     if (pattern != NULL) {
1848         patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1849         if (patternc == NULL) {
1850             xmlGenericError(xmlGenericErrorContext,
1851                     "Pattern %s failed to compile\n", pattern);
1852             progresult = XMLLINT_ERR_SCHEMAPAT;
1853             pattern = NULL;
1854         }
1855     }
1856     if (patternc != NULL) {
1857         patstream = xmlPatternGetStreamCtxt(patternc);
1858         if (patstream != NULL) {
1859             ret = xmlStreamPush(patstream, NULL, NULL);
1860             if (ret < 0) {
1861                 fprintf(stderr, "xmlStreamPush() failure\n");
1862                 xmlFreeStreamCtxt(patstream);
1863                 patstream = NULL;
1864             }
1865         }
1866     }
1867 #endif
1868
1869
1870     if (reader != NULL) {
1871 #ifdef LIBXML_VALID_ENABLED
1872         if (valid)
1873             xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
1874         else
1875 #endif /* LIBXML_VALID_ENABLED */
1876             xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
1877 #ifdef LIBXML_SCHEMAS_ENABLED
1878         if (relaxng != NULL) {
1879             if ((timing) && (!repeat)) {
1880                 startTimer();
1881             }
1882             ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1883             if (ret < 0) {
1884                 xmlGenericError(xmlGenericErrorContext,
1885                         "Relax-NG schema %s failed to compile\n", relaxng);
1886                 progresult = XMLLINT_ERR_SCHEMACOMP;
1887                 relaxng = NULL;
1888             }
1889             if ((timing) && (!repeat)) {
1890                 endTimer("Compiling the schemas");
1891             }
1892         }
1893         if (schema != NULL) {
1894             if ((timing) && (!repeat)) {
1895                 startTimer();
1896             }
1897             ret = xmlTextReaderSchemaValidate(reader, schema);
1898             if (ret < 0) {
1899                 xmlGenericError(xmlGenericErrorContext,
1900                         "XSD schema %s failed to compile\n", schema);
1901                 progresult = XMLLINT_ERR_SCHEMACOMP;
1902                 schema = NULL;
1903             }
1904             if ((timing) && (!repeat)) {
1905                 endTimer("Compiling the schemas");
1906             }
1907         }
1908 #endif
1909
1910         /*
1911          * Process all nodes in sequence
1912          */
1913         if ((timing) && (!repeat)) {
1914             startTimer();
1915         }
1916         ret = xmlTextReaderRead(reader);
1917         while (ret == 1) {
1918             if ((debug)
1919 #ifdef LIBXML_PATTERN_ENABLED
1920                 || (patternc)
1921 #endif
1922                )
1923                 processNode(reader);
1924             ret = xmlTextReaderRead(reader);
1925         }
1926         if ((timing) && (!repeat)) {
1927 #ifdef LIBXML_SCHEMAS_ENABLED
1928             if (relaxng != NULL)
1929                 endTimer("Parsing and validating");
1930             else
1931 #endif
1932 #ifdef LIBXML_VALID_ENABLED
1933             if (valid)
1934                 endTimer("Parsing and validating");
1935             else
1936 #endif
1937             endTimer("Parsing");
1938         }
1939
1940 #ifdef LIBXML_VALID_ENABLED
1941         if (valid) {
1942             if (xmlTextReaderIsValid(reader) != 1) {
1943                 xmlGenericError(xmlGenericErrorContext,
1944                         "Document %s does not validate\n", filename);
1945                 progresult = XMLLINT_ERR_VALID;
1946             }
1947         }
1948 #endif /* LIBXML_VALID_ENABLED */
1949 #ifdef LIBXML_SCHEMAS_ENABLED
1950         if ((relaxng != NULL) || (schema != NULL)) {
1951             if (xmlTextReaderIsValid(reader) != 1) {
1952                 fprintf(stderr, "%s fails to validate\n", filename);
1953                 progresult = XMLLINT_ERR_VALID;
1954             } else {
1955                 fprintf(stderr, "%s validates\n", filename);
1956             }
1957         }
1958 #endif
1959         /*
1960          * Done, cleanup and status
1961          */
1962         xmlFreeTextReader(reader);
1963         if (ret != 0) {
1964             fprintf(stderr, "%s : failed to parse\n", filename);
1965             progresult = XMLLINT_ERR_UNCLASS;
1966         }
1967     } else {
1968         fprintf(stderr, "Unable to open %s\n", filename);
1969         progresult = XMLLINT_ERR_UNCLASS;
1970     }
1971 #ifdef LIBXML_PATTERN_ENABLED
1972     if (patstream != NULL) {
1973         xmlFreeStreamCtxt(patstream);
1974         patstream = NULL;
1975     }
1976 #endif
1977 #ifdef HAVE_SYS_MMAN_H
1978     if (memory) {
1979         xmlFreeParserInputBuffer(input);
1980         munmap((char *) base, info.st_size);
1981         close(fd);
1982     }
1983 #endif
1984 }
1985
1986 static void walkDoc(xmlDocPtr doc) {
1987     xmlTextReaderPtr reader;
1988     int ret;
1989
1990 #ifdef LIBXML_PATTERN_ENABLED
1991     xmlNodePtr root;
1992     const xmlChar *namespaces[22];
1993     int i;
1994     xmlNsPtr ns;
1995
1996     root = xmlDocGetRootElement(doc);
1997     for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1998         namespaces[i++] = ns->href;
1999         namespaces[i++] = ns->prefix;
2000     }
2001     namespaces[i++] = NULL;
2002     namespaces[i] = NULL;
2003
2004     if (pattern != NULL) {
2005         patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2006                                      0, &namespaces[0]);
2007         if (patternc == NULL) {
2008             xmlGenericError(xmlGenericErrorContext,
2009                     "Pattern %s failed to compile\n", pattern);
2010             progresult = XMLLINT_ERR_SCHEMAPAT;
2011             pattern = NULL;
2012         }
2013     }
2014     if (patternc != NULL) {
2015         patstream = xmlPatternGetStreamCtxt(patternc);
2016         if (patstream != NULL) {
2017             ret = xmlStreamPush(patstream, NULL, NULL);
2018             if (ret < 0) {
2019                 fprintf(stderr, "xmlStreamPush() failure\n");
2020                 xmlFreeStreamCtxt(patstream);
2021                 patstream = NULL;
2022             }
2023         }
2024     }
2025 #endif /* LIBXML_PATTERN_ENABLED */
2026     reader = xmlReaderWalker(doc);
2027     if (reader != NULL) {
2028         if ((timing) && (!repeat)) {
2029             startTimer();
2030         }
2031         ret = xmlTextReaderRead(reader);
2032         while (ret == 1) {
2033             if ((debug)
2034 #ifdef LIBXML_PATTERN_ENABLED
2035                 || (patternc)
2036 #endif
2037                )
2038                 processNode(reader);
2039             ret = xmlTextReaderRead(reader);
2040         }
2041         if ((timing) && (!repeat)) {
2042             endTimer("walking through the doc");
2043         }
2044         xmlFreeTextReader(reader);
2045         if (ret != 0) {
2046             fprintf(stderr, "failed to walk through the doc\n");
2047             progresult = XMLLINT_ERR_UNCLASS;
2048         }
2049     } else {
2050         fprintf(stderr, "Failed to crate a reader from the document\n");
2051         progresult = XMLLINT_ERR_UNCLASS;
2052     }
2053 #ifdef LIBXML_PATTERN_ENABLED
2054     if (patstream != NULL) {
2055         xmlFreeStreamCtxt(patstream);
2056         patstream = NULL;
2057     }
2058 #endif
2059 }
2060 #endif /* LIBXML_READER_ENABLED */
2061
2062 #ifdef LIBXML_XPATH_ENABLED
2063 /************************************************************************
2064  *                                                                      *
2065  *                      XPath Query                                     *
2066  *                                                                      *
2067  ************************************************************************/
2068
2069 static void doXPathDump(xmlXPathObjectPtr cur) {
2070     switch(cur->type) {
2071         case XPATH_NODESET: {
2072             int i;
2073             xmlNodePtr node;
2074 #ifdef LIBXML_OUTPUT_ENABLED
2075             xmlSaveCtxtPtr ctxt;
2076
2077             if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
2078                 fprintf(stderr, "XPath set is empty\n");
2079                 progresult = XMLLINT_ERR_XPATH;
2080                 break;
2081             }
2082             ctxt = xmlSaveToFd(1, NULL, 0);
2083             if (ctxt == NULL) {
2084                 fprintf(stderr, "Out of memory for XPath\n");
2085                 progresult = XMLLINT_ERR_MEM;
2086                 return;
2087             }
2088             for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2089                 node = cur->nodesetval->nodeTab[i];
2090                 xmlSaveTree(ctxt, node);
2091             }
2092             xmlSaveClose(ctxt);
2093 #else
2094             printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2095 #endif
2096             break;
2097         }
2098         case XPATH_BOOLEAN:
2099             if (cur->boolval) printf("true");
2100             else printf("false");
2101             break;
2102         case XPATH_NUMBER:
2103             switch (xmlXPathIsInf(cur->floatval)) {
2104             case 1:
2105                 printf("Infinity");
2106                 break;
2107             case -1:
2108                 printf("-Infinity");
2109                 break;
2110             default:
2111                 if (xmlXPathIsNaN(cur->floatval)) {
2112                     printf("NaN");
2113                 } else {
2114                     printf("%0g", cur->floatval);
2115                 }
2116             }
2117             break;
2118         case XPATH_STRING:
2119             printf("%s", (const char *) cur->stringval);
2120             break;
2121         case XPATH_UNDEFINED:
2122             fprintf(stderr, "XPath Object is uninitialized\n");
2123             progresult = XMLLINT_ERR_XPATH;
2124             break;
2125         default:
2126             fprintf(stderr, "XPath object of unexpected type\n");
2127             progresult = XMLLINT_ERR_XPATH;
2128             break;
2129     }
2130 }
2131
2132 static void doXPathQuery(xmlDocPtr doc, const char *query) {
2133     xmlXPathContextPtr ctxt;
2134     xmlXPathObjectPtr res;
2135
2136     ctxt = xmlXPathNewContext(doc);
2137     if (ctxt == NULL) {
2138         fprintf(stderr, "Out of memory for XPath\n");
2139         progresult = XMLLINT_ERR_MEM;
2140         return;
2141     }
2142     ctxt->node = xmlDocGetRootElement(doc);
2143     res = xmlXPathEval(BAD_CAST query, ctxt);
2144     xmlXPathFreeContext(ctxt);
2145
2146     if (res == NULL) {
2147         fprintf(stderr, "XPath evaluation failure\n");
2148         progresult = XMLLINT_ERR_XPATH;
2149         return;
2150     }
2151     doXPathDump(res);
2152     xmlXPathFreeObject(res);
2153 }
2154 #endif /* LIBXML_XPATH_ENABLED */
2155
2156 /************************************************************************
2157  *                                                                      *
2158  *                      Tree Test processing                            *
2159  *                                                                      *
2160  ************************************************************************/
2161 static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
2162     xmlDocPtr doc = NULL;
2163 #ifdef LIBXML_TREE_ENABLED
2164     xmlDocPtr tmp;
2165 #endif /* LIBXML_TREE_ENABLED */
2166
2167     if ((timing) && (!repeat))
2168         startTimer();
2169
2170
2171 #ifdef LIBXML_TREE_ENABLED
2172     if (filename == NULL) {
2173         if (generate) {
2174             xmlNodePtr n;
2175
2176             doc = xmlNewDoc(BAD_CAST "1.0");
2177             n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
2178             xmlNodeSetContent(n, BAD_CAST "abc");
2179             xmlDocSetRootElement(doc, n);
2180         }
2181     }
2182 #endif /* LIBXML_TREE_ENABLED */
2183 #ifdef LIBXML_HTML_ENABLED
2184 #ifdef LIBXML_PUSH_ENABLED
2185     else if ((html) && (push)) {
2186         FILE *f;
2187
2188 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2189         f = fopen(filename, "rb");
2190 #else
2191         f = fopen(filename, "r");
2192 #endif
2193         if (f != NULL) {
2194             int res, size = 3;
2195             char chars[4096];
2196             htmlParserCtxtPtr ctxt;
2197
2198             /* if (repeat) */
2199                 size = 4096;
2200             res = fread(chars, 1, 4, f);
2201             if (res > 0) {
2202                 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
2203                             chars, res, filename, XML_CHAR_ENCODING_NONE);
2204                 while ((res = fread(chars, 1, size, f)) > 0) {
2205                     htmlParseChunk(ctxt, chars, res, 0);
2206                 }
2207                 htmlParseChunk(ctxt, chars, 0, 1);
2208                 doc = ctxt->myDoc;
2209                 htmlFreeParserCtxt(ctxt);
2210             }
2211             fclose(f);
2212         }
2213     }
2214 #endif /* LIBXML_PUSH_ENABLED */
2215 #ifdef HAVE_SYS_MMAN_H
2216     else if ((html) && (memory)) {
2217         int fd;
2218         struct stat info;
2219         const char *base;
2220         if (stat(filename, &info) < 0)
2221             return;
2222         if ((fd = open(filename, O_RDONLY)) < 0)
2223             return;
2224         base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2225         if (base == (void *) MAP_FAILED)
2226             return;
2227
2228         doc = htmlReadMemory((char *) base, info.st_size, filename,
2229                              NULL, options);
2230
2231         munmap((char *) base, info.st_size);
2232         close(fd);
2233     }
2234 #endif
2235     else if (html) {
2236         doc = htmlReadFile(filename, NULL, options);
2237     }
2238 #endif /* LIBXML_HTML_ENABLED */
2239     else {
2240 #ifdef LIBXML_PUSH_ENABLED
2241         /*
2242          * build an XML tree from a string;
2243          */
2244         if (push) {
2245             FILE *f;
2246
2247             /* '-' Usually means stdin -<sven@zen.org> */
2248             if ((filename[0] == '-') && (filename[1] == 0)) {
2249               f = stdin;
2250             } else {
2251 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2252                 f = fopen(filename, "rb");
2253 #else
2254                 f = fopen(filename, "r");
2255 #endif
2256             }
2257             if (f != NULL) {
2258                 int ret;
2259                 int res, size = 1024;
2260                 char chars[1024];
2261                 xmlParserCtxtPtr ctxt;
2262
2263                 /* if (repeat) size = 1024; */
2264                 res = fread(chars, 1, 4, f);
2265                 if (res > 0) {
2266                     ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2267                                 chars, res, filename);
2268                     xmlCtxtUseOptions(ctxt, options);
2269                     while ((res = fread(chars, 1, size, f)) > 0) {
2270                         xmlParseChunk(ctxt, chars, res, 0);
2271                     }
2272                     xmlParseChunk(ctxt, chars, 0, 1);
2273                     doc = ctxt->myDoc;
2274                     ret = ctxt->wellFormed;
2275                     xmlFreeParserCtxt(ctxt);
2276                     if (!ret) {
2277                         xmlFreeDoc(doc);
2278                         doc = NULL;
2279                     }
2280                 }
2281                 if (f != stdin)
2282                     fclose(f);
2283             }
2284         } else
2285 #endif /* LIBXML_PUSH_ENABLED */
2286         if (testIO) {
2287             if ((filename[0] == '-') && (filename[1] == 0)) {
2288                 doc = xmlReadFd(0, NULL, NULL, options);
2289             } else {
2290                 FILE *f;
2291
2292 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2293                 f = fopen(filename, "rb");
2294 #else
2295                 f = fopen(filename, "r");
2296 #endif
2297                 if (f != NULL) {
2298                     if (rectxt == NULL)
2299                         doc = xmlReadIO((xmlInputReadCallback) myRead,
2300                                         (xmlInputCloseCallback) myClose, f,
2301                                         filename, NULL, options);
2302                     else
2303                         doc = xmlCtxtReadIO(rectxt,
2304                                         (xmlInputReadCallback) myRead,
2305                                         (xmlInputCloseCallback) myClose, f,
2306                                         filename, NULL, options);
2307                 } else
2308                     doc = NULL;
2309             }
2310         } else if (htmlout) {
2311             xmlParserCtxtPtr ctxt;
2312
2313             if (rectxt == NULL)
2314                 ctxt = xmlNewParserCtxt();
2315             else
2316                 ctxt = rectxt;
2317             if (ctxt == NULL) {
2318                 doc = NULL;
2319             } else {
2320                 ctxt->sax->error = xmlHTMLError;
2321                 ctxt->sax->warning = xmlHTMLWarning;
2322                 ctxt->vctxt.error = xmlHTMLValidityError;
2323                 ctxt->vctxt.warning = xmlHTMLValidityWarning;
2324
2325                 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2326
2327                 if (rectxt == NULL)
2328                     xmlFreeParserCtxt(ctxt);
2329             }
2330 #ifdef HAVE_SYS_MMAN_H
2331         } else if (memory) {
2332             int fd;
2333             struct stat info;
2334             const char *base;
2335             if (stat(filename, &info) < 0)
2336                 return;
2337             if ((fd = open(filename, O_RDONLY)) < 0)
2338                 return;
2339             base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2340             if (base == (void *) MAP_FAILED)
2341                 return;
2342
2343             if (rectxt == NULL)
2344                 doc = xmlReadMemory((char *) base, info.st_size,
2345                                     filename, NULL, options);
2346             else
2347                 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2348                                         filename, NULL, options);
2349
2350             munmap((char *) base, info.st_size);
2351             close(fd);
2352 #endif
2353 #ifdef LIBXML_VALID_ENABLED
2354         } else if (valid) {
2355             xmlParserCtxtPtr ctxt = NULL;
2356
2357             if (rectxt == NULL)
2358                 ctxt = xmlNewParserCtxt();
2359             else
2360                 ctxt = rectxt;
2361             if (ctxt == NULL) {
2362                 doc = NULL;
2363             } else {
2364                 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2365
2366                 if (ctxt->valid == 0)
2367                     progresult = XMLLINT_ERR_RDFILE;
2368                 if (rectxt == NULL)
2369                     xmlFreeParserCtxt(ctxt);
2370             }
2371 #endif /* LIBXML_VALID_ENABLED */
2372         } else {
2373             if (rectxt != NULL)
2374                 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
2375             else {
2376 #ifdef LIBXML_SAX1_ENABLED
2377                 if (sax1)
2378                     doc = xmlParseFile(filename);
2379                 else
2380 #endif /* LIBXML_SAX1_ENABLED */
2381                 doc = xmlReadFile(filename, NULL, options);
2382             }
2383         }
2384     }
2385
2386     /*
2387      * If we don't have a document we might as well give up.  Do we
2388      * want an error message here?  <sven@zen.org> */
2389     if (doc == NULL) {
2390         progresult = XMLLINT_ERR_UNCLASS;
2391         return;
2392     }
2393
2394     if ((timing) && (!repeat)) {
2395         endTimer("Parsing");
2396     }
2397
2398     /*
2399      * Remove DOCTYPE nodes
2400      */
2401     if (dropdtd) {
2402         xmlDtdPtr dtd;
2403
2404         dtd = xmlGetIntSubset(doc);
2405         if (dtd != NULL) {
2406             xmlUnlinkNode((xmlNodePtr)dtd);
2407             xmlFreeDtd(dtd);
2408         }
2409     }
2410
2411 #ifdef LIBXML_XINCLUDE_ENABLED
2412     if (xinclude) {
2413         if ((timing) && (!repeat)) {
2414             startTimer();
2415         }
2416         if (xmlXIncludeProcessFlags(doc, options) < 0)
2417             progresult = XMLLINT_ERR_UNCLASS;
2418         if ((timing) && (!repeat)) {
2419             endTimer("Xinclude processing");
2420         }
2421     }
2422 #endif
2423
2424 #ifdef LIBXML_XPATH_ENABLED
2425     if (xpathquery != NULL) {
2426         doXPathQuery(doc, xpathquery);
2427     }
2428 #endif
2429
2430 #ifdef LIBXML_DEBUG_ENABLED
2431 #ifdef LIBXML_XPATH_ENABLED
2432     /*
2433      * shell interaction
2434      */
2435     if (shell) {
2436         xmlXPathOrderDocElems(doc);
2437         xmlShell(doc, filename, xmlShellReadline, stdout);
2438     }
2439 #endif
2440 #endif
2441
2442 #ifdef LIBXML_TREE_ENABLED
2443     /*
2444      * test intermediate copy if needed.
2445      */
2446     if (copy) {
2447         tmp = doc;
2448         if (timing) {
2449             startTimer();
2450         }
2451         doc = xmlCopyDoc(doc, 1);
2452         if (timing) {
2453             endTimer("Copying");
2454         }
2455         if (timing) {
2456             startTimer();
2457         }
2458         xmlFreeDoc(tmp);
2459         if (timing) {
2460             endTimer("Freeing original");
2461         }
2462     }
2463 #endif /* LIBXML_TREE_ENABLED */
2464
2465 #ifdef LIBXML_VALID_ENABLED
2466     if ((insert) && (!html)) {
2467         const xmlChar* list[256];
2468         int nb, i;
2469         xmlNodePtr node;
2470
2471         if (doc->children != NULL) {
2472             node = doc->children;
2473             while ((node != NULL) && (node->last == NULL)) node = node->next;
2474             if (node != NULL) {
2475                 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2476                 if (nb < 0) {
2477                     fprintf(stderr, "could not get valid list of elements\n");
2478                 } else if (nb == 0) {
2479                     fprintf(stderr, "No element can be inserted under root\n");
2480                 } else {
2481                     fprintf(stderr, "%d element types can be inserted under root:\n",
2482                            nb);
2483                     for (i = 0;i < nb;i++) {
2484                          fprintf(stderr, "%s\n", (char *) list[i]);
2485                     }
2486                 }
2487             }
2488         }
2489     }else
2490 #endif /* LIBXML_VALID_ENABLED */
2491 #ifdef LIBXML_READER_ENABLED
2492     if (walker) {
2493         walkDoc(doc);
2494     }
2495 #endif /* LIBXML_READER_ENABLED */
2496 #ifdef LIBXML_OUTPUT_ENABLED
2497     if (noout == 0) {
2498         int ret;
2499
2500         /*
2501          * print it.
2502          */
2503 #ifdef LIBXML_DEBUG_ENABLED
2504         if (!debug) {
2505 #endif
2506             if ((timing) && (!repeat)) {
2507                 startTimer();
2508             }
2509 #ifdef LIBXML_HTML_ENABLED
2510             if ((html) && (!xmlout)) {
2511                 if (compress) {
2512                     htmlSaveFile(output ? output : "-", doc);
2513                 }
2514                 else if (encoding != NULL) {
2515                     if (format == 1) {
2516                         htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2517                     }
2518                     else {
2519                         htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2520                     }
2521                 }
2522                 else if (format == 1) {
2523                     htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2524                 }
2525                 else {
2526                     FILE *out;
2527                     if (output == NULL)
2528                         out = stdout;
2529                     else {
2530                         out = fopen(output,"wb");
2531                     }
2532                     if (out != NULL) {
2533                         if (htmlDocDump(out, doc) < 0)
2534                             progresult = XMLLINT_ERR_OUT;
2535
2536                         if (output != NULL)
2537                             fclose(out);
2538                     } else {
2539                         fprintf(stderr, "failed to open %s\n", output);
2540                         progresult = XMLLINT_ERR_OUT;
2541                     }
2542                 }
2543                 if ((timing) && (!repeat)) {
2544                     endTimer("Saving");
2545                 }
2546             } else
2547 #endif
2548 #ifdef LIBXML_C14N_ENABLED
2549             if (canonical) {
2550                 xmlChar *result = NULL;
2551                 int size;
2552
2553                 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2554                 if (size >= 0) {
2555                     if (write(1, result, size) == -1) {
2556                         fprintf(stderr, "Can't write data\n");
2557                     }
2558                     xmlFree(result);
2559                 } else {
2560                     fprintf(stderr, "Failed to canonicalize\n");
2561                     progresult = XMLLINT_ERR_OUT;
2562                 }
2563             } else if (canonical) {
2564                 xmlChar *result = NULL;
2565                 int size;
2566
2567                 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
2568                 if (size >= 0) {
2569                     if (write(1, result, size) == -1) {
2570                         fprintf(stderr, "Can't write data\n");
2571                     }
2572                     xmlFree(result);
2573                 } else {
2574                     fprintf(stderr, "Failed to canonicalize\n");
2575                     progresult = XMLLINT_ERR_OUT;
2576                 }
2577             } else
2578             if (exc_canonical) {
2579                 xmlChar *result = NULL;
2580                 int size;
2581
2582                 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
2583                 if (size >= 0) {
2584                     if (write(1, result, size) == -1) {
2585                         fprintf(stderr, "Can't write data\n");
2586                     }
2587                     xmlFree(result);
2588                 } else {
2589                     fprintf(stderr, "Failed to canonicalize\n");
2590                     progresult = XMLLINT_ERR_OUT;
2591                 }
2592             } else
2593 #endif
2594 #ifdef HAVE_SYS_MMAN_H
2595             if (memory) {
2596                 xmlChar *result;
2597                 int len;
2598
2599                 if (encoding != NULL) {
2600                     if (format == 1) {
2601                         xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
2602                     } else {
2603                         xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2604                     }
2605                 } else {
2606                     if (format == 1)
2607                         xmlDocDumpFormatMemory(doc, &result, &len, 1);
2608                     else
2609                         xmlDocDumpMemory(doc, &result, &len);
2610                 }
2611                 if (result == NULL) {
2612                     fprintf(stderr, "Failed to save\n");
2613                     progresult = XMLLINT_ERR_OUT;
2614                 } else {
2615                     if (write(1, result, len) == -1) {
2616                         fprintf(stderr, "Can't write data\n");
2617                     }
2618                     xmlFree(result);
2619                 }
2620
2621             } else
2622 #endif /* HAVE_SYS_MMAN_H */
2623             if (compress) {
2624                 xmlSaveFile(output ? output : "-", doc);
2625             } else if (oldout) {
2626                 if (encoding != NULL) {
2627                     if (format == 1) {
2628                         ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2629                                                    encoding, 1);
2630                     }
2631                     else {
2632                         ret = xmlSaveFileEnc(output ? output : "-", doc,
2633                                              encoding);
2634                     }
2635                     if (ret < 0) {
2636                         fprintf(stderr, "failed save to %s\n",
2637                                 output ? output : "-");
2638                         progresult = XMLLINT_ERR_OUT;
2639                     }
2640                 } else if (format == 1) {
2641                     ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2642                     if (ret < 0) {
2643                         fprintf(stderr, "failed save to %s\n",
2644                                 output ? output : "-");
2645                         progresult = XMLLINT_ERR_OUT;
2646                     }
2647                 } else {
2648                     FILE *out;
2649                     if (output == NULL)
2650                         out = stdout;
2651                     else {
2652                         out = fopen(output,"wb");
2653                     }
2654                     if (out != NULL) {
2655                         if (xmlDocDump(out, doc) < 0)
2656                             progresult = XMLLINT_ERR_OUT;
2657
2658                         if (output != NULL)
2659                             fclose(out);
2660                     } else {
2661                         fprintf(stderr, "failed to open %s\n", output);
2662                         progresult = XMLLINT_ERR_OUT;
2663                     }
2664                 }
2665             } else {
2666                 xmlSaveCtxtPtr ctxt;
2667                 int saveOpts = 0;
2668
2669                 if (format == 1)
2670                     saveOpts |= XML_SAVE_FORMAT;
2671                 else if (format == 2)
2672                     saveOpts |= XML_SAVE_WSNONSIG;
2673
2674 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
2675                 if (xmlout)
2676                     saveOpts |= XML_SAVE_AS_XML;
2677 #endif
2678
2679                 if (output == NULL)
2680                     ctxt = xmlSaveToFd(1, encoding, saveOpts);
2681                 else
2682                     ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2683
2684                 if (ctxt != NULL) {
2685                     if (xmlSaveDoc(ctxt, doc) < 0) {
2686                         fprintf(stderr, "failed save to %s\n",
2687                                 output ? output : "-");
2688                         progresult = XMLLINT_ERR_OUT;
2689                     }
2690                     xmlSaveClose(ctxt);
2691                 } else {
2692                     progresult = XMLLINT_ERR_OUT;
2693                 }
2694             }
2695             if ((timing) && (!repeat)) {
2696                 endTimer("Saving");
2697             }
2698 #ifdef LIBXML_DEBUG_ENABLED
2699         } else {
2700             FILE *out;
2701             if (output == NULL)
2702                 out = stdout;
2703             else {
2704                 out = fopen(output,"wb");
2705             }
2706             if (out != NULL) {
2707                 xmlDebugDumpDocument(out, doc);
2708
2709                 if (output != NULL)
2710                     fclose(out);
2711             } else {
2712                 fprintf(stderr, "failed to open %s\n", output);
2713                 progresult = XMLLINT_ERR_OUT;
2714             }
2715         }
2716 #endif
2717     }
2718 #endif /* LIBXML_OUTPUT_ENABLED */
2719
2720 #ifdef LIBXML_VALID_ENABLED
2721     /*
2722      * A posteriori validation test
2723      */
2724     if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
2725         xmlDtdPtr dtd;
2726
2727         if ((timing) && (!repeat)) {
2728             startTimer();
2729         }
2730         if (dtdvalid != NULL)
2731             dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
2732         else
2733             dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
2734         if ((timing) && (!repeat)) {
2735             endTimer("Parsing DTD");
2736         }
2737         if (dtd == NULL) {
2738             if (dtdvalid != NULL)
2739                 xmlGenericError(xmlGenericErrorContext,
2740                         "Could not parse DTD %s\n", dtdvalid);
2741             else
2742                 xmlGenericError(xmlGenericErrorContext,
2743                         "Could not parse DTD %s\n", dtdvalidfpi);
2744             progresult = XMLLINT_ERR_DTD;
2745         } else {
2746             xmlValidCtxtPtr cvp;
2747
2748             if ((cvp = xmlNewValidCtxt()) == NULL) {
2749                 xmlGenericError(xmlGenericErrorContext,
2750                         "Couldn't allocate validation context\n");
2751                 exit(-1);
2752             }
2753             cvp->userData = (void *) stderr;
2754             cvp->error    = (xmlValidityErrorFunc) fprintf;
2755             cvp->warning  = (xmlValidityWarningFunc) fprintf;
2756
2757             if ((timing) && (!repeat)) {
2758                 startTimer();
2759             }
2760             if (!xmlValidateDtd(cvp, doc, dtd)) {
2761                 if (dtdvalid != NULL)
2762                     xmlGenericError(xmlGenericErrorContext,
2763                             "Document %s does not validate against %s\n",
2764                             filename, dtdvalid);
2765                 else
2766                     xmlGenericError(xmlGenericErrorContext,
2767                             "Document %s does not validate against %s\n",
2768                             filename, dtdvalidfpi);
2769                 progresult = XMLLINT_ERR_VALID;
2770             }
2771             if ((timing) && (!repeat)) {
2772                 endTimer("Validating against DTD");
2773             }
2774             xmlFreeValidCtxt(cvp);
2775             xmlFreeDtd(dtd);
2776         }
2777     } else if (postvalid) {
2778         xmlValidCtxtPtr cvp;
2779
2780         if ((cvp = xmlNewValidCtxt()) == NULL) {
2781             xmlGenericError(xmlGenericErrorContext,
2782                     "Couldn't allocate validation context\n");
2783             exit(-1);
2784         }
2785
2786         if ((timing) && (!repeat)) {
2787             startTimer();
2788         }
2789         cvp->userData = (void *) stderr;
2790         cvp->error    = (xmlValidityErrorFunc) fprintf;
2791         cvp->warning  = (xmlValidityWarningFunc) fprintf;
2792         if (!xmlValidateDocument(cvp, doc)) {
2793             xmlGenericError(xmlGenericErrorContext,
2794                     "Document %s does not validate\n", filename);
2795             progresult = XMLLINT_ERR_VALID;
2796         }
2797         if ((timing) && (!repeat)) {
2798             endTimer("Validating");
2799         }
2800         xmlFreeValidCtxt(cvp);
2801     }
2802 #endif /* LIBXML_VALID_ENABLED */
2803 #ifdef LIBXML_SCHEMATRON_ENABLED
2804     if (wxschematron != NULL) {
2805         xmlSchematronValidCtxtPtr ctxt;
2806         int ret;
2807         int flag;
2808
2809         if ((timing) && (!repeat)) {
2810             startTimer();
2811         }
2812
2813         if (debug)
2814             flag = XML_SCHEMATRON_OUT_XML;
2815         else
2816             flag = XML_SCHEMATRON_OUT_TEXT;
2817         if (noout)
2818             flag |= XML_SCHEMATRON_OUT_QUIET;
2819         ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2820 #if 0
2821         xmlSchematronSetValidErrors(ctxt,
2822                 (xmlSchematronValidityErrorFunc) fprintf,
2823                 (xmlSchematronValidityWarningFunc) fprintf,
2824                 stderr);
2825 #endif
2826         ret = xmlSchematronValidateDoc(ctxt, doc);
2827         if (ret == 0) {
2828             fprintf(stderr, "%s validates\n", filename);
2829         } else if (ret > 0) {
2830             fprintf(stderr, "%s fails to validate\n", filename);
2831             progresult = XMLLINT_ERR_VALID;
2832         } else {
2833             fprintf(stderr, "%s validation generated an internal error\n",
2834                    filename);
2835             progresult = XMLLINT_ERR_VALID;
2836         }
2837         xmlSchematronFreeValidCtxt(ctxt);
2838         if ((timing) && (!repeat)) {
2839             endTimer("Validating");
2840         }
2841     }
2842 #endif
2843 #ifdef LIBXML_SCHEMAS_ENABLED
2844     if (relaxngschemas != NULL) {
2845         xmlRelaxNGValidCtxtPtr ctxt;
2846         int ret;
2847
2848         if ((timing) && (!repeat)) {
2849             startTimer();
2850         }
2851
2852         ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2853         xmlRelaxNGSetValidErrors(ctxt,
2854                 (xmlRelaxNGValidityErrorFunc) fprintf,
2855                 (xmlRelaxNGValidityWarningFunc) fprintf,
2856                 stderr);
2857         ret = xmlRelaxNGValidateDoc(ctxt, doc);
2858         if (ret == 0) {
2859             fprintf(stderr, "%s validates\n", filename);
2860         } else if (ret > 0) {
2861             fprintf(stderr, "%s fails to validate\n", filename);
2862             progresult = XMLLINT_ERR_VALID;
2863         } else {
2864             fprintf(stderr, "%s validation generated an internal error\n",
2865                    filename);
2866             progresult = XMLLINT_ERR_VALID;
2867         }
2868         xmlRelaxNGFreeValidCtxt(ctxt);
2869         if ((timing) && (!repeat)) {
2870             endTimer("Validating");
2871         }
2872     } else if (wxschemas != NULL) {
2873         xmlSchemaValidCtxtPtr ctxt;
2874         int ret;
2875
2876         if ((timing) && (!repeat)) {
2877             startTimer();
2878         }
2879
2880         ctxt = xmlSchemaNewValidCtxt(wxschemas);
2881         xmlSchemaSetValidErrors(ctxt,
2882                 (xmlSchemaValidityErrorFunc) fprintf,
2883                 (xmlSchemaValidityWarningFunc) fprintf,
2884                 stderr);
2885         ret = xmlSchemaValidateDoc(ctxt, doc);
2886         if (ret == 0) {
2887             fprintf(stderr, "%s validates\n", filename);
2888         } else if (ret > 0) {
2889             fprintf(stderr, "%s fails to validate\n", filename);
2890             progresult = XMLLINT_ERR_VALID;
2891         } else {
2892             fprintf(stderr, "%s validation generated an internal error\n",
2893                    filename);
2894             progresult = XMLLINT_ERR_VALID;
2895         }
2896         xmlSchemaFreeValidCtxt(ctxt);
2897         if ((timing) && (!repeat)) {
2898             endTimer("Validating");
2899         }
2900     }
2901 #endif
2902
2903 #ifdef LIBXML_DEBUG_ENABLED
2904 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
2905     if ((debugent) && (!html))
2906         xmlDebugDumpEntities(stderr, doc);
2907 #endif
2908 #endif
2909
2910     /*
2911      * free it.
2912      */
2913     if ((timing) && (!repeat)) {
2914         startTimer();
2915     }
2916     xmlFreeDoc(doc);
2917     if ((timing) && (!repeat)) {
2918         endTimer("Freeing");
2919     }
2920 }
2921
2922 /************************************************************************
2923  *                                                                      *
2924  *                      Usage and Main                                  *
2925  *                                                                      *
2926  ************************************************************************/
2927
2928 static void showVersion(const char *name) {
2929     fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2930     fprintf(stderr, "   compiled with: ");
2931     if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2932     if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2933     if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2934     if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2935     if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2936     if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2937     if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2938     if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
2939     if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2940     if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
2941     if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
2942     if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2943     if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2944     if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2945     if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2946     if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2947     if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2948     if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2949     if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2950     if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2951     if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2952     if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2953     if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2954     if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2955     if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2956     if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2957     if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2958     if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2959     if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2960     if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
2961     if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
2962     if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
2963     fprintf(stderr, "\n");
2964 }
2965
2966 static void usage(const char *name) {
2967     printf("Usage : %s [options] XMLfiles ...\n", name);
2968 #ifdef LIBXML_OUTPUT_ENABLED
2969     printf("\tParse the XML files and output the result of the parsing\n");
2970 #else
2971     printf("\tParse the XML files\n");
2972 #endif /* LIBXML_OUTPUT_ENABLED */
2973     printf("\t--version : display the version of the XML library used\n");
2974 #ifdef LIBXML_DEBUG_ENABLED
2975     printf("\t--debug : dump a debug tree of the in-memory document\n");
2976     printf("\t--shell : run a navigating shell\n");
2977     printf("\t--debugent : debug the entities defined in the document\n");
2978 #else
2979 #ifdef LIBXML_READER_ENABLED
2980     printf("\t--debug : dump the nodes content when using --stream\n");
2981 #endif /* LIBXML_READER_ENABLED */
2982 #endif
2983 #ifdef LIBXML_TREE_ENABLED
2984     printf("\t--copy : used to test the internal copy implementation\n");
2985 #endif /* LIBXML_TREE_ENABLED */
2986     printf("\t--recover : output what was parsable on broken XML documents\n");
2987     printf("\t--huge : remove any internal arbitrary parser limits\n");
2988     printf("\t--noent : substitute entity references by their value\n");
2989     printf("\t--noenc : ignore any encoding specified inside the document\n");
2990     printf("\t--noout : don't output the result tree\n");
2991     printf("\t--path 'paths': provide a set of paths for resources\n");
2992     printf("\t--load-trace : print trace of all external entites loaded\n");
2993     printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
2994     printf("\t--nocompact : do not generate compact text nodes\n");
2995     printf("\t--htmlout : output results as HTML\n");
2996     printf("\t--nowrap : do not put HTML doc wrapper\n");
2997 #ifdef LIBXML_VALID_ENABLED
2998     printf("\t--valid : validate the document in addition to std well-formed check\n");
2999     printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
3000     printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
3001     printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
3002 #endif /* LIBXML_VALID_ENABLED */
3003     printf("\t--timing : print some timings\n");
3004     printf("\t--output file or -o file: save to a given file\n");
3005     printf("\t--repeat : repeat 100 times, for timing or profiling\n");
3006     printf("\t--insert : ad-hoc test for valid insertions\n");
3007 #ifdef LIBXML_OUTPUT_ENABLED
3008 #ifdef HAVE_ZLIB_H
3009     printf("\t--compress : turn on gzip compression of output\n");
3010 #endif
3011 #endif /* LIBXML_OUTPUT_ENABLED */
3012 #ifdef LIBXML_HTML_ENABLED
3013     printf("\t--html : use the HTML parser\n");
3014     printf("\t--xmlout : force to use the XML serializer when using --html\n");
3015     printf("\t--nodefdtd : do not default HTML doctype\n");
3016 #endif
3017 #ifdef LIBXML_PUSH_ENABLED
3018     printf("\t--push : use the push mode of the parser\n");
3019 #endif /* LIBXML_PUSH_ENABLED */
3020 #ifdef HAVE_SYS_MMAN_H
3021     printf("\t--memory : parse from memory\n");
3022 #endif
3023     printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
3024     printf("\t--nowarning : do not emit warnings from parser/validator\n");
3025     printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
3026     printf("\t--nocdata : replace cdata section with text nodes\n");
3027 #ifdef LIBXML_OUTPUT_ENABLED
3028     printf("\t--format : reformat/reindent the input\n");
3029     printf("\t--encode encoding : output in the given encoding\n");
3030     printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
3031     printf("\t--pretty STYLE : pretty-print in a particular style\n");
3032     printf("\t                 0 Do not pretty print\n");
3033     printf("\t                 1 Format the XML content, as --format\n");
3034     printf("\t                 2 Add whitespace inside tags, preserving content\n");
3035 #endif /* LIBXML_OUTPUT_ENABLED */
3036     printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3037     printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
3038     printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
3039 #ifdef LIBXML_C14N_ENABLED
3040 #endif /* LIBXML_C14N_ENABLED */
3041     printf("\t--nsclean : remove redundant namespace declarations\n");
3042     printf("\t--testIO : test user I/O support\n");
3043 #ifdef LIBXML_CATALOG_ENABLED
3044     printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3045     printf("\t             otherwise XML Catalogs starting from \n");
3046     printf("\t         %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
3047     printf("\t--nocatalogs: deactivate all catalogs\n");
3048 #endif
3049     printf("\t--auto : generate a small doc on the fly\n");
3050 #ifdef LIBXML_XINCLUDE_ENABLED
3051     printf("\t--xinclude : do XInclude processing\n");
3052     printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
3053     printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
3054 #endif
3055     printf("\t--loaddtd : fetch external DTD\n");
3056     printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
3057 #ifdef LIBXML_READER_ENABLED
3058     printf("\t--stream : use the streaming interface to process very large files\n");
3059     printf("\t--walker : create a reader and walk though the resulting doc\n");
3060 #endif /* LIBXML_READER_ENABLED */
3061 #ifdef LIBXML_PATTERN_ENABLED
3062     printf("\t--pattern pattern_value : test the pattern support\n");
3063 #endif
3064     printf("\t--chkregister : verify the node registration code\n");
3065 #ifdef LIBXML_SCHEMAS_ENABLED
3066     printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
3067     printf("\t--schema schema : do validation against the WXS schema\n");
3068 #endif
3069 #ifdef LIBXML_SCHEMATRON_ENABLED
3070     printf("\t--schematron schema : do validation against a schematron\n");
3071 #endif
3072 #ifdef LIBXML_SAX1_ENABLED
3073     printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3074 #endif
3075     printf("\t--sax: do not build a tree but work just at the SAX level\n");
3076     printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
3077 #ifdef LIBXML_XPATH_ENABLED
3078     printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
3079 #endif
3080
3081     printf("\nLibxml project home page: http://xmlsoft.org/\n");
3082     printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
3083 }
3084
3085 static void registerNode(xmlNodePtr node)
3086 {
3087     node->_private = malloc(sizeof(long));
3088     *(long*)node->_private = (long) 0x81726354;
3089     nbregister++;
3090 }
3091
3092 static void deregisterNode(xmlNodePtr node)
3093 {
3094     assert(node->_private != NULL);
3095     assert(*(long*)node->_private == (long) 0x81726354);
3096     free(node->_private);
3097     nbregister--;
3098 }
3099
3100 int
3101 main(int argc, char **argv) {
3102     int i, acount;
3103     int files = 0;
3104     int version = 0;
3105     const char* indent;
3106
3107     if (argc <= 1) {
3108         usage(argv[0]);
3109         return(1);
3110     }
3111     LIBXML_TEST_VERSION
3112     for (i = 1; i < argc ; i++) {
3113         if (!strcmp(argv[i], "-"))
3114             break;
3115
3116         if (argv[i][0] != '-')
3117             continue;
3118         if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3119             debug++;
3120         else
3121 #ifdef LIBXML_DEBUG_ENABLED
3122         if ((!strcmp(argv[i], "-shell")) ||
3123                  (!strcmp(argv[i], "--shell"))) {
3124             shell++;
3125             noout = 1;
3126         } else
3127 #endif
3128 #ifdef LIBXML_TREE_ENABLED
3129         if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3130             copy++;
3131         else
3132 #endif /* LIBXML_TREE_ENABLED */
3133         if ((!strcmp(argv[i], "-recover")) ||
3134                  (!strcmp(argv[i], "--recover"))) {
3135             recovery++;
3136             options |= XML_PARSE_RECOVER;
3137         } else if ((!strcmp(argv[i], "-huge")) ||
3138                  (!strcmp(argv[i], "--huge"))) {
3139             options |= XML_PARSE_HUGE;
3140         } else if ((!strcmp(argv[i], "-noent")) ||
3141                  (!strcmp(argv[i], "--noent"))) {
3142             noent++;
3143             options |= XML_PARSE_NOENT;
3144         } else if ((!strcmp(argv[i], "-noenc")) ||
3145                  (!strcmp(argv[i], "--noenc"))) {
3146             noenc++;
3147             options |= XML_PARSE_IGNORE_ENC;
3148         } else if ((!strcmp(argv[i], "-nsclean")) ||
3149                  (!strcmp(argv[i], "--nsclean"))) {
3150             options |= XML_PARSE_NSCLEAN;
3151         } else if ((!strcmp(argv[i], "-nocdata")) ||
3152                  (!strcmp(argv[i], "--nocdata"))) {
3153             options |= XML_PARSE_NOCDATA;
3154         } else if ((!strcmp(argv[i], "-nodict")) ||
3155                  (!strcmp(argv[i], "--nodict"))) {
3156             options |= XML_PARSE_NODICT;
3157         } else if ((!strcmp(argv[i], "-version")) ||
3158                  (!strcmp(argv[i], "--version"))) {
3159             showVersion(argv[0]);
3160             version = 1;
3161         } else if ((!strcmp(argv[i], "-noout")) ||
3162                  (!strcmp(argv[i], "--noout")))
3163             noout++;
3164 #ifdef LIBXML_OUTPUT_ENABLED
3165         else if ((!strcmp(argv[i], "-o")) ||
3166                  (!strcmp(argv[i], "-output")) ||
3167                  (!strcmp(argv[i], "--output"))) {
3168             i++;
3169             output = argv[i];
3170         }
3171 #endif /* LIBXML_OUTPUT_ENABLED */
3172         else if ((!strcmp(argv[i], "-htmlout")) ||
3173                  (!strcmp(argv[i], "--htmlout")))
3174             htmlout++;
3175         else if ((!strcmp(argv[i], "-nowrap")) ||
3176                  (!strcmp(argv[i], "--nowrap")))
3177             nowrap++;
3178 #ifdef LIBXML_HTML_ENABLED
3179         else if ((!strcmp(argv[i], "-html")) ||
3180                  (!strcmp(argv[i], "--html"))) {
3181             html++;
3182         }
3183         else if ((!strcmp(argv[i], "-xmlout")) ||
3184                  (!strcmp(argv[i], "--xmlout"))) {
3185             xmlout++;
3186         } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3187                  (!strcmp(argv[i], "--nodefdtd"))) {
3188             nodefdtd++;
3189             options |= HTML_PARSE_NODEFDTD;
3190         }
3191 #endif /* LIBXML_HTML_ENABLED */
3192         else if ((!strcmp(argv[i], "-loaddtd")) ||
3193                  (!strcmp(argv[i], "--loaddtd"))) {
3194             loaddtd++;
3195             options |= XML_PARSE_DTDLOAD;
3196         } else if ((!strcmp(argv[i], "-dtdattr")) ||
3197                  (!strcmp(argv[i], "--dtdattr"))) {
3198             loaddtd++;
3199             dtdattrs++;
3200             options |= XML_PARSE_DTDATTR;
3201         }
3202 #ifdef LIBXML_VALID_ENABLED
3203         else if ((!strcmp(argv[i], "-valid")) ||
3204                  (!strcmp(argv[i], "--valid"))) {
3205             valid++;
3206             options |= XML_PARSE_DTDVALID;
3207         } else if ((!strcmp(argv[i], "-postvalid")) ||
3208                  (!strcmp(argv[i], "--postvalid"))) {
3209             postvalid++;
3210             loaddtd++;
3211             options |= XML_PARSE_DTDLOAD;
3212         } else if ((!strcmp(argv[i], "-dtdvalid")) ||
3213                  (!strcmp(argv[i], "--dtdvalid"))) {
3214             i++;
3215             dtdvalid = argv[i];
3216             loaddtd++;
3217             options |= XML_PARSE_DTDLOAD;
3218         } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3219                  (!strcmp(argv[i], "--dtdvalidfpi"))) {
3220             i++;
3221             dtdvalidfpi = argv[i];
3222             loaddtd++;
3223             options |= XML_PARSE_DTDLOAD;
3224         }
3225 #endif /* LIBXML_VALID_ENABLED */
3226         else if ((!strcmp(argv[i], "-dropdtd")) ||
3227                  (!strcmp(argv[i], "--dropdtd")))
3228             dropdtd++;
3229         else if ((!strcmp(argv[i], "-insert")) ||
3230                  (!strcmp(argv[i], "--insert")))
3231             insert++;
3232         else if ((!strcmp(argv[i], "-timing")) ||
3233                  (!strcmp(argv[i], "--timing")))
3234             timing++;
3235         else if ((!strcmp(argv[i], "-auto")) ||
3236                  (!strcmp(argv[i], "--auto")))
3237             generate++;
3238         else if ((!strcmp(argv[i], "-repeat")) ||
3239                  (!strcmp(argv[i], "--repeat"))) {
3240             if (repeat)
3241                 repeat *= 10;
3242             else
3243                 repeat = 100;
3244         }
3245 #ifdef LIBXML_PUSH_ENABLED
3246         else if ((!strcmp(argv[i], "-push")) ||
3247                  (!strcmp(argv[i], "--push")))
3248             push++;
3249 #endif /* LIBXML_PUSH_ENABLED */
3250 #ifdef HAVE_SYS_MMAN_H
3251         else if ((!strcmp(argv[i], "-memory")) ||
3252                  (!strcmp(argv[i], "--memory")))
3253             memory++;
3254 #endif
3255         else if ((!strcmp(argv[i], "-testIO")) ||
3256                  (!strcmp(argv[i], "--testIO")))
3257             testIO++;
3258 #ifdef LIBXML_XINCLUDE_ENABLED
3259         else if ((!strcmp(argv[i], "-xinclude")) ||
3260                  (!strcmp(argv[i], "--xinclude"))) {
3261             xinclude++;
3262             options |= XML_PARSE_XINCLUDE;
3263         }
3264         else if ((!strcmp(argv[i], "-noxincludenode")) ||
3265                  (!strcmp(argv[i], "--noxincludenode"))) {
3266             xinclude++;
3267             options |= XML_PARSE_XINCLUDE;
3268             options |= XML_PARSE_NOXINCNODE;
3269         }
3270         else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3271                  (!strcmp(argv[i], "--nofixup-base-uris"))) {
3272             xinclude++;
3273             options |= XML_PARSE_XINCLUDE;
3274             options |= XML_PARSE_NOBASEFIX;
3275         }
3276 #endif
3277 #ifdef LIBXML_OUTPUT_ENABLED
3278 #ifdef HAVE_ZLIB_H
3279         else if ((!strcmp(argv[i], "-compress")) ||
3280                  (!strcmp(argv[i], "--compress"))) {
3281             compress++;
3282             xmlSetCompressMode(9);
3283         }
3284 #endif
3285 #endif /* LIBXML_OUTPUT_ENABLED */
3286         else if ((!strcmp(argv[i], "-nowarning")) ||
3287                  (!strcmp(argv[i], "--nowarning"))) {
3288             xmlGetWarningsDefaultValue = 0;
3289             xmlPedanticParserDefault(0);
3290             options |= XML_PARSE_NOWARNING;
3291         }
3292         else if ((!strcmp(argv[i], "-pedantic")) ||
3293                  (!strcmp(argv[i], "--pedantic"))) {
3294             xmlGetWarningsDefaultValue = 1;
3295             xmlPedanticParserDefault(1);
3296             options |= XML_PARSE_PEDANTIC;
3297         }
3298 #ifdef LIBXML_DEBUG_ENABLED
3299         else if ((!strcmp(argv[i], "-debugent")) ||
3300                  (!strcmp(argv[i], "--debugent"))) {
3301             debugent++;
3302             xmlParserDebugEntities = 1;
3303         }
3304 #endif
3305 #ifdef LIBXML_C14N_ENABLED
3306         else if ((!strcmp(argv[i], "-c14n")) ||
3307                  (!strcmp(argv[i], "--c14n"))) {
3308             canonical++;
3309             options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3310         }
3311         else if ((!strcmp(argv[i], "-c14n11")) ||
3312                  (!strcmp(argv[i], "--c14n11"))) {
3313             canonical_11++;
3314             options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3315         }
3316         else if ((!strcmp(argv[i], "-exc-c14n")) ||
3317                  (!strcmp(argv[i], "--exc-c14n"))) {
3318             exc_canonical++;
3319             options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3320         }
3321 #endif
3322 #ifdef LIBXML_CATALOG_ENABLED
3323         else if ((!strcmp(argv[i], "-catalogs")) ||
3324                  (!strcmp(argv[i], "--catalogs"))) {
3325             catalogs++;
3326         } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3327                  (!strcmp(argv[i], "--nocatalogs"))) {
3328             nocatalogs++;
3329         }
3330 #endif
3331         else if ((!strcmp(argv[i], "-encode")) ||
3332                  (!strcmp(argv[i], "--encode"))) {
3333             i++;
3334             encoding = argv[i];
3335             /*
3336              * OK it's for testing purposes
3337              */
3338             xmlAddEncodingAlias("UTF-8", "DVEnc");
3339         }
3340         else if ((!strcmp(argv[i], "-noblanks")) ||
3341                  (!strcmp(argv[i], "--noblanks"))) {
3342              noblanks++;
3343              xmlKeepBlanksDefault(0);
3344         }
3345         else if ((!strcmp(argv[i], "-maxmem")) ||
3346                  (!strcmp(argv[i], "--maxmem"))) {
3347              i++;
3348              if (sscanf(argv[i], "%d", &maxmem) == 1) {
3349                  xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3350                              myStrdupFunc);
3351              } else {
3352                  maxmem = 0;
3353              }
3354         }
3355         else if ((!strcmp(argv[i], "-format")) ||
3356                  (!strcmp(argv[i], "--format"))) {
3357              noblanks++;
3358 #ifdef LIBXML_OUTPUT_ENABLED
3359              format = 1;
3360 #endif /* LIBXML_OUTPUT_ENABLED */
3361              xmlKeepBlanksDefault(0);
3362         }
3363         else if ((!strcmp(argv[i], "-pretty")) ||
3364                  (!strcmp(argv[i], "--pretty"))) {
3365              i++;
3366 #ifdef LIBXML_OUTPUT_ENABLED
3367              format = atoi(argv[i]);
3368              if (format == 1) {
3369                  noblanks++;
3370                  xmlKeepBlanksDefault(0);
3371              }
3372 #endif /* LIBXML_OUTPUT_ENABLED */
3373         }
3374 #ifdef LIBXML_READER_ENABLED
3375         else if ((!strcmp(argv[i], "-stream")) ||
3376                  (!strcmp(argv[i], "--stream"))) {
3377              stream++;
3378         }
3379         else if ((!strcmp(argv[i], "-walker")) ||
3380                  (!strcmp(argv[i], "--walker"))) {
3381              walker++;
3382              noout++;
3383         }
3384 #endif /* LIBXML_READER_ENABLED */
3385 #ifdef LIBXML_SAX1_ENABLED
3386         else if ((!strcmp(argv[i], "-sax1")) ||
3387                  (!strcmp(argv[i], "--sax1"))) {
3388             sax1++;
3389             options |= XML_PARSE_SAX1;
3390         }
3391 #endif /* LIBXML_SAX1_ENABLED */
3392         else if ((!strcmp(argv[i], "-sax")) ||
3393                  (!strcmp(argv[i], "--sax"))) {
3394             sax++;
3395         }
3396         else if ((!strcmp(argv[i], "-chkregister")) ||
3397                  (!strcmp(argv[i], "--chkregister"))) {
3398             chkregister++;
3399 #ifdef LIBXML_SCHEMAS_ENABLED
3400         } else if ((!strcmp(argv[i], "-relaxng")) ||
3401                  (!strcmp(argv[i], "--relaxng"))) {
3402             i++;
3403             relaxng = argv[i];
3404             noent++;
3405             options |= XML_PARSE_NOENT;
3406         } else if ((!strcmp(argv[i], "-schema")) ||
3407                  (!strcmp(argv[i], "--schema"))) {
3408             i++;
3409             schema = argv[i];
3410             noent++;
3411 #endif
3412 #ifdef LIBXML_SCHEMATRON_ENABLED
3413         } else if ((!strcmp(argv[i], "-schematron")) ||
3414                  (!strcmp(argv[i], "--schematron"))) {
3415             i++;
3416             schematron = argv[i];
3417             noent++;
3418 #endif
3419         } else if ((!strcmp(argv[i], "-nonet")) ||
3420                    (!strcmp(argv[i], "--nonet"))) {
3421             options |= XML_PARSE_NONET;
3422             xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
3423         } else if ((!strcmp(argv[i], "-nocompact")) ||
3424                    (!strcmp(argv[i], "--nocompact"))) {
3425             options &= ~XML_PARSE_COMPACT;
3426         } else if ((!strcmp(argv[i], "-load-trace")) ||
3427                    (!strcmp(argv[i], "--load-trace"))) {
3428             load_trace++;
3429         } else if ((!strcmp(argv[i], "-path")) ||
3430                    (!strcmp(argv[i], "--path"))) {
3431             i++;
3432             parsePath(BAD_CAST argv[i]);
3433 #ifdef LIBXML_PATTERN_ENABLED
3434         } else if ((!strcmp(argv[i], "-pattern")) ||
3435                    (!strcmp(argv[i], "--pattern"))) {
3436             i++;
3437             pattern = argv[i];
3438 #endif
3439 #ifdef LIBXML_XPATH_ENABLED
3440         } else if ((!strcmp(argv[i], "-xpath")) ||
3441                    (!strcmp(argv[i], "--xpath"))) {
3442             i++;
3443             noout++;
3444             xpathquery = argv[i];
3445 #endif
3446         } else if ((!strcmp(argv[i], "-oldxml10")) ||
3447                    (!strcmp(argv[i], "--oldxml10"))) {
3448             oldxml10++;
3449             options |= XML_PARSE_OLD10;
3450         } else {
3451             fprintf(stderr, "Unknown option %s\n", argv[i]);
3452             usage(argv[0]);
3453             return(1);
3454         }
3455     }
3456
3457 #ifdef LIBXML_CATALOG_ENABLED
3458     if (nocatalogs == 0) {
3459         if (catalogs) {
3460             const char *catal;
3461
3462             catal = getenv("SGML_CATALOG_FILES");
3463             if (catal != NULL) {
3464                 xmlLoadCatalogs(catal);
3465             } else {
3466                 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3467             }
3468         }
3469     }
3470 #endif
3471
3472 #ifdef LIBXML_SAX1_ENABLED
3473     if (sax1)
3474         xmlSAXDefaultVersion(1);
3475     else
3476         xmlSAXDefaultVersion(2);
3477 #endif /* LIBXML_SAX1_ENABLED */
3478
3479     if (chkregister) {
3480         xmlRegisterNodeDefault(registerNode);
3481         xmlDeregisterNodeDefault(deregisterNode);
3482     }
3483
3484     indent = getenv("XMLLINT_INDENT");
3485     if(indent != NULL) {
3486         xmlTreeIndentString = indent;
3487     }
3488
3489
3490     defaultEntityLoader = xmlGetExternalEntityLoader();
3491     xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3492
3493     xmlLineNumbersDefault(1);
3494     if (loaddtd != 0)
3495         xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3496     if (dtdattrs)
3497         xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
3498     if (noent != 0) xmlSubstituteEntitiesDefault(1);
3499 #ifdef LIBXML_VALID_ENABLED
3500     if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
3501 #endif /* LIBXML_VALID_ENABLED */
3502     if ((htmlout) && (!nowrap)) {
3503         xmlGenericError(xmlGenericErrorContext,
3504          "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
3505         xmlGenericError(xmlGenericErrorContext,
3506                 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3507         xmlGenericError(xmlGenericErrorContext,
3508          "<html><head><title>%s output</title></head>\n",
3509                 argv[0]);
3510         xmlGenericError(xmlGenericErrorContext,
3511          "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3512                 argv[0]);
3513     }
3514
3515 #ifdef LIBXML_SCHEMATRON_ENABLED
3516     if ((schematron != NULL) && (sax == 0)
3517 #ifdef LIBXML_READER_ENABLED
3518         && (stream == 0)
3519 #endif /* LIBXML_READER_ENABLED */
3520         ) {
3521         xmlSchematronParserCtxtPtr ctxt;
3522
3523         /* forces loading the DTDs */
3524         xmlLoadExtDtdDefaultValue |= 1;
3525         options |= XML_PARSE_DTDLOAD;
3526         if (timing) {
3527             startTimer();
3528         }
3529         ctxt = xmlSchematronNewParserCtxt(schematron);
3530 #if 0
3531         xmlSchematronSetParserErrors(ctxt,
3532                 (xmlSchematronValidityErrorFunc) fprintf,
3533                 (xmlSchematronValidityWarningFunc) fprintf,
3534                 stderr);
3535 #endif
3536         wxschematron = xmlSchematronParse(ctxt);
3537         if (wxschematron == NULL) {
3538             xmlGenericError(xmlGenericErrorContext,
3539                     "Schematron schema %s failed to compile\n", schematron);
3540             progresult = XMLLINT_ERR_SCHEMACOMP;
3541             schematron = NULL;
3542         }
3543         xmlSchematronFreeParserCtxt(ctxt);
3544         if (timing) {
3545             endTimer("Compiling the schemas");
3546         }
3547     }
3548 #endif
3549 #ifdef LIBXML_SCHEMAS_ENABLED
3550     if ((relaxng != NULL) && (sax == 0)
3551 #ifdef LIBXML_READER_ENABLED
3552         && (stream == 0)
3553 #endif /* LIBXML_READER_ENABLED */
3554         ) {
3555         xmlRelaxNGParserCtxtPtr ctxt;
3556
3557         /* forces loading the DTDs */
3558         xmlLoadExtDtdDefaultValue |= 1;
3559         options |= XML_PARSE_DTDLOAD;
3560         if (timing) {
3561             startTimer();
3562         }
3563         ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3564         xmlRelaxNGSetParserErrors(ctxt,
3565                 (xmlRelaxNGValidityErrorFunc) fprintf,
3566                 (xmlRelaxNGValidityWarningFunc) fprintf,
3567                 stderr);
3568         relaxngschemas = xmlRelaxNGParse(ctxt);
3569         if (relaxngschemas == NULL) {
3570             xmlGenericError(xmlGenericErrorContext,
3571                     "Relax-NG schema %s failed to compile\n", relaxng);
3572             progresult = XMLLINT_ERR_SCHEMACOMP;
3573             relaxng = NULL;
3574         }
3575         xmlRelaxNGFreeParserCtxt(ctxt);
3576         if (timing) {
3577             endTimer("Compiling the schemas");
3578         }
3579     } else if ((schema != NULL)
3580 #ifdef LIBXML_READER_ENABLED
3581                 && (stream == 0)
3582 #endif
3583         ) {
3584         xmlSchemaParserCtxtPtr ctxt;
3585
3586         if (timing) {
3587             startTimer();
3588         }
3589         ctxt = xmlSchemaNewParserCtxt(schema);
3590         xmlSchemaSetParserErrors(ctxt,
3591                 (xmlSchemaValidityErrorFunc) fprintf,
3592                 (xmlSchemaValidityWarningFunc) fprintf,
3593                 stderr);
3594         wxschemas = xmlSchemaParse(ctxt);
3595         if (wxschemas == NULL) {
3596             xmlGenericError(xmlGenericErrorContext,
3597                     "WXS schema %s failed to compile\n", schema);
3598             progresult = XMLLINT_ERR_SCHEMACOMP;
3599             schema = NULL;
3600         }
3601         xmlSchemaFreeParserCtxt(ctxt);
3602         if (timing) {
3603             endTimer("Compiling the schemas");
3604         }
3605     }
3606 #endif /* LIBXML_SCHEMAS_ENABLED */
3607 #ifdef LIBXML_PATTERN_ENABLED
3608     if ((pattern != NULL)
3609 #ifdef LIBXML_READER_ENABLED
3610         && (walker == 0)
3611 #endif
3612         ) {
3613         patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
3614         if (patternc == NULL) {
3615             xmlGenericError(xmlGenericErrorContext,
3616                     "Pattern %s failed to compile\n", pattern);
3617             progresult = XMLLINT_ERR_SCHEMAPAT;
3618             pattern = NULL;
3619         }
3620     }
3621 #endif /* LIBXML_PATTERN_ENABLED */
3622     for (i = 1; i < argc ; i++) {
3623         if ((!strcmp(argv[i], "-encode")) ||
3624                  (!strcmp(argv[i], "--encode"))) {
3625             i++;
3626             continue;
3627         } else if ((!strcmp(argv[i], "-o")) ||
3628                    (!strcmp(argv[i], "-output")) ||
3629                    (!strcmp(argv[i], "--output"))) {
3630             i++;
3631             continue;
3632         }
3633 #ifdef LIBXML_VALID_ENABLED
3634         if ((!strcmp(argv[i], "-dtdvalid")) ||
3635                  (!strcmp(argv[i], "--dtdvalid"))) {
3636             i++;
3637             continue;
3638         }
3639         if ((!strcmp(argv[i], "-path")) ||
3640                    (!strcmp(argv[i], "--path"))) {
3641             i++;
3642             continue;
3643         }
3644         if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3645                  (!strcmp(argv[i], "--dtdvalidfpi"))) {
3646             i++;
3647             continue;
3648         }
3649 #endif /* LIBXML_VALID_ENABLED */
3650         if ((!strcmp(argv[i], "-relaxng")) ||
3651                  (!strcmp(argv[i], "--relaxng"))) {
3652             i++;
3653             continue;
3654         }
3655         if ((!strcmp(argv[i], "-maxmem")) ||
3656                  (!strcmp(argv[i], "--maxmem"))) {
3657             i++;
3658             continue;
3659         }
3660         if ((!strcmp(argv[i], "-pretty")) ||
3661                  (!strcmp(argv[i], "--pretty"))) {
3662             i++;
3663             continue;
3664         }
3665         if ((!strcmp(argv[i], "-schema")) ||
3666                  (!strcmp(argv[i], "--schema"))) {
3667             i++;
3668             continue;
3669         }
3670         if ((!strcmp(argv[i], "-schematron")) ||
3671                  (!strcmp(argv[i], "--schematron"))) {
3672             i++;
3673             continue;
3674         }
3675 #ifdef LIBXML_PATTERN_ENABLED
3676         if ((!strcmp(argv[i], "-pattern")) ||
3677             (!strcmp(argv[i], "--pattern"))) {
3678             i++;
3679             continue;
3680         }
3681 #endif
3682 #ifdef LIBXML_XPATH_ENABLED
3683         if ((!strcmp(argv[i], "-xpath")) ||
3684             (!strcmp(argv[i], "--xpath"))) {
3685             i++;
3686             continue;
3687         }
3688 #endif
3689         if ((timing) && (repeat))
3690             startTimer();
3691         /* Remember file names.  "-" means stdin.  <sven@zen.org> */
3692         if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
3693             if (repeat) {
3694                 xmlParserCtxtPtr ctxt = NULL;
3695
3696                 for (acount = 0;acount < repeat;acount++) {
3697 #ifdef LIBXML_READER_ENABLED
3698                     if (stream != 0) {
3699                         streamFile(argv[i]);
3700                     } else {
3701 #endif /* LIBXML_READER_ENABLED */
3702                         if (sax) {
3703                             testSAX(argv[i]);
3704                         } else {
3705                             if (ctxt == NULL)
3706                                 ctxt = xmlNewParserCtxt();
3707                             parseAndPrintFile(argv[i], ctxt);
3708                         }
3709 #ifdef LIBXML_READER_ENABLED
3710                     }
3711 #endif /* LIBXML_READER_ENABLED */
3712                 }
3713                 if (ctxt != NULL)
3714                     xmlFreeParserCtxt(ctxt);
3715             } else {
3716                 nbregister = 0;
3717
3718 #ifdef LIBXML_READER_ENABLED
3719                 if (stream != 0)
3720                     streamFile(argv[i]);
3721                 else
3722 #endif /* LIBXML_READER_ENABLED */
3723                 if (sax) {
3724                     testSAX(argv[i]);
3725                 } else {
3726                     parseAndPrintFile(argv[i], NULL);
3727                 }
3728
3729                 if ((chkregister) && (nbregister != 0)) {
3730                     fprintf(stderr, "Registration count off: %d\n", nbregister);
3731                     progresult = XMLLINT_ERR_RDREGIS;
3732                 }
3733             }
3734             files ++;
3735             if ((timing) && (repeat)) {
3736                 endTimer("%d iterations", repeat);
3737             }
3738         }
3739     }
3740     if (generate)
3741         parseAndPrintFile(NULL, NULL);
3742     if ((htmlout) && (!nowrap)) {
3743         xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
3744     }
3745     if ((files == 0) && (!generate) && (version == 0)) {
3746         usage(argv[0]);
3747     }
3748 #ifdef LIBXML_SCHEMATRON_ENABLED
3749     if (wxschematron != NULL)
3750         xmlSchematronFree(wxschematron);
3751 #endif
3752 #ifdef LIBXML_SCHEMAS_ENABLED
3753     if (relaxngschemas != NULL)
3754         xmlRelaxNGFree(relaxngschemas);
3755     if (wxschemas != NULL)
3756         xmlSchemaFree(wxschemas);
3757     xmlRelaxNGCleanupTypes();
3758 #endif
3759 #ifdef LIBXML_PATTERN_ENABLED
3760     if (patternc != NULL)
3761         xmlFreePattern(patternc);
3762 #endif
3763     xmlCleanupParser();
3764     xmlMemoryDump();
3765
3766     return(progresult);
3767 }
3768