blob: 82f09ef212d892db2415951dfc30a06f8228b9e3 [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
9#ifdef WIN32
10#include "win32config.h"
11#else
12#include "config.h"
13#endif
14
15#include <stdio.h>
16#include <string.h>
17#include <stdio.h>
18#include <stdarg.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000019#ifdef _WIN32
20#ifdef _MSC_VER
21#include <winsock2.h>
22#pragma comment(lib, "ws2_32.lib")
23#define gettimeofday(p1,p2)
24#endif /* _MSC_VER */
25#else /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000026#include <sys/time.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000027#endif /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000028
Daniel Veillardce8b83b2000-04-05 18:38:42 +000029
30#ifdef HAVE_SYS_TYPES_H
31#include <sys/types.h>
32#endif
33#ifdef HAVE_SYS_STAT_H
34#include <sys/stat.h>
35#endif
36#ifdef HAVE_FCNTL_H
37#include <fcntl.h>
38#endif
39#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000042#ifdef HAVE_SYS_MMAN_H
43#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000044/* seems needed for Solaris */
45#ifndef MAP_FAILED
46#define MAP_FAILED ((void *) -1)
47#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000048#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000049#ifdef HAVE_STDLIB_H
50#include <stdlib.h>
51#endif
52#ifdef HAVE_LIBREADLINE
53#include <readline/readline.h>
54#ifdef HAVE_LIBHISTORY
55#include <readline/history.h>
56#endif
57#endif
58
59#include <libxml/xmlmemory.h>
60#include <libxml/parser.h>
61#include <libxml/parserInternals.h>
62#include <libxml/HTMLparser.h>
63#include <libxml/HTMLtree.h>
64#include <libxml/tree.h>
65#include <libxml/xpath.h>
66#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000067#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000068#ifdef LIBXML_XINCLUDE_ENABLED
69#include <libxml/xinclude.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 Veillard5e873c42000-04-12 13:27:38 +000095static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +000096static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000097#ifdef LIBXML_XINCLUDE_ENABLED
98static int xinclude = 0;
99#endif
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000100static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000101static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000102static int generate = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000103static struct timeval begin, end;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000104
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000105
106#ifdef VMS
107extern int xmlDoValidityCheckingDefaultVal;
108#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
109#else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000110extern int xmlDoValidityCheckingDefaultValue;
Daniel Veillardce6e98d2000-11-25 09:54:49 +0000111#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000112extern int xmlGetWarningsDefaultValue;
113
114/************************************************************************
115 * *
116 * HTML ouput *
117 * *
118 ************************************************************************/
119char buffer[50000];
120
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000121static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000122xmlHTMLEncodeSend(void) {
123 char *result;
124
125 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
126 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000127 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000128 xmlFree(result);
129 }
130 buffer[0] = 0;
131}
132
133/**
134 * xmlHTMLPrintFileInfo:
135 * @input: an xmlParserInputPtr input
136 *
137 * Displays the associated file and line informations for the current input
138 */
139
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000140static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000141xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000142 xmlGenericError(xmlGenericErrorContext, "<p>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000143 if (input != NULL) {
144 if (input->filename) {
145 sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
146 input->line);
147 } else {
148 sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
149 }
150 }
151 xmlHTMLEncodeSend();
152}
153
154/**
155 * xmlHTMLPrintFileContext:
156 * @input: an xmlParserInputPtr input
157 *
158 * Displays current context within the input content for error tracking
159 */
160
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000161static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000162xmlHTMLPrintFileContext(xmlParserInputPtr input) {
163 const xmlChar *cur, *base;
164 int n;
165
166 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000167 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000168 cur = input->cur;
169 base = input->base;
170 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
171 cur--;
172 }
173 n = 0;
174 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
175 cur--;
176 if ((*cur == '\n') || (*cur == '\r')) cur++;
177 base = cur;
178 n = 0;
179 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
180 sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
181 n++;
182 }
183 sprintf(&buffer[strlen(buffer)], "\n");
184 cur = input->cur;
185 while ((*cur == '\n') || (*cur == '\r'))
186 cur--;
187 n = 0;
188 while ((cur != base) && (n++ < 80)) {
189 sprintf(&buffer[strlen(buffer)], " ");
190 base++;
191 }
192 sprintf(&buffer[strlen(buffer)],"^\n");
193 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000194 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000195}
196
197/**
198 * xmlHTMLError:
199 * @ctx: an XML parser context
200 * @msg: the message to display/transmit
201 * @...: extra parameters for the message display
202 *
203 * Display and format an error messages, gives file, line, position and
204 * extra parameters.
205 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000206static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000207xmlHTMLError(void *ctx, const char *msg, ...)
208{
209 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
210 xmlParserInputPtr input;
211 xmlParserInputPtr cur = NULL;
212 va_list args;
213
214 buffer[0] = 0;
215 input = ctxt->input;
216 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
217 cur = input;
218 input = ctxt->inputTab[ctxt->inputNr - 2];
219 }
220
221 xmlHTMLPrintFileInfo(input);
222
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000223 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000224 va_start(args, msg);
225 vsprintf(&buffer[strlen(buffer)], msg, args);
226 va_end(args);
227 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000228 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000229
230 xmlHTMLPrintFileContext(input);
231 xmlHTMLEncodeSend();
232}
233
234/**
235 * xmlHTMLWarning:
236 * @ctx: an XML parser context
237 * @msg: the message to display/transmit
238 * @...: extra parameters for the message display
239 *
240 * Display and format a warning messages, gives file, line, position and
241 * extra parameters.
242 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000243static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000244xmlHTMLWarning(void *ctx, const char *msg, ...)
245{
246 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
247 xmlParserInputPtr input;
248 xmlParserInputPtr cur = NULL;
249 va_list args;
250
251 buffer[0] = 0;
252 input = ctxt->input;
253 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
254 cur = input;
255 input = ctxt->inputTab[ctxt->inputNr - 2];
256 }
257
258
259 xmlHTMLPrintFileInfo(input);
260
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000261 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000262 va_start(args, msg);
263 vsprintf(&buffer[strlen(buffer)], msg, args);
264 va_end(args);
265 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000266 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000267
268 xmlHTMLPrintFileContext(input);
269 xmlHTMLEncodeSend();
270}
271
272/**
273 * xmlHTMLValidityError:
274 * @ctx: an XML parser context
275 * @msg: the message to display/transmit
276 * @...: extra parameters for the message display
277 *
278 * Display and format an validity error messages, gives file,
279 * line, position and extra parameters.
280 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000281static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000282xmlHTMLValidityError(void *ctx, const char *msg, ...)
283{
284 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
285 xmlParserInputPtr input;
286 va_list args;
287
288 buffer[0] = 0;
289 input = ctxt->input;
290 if ((input->filename == NULL) && (ctxt->inputNr > 1))
291 input = ctxt->inputTab[ctxt->inputNr - 2];
292
293 xmlHTMLPrintFileInfo(input);
294
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000295 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000296 va_start(args, msg);
297 vsprintf(&buffer[strlen(buffer)], msg, args);
298 va_end(args);
299 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000300 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000301
302 xmlHTMLPrintFileContext(input);
303 xmlHTMLEncodeSend();
304}
305
306/**
307 * xmlHTMLValidityWarning:
308 * @ctx: an XML parser context
309 * @msg: the message to display/transmit
310 * @...: extra parameters for the message display
311 *
312 * Display and format a validity warning messages, gives file, line,
313 * position and extra parameters.
314 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000315static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000316xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
317{
318 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
319 xmlParserInputPtr input;
320 va_list args;
321
322 buffer[0] = 0;
323 input = ctxt->input;
324 if ((input->filename == NULL) && (ctxt->inputNr > 1))
325 input = ctxt->inputTab[ctxt->inputNr - 2];
326
327 xmlHTMLPrintFileInfo(input);
328
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000329 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000330 va_start(args, msg);
331 vsprintf(&buffer[strlen(buffer)], msg, args);
332 va_end(args);
333 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000334 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000335
336 xmlHTMLPrintFileContext(input);
337 xmlHTMLEncodeSend();
338}
339
340/************************************************************************
341 * *
342 * Shell Interface *
343 * *
344 ************************************************************************/
345/**
346 * xmlShellReadline:
347 * @prompt: the prompt value
348 *
349 * Read a string
350 *
351 * Returns a pointer to it or NULL on EOF the caller is expected to
352 * free the returned string.
353 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000354static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000355xmlShellReadline(char *prompt) {
356#ifdef HAVE_LIBREADLINE
357 char *line_read;
358
359 /* Get a line from the user. */
360 line_read = readline (prompt);
361
362 /* If the line has any text in it, save it on the history. */
363 if (line_read && *line_read)
364 add_history (line_read);
365
366 return (line_read);
367#else
368 char line_read[501];
369
370 if (prompt != NULL)
371 fprintf(stdout, "%s", prompt);
372 if (!fgets(line_read, 500, stdin))
373 return(NULL);
374 line_read[500] = 0;
375 return(strdup(line_read));
376#endif
377}
378
379/************************************************************************
380 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000381 * I/O Interfaces *
382 * *
383 ************************************************************************/
384
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000385static int myRead(FILE *f, char * buf, int len) {
386 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000387}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000388static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000389 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000390 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000391 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000392}
393
394/************************************************************************
395 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000396 * Test processing *
397 * *
398 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000399static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000400 xmlDocPtr doc = NULL, tmp;
401
Daniel Veillard48b2f892001-02-25 16:11:03 +0000402 if ((timing) && (!repeat))
403 gettimeofday(&begin, NULL);
404
405
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000406 if (filename == NULL) {
407 if (generate) {
408 xmlNodePtr n;
409
410 doc = xmlNewDoc(BAD_CAST "1.0");
411 n = xmlNewNode(NULL, BAD_CAST "info");
412 xmlNodeSetContent(n, BAD_CAST "abc");
413 xmlDocSetRootElement(doc, n);
414 }
415 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000416#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000417 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000418 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000419 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000420#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000421 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000422 /*
423 * build an XML tree from a string;
424 */
425 if (push) {
426 FILE *f;
427
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000428 /* '-' Usually means stdin -<sven@zen.org> */
429 if ((filename[0] == '-') && (filename[1] == 0)) {
430 f = stdin;
431 } else {
432 f = fopen(filename, "r");
433 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000434 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000435 int ret;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000436 int res, size = 3;
437 char chars[1024];
438 xmlParserCtxtPtr ctxt;
439
440 if (repeat)
441 size = 1024;
442 res = fread(chars, 1, 4, f);
443 if (res > 0) {
444 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
445 chars, res, filename);
446 while ((res = fread(chars, 1, size, f)) > 0) {
447 xmlParseChunk(ctxt, chars, res, 0);
448 }
449 xmlParseChunk(ctxt, chars, 0, 1);
450 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000451 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000452 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000453 if (!ret) {
454 xmlFreeDoc(doc);
455 doc = NULL;
456 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000457 }
458 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000459 } else if (testIO) {
460 int ret;
461 FILE *f;
462
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000463 /* '-' Usually means stdin -<sven@zen.org> */
464 if ((filename[0] == '-') && (filename[1] == 0)) {
465 f = stdin;
466 } else {
467 f = fopen(filename, "r");
468 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000469 if (f != NULL) {
470 xmlParserCtxtPtr ctxt;
471
472 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
473 (xmlInputReadCallback) myRead,
474 (xmlInputCloseCallback) myClose,
475 f, XML_CHAR_ENCODING_NONE);
476 xmlParseDocument(ctxt);
477
478 ret = ctxt->wellFormed;
479 doc = ctxt->myDoc;
480 xmlFreeParserCtxt(ctxt);
481 if (!ret) {
482 xmlFreeDoc(doc);
483 doc = NULL;
484 }
485 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000486 } else if (recovery) {
487 doc = xmlRecoverFile(filename);
488 } else if (htmlout) {
489 int ret;
490 xmlParserCtxtPtr ctxt;
491 xmlSAXHandler silent, *old;
492
493 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000494
495 if (ctxt == NULL) {
496 /* If xmlCreateFileParseCtxt() return NULL something
497 strange happened so we don't want to do anything. Do
498 we want to print an error message here?
499 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000500 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000501 } else {
502 memcpy(&silent, ctxt->sax, sizeof(silent));
503 old = ctxt->sax;
504 silent.error = xmlHTMLError;
505 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000506 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000507 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000508 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000509 silent.fatalError = xmlHTMLError;
510 ctxt->sax = &silent;
511 ctxt->vctxt.error = xmlHTMLValidityError;
512 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000513 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000514 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000515 ctxt->vctxt.warning = NULL;
516
Daniel Veillard88a172f2000-08-04 18:23:10 +0000517 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000518
Daniel Veillard88a172f2000-08-04 18:23:10 +0000519 ret = ctxt->wellFormed;
520 doc = ctxt->myDoc;
521 ctxt->sax = old;
522 xmlFreeParserCtxt(ctxt);
523 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000524 xmlFreeDoc(doc);
525 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000526 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000527 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000528#ifdef HAVE_SYS_MMAN_H
529 } else if (memory) {
530 int fd;
531 struct stat info;
532 const char *base;
533 if (stat(filename, &info) < 0)
534 return;
535 if ((fd = open(filename, O_RDONLY)) < 0)
536 return;
537 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000538 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000539 return;
540
541 doc = xmlParseMemory((char *) base, info.st_size);
542 munmap((char *) base, info.st_size);
543#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000544 } else
545 doc = xmlParseFile(filename);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000546 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000547
Daniel Veillard88a172f2000-08-04 18:23:10 +0000548 /*
549 * If we don't have a document we might as well give up. Do we
550 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000551 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000552 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000553 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000554 }
555
Daniel Veillard48b2f892001-02-25 16:11:03 +0000556 if ((timing) && (!repeat)) {
557 long msec;
558 gettimeofday(&end, NULL);
559 msec = end.tv_sec - begin.tv_sec;
560 msec *= 1000;
561 msec += (end.tv_usec - begin.tv_usec) / 1000;
562 fprintf(stderr, "Parsing took %ld ms\n", msec);
563 }
564
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000565#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000566 if (xinclude) {
567 if ((timing) && (!repeat)) {
568 gettimeofday(&begin, NULL);
569 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000570 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000571 if ((timing) && (!repeat)) {
572 long msec;
573 gettimeofday(&end, NULL);
574 msec = end.tv_sec - begin.tv_sec;
575 msec *= 1000;
576 msec += (end.tv_usec - begin.tv_usec) / 1000;
577 fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
578 }
579 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000580#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000581
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000582#ifdef LIBXML_DEBUG_ENABLED
583 /*
584 * shell interraction
585 */
586 if (shell)
587 xmlShell(doc, filename, xmlShellReadline, stdout);
588#endif
589
590 /*
591 * test intermediate copy if needed.
592 */
593 if (copy) {
594 tmp = doc;
595 doc = xmlCopyDoc(doc, 1);
596 xmlFreeDoc(tmp);
597 }
598
599 if ((insert) && (!html)) {
600 const xmlChar* list[256];
601 int nb, i;
602 xmlNodePtr node;
603
604 if (doc->children != NULL) {
605 node = doc->children;
606 while ((node != NULL) && (node->last == NULL)) node = node->next;
607 if (node != NULL) {
608 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
609 if (nb < 0) {
610 printf("could not get valid list of elements\n");
611 } else if (nb == 0) {
612 printf("No element can be indersted under root\n");
613 } else {
614 printf("%d element types can be indersted under root:\n",
615 nb);
616 for (i = 0;i < nb;i++) {
617 printf("%s\n", list[i]);
618 }
619 }
620 }
621 }
622 }else if (noout == 0) {
623 /*
624 * print it.
625 */
626#ifdef LIBXML_DEBUG_ENABLED
627 if (!debug) {
628#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000629 if ((timing) && (!repeat)) {
630 gettimeofday(&begin, NULL);
631 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000632#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000633 if (memory) {
634 xmlChar *result;
635 int len;
636
637 if (encoding != NULL) {
638 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
639 } else {
640 xmlDocDumpMemory(doc, &result, &len);
641 }
642 if (result == NULL) {
643 fprintf(stderr, "Failed to save\n");
644 } else {
645 write(1, result, len);
646 xmlFree(result);
647 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000648 } else
649#endif /* HAVE_SYS_MMAN_H */
650 if (compress)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000651 xmlSaveFile("-", doc);
Daniel Veillardbe803962000-06-28 23:40:59 +0000652 else if (encoding != NULL)
653 xmlSaveFileEnc("-", doc, encoding);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000654 else
655 xmlDocDump(stdout, doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000656 if ((timing) && (!repeat)) {
657 long msec;
658 gettimeofday(&end, NULL);
659 msec = end.tv_sec - begin.tv_sec;
660 msec *= 1000;
661 msec += (end.tv_usec - begin.tv_usec) / 1000;
662 fprintf(stderr, "Saving took %ld ms\n", msec);
663 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000664#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000665 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000666 xmlDebugDumpDocument(stdout, doc);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000667 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000668#endif
669 }
670
671 /*
672 * A posteriori validation test
673 */
Daniel Veillardcd429612000-10-11 15:57:05 +0000674 if (dtdvalid != NULL) {
675 xmlDtdPtr dtd;
676
Daniel Veillard48b2f892001-02-25 16:11:03 +0000677 if ((timing) && (!repeat)) {
678 gettimeofday(&begin, NULL);
679 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000680 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000681 if ((timing) && (!repeat)) {
682 long msec;
683 gettimeofday(&end, NULL);
684 msec = end.tv_sec - begin.tv_sec;
685 msec *= 1000;
686 msec += (end.tv_usec - begin.tv_usec) / 1000;
687 fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
688 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000689 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000690 xmlGenericError(xmlGenericErrorContext,
691 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000692 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +0000693 } else {
694 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000695 if ((timing) && (!repeat)) {
696 gettimeofday(&begin, NULL);
697 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000698 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
699 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000700 xmlGenericError(xmlGenericErrorContext,
701 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +0000702 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000703 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000704 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000705 if ((timing) && (!repeat)) {
706 long msec;
707 gettimeofday(&end, NULL);
708 msec = end.tv_sec - begin.tv_sec;
709 msec *= 1000;
710 msec += (end.tv_usec - begin.tv_usec) / 1000;
711 fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
712 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000713 xmlFreeDtd(dtd);
714 }
715 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000716 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000717 if ((timing) && (!repeat)) {
718 gettimeofday(&begin, NULL);
719 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000720 cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +0000721 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000722 xmlGenericError(xmlGenericErrorContext,
723 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000724 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +0000725 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000726 if ((timing) && (!repeat)) {
727 long msec;
728 gettimeofday(&end, NULL);
729 msec = end.tv_sec - begin.tv_sec;
730 msec *= 1000;
731 msec += (end.tv_usec - begin.tv_usec) / 1000;
732 fprintf(stderr, "Validating took %ld ms\n", msec);
733 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000734 }
735
736#ifdef LIBXML_DEBUG_ENABLED
737 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000738 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000739#endif
740
741 /*
742 * free it.
743 */
Daniel Veillard48b2f892001-02-25 16:11:03 +0000744 if ((timing) && (!repeat)) {
745 gettimeofday(&begin, NULL);
746 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000747 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000748 if ((timing) && (!repeat)) {
749 long msec;
750 gettimeofday(&end, NULL);
751 msec = end.tv_sec - begin.tv_sec;
752 msec *= 1000;
753 msec += (end.tv_usec - begin.tv_usec) / 1000;
754 fprintf(stderr, "Freeing took %ld ms\n", msec);
755 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000756}
757
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000758int
759main(int argc, char **argv) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000760 int i, count;
761 int files = 0;
762
Daniel Veillardbe803962000-06-28 23:40:59 +0000763 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000764 for (i = 1; i < argc ; i++) {
765#ifdef LIBXML_DEBUG_ENABLED
766 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
767 debug++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000768 else if ((!strcmp(argv[i], "-shell")) ||
769 (!strcmp(argv[i], "--shell"))) {
770 shell++;
771 noout = 1;
772 } else
773#endif
774 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
775 copy++;
776 else if ((!strcmp(argv[i], "-recover")) ||
777 (!strcmp(argv[i], "--recover")))
778 recovery++;
779 else if ((!strcmp(argv[i], "-noent")) ||
780 (!strcmp(argv[i], "--noent")))
781 noent++;
782 else if ((!strcmp(argv[i], "-noout")) ||
783 (!strcmp(argv[i], "--noout")))
784 noout++;
785 else if ((!strcmp(argv[i], "-htmlout")) ||
786 (!strcmp(argv[i], "--htmlout")))
787 htmlout++;
788#ifdef LIBXML_HTML_ENABLED
789 else if ((!strcmp(argv[i], "-html")) ||
790 (!strcmp(argv[i], "--html"))) {
791 html++;
792 }
793#endif /* LIBXML_HTML_ENABLED */
794 else if ((!strcmp(argv[i], "-nowrap")) ||
795 (!strcmp(argv[i], "--nowrap")))
796 nowrap++;
797 else if ((!strcmp(argv[i], "-valid")) ||
798 (!strcmp(argv[i], "--valid")))
799 valid++;
800 else if ((!strcmp(argv[i], "-postvalid")) ||
801 (!strcmp(argv[i], "--postvalid")))
802 postvalid++;
Daniel Veillardcd429612000-10-11 15:57:05 +0000803 else if ((!strcmp(argv[i], "-dtdvalid")) ||
804 (!strcmp(argv[i], "--dtdvalid"))) {
805 i++;
806 dtdvalid = argv[i];
807 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000808 else if ((!strcmp(argv[i], "-insert")) ||
809 (!strcmp(argv[i], "--insert")))
810 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000811 else if ((!strcmp(argv[i], "-timing")) ||
812 (!strcmp(argv[i], "--timing")))
813 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000814 else if ((!strcmp(argv[i], "-auto")) ||
815 (!strcmp(argv[i], "--auto")))
816 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000817 else if ((!strcmp(argv[i], "-repeat")) ||
818 (!strcmp(argv[i], "--repeat")))
819 repeat++;
820 else if ((!strcmp(argv[i], "-push")) ||
821 (!strcmp(argv[i], "--push")))
822 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000823#ifdef HAVE_SYS_MMAN_H
824 else if ((!strcmp(argv[i], "-memory")) ||
825 (!strcmp(argv[i], "--memory")))
826 memory++;
827#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000828 else if ((!strcmp(argv[i], "-testIO")) ||
829 (!strcmp(argv[i], "--testIO")))
830 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000831#ifdef LIBXML_XINCLUDE_ENABLED
832 else if ((!strcmp(argv[i], "-xinclude")) ||
833 (!strcmp(argv[i], "--xinclude")))
834 xinclude++;
835#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000836 else if ((!strcmp(argv[i], "-compress")) ||
837 (!strcmp(argv[i], "--compress"))) {
838 compress++;
839 xmlSetCompressMode(9);
840 }
841 else if ((!strcmp(argv[i], "-nowarning")) ||
842 (!strcmp(argv[i], "--nowarning"))) {
843 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000844 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000845 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000846 else if ((!strcmp(argv[i], "-pedantic")) ||
847 (!strcmp(argv[i], "--pedantic"))) {
848 xmlGetWarningsDefaultValue = 1;
849 xmlPedanticParserDefault(1);
850 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000851#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000852 else if ((!strcmp(argv[i], "-debugent")) ||
853 (!strcmp(argv[i], "--debugent"))) {
854 debugent++;
855 xmlParserDebugEntities = 1;
856 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +0000857#endif
Daniel Veillardbe803962000-06-28 23:40:59 +0000858 else if ((!strcmp(argv[i], "-encode")) ||
859 (!strcmp(argv[i], "--encode"))) {
860 i++;
861 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000862 /*
863 * OK it's for testing purposes
864 */
865 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +0000866 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000867 else if ((!strcmp(argv[i], "-noblanks")) ||
868 (!strcmp(argv[i], "--noblanks"))) {
869 noblanks++;
870 xmlKeepBlanksDefault(0);
871 }
872 }
873 if (noent != 0) xmlSubstituteEntitiesDefault(1);
874 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
875 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000876 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000877 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000878 xmlGenericError(xmlGenericErrorContext,
879 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
880 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000881 "<html><head><title>%s output</title></head>\n",
882 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000883 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000884 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
885 argv[0]);
886 }
887 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000888 if ((!strcmp(argv[i], "-encode")) ||
889 (!strcmp(argv[i], "--encode"))) {
890 i++;
891 continue;
892 }
Daniel Veillardcd429612000-10-11 15:57:05 +0000893 if ((!strcmp(argv[i], "-dtdvalid")) ||
894 (!strcmp(argv[i], "--dtdvalid"))) {
895 i++;
896 continue;
897 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000898 if ((timing) && (repeat))
899 gettimeofday(&begin, NULL);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000900 /* Remember file names. "-" means stding. <sven@zen.org> */
901 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000902 if (repeat) {
903 for (count = 0;count < 100 * repeat;count++)
904 parseAndPrintFile(argv[i]);
905 } else
906 parseAndPrintFile(argv[i]);
907 files ++;
908 }
Daniel Veillard48b2f892001-02-25 16:11:03 +0000909 if ((timing) && (repeat)) {
910 long msec;
911 gettimeofday(&end, NULL);
912 msec = end.tv_sec - begin.tv_sec;
913 msec *= 1000;
914 msec += (end.tv_usec - begin.tv_usec) / 1000;
915 fprintf(stderr, "100 iteration took %ld ms\n", msec);
916 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000917 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000918 if (generate)
919 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000920 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000921 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000922 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000923 if ((files == 0) && (!generate)) {
Daniel Veillard48b2f892001-02-25 16:11:03 +0000924 printf("Usage : %s [options] XMLfiles ...\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000925 argv[0]);
926 printf("\tParse the XML files and output the result of the parsing\n");
927#ifdef LIBXML_DEBUG_ENABLED
928 printf("\t--debug : dump a debug tree of the in-memory document\n");
929 printf("\t--shell : run a navigating shell\n");
930 printf("\t--debugent : debug the entities defined in the document\n");
931#endif
932 printf("\t--copy : used to test the internal copy implementation\n");
933 printf("\t--recover : output what was parsable on broken XML documents\n");
934 printf("\t--noent : substitute entity references by their value\n");
935 printf("\t--noout : don't output the result tree\n");
936 printf("\t--htmlout : output results as HTML\n");
937 printf("\t--nowarp : do not put HTML doc wrapper\n");
938 printf("\t--valid : validate the document in addition to std well-formed check\n");
939 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
Daniel Veillardcd429612000-10-11 15:57:05 +0000940 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000941 printf("\t--timing : print some timings\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000942 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
943 printf("\t--insert : ad-hoc test for valid insertions\n");
944 printf("\t--compress : turn on gzip compression of output\n");
945#ifdef LIBXML_HTML_ENABLED
946 printf("\t--html : use the HTML parser\n");
947#endif
948 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard46e370e2000-07-21 20:32:03 +0000949#ifdef HAVE_SYS_MMAN_H
950 printf("\t--memory : parse from memory\n");
951#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000952 printf("\t--nowarning : do not emit warnings from parser/validator\n");
953 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard5e873c42000-04-12 13:27:38 +0000954 printf("\t--testIO : test user I/O support\n");
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000955 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000956 printf("\t--auto : generate a small doc on the fly\n");
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000957#ifdef LIBXML_XINCLUDE_ENABLED
958 printf("\t--xinclude : do XInclude processing\n");
959#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000960 }
961 xmlCleanupParser();
962 xmlMemoryDump();
963
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000964 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000965}
Daniel Veillard88a172f2000-08-04 18:23:10 +0000966