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