blob: abc612ac908d8d80f9993d2931ed77233972a1e4 [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 Veillard90493a92001-08-14 14:12:47 +000095static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000096static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000097static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000098#ifdef LIBXML_XINCLUDE_ENABLED
99static int xinclude = 0;
100#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000101static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000102static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000103static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000104static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000105static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000106static struct timeval begin, end;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000107
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000108/************************************************************************
109 * *
110 * HTML ouput *
111 * *
112 ************************************************************************/
113char buffer[50000];
114
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000115static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000116xmlHTMLEncodeSend(void) {
117 char *result;
118
119 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
120 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000121 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000122 xmlFree(result);
123 }
124 buffer[0] = 0;
125}
126
127/**
128 * xmlHTMLPrintFileInfo:
129 * @input: an xmlParserInputPtr input
130 *
131 * Displays the associated file and line informations for the current input
132 */
133
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000134static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000135xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000136 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000137 if (input != NULL) {
138 if (input->filename) {
139 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
140 input->line);
141 } else {
142 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
143 }
144 }
145 xmlHTMLEncodeSend();
146}
147
148/**
149 * xmlHTMLPrintFileContext:
150 * @input: an xmlParserInputPtr input
151 *
152 * Displays current context within the input content for error tracking
153 */
154
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000155static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000156xmlHTMLPrintFileContext(xmlParserInputPtr input) {
157 const xmlChar *cur, *base;
158 int n;
159
160 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000161 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000162 cur = input->cur;
163 base = input->base;
164 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
165 cur--;
166 }
167 n = 0;
168 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
169 cur--;
170 if ((*cur == '\n') || (*cur == '\r')) cur++;
171 base = cur;
172 n = 0;
173 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
174 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
175 n++;
176 }
177 sprintf(&buffer[strlen(buffer)], "\n");
178 cur = input->cur;
179 while ((*cur == '\n') || (*cur == '\r'))
180 cur--;
181 n = 0;
182 while ((cur != base) && (n++ < 80)) {
183 sprintf(&buffer[strlen(buffer)], " ");
184 base++;
185 }
186 sprintf(&buffer[strlen(buffer)],"^\n");
187 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000188 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000189}
190
191/**
192 * xmlHTMLError:
193 * @ctx: an XML parser context
194 * @msg: the message to display/transmit
195 * @...: extra parameters for the message display
196 *
197 * Display and format an error messages, gives file, line, position and
198 * extra parameters.
199 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000200static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000201xmlHTMLError(void *ctx, const char *msg, ...)
202{
203 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
204 xmlParserInputPtr input;
205 xmlParserInputPtr cur = NULL;
206 va_list args;
207
208 buffer[0] = 0;
209 input = ctxt->input;
210 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
211 cur = input;
212 input = ctxt->inputTab[ctxt->inputNr - 2];
213 }
214
215 xmlHTMLPrintFileInfo(input);
216
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000217 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000218 va_start(args, msg);
219 vsprintf(&buffer[strlen(buffer)], msg, args);
220 va_end(args);
221 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000222 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000223
224 xmlHTMLPrintFileContext(input);
225 xmlHTMLEncodeSend();
226}
227
228/**
229 * xmlHTMLWarning:
230 * @ctx: an XML parser context
231 * @msg: the message to display/transmit
232 * @...: extra parameters for the message display
233 *
234 * Display and format a warning messages, gives file, line, position and
235 * extra parameters.
236 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000237static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000238xmlHTMLWarning(void *ctx, const char *msg, ...)
239{
240 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
241 xmlParserInputPtr input;
242 xmlParserInputPtr cur = NULL;
243 va_list args;
244
245 buffer[0] = 0;
246 input = ctxt->input;
247 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
248 cur = input;
249 input = ctxt->inputTab[ctxt->inputNr - 2];
250 }
251
252
253 xmlHTMLPrintFileInfo(input);
254
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000255 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000256 va_start(args, msg);
257 vsprintf(&buffer[strlen(buffer)], msg, args);
258 va_end(args);
259 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000260 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000261
262 xmlHTMLPrintFileContext(input);
263 xmlHTMLEncodeSend();
264}
265
266/**
267 * xmlHTMLValidityError:
268 * @ctx: an XML parser context
269 * @msg: the message to display/transmit
270 * @...: extra parameters for the message display
271 *
272 * Display and format an validity error messages, gives file,
273 * line, position and extra parameters.
274 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000275static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000276xmlHTMLValidityError(void *ctx, const char *msg, ...)
277{
278 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
279 xmlParserInputPtr input;
280 va_list args;
281
282 buffer[0] = 0;
283 input = ctxt->input;
284 if ((input->filename == NULL) && (ctxt->inputNr > 1))
285 input = ctxt->inputTab[ctxt->inputNr - 2];
286
287 xmlHTMLPrintFileInfo(input);
288
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000289 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000290 va_start(args, msg);
291 vsprintf(&buffer[strlen(buffer)], msg, args);
292 va_end(args);
293 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000294 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000295
296 xmlHTMLPrintFileContext(input);
297 xmlHTMLEncodeSend();
298}
299
300/**
301 * xmlHTMLValidityWarning:
302 * @ctx: an XML parser context
303 * @msg: the message to display/transmit
304 * @...: extra parameters for the message display
305 *
306 * Display and format a validity warning messages, gives file, line,
307 * position and extra parameters.
308 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000309static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000310xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
311{
312 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
313 xmlParserInputPtr input;
314 va_list args;
315
316 buffer[0] = 0;
317 input = ctxt->input;
318 if ((input->filename == NULL) && (ctxt->inputNr > 1))
319 input = ctxt->inputTab[ctxt->inputNr - 2];
320
321 xmlHTMLPrintFileInfo(input);
322
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000323 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000324 va_start(args, msg);
325 vsprintf(&buffer[strlen(buffer)], msg, args);
326 va_end(args);
327 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000328 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000329
330 xmlHTMLPrintFileContext(input);
331 xmlHTMLEncodeSend();
332}
333
334/************************************************************************
335 * *
336 * Shell Interface *
337 * *
338 ************************************************************************/
339/**
340 * xmlShellReadline:
341 * @prompt: the prompt value
342 *
343 * Read a string
344 *
345 * Returns a pointer to it or NULL on EOF the caller is expected to
346 * free the returned string.
347 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000348static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000349xmlShellReadline(char *prompt) {
350#ifdef HAVE_LIBREADLINE
351 char *line_read;
352
353 /* Get a line from the user. */
354 line_read = readline (prompt);
355
356 /* If the line has any text in it, save it on the history. */
357 if (line_read && *line_read)
358 add_history (line_read);
359
360 return (line_read);
361#else
362 char line_read[501];
363
364 if (prompt != NULL)
365 fprintf(stdout, "%s", prompt);
366 if (!fgets(line_read, 500, stdin))
367 return(NULL);
368 line_read[500] = 0;
369 return(strdup(line_read));
370#endif
371}
372
373/************************************************************************
374 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000375 * I/O Interfaces *
376 * *
377 ************************************************************************/
378
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000379static int myRead(FILE *f, char * buf, int len) {
380 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000381}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000382static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000383 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000384 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000385 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000386}
387
388/************************************************************************
389 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000390 * Test processing *
391 * *
392 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000393static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000394 xmlDocPtr doc = NULL, tmp;
395
Daniel Veillard48b2f892001-02-25 16:11:03 +0000396 if ((timing) && (!repeat))
397 gettimeofday(&begin, NULL);
398
399
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000400 if (filename == NULL) {
401 if (generate) {
402 xmlNodePtr n;
403
404 doc = xmlNewDoc(BAD_CAST "1.0");
405 n = xmlNewNode(NULL, BAD_CAST "info");
406 xmlNodeSetContent(n, BAD_CAST "abc");
407 xmlDocSetRootElement(doc, n);
408 }
409 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000410#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000411 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000412 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000413 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000414#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000415 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000416 /*
417 * build an XML tree from a string;
418 */
419 if (push) {
420 FILE *f;
421
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000422 /* '-' Usually means stdin -<sven@zen.org> */
423 if ((filename[0] == '-') && (filename[1] == 0)) {
424 f = stdin;
425 } else {
426 f = fopen(filename, "r");
427 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000428 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000429 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000430 int res, size = 3;
431 char chars[1024];
432 xmlParserCtxtPtr ctxt;
433
434 if (repeat)
435 size = 1024;
436 res = fread(chars, 1, 4, f);
437 if (res > 0) {
438 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
439 chars, res, filename);
440 while ((res = fread(chars, 1, size, f)) > 0) {
441 xmlParseChunk(ctxt, chars, res, 0);
442 }
443 xmlParseChunk(ctxt, chars, 0, 1);
444 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000445 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000446 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000447 if (!ret) {
448 xmlFreeDoc(doc);
449 doc = NULL;
450 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000451 }
452 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000453 } else if (testIO) {
454 int ret;
455 FILE *f;
456
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000457 /* '-' Usually means stdin -<sven@zen.org> */
458 if ((filename[0] == '-') && (filename[1] == 0)) {
459 f = stdin;
460 } else {
461 f = fopen(filename, "r");
462 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000463 if (f != NULL) {
464 xmlParserCtxtPtr ctxt;
465
466 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
467 (xmlInputReadCallback) myRead,
468 (xmlInputCloseCallback) myClose,
469 f, XML_CHAR_ENCODING_NONE);
470 xmlParseDocument(ctxt);
471
472 ret = ctxt->wellFormed;
473 doc = ctxt->myDoc;
474 xmlFreeParserCtxt(ctxt);
475 if (!ret) {
476 xmlFreeDoc(doc);
477 doc = NULL;
478 }
479 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000480 } else if (recovery) {
481 doc = xmlRecoverFile(filename);
482 } else if (htmlout) {
483 int ret;
484 xmlParserCtxtPtr ctxt;
485 xmlSAXHandler silent, *old;
486
487 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000488
489 if (ctxt == NULL) {
490 /* If xmlCreateFileParseCtxt() return NULL something
491 strange happened so we don't want to do anything. Do
492 we want to print an error message here?
493 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000494 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000495 } else {
496 memcpy(&silent, ctxt->sax, sizeof(silent));
497 old = ctxt->sax;
498 silent.error = xmlHTMLError;
499 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000500 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000501 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000502 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000503 silent.fatalError = xmlHTMLError;
504 ctxt->sax = &silent;
505 ctxt->vctxt.error = xmlHTMLValidityError;
506 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000507 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000508 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000509 ctxt->vctxt.warning = NULL;
510
Daniel Veillard88a172f2000-08-04 18:23:10 +0000511 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000512
Daniel Veillard88a172f2000-08-04 18:23:10 +0000513 ret = ctxt->wellFormed;
514 doc = ctxt->myDoc;
515 ctxt->sax = old;
516 xmlFreeParserCtxt(ctxt);
517 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000518 xmlFreeDoc(doc);
519 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000520 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000521 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000522#ifdef HAVE_SYS_MMAN_H
523 } else if (memory) {
524 int fd;
525 struct stat info;
526 const char *base;
527 if (stat(filename, &info) < 0)
528 return;
529 if ((fd = open(filename, O_RDONLY)) < 0)
530 return;
531 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000532 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000533 return;
534
535 doc = xmlParseMemory((char *) base, info.st_size);
536 munmap((char *) base, info.st_size);
537#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000538 } else
539 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000540 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000541
Daniel Veillard88a172f2000-08-04 18:23:10 +0000542 /*
543 * If we don't have a document we might as well give up. Do we
544 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000545 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000546 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000547 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000548 }
549
Daniel Veillard48b2f892001-02-25 16:11:03 +0000550 if ((timing) && (!repeat)) {
551 long msec;
552 gettimeofday(&end, NULL);
553 msec = end.tv_sec - begin.tv_sec;
554 msec *= 1000;
555 msec += (end.tv_usec - begin.tv_usec) / 1000;
556 fprintf(stderr, "Parsing took %ld ms\n", msec);
557 }
558
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000559#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000560 if (xinclude) {
561 if ((timing) && (!repeat)) {
562 gettimeofday(&begin, NULL);
563 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000564 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000565 if ((timing) && (!repeat)) {
566 long msec;
567 gettimeofday(&end, NULL);
568 msec = end.tv_sec - begin.tv_sec;
569 msec *= 1000;
570 msec += (end.tv_usec - begin.tv_usec) / 1000;
571 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
572 }
573 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000574#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000575
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000576#ifdef LIBXML_DEBUG_ENABLED
577 /*
578 * shell interraction
579 */
580 if (shell)
581 xmlShell(doc, filename, xmlShellReadline, stdout);
582#endif
583
584 /*
585 * test intermediate copy if needed.
586 */
587 if (copy) {
588 tmp = doc;
589 doc = xmlCopyDoc(doc, 1);
590 xmlFreeDoc(tmp);
591 }
592
593 if ((insert) && (!html)) {
594 const xmlChar* list[256];
595 int nb, i;
596 xmlNodePtr node;
597
598 if (doc->children != NULL) {
599 node = doc->children;
600 while ((node != NULL) && (node->last == NULL)) node = node->next;
601 if (node != NULL) {
602 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
603 if (nb < 0) {
604 printf("could not get valid list of elements\n");
605 } else if (nb == 0) {
606 printf("No element can be indersted under root\n");
607 } else {
608 printf("%d element types can be indersted under root:\n",
609 nb);
610 for (i = 0;i < nb;i++) {
611 printf("%s\n", list[i]);
612 }
613 }
614 }
615 }
616 }else if (noout == 0) {
617 /*
618 * print it.
619 */
620#ifdef LIBXML_DEBUG_ENABLED
621 if (!debug) {
622#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000623 if ((timing) && (!repeat)) {
624 gettimeofday(&begin, NULL);
625 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000626#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000627 if (memory) {
628 xmlChar *result;
629 int len;
630
631 if (encoding != NULL) {
632 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
633 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +0000634 if (format)
635 xmlDocDumpFormatMemory(doc, &result, &len, 1);
636 else
637 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000638 }
639 if (result == NULL) {
640 fprintf(stderr, "Failed to save\n");
641 } else {
642 write(1, result, len);
643 xmlFree(result);
644 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000645 } else
646#endif /* HAVE_SYS_MMAN_H */
647 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000648 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000649 else if (encoding != NULL)
650 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillard90493a92001-08-14 14:12:47 +0000651 else if (format)
652 xmlSaveFormatFile("-", doc, 1);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000653 else
654 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000655 if ((timing) && (!repeat)) {
656 long msec;
657 gettimeofday(&end, NULL);
658 msec = end.tv_sec - begin.tv_sec;
659 msec *= 1000;
660 msec += (end.tv_usec - begin.tv_usec) / 1000;
661 fprintf(stderr, "Saving took %ld ms\n", msec);
662 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000663#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000664 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000665 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000666 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000667#endif
668 }
669
670 /*
671 * A posteriori validation test
672 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000673 if (dtdvalid != NULL) {
674 xmlDtdPtr dtd;
675
Daniel Veillard48b2f892001-02-25 16:11:03 +0000676 if ((timing) && (!repeat)) {
677 gettimeofday(&begin, NULL);
678 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000679 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000680 if ((timing) && (!repeat)) {
681 long msec;
682 gettimeofday(&end, NULL);
683 msec = end.tv_sec - begin.tv_sec;
684 msec *= 1000;
685 msec += (end.tv_usec - begin.tv_usec) / 1000;
686 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
687 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000688 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000689 xmlGenericError(xmlGenericErrorContext,
690 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000691 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000692 } else {
693 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000694 if ((timing) && (!repeat)) {
695 gettimeofday(&begin, NULL);
696 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000697 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
698 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000699 xmlGenericError(xmlGenericErrorContext,
700 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000701 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000702 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000703 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000704 if ((timing) && (!repeat)) {
705 long msec;
706 gettimeofday(&end, NULL);
707 msec = end.tv_sec - begin.tv_sec;
708 msec *= 1000;
709 msec += (end.tv_usec - begin.tv_usec) / 1000;
710 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
711 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000712 xmlFreeDtd(dtd);
713 }
714 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000715 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000716 if ((timing) && (!repeat)) {
717 gettimeofday(&begin, NULL);
718 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000719 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000720 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000721 xmlGenericError(xmlGenericErrorContext,
722 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000723 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000724 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000725 if ((timing) && (!repeat)) {
726 long msec;
727 gettimeofday(&end, NULL);
728 msec = end.tv_sec - begin.tv_sec;
729 msec *= 1000;
730 msec += (end.tv_usec - begin.tv_usec) / 1000;
731 fprintf(stderr, "Validating took %ld ms\n", msec);
732 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000733 }
734
735#ifdef LIBXML_DEBUG_ENABLED
736 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000737 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000738#endif
739
740 /*
741 * free it.
742 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000743 if ((timing) && (!repeat)) {
744 gettimeofday(&begin, NULL);
745 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000746 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000747 if ((timing) && (!repeat)) {
748 long msec;
749 gettimeofday(&end, NULL);
750 msec = end.tv_sec - begin.tv_sec;
751 msec *= 1000;
752 msec += (end.tv_usec - begin.tv_usec) / 1000;
753 fprintf(stderr, "Freeing took %ld ms\n", msec);
754 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000755}
756
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000757/************************************************************************
758 * *
759 * Usage and Main *
760 * *
761 ************************************************************************/
762
763static void usage(const char *name) {
764 printf("Usage : %s [options] XMLfiles ...\n", name);
765 printf("\tParse the XML files and output the result of the parsing\n");
766 printf("\t--version : display the version of the XML library used\n");
767#ifdef LIBXML_DEBUG_ENABLED
768 printf("\t--debug : dump a debug tree of the in-memory document\n");
769 printf("\t--shell : run a navigating shell\n");
770 printf("\t--debugent : debug the entities defined in the document\n");
771#endif
772 printf("\t--copy : used to test the internal copy implementation\n");
773 printf("\t--recover : output what was parsable on broken XML documents\n");
774 printf("\t--noent : substitute entity references by their value\n");
775 printf("\t--noout : don't output the result tree\n");
776 printf("\t--htmlout : output results as HTML\n");
777 printf("\t--nowarp : do not put HTML doc wrapper\n");
778 printf("\t--valid : validate the document in addition to std well-formed check\n");
779 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
780 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
781 printf("\t--timing : print some timings\n");
782 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
783 printf("\t--insert : ad-hoc test for valid insertions\n");
784 printf("\t--compress : turn on gzip compression of output\n");
785#ifdef LIBXML_HTML_ENABLED
786 printf("\t--html : use the HTML parser\n");
787#endif
788 printf("\t--push : use the push mode of the parser\n");
789#ifdef HAVE_SYS_MMAN_H
790 printf("\t--memory : parse from memory\n");
791#endif
792 printf("\t--nowarning : do not emit warnings from parser/validator\n");
793 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +0000794 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000795 printf("\t--testIO : test user I/O support\n");
796 printf("\t--encode encoding : output in the given encoding\n");
797#ifdef LIBXML_CATALOG_ENABLED
798 printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
799#endif
800 printf("\t--auto : generate a small doc on the fly\n");
801#ifdef LIBXML_XINCLUDE_ENABLED
802 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000803#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000804 printf("\t--loaddtd : fetch external Dtd\n");
805 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000806}
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 Veillard48da9102001-08-07 01:10:10 +0000862 else if ((!strcmp(argv[i], "-dtdattr")) ||
863 (!strcmp(argv[i], "--dtdattr"))) {
864 loaddtd++;
865 dtdattrs++;
866 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000867 (!strcmp(argv[i], "--valid")))
868 valid++;
869 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000870 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000871 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000872 loaddtd++;
873 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +0000874 (!strcmp(argv[i], "--dtdvalid"))) {
875 i++;
876 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000877 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000878 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000879 else if ((!strcmp(argv[i], "-insert")) ||
880 (!strcmp(argv[i], "--insert")))
881 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000882 else if ((!strcmp(argv[i], "-timing")) ||
883 (!strcmp(argv[i], "--timing")))
884 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000885 else if ((!strcmp(argv[i], "-auto")) ||
886 (!strcmp(argv[i], "--auto")))
887 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000888 else if ((!strcmp(argv[i], "-repeat")) ||
889 (!strcmp(argv[i], "--repeat")))
890 repeat++;
891 else if ((!strcmp(argv[i], "-push")) ||
892 (!strcmp(argv[i], "--push")))
893 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000894#ifdef HAVE_SYS_MMAN_H
895 else if ((!strcmp(argv[i], "-memory")) ||
896 (!strcmp(argv[i], "--memory")))
897 memory++;
898#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000899 else if ((!strcmp(argv[i], "-testIO")) ||
900 (!strcmp(argv[i], "--testIO")))
901 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000902#ifdef LIBXML_XINCLUDE_ENABLED
903 else if ((!strcmp(argv[i], "-xinclude")) ||
904 (!strcmp(argv[i], "--xinclude")))
905 xinclude++;
906#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000907 else if ((!strcmp(argv[i], "-compress")) ||
908 (!strcmp(argv[i], "--compress"))) {
909 compress++;
910 xmlSetCompressMode(9);
911 }
912 else if ((!strcmp(argv[i], "-nowarning")) ||
913 (!strcmp(argv[i], "--nowarning"))) {
914 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000915 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000916 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000917 else if ((!strcmp(argv[i], "-pedantic")) ||
918 (!strcmp(argv[i], "--pedantic"))) {
919 xmlGetWarningsDefaultValue = 1;
920 xmlPedanticParserDefault(1);
921 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000922#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000923 else if ((!strcmp(argv[i], "-debugent")) ||
924 (!strcmp(argv[i], "--debugent"))) {
925 debugent++;
926 xmlParserDebugEntities = 1;
927 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000928#endif
Daniel Veillard81418e32001-05-22 15:08:55 +0000929#ifdef LIBXML_CATALOG_ENABLED
930 else if ((!strcmp(argv[i], "-catalogs")) ||
931 (!strcmp(argv[i], "--catalogs"))) {
932 const char *catalogs;
933
934 catalogs = getenv("SGML_CATALOG_FILES");
935 if (catalogs == NULL) {
936 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
937 } else {
938 xmlLoadCatalogs(catalogs);
939 }
940 }
941#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000942 else if ((!strcmp(argv[i], "-encode")) ||
943 (!strcmp(argv[i], "--encode"))) {
944 i++;
945 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000946 /*
947 * OK it's for testing purposes
948 */
949 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000950 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000951 else if ((!strcmp(argv[i], "-noblanks")) ||
952 (!strcmp(argv[i], "--noblanks"))) {
953 noblanks++;
954 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +0000955 }
956 else if ((!strcmp(argv[i], "-format")) ||
957 (!strcmp(argv[i], "--format"))) {
958 noblanks++;
959 format++;
960 xmlKeepBlanksDefault(0);
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000961 } else {
962 fprintf(stderr, "Unknown option %s\n", argv[i]);
963 usage(argv[0]);
964 return(1);
965 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000966 }
Daniel Veillardd9bad132001-07-23 19:39:43 +0000967 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +0000968 if (loaddtd != 0)
969 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
970 if (dtdattrs)
971 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000972 if (noent != 0) xmlSubstituteEntitiesDefault(1);
973 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
974 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000975 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000976 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000977 xmlGenericError(xmlGenericErrorContext,
978 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
979 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000980 "<html><head><title>%s output</title></head>\n",
981 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000982 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000983 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
984 argv[0]);
985 }
986 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000987 if ((!strcmp(argv[i], "-encode")) ||
988 (!strcmp(argv[i], "--encode"))) {
989 i++;
990 continue;
991 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000992 if ((!strcmp(argv[i], "-dtdvalid")) ||
993 (!strcmp(argv[i], "--dtdvalid"))) {
994 i++;
995 continue;
996 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000997 if ((timing) && (repeat))
998 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000999 /* Remember file names. "-" means stding. <sven@zen.org> */
1000 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001001 if (repeat) {
1002 for (count = 0;count < 100 * repeat;count++)
1003 parseAndPrintFile(argv[i]);
1004 } else
1005 parseAndPrintFile(argv[i]);
1006 files ++;
1007 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001008 if ((timing) && (repeat)) {
1009 long msec;
1010 gettimeofday(&end, NULL);
1011 msec = end.tv_sec - begin.tv_sec;
1012 msec *= 1000;
1013 msec += (end.tv_usec - begin.tv_usec) / 1000;
1014 fprintf(stderr, "100 iteration took %ld ms\n", msec);
1015 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001016 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001017 if (generate)
1018 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001019 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001020 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001021 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001022 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001023 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001024 }
1025 xmlCleanupParser();
1026 xmlMemoryDump();
1027
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001028 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001029}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001030