blob: eaab6ddba1983bfef3e7e168826e16ab6983d139 [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 *
6 * Daniel.Veillard@w3.org
7 */
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 Veillard2d90de42001-04-16 17:46:18 +000013#ifdef _WIN32
14#ifdef _MSC_VER
15#include <winsock2.h>
16#pragma comment(lib, "ws2_32.lib")
17#define gettimeofday(p1,p2)
18#endif /* _MSC_VER */
19#else /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000020#include <sys/time.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000021#endif /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000022
Daniel Veillardce8b83b2000-04-05 18:38:42 +000023
24#ifdef HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27#ifdef HAVE_SYS_STAT_H
28#include <sys/stat.h>
29#endif
30#ifdef HAVE_FCNTL_H
31#include <fcntl.h>
32#endif
33#ifdef HAVE_UNISTD_H
34#include <unistd.h>
35#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000036#ifdef HAVE_SYS_MMAN_H
37#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000038/* seems needed for Solaris */
39#ifndef MAP_FAILED
40#define MAP_FAILED ((void *) -1)
41#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000042#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000043#ifdef HAVE_STDLIB_H
44#include <stdlib.h>
45#endif
46#ifdef HAVE_LIBREADLINE
47#include <readline/readline.h>
48#ifdef HAVE_LIBHISTORY
49#include <readline/history.h>
50#endif
51#endif
52
53#include <libxml/xmlmemory.h>
54#include <libxml/parser.h>
55#include <libxml/parserInternals.h>
56#include <libxml/HTMLparser.h>
57#include <libxml/HTMLtree.h>
58#include <libxml/tree.h>
59#include <libxml/xpath.h>
60#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000061#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000062#ifdef LIBXML_XINCLUDE_ENABLED
63#include <libxml/xinclude.h>
64#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000065
66#ifdef LIBXML_DEBUG_ENABLED
67static int debug = 0;
68static int shell = 0;
69static int debugent = 0;
70#endif
71static int copy = 0;
72static int recovery = 0;
73static int noent = 0;
74static int noout = 0;
75static int nowrap = 0;
76static int valid = 0;
77static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +000078static char * dtdvalid = NULL;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000079static int repeat = 0;
80static int insert = 0;
81static int compress = 0;
82static int html = 0;
83static int htmlout = 0;
84static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +000085#ifdef HAVE_SYS_MMAN_H
86static int memory = 0;
87#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000088static int noblanks = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000089static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000090static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000091#ifdef LIBXML_XINCLUDE_ENABLED
92static int xinclude = 0;
93#endif
Daniel Veillardf7cd4812001-02-23 18:44:52 +000094static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +000095static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +000096static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +000097static struct timeval begin, end;
Daniel Veillardce8b83b2000-04-05 18:38:42 +000098
Daniel Veillardce6e98d2000-11-25 09:54:49 +000099
100#ifdef VMS
101extern int xmlDoValidityCheckingDefaultVal;
102#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
103#else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000104extern int xmlDoValidityCheckingDefaultValue;
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000105#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000106extern int xmlGetWarningsDefaultValue;
107
108/************************************************************************
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 {
634 xmlDocDumpMemory(doc, &result, &len);
635 }
636 if (result == NULL) {
637 fprintf(stderr, "Failed to save\n");
638 } else {
639 write(1, result, len);
640 xmlFree(result);
641 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000642 } else
643#endif /* HAVE_SYS_MMAN_H */
644 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000646 else if (encoding != NULL)
647 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000648 else
649 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000650 if ((timing) && (!repeat)) {
651 long msec;
652 gettimeofday(&end, NULL);
653 msec = end.tv_sec - begin.tv_sec;
654 msec *= 1000;
655 msec += (end.tv_usec - begin.tv_usec) / 1000;
656 fprintf(stderr, "Saving took %ld ms\n", msec);
657 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000658#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000659 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000660 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000661 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000662#endif
663 }
664
665 /*
666 * A posteriori validation test
667 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000668 if (dtdvalid != NULL) {
669 xmlDtdPtr dtd;
670
Daniel Veillard48b2f892001-02-25 16:11:03 +0000671 if ((timing) && (!repeat)) {
672 gettimeofday(&begin, NULL);
673 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000674 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000675 if ((timing) && (!repeat)) {
676 long msec;
677 gettimeofday(&end, NULL);
678 msec = end.tv_sec - begin.tv_sec;
679 msec *= 1000;
680 msec += (end.tv_usec - begin.tv_usec) / 1000;
681 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
682 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000683 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000684 xmlGenericError(xmlGenericErrorContext,
685 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000686 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000687 } else {
688 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000689 if ((timing) && (!repeat)) {
690 gettimeofday(&begin, NULL);
691 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000692 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
693 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000694 xmlGenericError(xmlGenericErrorContext,
695 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000696 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000697 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000698 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000699 if ((timing) && (!repeat)) {
700 long msec;
701 gettimeofday(&end, NULL);
702 msec = end.tv_sec - begin.tv_sec;
703 msec *= 1000;
704 msec += (end.tv_usec - begin.tv_usec) / 1000;
705 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
706 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000707 xmlFreeDtd(dtd);
708 }
709 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000710 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000711 if ((timing) && (!repeat)) {
712 gettimeofday(&begin, NULL);
713 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000714 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000715 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000716 xmlGenericError(xmlGenericErrorContext,
717 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000718 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000719 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000720 if ((timing) && (!repeat)) {
721 long msec;
722 gettimeofday(&end, NULL);
723 msec = end.tv_sec - begin.tv_sec;
724 msec *= 1000;
725 msec += (end.tv_usec - begin.tv_usec) / 1000;
726 fprintf(stderr, "Validating took %ld ms\n", msec);
727 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000728 }
729
730#ifdef LIBXML_DEBUG_ENABLED
731 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000732 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000733#endif
734
735 /*
736 * free it.
737 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000738 if ((timing) && (!repeat)) {
739 gettimeofday(&begin, NULL);
740 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000741 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000742 if ((timing) && (!repeat)) {
743 long msec;
744 gettimeofday(&end, NULL);
745 msec = end.tv_sec - begin.tv_sec;
746 msec *= 1000;
747 msec += (end.tv_usec - begin.tv_usec) / 1000;
748 fprintf(stderr, "Freeing took %ld ms\n", msec);
749 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000750}
751
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000752int
753main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000754 int i, count;
755 int files = 0;
756
Daniel Veillardbe803962000-06-28 23:40:59 +0000757 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000758 for (i = 1; i < argc ; i++) {
759#ifdef LIBXML_DEBUG_ENABLED
760 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
761 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000762 else if ((!strcmp(argv[i], "-shell")) ||
763 (!strcmp(argv[i], "--shell"))) {
764 shell++;
765 noout = 1;
766 } else
767#endif
768 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
769 copy++;
770 else if ((!strcmp(argv[i], "-recover")) ||
771 (!strcmp(argv[i], "--recover")))
772 recovery++;
773 else if ((!strcmp(argv[i], "-noent")) ||
774 (!strcmp(argv[i], "--noent")))
775 noent++;
776 else if ((!strcmp(argv[i], "-noout")) ||
777 (!strcmp(argv[i], "--noout")))
778 noout++;
779 else if ((!strcmp(argv[i], "-htmlout")) ||
780 (!strcmp(argv[i], "--htmlout")))
781 htmlout++;
782#ifdef LIBXML_HTML_ENABLED
783 else if ((!strcmp(argv[i], "-html")) ||
784 (!strcmp(argv[i], "--html"))) {
785 html++;
786 }
787#endif /* LIBXML_HTML_ENABLED */
788 else if ((!strcmp(argv[i], "-nowrap")) ||
789 (!strcmp(argv[i], "--nowrap")))
790 nowrap++;
791 else if ((!strcmp(argv[i], "-valid")) ||
792 (!strcmp(argv[i], "--valid")))
793 valid++;
794 else if ((!strcmp(argv[i], "-postvalid")) ||
795 (!strcmp(argv[i], "--postvalid")))
796 postvalid++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000797 else if ((!strcmp(argv[i], "-dtdvalid")) ||
798 (!strcmp(argv[i], "--dtdvalid"))) {
799 i++;
800 dtdvalid = argv[i];
801 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000802 else if ((!strcmp(argv[i], "-insert")) ||
803 (!strcmp(argv[i], "--insert")))
804 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000805 else if ((!strcmp(argv[i], "-timing")) ||
806 (!strcmp(argv[i], "--timing")))
807 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000808 else if ((!strcmp(argv[i], "-auto")) ||
809 (!strcmp(argv[i], "--auto")))
810 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000811 else if ((!strcmp(argv[i], "-repeat")) ||
812 (!strcmp(argv[i], "--repeat")))
813 repeat++;
814 else if ((!strcmp(argv[i], "-push")) ||
815 (!strcmp(argv[i], "--push")))
816 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000817#ifdef HAVE_SYS_MMAN_H
818 else if ((!strcmp(argv[i], "-memory")) ||
819 (!strcmp(argv[i], "--memory")))
820 memory++;
821#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000822 else if ((!strcmp(argv[i], "-testIO")) ||
823 (!strcmp(argv[i], "--testIO")))
824 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000825#ifdef LIBXML_XINCLUDE_ENABLED
826 else if ((!strcmp(argv[i], "-xinclude")) ||
827 (!strcmp(argv[i], "--xinclude")))
828 xinclude++;
829#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000830 else if ((!strcmp(argv[i], "-compress")) ||
831 (!strcmp(argv[i], "--compress"))) {
832 compress++;
833 xmlSetCompressMode(9);
834 }
835 else if ((!strcmp(argv[i], "-nowarning")) ||
836 (!strcmp(argv[i], "--nowarning"))) {
837 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000838 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000839 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000840 else if ((!strcmp(argv[i], "-pedantic")) ||
841 (!strcmp(argv[i], "--pedantic"))) {
842 xmlGetWarningsDefaultValue = 1;
843 xmlPedanticParserDefault(1);
844 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000845#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000846 else if ((!strcmp(argv[i], "-debugent")) ||
847 (!strcmp(argv[i], "--debugent"))) {
848 debugent++;
849 xmlParserDebugEntities = 1;
850 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000851#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000852 else if ((!strcmp(argv[i], "-encode")) ||
853 (!strcmp(argv[i], "--encode"))) {
854 i++;
855 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000856 /*
857 * OK it's for testing purposes
858 */
859 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000860 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000861 else if ((!strcmp(argv[i], "-noblanks")) ||
862 (!strcmp(argv[i], "--noblanks"))) {
863 noblanks++;
864 xmlKeepBlanksDefault(0);
865 }
866 }
867 if (noent != 0) xmlSubstituteEntitiesDefault(1);
868 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
869 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000870 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000871 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000872 xmlGenericError(xmlGenericErrorContext,
873 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
874 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000875 "<html><head><title>%s output</title></head>\n",
876 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000877 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000878 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
879 argv[0]);
880 }
881 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000882 if ((!strcmp(argv[i], "-encode")) ||
883 (!strcmp(argv[i], "--encode"))) {
884 i++;
885 continue;
886 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000887 if ((!strcmp(argv[i], "-dtdvalid")) ||
888 (!strcmp(argv[i], "--dtdvalid"))) {
889 i++;
890 continue;
891 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000892 if ((timing) && (repeat))
893 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000894 /* Remember file names. "-" means stding. <sven@zen.org> */
895 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000896 if (repeat) {
897 for (count = 0;count < 100 * repeat;count++)
898 parseAndPrintFile(argv[i]);
899 } else
900 parseAndPrintFile(argv[i]);
901 files ++;
902 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000903 if ((timing) && (repeat)) {
904 long msec;
905 gettimeofday(&end, NULL);
906 msec = end.tv_sec - begin.tv_sec;
907 msec *= 1000;
908 msec += (end.tv_usec - begin.tv_usec) / 1000;
909 fprintf(stderr, "100 iteration took %ld ms\n", msec);
910 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000911 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000912 if (generate)
913 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000914 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000915 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000916 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000917 if ((files == 0) && (!generate)) {
Daniel Veillard48b2f892001-02-25 16:11:03 +0000918 printf("Usage : %s [options] XMLfiles ...\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000919 argv[0]);
920 printf("\tParse the XML files and output the result of the parsing\n");
921#ifdef LIBXML_DEBUG_ENABLED
922 printf("\t--debug : dump a debug tree of the in-memory document\n");
923 printf("\t--shell : run a navigating shell\n");
924 printf("\t--debugent : debug the entities defined in the document\n");
925#endif
926 printf("\t--copy : used to test the internal copy implementation\n");
927 printf("\t--recover : output what was parsable on broken XML documents\n");
928 printf("\t--noent : substitute entity references by their value\n");
929 printf("\t--noout : don't output the result tree\n");
930 printf("\t--htmlout : output results as HTML\n");
931 printf("\t--nowarp : do not put HTML doc wrapper\n");
932 printf("\t--valid : validate the document in addition to std well-formed check\n");
933 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
Daniel Veillardcd429612000-10-11 15:57:05 +0000934 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000935 printf("\t--timing : print some timings\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000936 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
937 printf("\t--insert : ad-hoc test for valid insertions\n");
938 printf("\t--compress : turn on gzip compression of output\n");
939#ifdef LIBXML_HTML_ENABLED
940 printf("\t--html : use the HTML parser\n");
941#endif
942 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard46e370e2000-07-21 20:32:03 +0000943#ifdef HAVE_SYS_MMAN_H
944 printf("\t--memory : parse from memory\n");
945#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000946 printf("\t--nowarning : do not emit warnings from parser/validator\n");
947 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard5e873c42000-04-12 13:27:38 +0000948 printf("\t--testIO : test user I/O support\n");
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000949 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000950 printf("\t--auto : generate a small doc on the fly\n");
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000951#ifdef LIBXML_XINCLUDE_ENABLED
952 printf("\t--xinclude : do XInclude processing\n");
953#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000954 }
955 xmlCleanupParser();
956 xmlMemoryDump();
957
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000958 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000959}
Daniel Veillard88a172f2000-08-04 18:23:10 +0000960