blob: 22f8ea30df2f145b87ad943811d224dbd948f66a [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 Veillarde2940dd2001-08-22 00:06:49 +0000107#ifdef LIBXML_CATALOG_ENABLED
108static int catalogs = 0;
109static int nocatalogs = 0;
110#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000111
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000112/************************************************************************
113 * *
114 * HTML ouput *
115 * *
116 ************************************************************************/
117char buffer[50000];
118
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000119static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000120xmlHTMLEncodeSend(void) {
121 char *result;
122
123 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
124 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000125 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000126 xmlFree(result);
127 }
128 buffer[0] = 0;
129}
130
131/**
132 * xmlHTMLPrintFileInfo:
133 * @input: an xmlParserInputPtr input
134 *
135 * Displays the associated file and line informations for the current input
136 */
137
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000138static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000139xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000140 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000141 if (input != NULL) {
142 if (input->filename) {
143 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
144 input->line);
145 } else {
146 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
147 }
148 }
149 xmlHTMLEncodeSend();
150}
151
152/**
153 * xmlHTMLPrintFileContext:
154 * @input: an xmlParserInputPtr input
155 *
156 * Displays current context within the input content for error tracking
157 */
158
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000159static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000160xmlHTMLPrintFileContext(xmlParserInputPtr input) {
161 const xmlChar *cur, *base;
162 int n;
163
164 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000165 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000166 cur = input->cur;
167 base = input->base;
168 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
169 cur--;
170 }
171 n = 0;
172 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
173 cur--;
174 if ((*cur == '\n') || (*cur == '\r')) cur++;
175 base = cur;
176 n = 0;
177 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
178 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
179 n++;
180 }
181 sprintf(&buffer[strlen(buffer)], "\n");
182 cur = input->cur;
183 while ((*cur == '\n') || (*cur == '\r'))
184 cur--;
185 n = 0;
186 while ((cur != base) && (n++ < 80)) {
187 sprintf(&buffer[strlen(buffer)], " ");
188 base++;
189 }
190 sprintf(&buffer[strlen(buffer)],"^\n");
191 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000192 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000193}
194
195/**
196 * xmlHTMLError:
197 * @ctx: an XML parser context
198 * @msg: the message to display/transmit
199 * @...: extra parameters for the message display
200 *
201 * Display and format an error messages, gives file, line, position and
202 * extra parameters.
203 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000204static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000205xmlHTMLError(void *ctx, const char *msg, ...)
206{
207 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
208 xmlParserInputPtr input;
209 xmlParserInputPtr cur = NULL;
210 va_list args;
211
212 buffer[0] = 0;
213 input = ctxt->input;
214 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
215 cur = input;
216 input = ctxt->inputTab[ctxt->inputNr - 2];
217 }
218
219 xmlHTMLPrintFileInfo(input);
220
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000221 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000222 va_start(args, msg);
223 vsprintf(&buffer[strlen(buffer)], msg, args);
224 va_end(args);
225 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000226 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000227
228 xmlHTMLPrintFileContext(input);
229 xmlHTMLEncodeSend();
230}
231
232/**
233 * xmlHTMLWarning:
234 * @ctx: an XML parser context
235 * @msg: the message to display/transmit
236 * @...: extra parameters for the message display
237 *
238 * Display and format a warning messages, gives file, line, position and
239 * extra parameters.
240 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000241static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000242xmlHTMLWarning(void *ctx, const char *msg, ...)
243{
244 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
245 xmlParserInputPtr input;
246 xmlParserInputPtr cur = NULL;
247 va_list args;
248
249 buffer[0] = 0;
250 input = ctxt->input;
251 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
252 cur = input;
253 input = ctxt->inputTab[ctxt->inputNr - 2];
254 }
255
256
257 xmlHTMLPrintFileInfo(input);
258
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000259 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000260 va_start(args, msg);
261 vsprintf(&buffer[strlen(buffer)], msg, args);
262 va_end(args);
263 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000264 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000265
266 xmlHTMLPrintFileContext(input);
267 xmlHTMLEncodeSend();
268}
269
270/**
271 * xmlHTMLValidityError:
272 * @ctx: an XML parser context
273 * @msg: the message to display/transmit
274 * @...: extra parameters for the message display
275 *
276 * Display and format an validity error messages, gives file,
277 * line, position and extra parameters.
278 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000279static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000280xmlHTMLValidityError(void *ctx, const char *msg, ...)
281{
282 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
283 xmlParserInputPtr input;
284 va_list args;
285
286 buffer[0] = 0;
287 input = ctxt->input;
288 if ((input->filename == NULL) && (ctxt->inputNr > 1))
289 input = ctxt->inputTab[ctxt->inputNr - 2];
290
291 xmlHTMLPrintFileInfo(input);
292
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000293 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000294 va_start(args, msg);
295 vsprintf(&buffer[strlen(buffer)], msg, args);
296 va_end(args);
297 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000298 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000299
300 xmlHTMLPrintFileContext(input);
301 xmlHTMLEncodeSend();
302}
303
304/**
305 * xmlHTMLValidityWarning:
306 * @ctx: an XML parser context
307 * @msg: the message to display/transmit
308 * @...: extra parameters for the message display
309 *
310 * Display and format a validity warning messages, gives file, line,
311 * position and extra parameters.
312 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000313static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000314xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
315{
316 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
317 xmlParserInputPtr input;
318 va_list args;
319
320 buffer[0] = 0;
321 input = ctxt->input;
322 if ((input->filename == NULL) && (ctxt->inputNr > 1))
323 input = ctxt->inputTab[ctxt->inputNr - 2];
324
325 xmlHTMLPrintFileInfo(input);
326
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000327 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000328 va_start(args, msg);
329 vsprintf(&buffer[strlen(buffer)], msg, args);
330 va_end(args);
331 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000332 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000333
334 xmlHTMLPrintFileContext(input);
335 xmlHTMLEncodeSend();
336}
337
338/************************************************************************
339 * *
340 * Shell Interface *
341 * *
342 ************************************************************************/
343/**
344 * xmlShellReadline:
345 * @prompt: the prompt value
346 *
347 * Read a string
348 *
349 * Returns a pointer to it or NULL on EOF the caller is expected to
350 * free the returned string.
351 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000352static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000353xmlShellReadline(char *prompt) {
354#ifdef HAVE_LIBREADLINE
355 char *line_read;
356
357 /* Get a line from the user. */
358 line_read = readline (prompt);
359
360 /* If the line has any text in it, save it on the history. */
361 if (line_read && *line_read)
362 add_history (line_read);
363
364 return (line_read);
365#else
366 char line_read[501];
367
368 if (prompt != NULL)
369 fprintf(stdout, "%s", prompt);
370 if (!fgets(line_read, 500, stdin))
371 return(NULL);
372 line_read[500] = 0;
373 return(strdup(line_read));
374#endif
375}
376
377/************************************************************************
378 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000379 * I/O Interfaces *
380 * *
381 ************************************************************************/
382
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000383static int myRead(FILE *f, char * buf, int len) {
384 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000385}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000386static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000387 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000388 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000389 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000390}
391
392/************************************************************************
393 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000394 * Test processing *
395 * *
396 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000397static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000398 xmlDocPtr doc = NULL, tmp;
399
Daniel Veillard48b2f892001-02-25 16:11:03 +0000400 if ((timing) && (!repeat))
401 gettimeofday(&begin, NULL);
402
403
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000404 if (filename == NULL) {
405 if (generate) {
406 xmlNodePtr n;
407
408 doc = xmlNewDoc(BAD_CAST "1.0");
409 n = xmlNewNode(NULL, BAD_CAST "info");
410 xmlNodeSetContent(n, BAD_CAST "abc");
411 xmlDocSetRootElement(doc, n);
412 }
413 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000414#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000415 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000416 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000417 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000418#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000419 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000420 /*
421 * build an XML tree from a string;
422 */
423 if (push) {
424 FILE *f;
425
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000426 /* '-' Usually means stdin -<sven@zen.org> */
427 if ((filename[0] == '-') && (filename[1] == 0)) {
428 f = stdin;
429 } else {
430 f = fopen(filename, "r");
431 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000432 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000433 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000434 int res, size = 3;
435 char chars[1024];
436 xmlParserCtxtPtr ctxt;
437
438 if (repeat)
439 size = 1024;
440 res = fread(chars, 1, 4, f);
441 if (res > 0) {
442 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
443 chars, res, filename);
444 while ((res = fread(chars, 1, size, f)) > 0) {
445 xmlParseChunk(ctxt, chars, res, 0);
446 }
447 xmlParseChunk(ctxt, chars, 0, 1);
448 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000449 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000450 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000451 if (!ret) {
452 xmlFreeDoc(doc);
453 doc = NULL;
454 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000455 }
456 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000457 } else if (testIO) {
458 int ret;
459 FILE *f;
460
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000461 /* '-' Usually means stdin -<sven@zen.org> */
462 if ((filename[0] == '-') && (filename[1] == 0)) {
463 f = stdin;
464 } else {
465 f = fopen(filename, "r");
466 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000467 if (f != NULL) {
468 xmlParserCtxtPtr ctxt;
469
470 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
471 (xmlInputReadCallback) myRead,
472 (xmlInputCloseCallback) myClose,
473 f, XML_CHAR_ENCODING_NONE);
474 xmlParseDocument(ctxt);
475
476 ret = ctxt->wellFormed;
477 doc = ctxt->myDoc;
478 xmlFreeParserCtxt(ctxt);
479 if (!ret) {
480 xmlFreeDoc(doc);
481 doc = NULL;
482 }
483 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000484 } else if (recovery) {
485 doc = xmlRecoverFile(filename);
486 } else if (htmlout) {
487 int ret;
488 xmlParserCtxtPtr ctxt;
489 xmlSAXHandler silent, *old;
490
491 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000492
493 if (ctxt == NULL) {
494 /* If xmlCreateFileParseCtxt() return NULL something
495 strange happened so we don't want to do anything. Do
496 we want to print an error message here?
497 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000498 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000499 } else {
500 memcpy(&silent, ctxt->sax, sizeof(silent));
501 old = ctxt->sax;
502 silent.error = xmlHTMLError;
503 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000504 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000505 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000506 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000507 silent.fatalError = xmlHTMLError;
508 ctxt->sax = &silent;
509 ctxt->vctxt.error = xmlHTMLValidityError;
510 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000511 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000512 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000513 ctxt->vctxt.warning = NULL;
514
Daniel Veillard88a172f2000-08-04 18:23:10 +0000515 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000516
Daniel Veillard88a172f2000-08-04 18:23:10 +0000517 ret = ctxt->wellFormed;
518 doc = ctxt->myDoc;
519 ctxt->sax = old;
520 xmlFreeParserCtxt(ctxt);
521 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000522 xmlFreeDoc(doc);
523 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000524 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000525 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000526#ifdef HAVE_SYS_MMAN_H
527 } else if (memory) {
528 int fd;
529 struct stat info;
530 const char *base;
531 if (stat(filename, &info) < 0)
532 return;
533 if ((fd = open(filename, O_RDONLY)) < 0)
534 return;
535 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000536 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000537 return;
538
539 doc = xmlParseMemory((char *) base, info.st_size);
540 munmap((char *) base, info.st_size);
541#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000542 } else
543 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000544 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000545
Daniel Veillard88a172f2000-08-04 18:23:10 +0000546 /*
547 * If we don't have a document we might as well give up. Do we
548 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000549 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000550 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000551 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000552 }
553
Daniel Veillard48b2f892001-02-25 16:11:03 +0000554 if ((timing) && (!repeat)) {
555 long msec;
556 gettimeofday(&end, NULL);
557 msec = end.tv_sec - begin.tv_sec;
558 msec *= 1000;
559 msec += (end.tv_usec - begin.tv_usec) / 1000;
560 fprintf(stderr, "Parsing took %ld ms\n", msec);
561 }
562
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000563#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000564 if (xinclude) {
565 if ((timing) && (!repeat)) {
566 gettimeofday(&begin, NULL);
567 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000568 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000569 if ((timing) && (!repeat)) {
570 long msec;
571 gettimeofday(&end, NULL);
572 msec = end.tv_sec - begin.tv_sec;
573 msec *= 1000;
574 msec += (end.tv_usec - begin.tv_usec) / 1000;
575 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
576 }
577 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000578#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000579
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000580#ifdef LIBXML_DEBUG_ENABLED
581 /*
582 * shell interraction
583 */
584 if (shell)
585 xmlShell(doc, filename, xmlShellReadline, stdout);
586#endif
587
588 /*
589 * test intermediate copy if needed.
590 */
591 if (copy) {
592 tmp = doc;
593 doc = xmlCopyDoc(doc, 1);
594 xmlFreeDoc(tmp);
595 }
596
597 if ((insert) && (!html)) {
598 const xmlChar* list[256];
599 int nb, i;
600 xmlNodePtr node;
601
602 if (doc->children != NULL) {
603 node = doc->children;
604 while ((node != NULL) && (node->last == NULL)) node = node->next;
605 if (node != NULL) {
606 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
607 if (nb < 0) {
608 printf("could not get valid list of elements\n");
609 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000610 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000611 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000612 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000613 nb);
614 for (i = 0;i < nb;i++) {
615 printf("%s\n", list[i]);
616 }
617 }
618 }
619 }
620 }else if (noout == 0) {
621 /*
622 * print it.
623 */
624#ifdef LIBXML_DEBUG_ENABLED
625 if (!debug) {
626#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000627 if ((timing) && (!repeat)) {
628 gettimeofday(&begin, NULL);
629 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000630#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000631 if (memory) {
632 xmlChar *result;
633 int len;
634
635 if (encoding != NULL) {
636 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
637 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +0000638 if (format)
639 xmlDocDumpFormatMemory(doc, &result, &len, 1);
640 else
641 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000642 }
643 if (result == NULL) {
644 fprintf(stderr, "Failed to save\n");
645 } else {
646 write(1, result, len);
647 xmlFree(result);
648 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000649 } else
650#endif /* HAVE_SYS_MMAN_H */
651 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000652 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000653 else if (encoding != NULL)
654 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillard90493a92001-08-14 14:12:47 +0000655 else if (format)
656 xmlSaveFormatFile("-", doc, 1);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000657 else
658 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000659 if ((timing) && (!repeat)) {
660 long msec;
661 gettimeofday(&end, NULL);
662 msec = end.tv_sec - begin.tv_sec;
663 msec *= 1000;
664 msec += (end.tv_usec - begin.tv_usec) / 1000;
665 fprintf(stderr, "Saving took %ld ms\n", msec);
666 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000667#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000668 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000669 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000670 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000671#endif
672 }
673
674 /*
675 * A posteriori validation test
676 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000677 if (dtdvalid != NULL) {
678 xmlDtdPtr dtd;
679
Daniel Veillard48b2f892001-02-25 16:11:03 +0000680 if ((timing) && (!repeat)) {
681 gettimeofday(&begin, NULL);
682 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000683 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000684 if ((timing) && (!repeat)) {
685 long msec;
686 gettimeofday(&end, NULL);
687 msec = end.tv_sec - begin.tv_sec;
688 msec *= 1000;
689 msec += (end.tv_usec - begin.tv_usec) / 1000;
690 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
691 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000692 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000693 xmlGenericError(xmlGenericErrorContext,
694 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000695 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000696 } else {
697 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000698 if ((timing) && (!repeat)) {
699 gettimeofday(&begin, NULL);
700 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000701 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
702 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000703 xmlGenericError(xmlGenericErrorContext,
704 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000705 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000706 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000707 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000708 if ((timing) && (!repeat)) {
709 long msec;
710 gettimeofday(&end, NULL);
711 msec = end.tv_sec - begin.tv_sec;
712 msec *= 1000;
713 msec += (end.tv_usec - begin.tv_usec) / 1000;
714 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
715 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000716 xmlFreeDtd(dtd);
717 }
718 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000719 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000720 if ((timing) && (!repeat)) {
721 gettimeofday(&begin, NULL);
722 }
Daniel Veillardb7664f42001-08-19 13:00:43 +0000723 cvp.userData = (void *) stderr;
724 cvp.error = (xmlValidityErrorFunc) fprintf;
725 cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000726 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000727 xmlGenericError(xmlGenericErrorContext,
728 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000729 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000730 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000731 if ((timing) && (!repeat)) {
732 long msec;
733 gettimeofday(&end, NULL);
734 msec = end.tv_sec - begin.tv_sec;
735 msec *= 1000;
736 msec += (end.tv_usec - begin.tv_usec) / 1000;
737 fprintf(stderr, "Validating took %ld ms\n", msec);
738 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000739 }
740
741#ifdef LIBXML_DEBUG_ENABLED
742 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000743 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000744#endif
745
746 /*
747 * free it.
748 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000749 if ((timing) && (!repeat)) {
750 gettimeofday(&begin, NULL);
751 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000752 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000753 if ((timing) && (!repeat)) {
754 long msec;
755 gettimeofday(&end, NULL);
756 msec = end.tv_sec - begin.tv_sec;
757 msec *= 1000;
758 msec += (end.tv_usec - begin.tv_usec) / 1000;
759 fprintf(stderr, "Freeing took %ld ms\n", msec);
760 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000761}
762
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000763/************************************************************************
764 * *
765 * Usage and Main *
766 * *
767 ************************************************************************/
768
769static void usage(const char *name) {
770 printf("Usage : %s [options] XMLfiles ...\n", name);
771 printf("\tParse the XML files and output the result of the parsing\n");
772 printf("\t--version : display the version of the XML library used\n");
773#ifdef LIBXML_DEBUG_ENABLED
774 printf("\t--debug : dump a debug tree of the in-memory document\n");
775 printf("\t--shell : run a navigating shell\n");
776 printf("\t--debugent : debug the entities defined in the document\n");
777#endif
778 printf("\t--copy : used to test the internal copy implementation\n");
779 printf("\t--recover : output what was parsable on broken XML documents\n");
780 printf("\t--noent : substitute entity references by their value\n");
781 printf("\t--noout : don't output the result tree\n");
782 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +0000783 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000784 printf("\t--valid : validate the document in addition to std well-formed check\n");
785 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
786 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
787 printf("\t--timing : print some timings\n");
788 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
789 printf("\t--insert : ad-hoc test for valid insertions\n");
790 printf("\t--compress : turn on gzip compression of output\n");
791#ifdef LIBXML_HTML_ENABLED
792 printf("\t--html : use the HTML parser\n");
793#endif
794 printf("\t--push : use the push mode of the parser\n");
795#ifdef HAVE_SYS_MMAN_H
796 printf("\t--memory : parse from memory\n");
797#endif
798 printf("\t--nowarning : do not emit warnings from parser/validator\n");
799 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +0000800 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000801 printf("\t--testIO : test user I/O support\n");
802 printf("\t--encode encoding : output in the given encoding\n");
803#ifdef LIBXML_CATALOG_ENABLED
804 printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000805 printf("\t otherwise /etc/xml/catalog is activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +0000806 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000807#endif
808 printf("\t--auto : generate a small doc on the fly\n");
809#ifdef LIBXML_XINCLUDE_ENABLED
810 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000811#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000812 printf("\t--loaddtd : fetch external Dtd\n");
813 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000814}
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000815int
816main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000817 int i, count;
818 int files = 0;
819
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000820 if (argc <= 1) {
821 usage(argv[0]);
822 return(1);
823 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000824 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000825 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000826 if (!strcmp(argv[i], "-"))
827 break;
828
829 if (argv[i][0] != '-')
830 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000831#ifdef LIBXML_DEBUG_ENABLED
832 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
833 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000834 else if ((!strcmp(argv[i], "-shell")) ||
835 (!strcmp(argv[i], "--shell"))) {
836 shell++;
837 noout = 1;
838 } else
839#endif
840 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
841 copy++;
842 else if ((!strcmp(argv[i], "-recover")) ||
843 (!strcmp(argv[i], "--recover")))
844 recovery++;
845 else if ((!strcmp(argv[i], "-noent")) ||
846 (!strcmp(argv[i], "--noent")))
847 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +0000848 else if ((!strcmp(argv[i], "-version")) ||
849 (!strcmp(argv[i], "--version")))
850 fprintf(stderr, "xmllint: using libxml version %s\n",
851 xmlParserVersion);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000852 else if ((!strcmp(argv[i], "-noout")) ||
853 (!strcmp(argv[i], "--noout")))
854 noout++;
855 else if ((!strcmp(argv[i], "-htmlout")) ||
856 (!strcmp(argv[i], "--htmlout")))
857 htmlout++;
858#ifdef LIBXML_HTML_ENABLED
859 else if ((!strcmp(argv[i], "-html")) ||
860 (!strcmp(argv[i], "--html"))) {
861 html++;
862 }
863#endif /* LIBXML_HTML_ENABLED */
864 else if ((!strcmp(argv[i], "-nowrap")) ||
865 (!strcmp(argv[i], "--nowrap")))
866 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000867 else if ((!strcmp(argv[i], "-loaddtd")) ||
868 (!strcmp(argv[i], "--loaddtd")))
869 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +0000870 else if ((!strcmp(argv[i], "-dtdattr")) ||
871 (!strcmp(argv[i], "--dtdattr"))) {
872 loaddtd++;
873 dtdattrs++;
874 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000875 (!strcmp(argv[i], "--valid")))
876 valid++;
877 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000878 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000879 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000880 loaddtd++;
881 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +0000882 (!strcmp(argv[i], "--dtdvalid"))) {
883 i++;
884 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000885 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000886 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000887 else if ((!strcmp(argv[i], "-insert")) ||
888 (!strcmp(argv[i], "--insert")))
889 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000890 else if ((!strcmp(argv[i], "-timing")) ||
891 (!strcmp(argv[i], "--timing")))
892 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000893 else if ((!strcmp(argv[i], "-auto")) ||
894 (!strcmp(argv[i], "--auto")))
895 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000896 else if ((!strcmp(argv[i], "-repeat")) ||
897 (!strcmp(argv[i], "--repeat")))
898 repeat++;
899 else if ((!strcmp(argv[i], "-push")) ||
900 (!strcmp(argv[i], "--push")))
901 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000902#ifdef HAVE_SYS_MMAN_H
903 else if ((!strcmp(argv[i], "-memory")) ||
904 (!strcmp(argv[i], "--memory")))
905 memory++;
906#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000907 else if ((!strcmp(argv[i], "-testIO")) ||
908 (!strcmp(argv[i], "--testIO")))
909 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000910#ifdef LIBXML_XINCLUDE_ENABLED
911 else if ((!strcmp(argv[i], "-xinclude")) ||
912 (!strcmp(argv[i], "--xinclude")))
913 xinclude++;
914#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000915 else if ((!strcmp(argv[i], "-compress")) ||
916 (!strcmp(argv[i], "--compress"))) {
917 compress++;
918 xmlSetCompressMode(9);
919 }
920 else if ((!strcmp(argv[i], "-nowarning")) ||
921 (!strcmp(argv[i], "--nowarning"))) {
922 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000923 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000924 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000925 else if ((!strcmp(argv[i], "-pedantic")) ||
926 (!strcmp(argv[i], "--pedantic"))) {
927 xmlGetWarningsDefaultValue = 1;
928 xmlPedanticParserDefault(1);
929 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000930#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000931 else if ((!strcmp(argv[i], "-debugent")) ||
932 (!strcmp(argv[i], "--debugent"))) {
933 debugent++;
934 xmlParserDebugEntities = 1;
935 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000936#endif
Daniel Veillard81418e32001-05-22 15:08:55 +0000937#ifdef LIBXML_CATALOG_ENABLED
938 else if ((!strcmp(argv[i], "-catalogs")) ||
939 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000940 catalogs++;
941 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
942 (!strcmp(argv[i], "--nocatalogs"))) {
943 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +0000944 }
945#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000946 else if ((!strcmp(argv[i], "-encode")) ||
947 (!strcmp(argv[i], "--encode"))) {
948 i++;
949 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000950 /*
951 * OK it's for testing purposes
952 */
953 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000954 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000955 else if ((!strcmp(argv[i], "-noblanks")) ||
956 (!strcmp(argv[i], "--noblanks"))) {
957 noblanks++;
958 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +0000959 }
960 else if ((!strcmp(argv[i], "-format")) ||
961 (!strcmp(argv[i], "--format"))) {
962 noblanks++;
963 format++;
964 xmlKeepBlanksDefault(0);
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000965 } else {
966 fprintf(stderr, "Unknown option %s\n", argv[i]);
967 usage(argv[0]);
968 return(1);
969 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000970 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000971
972#ifdef LIBXML_CATALOG_ENABLED
973 if (nocatalogs == 0) {
974 if (catalogs) {
975 const char *catal;
976
977 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +0000978 if (catal != NULL) {
979 xmlLoadCatalogs(catal);
980 } else {
981 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
982 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000983 }
984 }
985#endif
Daniel Veillardd9bad132001-07-23 19:39:43 +0000986 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +0000987 if (loaddtd != 0)
988 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
989 if (dtdattrs)
990 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000991 if (noent != 0) xmlSubstituteEntitiesDefault(1);
992 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
993 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000994 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000995 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000996 xmlGenericError(xmlGenericErrorContext,
997 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
998 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000999 "<html><head><title>%s output</title></head>\n",
1000 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001001 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001002 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1003 argv[0]);
1004 }
1005 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001006 if ((!strcmp(argv[i], "-encode")) ||
1007 (!strcmp(argv[i], "--encode"))) {
1008 i++;
1009 continue;
1010 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001011 if ((!strcmp(argv[i], "-dtdvalid")) ||
1012 (!strcmp(argv[i], "--dtdvalid"))) {
1013 i++;
1014 continue;
1015 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001016 if ((timing) && (repeat))
1017 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001018 /* Remember file names. "-" means stding. <sven@zen.org> */
1019 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001020 if (repeat) {
1021 for (count = 0;count < 100 * repeat;count++)
1022 parseAndPrintFile(argv[i]);
1023 } else
1024 parseAndPrintFile(argv[i]);
1025 files ++;
1026 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001027 if ((timing) && (repeat)) {
1028 long msec;
1029 gettimeofday(&end, NULL);
1030 msec = end.tv_sec - begin.tv_sec;
1031 msec *= 1000;
1032 msec += (end.tv_usec - begin.tv_usec) / 1000;
1033 fprintf(stderr, "100 iteration took %ld ms\n", msec);
1034 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001035 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001036 if (generate)
1037 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001038 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001039 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001040 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001041 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001042 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001043 }
1044 xmlCleanupParser();
1045 xmlMemoryDump();
1046
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001047 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001048}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001049