• 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             xmlOutputBufferPtr buf;
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             buf = xmlOutputBufferCreateFile(stdout, NULL);
2082             if (buf == 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                 xmlNodeDumpOutput(buf, node->doc, node, 0, 0, NULL);
2090                 xmlOutputBufferWrite(buf, 1, "\n");
2091             }
2092             xmlOutputBufferClose(buf);
2093 #else
2094             printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2095 #endif
2096 	    break;
2097         }
2098         case XPATH_BOOLEAN:
2099 	    if (cur->boolval) printf("true\n");
2100 	    else printf("false\n");
2101 	    break;
2102         case XPATH_NUMBER:
2103 	    switch (xmlXPathIsInf(cur->floatval)) {
2104 	    case 1:
2105 		printf("Infinity\n");
2106 		break;
2107 	    case -1:
2108 		printf("-Infinity\n");
2109 		break;
2110 	    default:
2111 		if (xmlXPathIsNaN(cur->floatval)) {
2112 		    printf("NaN\n");
2113 		} else {
2114 		    printf("%0g\n", cur->floatval);
2115 		}
2116 	    }
2117 	    break;
2118         case XPATH_STRING:
2119 	    printf("%s\n", (const char *) cur->stringval);
2120 	    break;
2121         case XPATH_UNDEFINED:
2122 	    fprintf(stderr, "XPath Object is uninitialized\n");
2123             progresult = XMLLINT_ERR_XPATH;
2124 	    break;
2125 	default:
2126 	    fprintf(stderr, "XPath object of unexpected type\n");
2127             progresult = XMLLINT_ERR_XPATH;
2128 	    break;
2129     }
2130 }
2131 
doXPathQuery(xmlDocPtr doc,const char * query)2132 static void doXPathQuery(xmlDocPtr doc, const char *query) {
2133     xmlXPathContextPtr ctxt;
2134     xmlXPathObjectPtr res;
2135 
2136     ctxt = xmlXPathNewContext(doc);
2137     if (ctxt == NULL) {
2138         fprintf(stderr, "Out of memory for XPath\n");
2139         progresult = XMLLINT_ERR_MEM;
2140         return;
2141     }
2142     ctxt->node = (xmlNodePtr) doc;
2143     res = xmlXPathEval(BAD_CAST query, ctxt);
2144     xmlXPathFreeContext(ctxt);
2145 
2146     if (res == NULL) {
2147         fprintf(stderr, "XPath evaluation failure\n");
2148         progresult = XMLLINT_ERR_XPATH;
2149         return;
2150     }
2151     doXPathDump(res);
2152     xmlXPathFreeObject(res);
2153 }
2154 #endif /* LIBXML_XPATH_ENABLED */
2155 
2156 /************************************************************************
2157  *									*
2158  *			Tree Test processing				*
2159  *									*
2160  ************************************************************************/
parseAndPrintFile(char * filename,xmlParserCtxtPtr rectxt)2161 static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
2162     xmlDocPtr doc = NULL;
2163 #ifdef LIBXML_TREE_ENABLED
2164     xmlDocPtr tmp;
2165 #endif /* LIBXML_TREE_ENABLED */
2166 
2167     if ((timing) && (!repeat))
2168 	startTimer();
2169 
2170 
2171 #ifdef LIBXML_TREE_ENABLED
2172     if (filename == NULL) {
2173 	if (generate) {
2174 	    xmlNodePtr n;
2175 
2176 	    doc = xmlNewDoc(BAD_CAST "1.0");
2177 	    n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
2178 	    xmlNodeSetContent(n, BAD_CAST "abc");
2179 	    xmlDocSetRootElement(doc, n);
2180 	}
2181     }
2182 #endif /* LIBXML_TREE_ENABLED */
2183 #ifdef LIBXML_HTML_ENABLED
2184 #ifdef LIBXML_PUSH_ENABLED
2185     else if ((html) && (push)) {
2186         FILE *f;
2187 
2188 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2189 	f = fopen(filename, "rb");
2190 #elif defined(__OS400__)
2191 	f = fopen(filename, "rb");
2192 #else
2193 	f = fopen(filename, "r");
2194 #endif
2195         if (f != NULL) {
2196             int res;
2197             char chars[4096];
2198             htmlParserCtxtPtr ctxt;
2199 
2200             res = fread(chars, 1, 4, f);
2201             if (res > 0) {
2202                 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
2203                             chars, res, filename, XML_CHAR_ENCODING_NONE);
2204                 xmlCtxtUseOptions(ctxt, options);
2205                 while ((res = fread(chars, 1, pushsize, f)) > 0) {
2206                     htmlParseChunk(ctxt, chars, res, 0);
2207                 }
2208                 htmlParseChunk(ctxt, chars, 0, 1);
2209                 doc = ctxt->myDoc;
2210                 htmlFreeParserCtxt(ctxt);
2211             }
2212             fclose(f);
2213         }
2214     }
2215 #endif /* LIBXML_PUSH_ENABLED */
2216 #ifdef HAVE_MMAP
2217     else if ((html) && (memory)) {
2218 	int fd;
2219 	struct stat info;
2220 	const char *base;
2221 	if (stat(filename, &info) < 0)
2222 	    return;
2223 	if ((fd = open(filename, O_RDONLY)) < 0)
2224 	    return;
2225 	base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2226 	if (base == (void *) MAP_FAILED) {
2227 	    close(fd);
2228 	    fprintf(stderr, "mmap failure for file %s\n", filename);
2229 	    progresult = XMLLINT_ERR_RDFILE;
2230 	    return;
2231 	}
2232 
2233 	doc = htmlReadMemory((char *) base, info.st_size, filename,
2234 	                     NULL, options);
2235 
2236 	munmap((char *) base, info.st_size);
2237 	close(fd);
2238     }
2239 #endif
2240     else if (html) {
2241 	doc = htmlReadFile(filename, NULL, options);
2242     }
2243 #endif /* LIBXML_HTML_ENABLED */
2244     else {
2245 #ifdef LIBXML_PUSH_ENABLED
2246 	/*
2247 	 * build an XML tree from a string;
2248 	 */
2249 	if (push) {
2250 	    FILE *f;
2251 
2252 	    /* '-' Usually means stdin -<sven@zen.org> */
2253 	    if ((filename[0] == '-') && (filename[1] == 0)) {
2254 	      f = stdin;
2255 	    } else {
2256 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2257 		f = fopen(filename, "rb");
2258 #elif defined(__OS400__)
2259 		f = fopen(filename, "rb");
2260 #else
2261 		f = fopen(filename, "r");
2262 #endif
2263 	    }
2264 	    if (f != NULL) {
2265 		int ret;
2266 	        int res, size = 1024;
2267 	        char chars[1024];
2268                 xmlParserCtxtPtr ctxt;
2269 
2270 		/* if (repeat) size = 1024; */
2271 		res = fread(chars, 1, 4, f);
2272 		if (res > 0) {
2273 		    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2274 		                chars, res, filename);
2275 		    xmlCtxtUseOptions(ctxt, options);
2276 		    while ((res = fread(chars, 1, size, f)) > 0) {
2277 			xmlParseChunk(ctxt, chars, res, 0);
2278 		    }
2279 		    xmlParseChunk(ctxt, chars, 0, 1);
2280 		    doc = ctxt->myDoc;
2281 		    ret = ctxt->wellFormed;
2282 		    xmlFreeParserCtxt(ctxt);
2283 		    if (!ret) {
2284 			xmlFreeDoc(doc);
2285 			doc = NULL;
2286 		    }
2287 	        }
2288                 if (f != stdin)
2289                     fclose(f);
2290 	    }
2291 	} else
2292 #endif /* LIBXML_PUSH_ENABLED */
2293         if (testIO) {
2294 	    if ((filename[0] == '-') && (filename[1] == 0)) {
2295 	        doc = xmlReadFd(0, NULL, NULL, options);
2296 	    } else {
2297 	        FILE *f;
2298 
2299 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2300 		f = fopen(filename, "rb");
2301 #elif defined(__OS400__)
2302 		f = fopen(filename, "rb");
2303 #else
2304 		f = fopen(filename, "r");
2305 #endif
2306 		if (f != NULL) {
2307 		    if (rectxt == NULL)
2308 			doc = xmlReadIO(myRead, myClose, f, filename, NULL,
2309                                         options);
2310 		    else
2311 			doc = xmlCtxtReadIO(rectxt, myRead, myClose, f,
2312 					    filename, NULL, options);
2313 		} else
2314 		    doc = NULL;
2315 	    }
2316 	} else if (htmlout) {
2317 	    xmlParserCtxtPtr ctxt;
2318 
2319 	    if (rectxt == NULL)
2320 		ctxt = xmlNewParserCtxt();
2321 	    else
2322 	        ctxt = rectxt;
2323 	    if (ctxt == NULL) {
2324 	        doc = NULL;
2325 	    } else {
2326 	        ctxt->sax->error = xmlHTMLError;
2327 	        ctxt->sax->warning = xmlHTMLWarning;
2328 	        ctxt->vctxt.error = xmlHTMLValidityError;
2329 	        ctxt->vctxt.warning = xmlHTMLValidityWarning;
2330 
2331 		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2332 
2333 		if (rectxt == NULL)
2334 		    xmlFreeParserCtxt(ctxt);
2335 	    }
2336 #ifdef HAVE_MMAP
2337 	} else if (memory) {
2338 	    int fd;
2339 	    struct stat info;
2340 	    const char *base;
2341 	    if (stat(filename, &info) < 0)
2342 		return;
2343 	    if ((fd = open(filename, O_RDONLY)) < 0)
2344 		return;
2345 	    base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2346 	    if (base == (void *) MAP_FAILED) {
2347 	        close(fd);
2348 	        fprintf(stderr, "mmap failure for file %s\n", filename);
2349 		progresult = XMLLINT_ERR_RDFILE;
2350 	        return;
2351 	    }
2352 
2353 	    if (rectxt == NULL)
2354 		doc = xmlReadMemory((char *) base, info.st_size,
2355 		                    filename, NULL, options);
2356 	    else
2357 		doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2358 			                filename, NULL, options);
2359 
2360 	    munmap((char *) base, info.st_size);
2361 	    close(fd);
2362 #endif
2363 #ifdef LIBXML_VALID_ENABLED
2364 	} else if (valid) {
2365 	    xmlParserCtxtPtr ctxt = NULL;
2366 
2367 	    if (rectxt == NULL)
2368 		ctxt = xmlNewParserCtxt();
2369 	    else
2370 	        ctxt = rectxt;
2371 	    if (ctxt == NULL) {
2372 	        doc = NULL;
2373 	    } else {
2374 		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2375 
2376 		if (ctxt->valid == 0)
2377 		    progresult = XMLLINT_ERR_RDFILE;
2378 		if (rectxt == NULL)
2379 		    xmlFreeParserCtxt(ctxt);
2380 	    }
2381 #endif /* LIBXML_VALID_ENABLED */
2382 	} else {
2383 	    if (rectxt != NULL)
2384 	        doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
2385 	    else {
2386 #ifdef LIBXML_SAX1_ENABLED
2387                 if (sax1)
2388 		    doc = xmlParseFile(filename);
2389 		else
2390 #endif /* LIBXML_SAX1_ENABLED */
2391 		doc = xmlReadFile(filename, NULL, options);
2392 	    }
2393 	}
2394     }
2395 
2396     /*
2397      * If we don't have a document we might as well give up.  Do we
2398      * want an error message here?  <sven@zen.org> */
2399     if (doc == NULL) {
2400 	progresult = XMLLINT_ERR_UNCLASS;
2401 	return;
2402     }
2403 
2404     if ((timing) && (!repeat)) {
2405 	endTimer("Parsing");
2406     }
2407 
2408     /*
2409      * Remove DOCTYPE nodes
2410      */
2411     if (dropdtd) {
2412 	xmlDtdPtr dtd;
2413 
2414 	dtd = xmlGetIntSubset(doc);
2415 	if (dtd != NULL) {
2416 	    xmlUnlinkNode((xmlNodePtr)dtd);
2417 	    xmlFreeDtd(dtd);
2418 	}
2419     }
2420 
2421 #ifdef LIBXML_XINCLUDE_ENABLED
2422     if (xinclude) {
2423 	if ((timing) && (!repeat)) {
2424 	    startTimer();
2425 	}
2426 	if (xmlXIncludeProcessFlags(doc, options) < 0)
2427 	    progresult = XMLLINT_ERR_UNCLASS;
2428 	if ((timing) && (!repeat)) {
2429 	    endTimer("Xinclude processing");
2430 	}
2431     }
2432 #endif
2433 
2434 #ifdef LIBXML_XPATH_ENABLED
2435     if (xpathquery != NULL) {
2436         doXPathQuery(doc, xpathquery);
2437     }
2438 #endif
2439 
2440 #ifdef LIBXML_DEBUG_ENABLED
2441 #ifdef LIBXML_XPATH_ENABLED
2442     /*
2443      * shell interaction
2444      */
2445     if (shell) {
2446         xmlXPathOrderDocElems(doc);
2447         xmlShell(doc, filename, xmlShellReadline, stdout);
2448     }
2449 #endif
2450 #endif
2451 
2452 #ifdef LIBXML_TREE_ENABLED
2453     /*
2454      * test intermediate copy if needed.
2455      */
2456     if (copy) {
2457         tmp = doc;
2458 	if (timing) {
2459 	    startTimer();
2460 	}
2461 	doc = xmlCopyDoc(doc, 1);
2462 	if (timing) {
2463 	    endTimer("Copying");
2464 	}
2465 	if (timing) {
2466 	    startTimer();
2467 	}
2468 	xmlFreeDoc(tmp);
2469 	if (timing) {
2470 	    endTimer("Freeing original");
2471 	}
2472     }
2473 #endif /* LIBXML_TREE_ENABLED */
2474 
2475 #ifdef LIBXML_VALID_ENABLED
2476     if ((insert) && (!html)) {
2477         const xmlChar* list[256];
2478 	int nb, i;
2479 	xmlNodePtr node;
2480 
2481 	if (doc->children != NULL) {
2482 	    node = doc->children;
2483 	    while ((node != NULL) && (node->last == NULL)) node = node->next;
2484 	    if (node != NULL) {
2485 		nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2486 		if (nb < 0) {
2487 		    fprintf(stderr, "could not get valid list of elements\n");
2488 		} else if (nb == 0) {
2489 		    fprintf(stderr, "No element can be inserted under root\n");
2490 		} else {
2491 		    fprintf(stderr, "%d element types can be inserted under root:\n",
2492 		           nb);
2493 		    for (i = 0;i < nb;i++) {
2494 			 fprintf(stderr, "%s\n", (char *) list[i]);
2495 		    }
2496 		}
2497 	    }
2498 	}
2499     }else
2500 #endif /* LIBXML_VALID_ENABLED */
2501 #ifdef LIBXML_READER_ENABLED
2502     if (walker) {
2503         walkDoc(doc);
2504     }
2505 #endif /* LIBXML_READER_ENABLED */
2506 #ifdef LIBXML_OUTPUT_ENABLED
2507     if (noout == 0) {
2508         int ret;
2509 
2510 	/*
2511 	 * print it.
2512 	 */
2513 #ifdef LIBXML_DEBUG_ENABLED
2514 	if (!debug) {
2515 #endif
2516 	    if ((timing) && (!repeat)) {
2517 		startTimer();
2518 	    }
2519 #ifdef LIBXML_HTML_ENABLED
2520             if ((html) && (!xmlout)) {
2521 		if (compress) {
2522 		    htmlSaveFile(output ? output : "-", doc);
2523 		}
2524 		else if (encoding != NULL) {
2525 		    if (format == 1) {
2526 			htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2527 		    }
2528 		    else {
2529 			htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2530 		    }
2531 		}
2532 		else if (format == 1) {
2533 		    htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2534 		}
2535 		else {
2536 		    FILE *out;
2537 		    if (output == NULL)
2538 			out = stdout;
2539 		    else {
2540 			out = fopen(output,"wb");
2541 		    }
2542 		    if (out != NULL) {
2543 			if (htmlDocDump(out, doc) < 0)
2544 			    progresult = XMLLINT_ERR_OUT;
2545 
2546 			if (output != NULL)
2547 			    fclose(out);
2548 		    } else {
2549 			fprintf(stderr, "failed to open %s\n", output);
2550 			progresult = XMLLINT_ERR_OUT;
2551 		    }
2552 		}
2553 		if ((timing) && (!repeat)) {
2554 		    endTimer("Saving");
2555 		}
2556 	    } else
2557 #endif
2558 #ifdef LIBXML_C14N_ENABLED
2559             if (canonical) {
2560 	        xmlChar *result = NULL;
2561 		int size;
2562 
2563 		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2564 		if (size >= 0) {
2565 		    if (write(1, result, size) == -1) {
2566 		        fprintf(stderr, "Can't write data\n");
2567 		    }
2568 		    xmlFree(result);
2569 		} else {
2570 		    fprintf(stderr, "Failed to canonicalize\n");
2571 		    progresult = XMLLINT_ERR_OUT;
2572 		}
2573 	    } else if (canonical_11) {
2574 	        xmlChar *result = NULL;
2575 		int size;
2576 
2577 		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
2578 		if (size >= 0) {
2579 		    if (write(1, result, size) == -1) {
2580 		        fprintf(stderr, "Can't write data\n");
2581 		    }
2582 		    xmlFree(result);
2583 		} else {
2584 		    fprintf(stderr, "Failed to canonicalize\n");
2585 		    progresult = XMLLINT_ERR_OUT;
2586 		}
2587 	    } else
2588             if (exc_canonical) {
2589 	        xmlChar *result = NULL;
2590 		int size;
2591 
2592 		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
2593 		if (size >= 0) {
2594 		    if (write(1, result, size) == -1) {
2595 		        fprintf(stderr, "Can't write data\n");
2596 		    }
2597 		    xmlFree(result);
2598 		} else {
2599 		    fprintf(stderr, "Failed to canonicalize\n");
2600 		    progresult = XMLLINT_ERR_OUT;
2601 		}
2602 	    } else
2603 #endif
2604 #ifdef HAVE_MMAP
2605 	    if (memory) {
2606 		xmlChar *result;
2607 		int len;
2608 
2609 		if (encoding != NULL) {
2610 		    if (format == 1) {
2611 		        xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
2612 		    } else {
2613 			xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2614 		    }
2615 		} else {
2616 		    if (format == 1)
2617 			xmlDocDumpFormatMemory(doc, &result, &len, 1);
2618 		    else
2619 			xmlDocDumpMemory(doc, &result, &len);
2620 		}
2621 		if (result == NULL) {
2622 		    fprintf(stderr, "Failed to save\n");
2623 		    progresult = XMLLINT_ERR_OUT;
2624 		} else {
2625 		    if (write(1, result, len) == -1) {
2626 		        fprintf(stderr, "Can't write data\n");
2627 		    }
2628 		    xmlFree(result);
2629 		}
2630 
2631 	    } else
2632 #endif /* HAVE_MMAP */
2633 	    if (compress) {
2634 		xmlSaveFile(output ? output : "-", doc);
2635 	    } else if (oldout) {
2636 	        if (encoding != NULL) {
2637 		    if (format == 1) {
2638 			ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2639 						   encoding, 1);
2640 		    }
2641 		    else {
2642 			ret = xmlSaveFileEnc(output ? output : "-", doc,
2643 			                     encoding);
2644 		    }
2645 		    if (ret < 0) {
2646 			fprintf(stderr, "failed save to %s\n",
2647 				output ? output : "-");
2648 			progresult = XMLLINT_ERR_OUT;
2649 		    }
2650 		} else if (format == 1) {
2651 		    ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2652 		    if (ret < 0) {
2653 			fprintf(stderr, "failed save to %s\n",
2654 				output ? output : "-");
2655 			progresult = XMLLINT_ERR_OUT;
2656 		    }
2657 		} else {
2658 		    FILE *out;
2659 		    if (output == NULL)
2660 			out = stdout;
2661 		    else {
2662 			out = fopen(output,"wb");
2663 		    }
2664 		    if (out != NULL) {
2665 			if (xmlDocDump(out, doc) < 0)
2666 			    progresult = XMLLINT_ERR_OUT;
2667 
2668 			if (output != NULL)
2669 			    fclose(out);
2670 		    } else {
2671 			fprintf(stderr, "failed to open %s\n", output);
2672 			progresult = XMLLINT_ERR_OUT;
2673 		    }
2674 		}
2675 	    } else {
2676 	        xmlSaveCtxtPtr ctxt;
2677 		int saveOpts = 0;
2678 
2679                 if (format == 1)
2680 		    saveOpts |= XML_SAVE_FORMAT;
2681                 else if (format == 2)
2682                     saveOpts |= XML_SAVE_WSNONSIG;
2683 
2684 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
2685                 if (xmlout)
2686                     saveOpts |= XML_SAVE_AS_XML;
2687 #endif
2688 
2689 		if (output == NULL)
2690 		    ctxt = xmlSaveToFd(1, encoding, saveOpts);
2691 		else
2692 		    ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2693 
2694 		if (ctxt != NULL) {
2695 		    if (xmlSaveDoc(ctxt, doc) < 0) {
2696 			fprintf(stderr, "failed save to %s\n",
2697 				output ? output : "-");
2698 			progresult = XMLLINT_ERR_OUT;
2699 		    }
2700 		    xmlSaveClose(ctxt);
2701 		} else {
2702 		    progresult = XMLLINT_ERR_OUT;
2703 		}
2704 	    }
2705 	    if ((timing) && (!repeat)) {
2706 		endTimer("Saving");
2707 	    }
2708 #ifdef LIBXML_DEBUG_ENABLED
2709 	} else {
2710 	    FILE *out;
2711 	    if (output == NULL)
2712 	        out = stdout;
2713 	    else {
2714 		out = fopen(output,"wb");
2715 	    }
2716 	    if (out != NULL) {
2717 		xmlDebugDumpDocument(out, doc);
2718 
2719 		if (output != NULL)
2720 		    fclose(out);
2721 	    } else {
2722 		fprintf(stderr, "failed to open %s\n", output);
2723 		progresult = XMLLINT_ERR_OUT;
2724 	    }
2725 	}
2726 #endif
2727     }
2728 #endif /* LIBXML_OUTPUT_ENABLED */
2729 
2730 #ifdef LIBXML_VALID_ENABLED
2731     /*
2732      * A posteriori validation test
2733      */
2734     if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
2735 	xmlDtdPtr dtd;
2736 
2737 	if ((timing) && (!repeat)) {
2738 	    startTimer();
2739 	}
2740 	if (dtdvalid != NULL)
2741 	    dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
2742 	else
2743 	    dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
2744 	if ((timing) && (!repeat)) {
2745 	    endTimer("Parsing DTD");
2746 	}
2747 	if (dtd == NULL) {
2748 	    if (dtdvalid != NULL)
2749 		xmlGenericError(xmlGenericErrorContext,
2750 			"Could not parse DTD %s\n", dtdvalid);
2751 	    else
2752 		xmlGenericError(xmlGenericErrorContext,
2753 			"Could not parse DTD %s\n", dtdvalidfpi);
2754 	    progresult = XMLLINT_ERR_DTD;
2755 	} else {
2756 	    xmlValidCtxtPtr cvp;
2757 
2758 	    if ((cvp = xmlNewValidCtxt()) == NULL) {
2759 		xmlGenericError(xmlGenericErrorContext,
2760 			"Couldn't allocate validation context\n");
2761 		exit(-1);
2762 	    }
2763 	    cvp->userData = (void *) stderr;
2764 	    cvp->error    = (xmlValidityErrorFunc) fprintf;
2765 	    cvp->warning  = (xmlValidityWarningFunc) fprintf;
2766 
2767 	    if ((timing) && (!repeat)) {
2768 		startTimer();
2769 	    }
2770 	    if (!xmlValidateDtd(cvp, doc, dtd)) {
2771 		if (dtdvalid != NULL)
2772 		    xmlGenericError(xmlGenericErrorContext,
2773 			    "Document %s does not validate against %s\n",
2774 			    filename, dtdvalid);
2775 		else
2776 		    xmlGenericError(xmlGenericErrorContext,
2777 			    "Document %s does not validate against %s\n",
2778 			    filename, dtdvalidfpi);
2779 		progresult = XMLLINT_ERR_VALID;
2780 	    }
2781 	    if ((timing) && (!repeat)) {
2782 		endTimer("Validating against DTD");
2783 	    }
2784 	    xmlFreeValidCtxt(cvp);
2785 	    xmlFreeDtd(dtd);
2786 	}
2787     } else if (postvalid) {
2788 	xmlValidCtxtPtr cvp;
2789 
2790 	if ((cvp = xmlNewValidCtxt()) == NULL) {
2791 	    xmlGenericError(xmlGenericErrorContext,
2792 		    "Couldn't allocate validation context\n");
2793 	    exit(-1);
2794 	}
2795 
2796 	if ((timing) && (!repeat)) {
2797 	    startTimer();
2798 	}
2799 	cvp->userData = (void *) stderr;
2800 	cvp->error    = (xmlValidityErrorFunc) fprintf;
2801 	cvp->warning  = (xmlValidityWarningFunc) fprintf;
2802 	if (!xmlValidateDocument(cvp, doc)) {
2803 	    xmlGenericError(xmlGenericErrorContext,
2804 		    "Document %s does not validate\n", filename);
2805 	    progresult = XMLLINT_ERR_VALID;
2806 	}
2807 	if ((timing) && (!repeat)) {
2808 	    endTimer("Validating");
2809 	}
2810 	xmlFreeValidCtxt(cvp);
2811     }
2812 #endif /* LIBXML_VALID_ENABLED */
2813 #ifdef LIBXML_SCHEMATRON_ENABLED
2814     if (wxschematron != NULL) {
2815 	xmlSchematronValidCtxtPtr ctxt;
2816 	int ret;
2817 	int flag;
2818 
2819 	if ((timing) && (!repeat)) {
2820 	    startTimer();
2821 	}
2822 
2823 	if (debug)
2824 	    flag = XML_SCHEMATRON_OUT_XML;
2825 	else
2826 	    flag = XML_SCHEMATRON_OUT_TEXT;
2827 	if (noout)
2828 	    flag |= XML_SCHEMATRON_OUT_QUIET;
2829 	ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2830 #if 0
2831 	xmlSchematronSetValidErrors(ctxt,
2832 		(xmlSchematronValidityErrorFunc) fprintf,
2833 		(xmlSchematronValidityWarningFunc) fprintf,
2834 		stderr);
2835 #endif
2836 	ret = xmlSchematronValidateDoc(ctxt, doc);
2837 	if (ret == 0) {
2838 	    fprintf(stderr, "%s validates\n", filename);
2839 	} else if (ret > 0) {
2840 	    fprintf(stderr, "%s fails to validate\n", filename);
2841 	    progresult = XMLLINT_ERR_VALID;
2842 	} else {
2843 	    fprintf(stderr, "%s validation generated an internal error\n",
2844 		   filename);
2845 	    progresult = XMLLINT_ERR_VALID;
2846 	}
2847 	xmlSchematronFreeValidCtxt(ctxt);
2848 	if ((timing) && (!repeat)) {
2849 	    endTimer("Validating");
2850 	}
2851     }
2852 #endif
2853 #ifdef LIBXML_SCHEMAS_ENABLED
2854     if (relaxngschemas != NULL) {
2855 	xmlRelaxNGValidCtxtPtr ctxt;
2856 	int ret;
2857 
2858 	if ((timing) && (!repeat)) {
2859 	    startTimer();
2860 	}
2861 
2862 	ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2863 	xmlRelaxNGSetValidErrors(ctxt,
2864 		(xmlRelaxNGValidityErrorFunc) fprintf,
2865 		(xmlRelaxNGValidityWarningFunc) fprintf,
2866 		stderr);
2867 	ret = xmlRelaxNGValidateDoc(ctxt, doc);
2868 	if (ret == 0) {
2869 	    fprintf(stderr, "%s validates\n", filename);
2870 	} else if (ret > 0) {
2871 	    fprintf(stderr, "%s fails to validate\n", filename);
2872 	    progresult = XMLLINT_ERR_VALID;
2873 	} else {
2874 	    fprintf(stderr, "%s validation generated an internal error\n",
2875 		   filename);
2876 	    progresult = XMLLINT_ERR_VALID;
2877 	}
2878 	xmlRelaxNGFreeValidCtxt(ctxt);
2879 	if ((timing) && (!repeat)) {
2880 	    endTimer("Validating");
2881 	}
2882     } else if (wxschemas != NULL) {
2883 	xmlSchemaValidCtxtPtr ctxt;
2884 	int ret;
2885 
2886 	if ((timing) && (!repeat)) {
2887 	    startTimer();
2888 	}
2889 
2890 	ctxt = xmlSchemaNewValidCtxt(wxschemas);
2891 	xmlSchemaSetValidErrors(ctxt,
2892 		(xmlSchemaValidityErrorFunc) fprintf,
2893 		(xmlSchemaValidityWarningFunc) fprintf,
2894 		stderr);
2895 	ret = xmlSchemaValidateDoc(ctxt, doc);
2896 	if (ret == 0) {
2897 	    fprintf(stderr, "%s validates\n", filename);
2898 	} else if (ret > 0) {
2899 	    fprintf(stderr, "%s fails to validate\n", filename);
2900 	    progresult = XMLLINT_ERR_VALID;
2901 	} else {
2902 	    fprintf(stderr, "%s validation generated an internal error\n",
2903 		   filename);
2904 	    progresult = XMLLINT_ERR_VALID;
2905 	}
2906 	xmlSchemaFreeValidCtxt(ctxt);
2907 	if ((timing) && (!repeat)) {
2908 	    endTimer("Validating");
2909 	}
2910     }
2911 #endif
2912 
2913 #ifdef LIBXML_DEBUG_ENABLED
2914 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
2915     if ((debugent) && (!html))
2916 	xmlDebugDumpEntities(stderr, doc);
2917 #endif
2918 #endif
2919 
2920     /*
2921      * free it.
2922      */
2923     if ((timing) && (!repeat)) {
2924 	startTimer();
2925     }
2926     xmlFreeDoc(doc);
2927     if ((timing) && (!repeat)) {
2928 	endTimer("Freeing");
2929     }
2930 }
2931 
2932 /************************************************************************
2933  *									*
2934  *			Usage and Main					*
2935  *									*
2936  ************************************************************************/
2937 
showVersion(const char * name)2938 static void showVersion(const char *name) {
2939     fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2940     fprintf(stderr, "   compiled with: ");
2941     if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2942     if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2943     if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2944     if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2945     if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2946     if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2947     if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2948     if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
2949     if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2950     if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
2951     if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
2952     if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2953     if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2954     if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2955     if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2956     if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2957     if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2958     if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2959     if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2960     if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
2961     if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2962     if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2963     if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2964     if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2965     if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2966     if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2967     if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2968     if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2969     if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2970     if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2971     if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
2972     if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
2973     if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
2974     fprintf(stderr, "\n");
2975 }
2976 
usage(FILE * f,const char * name)2977 static void usage(FILE *f, const char *name) {
2978     fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
2979 #ifdef LIBXML_OUTPUT_ENABLED
2980     fprintf(f, "\tParse the XML files and output the result of the parsing\n");
2981 #else
2982     fprintf(f, "\tParse the XML files\n");
2983 #endif /* LIBXML_OUTPUT_ENABLED */
2984     fprintf(f, "\t--version : display the version of the XML library used\n");
2985 #ifdef LIBXML_DEBUG_ENABLED
2986     fprintf(f, "\t--debug : dump a debug tree of the in-memory document\n");
2987     fprintf(f, "\t--shell : run a navigating shell\n");
2988     fprintf(f, "\t--debugent : debug the entities defined in the document\n");
2989 #else
2990 #ifdef LIBXML_READER_ENABLED
2991     fprintf(f, "\t--debug : dump the nodes content when using --stream\n");
2992 #endif /* LIBXML_READER_ENABLED */
2993 #endif
2994 #ifdef LIBXML_TREE_ENABLED
2995     fprintf(f, "\t--copy : used to test the internal copy implementation\n");
2996 #endif /* LIBXML_TREE_ENABLED */
2997     fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
2998     fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
2999     fprintf(f, "\t--noent : substitute entity references by their value\n");
3000     fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
3001     fprintf(f, "\t--noout : don't output the result tree\n");
3002     fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
3003     fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
3004     fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
3005     fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
3006     fprintf(f, "\t--htmlout : output results as HTML\n");
3007     fprintf(f, "\t--nowrap : do not put HTML doc wrapper\n");
3008 #ifdef LIBXML_VALID_ENABLED
3009     fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
3010     fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
3011     fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
3012     fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
3013 #endif /* LIBXML_VALID_ENABLED */
3014     fprintf(f, "\t--timing : print some timings\n");
3015     fprintf(f, "\t--output file or -o file: save to a given file\n");
3016     fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
3017     fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
3018 #ifdef LIBXML_OUTPUT_ENABLED
3019 #ifdef LIBXML_ZLIB_ENABLED
3020     fprintf(f, "\t--compress : turn on gzip compression of output\n");
3021 #endif
3022 #endif /* LIBXML_OUTPUT_ENABLED */
3023 #ifdef LIBXML_HTML_ENABLED
3024     fprintf(f, "\t--html : use the HTML parser\n");
3025     fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
3026     fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
3027 #endif
3028 #ifdef LIBXML_PUSH_ENABLED
3029     fprintf(f, "\t--push : use the push mode of the parser\n");
3030     fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n");
3031 #endif /* LIBXML_PUSH_ENABLED */
3032 #ifdef HAVE_MMAP
3033     fprintf(f, "\t--memory : parse from memory\n");
3034 #endif
3035     fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
3036     fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
3037     fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
3038     fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
3039 #ifdef LIBXML_OUTPUT_ENABLED
3040     fprintf(f, "\t--format : reformat/reindent the output\n");
3041     fprintf(f, "\t--encode encoding : output in the given encoding\n");
3042     fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
3043     fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
3044     fprintf(f, "\t                 0 Do not pretty print\n");
3045     fprintf(f, "\t                 1 Format the XML content, as --format\n");
3046     fprintf(f, "\t                 2 Add whitespace inside tags, preserving content\n");
3047 #endif /* LIBXML_OUTPUT_ENABLED */
3048     fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3049     fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
3050     fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
3051 #ifdef LIBXML_C14N_ENABLED
3052 #endif /* LIBXML_C14N_ENABLED */
3053     fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
3054     fprintf(f, "\t--testIO : test user I/O support\n");
3055 #ifdef LIBXML_CATALOG_ENABLED
3056     fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3057     fprintf(f, "\t             otherwise XML Catalogs starting from \n");
3058     fprintf(f, "\t         %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
3059     fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
3060 #endif
3061     fprintf(f, "\t--auto : generate a small doc on the fly\n");
3062 #ifdef LIBXML_XINCLUDE_ENABLED
3063     fprintf(f, "\t--xinclude : do XInclude processing\n");
3064     fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
3065     fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
3066 #endif
3067     fprintf(f, "\t--loaddtd : fetch external DTD\n");
3068     fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
3069 #ifdef LIBXML_READER_ENABLED
3070     fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
3071     fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
3072 #endif /* LIBXML_READER_ENABLED */
3073 #ifdef LIBXML_PATTERN_ENABLED
3074     fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
3075 #endif
3076     fprintf(f, "\t--chkregister : verify the node registration code\n");
3077 #ifdef LIBXML_SCHEMAS_ENABLED
3078     fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
3079     fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
3080 #endif
3081 #ifdef LIBXML_SCHEMATRON_ENABLED
3082     fprintf(f, "\t--schematron schema : do validation against a schematron\n");
3083 #endif
3084 #ifdef LIBXML_SAX1_ENABLED
3085     fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
3086 #endif
3087     fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
3088     fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
3089 #ifdef LIBXML_XPATH_ENABLED
3090     fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
3091 #endif
3092 
3093     fprintf(f, "\nLibxml project home page: http://xmlsoft.org/\n");
3094     fprintf(f, "To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
3095 }
3096 
registerNode(xmlNodePtr node)3097 static void registerNode(xmlNodePtr node)
3098 {
3099     node->_private = malloc(sizeof(long));
3100     if (node->_private == NULL) {
3101         fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3102 	exit(XMLLINT_ERR_MEM);
3103     }
3104     *(long*)node->_private = (long) 0x81726354;
3105     nbregister++;
3106 }
3107 
deregisterNode(xmlNodePtr node)3108 static void deregisterNode(xmlNodePtr node)
3109 {
3110     assert(node->_private != NULL);
3111     assert(*(long*)node->_private == (long) 0x81726354);
3112     free(node->_private);
3113     nbregister--;
3114 }
3115 
3116 int
main(int argc,char ** argv)3117 main(int argc, char **argv) {
3118     int i, acount;
3119     int files = 0;
3120     int version = 0;
3121     const char* indent;
3122 
3123     if (argc <= 1) {
3124 	usage(stderr, argv[0]);
3125 	return(1);
3126     }
3127     LIBXML_TEST_VERSION
3128     for (i = 1; i < argc ; i++) {
3129 	if (!strcmp(argv[i], "-"))
3130 	    break;
3131 
3132 	if (argv[i][0] != '-')
3133 	    continue;
3134 	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3135 	    debug++;
3136 	else
3137 #ifdef LIBXML_DEBUG_ENABLED
3138 	if ((!strcmp(argv[i], "-shell")) ||
3139 	         (!strcmp(argv[i], "--shell"))) {
3140 	    shell++;
3141             noout = 1;
3142         } else
3143 #endif
3144 #ifdef LIBXML_TREE_ENABLED
3145 	if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3146 	    copy++;
3147 	else
3148 #endif /* LIBXML_TREE_ENABLED */
3149 	if ((!strcmp(argv[i], "-recover")) ||
3150 	         (!strcmp(argv[i], "--recover"))) {
3151 	    recovery++;
3152 	    options |= XML_PARSE_RECOVER;
3153 	} else if ((!strcmp(argv[i], "-huge")) ||
3154 	         (!strcmp(argv[i], "--huge"))) {
3155 	    options |= XML_PARSE_HUGE;
3156 	} else if ((!strcmp(argv[i], "-noent")) ||
3157 	         (!strcmp(argv[i], "--noent"))) {
3158 	    noent++;
3159 	    options |= XML_PARSE_NOENT;
3160 	} else if ((!strcmp(argv[i], "-noenc")) ||
3161 	         (!strcmp(argv[i], "--noenc"))) {
3162 	    noenc++;
3163 	    options |= XML_PARSE_IGNORE_ENC;
3164 	} else if ((!strcmp(argv[i], "-nsclean")) ||
3165 	         (!strcmp(argv[i], "--nsclean"))) {
3166 	    options |= XML_PARSE_NSCLEAN;
3167 	} else if ((!strcmp(argv[i], "-nocdata")) ||
3168 	         (!strcmp(argv[i], "--nocdata"))) {
3169 	    options |= XML_PARSE_NOCDATA;
3170 	} else if ((!strcmp(argv[i], "-nodict")) ||
3171 	         (!strcmp(argv[i], "--nodict"))) {
3172 	    options |= XML_PARSE_NODICT;
3173 	} else if ((!strcmp(argv[i], "-version")) ||
3174 	         (!strcmp(argv[i], "--version"))) {
3175 	    showVersion(argv[0]);
3176 	    version = 1;
3177 	} else if ((!strcmp(argv[i], "-noout")) ||
3178 	         (!strcmp(argv[i], "--noout")))
3179 	    noout++;
3180 #ifdef LIBXML_OUTPUT_ENABLED
3181 	else if ((!strcmp(argv[i], "-o")) ||
3182 	         (!strcmp(argv[i], "-output")) ||
3183 	         (!strcmp(argv[i], "--output"))) {
3184 	    i++;
3185 	    output = argv[i];
3186 	}
3187 #endif /* LIBXML_OUTPUT_ENABLED */
3188 	else if ((!strcmp(argv[i], "-htmlout")) ||
3189 	         (!strcmp(argv[i], "--htmlout")))
3190 	    htmlout++;
3191 	else if ((!strcmp(argv[i], "-nowrap")) ||
3192 	         (!strcmp(argv[i], "--nowrap")))
3193 	    nowrap++;
3194 #ifdef LIBXML_HTML_ENABLED
3195 	else if ((!strcmp(argv[i], "-html")) ||
3196 	         (!strcmp(argv[i], "--html"))) {
3197 	    html++;
3198         }
3199 	else if ((!strcmp(argv[i], "-xmlout")) ||
3200 	         (!strcmp(argv[i], "--xmlout"))) {
3201 	    xmlout++;
3202 	} else if ((!strcmp(argv[i], "-nodefdtd")) ||
3203 	         (!strcmp(argv[i], "--nodefdtd"))) {
3204             nodefdtd++;
3205 	    options |= HTML_PARSE_NODEFDTD;
3206         }
3207 #endif /* LIBXML_HTML_ENABLED */
3208 	else if ((!strcmp(argv[i], "-loaddtd")) ||
3209 	         (!strcmp(argv[i], "--loaddtd"))) {
3210 	    loaddtd++;
3211 	    options |= XML_PARSE_DTDLOAD;
3212 	} else if ((!strcmp(argv[i], "-dtdattr")) ||
3213 	         (!strcmp(argv[i], "--dtdattr"))) {
3214 	    loaddtd++;
3215 	    dtdattrs++;
3216 	    options |= XML_PARSE_DTDATTR;
3217 	}
3218 #ifdef LIBXML_VALID_ENABLED
3219 	else if ((!strcmp(argv[i], "-valid")) ||
3220 	         (!strcmp(argv[i], "--valid"))) {
3221 	    valid++;
3222 	    options |= XML_PARSE_DTDVALID;
3223 	} else if ((!strcmp(argv[i], "-postvalid")) ||
3224 	         (!strcmp(argv[i], "--postvalid"))) {
3225 	    postvalid++;
3226 	    loaddtd++;
3227 	    options |= XML_PARSE_DTDLOAD;
3228 	} else if ((!strcmp(argv[i], "-dtdvalid")) ||
3229 	         (!strcmp(argv[i], "--dtdvalid"))) {
3230 	    i++;
3231 	    dtdvalid = argv[i];
3232 	    loaddtd++;
3233 	    options |= XML_PARSE_DTDLOAD;
3234 	} else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3235 	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
3236 	    i++;
3237 	    dtdvalidfpi = argv[i];
3238 	    loaddtd++;
3239 	    options |= XML_PARSE_DTDLOAD;
3240         }
3241 #endif /* LIBXML_VALID_ENABLED */
3242 	else if ((!strcmp(argv[i], "-dropdtd")) ||
3243 	         (!strcmp(argv[i], "--dropdtd")))
3244 	    dropdtd++;
3245 	else if ((!strcmp(argv[i], "-insert")) ||
3246 	         (!strcmp(argv[i], "--insert")))
3247 	    insert++;
3248 	else if ((!strcmp(argv[i], "-timing")) ||
3249 	         (!strcmp(argv[i], "--timing")))
3250 	    timing++;
3251 	else if ((!strcmp(argv[i], "-auto")) ||
3252 	         (!strcmp(argv[i], "--auto")))
3253 	    generate++;
3254 	else if ((!strcmp(argv[i], "-repeat")) ||
3255 	         (!strcmp(argv[i], "--repeat"))) {
3256 	    if (repeat)
3257 	        repeat *= 10;
3258 	    else
3259 	        repeat = 100;
3260 	}
3261 #ifdef LIBXML_PUSH_ENABLED
3262 	else if ((!strcmp(argv[i], "-push")) ||
3263 	         (!strcmp(argv[i], "--push")))
3264 	    push++;
3265 	else if ((!strcmp(argv[i], "-pushsmall")) ||
3266 	         (!strcmp(argv[i], "--pushsmall"))) {
3267 	    push++;
3268             pushsize = 10;
3269         }
3270 #endif /* LIBXML_PUSH_ENABLED */
3271 #ifdef HAVE_MMAP
3272 	else if ((!strcmp(argv[i], "-memory")) ||
3273 	         (!strcmp(argv[i], "--memory")))
3274 	    memory++;
3275 #endif
3276 	else if ((!strcmp(argv[i], "-testIO")) ||
3277 	         (!strcmp(argv[i], "--testIO")))
3278 	    testIO++;
3279 #ifdef LIBXML_XINCLUDE_ENABLED
3280 	else if ((!strcmp(argv[i], "-xinclude")) ||
3281 	         (!strcmp(argv[i], "--xinclude"))) {
3282 	    xinclude++;
3283 	    options |= XML_PARSE_XINCLUDE;
3284 	}
3285 	else if ((!strcmp(argv[i], "-noxincludenode")) ||
3286 	         (!strcmp(argv[i], "--noxincludenode"))) {
3287 	    xinclude++;
3288 	    options |= XML_PARSE_XINCLUDE;
3289 	    options |= XML_PARSE_NOXINCNODE;
3290 	}
3291 	else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3292 	         (!strcmp(argv[i], "--nofixup-base-uris"))) {
3293 	    xinclude++;
3294 	    options |= XML_PARSE_XINCLUDE;
3295 	    options |= XML_PARSE_NOBASEFIX;
3296 	}
3297 #endif
3298 #ifdef LIBXML_OUTPUT_ENABLED
3299 #ifdef LIBXML_ZLIB_ENABLED
3300 	else if ((!strcmp(argv[i], "-compress")) ||
3301 	         (!strcmp(argv[i], "--compress"))) {
3302 	    compress++;
3303 	    xmlSetCompressMode(9);
3304         }
3305 #endif
3306 #endif /* LIBXML_OUTPUT_ENABLED */
3307 	else if ((!strcmp(argv[i], "-nowarning")) ||
3308 	         (!strcmp(argv[i], "--nowarning"))) {
3309 	    xmlGetWarningsDefaultValue = 0;
3310 	    xmlPedanticParserDefault(0);
3311 	    options |= XML_PARSE_NOWARNING;
3312         }
3313 	else if ((!strcmp(argv[i], "-pedantic")) ||
3314 	         (!strcmp(argv[i], "--pedantic"))) {
3315 	    xmlGetWarningsDefaultValue = 1;
3316 	    xmlPedanticParserDefault(1);
3317 	    options |= XML_PARSE_PEDANTIC;
3318         }
3319 #ifdef LIBXML_DEBUG_ENABLED
3320 	else if ((!strcmp(argv[i], "-debugent")) ||
3321 		 (!strcmp(argv[i], "--debugent"))) {
3322 	    debugent++;
3323 	    xmlParserDebugEntities = 1;
3324 	}
3325 #endif
3326 #ifdef LIBXML_C14N_ENABLED
3327 	else if ((!strcmp(argv[i], "-c14n")) ||
3328 		 (!strcmp(argv[i], "--c14n"))) {
3329 	    canonical++;
3330 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3331 	}
3332 	else if ((!strcmp(argv[i], "-c14n11")) ||
3333 		 (!strcmp(argv[i], "--c14n11"))) {
3334 	    canonical_11++;
3335 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3336 	}
3337 	else if ((!strcmp(argv[i], "-exc-c14n")) ||
3338 		 (!strcmp(argv[i], "--exc-c14n"))) {
3339 	    exc_canonical++;
3340 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3341 	}
3342 #endif
3343 #ifdef LIBXML_CATALOG_ENABLED
3344 	else if ((!strcmp(argv[i], "-catalogs")) ||
3345 		 (!strcmp(argv[i], "--catalogs"))) {
3346 	    catalogs++;
3347 	} else if ((!strcmp(argv[i], "-nocatalogs")) ||
3348 		 (!strcmp(argv[i], "--nocatalogs"))) {
3349 	    nocatalogs++;
3350 	}
3351 #endif
3352 	else if ((!strcmp(argv[i], "-encode")) ||
3353 	         (!strcmp(argv[i], "--encode"))) {
3354 	    i++;
3355 	    encoding = argv[i];
3356 	    /*
3357 	     * OK it's for testing purposes
3358 	     */
3359 	    xmlAddEncodingAlias("UTF-8", "DVEnc");
3360         }
3361 	else if ((!strcmp(argv[i], "-noblanks")) ||
3362 	         (!strcmp(argv[i], "--noblanks"))) {
3363 	    noblanks++;
3364 	    xmlKeepBlanksDefault(0);
3365 	    options |= XML_PARSE_NOBLANKS;
3366         }
3367 	else if ((!strcmp(argv[i], "-maxmem")) ||
3368 	         (!strcmp(argv[i], "--maxmem"))) {
3369 	     i++;
3370 	     if (sscanf(argv[i], "%d", &maxmem) == 1) {
3371 	         xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3372 		             myStrdupFunc);
3373 	     } else {
3374 	         maxmem = 0;
3375 	     }
3376         }
3377 	else if ((!strcmp(argv[i], "-format")) ||
3378 	         (!strcmp(argv[i], "--format"))) {
3379 	     noblanks++;
3380 #ifdef LIBXML_OUTPUT_ENABLED
3381 	     format = 1;
3382 #endif /* LIBXML_OUTPUT_ENABLED */
3383 	     xmlKeepBlanksDefault(0);
3384 	}
3385 	else if ((!strcmp(argv[i], "-pretty")) ||
3386 	         (!strcmp(argv[i], "--pretty"))) {
3387 	     i++;
3388 #ifdef LIBXML_OUTPUT_ENABLED
3389        if (argv[i] != NULL) {
3390 	         format = atoi(argv[i]);
3391 	         if (format == 1) {
3392 	             noblanks++;
3393 	             xmlKeepBlanksDefault(0);
3394 	         }
3395        }
3396 #endif /* LIBXML_OUTPUT_ENABLED */
3397 	}
3398 #ifdef LIBXML_READER_ENABLED
3399 	else if ((!strcmp(argv[i], "-stream")) ||
3400 	         (!strcmp(argv[i], "--stream"))) {
3401 	     stream++;
3402 	}
3403 	else if ((!strcmp(argv[i], "-walker")) ||
3404 	         (!strcmp(argv[i], "--walker"))) {
3405 	     walker++;
3406              noout++;
3407 	}
3408 #endif /* LIBXML_READER_ENABLED */
3409 #ifdef LIBXML_SAX1_ENABLED
3410 	else if ((!strcmp(argv[i], "-sax1")) ||
3411 	         (!strcmp(argv[i], "--sax1"))) {
3412 	    sax1++;
3413 	    options |= XML_PARSE_SAX1;
3414 	}
3415 #endif /* LIBXML_SAX1_ENABLED */
3416 	else if ((!strcmp(argv[i], "-sax")) ||
3417 	         (!strcmp(argv[i], "--sax"))) {
3418 	    sax++;
3419 	}
3420 	else if ((!strcmp(argv[i], "-chkregister")) ||
3421 	         (!strcmp(argv[i], "--chkregister"))) {
3422 	    chkregister++;
3423 #ifdef LIBXML_SCHEMAS_ENABLED
3424 	} else if ((!strcmp(argv[i], "-relaxng")) ||
3425 	         (!strcmp(argv[i], "--relaxng"))) {
3426 	    i++;
3427 	    relaxng = argv[i];
3428 	    noent++;
3429 	    options |= XML_PARSE_NOENT;
3430 	} else if ((!strcmp(argv[i], "-schema")) ||
3431 	         (!strcmp(argv[i], "--schema"))) {
3432 	    i++;
3433 	    schema = argv[i];
3434 	    noent++;
3435 #endif
3436 #ifdef LIBXML_SCHEMATRON_ENABLED
3437 	} else if ((!strcmp(argv[i], "-schematron")) ||
3438 	         (!strcmp(argv[i], "--schematron"))) {
3439 	    i++;
3440 	    schematron = argv[i];
3441 	    noent++;
3442 #endif
3443         } else if ((!strcmp(argv[i], "-nonet")) ||
3444                    (!strcmp(argv[i], "--nonet"))) {
3445 	    options |= XML_PARSE_NONET;
3446 	    xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
3447         } else if ((!strcmp(argv[i], "-nocompact")) ||
3448                    (!strcmp(argv[i], "--nocompact"))) {
3449 	    options &= ~XML_PARSE_COMPACT;
3450 	} else if ((!strcmp(argv[i], "-load-trace")) ||
3451 	           (!strcmp(argv[i], "--load-trace"))) {
3452 	    load_trace++;
3453         } else if ((!strcmp(argv[i], "-path")) ||
3454                    (!strcmp(argv[i], "--path"))) {
3455 	    i++;
3456 	    parsePath(BAD_CAST argv[i]);
3457 #ifdef LIBXML_PATTERN_ENABLED
3458         } else if ((!strcmp(argv[i], "-pattern")) ||
3459                    (!strcmp(argv[i], "--pattern"))) {
3460 	    i++;
3461 	    pattern = argv[i];
3462 #endif
3463 #ifdef LIBXML_XPATH_ENABLED
3464         } else if ((!strcmp(argv[i], "-xpath")) ||
3465                    (!strcmp(argv[i], "--xpath"))) {
3466 	    i++;
3467 	    noout++;
3468 	    xpathquery = argv[i];
3469 #endif
3470 	} else if ((!strcmp(argv[i], "-oldxml10")) ||
3471 	           (!strcmp(argv[i], "--oldxml10"))) {
3472 	    oldxml10++;
3473 	    options |= XML_PARSE_OLD10;
3474 	} else {
3475 	    fprintf(stderr, "Unknown option %s\n", argv[i]);
3476 	    usage(stderr, argv[0]);
3477 	    return(1);
3478 	}
3479     }
3480 
3481 #ifdef LIBXML_CATALOG_ENABLED
3482     if (nocatalogs == 0) {
3483 	if (catalogs) {
3484 	    const char *catal;
3485 
3486 	    catal = getenv("SGML_CATALOG_FILES");
3487 	    if (catal != NULL) {
3488 		xmlLoadCatalogs(catal);
3489 	    } else {
3490 		fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3491 	    }
3492 	}
3493     }
3494 #endif
3495 
3496 #ifdef LIBXML_SAX1_ENABLED
3497     if (sax1)
3498         xmlSAXDefaultVersion(1);
3499     else
3500         xmlSAXDefaultVersion(2);
3501 #endif /* LIBXML_SAX1_ENABLED */
3502 
3503     if (chkregister) {
3504 	xmlRegisterNodeDefault(registerNode);
3505 	xmlDeregisterNodeDefault(deregisterNode);
3506     }
3507 
3508     indent = getenv("XMLLINT_INDENT");
3509     if(indent != NULL) {
3510 	xmlTreeIndentString = indent;
3511     }
3512 
3513 
3514     defaultEntityLoader = xmlGetExternalEntityLoader();
3515     xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3516 
3517     xmlLineNumbersDefault(1);
3518     if (loaddtd != 0)
3519 	xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3520     if (dtdattrs)
3521 	xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
3522     if (noent != 0) xmlSubstituteEntitiesDefault(1);
3523 #ifdef LIBXML_VALID_ENABLED
3524     if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
3525 #endif /* LIBXML_VALID_ENABLED */
3526     if ((htmlout) && (!nowrap)) {
3527 	xmlGenericError(xmlGenericErrorContext,
3528          "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
3529 	xmlGenericError(xmlGenericErrorContext,
3530 		"\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3531 	xmlGenericError(xmlGenericErrorContext,
3532 	 "<html><head><title>%s output</title></head>\n",
3533 		argv[0]);
3534 	xmlGenericError(xmlGenericErrorContext,
3535 	 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3536 		argv[0]);
3537     }
3538 
3539 #ifdef LIBXML_SCHEMATRON_ENABLED
3540     if ((schematron != NULL) && (sax == 0)
3541 #ifdef LIBXML_READER_ENABLED
3542         && (stream == 0)
3543 #endif /* LIBXML_READER_ENABLED */
3544 	) {
3545 	xmlSchematronParserCtxtPtr ctxt;
3546 
3547         /* forces loading the DTDs */
3548         xmlLoadExtDtdDefaultValue |= 1;
3549 	options |= XML_PARSE_DTDLOAD;
3550 	if (timing) {
3551 	    startTimer();
3552 	}
3553 	ctxt = xmlSchematronNewParserCtxt(schematron);
3554 #if 0
3555 	xmlSchematronSetParserErrors(ctxt,
3556 		(xmlSchematronValidityErrorFunc) fprintf,
3557 		(xmlSchematronValidityWarningFunc) fprintf,
3558 		stderr);
3559 #endif
3560 	wxschematron = xmlSchematronParse(ctxt);
3561 	if (wxschematron == NULL) {
3562 	    xmlGenericError(xmlGenericErrorContext,
3563 		    "Schematron schema %s failed to compile\n", schematron);
3564             progresult = XMLLINT_ERR_SCHEMACOMP;
3565 	    schematron = NULL;
3566 	}
3567 	xmlSchematronFreeParserCtxt(ctxt);
3568 	if (timing) {
3569 	    endTimer("Compiling the schemas");
3570 	}
3571     }
3572 #endif
3573 #ifdef LIBXML_SCHEMAS_ENABLED
3574     if ((relaxng != NULL) && (sax == 0)
3575 #ifdef LIBXML_READER_ENABLED
3576         && (stream == 0)
3577 #endif /* LIBXML_READER_ENABLED */
3578 	) {
3579 	xmlRelaxNGParserCtxtPtr ctxt;
3580 
3581         /* forces loading the DTDs */
3582         xmlLoadExtDtdDefaultValue |= 1;
3583 	options |= XML_PARSE_DTDLOAD;
3584 	if (timing) {
3585 	    startTimer();
3586 	}
3587 	ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3588 	xmlRelaxNGSetParserErrors(ctxt,
3589 		(xmlRelaxNGValidityErrorFunc) fprintf,
3590 		(xmlRelaxNGValidityWarningFunc) fprintf,
3591 		stderr);
3592 	relaxngschemas = xmlRelaxNGParse(ctxt);
3593 	if (relaxngschemas == NULL) {
3594 	    xmlGenericError(xmlGenericErrorContext,
3595 		    "Relax-NG schema %s failed to compile\n", relaxng);
3596             progresult = XMLLINT_ERR_SCHEMACOMP;
3597 	    relaxng = NULL;
3598 	}
3599 	xmlRelaxNGFreeParserCtxt(ctxt);
3600 	if (timing) {
3601 	    endTimer("Compiling the schemas");
3602 	}
3603     } else if ((schema != NULL)
3604 #ifdef LIBXML_READER_ENABLED
3605 		&& (stream == 0)
3606 #endif
3607 	) {
3608 	xmlSchemaParserCtxtPtr ctxt;
3609 
3610 	if (timing) {
3611 	    startTimer();
3612 	}
3613 	ctxt = xmlSchemaNewParserCtxt(schema);
3614 	xmlSchemaSetParserErrors(ctxt,
3615 		(xmlSchemaValidityErrorFunc) fprintf,
3616 		(xmlSchemaValidityWarningFunc) fprintf,
3617 		stderr);
3618 	wxschemas = xmlSchemaParse(ctxt);
3619 	if (wxschemas == NULL) {
3620 	    xmlGenericError(xmlGenericErrorContext,
3621 		    "WXS schema %s failed to compile\n", schema);
3622             progresult = XMLLINT_ERR_SCHEMACOMP;
3623 	    schema = NULL;
3624 	}
3625 	xmlSchemaFreeParserCtxt(ctxt);
3626 	if (timing) {
3627 	    endTimer("Compiling the schemas");
3628 	}
3629     }
3630 #endif /* LIBXML_SCHEMAS_ENABLED */
3631 #ifdef LIBXML_PATTERN_ENABLED
3632     if ((pattern != NULL)
3633 #ifdef LIBXML_READER_ENABLED
3634         && (walker == 0)
3635 #endif
3636 	) {
3637         patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
3638 	if (patternc == NULL) {
3639 	    xmlGenericError(xmlGenericErrorContext,
3640 		    "Pattern %s failed to compile\n", pattern);
3641             progresult = XMLLINT_ERR_SCHEMAPAT;
3642 	    pattern = NULL;
3643 	}
3644     }
3645 #endif /* LIBXML_PATTERN_ENABLED */
3646     for (i = 1; i < argc ; i++) {
3647 	if ((!strcmp(argv[i], "-encode")) ||
3648 	         (!strcmp(argv[i], "--encode"))) {
3649 	    i++;
3650 	    continue;
3651         } else if ((!strcmp(argv[i], "-o")) ||
3652                    (!strcmp(argv[i], "-output")) ||
3653                    (!strcmp(argv[i], "--output"))) {
3654             i++;
3655 	    continue;
3656         }
3657 #ifdef LIBXML_VALID_ENABLED
3658 	if ((!strcmp(argv[i], "-dtdvalid")) ||
3659 	         (!strcmp(argv[i], "--dtdvalid"))) {
3660 	    i++;
3661 	    continue;
3662         }
3663 	if ((!strcmp(argv[i], "-path")) ||
3664                    (!strcmp(argv[i], "--path"))) {
3665             i++;
3666 	    continue;
3667         }
3668 	if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3669 	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
3670 	    i++;
3671 	    continue;
3672         }
3673 #endif /* LIBXML_VALID_ENABLED */
3674 	if ((!strcmp(argv[i], "-relaxng")) ||
3675 	         (!strcmp(argv[i], "--relaxng"))) {
3676 	    i++;
3677 	    continue;
3678         }
3679 	if ((!strcmp(argv[i], "-maxmem")) ||
3680 	         (!strcmp(argv[i], "--maxmem"))) {
3681 	    i++;
3682 	    continue;
3683         }
3684 	if ((!strcmp(argv[i], "-pretty")) ||
3685 	         (!strcmp(argv[i], "--pretty"))) {
3686 	    i++;
3687 	    continue;
3688         }
3689 	if ((!strcmp(argv[i], "-schema")) ||
3690 	         (!strcmp(argv[i], "--schema"))) {
3691 	    i++;
3692 	    continue;
3693         }
3694 	if ((!strcmp(argv[i], "-schematron")) ||
3695 	         (!strcmp(argv[i], "--schematron"))) {
3696 	    i++;
3697 	    continue;
3698         }
3699 #ifdef LIBXML_PATTERN_ENABLED
3700         if ((!strcmp(argv[i], "-pattern")) ||
3701 	    (!strcmp(argv[i], "--pattern"))) {
3702 	    i++;
3703 	    continue;
3704 	}
3705 #endif
3706 #ifdef LIBXML_XPATH_ENABLED
3707         if ((!strcmp(argv[i], "-xpath")) ||
3708 	    (!strcmp(argv[i], "--xpath"))) {
3709 	    i++;
3710 	    continue;
3711 	}
3712 #endif
3713 	if ((timing) && (repeat))
3714 	    startTimer();
3715 	/* Remember file names.  "-" means stdin.  <sven@zen.org> */
3716 	if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
3717 	    if (repeat) {
3718 		xmlParserCtxtPtr ctxt = NULL;
3719 
3720 		for (acount = 0;acount < repeat;acount++) {
3721 #ifdef LIBXML_READER_ENABLED
3722 		    if (stream != 0) {
3723 			streamFile(argv[i]);
3724 		    } else {
3725 #endif /* LIBXML_READER_ENABLED */
3726                         if (sax) {
3727 			    testSAX(argv[i]);
3728 			} else {
3729 			    if (ctxt == NULL)
3730 				ctxt = xmlNewParserCtxt();
3731 			    parseAndPrintFile(argv[i], ctxt);
3732 			}
3733 #ifdef LIBXML_READER_ENABLED
3734 		    }
3735 #endif /* LIBXML_READER_ENABLED */
3736 		}
3737 		if (ctxt != NULL)
3738 		    xmlFreeParserCtxt(ctxt);
3739 	    } else {
3740 		nbregister = 0;
3741 
3742 #ifdef LIBXML_READER_ENABLED
3743 		if (stream != 0)
3744 		    streamFile(argv[i]);
3745 		else
3746 #endif /* LIBXML_READER_ENABLED */
3747                 if (sax) {
3748 		    testSAX(argv[i]);
3749 		} else {
3750 		    parseAndPrintFile(argv[i], NULL);
3751 		}
3752 
3753                 if ((chkregister) && (nbregister != 0)) {
3754 		    fprintf(stderr, "Registration count off: %d\n", nbregister);
3755 		    progresult = XMLLINT_ERR_RDREGIS;
3756 		}
3757 	    }
3758 	    files ++;
3759 	    if ((timing) && (repeat)) {
3760 		endTimer("%d iterations", repeat);
3761 	    }
3762 	}
3763     }
3764     if (generate)
3765 	parseAndPrintFile(NULL, NULL);
3766     if ((htmlout) && (!nowrap)) {
3767 	xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
3768     }
3769     if ((files == 0) && (!generate) && (version == 0)) {
3770 	usage(stderr, argv[0]);
3771     }
3772 #ifdef LIBXML_SCHEMATRON_ENABLED
3773     if (wxschematron != NULL)
3774 	xmlSchematronFree(wxschematron);
3775 #endif
3776 #ifdef LIBXML_SCHEMAS_ENABLED
3777     if (relaxngschemas != NULL)
3778 	xmlRelaxNGFree(relaxngschemas);
3779     if (wxschemas != NULL)
3780 	xmlSchemaFree(wxschemas);
3781     xmlRelaxNGCleanupTypes();
3782 #endif
3783 #ifdef LIBXML_PATTERN_ENABLED
3784     if (patternc != NULL)
3785         xmlFreePattern(patternc);
3786 #endif
3787     xmlCleanupParser();
3788     xmlMemoryDump();
3789 
3790     return(progresult);
3791 }
3792 
3793