blob: cce235b7f9d44e86cbd05953353778e02482ff97 [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 Veillard28ae6362001-07-14 16:44:32 +000013
Daniel Veillard2d90de42001-04-16 17:46:18 +000014#ifdef _WIN32
15#ifdef _MSC_VER
16#include <winsock2.h>
17#pragma comment(lib, "ws2_32.lib")
18#define gettimeofday(p1,p2)
Daniel Veillard28ae6362001-07-14 16:44:32 +000019#else /* _MSC_VER */
20#include <sys/time.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000021#endif /* _MSC_VER */
22#else /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000023#include <sys/time.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000024#endif /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000025
Daniel Veillardce8b83b2000-04-05 18:38:42 +000026
27#ifdef HAVE_SYS_TYPES_H
28#include <sys/types.h>
29#endif
30#ifdef HAVE_SYS_STAT_H
31#include <sys/stat.h>
32#endif
33#ifdef HAVE_FCNTL_H
34#include <fcntl.h>
35#endif
36#ifdef HAVE_UNISTD_H
37#include <unistd.h>
38#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000039#ifdef HAVE_SYS_MMAN_H
40#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000041/* seems needed for Solaris */
42#ifndef MAP_FAILED
43#define MAP_FAILED ((void *) -1)
44#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000045#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000046#ifdef HAVE_STDLIB_H
47#include <stdlib.h>
48#endif
49#ifdef HAVE_LIBREADLINE
50#include <readline/readline.h>
51#ifdef HAVE_LIBHISTORY
52#include <readline/history.h>
53#endif
54#endif
55
56#include <libxml/xmlmemory.h>
57#include <libxml/parser.h>
58#include <libxml/parserInternals.h>
59#include <libxml/HTMLparser.h>
60#include <libxml/HTMLtree.h>
61#include <libxml/tree.h>
62#include <libxml/xpath.h>
63#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000064#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000065#ifdef LIBXML_XINCLUDE_ENABLED
66#include <libxml/xinclude.h>
67#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000068#ifdef LIBXML_CATALOG_ENABLED
69#include <libxml/catalog.h>
70#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000071
72#ifdef LIBXML_DEBUG_ENABLED
73static int debug = 0;
74static int shell = 0;
75static int debugent = 0;
76#endif
77static int copy = 0;
78static int recovery = 0;
79static int noent = 0;
80static int noout = 0;
81static int nowrap = 0;
82static int valid = 0;
83static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +000084static char * dtdvalid = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000085static int repeat = 0;
86static int insert = 0;
87static int compress = 0;
88static int html = 0;
89static int htmlout = 0;
90static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +000091#ifdef HAVE_SYS_MMAN_H
92static int memory = 0;
93#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000094static int noblanks = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000095static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000096static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000097#ifdef LIBXML_XINCLUDE_ENABLED
98static int xinclude = 0;
99#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000100static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000101static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000102static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000103static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000104static struct timeval begin, end;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000105
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000106
107#ifdef VMS
108extern int xmlDoValidityCheckingDefaultVal;
109#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
110#else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000111extern int xmlDoValidityCheckingDefaultValue;
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000112#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000113extern int xmlGetWarningsDefaultValue;
114
115/************************************************************************
116 * *
117 * HTML ouput *
118 * *
119 ************************************************************************/
120char buffer[50000];
121
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000122static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000123xmlHTMLEncodeSend(void) {
124 char *result;
125
126 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
127 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000128 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000129 xmlFree(result);
130 }
131 buffer[0] = 0;
132}
133
134/**
135 * xmlHTMLPrintFileInfo:
136 * @input: an xmlParserInputPtr input
137 *
138 * Displays the associated file and line informations for the current input
139 */
140
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000141static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000142xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000143 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000144 if (input != NULL) {
145 if (input->filename) {
146 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
147 input->line);
148 } else {
149 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
150 }
151 }
152 xmlHTMLEncodeSend();
153}
154
155/**
156 * xmlHTMLPrintFileContext:
157 * @input: an xmlParserInputPtr input
158 *
159 * Displays current context within the input content for error tracking
160 */
161
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000162static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000163xmlHTMLPrintFileContext(xmlParserInputPtr input) {
164 const xmlChar *cur, *base;
165 int n;
166
167 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000168 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000169 cur = input->cur;
170 base = input->base;
171 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
172 cur--;
173 }
174 n = 0;
175 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
176 cur--;
177 if ((*cur == '\n') || (*cur == '\r')) cur++;
178 base = cur;
179 n = 0;
180 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
181 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
182 n++;
183 }
184 sprintf(&buffer[strlen(buffer)], "\n");
185 cur = input->cur;
186 while ((*cur == '\n') || (*cur == '\r'))
187 cur--;
188 n = 0;
189 while ((cur != base) && (n++ < 80)) {
190 sprintf(&buffer[strlen(buffer)], " ");
191 base++;
192 }
193 sprintf(&buffer[strlen(buffer)],"^\n");
194 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000195 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000196}
197
198/**
199 * xmlHTMLError:
200 * @ctx: an XML parser context
201 * @msg: the message to display/transmit
202 * @...: extra parameters for the message display
203 *
204 * Display and format an error messages, gives file, line, position and
205 * extra parameters.
206 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000207static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000208xmlHTMLError(void *ctx, const char *msg, ...)
209{
210 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
211 xmlParserInputPtr input;
212 xmlParserInputPtr cur = NULL;
213 va_list args;
214
215 buffer[0] = 0;
216 input = ctxt->input;
217 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
218 cur = input;
219 input = ctxt->inputTab[ctxt->inputNr - 2];
220 }
221
222 xmlHTMLPrintFileInfo(input);
223
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000224 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000225 va_start(args, msg);
226 vsprintf(&buffer[strlen(buffer)], msg, args);
227 va_end(args);
228 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000229 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000230
231 xmlHTMLPrintFileContext(input);
232 xmlHTMLEncodeSend();
233}
234
235/**
236 * xmlHTMLWarning:
237 * @ctx: an XML parser context
238 * @msg: the message to display/transmit
239 * @...: extra parameters for the message display
240 *
241 * Display and format a warning messages, gives file, line, position and
242 * extra parameters.
243 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000244static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000245xmlHTMLWarning(void *ctx, const char *msg, ...)
246{
247 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
248 xmlParserInputPtr input;
249 xmlParserInputPtr cur = NULL;
250 va_list args;
251
252 buffer[0] = 0;
253 input = ctxt->input;
254 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
255 cur = input;
256 input = ctxt->inputTab[ctxt->inputNr - 2];
257 }
258
259
260 xmlHTMLPrintFileInfo(input);
261
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000262 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000263 va_start(args, msg);
264 vsprintf(&buffer[strlen(buffer)], msg, args);
265 va_end(args);
266 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000267 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000268
269 xmlHTMLPrintFileContext(input);
270 xmlHTMLEncodeSend();
271}
272
273/**
274 * xmlHTMLValidityError:
275 * @ctx: an XML parser context
276 * @msg: the message to display/transmit
277 * @...: extra parameters for the message display
278 *
279 * Display and format an validity error messages, gives file,
280 * line, position and extra parameters.
281 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000282static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000283xmlHTMLValidityError(void *ctx, const char *msg, ...)
284{
285 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
286 xmlParserInputPtr input;
287 va_list args;
288
289 buffer[0] = 0;
290 input = ctxt->input;
291 if ((input->filename == NULL) && (ctxt->inputNr > 1))
292 input = ctxt->inputTab[ctxt->inputNr - 2];
293
294 xmlHTMLPrintFileInfo(input);
295
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000296 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000297 va_start(args, msg);
298 vsprintf(&buffer[strlen(buffer)], msg, args);
299 va_end(args);
300 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000301 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000302
303 xmlHTMLPrintFileContext(input);
304 xmlHTMLEncodeSend();
305}
306
307/**
308 * xmlHTMLValidityWarning:
309 * @ctx: an XML parser context
310 * @msg: the message to display/transmit
311 * @...: extra parameters for the message display
312 *
313 * Display and format a validity warning messages, gives file, line,
314 * position and extra parameters.
315 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000316static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000317xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
318{
319 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
320 xmlParserInputPtr input;
321 va_list args;
322
323 buffer[0] = 0;
324 input = ctxt->input;
325 if ((input->filename == NULL) && (ctxt->inputNr > 1))
326 input = ctxt->inputTab[ctxt->inputNr - 2];
327
328 xmlHTMLPrintFileInfo(input);
329
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000330 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000331 va_start(args, msg);
332 vsprintf(&buffer[strlen(buffer)], msg, args);
333 va_end(args);
334 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000335 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000336
337 xmlHTMLPrintFileContext(input);
338 xmlHTMLEncodeSend();
339}
340
341/************************************************************************
342 * *
343 * Shell Interface *
344 * *
345 ************************************************************************/
346/**
347 * xmlShellReadline:
348 * @prompt: the prompt value
349 *
350 * Read a string
351 *
352 * Returns a pointer to it or NULL on EOF the caller is expected to
353 * free the returned string.
354 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000355static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000356xmlShellReadline(char *prompt) {
357#ifdef HAVE_LIBREADLINE
358 char *line_read;
359
360 /* Get a line from the user. */
361 line_read = readline (prompt);
362
363 /* If the line has any text in it, save it on the history. */
364 if (line_read && *line_read)
365 add_history (line_read);
366
367 return (line_read);
368#else
369 char line_read[501];
370
371 if (prompt != NULL)
372 fprintf(stdout, "%s", prompt);
373 if (!fgets(line_read, 500, stdin))
374 return(NULL);
375 line_read[500] = 0;
376 return(strdup(line_read));
377#endif
378}
379
380/************************************************************************
381 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000382 * I/O Interfaces *
383 * *
384 ************************************************************************/
385
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000386static int myRead(FILE *f, char * buf, int len) {
387 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000388}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000389static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000390 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000391 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000392 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000393}
394
395/************************************************************************
396 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000397 * Test processing *
398 * *
399 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000400static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000401 xmlDocPtr doc = NULL, tmp;
402
Daniel Veillard48b2f892001-02-25 16:11:03 +0000403 if ((timing) && (!repeat))
404 gettimeofday(&begin, NULL);
405
406
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000407 if (filename == NULL) {
408 if (generate) {
409 xmlNodePtr n;
410
411 doc = xmlNewDoc(BAD_CAST "1.0");
412 n = xmlNewNode(NULL, BAD_CAST "info");
413 xmlNodeSetContent(n, BAD_CAST "abc");
414 xmlDocSetRootElement(doc, n);
415 }
416 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000417#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000418 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000419 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000420 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000421#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000422 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000423 /*
424 * build an XML tree from a string;
425 */
426 if (push) {
427 FILE *f;
428
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000429 /* '-' Usually means stdin -<sven@zen.org> */
430 if ((filename[0] == '-') && (filename[1] == 0)) {
431 f = stdin;
432 } else {
433 f = fopen(filename, "r");
434 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000435 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000436 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000437 int res, size = 3;
438 char chars[1024];
439 xmlParserCtxtPtr ctxt;
440
441 if (repeat)
442 size = 1024;
443 res = fread(chars, 1, 4, f);
444 if (res > 0) {
445 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
446 chars, res, filename);
447 while ((res = fread(chars, 1, size, f)) > 0) {
448 xmlParseChunk(ctxt, chars, res, 0);
449 }
450 xmlParseChunk(ctxt, chars, 0, 1);
451 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000452 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000453 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000454 if (!ret) {
455 xmlFreeDoc(doc);
456 doc = NULL;
457 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000458 }
459 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000460 } else if (testIO) {
461 int ret;
462 FILE *f;
463
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000464 /* '-' Usually means stdin -<sven@zen.org> */
465 if ((filename[0] == '-') && (filename[1] == 0)) {
466 f = stdin;
467 } else {
468 f = fopen(filename, "r");
469 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000470 if (f != NULL) {
471 xmlParserCtxtPtr ctxt;
472
473 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
474 (xmlInputReadCallback) myRead,
475 (xmlInputCloseCallback) myClose,
476 f, XML_CHAR_ENCODING_NONE);
477 xmlParseDocument(ctxt);
478
479 ret = ctxt->wellFormed;
480 doc = ctxt->myDoc;
481 xmlFreeParserCtxt(ctxt);
482 if (!ret) {
483 xmlFreeDoc(doc);
484 doc = NULL;
485 }
486 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000487 } else if (recovery) {
488 doc = xmlRecoverFile(filename);
489 } else if (htmlout) {
490 int ret;
491 xmlParserCtxtPtr ctxt;
492 xmlSAXHandler silent, *old;
493
494 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000495
496 if (ctxt == NULL) {
497 /* If xmlCreateFileParseCtxt() return NULL something
498 strange happened so we don't want to do anything. Do
499 we want to print an error message here?
500 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000501 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000502 } else {
503 memcpy(&silent, ctxt->sax, sizeof(silent));
504 old = ctxt->sax;
505 silent.error = xmlHTMLError;
506 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000507 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000508 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000509 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000510 silent.fatalError = xmlHTMLError;
511 ctxt->sax = &silent;
512 ctxt->vctxt.error = xmlHTMLValidityError;
513 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000514 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000515 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000516 ctxt->vctxt.warning = NULL;
517
Daniel Veillard88a172f2000-08-04 18:23:10 +0000518 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000519
Daniel Veillard88a172f2000-08-04 18:23:10 +0000520 ret = ctxt->wellFormed;
521 doc = ctxt->myDoc;
522 ctxt->sax = old;
523 xmlFreeParserCtxt(ctxt);
524 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000525 xmlFreeDoc(doc);
526 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000527 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000528 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000529#ifdef HAVE_SYS_MMAN_H
530 } else if (memory) {
531 int fd;
532 struct stat info;
533 const char *base;
534 if (stat(filename, &info) < 0)
535 return;
536 if ((fd = open(filename, O_RDONLY)) < 0)
537 return;
538 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000539 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000540 return;
541
542 doc = xmlParseMemory((char *) base, info.st_size);
543 munmap((char *) base, info.st_size);
544#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000545 } else
546 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000547 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000548
Daniel Veillard88a172f2000-08-04 18:23:10 +0000549 /*
550 * If we don't have a document we might as well give up. Do we
551 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000552 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000553 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000554 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000555 }
556
Daniel Veillard48b2f892001-02-25 16:11:03 +0000557 if ((timing) && (!repeat)) {
558 long msec;
559 gettimeofday(&end, NULL);
560 msec = end.tv_sec - begin.tv_sec;
561 msec *= 1000;
562 msec += (end.tv_usec - begin.tv_usec) / 1000;
563 fprintf(stderr, "Parsing took %ld ms\n", msec);
564 }
565
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000566#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000567 if (xinclude) {
568 if ((timing) && (!repeat)) {
569 gettimeofday(&begin, NULL);
570 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000571 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000572 if ((timing) && (!repeat)) {
573 long msec;
574 gettimeofday(&end, NULL);
575 msec = end.tv_sec - begin.tv_sec;
576 msec *= 1000;
577 msec += (end.tv_usec - begin.tv_usec) / 1000;
578 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
579 }
580 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000581#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000582
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000583#ifdef LIBXML_DEBUG_ENABLED
584 /*
585 * shell interraction
586 */
587 if (shell)
588 xmlShell(doc, filename, xmlShellReadline, stdout);
589#endif
590
591 /*
592 * test intermediate copy if needed.
593 */
594 if (copy) {
595 tmp = doc;
596 doc = xmlCopyDoc(doc, 1);
597 xmlFreeDoc(tmp);
598 }
599
600 if ((insert) && (!html)) {
601 const xmlChar* list[256];
602 int nb, i;
603 xmlNodePtr node;
604
605 if (doc->children != NULL) {
606 node = doc->children;
607 while ((node != NULL) && (node->last == NULL)) node = node->next;
608 if (node != NULL) {
609 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
610 if (nb < 0) {
611 printf("could not get valid list of elements\n");
612 } else if (nb == 0) {
613 printf("No element can be indersted under root\n");
614 } else {
615 printf("%d element types can be indersted under root:\n",
616 nb);
617 for (i = 0;i < nb;i++) {
618 printf("%s\n", list[i]);
619 }
620 }
621 }
622 }
623 }else if (noout == 0) {
624 /*
625 * print it.
626 */
627#ifdef LIBXML_DEBUG_ENABLED
628 if (!debug) {
629#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000630 if ((timing) && (!repeat)) {
631 gettimeofday(&begin, NULL);
632 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000633#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000634 if (memory) {
635 xmlChar *result;
636 int len;
637
638 if (encoding != NULL) {
639 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
640 } else {
641 xmlDocDumpMemory(doc, &result, &len);
642 }
643 if (result == NULL) {
644 fprintf(stderr, "Failed to save\n");
645 } else {
646 write(1, result, len);
647 xmlFree(result);
648 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000649 } else
650#endif /* HAVE_SYS_MMAN_H */
651 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000652 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000653 else if (encoding != NULL)
654 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000655 else
656 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000657 if ((timing) && (!repeat)) {
658 long msec;
659 gettimeofday(&end, NULL);
660 msec = end.tv_sec - begin.tv_sec;
661 msec *= 1000;
662 msec += (end.tv_usec - begin.tv_usec) / 1000;
663 fprintf(stderr, "Saving took %ld ms\n", msec);
664 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000665#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000666 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000667 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000668 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000669#endif
670 }
671
672 /*
673 * A posteriori validation test
674 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000675 if (dtdvalid != NULL) {
676 xmlDtdPtr dtd;
677
Daniel Veillard48b2f892001-02-25 16:11:03 +0000678 if ((timing) && (!repeat)) {
679 gettimeofday(&begin, NULL);
680 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000681 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000682 if ((timing) && (!repeat)) {
683 long msec;
684 gettimeofday(&end, NULL);
685 msec = end.tv_sec - begin.tv_sec;
686 msec *= 1000;
687 msec += (end.tv_usec - begin.tv_usec) / 1000;
688 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
689 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000690 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000691 xmlGenericError(xmlGenericErrorContext,
692 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000693 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000694 } else {
695 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000696 if ((timing) && (!repeat)) {
697 gettimeofday(&begin, NULL);
698 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000699 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
700 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000701 xmlGenericError(xmlGenericErrorContext,
702 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000703 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000704 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000705 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000706 if ((timing) && (!repeat)) {
707 long msec;
708 gettimeofday(&end, NULL);
709 msec = end.tv_sec - begin.tv_sec;
710 msec *= 1000;
711 msec += (end.tv_usec - begin.tv_usec) / 1000;
712 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
713 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000714 xmlFreeDtd(dtd);
715 }
716 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000717 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000718 if ((timing) && (!repeat)) {
719 gettimeofday(&begin, NULL);
720 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000721 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000722 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000723 xmlGenericError(xmlGenericErrorContext,
724 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000725 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000726 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000727 if ((timing) && (!repeat)) {
728 long msec;
729 gettimeofday(&end, NULL);
730 msec = end.tv_sec - begin.tv_sec;
731 msec *= 1000;
732 msec += (end.tv_usec - begin.tv_usec) / 1000;
733 fprintf(stderr, "Validating took %ld ms\n", msec);
734 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000735 }
736
737#ifdef LIBXML_DEBUG_ENABLED
738 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000739 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000740#endif
741
742 /*
743 * free it.
744 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000745 if ((timing) && (!repeat)) {
746 gettimeofday(&begin, NULL);
747 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000748 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000749 if ((timing) && (!repeat)) {
750 long msec;
751 gettimeofday(&end, NULL);
752 msec = end.tv_sec - begin.tv_sec;
753 msec *= 1000;
754 msec += (end.tv_usec - begin.tv_usec) / 1000;
755 fprintf(stderr, "Freeing took %ld ms\n", msec);
756 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000757}
758
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000759/************************************************************************
760 * *
761 * Usage and Main *
762 * *
763 ************************************************************************/
764
765static void usage(const char *name) {
766 printf("Usage : %s [options] XMLfiles ...\n", name);
767 printf("\tParse the XML files and output the result of the parsing\n");
768 printf("\t--version : display the version of the XML library used\n");
769#ifdef LIBXML_DEBUG_ENABLED
770 printf("\t--debug : dump a debug tree of the in-memory document\n");
771 printf("\t--shell : run a navigating shell\n");
772 printf("\t--debugent : debug the entities defined in the document\n");
773#endif
774 printf("\t--copy : used to test the internal copy implementation\n");
775 printf("\t--recover : output what was parsable on broken XML documents\n");
776 printf("\t--noent : substitute entity references by their value\n");
777 printf("\t--noout : don't output the result tree\n");
778 printf("\t--htmlout : output results as HTML\n");
779 printf("\t--nowarp : do not put HTML doc wrapper\n");
780 printf("\t--valid : validate the document in addition to std well-formed check\n");
781 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
782 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
783 printf("\t--timing : print some timings\n");
784 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
785 printf("\t--insert : ad-hoc test for valid insertions\n");
786 printf("\t--compress : turn on gzip compression of output\n");
787#ifdef LIBXML_HTML_ENABLED
788 printf("\t--html : use the HTML parser\n");
789#endif
790 printf("\t--push : use the push mode of the parser\n");
791#ifdef HAVE_SYS_MMAN_H
792 printf("\t--memory : parse from memory\n");
793#endif
794 printf("\t--nowarning : do not emit warnings from parser/validator\n");
795 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
796 printf("\t--testIO : test user I/O support\n");
797 printf("\t--encode encoding : output in the given encoding\n");
798#ifdef LIBXML_CATALOG_ENABLED
799 printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
800#endif
801 printf("\t--auto : generate a small doc on the fly\n");
802#ifdef LIBXML_XINCLUDE_ENABLED
803 printf("\t--xinclude : do XInclude processing\n");
804 printf("\t--loaddtd : fetch external Dtd\n");
805#endif
806}
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000807int
808main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000809 int i, count;
810 int files = 0;
811
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000812 if (argc <= 1) {
813 usage(argv[0]);
814 return(1);
815 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000816 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000817 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000818 if (!strcmp(argv[i], "-"))
819 break;
820
821 if (argv[i][0] != '-')
822 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000823#ifdef LIBXML_DEBUG_ENABLED
824 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
825 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000826 else if ((!strcmp(argv[i], "-shell")) ||
827 (!strcmp(argv[i], "--shell"))) {
828 shell++;
829 noout = 1;
830 } else
831#endif
832 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
833 copy++;
834 else if ((!strcmp(argv[i], "-recover")) ||
835 (!strcmp(argv[i], "--recover")))
836 recovery++;
837 else if ((!strcmp(argv[i], "-noent")) ||
838 (!strcmp(argv[i], "--noent")))
839 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +0000840 else if ((!strcmp(argv[i], "-version")) ||
841 (!strcmp(argv[i], "--version")))
842 fprintf(stderr, "xmllint: using libxml version %s\n",
843 xmlParserVersion);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000844 else if ((!strcmp(argv[i], "-noout")) ||
845 (!strcmp(argv[i], "--noout")))
846 noout++;
847 else if ((!strcmp(argv[i], "-htmlout")) ||
848 (!strcmp(argv[i], "--htmlout")))
849 htmlout++;
850#ifdef LIBXML_HTML_ENABLED
851 else if ((!strcmp(argv[i], "-html")) ||
852 (!strcmp(argv[i], "--html"))) {
853 html++;
854 }
855#endif /* LIBXML_HTML_ENABLED */
856 else if ((!strcmp(argv[i], "-nowrap")) ||
857 (!strcmp(argv[i], "--nowrap")))
858 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000859 else if ((!strcmp(argv[i], "-loaddtd")) ||
860 (!strcmp(argv[i], "--loaddtd")))
861 loaddtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000862 else if ((!strcmp(argv[i], "-valid")) ||
863 (!strcmp(argv[i], "--valid")))
864 valid++;
865 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000866 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000867 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000868 loaddtd++;
869 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +0000870 (!strcmp(argv[i], "--dtdvalid"))) {
871 i++;
872 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000873 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000874 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000875 else if ((!strcmp(argv[i], "-insert")) ||
876 (!strcmp(argv[i], "--insert")))
877 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000878 else if ((!strcmp(argv[i], "-timing")) ||
879 (!strcmp(argv[i], "--timing")))
880 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000881 else if ((!strcmp(argv[i], "-auto")) ||
882 (!strcmp(argv[i], "--auto")))
883 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000884 else if ((!strcmp(argv[i], "-repeat")) ||
885 (!strcmp(argv[i], "--repeat")))
886 repeat++;
887 else if ((!strcmp(argv[i], "-push")) ||
888 (!strcmp(argv[i], "--push")))
889 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000890#ifdef HAVE_SYS_MMAN_H
891 else if ((!strcmp(argv[i], "-memory")) ||
892 (!strcmp(argv[i], "--memory")))
893 memory++;
894#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000895 else if ((!strcmp(argv[i], "-testIO")) ||
896 (!strcmp(argv[i], "--testIO")))
897 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000898#ifdef LIBXML_XINCLUDE_ENABLED
899 else if ((!strcmp(argv[i], "-xinclude")) ||
900 (!strcmp(argv[i], "--xinclude")))
901 xinclude++;
902#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000903 else if ((!strcmp(argv[i], "-compress")) ||
904 (!strcmp(argv[i], "--compress"))) {
905 compress++;
906 xmlSetCompressMode(9);
907 }
908 else if ((!strcmp(argv[i], "-nowarning")) ||
909 (!strcmp(argv[i], "--nowarning"))) {
910 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000911 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000912 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000913 else if ((!strcmp(argv[i], "-pedantic")) ||
914 (!strcmp(argv[i], "--pedantic"))) {
915 xmlGetWarningsDefaultValue = 1;
916 xmlPedanticParserDefault(1);
917 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000918#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000919 else if ((!strcmp(argv[i], "-debugent")) ||
920 (!strcmp(argv[i], "--debugent"))) {
921 debugent++;
922 xmlParserDebugEntities = 1;
923 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000924#endif
Daniel Veillard81418e32001-05-22 15:08:55 +0000925#ifdef LIBXML_CATALOG_ENABLED
926 else if ((!strcmp(argv[i], "-catalogs")) ||
927 (!strcmp(argv[i], "--catalogs"))) {
928 const char *catalogs;
929
930 catalogs = getenv("SGML_CATALOG_FILES");
931 if (catalogs == NULL) {
932 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
933 } else {
934 xmlLoadCatalogs(catalogs);
935 }
936 }
937#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000938 else if ((!strcmp(argv[i], "-encode")) ||
939 (!strcmp(argv[i], "--encode"))) {
940 i++;
941 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000942 /*
943 * OK it's for testing purposes
944 */
945 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000946 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000947 else if ((!strcmp(argv[i], "-noblanks")) ||
948 (!strcmp(argv[i], "--noblanks"))) {
949 noblanks++;
950 xmlKeepBlanksDefault(0);
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000951 } else {
952 fprintf(stderr, "Unknown option %s\n", argv[i]);
953 usage(argv[0]);
954 return(1);
955 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000956 }
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000957 if (loaddtd != 0) xmlLoadExtDtdDefaultValue = 6; /* fetch DTDs by default */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000958 if (noent != 0) xmlSubstituteEntitiesDefault(1);
959 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
960 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000961 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000962 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000963 xmlGenericError(xmlGenericErrorContext,
964 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
965 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000966 "<html><head><title>%s output</title></head>\n",
967 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000968 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000969 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
970 argv[0]);
971 }
972 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000973 if ((!strcmp(argv[i], "-encode")) ||
974 (!strcmp(argv[i], "--encode"))) {
975 i++;
976 continue;
977 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000978 if ((!strcmp(argv[i], "-dtdvalid")) ||
979 (!strcmp(argv[i], "--dtdvalid"))) {
980 i++;
981 continue;
982 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000983 if ((timing) && (repeat))
984 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000985 /* Remember file names. "-" means stding. <sven@zen.org> */
986 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000987 if (repeat) {
988 for (count = 0;count < 100 * repeat;count++)
989 parseAndPrintFile(argv[i]);
990 } else
991 parseAndPrintFile(argv[i]);
992 files ++;
993 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000994 if ((timing) && (repeat)) {
995 long msec;
996 gettimeofday(&end, NULL);
997 msec = end.tv_sec - begin.tv_sec;
998 msec *= 1000;
999 msec += (end.tv_usec - begin.tv_usec) / 1000;
1000 fprintf(stderr, "100 iteration took %ld ms\n", msec);
1001 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001002 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001003 if (generate)
1004 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001005 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001006 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001007 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001008 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001009 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001010 }
1011 xmlCleanupParser();
1012 xmlMemoryDump();
1013
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001014 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001015}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001016