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