blob: 5ce88e1743011e9668ab1078b94ba1794b7a1fb5 [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 Veillardce8b83b2000-04-05 18:38:42 +000058
59#ifdef LIBXML_DEBUG_ENABLED
60static int debug = 0;
61static int shell = 0;
62static int debugent = 0;
63#endif
64static int copy = 0;
65static int recovery = 0;
66static int noent = 0;
67static int noout = 0;
68static int nowrap = 0;
69static int valid = 0;
70static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +000071static char * dtdvalid = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000072static int repeat = 0;
73static int insert = 0;
74static int compress = 0;
75static int html = 0;
76static int htmlout = 0;
77static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +000078#ifdef HAVE_SYS_MMAN_H
79static int memory = 0;
80#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000081static int noblanks = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000082static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000083static char *encoding = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000084
85extern int xmlDoValidityCheckingDefaultValue;
86extern int xmlGetWarningsDefaultValue;
87
88/************************************************************************
89 * *
90 * HTML ouput *
91 * *
92 ************************************************************************/
93char buffer[50000];
94
95void
96xmlHTMLEncodeSend(void) {
97 char *result;
98
99 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
100 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000101 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000102 xmlFree(result);
103 }
104 buffer[0] = 0;
105}
106
107/**
108 * xmlHTMLPrintFileInfo:
109 * @input: an xmlParserInputPtr input
110 *
111 * Displays the associated file and line informations for the current input
112 */
113
114void
115xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000116 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000117 if (input != NULL) {
118 if (input->filename) {
119 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
120 input->line);
121 } else {
122 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
123 }
124 }
125 xmlHTMLEncodeSend();
126}
127
128/**
129 * xmlHTMLPrintFileContext:
130 * @input: an xmlParserInputPtr input
131 *
132 * Displays current context within the input content for error tracking
133 */
134
135void
136xmlHTMLPrintFileContext(xmlParserInputPtr input) {
137 const xmlChar *cur, *base;
138 int n;
139
140 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000141 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000142 cur = input->cur;
143 base = input->base;
144 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
145 cur--;
146 }
147 n = 0;
148 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
149 cur--;
150 if ((*cur == '\n') || (*cur == '\r')) cur++;
151 base = cur;
152 n = 0;
153 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
154 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
155 n++;
156 }
157 sprintf(&buffer[strlen(buffer)], "\n");
158 cur = input->cur;
159 while ((*cur == '\n') || (*cur == '\r'))
160 cur--;
161 n = 0;
162 while ((cur != base) && (n++ < 80)) {
163 sprintf(&buffer[strlen(buffer)], " ");
164 base++;
165 }
166 sprintf(&buffer[strlen(buffer)],"^\n");
167 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000168 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000169}
170
171/**
172 * xmlHTMLError:
173 * @ctx: an XML parser context
174 * @msg: the message to display/transmit
175 * @...: extra parameters for the message display
176 *
177 * Display and format an error messages, gives file, line, position and
178 * extra parameters.
179 */
180void
181xmlHTMLError(void *ctx, const char *msg, ...)
182{
183 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
184 xmlParserInputPtr input;
185 xmlParserInputPtr cur = NULL;
186 va_list args;
187
188 buffer[0] = 0;
189 input = ctxt->input;
190 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
191 cur = input;
192 input = ctxt->inputTab[ctxt->inputNr - 2];
193 }
194
195 xmlHTMLPrintFileInfo(input);
196
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000197 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000198 va_start(args, msg);
199 vsprintf(&buffer[strlen(buffer)], msg, args);
200 va_end(args);
201 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000202 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000203
204 xmlHTMLPrintFileContext(input);
205 xmlHTMLEncodeSend();
206}
207
208/**
209 * xmlHTMLWarning:
210 * @ctx: an XML parser context
211 * @msg: the message to display/transmit
212 * @...: extra parameters for the message display
213 *
214 * Display and format a warning messages, gives file, line, position and
215 * extra parameters.
216 */
217void
218xmlHTMLWarning(void *ctx, const char *msg, ...)
219{
220 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
221 xmlParserInputPtr input;
222 xmlParserInputPtr cur = NULL;
223 va_list args;
224
225 buffer[0] = 0;
226 input = ctxt->input;
227 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
228 cur = input;
229 input = ctxt->inputTab[ctxt->inputNr - 2];
230 }
231
232
233 xmlHTMLPrintFileInfo(input);
234
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000235 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000236 va_start(args, msg);
237 vsprintf(&buffer[strlen(buffer)], msg, args);
238 va_end(args);
239 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000240 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000241
242 xmlHTMLPrintFileContext(input);
243 xmlHTMLEncodeSend();
244}
245
246/**
247 * xmlHTMLValidityError:
248 * @ctx: an XML parser context
249 * @msg: the message to display/transmit
250 * @...: extra parameters for the message display
251 *
252 * Display and format an validity error messages, gives file,
253 * line, position and extra parameters.
254 */
255void
256xmlHTMLValidityError(void *ctx, const char *msg, ...)
257{
258 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
259 xmlParserInputPtr input;
260 va_list args;
261
262 buffer[0] = 0;
263 input = ctxt->input;
264 if ((input->filename == NULL) && (ctxt->inputNr > 1))
265 input = ctxt->inputTab[ctxt->inputNr - 2];
266
267 xmlHTMLPrintFileInfo(input);
268
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000269 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000270 va_start(args, msg);
271 vsprintf(&buffer[strlen(buffer)], msg, args);
272 va_end(args);
273 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000274 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000275
276 xmlHTMLPrintFileContext(input);
277 xmlHTMLEncodeSend();
278}
279
280/**
281 * xmlHTMLValidityWarning:
282 * @ctx: an XML parser context
283 * @msg: the message to display/transmit
284 * @...: extra parameters for the message display
285 *
286 * Display and format a validity warning messages, gives file, line,
287 * position and extra parameters.
288 */
289void
290xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
291{
292 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
293 xmlParserInputPtr input;
294 va_list args;
295
296 buffer[0] = 0;
297 input = ctxt->input;
298 if ((input->filename == NULL) && (ctxt->inputNr > 1))
299 input = ctxt->inputTab[ctxt->inputNr - 2];
300
301 xmlHTMLPrintFileInfo(input);
302
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000303 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000304 va_start(args, msg);
305 vsprintf(&buffer[strlen(buffer)], msg, args);
306 va_end(args);
307 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000308 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000309
310 xmlHTMLPrintFileContext(input);
311 xmlHTMLEncodeSend();
312}
313
314/************************************************************************
315 * *
316 * Shell Interface *
317 * *
318 ************************************************************************/
319/**
320 * xmlShellReadline:
321 * @prompt: the prompt value
322 *
323 * Read a string
324 *
325 * Returns a pointer to it or NULL on EOF the caller is expected to
326 * free the returned string.
327 */
328char *
329xmlShellReadline(char *prompt) {
330#ifdef HAVE_LIBREADLINE
331 char *line_read;
332
333 /* Get a line from the user. */
334 line_read = readline (prompt);
335
336 /* If the line has any text in it, save it on the history. */
337 if (line_read && *line_read)
338 add_history (line_read);
339
340 return (line_read);
341#else
342 char line_read[501];
343
344 if (prompt != NULL)
345 fprintf(stdout, "%s", prompt);
346 if (!fgets(line_read, 500, stdin))
347 return(NULL);
348 line_read[500] = 0;
349 return(strdup(line_read));
350#endif
351}
352
353/************************************************************************
354 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000355 * I/O Interfaces *
356 * *
357 ************************************************************************/
358
359int myRead(FILE *f, char * buffer, int len) {
360 return(fread(buffer, 1, len, f));
361}
362void myClose(FILE *f) {
363 fclose(f);
364}
365
366/************************************************************************
367 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000368 * Test processing *
369 * *
370 ************************************************************************/
371void parseAndPrintFile(char *filename) {
372 xmlDocPtr doc = NULL, tmp;
373
374#ifdef LIBXML_HTML_ENABLED
375 if (html) {
376 doc = htmlParseFile(filename, NULL);
377 } else {
378#endif /* LIBXML_HTML_ENABLED */
379 /*
380 * build an XML tree from a string;
381 */
382 if (push) {
383 FILE *f;
384
385 f = fopen(filename, "r");
386 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000387 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000388 int res, size = 3;
389 char chars[1024];
390 xmlParserCtxtPtr ctxt;
391
392 if (repeat)
393 size = 1024;
394 res = fread(chars, 1, 4, f);
395 if (res > 0) {
396 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
397 chars, res, filename);
398 while ((res = fread(chars, 1, size, f)) > 0) {
399 xmlParseChunk(ctxt, chars, res, 0);
400 }
401 xmlParseChunk(ctxt, chars, 0, 1);
402 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000403 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000404 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000405 if (!ret) {
406 xmlFreeDoc(doc);
407 doc = NULL;
408 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000409 }
410 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000411 } else if (testIO) {
412 int ret;
413 FILE *f;
414
415 f = fopen(filename, "r");
416 if (f != NULL) {
417 xmlParserCtxtPtr ctxt;
418
419 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
420 (xmlInputReadCallback) myRead,
421 (xmlInputCloseCallback) myClose,
422 f, XML_CHAR_ENCODING_NONE);
423 xmlParseDocument(ctxt);
424
425 ret = ctxt->wellFormed;
426 doc = ctxt->myDoc;
427 xmlFreeParserCtxt(ctxt);
428 if (!ret) {
429 xmlFreeDoc(doc);
430 doc = NULL;
431 }
432 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000433 } else if (recovery) {
434 doc = xmlRecoverFile(filename);
435 } else if (htmlout) {
436 int ret;
437 xmlParserCtxtPtr ctxt;
438 xmlSAXHandler silent, *old;
439
440 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000441
442 if (ctxt == NULL) {
443 /* If xmlCreateFileParseCtxt() return NULL something
444 strange happened so we don't want to do anything. Do
445 we want to print an error message here?
446 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000447 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000448 } else {
449 memcpy(&silent, ctxt->sax, sizeof(silent));
450 old = ctxt->sax;
451 silent.error = xmlHTMLError;
452 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000453 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000454 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000455 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000456 silent.fatalError = xmlHTMLError;
457 ctxt->sax = &silent;
458 ctxt->vctxt.error = xmlHTMLValidityError;
459 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000460 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000461 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000462 ctxt->vctxt.warning = NULL;
463
Daniel Veillard88a172f2000-08-04 18:23:10 +0000464 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000465
Daniel Veillard88a172f2000-08-04 18:23:10 +0000466 ret = ctxt->wellFormed;
467 doc = ctxt->myDoc;
468 ctxt->sax = old;
469 xmlFreeParserCtxt(ctxt);
470 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000471 xmlFreeDoc(doc);
472 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000473 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000474 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000475#ifdef HAVE_SYS_MMAN_H
476 } else if (memory) {
477 int fd;
478 struct stat info;
479 const char *base;
480 if (stat(filename, &info) < 0)
481 return;
482 if ((fd = open(filename, O_RDONLY)) < 0)
483 return;
484 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000485 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000486 return;
487
488 doc = xmlParseMemory((char *) base, info.st_size);
489 munmap((char *) base, info.st_size);
490#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000491 } else
492 doc = xmlParseFile(filename);
493#ifdef LIBXML_HTML_ENABLED
494 }
495#endif
496
Daniel Veillard88a172f2000-08-04 18:23:10 +0000497 /*
498 * If we don't have a document we might as well give up. Do we
499 * want an error message here? <sven@zen.org> */
500 if (doc == NULL)
501 {
502 return;
503 }
504
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000505#ifdef LIBXML_DEBUG_ENABLED
506 /*
507 * shell interraction
508 */
509 if (shell)
510 xmlShell(doc, filename, xmlShellReadline, stdout);
511#endif
512
513 /*
514 * test intermediate copy if needed.
515 */
516 if (copy) {
517 tmp = doc;
518 doc = xmlCopyDoc(doc, 1);
519 xmlFreeDoc(tmp);
520 }
521
522 if ((insert) && (!html)) {
523 const xmlChar* list[256];
524 int nb, i;
525 xmlNodePtr node;
526
527 if (doc->children != NULL) {
528 node = doc->children;
529 while ((node != NULL) && (node->last == NULL)) node = node->next;
530 if (node != NULL) {
531 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
532 if (nb < 0) {
533 printf("could not get valid list of elements\n");
534 } else if (nb == 0) {
535 printf("No element can be indersted under root\n");
536 } else {
537 printf("%d element types can be indersted under root:\n",
538 nb);
539 for (i = 0;i < nb;i++) {
540 printf("%s\n", list[i]);
541 }
542 }
543 }
544 }
545 }else if (noout == 0) {
546 /*
547 * print it.
548 */
549#ifdef LIBXML_DEBUG_ENABLED
550 if (!debug) {
551#endif
552 if (compress)
553 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000554 else if (encoding != NULL)
555 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000556 else
557 xmlDocDump(stdout, doc);
558#ifdef LIBXML_DEBUG_ENABLED
559 } else
560 xmlDebugDumpDocument(stdout, doc);
561#endif
562 }
563
564 /*
565 * A posteriori validation test
566 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000567 if (dtdvalid != NULL) {
568 xmlDtdPtr dtd;
569
570 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
571 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000572 xmlGenericError(xmlGenericErrorContext,
573 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardcd429612000-10-11 15:57:05 +0000574 } else {
575 xmlValidCtxt cvp;
576 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
577 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000578 xmlGenericError(xmlGenericErrorContext,
579 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000580 filename, dtdvalid);
581 }
582 xmlFreeDtd(dtd);
583 }
584 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000585 xmlValidCtxt cvp;
586 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000587 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000588 xmlGenericError(xmlGenericErrorContext,
589 "Document %s does not validate\n", filename);
Daniel Veillardcd429612000-10-11 15:57:05 +0000590 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000591 }
592
593#ifdef LIBXML_DEBUG_ENABLED
594 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000595 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000596#endif
597
598 /*
599 * free it.
600 */
601 xmlFreeDoc(doc);
602}
603
604int main(int argc, char **argv) {
605 int i, count;
606 int files = 0;
607
Daniel Veillardbe803962000-06-28 23:40:59 +0000608 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000609 for (i = 1; i < argc ; i++) {
610#ifdef LIBXML_DEBUG_ENABLED
611 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
612 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000613 else if ((!strcmp(argv[i], "-shell")) ||
614 (!strcmp(argv[i], "--shell"))) {
615 shell++;
616 noout = 1;
617 } else
618#endif
619 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
620 copy++;
621 else if ((!strcmp(argv[i], "-recover")) ||
622 (!strcmp(argv[i], "--recover")))
623 recovery++;
624 else if ((!strcmp(argv[i], "-noent")) ||
625 (!strcmp(argv[i], "--noent")))
626 noent++;
627 else if ((!strcmp(argv[i], "-noout")) ||
628 (!strcmp(argv[i], "--noout")))
629 noout++;
630 else if ((!strcmp(argv[i], "-htmlout")) ||
631 (!strcmp(argv[i], "--htmlout")))
632 htmlout++;
633#ifdef LIBXML_HTML_ENABLED
634 else if ((!strcmp(argv[i], "-html")) ||
635 (!strcmp(argv[i], "--html"))) {
636 html++;
637 }
638#endif /* LIBXML_HTML_ENABLED */
639 else if ((!strcmp(argv[i], "-nowrap")) ||
640 (!strcmp(argv[i], "--nowrap")))
641 nowrap++;
642 else if ((!strcmp(argv[i], "-valid")) ||
643 (!strcmp(argv[i], "--valid")))
644 valid++;
645 else if ((!strcmp(argv[i], "-postvalid")) ||
646 (!strcmp(argv[i], "--postvalid")))
647 postvalid++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000648 else if ((!strcmp(argv[i], "-dtdvalid")) ||
649 (!strcmp(argv[i], "--dtdvalid"))) {
650 i++;
651 dtdvalid = argv[i];
652 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000653 else if ((!strcmp(argv[i], "-insert")) ||
654 (!strcmp(argv[i], "--insert")))
655 insert++;
656 else if ((!strcmp(argv[i], "-repeat")) ||
657 (!strcmp(argv[i], "--repeat")))
658 repeat++;
659 else if ((!strcmp(argv[i], "-push")) ||
660 (!strcmp(argv[i], "--push")))
661 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000662#ifdef HAVE_SYS_MMAN_H
663 else if ((!strcmp(argv[i], "-memory")) ||
664 (!strcmp(argv[i], "--memory")))
665 memory++;
666#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000667 else if ((!strcmp(argv[i], "-testIO")) ||
668 (!strcmp(argv[i], "--testIO")))
669 testIO++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000670 else if ((!strcmp(argv[i], "-compress")) ||
671 (!strcmp(argv[i], "--compress"))) {
672 compress++;
673 xmlSetCompressMode(9);
674 }
675 else if ((!strcmp(argv[i], "-nowarning")) ||
676 (!strcmp(argv[i], "--nowarning"))) {
677 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000678 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000679 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000680 else if ((!strcmp(argv[i], "-pedantic")) ||
681 (!strcmp(argv[i], "--pedantic"))) {
682 xmlGetWarningsDefaultValue = 1;
683 xmlPedanticParserDefault(1);
684 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000685#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000686 else if ((!strcmp(argv[i], "-debugent")) ||
687 (!strcmp(argv[i], "--debugent"))) {
688 debugent++;
689 xmlParserDebugEntities = 1;
690 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000691#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000692 else if ((!strcmp(argv[i], "-encode")) ||
693 (!strcmp(argv[i], "--encode"))) {
694 i++;
695 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000696 /*
697 * OK it's for testing purposes
698 */
699 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000700 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000701 else if ((!strcmp(argv[i], "-noblanks")) ||
702 (!strcmp(argv[i], "--noblanks"))) {
703 noblanks++;
704 xmlKeepBlanksDefault(0);
705 }
706 }
707 if (noent != 0) xmlSubstituteEntitiesDefault(1);
708 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
709 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000710 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000711 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000712 xmlGenericError(xmlGenericErrorContext,
713 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
714 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000715 "<html><head><title>%s output</title></head>\n",
716 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000717 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000718 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
719 argv[0]);
720 }
721 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000722 if ((!strcmp(argv[i], "-encode")) ||
723 (!strcmp(argv[i], "--encode"))) {
724 i++;
725 continue;
726 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000727 if ((!strcmp(argv[i], "-dtdvalid")) ||
728 (!strcmp(argv[i], "--dtdvalid"))) {
729 i++;
730 continue;
731 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000732 if (argv[i][0] != '-') {
733 if (repeat) {
734 for (count = 0;count < 100 * repeat;count++)
735 parseAndPrintFile(argv[i]);
736 } else
737 parseAndPrintFile(argv[i]);
738 files ++;
739 }
740 }
741 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000742 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000743 }
744 if (files == 0) {
745 printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...\n",
746 argv[0]);
747 printf("\tParse the XML files and output the result of the parsing\n");
748#ifdef LIBXML_DEBUG_ENABLED
749 printf("\t--debug : dump a debug tree of the in-memory document\n");
750 printf("\t--shell : run a navigating shell\n");
751 printf("\t--debugent : debug the entities defined in the document\n");
752#endif
753 printf("\t--copy : used to test the internal copy implementation\n");
754 printf("\t--recover : output what was parsable on broken XML documents\n");
755 printf("\t--noent : substitute entity references by their value\n");
756 printf("\t--noout : don't output the result tree\n");
757 printf("\t--htmlout : output results as HTML\n");
758 printf("\t--nowarp : do not put HTML doc wrapper\n");
759 printf("\t--valid : validate the document in addition to std well-formed check\n");
760 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
Daniel Veillardcd429612000-10-11 15:57:05 +0000761 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000762 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
763 printf("\t--insert : ad-hoc test for valid insertions\n");
764 printf("\t--compress : turn on gzip compression of output\n");
765#ifdef LIBXML_HTML_ENABLED
766 printf("\t--html : use the HTML parser\n");
767#endif
768 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard46e370e2000-07-21 20:32:03 +0000769#ifdef HAVE_SYS_MMAN_H
770 printf("\t--memory : parse from memory\n");
771#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000772 printf("\t--nowarning : do not emit warnings from parser/validator\n");
773 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard5e873c42000-04-12 13:27:38 +0000774 printf("\t--testIO : test user I/O support\n");
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000775 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000776 }
777 xmlCleanupParser();
778 xmlMemoryDump();
779
780 return(0);
781}
Daniel Veillard88a172f2000-08-04 18:23:10 +0000782