blob: 8cb17b4fb6f41b22d95b22ca7722fa831f45ea48 [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 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillardce8b83b2000-04-05 18:38:42 +00007 */
8
Bjorn Reese70a9da52001-04-21 16:57:29 +00009#include "libxml.h"
Daniel Veillardce8b83b2000-04-05 18:38:42 +000010
Daniel Veillardce8b83b2000-04-05 18:38:42 +000011#include <string.h>
Daniel Veillardce8b83b2000-04-05 18:38:42 +000012#include <stdarg.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000013#ifdef _WIN32
14#ifdef _MSC_VER
15#include <winsock2.h>
16#pragma comment(lib, "ws2_32.lib")
17#define gettimeofday(p1,p2)
18#endif /* _MSC_VER */
19#else /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000020#include <sys/time.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000021#endif /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000022
Daniel Veillardce8b83b2000-04-05 18:38:42 +000023
24#ifdef HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27#ifdef HAVE_SYS_STAT_H
28#include <sys/stat.h>
29#endif
30#ifdef HAVE_FCNTL_H
31#include <fcntl.h>
32#endif
33#ifdef HAVE_UNISTD_H
34#include <unistd.h>
35#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000036#ifdef HAVE_SYS_MMAN_H
37#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000038/* seems needed for Solaris */
39#ifndef MAP_FAILED
40#define MAP_FAILED ((void *) -1)
41#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000042#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000043#ifdef HAVE_STDLIB_H
44#include <stdlib.h>
45#endif
46#ifdef HAVE_LIBREADLINE
47#include <readline/readline.h>
48#ifdef HAVE_LIBHISTORY
49#include <readline/history.h>
50#endif
51#endif
52
53#include <libxml/xmlmemory.h>
54#include <libxml/parser.h>
55#include <libxml/parserInternals.h>
56#include <libxml/HTMLparser.h>
57#include <libxml/HTMLtree.h>
58#include <libxml/tree.h>
59#include <libxml/xpath.h>
60#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000061#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000062#ifdef LIBXML_XINCLUDE_ENABLED
63#include <libxml/xinclude.h>
64#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000065#ifdef LIBXML_CATALOG_ENABLED
66#include <libxml/catalog.h>
67#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000068
69#ifdef LIBXML_DEBUG_ENABLED
70static int debug = 0;
71static int shell = 0;
72static int debugent = 0;
73#endif
74static int copy = 0;
75static int recovery = 0;
76static int noent = 0;
77static int noout = 0;
78static int nowrap = 0;
79static int valid = 0;
80static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +000081static char * dtdvalid = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000082static int repeat = 0;
83static int insert = 0;
84static int compress = 0;
85static int html = 0;
86static int htmlout = 0;
87static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +000088#ifdef HAVE_SYS_MMAN_H
89static int memory = 0;
90#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000091static int noblanks = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000092static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000093static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000094#ifdef LIBXML_XINCLUDE_ENABLED
95static int xinclude = 0;
96#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +000097static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +000098static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +000099static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000100static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000101static struct timeval begin, end;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000102
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000103
104#ifdef VMS
105extern int xmlDoValidityCheckingDefaultVal;
106#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
107#else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000108extern int xmlDoValidityCheckingDefaultValue;
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000109#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000110extern int xmlGetWarningsDefaultValue;
111
112/************************************************************************
113 * *
114 * HTML ouput *
115 * *
116 ************************************************************************/
117char buffer[50000];
118
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000119static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000120xmlHTMLEncodeSend(void) {
121 char *result;
122
123 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
124 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000125 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000126 xmlFree(result);
127 }
128 buffer[0] = 0;
129}
130
131/**
132 * xmlHTMLPrintFileInfo:
133 * @input: an xmlParserInputPtr input
134 *
135 * Displays the associated file and line informations for the current input
136 */
137
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000138static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000139xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000140 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000141 if (input != NULL) {
142 if (input->filename) {
143 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
144 input->line);
145 } else {
146 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
147 }
148 }
149 xmlHTMLEncodeSend();
150}
151
152/**
153 * xmlHTMLPrintFileContext:
154 * @input: an xmlParserInputPtr input
155 *
156 * Displays current context within the input content for error tracking
157 */
158
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000159static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000160xmlHTMLPrintFileContext(xmlParserInputPtr input) {
161 const xmlChar *cur, *base;
162 int n;
163
164 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000165 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000166 cur = input->cur;
167 base = input->base;
168 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
169 cur--;
170 }
171 n = 0;
172 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
173 cur--;
174 if ((*cur == '\n') || (*cur == '\r')) cur++;
175 base = cur;
176 n = 0;
177 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
178 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
179 n++;
180 }
181 sprintf(&buffer[strlen(buffer)], "\n");
182 cur = input->cur;
183 while ((*cur == '\n') || (*cur == '\r'))
184 cur--;
185 n = 0;
186 while ((cur != base) && (n++ < 80)) {
187 sprintf(&buffer[strlen(buffer)], " ");
188 base++;
189 }
190 sprintf(&buffer[strlen(buffer)],"^\n");
191 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000192 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000193}
194
195/**
196 * xmlHTMLError:
197 * @ctx: an XML parser context
198 * @msg: the message to display/transmit
199 * @...: extra parameters for the message display
200 *
201 * Display and format an error messages, gives file, line, position and
202 * extra parameters.
203 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000204static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000205xmlHTMLError(void *ctx, const char *msg, ...)
206{
207 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
208 xmlParserInputPtr input;
209 xmlParserInputPtr cur = NULL;
210 va_list args;
211
212 buffer[0] = 0;
213 input = ctxt->input;
214 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
215 cur = input;
216 input = ctxt->inputTab[ctxt->inputNr - 2];
217 }
218
219 xmlHTMLPrintFileInfo(input);
220
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000221 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000222 va_start(args, msg);
223 vsprintf(&buffer[strlen(buffer)], msg, args);
224 va_end(args);
225 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000226 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000227
228 xmlHTMLPrintFileContext(input);
229 xmlHTMLEncodeSend();
230}
231
232/**
233 * xmlHTMLWarning:
234 * @ctx: an XML parser context
235 * @msg: the message to display/transmit
236 * @...: extra parameters for the message display
237 *
238 * Display and format a warning messages, gives file, line, position and
239 * extra parameters.
240 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000241static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000242xmlHTMLWarning(void *ctx, const char *msg, ...)
243{
244 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
245 xmlParserInputPtr input;
246 xmlParserInputPtr cur = NULL;
247 va_list args;
248
249 buffer[0] = 0;
250 input = ctxt->input;
251 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
252 cur = input;
253 input = ctxt->inputTab[ctxt->inputNr - 2];
254 }
255
256
257 xmlHTMLPrintFileInfo(input);
258
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000259 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000260 va_start(args, msg);
261 vsprintf(&buffer[strlen(buffer)], msg, args);
262 va_end(args);
263 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000264 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000265
266 xmlHTMLPrintFileContext(input);
267 xmlHTMLEncodeSend();
268}
269
270/**
271 * xmlHTMLValidityError:
272 * @ctx: an XML parser context
273 * @msg: the message to display/transmit
274 * @...: extra parameters for the message display
275 *
276 * Display and format an validity error messages, gives file,
277 * line, position and extra parameters.
278 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000279static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000280xmlHTMLValidityError(void *ctx, const char *msg, ...)
281{
282 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
283 xmlParserInputPtr input;
284 va_list args;
285
286 buffer[0] = 0;
287 input = ctxt->input;
288 if ((input->filename == NULL) && (ctxt->inputNr > 1))
289 input = ctxt->inputTab[ctxt->inputNr - 2];
290
291 xmlHTMLPrintFileInfo(input);
292
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000293 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000294 va_start(args, msg);
295 vsprintf(&buffer[strlen(buffer)], msg, args);
296 va_end(args);
297 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000298 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000299
300 xmlHTMLPrintFileContext(input);
301 xmlHTMLEncodeSend();
302}
303
304/**
305 * xmlHTMLValidityWarning:
306 * @ctx: an XML parser context
307 * @msg: the message to display/transmit
308 * @...: extra parameters for the message display
309 *
310 * Display and format a validity warning messages, gives file, line,
311 * position and extra parameters.
312 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000313static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000314xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
315{
316 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
317 xmlParserInputPtr input;
318 va_list args;
319
320 buffer[0] = 0;
321 input = ctxt->input;
322 if ((input->filename == NULL) && (ctxt->inputNr > 1))
323 input = ctxt->inputTab[ctxt->inputNr - 2];
324
325 xmlHTMLPrintFileInfo(input);
326
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000327 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000328 va_start(args, msg);
329 vsprintf(&buffer[strlen(buffer)], msg, args);
330 va_end(args);
331 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000332 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000333
334 xmlHTMLPrintFileContext(input);
335 xmlHTMLEncodeSend();
336}
337
338/************************************************************************
339 * *
340 * Shell Interface *
341 * *
342 ************************************************************************/
343/**
344 * xmlShellReadline:
345 * @prompt: the prompt value
346 *
347 * Read a string
348 *
349 * Returns a pointer to it or NULL on EOF the caller is expected to
350 * free the returned string.
351 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000352static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000353xmlShellReadline(char *prompt) {
354#ifdef HAVE_LIBREADLINE
355 char *line_read;
356
357 /* Get a line from the user. */
358 line_read = readline (prompt);
359
360 /* If the line has any text in it, save it on the history. */
361 if (line_read && *line_read)
362 add_history (line_read);
363
364 return (line_read);
365#else
366 char line_read[501];
367
368 if (prompt != NULL)
369 fprintf(stdout, "%s", prompt);
370 if (!fgets(line_read, 500, stdin))
371 return(NULL);
372 line_read[500] = 0;
373 return(strdup(line_read));
374#endif
375}
376
377/************************************************************************
378 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000379 * I/O Interfaces *
380 * *
381 ************************************************************************/
382
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000383static int myRead(FILE *f, char * buf, int len) {
384 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000385}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000386static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000387 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000388 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000389 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000390}
391
392/************************************************************************
393 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000394 * Test processing *
395 * *
396 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000397static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000398 xmlDocPtr doc = NULL, tmp;
399
Daniel Veillard48b2f892001-02-25 16:11:03 +0000400 if ((timing) && (!repeat))
401 gettimeofday(&begin, NULL);
402
403
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000404 if (filename == NULL) {
405 if (generate) {
406 xmlNodePtr n;
407
408 doc = xmlNewDoc(BAD_CAST "1.0");
409 n = xmlNewNode(NULL, BAD_CAST "info");
410 xmlNodeSetContent(n, BAD_CAST "abc");
411 xmlDocSetRootElement(doc, n);
412 }
413 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000414#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000415 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000416 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000417 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000418#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000419 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000420 /*
421 * build an XML tree from a string;
422 */
423 if (push) {
424 FILE *f;
425
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000426 /* '-' Usually means stdin -<sven@zen.org> */
427 if ((filename[0] == '-') && (filename[1] == 0)) {
428 f = stdin;
429 } else {
430 f = fopen(filename, "r");
431 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000432 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000433 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000434 int res, size = 3;
435 char chars[1024];
436 xmlParserCtxtPtr ctxt;
437
438 if (repeat)
439 size = 1024;
440 res = fread(chars, 1, 4, f);
441 if (res > 0) {
442 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
443 chars, res, filename);
444 while ((res = fread(chars, 1, size, f)) > 0) {
445 xmlParseChunk(ctxt, chars, res, 0);
446 }
447 xmlParseChunk(ctxt, chars, 0, 1);
448 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000449 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000450 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000451 if (!ret) {
452 xmlFreeDoc(doc);
453 doc = NULL;
454 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000455 }
456 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000457 } else if (testIO) {
458 int ret;
459 FILE *f;
460
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000461 /* '-' Usually means stdin -<sven@zen.org> */
462 if ((filename[0] == '-') && (filename[1] == 0)) {
463 f = stdin;
464 } else {
465 f = fopen(filename, "r");
466 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000467 if (f != NULL) {
468 xmlParserCtxtPtr ctxt;
469
470 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
471 (xmlInputReadCallback) myRead,
472 (xmlInputCloseCallback) myClose,
473 f, XML_CHAR_ENCODING_NONE);
474 xmlParseDocument(ctxt);
475
476 ret = ctxt->wellFormed;
477 doc = ctxt->myDoc;
478 xmlFreeParserCtxt(ctxt);
479 if (!ret) {
480 xmlFreeDoc(doc);
481 doc = NULL;
482 }
483 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000484 } else if (recovery) {
485 doc = xmlRecoverFile(filename);
486 } else if (htmlout) {
487 int ret;
488 xmlParserCtxtPtr ctxt;
489 xmlSAXHandler silent, *old;
490
491 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000492
493 if (ctxt == NULL) {
494 /* If xmlCreateFileParseCtxt() return NULL something
495 strange happened so we don't want to do anything. Do
496 we want to print an error message here?
497 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000498 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000499 } else {
500 memcpy(&silent, ctxt->sax, sizeof(silent));
501 old = ctxt->sax;
502 silent.error = xmlHTMLError;
503 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000504 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000505 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000506 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000507 silent.fatalError = xmlHTMLError;
508 ctxt->sax = &silent;
509 ctxt->vctxt.error = xmlHTMLValidityError;
510 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000511 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000512 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000513 ctxt->vctxt.warning = NULL;
514
Daniel Veillard88a172f2000-08-04 18:23:10 +0000515 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000516
Daniel Veillard88a172f2000-08-04 18:23:10 +0000517 ret = ctxt->wellFormed;
518 doc = ctxt->myDoc;
519 ctxt->sax = old;
520 xmlFreeParserCtxt(ctxt);
521 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000522 xmlFreeDoc(doc);
523 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000524 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000525 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000526#ifdef HAVE_SYS_MMAN_H
527 } else if (memory) {
528 int fd;
529 struct stat info;
530 const char *base;
531 if (stat(filename, &info) < 0)
532 return;
533 if ((fd = open(filename, O_RDONLY)) < 0)
534 return;
535 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000536 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000537 return;
538
539 doc = xmlParseMemory((char *) base, info.st_size);
540 munmap((char *) base, info.st_size);
541#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000542 } else
543 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000544 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000545
Daniel Veillard88a172f2000-08-04 18:23:10 +0000546 /*
547 * If we don't have a document we might as well give up. Do we
548 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000549 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000550 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000551 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000552 }
553
Daniel Veillard48b2f892001-02-25 16:11:03 +0000554 if ((timing) && (!repeat)) {
555 long msec;
556 gettimeofday(&end, NULL);
557 msec = end.tv_sec - begin.tv_sec;
558 msec *= 1000;
559 msec += (end.tv_usec - begin.tv_usec) / 1000;
560 fprintf(stderr, "Parsing took %ld ms\n", msec);
561 }
562
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000563#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000564 if (xinclude) {
565 if ((timing) && (!repeat)) {
566 gettimeofday(&begin, NULL);
567 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000568 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000569 if ((timing) && (!repeat)) {
570 long msec;
571 gettimeofday(&end, NULL);
572 msec = end.tv_sec - begin.tv_sec;
573 msec *= 1000;
574 msec += (end.tv_usec - begin.tv_usec) / 1000;
575 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
576 }
577 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000578#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000579
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000580#ifdef LIBXML_DEBUG_ENABLED
581 /*
582 * shell interraction
583 */
584 if (shell)
585 xmlShell(doc, filename, xmlShellReadline, stdout);
586#endif
587
588 /*
589 * test intermediate copy if needed.
590 */
591 if (copy) {
592 tmp = doc;
593 doc = xmlCopyDoc(doc, 1);
594 xmlFreeDoc(tmp);
595 }
596
597 if ((insert) && (!html)) {
598 const xmlChar* list[256];
599 int nb, i;
600 xmlNodePtr node;
601
602 if (doc->children != NULL) {
603 node = doc->children;
604 while ((node != NULL) && (node->last == NULL)) node = node->next;
605 if (node != NULL) {
606 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
607 if (nb < 0) {
608 printf("could not get valid list of elements\n");
609 } else if (nb == 0) {
610 printf("No element can be indersted under root\n");
611 } else {
612 printf("%d element types can be indersted under root:\n",
613 nb);
614 for (i = 0;i < nb;i++) {
615 printf("%s\n", list[i]);
616 }
617 }
618 }
619 }
620 }else if (noout == 0) {
621 /*
622 * print it.
623 */
624#ifdef LIBXML_DEBUG_ENABLED
625 if (!debug) {
626#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000627 if ((timing) && (!repeat)) {
628 gettimeofday(&begin, NULL);
629 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000630#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000631 if (memory) {
632 xmlChar *result;
633 int len;
634
635 if (encoding != NULL) {
636 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
637 } else {
638 xmlDocDumpMemory(doc, &result, &len);
639 }
640 if (result == NULL) {
641 fprintf(stderr, "Failed to save\n");
642 } else {
643 write(1, result, len);
644 xmlFree(result);
645 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000646 } else
647#endif /* HAVE_SYS_MMAN_H */
648 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000649 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000650 else if (encoding != NULL)
651 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000652 else
653 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000654 if ((timing) && (!repeat)) {
655 long msec;
656 gettimeofday(&end, NULL);
657 msec = end.tv_sec - begin.tv_sec;
658 msec *= 1000;
659 msec += (end.tv_usec - begin.tv_usec) / 1000;
660 fprintf(stderr, "Saving took %ld ms\n", msec);
661 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000662#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000663 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000664 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000665 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000666#endif
667 }
668
669 /*
670 * A posteriori validation test
671 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000672 if (dtdvalid != NULL) {
673 xmlDtdPtr dtd;
674
Daniel Veillard48b2f892001-02-25 16:11:03 +0000675 if ((timing) && (!repeat)) {
676 gettimeofday(&begin, NULL);
677 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000678 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000679 if ((timing) && (!repeat)) {
680 long msec;
681 gettimeofday(&end, NULL);
682 msec = end.tv_sec - begin.tv_sec;
683 msec *= 1000;
684 msec += (end.tv_usec - begin.tv_usec) / 1000;
685 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
686 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000687 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000688 xmlGenericError(xmlGenericErrorContext,
689 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000690 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000691 } else {
692 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000693 if ((timing) && (!repeat)) {
694 gettimeofday(&begin, NULL);
695 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000696 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
697 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000698 xmlGenericError(xmlGenericErrorContext,
699 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000700 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000701 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000702 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000703 if ((timing) && (!repeat)) {
704 long msec;
705 gettimeofday(&end, NULL);
706 msec = end.tv_sec - begin.tv_sec;
707 msec *= 1000;
708 msec += (end.tv_usec - begin.tv_usec) / 1000;
709 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
710 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000711 xmlFreeDtd(dtd);
712 }
713 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000714 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000715 if ((timing) && (!repeat)) {
716 gettimeofday(&begin, NULL);
717 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000718 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000719 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000720 xmlGenericError(xmlGenericErrorContext,
721 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000722 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000723 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000724 if ((timing) && (!repeat)) {
725 long msec;
726 gettimeofday(&end, NULL);
727 msec = end.tv_sec - begin.tv_sec;
728 msec *= 1000;
729 msec += (end.tv_usec - begin.tv_usec) / 1000;
730 fprintf(stderr, "Validating took %ld ms\n", msec);
731 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000732 }
733
734#ifdef LIBXML_DEBUG_ENABLED
735 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000736 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000737#endif
738
739 /*
740 * free it.
741 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000742 if ((timing) && (!repeat)) {
743 gettimeofday(&begin, NULL);
744 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000745 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000746 if ((timing) && (!repeat)) {
747 long msec;
748 gettimeofday(&end, NULL);
749 msec = end.tv_sec - begin.tv_sec;
750 msec *= 1000;
751 msec += (end.tv_usec - begin.tv_usec) / 1000;
752 fprintf(stderr, "Freeing took %ld ms\n", msec);
753 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000754}
755
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000756/************************************************************************
757 * *
758 * Usage and Main *
759 * *
760 ************************************************************************/
761
762static void usage(const char *name) {
763 printf("Usage : %s [options] XMLfiles ...\n", name);
764 printf("\tParse the XML files and output the result of the parsing\n");
765 printf("\t--version : display the version of the XML library used\n");
766#ifdef LIBXML_DEBUG_ENABLED
767 printf("\t--debug : dump a debug tree of the in-memory document\n");
768 printf("\t--shell : run a navigating shell\n");
769 printf("\t--debugent : debug the entities defined in the document\n");
770#endif
771 printf("\t--copy : used to test the internal copy implementation\n");
772 printf("\t--recover : output what was parsable on broken XML documents\n");
773 printf("\t--noent : substitute entity references by their value\n");
774 printf("\t--noout : don't output the result tree\n");
775 printf("\t--htmlout : output results as HTML\n");
776 printf("\t--nowarp : do not put HTML doc wrapper\n");
777 printf("\t--valid : validate the document in addition to std well-formed check\n");
778 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
779 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
780 printf("\t--timing : print some timings\n");
781 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
782 printf("\t--insert : ad-hoc test for valid insertions\n");
783 printf("\t--compress : turn on gzip compression of output\n");
784#ifdef LIBXML_HTML_ENABLED
785 printf("\t--html : use the HTML parser\n");
786#endif
787 printf("\t--push : use the push mode of the parser\n");
788#ifdef HAVE_SYS_MMAN_H
789 printf("\t--memory : parse from memory\n");
790#endif
791 printf("\t--nowarning : do not emit warnings from parser/validator\n");
792 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
793 printf("\t--testIO : test user I/O support\n");
794 printf("\t--encode encoding : output in the given encoding\n");
795#ifdef LIBXML_CATALOG_ENABLED
796 printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
797#endif
798 printf("\t--auto : generate a small doc on the fly\n");
799#ifdef LIBXML_XINCLUDE_ENABLED
800 printf("\t--xinclude : do XInclude processing\n");
801 printf("\t--loaddtd : fetch external Dtd\n");
802#endif
803}
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000804int
805main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000806 int i, count;
807 int files = 0;
808
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000809 if (argc <= 1) {
810 usage(argv[0]);
811 return(1);
812 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000813 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000814 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000815 if (!strcmp(argv[i], "-"))
816 break;
817
818 if (argv[i][0] != '-')
819 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000820#ifdef LIBXML_DEBUG_ENABLED
821 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
822 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000823 else if ((!strcmp(argv[i], "-shell")) ||
824 (!strcmp(argv[i], "--shell"))) {
825 shell++;
826 noout = 1;
827 } else
828#endif
829 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
830 copy++;
831 else if ((!strcmp(argv[i], "-recover")) ||
832 (!strcmp(argv[i], "--recover")))
833 recovery++;
834 else if ((!strcmp(argv[i], "-noent")) ||
835 (!strcmp(argv[i], "--noent")))
836 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +0000837 else if ((!strcmp(argv[i], "-version")) ||
838 (!strcmp(argv[i], "--version")))
839 fprintf(stderr, "xmllint: using libxml version %s\n",
840 xmlParserVersion);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000841 else if ((!strcmp(argv[i], "-noout")) ||
842 (!strcmp(argv[i], "--noout")))
843 noout++;
844 else if ((!strcmp(argv[i], "-htmlout")) ||
845 (!strcmp(argv[i], "--htmlout")))
846 htmlout++;
847#ifdef LIBXML_HTML_ENABLED
848 else if ((!strcmp(argv[i], "-html")) ||
849 (!strcmp(argv[i], "--html"))) {
850 html++;
851 }
852#endif /* LIBXML_HTML_ENABLED */
853 else if ((!strcmp(argv[i], "-nowrap")) ||
854 (!strcmp(argv[i], "--nowrap")))
855 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000856 else if ((!strcmp(argv[i], "-loaddtd")) ||
857 (!strcmp(argv[i], "--loaddtd")))
858 loaddtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000859 else if ((!strcmp(argv[i], "-valid")) ||
860 (!strcmp(argv[i], "--valid")))
861 valid++;
862 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000863 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000864 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000865 loaddtd++;
866 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +0000867 (!strcmp(argv[i], "--dtdvalid"))) {
868 i++;
869 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000870 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000871 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000872 else if ((!strcmp(argv[i], "-insert")) ||
873 (!strcmp(argv[i], "--insert")))
874 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000875 else if ((!strcmp(argv[i], "-timing")) ||
876 (!strcmp(argv[i], "--timing")))
877 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000878 else if ((!strcmp(argv[i], "-auto")) ||
879 (!strcmp(argv[i], "--auto")))
880 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000881 else if ((!strcmp(argv[i], "-repeat")) ||
882 (!strcmp(argv[i], "--repeat")))
883 repeat++;
884 else if ((!strcmp(argv[i], "-push")) ||
885 (!strcmp(argv[i], "--push")))
886 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000887#ifdef HAVE_SYS_MMAN_H
888 else if ((!strcmp(argv[i], "-memory")) ||
889 (!strcmp(argv[i], "--memory")))
890 memory++;
891#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000892 else if ((!strcmp(argv[i], "-testIO")) ||
893 (!strcmp(argv[i], "--testIO")))
894 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000895#ifdef LIBXML_XINCLUDE_ENABLED
896 else if ((!strcmp(argv[i], "-xinclude")) ||
897 (!strcmp(argv[i], "--xinclude")))
898 xinclude++;
899#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000900 else if ((!strcmp(argv[i], "-compress")) ||
901 (!strcmp(argv[i], "--compress"))) {
902 compress++;
903 xmlSetCompressMode(9);
904 }
905 else if ((!strcmp(argv[i], "-nowarning")) ||
906 (!strcmp(argv[i], "--nowarning"))) {
907 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000908 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000909 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000910 else if ((!strcmp(argv[i], "-pedantic")) ||
911 (!strcmp(argv[i], "--pedantic"))) {
912 xmlGetWarningsDefaultValue = 1;
913 xmlPedanticParserDefault(1);
914 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000915#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000916 else if ((!strcmp(argv[i], "-debugent")) ||
917 (!strcmp(argv[i], "--debugent"))) {
918 debugent++;
919 xmlParserDebugEntities = 1;
920 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000921#endif
Daniel Veillard81418e32001-05-22 15:08:55 +0000922#ifdef LIBXML_CATALOG_ENABLED
923 else if ((!strcmp(argv[i], "-catalogs")) ||
924 (!strcmp(argv[i], "--catalogs"))) {
925 const char *catalogs;
926
927 catalogs = getenv("SGML_CATALOG_FILES");
928 if (catalogs == NULL) {
929 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
930 } else {
931 xmlLoadCatalogs(catalogs);
932 }
933 }
934#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000935 else if ((!strcmp(argv[i], "-encode")) ||
936 (!strcmp(argv[i], "--encode"))) {
937 i++;
938 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000939 /*
940 * OK it's for testing purposes
941 */
942 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000943 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000944 else if ((!strcmp(argv[i], "-noblanks")) ||
945 (!strcmp(argv[i], "--noblanks"))) {
946 noblanks++;
947 xmlKeepBlanksDefault(0);
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000948 } else {
949 fprintf(stderr, "Unknown option %s\n", argv[i]);
950 usage(argv[0]);
951 return(1);
952 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000953 }
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000954 if (loaddtd != 0) xmlLoadExtDtdDefaultValue = 6; /* fetch DTDs by default */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000955 if (noent != 0) xmlSubstituteEntitiesDefault(1);
956 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
957 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000958 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000959 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000960 xmlGenericError(xmlGenericErrorContext,
961 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
962 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000963 "<html><head><title>%s output</title></head>\n",
964 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000965 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000966 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
967 argv[0]);
968 }
969 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000970 if ((!strcmp(argv[i], "-encode")) ||
971 (!strcmp(argv[i], "--encode"))) {
972 i++;
973 continue;
974 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000975 if ((!strcmp(argv[i], "-dtdvalid")) ||
976 (!strcmp(argv[i], "--dtdvalid"))) {
977 i++;
978 continue;
979 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000980 if ((timing) && (repeat))
981 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000982 /* Remember file names. "-" means stding. <sven@zen.org> */
983 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000984 if (repeat) {
985 for (count = 0;count < 100 * repeat;count++)
986 parseAndPrintFile(argv[i]);
987 } else
988 parseAndPrintFile(argv[i]);
989 files ++;
990 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000991 if ((timing) && (repeat)) {
992 long msec;
993 gettimeofday(&end, NULL);
994 msec = end.tv_sec - begin.tv_sec;
995 msec *= 1000;
996 msec += (end.tv_usec - begin.tv_usec) / 1000;
997 fprintf(stderr, "100 iteration took %ld ms\n", msec);
998 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000999 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001000 if (generate)
1001 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001002 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001003 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001004 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001005 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001006 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001007 }
1008 xmlCleanupParser();
1009 xmlMemoryDump();
1010
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001011 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001012}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001013