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