blob: 3dd413a65b740a53f680098ddbfd65f650249abf [file] [log] [blame]
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001/*
2 * xmllint.c : a small tester program for XML input.
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel.Veillard@w3.org
7 */
8
9#ifdef WIN32
10#include "win32config.h"
11#else
12#include "config.h"
13#endif
14
15#include <stdio.h>
16#include <string.h>
17#include <stdio.h>
18#include <stdarg.h>
19
20#ifdef HAVE_SYS_TYPES_H
21#include <sys/types.h>
22#endif
23#ifdef HAVE_SYS_STAT_H
24#include <sys/stat.h>
25#endif
26#ifdef HAVE_FCNTL_H
27#include <fcntl.h>
28#endif
29#ifdef HAVE_UNISTD_H
30#include <unistd.h>
31#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000032#ifdef HAVE_SYS_MMAN_H
33#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000034/* seems needed for Solaris */
35#ifndef MAP_FAILED
36#define MAP_FAILED ((void *) -1)
37#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000038#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000039#ifdef HAVE_STDLIB_H
40#include <stdlib.h>
41#endif
42#ifdef HAVE_LIBREADLINE
43#include <readline/readline.h>
44#ifdef HAVE_LIBHISTORY
45#include <readline/history.h>
46#endif
47#endif
48
49#include <libxml/xmlmemory.h>
50#include <libxml/parser.h>
51#include <libxml/parserInternals.h>
52#include <libxml/HTMLparser.h>
53#include <libxml/HTMLtree.h>
54#include <libxml/tree.h>
55#include <libxml/xpath.h>
56#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000057#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000058#ifdef LIBXML_XINCLUDE_ENABLED
59#include <libxml/xinclude.h>
60#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000061
62#ifdef LIBXML_DEBUG_ENABLED
63static int debug = 0;
64static int shell = 0;
65static int debugent = 0;
66#endif
67static int copy = 0;
68static int recovery = 0;
69static int noent = 0;
70static int noout = 0;
71static int nowrap = 0;
72static int valid = 0;
73static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +000074static char * dtdvalid = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000075static int repeat = 0;
76static int insert = 0;
77static int compress = 0;
78static int html = 0;
79static int htmlout = 0;
80static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +000081#ifdef HAVE_SYS_MMAN_H
82static int memory = 0;
83#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000084static int noblanks = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000085static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000086static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000087#ifdef LIBXML_XINCLUDE_ENABLED
88static int xinclude = 0;
89#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000090
Daniel Veillardce6e98d2000-11-25 09:54:49 +000091
92#ifdef VMS
93extern int xmlDoValidityCheckingDefaultVal;
94#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
95#else
Daniel Veillardce8b83b2000-04-05 18:38:42 +000096extern int xmlDoValidityCheckingDefaultValue;
Daniel Veillardce6e98d2000-11-25 09:54:49 +000097#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000098extern int xmlGetWarningsDefaultValue;
99
100/************************************************************************
101 * *
102 * HTML ouput *
103 * *
104 ************************************************************************/
105char buffer[50000];
106
107void
108xmlHTMLEncodeSend(void) {
109 char *result;
110
111 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
112 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000113 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000114 xmlFree(result);
115 }
116 buffer[0] = 0;
117}
118
119/**
120 * xmlHTMLPrintFileInfo:
121 * @input: an xmlParserInputPtr input
122 *
123 * Displays the associated file and line informations for the current input
124 */
125
126void
127xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000128 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000129 if (input != NULL) {
130 if (input->filename) {
131 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
132 input->line);
133 } else {
134 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
135 }
136 }
137 xmlHTMLEncodeSend();
138}
139
140/**
141 * xmlHTMLPrintFileContext:
142 * @input: an xmlParserInputPtr input
143 *
144 * Displays current context within the input content for error tracking
145 */
146
147void
148xmlHTMLPrintFileContext(xmlParserInputPtr input) {
149 const xmlChar *cur, *base;
150 int n;
151
152 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000153 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000154 cur = input->cur;
155 base = input->base;
156 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
157 cur--;
158 }
159 n = 0;
160 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
161 cur--;
162 if ((*cur == '\n') || (*cur == '\r')) cur++;
163 base = cur;
164 n = 0;
165 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
166 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
167 n++;
168 }
169 sprintf(&buffer[strlen(buffer)], "\n");
170 cur = input->cur;
171 while ((*cur == '\n') || (*cur == '\r'))
172 cur--;
173 n = 0;
174 while ((cur != base) && (n++ < 80)) {
175 sprintf(&buffer[strlen(buffer)], " ");
176 base++;
177 }
178 sprintf(&buffer[strlen(buffer)],"^\n");
179 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000180 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000181}
182
183/**
184 * xmlHTMLError:
185 * @ctx: an XML parser context
186 * @msg: the message to display/transmit
187 * @...: extra parameters for the message display
188 *
189 * Display and format an error messages, gives file, line, position and
190 * extra parameters.
191 */
192void
193xmlHTMLError(void *ctx, const char *msg, ...)
194{
195 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
196 xmlParserInputPtr input;
197 xmlParserInputPtr cur = NULL;
198 va_list args;
199
200 buffer[0] = 0;
201 input = ctxt->input;
202 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
203 cur = input;
204 input = ctxt->inputTab[ctxt->inputNr - 2];
205 }
206
207 xmlHTMLPrintFileInfo(input);
208
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000209 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000210 va_start(args, msg);
211 vsprintf(&buffer[strlen(buffer)], msg, args);
212 va_end(args);
213 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000214 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000215
216 xmlHTMLPrintFileContext(input);
217 xmlHTMLEncodeSend();
218}
219
220/**
221 * xmlHTMLWarning:
222 * @ctx: an XML parser context
223 * @msg: the message to display/transmit
224 * @...: extra parameters for the message display
225 *
226 * Display and format a warning messages, gives file, line, position and
227 * extra parameters.
228 */
229void
230xmlHTMLWarning(void *ctx, const char *msg, ...)
231{
232 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
233 xmlParserInputPtr input;
234 xmlParserInputPtr cur = NULL;
235 va_list args;
236
237 buffer[0] = 0;
238 input = ctxt->input;
239 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
240 cur = input;
241 input = ctxt->inputTab[ctxt->inputNr - 2];
242 }
243
244
245 xmlHTMLPrintFileInfo(input);
246
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000247 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000248 va_start(args, msg);
249 vsprintf(&buffer[strlen(buffer)], msg, args);
250 va_end(args);
251 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000252 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000253
254 xmlHTMLPrintFileContext(input);
255 xmlHTMLEncodeSend();
256}
257
258/**
259 * xmlHTMLValidityError:
260 * @ctx: an XML parser context
261 * @msg: the message to display/transmit
262 * @...: extra parameters for the message display
263 *
264 * Display and format an validity error messages, gives file,
265 * line, position and extra parameters.
266 */
267void
268xmlHTMLValidityError(void *ctx, const char *msg, ...)
269{
270 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
271 xmlParserInputPtr input;
272 va_list args;
273
274 buffer[0] = 0;
275 input = ctxt->input;
276 if ((input->filename == NULL) && (ctxt->inputNr > 1))
277 input = ctxt->inputTab[ctxt->inputNr - 2];
278
279 xmlHTMLPrintFileInfo(input);
280
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000281 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000282 va_start(args, msg);
283 vsprintf(&buffer[strlen(buffer)], msg, args);
284 va_end(args);
285 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000286 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000287
288 xmlHTMLPrintFileContext(input);
289 xmlHTMLEncodeSend();
290}
291
292/**
293 * xmlHTMLValidityWarning:
294 * @ctx: an XML parser context
295 * @msg: the message to display/transmit
296 * @...: extra parameters for the message display
297 *
298 * Display and format a validity warning messages, gives file, line,
299 * position and extra parameters.
300 */
301void
302xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
303{
304 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
305 xmlParserInputPtr input;
306 va_list args;
307
308 buffer[0] = 0;
309 input = ctxt->input;
310 if ((input->filename == NULL) && (ctxt->inputNr > 1))
311 input = ctxt->inputTab[ctxt->inputNr - 2];
312
313 xmlHTMLPrintFileInfo(input);
314
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000315 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000316 va_start(args, msg);
317 vsprintf(&buffer[strlen(buffer)], msg, args);
318 va_end(args);
319 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000320 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000321
322 xmlHTMLPrintFileContext(input);
323 xmlHTMLEncodeSend();
324}
325
326/************************************************************************
327 * *
328 * Shell Interface *
329 * *
330 ************************************************************************/
331/**
332 * xmlShellReadline:
333 * @prompt: the prompt value
334 *
335 * Read a string
336 *
337 * Returns a pointer to it or NULL on EOF the caller is expected to
338 * free the returned string.
339 */
340char *
341xmlShellReadline(char *prompt) {
342#ifdef HAVE_LIBREADLINE
343 char *line_read;
344
345 /* Get a line from the user. */
346 line_read = readline (prompt);
347
348 /* If the line has any text in it, save it on the history. */
349 if (line_read && *line_read)
350 add_history (line_read);
351
352 return (line_read);
353#else
354 char line_read[501];
355
356 if (prompt != NULL)
357 fprintf(stdout, "%s", prompt);
358 if (!fgets(line_read, 500, stdin))
359 return(NULL);
360 line_read[500] = 0;
361 return(strdup(line_read));
362#endif
363}
364
365/************************************************************************
366 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000367 * I/O Interfaces *
368 * *
369 ************************************************************************/
370
371int myRead(FILE *f, char * buffer, int len) {
372 return(fread(buffer, 1, len, f));
373}
374void myClose(FILE *f) {
375 fclose(f);
376}
377
378/************************************************************************
379 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000380 * Test processing *
381 * *
382 ************************************************************************/
383void parseAndPrintFile(char *filename) {
384 xmlDocPtr doc = NULL, tmp;
385
386#ifdef LIBXML_HTML_ENABLED
387 if (html) {
388 doc = htmlParseFile(filename, NULL);
389 } else {
390#endif /* LIBXML_HTML_ENABLED */
391 /*
392 * build an XML tree from a string;
393 */
394 if (push) {
395 FILE *f;
396
397 f = fopen(filename, "r");
398 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000399 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000400 int res, size = 3;
401 char chars[1024];
402 xmlParserCtxtPtr ctxt;
403
404 if (repeat)
405 size = 1024;
406 res = fread(chars, 1, 4, f);
407 if (res > 0) {
408 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
409 chars, res, filename);
410 while ((res = fread(chars, 1, size, f)) > 0) {
411 xmlParseChunk(ctxt, chars, res, 0);
412 }
413 xmlParseChunk(ctxt, chars, 0, 1);
414 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000415 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000416 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000417 if (!ret) {
418 xmlFreeDoc(doc);
419 doc = NULL;
420 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000421 }
422 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000423 } else if (testIO) {
424 int ret;
425 FILE *f;
426
427 f = fopen(filename, "r");
428 if (f != NULL) {
429 xmlParserCtxtPtr ctxt;
430
431 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
432 (xmlInputReadCallback) myRead,
433 (xmlInputCloseCallback) myClose,
434 f, XML_CHAR_ENCODING_NONE);
435 xmlParseDocument(ctxt);
436
437 ret = ctxt->wellFormed;
438 doc = ctxt->myDoc;
439 xmlFreeParserCtxt(ctxt);
440 if (!ret) {
441 xmlFreeDoc(doc);
442 doc = NULL;
443 }
444 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000445 } else if (recovery) {
446 doc = xmlRecoverFile(filename);
447 } else if (htmlout) {
448 int ret;
449 xmlParserCtxtPtr ctxt;
450 xmlSAXHandler silent, *old;
451
452 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000453
454 if (ctxt == NULL) {
455 /* If xmlCreateFileParseCtxt() return NULL something
456 strange happened so we don't want to do anything. Do
457 we want to print an error message here?
458 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000459 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000460 } else {
461 memcpy(&silent, ctxt->sax, sizeof(silent));
462 old = ctxt->sax;
463 silent.error = xmlHTMLError;
464 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000465 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000466 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000467 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000468 silent.fatalError = xmlHTMLError;
469 ctxt->sax = &silent;
470 ctxt->vctxt.error = xmlHTMLValidityError;
471 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000472 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000473 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000474 ctxt->vctxt.warning = NULL;
475
Daniel Veillard88a172f2000-08-04 18:23:10 +0000476 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000477
Daniel Veillard88a172f2000-08-04 18:23:10 +0000478 ret = ctxt->wellFormed;
479 doc = ctxt->myDoc;
480 ctxt->sax = old;
481 xmlFreeParserCtxt(ctxt);
482 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000483 xmlFreeDoc(doc);
484 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000485 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000486 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000487#ifdef HAVE_SYS_MMAN_H
488 } else if (memory) {
489 int fd;
490 struct stat info;
491 const char *base;
492 if (stat(filename, &info) < 0)
493 return;
494 if ((fd = open(filename, O_RDONLY)) < 0)
495 return;
496 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000497 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000498 return;
499
500 doc = xmlParseMemory((char *) base, info.st_size);
501 munmap((char *) base, info.st_size);
502#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000503 } else
504 doc = xmlParseFile(filename);
505#ifdef LIBXML_HTML_ENABLED
506 }
507#endif
508
Daniel Veillard88a172f2000-08-04 18:23:10 +0000509 /*
510 * If we don't have a document we might as well give up. Do we
511 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000512 if (doc == NULL) {
Daniel Veillard88a172f2000-08-04 18:23:10 +0000513 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000514 }
515
516#ifdef LIBXML_XINCLUDE_ENABLED
517 if (xinclude)
518 xmlXIncludeProcess(doc);
519#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000520
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000521#ifdef LIBXML_DEBUG_ENABLED
522 /*
523 * shell interraction
524 */
525 if (shell)
526 xmlShell(doc, filename, xmlShellReadline, stdout);
527#endif
528
529 /*
530 * test intermediate copy if needed.
531 */
532 if (copy) {
533 tmp = doc;
534 doc = xmlCopyDoc(doc, 1);
535 xmlFreeDoc(tmp);
536 }
537
538 if ((insert) && (!html)) {
539 const xmlChar* list[256];
540 int nb, i;
541 xmlNodePtr node;
542
543 if (doc->children != NULL) {
544 node = doc->children;
545 while ((node != NULL) && (node->last == NULL)) node = node->next;
546 if (node != NULL) {
547 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
548 if (nb < 0) {
549 printf("could not get valid list of elements\n");
550 } else if (nb == 0) {
551 printf("No element can be indersted under root\n");
552 } else {
553 printf("%d element types can be indersted under root:\n",
554 nb);
555 for (i = 0;i < nb;i++) {
556 printf("%s\n", list[i]);
557 }
558 }
559 }
560 }
561 }else if (noout == 0) {
562 /*
563 * print it.
564 */
565#ifdef LIBXML_DEBUG_ENABLED
566 if (!debug) {
567#endif
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000568 if (memory) {
569 xmlChar *result;
570 int len;
571
572 if (encoding != NULL) {
573 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
574 } else {
575 xmlDocDumpMemory(doc, &result, &len);
576 }
577 if (result == NULL) {
578 fprintf(stderr, "Failed to save\n");
579 } else {
580 write(1, result, len);
581 xmlFree(result);
582 }
583 } else if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000584 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000585 else if (encoding != NULL)
586 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000587 else
588 xmlDocDump(stdout, doc);
589#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000590 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000591 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000592 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000593#endif
594 }
595
596 /*
597 * A posteriori validation test
598 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000599 if (dtdvalid != NULL) {
600 xmlDtdPtr dtd;
601
602 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
603 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000604 xmlGenericError(xmlGenericErrorContext,
605 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardcd429612000-10-11 15:57:05 +0000606 } else {
607 xmlValidCtxt cvp;
608 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
609 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000610 xmlGenericError(xmlGenericErrorContext,
611 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000612 filename, dtdvalid);
613 }
614 xmlFreeDtd(dtd);
615 }
616 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000617 xmlValidCtxt cvp;
618 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000619 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000620 xmlGenericError(xmlGenericErrorContext,
621 "Document %s does not validate\n", filename);
Daniel Veillardcd429612000-10-11 15:57:05 +0000622 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000623 }
624
625#ifdef LIBXML_DEBUG_ENABLED
626 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000627 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000628#endif
629
630 /*
631 * free it.
632 */
633 xmlFreeDoc(doc);
634}
635
636int main(int argc, char **argv) {
637 int i, count;
638 int files = 0;
639
Daniel Veillardbe803962000-06-28 23:40:59 +0000640 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000641 for (i = 1; i < argc ; i++) {
642#ifdef LIBXML_DEBUG_ENABLED
643 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
644 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645 else if ((!strcmp(argv[i], "-shell")) ||
646 (!strcmp(argv[i], "--shell"))) {
647 shell++;
648 noout = 1;
649 } else
650#endif
651 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
652 copy++;
653 else if ((!strcmp(argv[i], "-recover")) ||
654 (!strcmp(argv[i], "--recover")))
655 recovery++;
656 else if ((!strcmp(argv[i], "-noent")) ||
657 (!strcmp(argv[i], "--noent")))
658 noent++;
659 else if ((!strcmp(argv[i], "-noout")) ||
660 (!strcmp(argv[i], "--noout")))
661 noout++;
662 else if ((!strcmp(argv[i], "-htmlout")) ||
663 (!strcmp(argv[i], "--htmlout")))
664 htmlout++;
665#ifdef LIBXML_HTML_ENABLED
666 else if ((!strcmp(argv[i], "-html")) ||
667 (!strcmp(argv[i], "--html"))) {
668 html++;
669 }
670#endif /* LIBXML_HTML_ENABLED */
671 else if ((!strcmp(argv[i], "-nowrap")) ||
672 (!strcmp(argv[i], "--nowrap")))
673 nowrap++;
674 else if ((!strcmp(argv[i], "-valid")) ||
675 (!strcmp(argv[i], "--valid")))
676 valid++;
677 else if ((!strcmp(argv[i], "-postvalid")) ||
678 (!strcmp(argv[i], "--postvalid")))
679 postvalid++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000680 else if ((!strcmp(argv[i], "-dtdvalid")) ||
681 (!strcmp(argv[i], "--dtdvalid"))) {
682 i++;
683 dtdvalid = argv[i];
684 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000685 else if ((!strcmp(argv[i], "-insert")) ||
686 (!strcmp(argv[i], "--insert")))
687 insert++;
688 else if ((!strcmp(argv[i], "-repeat")) ||
689 (!strcmp(argv[i], "--repeat")))
690 repeat++;
691 else if ((!strcmp(argv[i], "-push")) ||
692 (!strcmp(argv[i], "--push")))
693 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000694#ifdef HAVE_SYS_MMAN_H
695 else if ((!strcmp(argv[i], "-memory")) ||
696 (!strcmp(argv[i], "--memory")))
697 memory++;
698#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000699 else if ((!strcmp(argv[i], "-testIO")) ||
700 (!strcmp(argv[i], "--testIO")))
701 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000702#ifdef LIBXML_XINCLUDE_ENABLED
703 else if ((!strcmp(argv[i], "-xinclude")) ||
704 (!strcmp(argv[i], "--xinclude")))
705 xinclude++;
706#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000707 else if ((!strcmp(argv[i], "-compress")) ||
708 (!strcmp(argv[i], "--compress"))) {
709 compress++;
710 xmlSetCompressMode(9);
711 }
712 else if ((!strcmp(argv[i], "-nowarning")) ||
713 (!strcmp(argv[i], "--nowarning"))) {
714 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000715 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000716 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000717 else if ((!strcmp(argv[i], "-pedantic")) ||
718 (!strcmp(argv[i], "--pedantic"))) {
719 xmlGetWarningsDefaultValue = 1;
720 xmlPedanticParserDefault(1);
721 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000722#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000723 else if ((!strcmp(argv[i], "-debugent")) ||
724 (!strcmp(argv[i], "--debugent"))) {
725 debugent++;
726 xmlParserDebugEntities = 1;
727 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000728#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000729 else if ((!strcmp(argv[i], "-encode")) ||
730 (!strcmp(argv[i], "--encode"))) {
731 i++;
732 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000733 /*
734 * OK it's for testing purposes
735 */
736 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000737 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000738 else if ((!strcmp(argv[i], "-noblanks")) ||
739 (!strcmp(argv[i], "--noblanks"))) {
740 noblanks++;
741 xmlKeepBlanksDefault(0);
742 }
743 }
744 if (noent != 0) xmlSubstituteEntitiesDefault(1);
745 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
746 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000747 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000748 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000749 xmlGenericError(xmlGenericErrorContext,
750 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
751 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000752 "<html><head><title>%s output</title></head>\n",
753 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000754 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000755 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
756 argv[0]);
757 }
758 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000759 if ((!strcmp(argv[i], "-encode")) ||
760 (!strcmp(argv[i], "--encode"))) {
761 i++;
762 continue;
763 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000764 if ((!strcmp(argv[i], "-dtdvalid")) ||
765 (!strcmp(argv[i], "--dtdvalid"))) {
766 i++;
767 continue;
768 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000769 if (argv[i][0] != '-') {
770 if (repeat) {
771 for (count = 0;count < 100 * repeat;count++)
772 parseAndPrintFile(argv[i]);
773 } else
774 parseAndPrintFile(argv[i]);
775 files ++;
776 }
777 }
778 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000779 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000780 }
781 if (files == 0) {
782 printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...\n",
783 argv[0]);
784 printf("\tParse the XML files and output the result of the parsing\n");
785#ifdef LIBXML_DEBUG_ENABLED
786 printf("\t--debug : dump a debug tree of the in-memory document\n");
787 printf("\t--shell : run a navigating shell\n");
788 printf("\t--debugent : debug the entities defined in the document\n");
789#endif
790 printf("\t--copy : used to test the internal copy implementation\n");
791 printf("\t--recover : output what was parsable on broken XML documents\n");
792 printf("\t--noent : substitute entity references by their value\n");
793 printf("\t--noout : don't output the result tree\n");
794 printf("\t--htmlout : output results as HTML\n");
795 printf("\t--nowarp : do not put HTML doc wrapper\n");
796 printf("\t--valid : validate the document in addition to std well-formed check\n");
797 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
Daniel Veillardcd429612000-10-11 15:57:05 +0000798 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000799 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
800 printf("\t--insert : ad-hoc test for valid insertions\n");
801 printf("\t--compress : turn on gzip compression of output\n");
802#ifdef LIBXML_HTML_ENABLED
803 printf("\t--html : use the HTML parser\n");
804#endif
805 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard46e370e2000-07-21 20:32:03 +0000806#ifdef HAVE_SYS_MMAN_H
807 printf("\t--memory : parse from memory\n");
808#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000809 printf("\t--nowarning : do not emit warnings from parser/validator\n");
810 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard5e873c42000-04-12 13:27:38 +0000811 printf("\t--testIO : test user I/O support\n");
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000812 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000813#ifdef LIBXML_XINCLUDE_ENABLED
814 printf("\t--xinclude : do XInclude processing\n");
815#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000816 }
817 xmlCleanupParser();
818 xmlMemoryDump();
819
820 return(0);
821}
Daniel Veillard88a172f2000-08-04 18:23:10 +0000822