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