blob: ba3c48ecc0c6a6839e36992e467f887d02b2b448 [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 Veillardb7664f42001-08-19 13:00:43 +0000719 cvp.userData = (void *) stderr;
720 cvp.error = (xmlValidityErrorFunc) fprintf;
721 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");
Daniel Veillard90493a92001-08-14 14:12:47 +0000796 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000797 printf("\t--testIO : test user I/O support\n");
798 printf("\t--encode encoding : output in the given encoding\n");
799#ifdef LIBXML_CATALOG_ENABLED
800 printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
801#endif
802 printf("\t--auto : generate a small doc on the fly\n");
803#ifdef LIBXML_XINCLUDE_ENABLED
804 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000805#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000806 printf("\t--loaddtd : fetch external Dtd\n");
807 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000808}
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000809int
810main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000811 int i, count;
812 int files = 0;
813
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000814 if (argc <= 1) {
815 usage(argv[0]);
816 return(1);
817 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000818 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000819 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000820 if (!strcmp(argv[i], "-"))
821 break;
822
823 if (argv[i][0] != '-')
824 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000825#ifdef LIBXML_DEBUG_ENABLED
826 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
827 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000828 else if ((!strcmp(argv[i], "-shell")) ||
829 (!strcmp(argv[i], "--shell"))) {
830 shell++;
831 noout = 1;
832 } else
833#endif
834 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
835 copy++;
836 else if ((!strcmp(argv[i], "-recover")) ||
837 (!strcmp(argv[i], "--recover")))
838 recovery++;
839 else if ((!strcmp(argv[i], "-noent")) ||
840 (!strcmp(argv[i], "--noent")))
841 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +0000842 else if ((!strcmp(argv[i], "-version")) ||
843 (!strcmp(argv[i], "--version")))
844 fprintf(stderr, "xmllint: using libxml version %s\n",
845 xmlParserVersion);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000846 else if ((!strcmp(argv[i], "-noout")) ||
847 (!strcmp(argv[i], "--noout")))
848 noout++;
849 else if ((!strcmp(argv[i], "-htmlout")) ||
850 (!strcmp(argv[i], "--htmlout")))
851 htmlout++;
852#ifdef LIBXML_HTML_ENABLED
853 else if ((!strcmp(argv[i], "-html")) ||
854 (!strcmp(argv[i], "--html"))) {
855 html++;
856 }
857#endif /* LIBXML_HTML_ENABLED */
858 else if ((!strcmp(argv[i], "-nowrap")) ||
859 (!strcmp(argv[i], "--nowrap")))
860 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000861 else if ((!strcmp(argv[i], "-loaddtd")) ||
862 (!strcmp(argv[i], "--loaddtd")))
863 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +0000864 else if ((!strcmp(argv[i], "-dtdattr")) ||
865 (!strcmp(argv[i], "--dtdattr"))) {
866 loaddtd++;
867 dtdattrs++;
868 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000869 (!strcmp(argv[i], "--valid")))
870 valid++;
871 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000872 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000873 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000874 loaddtd++;
875 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +0000876 (!strcmp(argv[i], "--dtdvalid"))) {
877 i++;
878 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000879 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000880 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000881 else if ((!strcmp(argv[i], "-insert")) ||
882 (!strcmp(argv[i], "--insert")))
883 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000884 else if ((!strcmp(argv[i], "-timing")) ||
885 (!strcmp(argv[i], "--timing")))
886 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000887 else if ((!strcmp(argv[i], "-auto")) ||
888 (!strcmp(argv[i], "--auto")))
889 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000890 else if ((!strcmp(argv[i], "-repeat")) ||
891 (!strcmp(argv[i], "--repeat")))
892 repeat++;
893 else if ((!strcmp(argv[i], "-push")) ||
894 (!strcmp(argv[i], "--push")))
895 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000896#ifdef HAVE_SYS_MMAN_H
897 else if ((!strcmp(argv[i], "-memory")) ||
898 (!strcmp(argv[i], "--memory")))
899 memory++;
900#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000901 else if ((!strcmp(argv[i], "-testIO")) ||
902 (!strcmp(argv[i], "--testIO")))
903 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000904#ifdef LIBXML_XINCLUDE_ENABLED
905 else if ((!strcmp(argv[i], "-xinclude")) ||
906 (!strcmp(argv[i], "--xinclude")))
907 xinclude++;
908#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000909 else if ((!strcmp(argv[i], "-compress")) ||
910 (!strcmp(argv[i], "--compress"))) {
911 compress++;
912 xmlSetCompressMode(9);
913 }
914 else if ((!strcmp(argv[i], "-nowarning")) ||
915 (!strcmp(argv[i], "--nowarning"))) {
916 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000917 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000918 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000919 else if ((!strcmp(argv[i], "-pedantic")) ||
920 (!strcmp(argv[i], "--pedantic"))) {
921 xmlGetWarningsDefaultValue = 1;
922 xmlPedanticParserDefault(1);
923 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000924#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000925 else if ((!strcmp(argv[i], "-debugent")) ||
926 (!strcmp(argv[i], "--debugent"))) {
927 debugent++;
928 xmlParserDebugEntities = 1;
929 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000930#endif
Daniel Veillard81418e32001-05-22 15:08:55 +0000931#ifdef LIBXML_CATALOG_ENABLED
932 else if ((!strcmp(argv[i], "-catalogs")) ||
933 (!strcmp(argv[i], "--catalogs"))) {
934 const char *catalogs;
935
936 catalogs = getenv("SGML_CATALOG_FILES");
937 if (catalogs == NULL) {
938 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
939 } else {
940 xmlLoadCatalogs(catalogs);
941 }
942 }
943#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000944 else if ((!strcmp(argv[i], "-encode")) ||
945 (!strcmp(argv[i], "--encode"))) {
946 i++;
947 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000948 /*
949 * OK it's for testing purposes
950 */
951 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000952 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000953 else if ((!strcmp(argv[i], "-noblanks")) ||
954 (!strcmp(argv[i], "--noblanks"))) {
955 noblanks++;
956 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +0000957 }
958 else if ((!strcmp(argv[i], "-format")) ||
959 (!strcmp(argv[i], "--format"))) {
960 noblanks++;
961 format++;
962 xmlKeepBlanksDefault(0);
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000963 } else {
964 fprintf(stderr, "Unknown option %s\n", argv[i]);
965 usage(argv[0]);
966 return(1);
967 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000968 }
Daniel Veillardd9bad132001-07-23 19:39:43 +0000969 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +0000970 if (loaddtd != 0)
971 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
972 if (dtdattrs)
973 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000974 if (noent != 0) xmlSubstituteEntitiesDefault(1);
975 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
976 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000977 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000978 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000979 xmlGenericError(xmlGenericErrorContext,
980 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
981 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000982 "<html><head><title>%s output</title></head>\n",
983 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000984 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000985 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
986 argv[0]);
987 }
988 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000989 if ((!strcmp(argv[i], "-encode")) ||
990 (!strcmp(argv[i], "--encode"))) {
991 i++;
992 continue;
993 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000994 if ((!strcmp(argv[i], "-dtdvalid")) ||
995 (!strcmp(argv[i], "--dtdvalid"))) {
996 i++;
997 continue;
998 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000999 if ((timing) && (repeat))
1000 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001001 /* Remember file names. "-" means stding. <sven@zen.org> */
1002 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001003 if (repeat) {
1004 for (count = 0;count < 100 * repeat;count++)
1005 parseAndPrintFile(argv[i]);
1006 } else
1007 parseAndPrintFile(argv[i]);
1008 files ++;
1009 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001010 if ((timing) && (repeat)) {
1011 long msec;
1012 gettimeofday(&end, NULL);
1013 msec = end.tv_sec - begin.tv_sec;
1014 msec *= 1000;
1015 msec += (end.tv_usec - begin.tv_usec) / 1000;
1016 fprintf(stderr, "100 iteration took %ld ms\n", msec);
1017 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001018 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001019 if (generate)
1020 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001021 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001022 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001023 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001024 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001025 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001026 }
1027 xmlCleanupParser();
1028 xmlMemoryDump();
1029
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001030 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001031}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001032