blob: e443a86f3ccc8d5dda918afb12118b1f46da187b [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
91extern int xmlDoValidityCheckingDefaultValue;
92extern int xmlGetWarningsDefaultValue;
93
94/************************************************************************
95 * *
96 * HTML ouput *
97 * *
98 ************************************************************************/
99char buffer[50000];
100
101void
102xmlHTMLEncodeSend(void) {
103 char *result;
104
105 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
106 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000107 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000108 xmlFree(result);
109 }
110 buffer[0] = 0;
111}
112
113/**
114 * xmlHTMLPrintFileInfo:
115 * @input: an xmlParserInputPtr input
116 *
117 * Displays the associated file and line informations for the current input
118 */
119
120void
121xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000122 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000123 if (input != NULL) {
124 if (input->filename) {
125 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
126 input->line);
127 } else {
128 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
129 }
130 }
131 xmlHTMLEncodeSend();
132}
133
134/**
135 * xmlHTMLPrintFileContext:
136 * @input: an xmlParserInputPtr input
137 *
138 * Displays current context within the input content for error tracking
139 */
140
141void
142xmlHTMLPrintFileContext(xmlParserInputPtr input) {
143 const xmlChar *cur, *base;
144 int n;
145
146 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000147 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000148 cur = input->cur;
149 base = input->base;
150 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
151 cur--;
152 }
153 n = 0;
154 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
155 cur--;
156 if ((*cur == '\n') || (*cur == '\r')) cur++;
157 base = cur;
158 n = 0;
159 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
160 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
161 n++;
162 }
163 sprintf(&buffer[strlen(buffer)], "\n");
164 cur = input->cur;
165 while ((*cur == '\n') || (*cur == '\r'))
166 cur--;
167 n = 0;
168 while ((cur != base) && (n++ < 80)) {
169 sprintf(&buffer[strlen(buffer)], " ");
170 base++;
171 }
172 sprintf(&buffer[strlen(buffer)],"^\n");
173 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000174 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000175}
176
177/**
178 * xmlHTMLError:
179 * @ctx: an XML parser context
180 * @msg: the message to display/transmit
181 * @...: extra parameters for the message display
182 *
183 * Display and format an error messages, gives file, line, position and
184 * extra parameters.
185 */
186void
187xmlHTMLError(void *ctx, const char *msg, ...)
188{
189 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
190 xmlParserInputPtr input;
191 xmlParserInputPtr cur = NULL;
192 va_list args;
193
194 buffer[0] = 0;
195 input = ctxt->input;
196 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
197 cur = input;
198 input = ctxt->inputTab[ctxt->inputNr - 2];
199 }
200
201 xmlHTMLPrintFileInfo(input);
202
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000203 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000204 va_start(args, msg);
205 vsprintf(&buffer[strlen(buffer)], msg, args);
206 va_end(args);
207 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000208 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000209
210 xmlHTMLPrintFileContext(input);
211 xmlHTMLEncodeSend();
212}
213
214/**
215 * xmlHTMLWarning:
216 * @ctx: an XML parser context
217 * @msg: the message to display/transmit
218 * @...: extra parameters for the message display
219 *
220 * Display and format a warning messages, gives file, line, position and
221 * extra parameters.
222 */
223void
224xmlHTMLWarning(void *ctx, const char *msg, ...)
225{
226 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
227 xmlParserInputPtr input;
228 xmlParserInputPtr cur = NULL;
229 va_list args;
230
231 buffer[0] = 0;
232 input = ctxt->input;
233 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
234 cur = input;
235 input = ctxt->inputTab[ctxt->inputNr - 2];
236 }
237
238
239 xmlHTMLPrintFileInfo(input);
240
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000241 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000242 va_start(args, msg);
243 vsprintf(&buffer[strlen(buffer)], msg, args);
244 va_end(args);
245 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000246 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000247
248 xmlHTMLPrintFileContext(input);
249 xmlHTMLEncodeSend();
250}
251
252/**
253 * xmlHTMLValidityError:
254 * @ctx: an XML parser context
255 * @msg: the message to display/transmit
256 * @...: extra parameters for the message display
257 *
258 * Display and format an validity error messages, gives file,
259 * line, position and extra parameters.
260 */
261void
262xmlHTMLValidityError(void *ctx, const char *msg, ...)
263{
264 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
265 xmlParserInputPtr input;
266 va_list args;
267
268 buffer[0] = 0;
269 input = ctxt->input;
270 if ((input->filename == NULL) && (ctxt->inputNr > 1))
271 input = ctxt->inputTab[ctxt->inputNr - 2];
272
273 xmlHTMLPrintFileInfo(input);
274
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000275 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000276 va_start(args, msg);
277 vsprintf(&buffer[strlen(buffer)], msg, args);
278 va_end(args);
279 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000280 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000281
282 xmlHTMLPrintFileContext(input);
283 xmlHTMLEncodeSend();
284}
285
286/**
287 * xmlHTMLValidityWarning:
288 * @ctx: an XML parser context
289 * @msg: the message to display/transmit
290 * @...: extra parameters for the message display
291 *
292 * Display and format a validity warning messages, gives file, line,
293 * position and extra parameters.
294 */
295void
296xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
297{
298 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
299 xmlParserInputPtr input;
300 va_list args;
301
302 buffer[0] = 0;
303 input = ctxt->input;
304 if ((input->filename == NULL) && (ctxt->inputNr > 1))
305 input = ctxt->inputTab[ctxt->inputNr - 2];
306
307 xmlHTMLPrintFileInfo(input);
308
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000309 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000310 va_start(args, msg);
311 vsprintf(&buffer[strlen(buffer)], msg, args);
312 va_end(args);
313 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000314 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000315
316 xmlHTMLPrintFileContext(input);
317 xmlHTMLEncodeSend();
318}
319
320/************************************************************************
321 * *
322 * Shell Interface *
323 * *
324 ************************************************************************/
325/**
326 * xmlShellReadline:
327 * @prompt: the prompt value
328 *
329 * Read a string
330 *
331 * Returns a pointer to it or NULL on EOF the caller is expected to
332 * free the returned string.
333 */
334char *
335xmlShellReadline(char *prompt) {
336#ifdef HAVE_LIBREADLINE
337 char *line_read;
338
339 /* Get a line from the user. */
340 line_read = readline (prompt);
341
342 /* If the line has any text in it, save it on the history. */
343 if (line_read && *line_read)
344 add_history (line_read);
345
346 return (line_read);
347#else
348 char line_read[501];
349
350 if (prompt != NULL)
351 fprintf(stdout, "%s", prompt);
352 if (!fgets(line_read, 500, stdin))
353 return(NULL);
354 line_read[500] = 0;
355 return(strdup(line_read));
356#endif
357}
358
359/************************************************************************
360 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000361 * I/O Interfaces *
362 * *
363 ************************************************************************/
364
365int myRead(FILE *f, char * buffer, int len) {
366 return(fread(buffer, 1, len, f));
367}
368void myClose(FILE *f) {
369 fclose(f);
370}
371
372/************************************************************************
373 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000374 * Test processing *
375 * *
376 ************************************************************************/
377void parseAndPrintFile(char *filename) {
378 xmlDocPtr doc = NULL, tmp;
379
380#ifdef LIBXML_HTML_ENABLED
381 if (html) {
382 doc = htmlParseFile(filename, NULL);
383 } else {
384#endif /* LIBXML_HTML_ENABLED */
385 /*
386 * build an XML tree from a string;
387 */
388 if (push) {
389 FILE *f;
390
391 f = fopen(filename, "r");
392 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000393 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000394 int res, size = 3;
395 char chars[1024];
396 xmlParserCtxtPtr ctxt;
397
398 if (repeat)
399 size = 1024;
400 res = fread(chars, 1, 4, f);
401 if (res > 0) {
402 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
403 chars, res, filename);
404 while ((res = fread(chars, 1, size, f)) > 0) {
405 xmlParseChunk(ctxt, chars, res, 0);
406 }
407 xmlParseChunk(ctxt, chars, 0, 1);
408 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000409 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000410 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000411 if (!ret) {
412 xmlFreeDoc(doc);
413 doc = NULL;
414 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000415 }
416 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000417 } else if (testIO) {
418 int ret;
419 FILE *f;
420
421 f = fopen(filename, "r");
422 if (f != NULL) {
423 xmlParserCtxtPtr ctxt;
424
425 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
426 (xmlInputReadCallback) myRead,
427 (xmlInputCloseCallback) myClose,
428 f, XML_CHAR_ENCODING_NONE);
429 xmlParseDocument(ctxt);
430
431 ret = ctxt->wellFormed;
432 doc = ctxt->myDoc;
433 xmlFreeParserCtxt(ctxt);
434 if (!ret) {
435 xmlFreeDoc(doc);
436 doc = NULL;
437 }
438 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000439 } else if (recovery) {
440 doc = xmlRecoverFile(filename);
441 } else if (htmlout) {
442 int ret;
443 xmlParserCtxtPtr ctxt;
444 xmlSAXHandler silent, *old;
445
446 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000447
448 if (ctxt == NULL) {
449 /* If xmlCreateFileParseCtxt() return NULL something
450 strange happened so we don't want to do anything. Do
451 we want to print an error message here?
452 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000453 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000454 } else {
455 memcpy(&silent, ctxt->sax, sizeof(silent));
456 old = ctxt->sax;
457 silent.error = xmlHTMLError;
458 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000459 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000460 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000461 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000462 silent.fatalError = xmlHTMLError;
463 ctxt->sax = &silent;
464 ctxt->vctxt.error = xmlHTMLValidityError;
465 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000466 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000467 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000468 ctxt->vctxt.warning = NULL;
469
Daniel Veillard88a172f2000-08-04 18:23:10 +0000470 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000471
Daniel Veillard88a172f2000-08-04 18:23:10 +0000472 ret = ctxt->wellFormed;
473 doc = ctxt->myDoc;
474 ctxt->sax = old;
475 xmlFreeParserCtxt(ctxt);
476 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000477 xmlFreeDoc(doc);
478 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000479 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000480 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000481#ifdef HAVE_SYS_MMAN_H
482 } else if (memory) {
483 int fd;
484 struct stat info;
485 const char *base;
486 if (stat(filename, &info) < 0)
487 return;
488 if ((fd = open(filename, O_RDONLY)) < 0)
489 return;
490 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000491 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000492 return;
493
494 doc = xmlParseMemory((char *) base, info.st_size);
495 munmap((char *) base, info.st_size);
496#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000497 } else
498 doc = xmlParseFile(filename);
499#ifdef LIBXML_HTML_ENABLED
500 }
501#endif
502
Daniel Veillard88a172f2000-08-04 18:23:10 +0000503 /*
504 * If we don't have a document we might as well give up. Do we
505 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000506 if (doc == NULL) {
Daniel Veillard88a172f2000-08-04 18:23:10 +0000507 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000508 }
509
510#ifdef LIBXML_XINCLUDE_ENABLED
511 if (xinclude)
512 xmlXIncludeProcess(doc);
513#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000514
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000515#ifdef LIBXML_DEBUG_ENABLED
516 /*
517 * shell interraction
518 */
519 if (shell)
520 xmlShell(doc, filename, xmlShellReadline, stdout);
521#endif
522
523 /*
524 * test intermediate copy if needed.
525 */
526 if (copy) {
527 tmp = doc;
528 doc = xmlCopyDoc(doc, 1);
529 xmlFreeDoc(tmp);
530 }
531
532 if ((insert) && (!html)) {
533 const xmlChar* list[256];
534 int nb, i;
535 xmlNodePtr node;
536
537 if (doc->children != NULL) {
538 node = doc->children;
539 while ((node != NULL) && (node->last == NULL)) node = node->next;
540 if (node != NULL) {
541 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
542 if (nb < 0) {
543 printf("could not get valid list of elements\n");
544 } else if (nb == 0) {
545 printf("No element can be indersted under root\n");
546 } else {
547 printf("%d element types can be indersted under root:\n",
548 nb);
549 for (i = 0;i < nb;i++) {
550 printf("%s\n", list[i]);
551 }
552 }
553 }
554 }
555 }else if (noout == 0) {
556 /*
557 * print it.
558 */
559#ifdef LIBXML_DEBUG_ENABLED
560 if (!debug) {
561#endif
562 if (compress)
563 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000564 else if (encoding != NULL)
565 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000566 else
567 xmlDocDump(stdout, doc);
568#ifdef LIBXML_DEBUG_ENABLED
569 } else
570 xmlDebugDumpDocument(stdout, doc);
571#endif
572 }
573
574 /*
575 * A posteriori validation test
576 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000577 if (dtdvalid != NULL) {
578 xmlDtdPtr dtd;
579
580 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
581 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000582 xmlGenericError(xmlGenericErrorContext,
583 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardcd429612000-10-11 15:57:05 +0000584 } else {
585 xmlValidCtxt cvp;
586 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
587 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000588 xmlGenericError(xmlGenericErrorContext,
589 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000590 filename, dtdvalid);
591 }
592 xmlFreeDtd(dtd);
593 }
594 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000595 xmlValidCtxt cvp;
596 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000597 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000598 xmlGenericError(xmlGenericErrorContext,
599 "Document %s does not validate\n", filename);
Daniel Veillardcd429612000-10-11 15:57:05 +0000600 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000601 }
602
603#ifdef LIBXML_DEBUG_ENABLED
604 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000605 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000606#endif
607
608 /*
609 * free it.
610 */
611 xmlFreeDoc(doc);
612}
613
614int main(int argc, char **argv) {
615 int i, count;
616 int files = 0;
617
Daniel Veillardbe803962000-06-28 23:40:59 +0000618 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000619 for (i = 1; i < argc ; i++) {
620#ifdef LIBXML_DEBUG_ENABLED
621 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
622 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000623 else if ((!strcmp(argv[i], "-shell")) ||
624 (!strcmp(argv[i], "--shell"))) {
625 shell++;
626 noout = 1;
627 } else
628#endif
629 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
630 copy++;
631 else if ((!strcmp(argv[i], "-recover")) ||
632 (!strcmp(argv[i], "--recover")))
633 recovery++;
634 else if ((!strcmp(argv[i], "-noent")) ||
635 (!strcmp(argv[i], "--noent")))
636 noent++;
637 else if ((!strcmp(argv[i], "-noout")) ||
638 (!strcmp(argv[i], "--noout")))
639 noout++;
640 else if ((!strcmp(argv[i], "-htmlout")) ||
641 (!strcmp(argv[i], "--htmlout")))
642 htmlout++;
643#ifdef LIBXML_HTML_ENABLED
644 else if ((!strcmp(argv[i], "-html")) ||
645 (!strcmp(argv[i], "--html"))) {
646 html++;
647 }
648#endif /* LIBXML_HTML_ENABLED */
649 else if ((!strcmp(argv[i], "-nowrap")) ||
650 (!strcmp(argv[i], "--nowrap")))
651 nowrap++;
652 else if ((!strcmp(argv[i], "-valid")) ||
653 (!strcmp(argv[i], "--valid")))
654 valid++;
655 else if ((!strcmp(argv[i], "-postvalid")) ||
656 (!strcmp(argv[i], "--postvalid")))
657 postvalid++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000658 else if ((!strcmp(argv[i], "-dtdvalid")) ||
659 (!strcmp(argv[i], "--dtdvalid"))) {
660 i++;
661 dtdvalid = argv[i];
662 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000663 else if ((!strcmp(argv[i], "-insert")) ||
664 (!strcmp(argv[i], "--insert")))
665 insert++;
666 else if ((!strcmp(argv[i], "-repeat")) ||
667 (!strcmp(argv[i], "--repeat")))
668 repeat++;
669 else if ((!strcmp(argv[i], "-push")) ||
670 (!strcmp(argv[i], "--push")))
671 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000672#ifdef HAVE_SYS_MMAN_H
673 else if ((!strcmp(argv[i], "-memory")) ||
674 (!strcmp(argv[i], "--memory")))
675 memory++;
676#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000677 else if ((!strcmp(argv[i], "-testIO")) ||
678 (!strcmp(argv[i], "--testIO")))
679 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000680#ifdef LIBXML_XINCLUDE_ENABLED
681 else if ((!strcmp(argv[i], "-xinclude")) ||
682 (!strcmp(argv[i], "--xinclude")))
683 xinclude++;
684#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000685 else if ((!strcmp(argv[i], "-compress")) ||
686 (!strcmp(argv[i], "--compress"))) {
687 compress++;
688 xmlSetCompressMode(9);
689 }
690 else if ((!strcmp(argv[i], "-nowarning")) ||
691 (!strcmp(argv[i], "--nowarning"))) {
692 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000693 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000694 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000695 else if ((!strcmp(argv[i], "-pedantic")) ||
696 (!strcmp(argv[i], "--pedantic"))) {
697 xmlGetWarningsDefaultValue = 1;
698 xmlPedanticParserDefault(1);
699 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000700#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000701 else if ((!strcmp(argv[i], "-debugent")) ||
702 (!strcmp(argv[i], "--debugent"))) {
703 debugent++;
704 xmlParserDebugEntities = 1;
705 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000706#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000707 else if ((!strcmp(argv[i], "-encode")) ||
708 (!strcmp(argv[i], "--encode"))) {
709 i++;
710 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000711 /*
712 * OK it's for testing purposes
713 */
714 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000715 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000716 else if ((!strcmp(argv[i], "-noblanks")) ||
717 (!strcmp(argv[i], "--noblanks"))) {
718 noblanks++;
719 xmlKeepBlanksDefault(0);
720 }
721 }
722 if (noent != 0) xmlSubstituteEntitiesDefault(1);
723 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
724 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000725 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000726 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000727 xmlGenericError(xmlGenericErrorContext,
728 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
729 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000730 "<html><head><title>%s output</title></head>\n",
731 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000732 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000733 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
734 argv[0]);
735 }
736 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000737 if ((!strcmp(argv[i], "-encode")) ||
738 (!strcmp(argv[i], "--encode"))) {
739 i++;
740 continue;
741 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000742 if ((!strcmp(argv[i], "-dtdvalid")) ||
743 (!strcmp(argv[i], "--dtdvalid"))) {
744 i++;
745 continue;
746 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000747 if (argv[i][0] != '-') {
748 if (repeat) {
749 for (count = 0;count < 100 * repeat;count++)
750 parseAndPrintFile(argv[i]);
751 } else
752 parseAndPrintFile(argv[i]);
753 files ++;
754 }
755 }
756 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000757 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000758 }
759 if (files == 0) {
760 printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...\n",
761 argv[0]);
762 printf("\tParse the XML files and output the result of the parsing\n");
763#ifdef LIBXML_DEBUG_ENABLED
764 printf("\t--debug : dump a debug tree of the in-memory document\n");
765 printf("\t--shell : run a navigating shell\n");
766 printf("\t--debugent : debug the entities defined in the document\n");
767#endif
768 printf("\t--copy : used to test the internal copy implementation\n");
769 printf("\t--recover : output what was parsable on broken XML documents\n");
770 printf("\t--noent : substitute entity references by their value\n");
771 printf("\t--noout : don't output the result tree\n");
772 printf("\t--htmlout : output results as HTML\n");
773 printf("\t--nowarp : do not put HTML doc wrapper\n");
774 printf("\t--valid : validate the document in addition to std well-formed check\n");
775 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
Daniel Veillardcd429612000-10-11 15:57:05 +0000776 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000777 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
778 printf("\t--insert : ad-hoc test for valid insertions\n");
779 printf("\t--compress : turn on gzip compression of output\n");
780#ifdef LIBXML_HTML_ENABLED
781 printf("\t--html : use the HTML parser\n");
782#endif
783 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard46e370e2000-07-21 20:32:03 +0000784#ifdef HAVE_SYS_MMAN_H
785 printf("\t--memory : parse from memory\n");
786#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000787 printf("\t--nowarning : do not emit warnings from parser/validator\n");
788 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard5e873c42000-04-12 13:27:38 +0000789 printf("\t--testIO : test user I/O support\n");
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000790 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000791#ifdef LIBXML_XINCLUDE_ENABLED
792 printf("\t--xinclude : do XInclude processing\n");
793#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000794 }
795 xmlCleanupParser();
796 xmlMemoryDump();
797
798 return(0);
799}
Daniel Veillard88a172f2000-08-04 18:23:10 +0000800