VirtualBox

source: vbox/trunk/src/libs/libxml2-2.12.6/xmllint.c

Last change on this file was 104106, checked in by vboxsync, 8 weeks ago

libxml2-2.9.14: Applied and adjusted our libxml2 changes to 2.9.14. bugref:10640

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

© 2023 Oracle
ContactPrivacy policyTerms of Use