VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/xmllint.c@ 105681

最後變更 在這個檔案從105681是 105420,由 vboxsync 提交於 4 月 前

libxml2-2.12.6: Applied and adjusted our libxml2 changes to 2.12.6. bugref:10730

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette