blob: da8939d6f8b6c729336d4a7ca7ab28f7f126932f [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 Veillard89cad532001-10-22 09:46:13 +000071#ifdef LIBXML_DOCB_ENABLED
72#include <libxml/DOCBparser.h>
73#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000074#include <libxml/globals.h>
Daniel Veillardce8b83b2000-04-05 18:38:42 +000075
76#ifdef LIBXML_DEBUG_ENABLED
77static int debug = 0;
78static int shell = 0;
79static int debugent = 0;
80#endif
81static int copy = 0;
82static int recovery = 0;
83static int noent = 0;
84static int noout = 0;
85static int nowrap = 0;
86static int valid = 0;
87static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +000088static char * dtdvalid = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000089static int repeat = 0;
90static int insert = 0;
91static int compress = 0;
Daniel Veillard89cad532001-10-22 09:46:13 +000092#ifdef LIBXML_DOCB_ENABLED
93static int sgml = 0;
94#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000095static int html = 0;
96static int htmlout = 0;
97static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +000098#ifdef HAVE_SYS_MMAN_H
99static int memory = 0;
100#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000101static int noblanks = 0;
Daniel Veillard90493a92001-08-14 14:12:47 +0000102static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000103static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000104static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000105#ifdef LIBXML_XINCLUDE_ENABLED
106static int xinclude = 0;
107#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000108static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000109static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000110static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000111static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000112static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000113static struct timeval begin, end;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000114#ifdef LIBXML_CATALOG_ENABLED
115static int catalogs = 0;
116static int nocatalogs = 0;
117#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000118
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000119/************************************************************************
120 * *
121 * HTML ouput *
122 * *
123 ************************************************************************/
124char buffer[50000];
125
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000126static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000127xmlHTMLEncodeSend(void) {
128 char *result;
129
130 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
131 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000132 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000133 xmlFree(result);
134 }
135 buffer[0] = 0;
136}
137
138/**
139 * xmlHTMLPrintFileInfo:
140 * @input: an xmlParserInputPtr input
141 *
142 * Displays the associated file and line informations for the current input
143 */
144
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000145static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000146xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000147 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000148 if (input != NULL) {
149 if (input->filename) {
150 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
151 input->line);
152 } else {
153 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
154 }
155 }
156 xmlHTMLEncodeSend();
157}
158
159/**
160 * xmlHTMLPrintFileContext:
161 * @input: an xmlParserInputPtr input
162 *
163 * Displays current context within the input content for error tracking
164 */
165
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000166static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000167xmlHTMLPrintFileContext(xmlParserInputPtr input) {
168 const xmlChar *cur, *base;
169 int n;
170
171 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000172 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000173 cur = input->cur;
174 base = input->base;
175 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
176 cur--;
177 }
178 n = 0;
179 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
180 cur--;
181 if ((*cur == '\n') || (*cur == '\r')) cur++;
182 base = cur;
183 n = 0;
184 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
185 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
186 n++;
187 }
188 sprintf(&buffer[strlen(buffer)], "\n");
189 cur = input->cur;
190 while ((*cur == '\n') || (*cur == '\r'))
191 cur--;
192 n = 0;
193 while ((cur != base) && (n++ < 80)) {
194 sprintf(&buffer[strlen(buffer)], " ");
195 base++;
196 }
197 sprintf(&buffer[strlen(buffer)],"^\n");
198 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000199 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000200}
201
202/**
203 * xmlHTMLError:
204 * @ctx: an XML parser context
205 * @msg: the message to display/transmit
206 * @...: extra parameters for the message display
207 *
208 * Display and format an error messages, gives file, line, position and
209 * extra parameters.
210 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000211static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000212xmlHTMLError(void *ctx, const char *msg, ...)
213{
214 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
215 xmlParserInputPtr input;
216 xmlParserInputPtr cur = NULL;
217 va_list args;
218
219 buffer[0] = 0;
220 input = ctxt->input;
221 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
222 cur = input;
223 input = ctxt->inputTab[ctxt->inputNr - 2];
224 }
225
226 xmlHTMLPrintFileInfo(input);
227
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000228 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000229 va_start(args, msg);
230 vsprintf(&buffer[strlen(buffer)], msg, args);
231 va_end(args);
232 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000233 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000234
235 xmlHTMLPrintFileContext(input);
236 xmlHTMLEncodeSend();
237}
238
239/**
240 * xmlHTMLWarning:
241 * @ctx: an XML parser context
242 * @msg: the message to display/transmit
243 * @...: extra parameters for the message display
244 *
245 * Display and format a warning messages, gives file, line, position and
246 * extra parameters.
247 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000248static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000249xmlHTMLWarning(void *ctx, const char *msg, ...)
250{
251 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
252 xmlParserInputPtr input;
253 xmlParserInputPtr cur = NULL;
254 va_list args;
255
256 buffer[0] = 0;
257 input = ctxt->input;
258 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
259 cur = input;
260 input = ctxt->inputTab[ctxt->inputNr - 2];
261 }
262
263
264 xmlHTMLPrintFileInfo(input);
265
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000266 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000267 va_start(args, msg);
268 vsprintf(&buffer[strlen(buffer)], msg, args);
269 va_end(args);
270 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000271 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000272
273 xmlHTMLPrintFileContext(input);
274 xmlHTMLEncodeSend();
275}
276
277/**
278 * xmlHTMLValidityError:
279 * @ctx: an XML parser context
280 * @msg: the message to display/transmit
281 * @...: extra parameters for the message display
282 *
283 * Display and format an validity error messages, gives file,
284 * line, position and extra parameters.
285 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000286static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000287xmlHTMLValidityError(void *ctx, const char *msg, ...)
288{
289 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
290 xmlParserInputPtr input;
291 va_list args;
292
293 buffer[0] = 0;
294 input = ctxt->input;
295 if ((input->filename == NULL) && (ctxt->inputNr > 1))
296 input = ctxt->inputTab[ctxt->inputNr - 2];
297
298 xmlHTMLPrintFileInfo(input);
299
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000300 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000301 va_start(args, msg);
302 vsprintf(&buffer[strlen(buffer)], msg, args);
303 va_end(args);
304 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000305 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000306
307 xmlHTMLPrintFileContext(input);
308 xmlHTMLEncodeSend();
309}
310
311/**
312 * xmlHTMLValidityWarning:
313 * @ctx: an XML parser context
314 * @msg: the message to display/transmit
315 * @...: extra parameters for the message display
316 *
317 * Display and format a validity warning messages, gives file, line,
318 * position and extra parameters.
319 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000320static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000321xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
322{
323 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
324 xmlParserInputPtr input;
325 va_list args;
326
327 buffer[0] = 0;
328 input = ctxt->input;
329 if ((input->filename == NULL) && (ctxt->inputNr > 1))
330 input = ctxt->inputTab[ctxt->inputNr - 2];
331
332 xmlHTMLPrintFileInfo(input);
333
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000334 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000335 va_start(args, msg);
336 vsprintf(&buffer[strlen(buffer)], msg, args);
337 va_end(args);
338 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000339 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000340
341 xmlHTMLPrintFileContext(input);
342 xmlHTMLEncodeSend();
343}
344
345/************************************************************************
346 * *
347 * Shell Interface *
348 * *
349 ************************************************************************/
350/**
351 * xmlShellReadline:
352 * @prompt: the prompt value
353 *
354 * Read a string
355 *
356 * Returns a pointer to it or NULL on EOF the caller is expected to
357 * free the returned string.
358 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000359static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000360xmlShellReadline(char *prompt) {
361#ifdef HAVE_LIBREADLINE
362 char *line_read;
363
364 /* Get a line from the user. */
365 line_read = readline (prompt);
366
367 /* If the line has any text in it, save it on the history. */
368 if (line_read && *line_read)
369 add_history (line_read);
370
371 return (line_read);
372#else
373 char line_read[501];
374
375 if (prompt != NULL)
376 fprintf(stdout, "%s", prompt);
377 if (!fgets(line_read, 500, stdin))
378 return(NULL);
379 line_read[500] = 0;
380 return(strdup(line_read));
381#endif
382}
383
384/************************************************************************
385 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000386 * I/O Interfaces *
387 * *
388 ************************************************************************/
389
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000390static int myRead(FILE *f, char * buf, int len) {
391 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000392}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000393static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000394 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000395 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000396 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000397}
398
399/************************************************************************
400 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000401 * Test processing *
402 * *
403 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000404static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000405 xmlDocPtr doc = NULL, tmp;
406
Daniel Veillard48b2f892001-02-25 16:11:03 +0000407 if ((timing) && (!repeat))
408 gettimeofday(&begin, NULL);
409
410
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000411 if (filename == NULL) {
412 if (generate) {
413 xmlNodePtr n;
414
415 doc = xmlNewDoc(BAD_CAST "1.0");
416 n = xmlNewNode(NULL, BAD_CAST "info");
417 xmlNodeSetContent(n, BAD_CAST "abc");
418 xmlDocSetRootElement(doc, n);
419 }
420 }
Daniel Veillard89cad532001-10-22 09:46:13 +0000421#ifdef LIBXML_DOCB_ENABLED
422 /*
423 * build an SGML tree from a string;
424 */
425 else if ((sgml) && (push)) {
426 FILE *f;
427
428 f = fopen(filename, "r");
429 if (f != NULL) {
430 int res, size = 3;
431 char chars[4096];
432 docbParserCtxtPtr ctxt;
433
434 /* if (repeat) */
435 size = 4096;
436 res = fread(chars, 1, 4, f);
437 if (res > 0) {
438 ctxt = docbCreatePushParserCtxt(NULL, NULL,
439 chars, res, filename, 0);
440 while ((res = fread(chars, 1, size, f)) > 0) {
441 docbParseChunk(ctxt, chars, res, 0);
442 }
443 docbParseChunk(ctxt, chars, 0, 1);
444 doc = ctxt->myDoc;
445 docbFreeParserCtxt(ctxt);
446 }
447 fclose(f);
448 }
449 } else if (sgml) {
450 doc = docbParseFile(filename, NULL);
451 }
452#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000453#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000454 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000455 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000456 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000457#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000458 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000459 /*
460 * build an XML tree from a string;
461 */
462 if (push) {
463 FILE *f;
464
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000465 /* '-' Usually means stdin -<sven@zen.org> */
466 if ((filename[0] == '-') && (filename[1] == 0)) {
467 f = stdin;
468 } else {
469 f = fopen(filename, "r");
470 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000471 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000472 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000473 int res, size = 3;
474 char chars[1024];
475 xmlParserCtxtPtr ctxt;
476
477 if (repeat)
478 size = 1024;
479 res = fread(chars, 1, 4, f);
480 if (res > 0) {
481 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
482 chars, res, filename);
483 while ((res = fread(chars, 1, size, f)) > 0) {
484 xmlParseChunk(ctxt, chars, res, 0);
485 }
486 xmlParseChunk(ctxt, chars, 0, 1);
487 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000488 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000489 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000490 if (!ret) {
491 xmlFreeDoc(doc);
492 doc = NULL;
493 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000494 }
495 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000496 } else if (testIO) {
497 int ret;
498 FILE *f;
499
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000500 /* '-' Usually means stdin -<sven@zen.org> */
501 if ((filename[0] == '-') && (filename[1] == 0)) {
502 f = stdin;
503 } else {
504 f = fopen(filename, "r");
505 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000506 if (f != NULL) {
507 xmlParserCtxtPtr ctxt;
508
509 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
510 (xmlInputReadCallback) myRead,
511 (xmlInputCloseCallback) myClose,
512 f, XML_CHAR_ENCODING_NONE);
513 xmlParseDocument(ctxt);
514
515 ret = ctxt->wellFormed;
516 doc = ctxt->myDoc;
517 xmlFreeParserCtxt(ctxt);
518 if (!ret) {
519 xmlFreeDoc(doc);
520 doc = NULL;
521 }
522 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000523 } else if (recovery) {
524 doc = xmlRecoverFile(filename);
525 } else if (htmlout) {
526 int ret;
527 xmlParserCtxtPtr ctxt;
528 xmlSAXHandler silent, *old;
529
530 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000531
532 if (ctxt == NULL) {
533 /* If xmlCreateFileParseCtxt() return NULL something
534 strange happened so we don't want to do anything. Do
535 we want to print an error message here?
536 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000537 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000538 } else {
539 memcpy(&silent, ctxt->sax, sizeof(silent));
540 old = ctxt->sax;
541 silent.error = xmlHTMLError;
542 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000543 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000544 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000545 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000546 silent.fatalError = xmlHTMLError;
547 ctxt->sax = &silent;
548 ctxt->vctxt.error = xmlHTMLValidityError;
549 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000550 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000551 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000552 ctxt->vctxt.warning = NULL;
553
Daniel Veillard88a172f2000-08-04 18:23:10 +0000554 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000555
Daniel Veillard88a172f2000-08-04 18:23:10 +0000556 ret = ctxt->wellFormed;
557 doc = ctxt->myDoc;
558 ctxt->sax = old;
559 xmlFreeParserCtxt(ctxt);
560 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000561 xmlFreeDoc(doc);
562 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000563 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000564 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000565#ifdef HAVE_SYS_MMAN_H
566 } else if (memory) {
567 int fd;
568 struct stat info;
569 const char *base;
570 if (stat(filename, &info) < 0)
571 return;
572 if ((fd = open(filename, O_RDONLY)) < 0)
573 return;
574 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000575 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000576 return;
577
578 doc = xmlParseMemory((char *) base, info.st_size);
579 munmap((char *) base, info.st_size);
580#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000581 } else
582 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000583 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000584
Daniel Veillard88a172f2000-08-04 18:23:10 +0000585 /*
586 * If we don't have a document we might as well give up. Do we
587 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000588 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000589 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000590 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000591 }
592
Daniel Veillard48b2f892001-02-25 16:11:03 +0000593 if ((timing) && (!repeat)) {
594 long msec;
595 gettimeofday(&end, NULL);
596 msec = end.tv_sec - begin.tv_sec;
597 msec *= 1000;
598 msec += (end.tv_usec - begin.tv_usec) / 1000;
599 fprintf(stderr, "Parsing took %ld ms\n", msec);
600 }
601
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000602#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000603 if (xinclude) {
604 if ((timing) && (!repeat)) {
605 gettimeofday(&begin, NULL);
606 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000607 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000608 if ((timing) && (!repeat)) {
609 long msec;
610 gettimeofday(&end, NULL);
611 msec = end.tv_sec - begin.tv_sec;
612 msec *= 1000;
613 msec += (end.tv_usec - begin.tv_usec) / 1000;
614 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
615 }
616 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000617#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000618
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000619#ifdef LIBXML_DEBUG_ENABLED
620 /*
621 * shell interraction
622 */
623 if (shell)
624 xmlShell(doc, filename, xmlShellReadline, stdout);
625#endif
626
627 /*
628 * test intermediate copy if needed.
629 */
630 if (copy) {
631 tmp = doc;
632 doc = xmlCopyDoc(doc, 1);
633 xmlFreeDoc(tmp);
634 }
635
636 if ((insert) && (!html)) {
637 const xmlChar* list[256];
638 int nb, i;
639 xmlNodePtr node;
640
641 if (doc->children != NULL) {
642 node = doc->children;
643 while ((node != NULL) && (node->last == NULL)) node = node->next;
644 if (node != NULL) {
645 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
646 if (nb < 0) {
647 printf("could not get valid list of elements\n");
648 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000649 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000650 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000651 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000652 nb);
653 for (i = 0;i < nb;i++) {
654 printf("%s\n", list[i]);
655 }
656 }
657 }
658 }
659 }else if (noout == 0) {
660 /*
661 * print it.
662 */
663#ifdef LIBXML_DEBUG_ENABLED
664 if (!debug) {
665#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000666 if ((timing) && (!repeat)) {
667 gettimeofday(&begin, NULL);
668 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000669#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000670 if (memory) {
671 xmlChar *result;
672 int len;
673
674 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +0000675 if ( format ) {
676 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
677 } else {
678 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
679 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000680 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +0000681 if (format)
682 xmlDocDumpFormatMemory(doc, &result, &len, 1);
683 else
684 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000685 }
686 if (result == NULL) {
687 fprintf(stderr, "Failed to save\n");
688 } else {
689 write(1, result, len);
690 xmlFree(result);
691 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000692 } else
693#endif /* HAVE_SYS_MMAN_H */
694 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000695 xmlSaveFile("-", doc);
Daniel Veillardd536f702001-11-08 17:32:47 +0000696 else if (encoding != NULL) {
697 if ( format ) {
698 xmlSaveFormatFileEnc("-", doc, encoding, 1);
699 }
700 else {
701 xmlSaveFileEnc("-", doc, encoding);
702 }
703 }
Daniel Veillard90493a92001-08-14 14:12:47 +0000704 else if (format)
705 xmlSaveFormatFile("-", doc, 1);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000706 else
707 xmlDocDump(stdout, doc);
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, "Saving took %ld ms\n", msec);
715 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000716#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000717 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000718 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000719 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000720#endif
721 }
722
723 /*
724 * A posteriori validation test
725 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000726 if (dtdvalid != NULL) {
727 xmlDtdPtr dtd;
728
Daniel Veillard48b2f892001-02-25 16:11:03 +0000729 if ((timing) && (!repeat)) {
730 gettimeofday(&begin, NULL);
731 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000732 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000733 if ((timing) && (!repeat)) {
734 long msec;
735 gettimeofday(&end, NULL);
736 msec = end.tv_sec - begin.tv_sec;
737 msec *= 1000;
738 msec += (end.tv_usec - begin.tv_usec) / 1000;
739 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
740 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000741 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000742 xmlGenericError(xmlGenericErrorContext,
743 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000744 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000745 } else {
746 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000747 if ((timing) && (!repeat)) {
748 gettimeofday(&begin, NULL);
749 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000750 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
751 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000752 xmlGenericError(xmlGenericErrorContext,
753 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000754 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000755 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000756 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000757 if ((timing) && (!repeat)) {
758 long msec;
759 gettimeofday(&end, NULL);
760 msec = end.tv_sec - begin.tv_sec;
761 msec *= 1000;
762 msec += (end.tv_usec - begin.tv_usec) / 1000;
763 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
764 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000765 xmlFreeDtd(dtd);
766 }
767 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000768 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000769 if ((timing) && (!repeat)) {
770 gettimeofday(&begin, NULL);
771 }
Daniel Veillardb7664f42001-08-19 13:00:43 +0000772 cvp.userData = (void *) stderr;
773 cvp.error = (xmlValidityErrorFunc) fprintf;
774 cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000775 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000776 xmlGenericError(xmlGenericErrorContext,
777 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000778 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000779 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000780 if ((timing) && (!repeat)) {
781 long msec;
782 gettimeofday(&end, NULL);
783 msec = end.tv_sec - begin.tv_sec;
784 msec *= 1000;
785 msec += (end.tv_usec - begin.tv_usec) / 1000;
786 fprintf(stderr, "Validating took %ld ms\n", msec);
787 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000788 }
789
790#ifdef LIBXML_DEBUG_ENABLED
791 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000792 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000793#endif
794
795 /*
796 * free it.
797 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000798 if ((timing) && (!repeat)) {
799 gettimeofday(&begin, NULL);
800 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000801 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000802 if ((timing) && (!repeat)) {
803 long msec;
804 gettimeofday(&end, NULL);
805 msec = end.tv_sec - begin.tv_sec;
806 msec *= 1000;
807 msec += (end.tv_usec - begin.tv_usec) / 1000;
808 fprintf(stderr, "Freeing took %ld ms\n", msec);
809 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000810}
811
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000812/************************************************************************
813 * *
814 * Usage and Main *
815 * *
816 ************************************************************************/
817
818static void usage(const char *name) {
819 printf("Usage : %s [options] XMLfiles ...\n", name);
820 printf("\tParse the XML files and output the result of the parsing\n");
821 printf("\t--version : display the version of the XML library used\n");
822#ifdef LIBXML_DEBUG_ENABLED
823 printf("\t--debug : dump a debug tree of the in-memory document\n");
824 printf("\t--shell : run a navigating shell\n");
825 printf("\t--debugent : debug the entities defined in the document\n");
826#endif
827 printf("\t--copy : used to test the internal copy implementation\n");
828 printf("\t--recover : output what was parsable on broken XML documents\n");
829 printf("\t--noent : substitute entity references by their value\n");
830 printf("\t--noout : don't output the result tree\n");
831 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +0000832 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000833 printf("\t--valid : validate the document in addition to std well-formed check\n");
834 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
835 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
836 printf("\t--timing : print some timings\n");
837 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
838 printf("\t--insert : ad-hoc test for valid insertions\n");
839 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard89cad532001-10-22 09:46:13 +0000840#ifdef LIBXML_DOCB_ENABLED
841 printf("\t--sgml : use the DocBook SGML parser\n");
842#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000843#ifdef LIBXML_HTML_ENABLED
844 printf("\t--html : use the HTML parser\n");
845#endif
846 printf("\t--push : use the push mode of the parser\n");
847#ifdef HAVE_SYS_MMAN_H
848 printf("\t--memory : parse from memory\n");
849#endif
850 printf("\t--nowarning : do not emit warnings from parser/validator\n");
851 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +0000852 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000853 printf("\t--testIO : test user I/O support\n");
854 printf("\t--encode encoding : output in the given encoding\n");
855#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +0000856 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
857 printf("\t otherwise XML Catalogs starting from \n");
858 printf("\t file:///etc/xml/catalog are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +0000859 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000860#endif
861 printf("\t--auto : generate a small doc on the fly\n");
862#ifdef LIBXML_XINCLUDE_ENABLED
863 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000864#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000865 printf("\t--loaddtd : fetch external Dtd\n");
866 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000867}
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000868int
869main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000870 int i, count;
871 int files = 0;
872
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000873 if (argc <= 1) {
874 usage(argv[0]);
875 return(1);
876 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000877 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000878 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000879 if (!strcmp(argv[i], "-"))
880 break;
881
882 if (argv[i][0] != '-')
883 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000884#ifdef LIBXML_DEBUG_ENABLED
885 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
886 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000887 else if ((!strcmp(argv[i], "-shell")) ||
888 (!strcmp(argv[i], "--shell"))) {
889 shell++;
890 noout = 1;
891 } else
892#endif
893 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
894 copy++;
895 else if ((!strcmp(argv[i], "-recover")) ||
896 (!strcmp(argv[i], "--recover")))
897 recovery++;
898 else if ((!strcmp(argv[i], "-noent")) ||
899 (!strcmp(argv[i], "--noent")))
900 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +0000901 else if ((!strcmp(argv[i], "-version")) ||
902 (!strcmp(argv[i], "--version")))
903 fprintf(stderr, "xmllint: using libxml version %s\n",
904 xmlParserVersion);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000905 else if ((!strcmp(argv[i], "-noout")) ||
906 (!strcmp(argv[i], "--noout")))
907 noout++;
908 else if ((!strcmp(argv[i], "-htmlout")) ||
909 (!strcmp(argv[i], "--htmlout")))
910 htmlout++;
Daniel Veillard89cad532001-10-22 09:46:13 +0000911#ifdef LIBXML_DOCB_ENABLED
912 else if ((!strcmp(argv[i], "-sgml")) ||
913 (!strcmp(argv[i], "--sgml"))) {
914 sgml++;
915 }
916#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000917#ifdef LIBXML_HTML_ENABLED
918 else if ((!strcmp(argv[i], "-html")) ||
919 (!strcmp(argv[i], "--html"))) {
920 html++;
921 }
922#endif /* LIBXML_HTML_ENABLED */
923 else if ((!strcmp(argv[i], "-nowrap")) ||
924 (!strcmp(argv[i], "--nowrap")))
925 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000926 else if ((!strcmp(argv[i], "-loaddtd")) ||
927 (!strcmp(argv[i], "--loaddtd")))
928 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +0000929 else if ((!strcmp(argv[i], "-dtdattr")) ||
930 (!strcmp(argv[i], "--dtdattr"))) {
931 loaddtd++;
932 dtdattrs++;
933 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000934 (!strcmp(argv[i], "--valid")))
935 valid++;
936 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000937 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000938 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000939 loaddtd++;
940 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +0000941 (!strcmp(argv[i], "--dtdvalid"))) {
942 i++;
943 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000944 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000945 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000946 else if ((!strcmp(argv[i], "-insert")) ||
947 (!strcmp(argv[i], "--insert")))
948 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000949 else if ((!strcmp(argv[i], "-timing")) ||
950 (!strcmp(argv[i], "--timing")))
951 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000952 else if ((!strcmp(argv[i], "-auto")) ||
953 (!strcmp(argv[i], "--auto")))
954 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000955 else if ((!strcmp(argv[i], "-repeat")) ||
956 (!strcmp(argv[i], "--repeat")))
957 repeat++;
958 else if ((!strcmp(argv[i], "-push")) ||
959 (!strcmp(argv[i], "--push")))
960 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000961#ifdef HAVE_SYS_MMAN_H
962 else if ((!strcmp(argv[i], "-memory")) ||
963 (!strcmp(argv[i], "--memory")))
964 memory++;
965#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000966 else if ((!strcmp(argv[i], "-testIO")) ||
967 (!strcmp(argv[i], "--testIO")))
968 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000969#ifdef LIBXML_XINCLUDE_ENABLED
970 else if ((!strcmp(argv[i], "-xinclude")) ||
971 (!strcmp(argv[i], "--xinclude")))
972 xinclude++;
973#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000974 else if ((!strcmp(argv[i], "-compress")) ||
975 (!strcmp(argv[i], "--compress"))) {
976 compress++;
977 xmlSetCompressMode(9);
978 }
979 else if ((!strcmp(argv[i], "-nowarning")) ||
980 (!strcmp(argv[i], "--nowarning"))) {
981 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000982 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000983 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000984 else if ((!strcmp(argv[i], "-pedantic")) ||
985 (!strcmp(argv[i], "--pedantic"))) {
986 xmlGetWarningsDefaultValue = 1;
987 xmlPedanticParserDefault(1);
988 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000989#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000990 else if ((!strcmp(argv[i], "-debugent")) ||
991 (!strcmp(argv[i], "--debugent"))) {
992 debugent++;
993 xmlParserDebugEntities = 1;
994 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000995#endif
Daniel Veillard81418e32001-05-22 15:08:55 +0000996#ifdef LIBXML_CATALOG_ENABLED
997 else if ((!strcmp(argv[i], "-catalogs")) ||
998 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000999 catalogs++;
1000 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1001 (!strcmp(argv[i], "--nocatalogs"))) {
1002 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001003 }
1004#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001005 else if ((!strcmp(argv[i], "-encode")) ||
1006 (!strcmp(argv[i], "--encode"))) {
1007 i++;
1008 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001009 /*
1010 * OK it's for testing purposes
1011 */
1012 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001013 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001014 else if ((!strcmp(argv[i], "-noblanks")) ||
1015 (!strcmp(argv[i], "--noblanks"))) {
1016 noblanks++;
1017 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001018 }
1019 else if ((!strcmp(argv[i], "-format")) ||
1020 (!strcmp(argv[i], "--format"))) {
1021 noblanks++;
1022 format++;
1023 xmlKeepBlanksDefault(0);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001024 } else {
1025 fprintf(stderr, "Unknown option %s\n", argv[i]);
1026 usage(argv[0]);
1027 return(1);
1028 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001029 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001030
1031#ifdef LIBXML_CATALOG_ENABLED
1032 if (nocatalogs == 0) {
1033 if (catalogs) {
1034 const char *catal;
1035
1036 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001037 if (catal != NULL) {
1038 xmlLoadCatalogs(catal);
1039 } else {
1040 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1041 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001042 }
1043 }
1044#endif
Daniel Veillardd9bad132001-07-23 19:39:43 +00001045 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001046 if (loaddtd != 0)
1047 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1048 if (dtdattrs)
1049 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001050 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1051 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1052 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001053 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001054 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001055 xmlGenericError(xmlGenericErrorContext,
1056 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1057 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001058 "<html><head><title>%s output</title></head>\n",
1059 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001060 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001061 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1062 argv[0]);
1063 }
1064 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001065 if ((!strcmp(argv[i], "-encode")) ||
1066 (!strcmp(argv[i], "--encode"))) {
1067 i++;
1068 continue;
1069 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001070 if ((!strcmp(argv[i], "-dtdvalid")) ||
1071 (!strcmp(argv[i], "--dtdvalid"))) {
1072 i++;
1073 continue;
1074 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001075 if ((timing) && (repeat))
1076 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001077 /* Remember file names. "-" means stding. <sven@zen.org> */
1078 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001079 if (repeat) {
1080 for (count = 0;count < 100 * repeat;count++)
1081 parseAndPrintFile(argv[i]);
1082 } else
1083 parseAndPrintFile(argv[i]);
1084 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001085 if ((timing) && (repeat)) {
1086 long msec;
1087 gettimeofday(&end, NULL);
1088 msec = end.tv_sec - begin.tv_sec;
1089 msec *= 1000;
1090 msec += (end.tv_usec - begin.tv_usec) / 1000;
1091 fprintf(stderr, "100 iterations took %ld ms\n", msec);
1092 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001093 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001094 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001095 if (generate)
1096 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001097 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001098 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001099 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001100 if ((files == 0) && (!generate)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001101 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001102 }
1103 xmlCleanupParser();
1104 xmlMemoryDump();
1105
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001106 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001107}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001108