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