blob: 6573c3ce8455f6aa38f7d4e2f412b7acc05c5c5d [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 Veillard48da9102001-08-07 01:10:10 +0000100static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000101static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000102static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000103static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000104static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000105static struct timeval begin, end;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000106
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000107/************************************************************************
108 * *
109 * HTML ouput *
110 * *
111 ************************************************************************/
112char buffer[50000];
113
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000114static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000115xmlHTMLEncodeSend(void) {
116 char *result;
117
118 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
119 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000120 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000121 xmlFree(result);
122 }
123 buffer[0] = 0;
124}
125
126/**
127 * xmlHTMLPrintFileInfo:
128 * @input: an xmlParserInputPtr input
129 *
130 * Displays the associated file and line informations for the current input
131 */
132
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000133static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000134xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000135 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000136 if (input != NULL) {
137 if (input->filename) {
138 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
139 input->line);
140 } else {
141 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
142 }
143 }
144 xmlHTMLEncodeSend();
145}
146
147/**
148 * xmlHTMLPrintFileContext:
149 * @input: an xmlParserInputPtr input
150 *
151 * Displays current context within the input content for error tracking
152 */
153
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000154static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000155xmlHTMLPrintFileContext(xmlParserInputPtr input) {
156 const xmlChar *cur, *base;
157 int n;
158
159 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000160 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000161 cur = input->cur;
162 base = input->base;
163 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
164 cur--;
165 }
166 n = 0;
167 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
168 cur--;
169 if ((*cur == '\n') || (*cur == '\r')) cur++;
170 base = cur;
171 n = 0;
172 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
173 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
174 n++;
175 }
176 sprintf(&buffer[strlen(buffer)], "\n");
177 cur = input->cur;
178 while ((*cur == '\n') || (*cur == '\r'))
179 cur--;
180 n = 0;
181 while ((cur != base) && (n++ < 80)) {
182 sprintf(&buffer[strlen(buffer)], " ");
183 base++;
184 }
185 sprintf(&buffer[strlen(buffer)],"^\n");
186 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000187 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000188}
189
190/**
191 * xmlHTMLError:
192 * @ctx: an XML parser context
193 * @msg: the message to display/transmit
194 * @...: extra parameters for the message display
195 *
196 * Display and format an error messages, gives file, line, position and
197 * extra parameters.
198 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000199static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000200xmlHTMLError(void *ctx, const char *msg, ...)
201{
202 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
203 xmlParserInputPtr input;
204 xmlParserInputPtr cur = NULL;
205 va_list args;
206
207 buffer[0] = 0;
208 input = ctxt->input;
209 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
210 cur = input;
211 input = ctxt->inputTab[ctxt->inputNr - 2];
212 }
213
214 xmlHTMLPrintFileInfo(input);
215
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000216 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000217 va_start(args, msg);
218 vsprintf(&buffer[strlen(buffer)], msg, args);
219 va_end(args);
220 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000221 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000222
223 xmlHTMLPrintFileContext(input);
224 xmlHTMLEncodeSend();
225}
226
227/**
228 * xmlHTMLWarning:
229 * @ctx: an XML parser context
230 * @msg: the message to display/transmit
231 * @...: extra parameters for the message display
232 *
233 * Display and format a warning messages, gives file, line, position and
234 * extra parameters.
235 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000236static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000237xmlHTMLWarning(void *ctx, const char *msg, ...)
238{
239 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
240 xmlParserInputPtr input;
241 xmlParserInputPtr cur = NULL;
242 va_list args;
243
244 buffer[0] = 0;
245 input = ctxt->input;
246 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
247 cur = input;
248 input = ctxt->inputTab[ctxt->inputNr - 2];
249 }
250
251
252 xmlHTMLPrintFileInfo(input);
253
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000254 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000255 va_start(args, msg);
256 vsprintf(&buffer[strlen(buffer)], msg, args);
257 va_end(args);
258 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000259 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000260
261 xmlHTMLPrintFileContext(input);
262 xmlHTMLEncodeSend();
263}
264
265/**
266 * xmlHTMLValidityError:
267 * @ctx: an XML parser context
268 * @msg: the message to display/transmit
269 * @...: extra parameters for the message display
270 *
271 * Display and format an validity error messages, gives file,
272 * line, position and extra parameters.
273 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000274static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000275xmlHTMLValidityError(void *ctx, const char *msg, ...)
276{
277 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
278 xmlParserInputPtr input;
279 va_list args;
280
281 buffer[0] = 0;
282 input = ctxt->input;
283 if ((input->filename == NULL) && (ctxt->inputNr > 1))
284 input = ctxt->inputTab[ctxt->inputNr - 2];
285
286 xmlHTMLPrintFileInfo(input);
287
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000288 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000289 va_start(args, msg);
290 vsprintf(&buffer[strlen(buffer)], msg, args);
291 va_end(args);
292 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000293 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000294
295 xmlHTMLPrintFileContext(input);
296 xmlHTMLEncodeSend();
297}
298
299/**
300 * xmlHTMLValidityWarning:
301 * @ctx: an XML parser context
302 * @msg: the message to display/transmit
303 * @...: extra parameters for the message display
304 *
305 * Display and format a validity warning messages, gives file, line,
306 * position and extra parameters.
307 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000308static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000309xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
310{
311 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
312 xmlParserInputPtr input;
313 va_list args;
314
315 buffer[0] = 0;
316 input = ctxt->input;
317 if ((input->filename == NULL) && (ctxt->inputNr > 1))
318 input = ctxt->inputTab[ctxt->inputNr - 2];
319
320 xmlHTMLPrintFileInfo(input);
321
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000322 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000323 va_start(args, msg);
324 vsprintf(&buffer[strlen(buffer)], msg, args);
325 va_end(args);
326 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000327 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000328
329 xmlHTMLPrintFileContext(input);
330 xmlHTMLEncodeSend();
331}
332
333/************************************************************************
334 * *
335 * Shell Interface *
336 * *
337 ************************************************************************/
338/**
339 * xmlShellReadline:
340 * @prompt: the prompt value
341 *
342 * Read a string
343 *
344 * Returns a pointer to it or NULL on EOF the caller is expected to
345 * free the returned string.
346 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000347static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000348xmlShellReadline(char *prompt) {
349#ifdef HAVE_LIBREADLINE
350 char *line_read;
351
352 /* Get a line from the user. */
353 line_read = readline (prompt);
354
355 /* If the line has any text in it, save it on the history. */
356 if (line_read && *line_read)
357 add_history (line_read);
358
359 return (line_read);
360#else
361 char line_read[501];
362
363 if (prompt != NULL)
364 fprintf(stdout, "%s", prompt);
365 if (!fgets(line_read, 500, stdin))
366 return(NULL);
367 line_read[500] = 0;
368 return(strdup(line_read));
369#endif
370}
371
372/************************************************************************
373 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000374 * I/O Interfaces *
375 * *
376 ************************************************************************/
377
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000378static int myRead(FILE *f, char * buf, int len) {
379 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000380}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000381static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000382 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000383 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000384 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000385}
386
387/************************************************************************
388 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000389 * Test processing *
390 * *
391 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000392static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000393 xmlDocPtr doc = NULL, tmp;
394
Daniel Veillard48b2f892001-02-25 16:11:03 +0000395 if ((timing) && (!repeat))
396 gettimeofday(&begin, NULL);
397
398
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000399 if (filename == NULL) {
400 if (generate) {
401 xmlNodePtr n;
402
403 doc = xmlNewDoc(BAD_CAST "1.0");
404 n = xmlNewNode(NULL, BAD_CAST "info");
405 xmlNodeSetContent(n, BAD_CAST "abc");
406 xmlDocSetRootElement(doc, n);
407 }
408 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000409#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000410 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000411 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000412 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000413#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000414 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000415 /*
416 * build an XML tree from a string;
417 */
418 if (push) {
419 FILE *f;
420
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000421 /* '-' Usually means stdin -<sven@zen.org> */
422 if ((filename[0] == '-') && (filename[1] == 0)) {
423 f = stdin;
424 } else {
425 f = fopen(filename, "r");
426 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000427 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000428 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000429 int res, size = 3;
430 char chars[1024];
431 xmlParserCtxtPtr ctxt;
432
433 if (repeat)
434 size = 1024;
435 res = fread(chars, 1, 4, f);
436 if (res > 0) {
437 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
438 chars, res, filename);
439 while ((res = fread(chars, 1, size, f)) > 0) {
440 xmlParseChunk(ctxt, chars, res, 0);
441 }
442 xmlParseChunk(ctxt, chars, 0, 1);
443 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000444 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000445 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000446 if (!ret) {
447 xmlFreeDoc(doc);
448 doc = NULL;
449 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000450 }
451 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000452 } else if (testIO) {
453 int ret;
454 FILE *f;
455
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000456 /* '-' Usually means stdin -<sven@zen.org> */
457 if ((filename[0] == '-') && (filename[1] == 0)) {
458 f = stdin;
459 } else {
460 f = fopen(filename, "r");
461 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000462 if (f != NULL) {
463 xmlParserCtxtPtr ctxt;
464
465 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
466 (xmlInputReadCallback) myRead,
467 (xmlInputCloseCallback) myClose,
468 f, XML_CHAR_ENCODING_NONE);
469 xmlParseDocument(ctxt);
470
471 ret = ctxt->wellFormed;
472 doc = ctxt->myDoc;
473 xmlFreeParserCtxt(ctxt);
474 if (!ret) {
475 xmlFreeDoc(doc);
476 doc = NULL;
477 }
478 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000479 } else if (recovery) {
480 doc = xmlRecoverFile(filename);
481 } else if (htmlout) {
482 int ret;
483 xmlParserCtxtPtr ctxt;
484 xmlSAXHandler silent, *old;
485
486 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000487
488 if (ctxt == NULL) {
489 /* If xmlCreateFileParseCtxt() return NULL something
490 strange happened so we don't want to do anything. Do
491 we want to print an error message here?
492 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000493 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000494 } else {
495 memcpy(&silent, ctxt->sax, sizeof(silent));
496 old = ctxt->sax;
497 silent.error = xmlHTMLError;
498 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000499 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000500 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000501 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000502 silent.fatalError = xmlHTMLError;
503 ctxt->sax = &silent;
504 ctxt->vctxt.error = xmlHTMLValidityError;
505 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000506 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000507 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000508 ctxt->vctxt.warning = NULL;
509
Daniel Veillard88a172f2000-08-04 18:23:10 +0000510 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000511
Daniel Veillard88a172f2000-08-04 18:23:10 +0000512 ret = ctxt->wellFormed;
513 doc = ctxt->myDoc;
514 ctxt->sax = old;
515 xmlFreeParserCtxt(ctxt);
516 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000517 xmlFreeDoc(doc);
518 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000519 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000520 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000521#ifdef HAVE_SYS_MMAN_H
522 } else if (memory) {
523 int fd;
524 struct stat info;
525 const char *base;
526 if (stat(filename, &info) < 0)
527 return;
528 if ((fd = open(filename, O_RDONLY)) < 0)
529 return;
530 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000531 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000532 return;
533
534 doc = xmlParseMemory((char *) base, info.st_size);
535 munmap((char *) base, info.st_size);
536#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000537 } else
538 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000539 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000540
Daniel Veillard88a172f2000-08-04 18:23:10 +0000541 /*
542 * If we don't have a document we might as well give up. Do we
543 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000544 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000545 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000546 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000547 }
548
Daniel Veillard48b2f892001-02-25 16:11:03 +0000549 if ((timing) && (!repeat)) {
550 long msec;
551 gettimeofday(&end, NULL);
552 msec = end.tv_sec - begin.tv_sec;
553 msec *= 1000;
554 msec += (end.tv_usec - begin.tv_usec) / 1000;
555 fprintf(stderr, "Parsing took %ld ms\n", msec);
556 }
557
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000558#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000559 if (xinclude) {
560 if ((timing) && (!repeat)) {
561 gettimeofday(&begin, NULL);
562 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000563 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000564 if ((timing) && (!repeat)) {
565 long msec;
566 gettimeofday(&end, NULL);
567 msec = end.tv_sec - begin.tv_sec;
568 msec *= 1000;
569 msec += (end.tv_usec - begin.tv_usec) / 1000;
570 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
571 }
572 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000573#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000574
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000575#ifdef LIBXML_DEBUG_ENABLED
576 /*
577 * shell interraction
578 */
579 if (shell)
580 xmlShell(doc, filename, xmlShellReadline, stdout);
581#endif
582
583 /*
584 * test intermediate copy if needed.
585 */
586 if (copy) {
587 tmp = doc;
588 doc = xmlCopyDoc(doc, 1);
589 xmlFreeDoc(tmp);
590 }
591
592 if ((insert) && (!html)) {
593 const xmlChar* list[256];
594 int nb, i;
595 xmlNodePtr node;
596
597 if (doc->children != NULL) {
598 node = doc->children;
599 while ((node != NULL) && (node->last == NULL)) node = node->next;
600 if (node != NULL) {
601 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
602 if (nb < 0) {
603 printf("could not get valid list of elements\n");
604 } else if (nb == 0) {
605 printf("No element can be indersted under root\n");
606 } else {
607 printf("%d element types can be indersted under root:\n",
608 nb);
609 for (i = 0;i < nb;i++) {
610 printf("%s\n", list[i]);
611 }
612 }
613 }
614 }
615 }else if (noout == 0) {
616 /*
617 * print it.
618 */
619#ifdef LIBXML_DEBUG_ENABLED
620 if (!debug) {
621#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000622 if ((timing) && (!repeat)) {
623 gettimeofday(&begin, NULL);
624 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000625#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000626 if (memory) {
627 xmlChar *result;
628 int len;
629
630 if (encoding != NULL) {
631 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
632 } else {
633 xmlDocDumpMemory(doc, &result, &len);
634 }
635 if (result == NULL) {
636 fprintf(stderr, "Failed to save\n");
637 } else {
638 write(1, result, len);
639 xmlFree(result);
640 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000641 } else
642#endif /* HAVE_SYS_MMAN_H */
643 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000644 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000645 else if (encoding != NULL)
646 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000647 else
648 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000649 if ((timing) && (!repeat)) {
650 long msec;
651 gettimeofday(&end, NULL);
652 msec = end.tv_sec - begin.tv_sec;
653 msec *= 1000;
654 msec += (end.tv_usec - begin.tv_usec) / 1000;
655 fprintf(stderr, "Saving took %ld ms\n", msec);
656 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000657#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000658 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000659 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000660 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000661#endif
662 }
663
664 /*
665 * A posteriori validation test
666 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000667 if (dtdvalid != NULL) {
668 xmlDtdPtr dtd;
669
Daniel Veillard48b2f892001-02-25 16:11:03 +0000670 if ((timing) && (!repeat)) {
671 gettimeofday(&begin, NULL);
672 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000673 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000674 if ((timing) && (!repeat)) {
675 long msec;
676 gettimeofday(&end, NULL);
677 msec = end.tv_sec - begin.tv_sec;
678 msec *= 1000;
679 msec += (end.tv_usec - begin.tv_usec) / 1000;
680 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
681 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000682 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000683 xmlGenericError(xmlGenericErrorContext,
684 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000685 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000686 } else {
687 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000688 if ((timing) && (!repeat)) {
689 gettimeofday(&begin, NULL);
690 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000691 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
692 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000693 xmlGenericError(xmlGenericErrorContext,
694 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000695 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000696 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000697 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000698 if ((timing) && (!repeat)) {
699 long msec;
700 gettimeofday(&end, NULL);
701 msec = end.tv_sec - begin.tv_sec;
702 msec *= 1000;
703 msec += (end.tv_usec - begin.tv_usec) / 1000;
704 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
705 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000706 xmlFreeDtd(dtd);
707 }
708 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000709 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000710 if ((timing) && (!repeat)) {
711 gettimeofday(&begin, NULL);
712 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000713 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000714 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000715 xmlGenericError(xmlGenericErrorContext,
716 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000717 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000718 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000719 if ((timing) && (!repeat)) {
720 long msec;
721 gettimeofday(&end, NULL);
722 msec = end.tv_sec - begin.tv_sec;
723 msec *= 1000;
724 msec += (end.tv_usec - begin.tv_usec) / 1000;
725 fprintf(stderr, "Validating took %ld ms\n", msec);
726 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000727 }
728
729#ifdef LIBXML_DEBUG_ENABLED
730 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000731 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000732#endif
733
734 /*
735 * free it.
736 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000737 if ((timing) && (!repeat)) {
738 gettimeofday(&begin, NULL);
739 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000740 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000741 if ((timing) && (!repeat)) {
742 long msec;
743 gettimeofday(&end, NULL);
744 msec = end.tv_sec - begin.tv_sec;
745 msec *= 1000;
746 msec += (end.tv_usec - begin.tv_usec) / 1000;
747 fprintf(stderr, "Freeing took %ld ms\n", msec);
748 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000749}
750
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000751/************************************************************************
752 * *
753 * Usage and Main *
754 * *
755 ************************************************************************/
756
757static void usage(const char *name) {
758 printf("Usage : %s [options] XMLfiles ...\n", name);
759 printf("\tParse the XML files and output the result of the parsing\n");
760 printf("\t--version : display the version of the XML library used\n");
761#ifdef LIBXML_DEBUG_ENABLED
762 printf("\t--debug : dump a debug tree of the in-memory document\n");
763 printf("\t--shell : run a navigating shell\n");
764 printf("\t--debugent : debug the entities defined in the document\n");
765#endif
766 printf("\t--copy : used to test the internal copy implementation\n");
767 printf("\t--recover : output what was parsable on broken XML documents\n");
768 printf("\t--noent : substitute entity references by their value\n");
769 printf("\t--noout : don't output the result tree\n");
770 printf("\t--htmlout : output results as HTML\n");
771 printf("\t--nowarp : do not put HTML doc wrapper\n");
772 printf("\t--valid : validate the document in addition to std well-formed check\n");
773 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
774 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
775 printf("\t--timing : print some timings\n");
776 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
777 printf("\t--insert : ad-hoc test for valid insertions\n");
778 printf("\t--compress : turn on gzip compression of output\n");
779#ifdef LIBXML_HTML_ENABLED
780 printf("\t--html : use the HTML parser\n");
781#endif
782 printf("\t--push : use the push mode of the parser\n");
783#ifdef HAVE_SYS_MMAN_H
784 printf("\t--memory : parse from memory\n");
785#endif
786 printf("\t--nowarning : do not emit warnings from parser/validator\n");
787 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
788 printf("\t--testIO : test user I/O support\n");
789 printf("\t--encode encoding : output in the given encoding\n");
790#ifdef LIBXML_CATALOG_ENABLED
791 printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
792#endif
793 printf("\t--auto : generate a small doc on the fly\n");
794#ifdef LIBXML_XINCLUDE_ENABLED
795 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000796#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000797 printf("\t--loaddtd : fetch external Dtd\n");
798 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000799}
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000800int
801main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000802 int i, count;
803 int files = 0;
804
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000805 if (argc <= 1) {
806 usage(argv[0]);
807 return(1);
808 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000809 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000810 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000811 if (!strcmp(argv[i], "-"))
812 break;
813
814 if (argv[i][0] != '-')
815 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000816#ifdef LIBXML_DEBUG_ENABLED
817 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
818 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000819 else if ((!strcmp(argv[i], "-shell")) ||
820 (!strcmp(argv[i], "--shell"))) {
821 shell++;
822 noout = 1;
823 } else
824#endif
825 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
826 copy++;
827 else if ((!strcmp(argv[i], "-recover")) ||
828 (!strcmp(argv[i], "--recover")))
829 recovery++;
830 else if ((!strcmp(argv[i], "-noent")) ||
831 (!strcmp(argv[i], "--noent")))
832 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +0000833 else if ((!strcmp(argv[i], "-version")) ||
834 (!strcmp(argv[i], "--version")))
835 fprintf(stderr, "xmllint: using libxml version %s\n",
836 xmlParserVersion);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000837 else if ((!strcmp(argv[i], "-noout")) ||
838 (!strcmp(argv[i], "--noout")))
839 noout++;
840 else if ((!strcmp(argv[i], "-htmlout")) ||
841 (!strcmp(argv[i], "--htmlout")))
842 htmlout++;
843#ifdef LIBXML_HTML_ENABLED
844 else if ((!strcmp(argv[i], "-html")) ||
845 (!strcmp(argv[i], "--html"))) {
846 html++;
847 }
848#endif /* LIBXML_HTML_ENABLED */
849 else if ((!strcmp(argv[i], "-nowrap")) ||
850 (!strcmp(argv[i], "--nowrap")))
851 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000852 else if ((!strcmp(argv[i], "-loaddtd")) ||
853 (!strcmp(argv[i], "--loaddtd")))
854 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +0000855 else if ((!strcmp(argv[i], "-dtdattr")) ||
856 (!strcmp(argv[i], "--dtdattr"))) {
857 loaddtd++;
858 dtdattrs++;
859 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000860 (!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 Veillardd9bad132001-07-23 19:39:43 +0000954 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +0000955 if (loaddtd != 0)
956 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
957 if (dtdattrs)
958 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000959 if (noent != 0) xmlSubstituteEntitiesDefault(1);
960 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
961 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000962 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000963 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000964 xmlGenericError(xmlGenericErrorContext,
965 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
966 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000967 "<html><head><title>%s output</title></head>\n",
968 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000969 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000970 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
971 argv[0]);
972 }
973 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000974 if ((!strcmp(argv[i], "-encode")) ||
975 (!strcmp(argv[i], "--encode"))) {
976 i++;
977 continue;
978 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000979 if ((!strcmp(argv[i], "-dtdvalid")) ||
980 (!strcmp(argv[i], "--dtdvalid"))) {
981 i++;
982 continue;
983 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000984 if ((timing) && (repeat))
985 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000986 /* Remember file names. "-" means stding. <sven@zen.org> */
987 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000988 if (repeat) {
989 for (count = 0;count < 100 * repeat;count++)
990 parseAndPrintFile(argv[i]);
991 } else
992 parseAndPrintFile(argv[i]);
993 files ++;
994 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000995 if ((timing) && (repeat)) {
996 long msec;
997 gettimeofday(&end, NULL);
998 msec = end.tv_sec - begin.tv_sec;
999 msec *= 1000;
1000 msec += (end.tv_usec - begin.tv_usec) / 1000;
1001 fprintf(stderr, "100 iteration took %ld ms\n", msec);
1002 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001003 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001004 if (generate)
1005 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001006 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001007 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001008 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001009 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001010 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001011 }
1012 xmlCleanupParser();
1013 xmlMemoryDump();
1014
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001015 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001016}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001017