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