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