missing project/build files
[client-tools.git] / src / external / 3rd / library / libxml / xmllint.c
blobfce097f12345c26ece53555654085cbf6f67e9d6
1 /*
2 * xmllint.c : a small tester program for XML input.
4 * See Copyright for the status of this software.
6 * daniel@veillard.com
7 */
9 #include "libxml.h"
11 #include <string.h>
12 #include <stdarg.h>
14 #if defined (_WIN32) && !defined(__CYGWIN__)
15 #ifdef _MSC_VER
16 #include <winsock2.h>
17 #pragma comment(lib, "ws2_32.lib")
18 #define gettimeofday(p1,p2)
19 #include <time.h>
20 #else /* _MSC_VER */
21 #include <sys/time.h>
22 #endif /* _MSC_VER */
23 #else /* _WIN32 */
24 #ifdef HAVE_SYS_TIME_H
25 #include <sys/time.h>
26 #endif
27 #ifdef HAVE_TIME_H
28 #include <time.h>
29 #endif
30 #endif /* _WIN32 */
32 #ifdef HAVE_SYS_TIMEB_H
33 #include <sys/timeb.h>
34 #endif
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45 #ifdef HAVE_UNISTD_H
46 #include <unistd.h>
47 #endif
48 #ifdef HAVE_SYS_MMAN_H
49 #include <sys/mman.h>
50 /* seems needed for Solaris */
51 #ifndef MAP_FAILED
52 #define MAP_FAILED ((void *) -1)
53 #endif
54 #endif
55 #ifdef HAVE_STDLIB_H
56 #include <stdlib.h>
57 #endif
58 #ifdef HAVE_LIBREADLINE
59 #include <readline/readline.h>
60 #ifdef HAVE_LIBHISTORY
61 #include <readline/history.h>
62 #endif
63 #endif
65 #include <libxml/xmlmemory.h>
66 #include <libxml/parser.h>
67 #include <libxml/parserInternals.h>
68 #include <libxml/HTMLparser.h>
69 #include <libxml/HTMLtree.h>
70 #include <libxml/tree.h>
71 #include <libxml/xpath.h>
72 #include <libxml/debugXML.h>
73 #include <libxml/xmlerror.h>
74 #ifdef LIBXML_XINCLUDE_ENABLED
75 #include <libxml/xinclude.h>
76 #endif
77 #ifdef LIBXML_CATALOG_ENABLED
78 #include <libxml/catalog.h>
79 #endif
80 #ifdef LIBXML_DOCB_ENABLED
81 #include <libxml/DOCBparser.h>
82 #endif
83 #include <libxml/globals.h>
85 #ifdef LIBXML_DEBUG_ENABLED
86 static int debug = 0;
87 static int shell = 0;
88 static int debugent = 0;
89 #endif
90 static int copy = 0;
91 static int recovery = 0;
92 static int noent = 0;
93 static int noout = 0;
94 static int nowrap = 0;
95 static int valid = 0;
96 static int postvalid = 0;
97 static char * dtdvalid = NULL;
98 static int repeat = 0;
99 static int insert = 0;
100 static int compress = 0;
101 #ifdef LIBXML_DOCB_ENABLED
102 static int sgml = 0;
103 #endif
104 static int html = 0;
105 static int htmlout = 0;
106 static int push = 0;
107 #ifdef HAVE_SYS_MMAN_H
108 static int memory = 0;
109 #endif
110 static int noblanks = 0;
111 static int format = 0;
112 static int testIO = 0;
113 static char *encoding = NULL;
114 #ifdef LIBXML_XINCLUDE_ENABLED
115 static int xinclude = 0;
116 #endif
117 static int dtdattrs = 0;
118 static int loaddtd = 0;
119 static int progresult = 0;
120 static int timing = 0;
121 static int generate = 0;
122 static int dropdtd = 0;
123 #ifdef LIBXML_CATALOG_ENABLED
124 static int catalogs = 0;
125 static int nocatalogs = 0;
126 #endif
127 static const char *output = NULL;
131 * Internal timing routines to remove the necessity to have unix-specific
132 * function calls
135 #ifndef HAVE_GETTIMEOFDAY
136 #ifdef HAVE_SYS_TIMEB_H
137 #ifdef HAVE_SYS_TIME_H
138 #ifdef HAVE_FTIME
141 my_gettimeofday(struct timeval *tvp, void *tzp)
143 struct timeb timebuffer;
145 ftime(&timebuffer);
146 if (tvp) {
147 tvp->tv_sec = timebuffer.time;
148 tvp->tv_usec = timebuffer.millitm * 1000L;
150 return (0);
152 #define HAVE_GETTIMEOFDAY 1
153 #define gettimeofday my_gettimeofday
155 #endif /* HAVE_FTIME */
156 #endif /* HAVE_SYS_TIME_H */
157 #endif /* HAVE_SYS_TIMEB_H */
158 #endif /* !HAVE_GETTIMEOFDAY */
160 #if defined(HAVE_GETTIMEOFDAY)
161 static struct timeval begin, end;
164 * startTimer: call where you want to start timing
166 static void
167 startTimer(void)
169 gettimeofday(&begin, NULL);
173 * endTimer: call where you want to stop timing and to print out a
174 * message about the timing performed; format is a printf
175 * type argument
177 static void
178 endTimer(const char *fmt, ...)
180 long msec;
181 va_list ap;
183 gettimeofday(&end, NULL);
184 msec = end.tv_sec - begin.tv_sec;
185 msec *= 1000;
186 msec += (end.tv_usec - begin.tv_usec) / 1000;
188 #ifndef HAVE_STDARG_H
189 #error "endTimer required stdarg functions"
190 #endif
191 va_start(ap, fmt);
192 vfprintf(stderr, fmt, ap);
193 va_end(ap);
195 fprintf(stderr, " took %ld ms\n", msec);
197 #elif defined(HAVE_TIME_H)
199 * No gettimeofday function, so we have to make do with calling clock.
200 * This is obviously less accurate, but there's little we can do about
201 * that.
203 #ifndef CLOCKS_PER_SEC
204 #define CLOCKS_PER_SEC 100
205 #endif
207 static clock_t begin, end;
208 static void
209 startTimer(void)
211 begin = clock();
213 static void
214 endTimer(const char *fmt, ...)
216 long msec;
217 va_list ap;
219 end = clock();
220 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
222 #ifndef HAVE_STDARG_H
223 #error "endTimer required stdarg functions"
224 #endif
225 va_start(ap, fmt);
226 vfprintf(stderr, fmt, ap);
227 va_end(ap);
228 fprintf(stderr, " took %ld ms\n", msec);
230 #else
233 * We don't have a gettimeofday or time.h, so we just don't do timing
235 static void
236 startTimer(void)
239 * Do nothing
242 static void
243 endTimer(char *format, ...)
246 * We cannot do anything because we don't have a timing function
248 #ifdef HAVE_STDARG_H
249 va_start(ap, format);
250 vfprintf(stderr, format, ap);
251 va_end(ap);
252 fprintf(stderr, " was not timed\n", msec);
253 #else
254 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
255 * this ?!
257 #endif
259 #endif
260 /************************************************************************
262 * HTML ouput *
264 ************************************************************************/
265 char buffer[50000];
267 static void
268 xmlHTMLEncodeSend(void) {
269 char *result;
271 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
272 if (result) {
273 xmlGenericError(xmlGenericErrorContext, "%s", result);
274 xmlFree(result);
276 buffer[0] = 0;
280 * xmlHTMLPrintFileInfo:
281 * @input: an xmlParserInputPtr input
283 * Displays the associated file and line informations for the current input
286 static void
287 xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
288 int len;
289 xmlGenericError(xmlGenericErrorContext, "<p>");
291 len = strlen(buffer);
292 if (input != NULL) {
293 if (input->filename) {
294 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
295 input->line);
296 } else {
297 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
300 xmlHTMLEncodeSend();
304 * xmlHTMLPrintFileContext:
305 * @input: an xmlParserInputPtr input
307 * Displays current context within the input content for error tracking
310 static void
311 xmlHTMLPrintFileContext(xmlParserInputPtr input) {
312 const xmlChar *cur, *base;
313 int len;
314 int n;
316 if (input == NULL) return;
317 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
318 cur = input->cur;
319 base = input->base;
320 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
321 cur--;
323 n = 0;
324 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
325 cur--;
326 if ((*cur == '\n') || (*cur == '\r')) cur++;
327 base = cur;
328 n = 0;
329 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
330 len = strlen(buffer);
331 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
332 (unsigned char) *cur++);
333 n++;
335 len = strlen(buffer);
336 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
337 cur = input->cur;
338 while ((*cur == '\n') || (*cur == '\r'))
339 cur--;
340 n = 0;
341 while ((cur != base) && (n++ < 80)) {
342 len = strlen(buffer);
343 snprintf(&buffer[len], sizeof(buffer) - len, " ");
344 base++;
346 len = strlen(buffer);
347 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
348 xmlHTMLEncodeSend();
349 xmlGenericError(xmlGenericErrorContext, "</pre>");
353 * xmlHTMLError:
354 * @ctx: an XML parser context
355 * @msg: the message to display/transmit
356 * @...: extra parameters for the message display
358 * Display and format an error messages, gives file, line, position and
359 * extra parameters.
361 static void
362 xmlHTMLError(void *ctx, const char *msg, ...)
364 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
365 xmlParserInputPtr input;
366 xmlParserInputPtr cur = NULL;
367 va_list args;
368 int len;
370 buffer[0] = 0;
371 input = ctxt->input;
372 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
373 cur = input;
374 input = ctxt->inputTab[ctxt->inputNr - 2];
377 xmlHTMLPrintFileInfo(input);
379 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
380 va_start(args, msg);
381 len = strlen(buffer);
382 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
383 va_end(args);
384 xmlHTMLEncodeSend();
385 xmlGenericError(xmlGenericErrorContext, "</p>\n");
387 xmlHTMLPrintFileContext(input);
388 xmlHTMLEncodeSend();
392 * xmlHTMLWarning:
393 * @ctx: an XML parser context
394 * @msg: the message to display/transmit
395 * @...: extra parameters for the message display
397 * Display and format a warning messages, gives file, line, position and
398 * extra parameters.
400 static void
401 xmlHTMLWarning(void *ctx, const char *msg, ...)
403 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
404 xmlParserInputPtr input;
405 xmlParserInputPtr cur = NULL;
406 va_list args;
407 int len;
409 buffer[0] = 0;
410 input = ctxt->input;
411 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
412 cur = input;
413 input = ctxt->inputTab[ctxt->inputNr - 2];
417 xmlHTMLPrintFileInfo(input);
419 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
420 va_start(args, msg);
421 len = strlen(buffer);
422 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
423 va_end(args);
424 xmlHTMLEncodeSend();
425 xmlGenericError(xmlGenericErrorContext, "</p>\n");
427 xmlHTMLPrintFileContext(input);
428 xmlHTMLEncodeSend();
432 * xmlHTMLValidityError:
433 * @ctx: an XML parser context
434 * @msg: the message to display/transmit
435 * @...: extra parameters for the message display
437 * Display and format an validity error messages, gives file,
438 * line, position and extra parameters.
440 static void
441 xmlHTMLValidityError(void *ctx, const char *msg, ...)
443 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
444 xmlParserInputPtr input;
445 va_list args;
446 int len;
448 buffer[0] = 0;
449 input = ctxt->input;
450 if ((input->filename == NULL) && (ctxt->inputNr > 1))
451 input = ctxt->inputTab[ctxt->inputNr - 2];
453 xmlHTMLPrintFileInfo(input);
455 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
456 len = strlen(buffer);
457 va_start(args, msg);
458 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
459 va_end(args);
460 xmlHTMLEncodeSend();
461 xmlGenericError(xmlGenericErrorContext, "</p>\n");
463 xmlHTMLPrintFileContext(input);
464 xmlHTMLEncodeSend();
468 * xmlHTMLValidityWarning:
469 * @ctx: an XML parser context
470 * @msg: the message to display/transmit
471 * @...: extra parameters for the message display
473 * Display and format a validity warning messages, gives file, line,
474 * position and extra parameters.
476 static void
477 xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
479 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
480 xmlParserInputPtr input;
481 va_list args;
482 int len;
484 buffer[0] = 0;
485 input = ctxt->input;
486 if ((input->filename == NULL) && (ctxt->inputNr > 1))
487 input = ctxt->inputTab[ctxt->inputNr - 2];
489 xmlHTMLPrintFileInfo(input);
491 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
492 va_start(args, msg);
493 len = strlen(buffer);
494 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
495 va_end(args);
496 xmlHTMLEncodeSend();
497 xmlGenericError(xmlGenericErrorContext, "</p>\n");
499 xmlHTMLPrintFileContext(input);
500 xmlHTMLEncodeSend();
503 /************************************************************************
505 * Shell Interface *
507 ************************************************************************/
509 * xmlShellReadline:
510 * @prompt: the prompt value
512 * Read a string
514 * Returns a pointer to it or NULL on EOF the caller is expected to
515 * free the returned string.
517 static char *
518 xmlShellReadline(char *prompt) {
519 #ifdef HAVE_LIBREADLINE
520 char *line_read;
522 /* Get a line from the user. */
523 line_read = readline (prompt);
525 /* If the line has any text in it, save it on the history. */
526 if (line_read && *line_read)
527 add_history (line_read);
529 return (line_read);
530 #else
531 char line_read[501];
532 char *ret;
533 int len;
535 if (prompt != NULL)
536 fprintf(stdout, "%s", prompt);
537 if (!fgets(line_read, 500, stdin))
538 return(NULL);
539 line_read[500] = 0;
540 len = strlen(line_read);
541 ret = (char *) malloc(len + 1);
542 if (ret != NULL) {
543 memcpy (ret, line_read, len + 1);
545 return(ret);
546 #endif
549 /************************************************************************
551 * I/O Interfaces *
553 ************************************************************************/
555 static int myRead(FILE *f, char * buf, int len) {
556 return(fread(buf, 1, len, f));
558 static void myClose(FILE *f) {
559 if (f != stdin) {
560 fclose(f);
564 /************************************************************************
566 * Test processing *
568 ************************************************************************/
569 static void parseAndPrintFile(char *filename) {
570 xmlDocPtr doc = NULL, tmp;
572 if ((timing) && (!repeat))
573 startTimer();
576 if (filename == NULL) {
577 if (generate) {
578 xmlNodePtr n;
580 doc = xmlNewDoc(BAD_CAST "1.0");
581 n = xmlNewNode(NULL, BAD_CAST "info");
582 xmlNodeSetContent(n, BAD_CAST "abc");
583 xmlDocSetRootElement(doc, n);
586 #ifdef LIBXML_DOCB_ENABLED
588 * build an SGML tree from a string;
590 else if ((sgml) && (push)) {
591 FILE *f;
593 f = fopen(filename, "r");
594 if (f != NULL) {
595 int res, size = 3;
596 char chars[4096];
597 docbParserCtxtPtr ctxt;
599 /* if (repeat) */
600 size = 4096;
601 res = fread(chars, 1, 4, f);
602 if (res > 0) {
603 ctxt = docbCreatePushParserCtxt(NULL, NULL,
604 chars, res, filename, 0);
605 while ((res = fread(chars, 1, size, f)) > 0) {
606 docbParseChunk(ctxt, chars, res, 0);
608 docbParseChunk(ctxt, chars, 0, 1);
609 doc = ctxt->myDoc;
610 docbFreeParserCtxt(ctxt);
612 fclose(f);
614 } else if (sgml) {
615 doc = docbParseFile(filename, NULL);
617 #endif
618 #ifdef LIBXML_HTML_ENABLED
619 else if (html) {
620 doc = htmlParseFile(filename, NULL);
622 #endif /* LIBXML_HTML_ENABLED */
623 else {
625 * build an XML tree from a string;
627 if (push) {
628 FILE *f;
630 /* '-' Usually means stdin -<sven@zen.org> */
631 if ((filename[0] == '-') && (filename[1] == 0)) {
632 f = stdin;
633 } else {
634 f = fopen(filename, "r");
636 if (f != NULL) {
637 int ret;
638 int res, size = 3;
639 char chars[1024];
640 xmlParserCtxtPtr ctxt;
642 if (repeat)
643 size = 1024;
644 res = fread(chars, 1, 4, f);
645 if (res > 0) {
646 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
647 chars, res, filename);
648 while ((res = fread(chars, 1, size, f)) > 0) {
649 xmlParseChunk(ctxt, chars, res, 0);
651 xmlParseChunk(ctxt, chars, 0, 1);
652 doc = ctxt->myDoc;
653 ret = ctxt->wellFormed;
654 xmlFreeParserCtxt(ctxt);
655 if (!ret) {
656 xmlFreeDoc(doc);
657 doc = NULL;
661 } else if (testIO) {
662 int ret;
663 FILE *f;
665 /* '-' Usually means stdin -<sven@zen.org> */
666 if ((filename[0] == '-') && (filename[1] == 0)) {
667 f = stdin;
668 } else {
669 f = fopen(filename, "r");
671 if (f != NULL) {
672 xmlParserCtxtPtr ctxt;
674 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
675 (xmlInputReadCallback) myRead,
676 (xmlInputCloseCallback) myClose,
677 f, XML_CHAR_ENCODING_NONE);
678 xmlParseDocument(ctxt);
680 ret = ctxt->wellFormed;
681 doc = ctxt->myDoc;
682 xmlFreeParserCtxt(ctxt);
683 if (!ret) {
684 xmlFreeDoc(doc);
685 doc = NULL;
688 } else if (recovery) {
689 doc = xmlRecoverFile(filename);
690 } else if (htmlout) {
691 int ret;
692 xmlParserCtxtPtr ctxt;
693 xmlSAXHandler silent, *old;
695 ctxt = xmlCreateFileParserCtxt(filename);
697 if (ctxt == NULL) {
698 /* If xmlCreateFileParserCtxt() return NULL something
699 strange happened so we don't want to do anything. Do
700 we want to print an error message here?
701 <sven@zen.org> */
702 doc = NULL;
703 } else {
704 memcpy(&silent, ctxt->sax, sizeof(silent));
705 old = ctxt->sax;
706 silent.error = xmlHTMLError;
707 if (xmlGetWarningsDefaultValue)
708 silent.warning = xmlHTMLWarning;
709 else
710 silent.warning = NULL;
711 silent.fatalError = xmlHTMLError;
712 ctxt->sax = &silent;
713 ctxt->vctxt.error = xmlHTMLValidityError;
714 if (xmlGetWarningsDefaultValue)
715 ctxt->vctxt.warning = xmlHTMLValidityWarning;
716 else
717 ctxt->vctxt.warning = NULL;
719 xmlParseDocument(ctxt);
721 ret = ctxt->wellFormed;
722 doc = ctxt->myDoc;
723 ctxt->sax = old;
724 xmlFreeParserCtxt(ctxt);
725 if (!ret) {
726 xmlFreeDoc(doc);
727 doc = NULL;
730 #ifdef HAVE_SYS_MMAN_H
731 } else if (memory) {
732 int fd;
733 struct stat info;
734 const char *base;
735 if (stat(filename, &info) < 0)
736 return;
737 if ((fd = open(filename, O_RDONLY)) < 0)
738 return;
739 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
740 if (base == (void *) MAP_FAILED)
741 return;
743 doc = xmlParseMemory((char *) base, info.st_size);
744 munmap((char *) base, info.st_size);
745 #endif
746 } else
747 doc = xmlParseFile(filename);
751 * If we don't have a document we might as well give up. Do we
752 * want an error message here? <sven@zen.org> */
753 if (doc == NULL) {
754 progresult = 1;
755 return;
758 if ((timing) && (!repeat)) {
759 endTimer("Parsing");
763 * Remove DOCTYPE nodes
765 if (dropdtd) {
766 xmlDtdPtr dtd;
768 dtd = xmlGetIntSubset(doc);
769 if (dtd != NULL) {
770 xmlUnlinkNode((xmlNodePtr)dtd);
771 xmlFreeDtd(dtd);
775 #ifdef LIBXML_XINCLUDE_ENABLED
776 if (xinclude) {
777 if ((timing) && (!repeat)) {
778 startTimer();
780 xmlXIncludeProcess(doc);
781 if ((timing) && (!repeat)) {
782 endTimer("Xinclude processing");
785 #endif
787 #ifdef LIBXML_DEBUG_ENABLED
789 * shell interaction
791 if (shell)
792 xmlShell(doc, filename, xmlShellReadline, stdout);
793 #endif
796 * test intermediate copy if needed.
798 if (copy) {
799 tmp = doc;
800 doc = xmlCopyDoc(doc, 1);
801 xmlFreeDoc(tmp);
804 if ((insert) && (!html)) {
805 const xmlChar* list[256];
806 int nb, i;
807 xmlNodePtr node;
809 if (doc->children != NULL) {
810 node = doc->children;
811 while ((node != NULL) && (node->last == NULL)) node = node->next;
812 if (node != NULL) {
813 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
814 if (nb < 0) {
815 printf("could not get valid list of elements\n");
816 } else if (nb == 0) {
817 printf("No element can be inserted under root\n");
818 } else {
819 printf("%d element types can be inserted under root:\n",
820 nb);
821 for (i = 0;i < nb;i++) {
822 printf("%s\n", list[i]);
827 }else if (noout == 0) {
829 * print it.
831 #ifdef LIBXML_DEBUG_ENABLED
832 if (!debug) {
833 #endif
834 if ((timing) && (!repeat)) {
835 startTimer();
837 #ifdef HAVE_SYS_MMAN_H
838 if (memory) {
839 xmlChar *result;
840 int len;
842 if (encoding != NULL) {
843 if ( format ) {
844 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
845 } else {
846 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
848 } else {
849 if (format)
850 xmlDocDumpFormatMemory(doc, &result, &len, 1);
851 else
852 xmlDocDumpMemory(doc, &result, &len);
854 if (result == NULL) {
855 fprintf(stderr, "Failed to save\n");
856 } else {
857 write(1, result, len);
858 xmlFree(result);
860 } else
861 #endif /* HAVE_SYS_MMAN_H */
862 if (compress) {
863 xmlSaveFile(output ? output : "-", doc);
865 else if (encoding != NULL) {
866 if ( format ) {
867 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
869 else {
870 xmlSaveFileEnc(output ? output : "-", doc, encoding);
873 else if (format) {
874 xmlSaveFormatFile(output ? output : "-", doc, 1);
876 else {
877 FILE *out;
878 if (output == NULL)
879 out = stdout;
880 else {
881 out = fopen(output,"wb");
883 xmlDocDump(out, doc);
885 if (output)
886 fclose(out);
888 if ((timing) && (!repeat)) {
889 endTimer("Saving");
891 #ifdef LIBXML_DEBUG_ENABLED
892 } else {
893 FILE *out;
894 if (output == NULL)
895 out = stdout;
896 else {
897 out = fopen(output,"wb");
899 xmlDebugDumpDocument(out, doc);
901 if (output)
902 fclose(out);
904 #endif
908 * A posteriori validation test
910 if (dtdvalid != NULL) {
911 xmlDtdPtr dtd;
913 if ((timing) && (!repeat)) {
914 startTimer();
916 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
917 if ((timing) && (!repeat)) {
918 endTimer("Parsing DTD");
920 if (dtd == NULL) {
921 xmlGenericError(xmlGenericErrorContext,
922 "Could not parse DTD %s\n", dtdvalid);
923 progresult = 2;
924 } else {
925 xmlValidCtxt cvp;
926 if ((timing) && (!repeat)) {
927 startTimer();
929 cvp.userData = (void *) stderr;
930 cvp.error = (xmlValidityErrorFunc) fprintf;
931 cvp.warning = (xmlValidityWarningFunc) fprintf;
932 if (!xmlValidateDtd(&cvp, doc, dtd)) {
933 xmlGenericError(xmlGenericErrorContext,
934 "Document %s does not validate against %s\n",
935 filename, dtdvalid);
936 progresult = 3;
938 if ((timing) && (!repeat)) {
939 endTimer("Validating against DTD");
941 xmlFreeDtd(dtd);
943 } else if (postvalid) {
944 xmlValidCtxt cvp;
945 if ((timing) && (!repeat)) {
946 startTimer();
948 cvp.userData = (void *) stderr;
949 cvp.error = (xmlValidityErrorFunc) fprintf;
950 cvp.warning = (xmlValidityWarningFunc) fprintf;
951 if (!xmlValidateDocument(&cvp, doc)) {
952 xmlGenericError(xmlGenericErrorContext,
953 "Document %s does not validate\n", filename);
954 progresult = 3;
956 if ((timing) && (!repeat)) {
957 endTimer("Validating");
961 #ifdef LIBXML_DEBUG_ENABLED
962 if ((debugent) && (!html))
963 xmlDebugDumpEntities(stderr, doc);
964 #endif
967 * free it.
969 if ((timing) && (!repeat)) {
970 startTimer();
972 xmlFreeDoc(doc);
973 if ((timing) && (!repeat)) {
974 endTimer("Freeing");
978 /************************************************************************
980 * Usage and Main *
982 ************************************************************************/
984 static void showVersion(const char *name) {
985 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
986 fprintf(stderr, " compiled with: ");
987 #ifdef LIBXML_FTP_ENABLED
988 fprintf(stderr, "FTP ");
989 #endif
990 #ifdef LIBXML_HTTP_ENABLED
991 fprintf(stderr, "HTTP ");
992 #endif
993 #ifdef LIBXML_HTML_ENABLED
994 fprintf(stderr, "HTML ");
995 #endif
996 #ifdef LIBXML_C14N_ENABLED
997 fprintf(stderr, "C14N ");
998 #endif
999 #ifdef LIBXML_CATALOG_ENABLED
1000 fprintf(stderr, "Catalog ");
1001 #endif
1002 #ifdef LIBXML_DOCB_ENABLED
1003 fprintf(stderr, "DocBook ");
1004 #endif
1005 #ifdef LIBXML_XPATH_ENABLED
1006 fprintf(stderr, "XPath ");
1007 #endif
1008 #ifdef LIBXML_XPTR_ENABLED
1009 fprintf(stderr, "XPointer ");
1010 #endif
1011 #ifdef LIBXML_XINCLUDE_ENABLED
1012 fprintf(stderr, "XInclude ");
1013 #endif
1014 #ifdef LIBXML_ICONV_ENABLED
1015 fprintf(stderr, "Iconv ");
1016 #endif
1017 #ifdef DEBUG_MEMORY_LOCATION
1018 fprintf(stderr, "MemDebug ");
1019 #endif
1020 #ifdef LIBXML_UNICODE_ENABLED
1021 fprintf(stderr, "Unicode ");
1022 #endif
1023 #ifdef LIBXML_REGEXP_ENABLED
1024 fprintf(stderr, "Regexps ");
1025 #endif
1026 #ifdef LIBXML_AUTOMATA_ENABLED
1027 fprintf(stderr, "Automata ");
1028 #endif
1029 #ifdef LIBXML_SCHEMAS_ENABLED
1030 fprintf(stderr, "Schemas ");
1031 #endif
1032 fprintf(stderr, "\n");
1035 static void usage(const char *name) {
1036 printf("Usage : %s [options] XMLfiles ...\n", name);
1037 printf("\tParse the XML files and output the result of the parsing\n");
1038 printf("\t--version : display the version of the XML library used\n");
1039 #ifdef LIBXML_DEBUG_ENABLED
1040 printf("\t--debug : dump a debug tree of the in-memory document\n");
1041 printf("\t--shell : run a navigating shell\n");
1042 printf("\t--debugent : debug the entities defined in the document\n");
1043 #endif
1044 printf("\t--copy : used to test the internal copy implementation\n");
1045 printf("\t--recover : output what was parsable on broken XML documents\n");
1046 printf("\t--noent : substitute entity references by their value\n");
1047 printf("\t--noout : don't output the result tree\n");
1048 printf("\t--htmlout : output results as HTML\n");
1049 printf("\t--nowrap : do not put HTML doc wrapper\n");
1050 printf("\t--valid : validate the document in addition to std well-formed check\n");
1051 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1052 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
1053 printf("\t--timing : print some timings\n");
1054 printf("\t--output file or -o file: save to a given file\n");
1055 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1056 printf("\t--insert : ad-hoc test for valid insertions\n");
1057 #ifdef HAVE_ZLIB_H
1058 printf("\t--compress : turn on gzip compression of output\n");
1059 #endif
1060 #ifdef LIBXML_DOCB_ENABLED
1061 printf("\t--sgml : use the DocBook SGML parser\n");
1062 #endif
1063 #ifdef LIBXML_HTML_ENABLED
1064 printf("\t--html : use the HTML parser\n");
1065 #endif
1066 printf("\t--push : use the push mode of the parser\n");
1067 #ifdef HAVE_SYS_MMAN_H
1068 printf("\t--memory : parse from memory\n");
1069 #endif
1070 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1071 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
1072 printf("\t--format : reformat/reindent the input\n");
1073 printf("\t--testIO : test user I/O support\n");
1074 printf("\t--encode encoding : output in the given encoding\n");
1075 #ifdef LIBXML_CATALOG_ENABLED
1076 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1077 printf("\t otherwise XML Catalogs starting from \n");
1078 printf("\t file:///etc/xml/catalog are activated by default\n");
1079 printf("\t--nocatalogs: deactivate all catalogs\n");
1080 #endif
1081 printf("\t--auto : generate a small doc on the fly\n");
1082 #ifdef LIBXML_XINCLUDE_ENABLED
1083 printf("\t--xinclude : do XInclude processing\n");
1084 #endif
1085 printf("\t--loaddtd : fetch external DTD\n");
1086 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
1087 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
1088 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1089 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
1092 main(int argc, char **argv) {
1093 int i, count;
1094 int files = 0;
1095 int version = 0;
1097 if (argc <= 1) {
1098 usage(argv[0]);
1099 return(1);
1101 LIBXML_TEST_VERSION
1102 for (i = 1; i < argc ; i++) {
1103 if (!strcmp(argv[i], "-"))
1104 break;
1106 if (argv[i][0] != '-')
1107 continue;
1108 #ifdef LIBXML_DEBUG_ENABLED
1109 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1110 debug++;
1111 else if ((!strcmp(argv[i], "-shell")) ||
1112 (!strcmp(argv[i], "--shell"))) {
1113 shell++;
1114 noout = 1;
1115 } else
1116 #endif
1117 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1118 copy++;
1119 else if ((!strcmp(argv[i], "-recover")) ||
1120 (!strcmp(argv[i], "--recover")))
1121 recovery++;
1122 else if ((!strcmp(argv[i], "-noent")) ||
1123 (!strcmp(argv[i], "--noent")))
1124 noent++;
1125 else if ((!strcmp(argv[i], "-version")) ||
1126 (!strcmp(argv[i], "--version"))) {
1127 showVersion(argv[0]);
1128 version = 1;
1129 } else if ((!strcmp(argv[i], "-noout")) ||
1130 (!strcmp(argv[i], "--noout")))
1131 noout++;
1132 else if ((!strcmp(argv[i], "-o")) ||
1133 (!strcmp(argv[i], "-output")) ||
1134 (!strcmp(argv[i], "--output"))) {
1135 i++;
1136 output = argv[i];
1138 else if ((!strcmp(argv[i], "-htmlout")) ||
1139 (!strcmp(argv[i], "--htmlout")))
1140 htmlout++;
1141 #ifdef LIBXML_DOCB_ENABLED
1142 else if ((!strcmp(argv[i], "-sgml")) ||
1143 (!strcmp(argv[i], "--sgml"))) {
1144 sgml++;
1146 #endif
1147 #ifdef LIBXML_HTML_ENABLED
1148 else if ((!strcmp(argv[i], "-html")) ||
1149 (!strcmp(argv[i], "--html"))) {
1150 html++;
1152 #endif /* LIBXML_HTML_ENABLED */
1153 else if ((!strcmp(argv[i], "-nowrap")) ||
1154 (!strcmp(argv[i], "--nowrap")))
1155 nowrap++;
1156 else if ((!strcmp(argv[i], "-loaddtd")) ||
1157 (!strcmp(argv[i], "--loaddtd")))
1158 loaddtd++;
1159 else if ((!strcmp(argv[i], "-dtdattr")) ||
1160 (!strcmp(argv[i], "--dtdattr"))) {
1161 loaddtd++;
1162 dtdattrs++;
1163 } else if ((!strcmp(argv[i], "-valid")) ||
1164 (!strcmp(argv[i], "--valid")))
1165 valid++;
1166 else if ((!strcmp(argv[i], "-postvalid")) ||
1167 (!strcmp(argv[i], "--postvalid"))) {
1168 postvalid++;
1169 loaddtd++;
1170 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
1171 (!strcmp(argv[i], "--dtdvalid"))) {
1172 i++;
1173 dtdvalid = argv[i];
1174 loaddtd++;
1176 else if ((!strcmp(argv[i], "-dropdtd")) ||
1177 (!strcmp(argv[i], "--dropdtd")))
1178 dropdtd++;
1179 else if ((!strcmp(argv[i], "-insert")) ||
1180 (!strcmp(argv[i], "--insert")))
1181 insert++;
1182 else if ((!strcmp(argv[i], "-timing")) ||
1183 (!strcmp(argv[i], "--timing")))
1184 timing++;
1185 else if ((!strcmp(argv[i], "-auto")) ||
1186 (!strcmp(argv[i], "--auto")))
1187 generate++;
1188 else if ((!strcmp(argv[i], "-repeat")) ||
1189 (!strcmp(argv[i], "--repeat")))
1190 repeat++;
1191 else if ((!strcmp(argv[i], "-push")) ||
1192 (!strcmp(argv[i], "--push")))
1193 push++;
1194 #ifdef HAVE_SYS_MMAN_H
1195 else if ((!strcmp(argv[i], "-memory")) ||
1196 (!strcmp(argv[i], "--memory")))
1197 memory++;
1198 #endif
1199 else if ((!strcmp(argv[i], "-testIO")) ||
1200 (!strcmp(argv[i], "--testIO")))
1201 testIO++;
1202 #ifdef LIBXML_XINCLUDE_ENABLED
1203 else if ((!strcmp(argv[i], "-xinclude")) ||
1204 (!strcmp(argv[i], "--xinclude")))
1205 xinclude++;
1206 #endif
1207 #ifdef HAVE_ZLIB_H
1208 else if ((!strcmp(argv[i], "-compress")) ||
1209 (!strcmp(argv[i], "--compress"))) {
1210 compress++;
1211 xmlSetCompressMode(9);
1213 #endif
1214 else if ((!strcmp(argv[i], "-nowarning")) ||
1215 (!strcmp(argv[i], "--nowarning"))) {
1216 xmlGetWarningsDefaultValue = 0;
1217 xmlPedanticParserDefault(0);
1219 else if ((!strcmp(argv[i], "-pedantic")) ||
1220 (!strcmp(argv[i], "--pedantic"))) {
1221 xmlGetWarningsDefaultValue = 1;
1222 xmlPedanticParserDefault(1);
1224 #ifdef LIBXML_DEBUG_ENABLED
1225 else if ((!strcmp(argv[i], "-debugent")) ||
1226 (!strcmp(argv[i], "--debugent"))) {
1227 debugent++;
1228 xmlParserDebugEntities = 1;
1230 #endif
1231 #ifdef LIBXML_CATALOG_ENABLED
1232 else if ((!strcmp(argv[i], "-catalogs")) ||
1233 (!strcmp(argv[i], "--catalogs"))) {
1234 catalogs++;
1235 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1236 (!strcmp(argv[i], "--nocatalogs"))) {
1237 nocatalogs++;
1239 #endif
1240 else if ((!strcmp(argv[i], "-encode")) ||
1241 (!strcmp(argv[i], "--encode"))) {
1242 i++;
1243 encoding = argv[i];
1245 * OK it's for testing purposes
1247 xmlAddEncodingAlias("UTF-8", "DVEnc");
1249 else if ((!strcmp(argv[i], "-noblanks")) ||
1250 (!strcmp(argv[i], "--noblanks"))) {
1251 noblanks++;
1252 xmlKeepBlanksDefault(0);
1254 else if ((!strcmp(argv[i], "-format")) ||
1255 (!strcmp(argv[i], "--format"))) {
1256 noblanks++;
1257 format++;
1258 xmlKeepBlanksDefault(0);
1259 } else {
1260 fprintf(stderr, "Unknown option %s\n", argv[i]);
1261 usage(argv[0]);
1262 return(1);
1266 #ifdef LIBXML_CATALOG_ENABLED
1267 if (nocatalogs == 0) {
1268 if (catalogs) {
1269 const char *catal;
1271 catal = getenv("SGML_CATALOG_FILES");
1272 if (catal != NULL) {
1273 xmlLoadCatalogs(catal);
1274 } else {
1275 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1279 #endif
1280 xmlLineNumbersDefault(1);
1281 if (loaddtd != 0)
1282 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1283 if (dtdattrs)
1284 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
1285 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1286 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1287 if ((htmlout) && (!nowrap)) {
1288 xmlGenericError(xmlGenericErrorContext,
1289 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
1290 xmlGenericError(xmlGenericErrorContext,
1291 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1292 xmlGenericError(xmlGenericErrorContext,
1293 "<html><head><title>%s output</title></head>\n",
1294 argv[0]);
1295 xmlGenericError(xmlGenericErrorContext,
1296 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1297 argv[0]);
1299 for (i = 1; i < argc ; i++) {
1300 if ((!strcmp(argv[i], "-encode")) ||
1301 (!strcmp(argv[i], "--encode"))) {
1302 i++;
1303 continue;
1304 } else if ((!strcmp(argv[i], "-o")) ||
1305 (!strcmp(argv[i], "-output")) ||
1306 (!strcmp(argv[i], "--output"))) {
1307 i++;
1308 continue;
1310 if ((!strcmp(argv[i], "-dtdvalid")) ||
1311 (!strcmp(argv[i], "--dtdvalid"))) {
1312 i++;
1313 continue;
1315 if ((timing) && (repeat))
1316 startTimer();
1317 /* Remember file names. "-" means stdin. <sven@zen.org> */
1318 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
1319 if (repeat) {
1320 for (count = 0;count < 100 * repeat;count++)
1321 parseAndPrintFile(argv[i]);
1322 } else
1323 parseAndPrintFile(argv[i]);
1324 files ++;
1325 if ((timing) && (repeat)) {
1326 endTimer("100 iterations");
1330 if (generate)
1331 parseAndPrintFile(NULL);
1332 if ((htmlout) && (!nowrap)) {
1333 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
1335 if ((files == 0) && (!generate) && (version == 0)) {
1336 usage(argv[0]);
1338 xmlCleanupParser();
1339 xmlMemoryDump();
1341 return(progresult);