blob: 80334d68764bdc9346d1958a5f88577ce4489d07 [file] [log] [blame]
Daniel Veillard5099ae81999-04-21 20:12:07 +00001/*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002 * testSAX.c : a small tester program for parsing using the SAX API.
Daniel Veillard5099ae81999-04-21 20:12:07 +00003 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillard5099ae81999-04-21 20:12:07 +00007 */
8
Bjorn Reese70a9da52001-04-21 16:57:29 +00009#include "libxml.h"
10
Daniel Veillard7f7d1111999-09-22 09:46:25 +000011#include <string.h>
12#include <stdarg.h>
13
14#ifdef HAVE_SYS_TYPES_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000015#include <sys/types.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000016#endif
Daniel Veillard5099ae81999-04-21 20:12:07 +000017#ifdef HAVE_SYS_STAT_H
18#include <sys/stat.h>
19#endif
20#ifdef HAVE_FCNTL_H
21#include <fcntl.h>
22#endif
23#ifdef HAVE_UNISTD_H
24#include <unistd.h>
25#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000026#ifdef HAVE_STDLIB_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000027#include <stdlib.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000028#endif
Daniel Veillard7a66ee61999-09-26 11:31:02 +000029#ifdef HAVE_STRING_H
30#include <string.h>
31#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000032
Daniel Veillard5099ae81999-04-21 20:12:07 +000033
Daniel Veillardd0463562001-10-13 09:15:48 +000034#include <libxml/globals.h>
Daniel Veillardb71379b2000-10-09 12:30:39 +000035#include <libxml/xmlerror.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000036#include <libxml/parser.h>
37#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
38#include <libxml/tree.h>
39#include <libxml/debugXML.h>
40#include <libxml/xmlmemory.h>
Daniel Veillard5099ae81999-04-21 20:12:07 +000041
42static int debug = 0;
43static int copy = 0;
44static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000045static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000046static int speed = 0;
Daniel Veillard5997aca2002-03-18 18:36:20 +000047static int noent = 0;
Daniel Veillarde50f3b52002-03-20 19:24:21 +000048static int quiet = 0;
Daniel Veillard0fb18932003-09-07 09:14:37 +000049static int nonull = 0;
50static int sax2 = 0;
Daniel Veillarde50f3b52002-03-20 19:24:21 +000051static int callbacks = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000052
53xmlSAXHandler emptySAXHandlerStruct = {
54 NULL, /* internalSubset */
55 NULL, /* isStandalone */
56 NULL, /* hasInternalSubset */
57 NULL, /* hasExternalSubset */
58 NULL, /* resolveEntity */
59 NULL, /* getEntity */
60 NULL, /* entityDecl */
61 NULL, /* notationDecl */
62 NULL, /* attributeDecl */
63 NULL, /* elementDecl */
64 NULL, /* unparsedEntityDecl */
65 NULL, /* setDocumentLocator */
66 NULL, /* startDocument */
67 NULL, /* endDocument */
68 NULL, /* startElement */
69 NULL, /* endElement */
70 NULL, /* reference */
71 NULL, /* characters */
72 NULL, /* ignorableWhitespace */
73 NULL, /* processingInstruction */
74 NULL, /* comment */
75 NULL, /* xmlParserWarning */
76 NULL, /* xmlParserError */
77 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000078 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000079 NULL, /* cdataBlock; */
Daniel Veillard0fb18932003-09-07 09:14:37 +000080 NULL, /* externalSubset; */
81 1,
82 NULL,
83 NULL, /* startElementNs */
84 NULL, /* endElementNs */
85 NULL /* attributeNs */
Daniel Veillard5099ae81999-04-21 20:12:07 +000086};
87
88xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000089extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000090
Daniel Veillard5099ae81999-04-21 20:12:07 +000091/************************************************************************
92 * *
93 * Debug Handlers *
94 * *
95 ************************************************************************/
96
97/**
98 * isStandaloneDebug:
99 * @ctxt: An XML parser context
100 *
101 * Is this document tagged standalone ?
102 *
103 * Returns 1 if true
104 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000105static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000106isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000107{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000108 callbacks++;
109 if (quiet)
110 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000111 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000112 return(0);
113}
114
115/**
116 * hasInternalSubsetDebug:
117 * @ctxt: An XML parser context
118 *
119 * Does this document has an internal subset
120 *
121 * Returns 1 if true
122 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000123static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000124hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000125{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000126 callbacks++;
127 if (quiet)
128 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000129 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000130 return(0);
131}
132
133/**
134 * hasExternalSubsetDebug:
135 * @ctxt: An XML parser context
136 *
137 * Does this document has an external subset
138 *
139 * Returns 1 if true
140 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000141static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000142hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000143{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000144 callbacks++;
145 if (quiet)
146 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000147 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000148 return(0);
149}
150
151/**
Daniel Veillard06047432000-04-24 11:33:38 +0000152 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000153 * @ctxt: An XML parser context
154 *
155 * Does this document has an internal subset
156 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000157static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000158internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000159 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000160{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000161 callbacks++;
162 if (quiet)
163 return;
Daniel Veillard808a3f12000-08-17 13:50:51 +0000164 fprintf(stdout, "SAX.internalSubset(%s,", name);
165 if (ExternalID == NULL)
166 fprintf(stdout, " ,");
167 else
168 fprintf(stdout, " %s,", ExternalID);
169 if (SystemID == NULL)
170 fprintf(stdout, " )\n");
171 else
172 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000173}
174
175/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000176 * externalSubsetDebug:
177 * @ctxt: An XML parser context
178 *
179 * Does this document has an external subset
180 */
181static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000182externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000183 const xmlChar *ExternalID, const xmlChar *SystemID)
184{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000185 callbacks++;
186 if (quiet)
187 return;
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000188 fprintf(stdout, "SAX.externalSubset(%s,", name);
189 if (ExternalID == NULL)
190 fprintf(stdout, " ,");
191 else
192 fprintf(stdout, " %s,", ExternalID);
193 if (SystemID == NULL)
194 fprintf(stdout, " )\n");
195 else
196 fprintf(stdout, " %s)\n", SystemID);
197}
198
199/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000200 * resolveEntityDebug:
201 * @ctxt: An XML parser context
202 * @publicId: The public ID of the entity
203 * @systemId: The system ID of the entity
204 *
205 * Special entity resolver, better left to the parser, it has
206 * more context than the application layer.
207 * The default behaviour is to NOT resolve the entities, in that case
208 * the ENTITY_REF nodes are built in the structure (and the parameter
209 * values).
210 *
211 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
212 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000213static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000214resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000215{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000216 callbacks++;
217 if (quiet)
218 return(NULL);
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000219 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000220
Daniel Veillard14fff061999-06-22 21:49:07 +0000221
222 fprintf(stdout, "SAX.resolveEntity(");
223 if (publicId != NULL)
224 fprintf(stdout, "%s", (char *)publicId);
225 else
226 fprintf(stdout, " ");
227 if (systemId != NULL)
228 fprintf(stdout, ", %s)\n", (char *)systemId);
229 else
230 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000231/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000232 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000233 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000234 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000235 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000236 return(NULL);
237}
238
239/**
240 * getEntityDebug:
241 * @ctxt: An XML parser context
242 * @name: The entity name
243 *
244 * Get an entity by name
245 *
246 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
247 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000248static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000249getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000250{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000251 callbacks++;
252 if (quiet)
253 return(NULL);
Daniel Veillard27d88741999-05-29 11:51:49 +0000254 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000255 return(NULL);
256}
257
Daniel Veillardb05deb71999-08-10 19:04:08 +0000258/**
259 * getParameterEntityDebug:
260 * @ctxt: An XML parser context
261 * @name: The entity name
262 *
263 * Get a parameter entity by name
264 *
265 * Returns the xmlParserInputPtr
266 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000267static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000268getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000269{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000270 callbacks++;
271 if (quiet)
272 return(NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000273 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
274 return(NULL);
275}
276
Daniel Veillard5099ae81999-04-21 20:12:07 +0000277
278/**
279 * entityDeclDebug:
280 * @ctxt: An XML parser context
281 * @name: the entity name
282 * @type: the entity type
283 * @publicId: The public ID of the entity
284 * @systemId: The system ID of the entity
285 * @content: the entity value (without processing).
286 *
287 * An entity definition has been parsed
288 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000289static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000290entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000291 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000292{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000293 callbacks++;
294 if (quiet)
295 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000296 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000297 name, type, publicId, systemId, content);
298}
299
300/**
301 * attributeDeclDebug:
302 * @ctxt: An XML parser context
303 * @name: the attribute name
304 * @type: the attribute type
305 *
306 * An attribute definition has been parsed
307 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000308static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000309attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000310 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000311 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000312{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000313 callbacks++;
314 if (quiet)
315 return;
Daniel Veillard7e99c632000-10-06 12:59:53 +0000316 if (defaultValue == NULL)
317 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
318 elem, name, type, def);
319 else
320 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000321 elem, name, type, def, defaultValue);
322}
323
324/**
325 * elementDeclDebug:
326 * @ctxt: An XML parser context
327 * @name: the element name
328 * @type: the element type
329 * @content: the element value (without processing).
330 *
331 * An element definition has been parsed
332 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000333static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000334elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
335 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000336{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000337 callbacks++;
338 if (quiet)
339 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000340 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000341 name, type);
342}
343
344/**
345 * notationDeclDebug:
346 * @ctxt: An XML parser context
347 * @name: The name of the notation
348 * @publicId: The public ID of the entity
349 * @systemId: The system ID of the entity
350 *
351 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000352 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000353static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000354notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000355 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000356{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000357 callbacks++;
358 if (quiet)
359 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000360 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000361 (char *) name, (char *) publicId, (char *) systemId);
362}
363
364/**
365 * unparsedEntityDeclDebug:
366 * @ctxt: An XML parser context
367 * @name: The name of the entity
368 * @publicId: The public ID of the entity
369 * @systemId: The system ID of the entity
370 * @notationName: the name of the notation
371 *
372 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000373 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000374static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000375unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000376 const xmlChar *publicId, const xmlChar *systemId,
377 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000378{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000379 callbacks++;
380 if (quiet)
381 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000382 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000383 (char *) name, (char *) publicId, (char *) systemId,
384 (char *) notationName);
385}
386
387/**
388 * setDocumentLocatorDebug:
389 * @ctxt: An XML parser context
390 * @loc: A SAX Locator
391 *
392 * Receive the document locator at startup, actually xmlDefaultSAXLocator
393 * Everything is available on the context, so this is useless in our case.
394 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000395static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000396setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000397{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000398 callbacks++;
399 if (quiet)
400 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000401 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000402}
403
404/**
405 * startDocumentDebug:
406 * @ctxt: An XML parser context
407 *
408 * called when the document start being processed.
409 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000410static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000411startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000412{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000413 callbacks++;
414 if (quiet)
415 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000416 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000417}
418
419/**
420 * endDocumentDebug:
421 * @ctxt: An XML parser context
422 *
423 * called when the document end has been detected.
424 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000425static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000426endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000427{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000428 callbacks++;
429 if (quiet)
430 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000431 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000432}
433
434/**
435 * startElementDebug:
436 * @ctxt: An XML parser context
437 * @name: The element name
438 *
439 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000440 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000441static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000442startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000443{
444 int i;
445
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000446 callbacks++;
447 if (quiet)
448 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000449 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000450 if (atts != NULL) {
451 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000452 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000453 if (atts[i] != NULL)
454 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000455 }
456 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000457 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000458}
459
460/**
461 * endElementDebug:
462 * @ctxt: An XML parser context
463 * @name: The element name
464 *
465 * called when the end of an element has been detected.
466 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000467static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000468endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000469{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000470 callbacks++;
471 if (quiet)
472 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000473 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000474}
475
476/**
477 * charactersDebug:
478 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000479 * @ch: a xmlChar string
480 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000481 *
482 * receiving some chars from the parser.
483 * Question: how much at a time ???
484 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000485static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000486charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000487{
Daniel Veillard87b95392000-08-12 21:12:04 +0000488 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000489 int i;
490
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000491 callbacks++;
492 if (quiet)
493 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000494 for (i = 0;(i<len) && (i < 30);i++)
495 output[i] = ch[i];
496 output[i] = 0;
497
498 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000499}
500
501/**
502 * referenceDebug:
503 * @ctxt: An XML parser context
504 * @name: The entity name
505 *
506 * called when an entity reference is detected.
507 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000508static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000509referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000510{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000511 callbacks++;
512 if (quiet)
513 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000514 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000515}
516
517/**
518 * ignorableWhitespaceDebug:
519 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000520 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000521 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000522 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000523 *
524 * receiving some ignorable whitespaces from the parser.
525 * Question: how much at a time ???
526 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000527static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000528ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000529{
Daniel Veillard87b95392000-08-12 21:12:04 +0000530 char output[40];
531 int i;
532
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000533 callbacks++;
534 if (quiet)
535 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000536 for (i = 0;(i<len) && (i < 30);i++)
537 output[i] = ch[i];
538 output[i] = 0;
539 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000540}
541
542/**
543 * processingInstructionDebug:
544 * @ctxt: An XML parser context
545 * @target: the target name
546 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000547 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000548 *
549 * A processing instruction has been parsed.
550 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000551static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000552processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000553 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000554{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000555 callbacks++;
556 if (quiet)
557 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000558 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000559 (char *) target, (char *) data);
560}
561
562/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000563 * cdataBlockDebug:
564 * @ctx: the user data (XML parser context)
565 * @value: The pcdata content
566 * @len: the block length
567 *
568 * called when a pcdata block has been parsed
569 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000570static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000571cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000572{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000573 callbacks++;
574 if (quiet)
575 return;
Daniel Veillard39915622000-10-15 10:06:55 +0000576 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000577 (char *) value, len);
578}
579
580/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000581 * commentDebug:
582 * @ctxt: An XML parser context
583 * @value: the comment content
584 *
585 * A comment has been parsed.
586 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000587static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000588commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000589{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000590 callbacks++;
591 if (quiet)
592 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000593 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000594}
595
596/**
597 * warningDebug:
598 * @ctxt: An XML parser context
599 * @msg: the message to display/transmit
600 * @...: extra parameters for the message display
601 *
602 * Display and format a warning messages, gives file, line, position and
603 * extra parameters.
604 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000605static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000606warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000607{
608 va_list args;
609
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000610 callbacks++;
611 if (quiet)
612 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000613 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000614 fprintf(stdout, "SAX.warning: ");
615 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000616 va_end(args);
617}
618
619/**
620 * errorDebug:
621 * @ctxt: An XML parser context
622 * @msg: the message to display/transmit
623 * @...: extra parameters for the message display
624 *
625 * Display and format a error messages, gives file, line, position and
626 * extra parameters.
627 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000628static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000629errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000630{
631 va_list args;
632
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000633 callbacks++;
634 if (quiet)
635 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000636 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000637 fprintf(stdout, "SAX.error: ");
638 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000639 va_end(args);
640}
641
642/**
643 * fatalErrorDebug:
644 * @ctxt: An XML parser context
645 * @msg: the message to display/transmit
646 * @...: extra parameters for the message display
647 *
648 * Display and format a fatalError messages, gives file, line, position and
649 * extra parameters.
650 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000651static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000652fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000653{
654 va_list args;
655
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000656 callbacks++;
657 if (quiet)
658 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000659 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000660 fprintf(stdout, "SAX.fatalError: ");
661 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000662 va_end(args);
663}
664
665xmlSAXHandler debugSAXHandlerStruct = {
666 internalSubsetDebug,
667 isStandaloneDebug,
668 hasInternalSubsetDebug,
669 hasExternalSubsetDebug,
670 resolveEntityDebug,
671 getEntityDebug,
672 entityDeclDebug,
673 notationDeclDebug,
674 attributeDeclDebug,
675 elementDeclDebug,
676 unparsedEntityDeclDebug,
677 setDocumentLocatorDebug,
678 startDocumentDebug,
679 endDocumentDebug,
680 startElementDebug,
681 endElementDebug,
682 referenceDebug,
683 charactersDebug,
684 ignorableWhitespaceDebug,
685 processingInstructionDebug,
686 commentDebug,
687 warningDebug,
688 errorDebug,
689 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000690 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000691 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000692 externalSubsetDebug,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000693 1,
694 NULL,
695 NULL,
696 NULL,
697 NULL
Daniel Veillard5099ae81999-04-21 20:12:07 +0000698};
699
700xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
701
Daniel Veillard0fb18932003-09-07 09:14:37 +0000702/*
703 * SAX2 specific callbacks
704 */
705/**
706 * startElementDebug:
707 * @ctxt: An XML parser context
708 * @name: The element name
709 *
710 * called when an opening tag has been processed.
711 */
712static void
713startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
714 const xmlChar *localname,
715 const xmlChar *prefix,
716 const xmlChar *URI,
717 int nb_namespaces,
718 const xmlChar **namespaces,
719 int nb_attributes)
720{
721 int i;
722
723 callbacks++;
724 if (quiet)
725 return;
726 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
727 if (prefix == NULL)
728 fprintf(stdout, ", NULL");
729 else
730 fprintf(stdout, ", %s", (char *) prefix);
731 if (URI == NULL)
732 fprintf(stdout, ", NULL");
733 else
734 fprintf(stdout, ", '%s'", (char *) URI);
735 fprintf(stdout, ", %d", nb_namespaces);
736
737 if (namespaces != NULL) {
738 for (i = 0;i < nb_namespaces * 2;i++) {
739 fprintf(stdout, ", xmlns");
740 if (namespaces[i] != NULL)
741 fprintf(stdout, ":%s", namespaces[i]);
742 i++;
743 fprintf(stdout, "='%s'", namespaces[i]);
744 }
745 }
746 fprintf(stdout, ", %d)\n", nb_attributes);
747}
748
749/**
750 * endElementDebug:
751 * @ctxt: An XML parser context
752 * @name: The element name
753 *
754 * called when the end of an element has been detected.
755 */
756static void
757endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
758 const xmlChar *localname,
759 const xmlChar *prefix,
760 const xmlChar *URI)
761{
762 callbacks++;
763 if (quiet)
764 return;
765 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
766 if (prefix == NULL)
767 fprintf(stdout, ", NULL");
768 else
769 fprintf(stdout, ", %s", (char *) prefix);
770 if (URI == NULL)
771 fprintf(stdout, ", NULL)\n");
772 else
773 fprintf(stdout, ", '%s')\n", (char *) URI);
774}
775
776/**
777 * attributeNsDebug:
778 * @ctxt: An XML parser context
779 * @name: The element name
780 *
781 * called when the end of an element has been detected.
782 */
783static void
784attributeNsDebug(void *ctx ATTRIBUTE_UNUSED,
785 const xmlChar *localname,
786 const xmlChar *prefix,
787 const xmlChar *URI,
788 const xmlChar *value,
789 int valuelen)
790{
791 callbacks++;
792 if (quiet)
793 return;
794 fprintf(stdout, "SAX.attributeNs(%s", (char *) localname);
795 if (prefix == NULL)
796 fprintf(stdout, ", NULL");
797 else
798 fprintf(stdout, ", %s", (char *) prefix);
799 if (URI == NULL)
800 fprintf(stdout, ", NULL");
801 else
802 fprintf(stdout, ", '%s'", (char *) URI);
803 if (valuelen > 13)
804 fprintf(stdout, ", %10s..., %d)\n", value, valuelen);
805 else
806 fprintf(stdout, ", %s, %d)\n", value, valuelen);
807}
808
809xmlSAXHandler debugSAX2HandlerStruct = {
810 internalSubsetDebug,
811 isStandaloneDebug,
812 hasInternalSubsetDebug,
813 hasExternalSubsetDebug,
814 resolveEntityDebug,
815 getEntityDebug,
816 entityDeclDebug,
817 notationDeclDebug,
818 attributeDeclDebug,
819 elementDeclDebug,
820 unparsedEntityDeclDebug,
821 setDocumentLocatorDebug,
822 startDocumentDebug,
823 endDocumentDebug,
824 NULL,
825 NULL,
826 referenceDebug,
827 charactersDebug,
828 ignorableWhitespaceDebug,
829 processingInstructionDebug,
830 commentDebug,
831 warningDebug,
832 errorDebug,
833 fatalErrorDebug,
834 getParameterEntityDebug,
835 cdataBlockDebug,
836 externalSubsetDebug,
837 1,
838 NULL,
839 startElementNsDebug,
840 endElementNsDebug,
841 attributeNsDebug
842};
843
844xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
845
Daniel Veillard5099ae81999-04-21 20:12:07 +0000846/************************************************************************
847 * *
848 * Debug *
849 * *
850 ************************************************************************/
851
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000852static void
853parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000854 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000855
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000856 if (push) {
857 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000858
Daniel Veillard0fb18932003-09-07 09:14:37 +0000859 if ((!quiet) && (!nonull)) {
860 /*
861 * Empty callbacks for checking
862 */
863 f = fopen(filename, "r");
864 if (f != NULL) {
865 int ret;
866 char chars[10];
867 xmlParserCtxtPtr ctxt;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000868
Daniel Veillard0fb18932003-09-07 09:14:37 +0000869 ret = fread(chars, 1, 4, f);
870 if (ret > 0) {
871 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
872 chars, ret, filename);
873 while ((ret = fread(chars, 1, 3, f)) > 0) {
874 xmlParseChunk(ctxt, chars, ret, 0);
875 }
876 xmlParseChunk(ctxt, chars, 0, 1);
877 xmlFreeParserCtxt(ctxt);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000878 }
Daniel Veillard0fb18932003-09-07 09:14:37 +0000879 fclose(f);
880 } else {
881 xmlGenericError(xmlGenericErrorContext,
882 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000883 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000884 }
885 /*
886 * Debug callback
887 */
888 f = fopen(filename, "r");
889 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000890 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000891 char chars[10];
892 xmlParserCtxtPtr ctxt;
893
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000894 ret = fread(chars, 1, 4, f);
895 if (ret > 0) {
Daniel Veillard0fb18932003-09-07 09:14:37 +0000896 if (sax2)
897 ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
898 chars, ret, filename);
899 else
900 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
901 chars, ret, filename);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000902 while ((ret = fread(chars, 1, 3, f)) > 0) {
903 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000904 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000905 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000906 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000907 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000908 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000909 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000910 }
911 }
912 fclose(f);
913 }
914 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000915 if (!speed) {
916 /*
917 * Empty callbacks for checking
918 */
Daniel Veillard0fb18932003-09-07 09:14:37 +0000919 if ((!quiet) && (!nonull)) {
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000920 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
921 if (res != 0) {
922 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
923 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000924 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000925
Daniel Veillard5e873c42000-04-12 13:27:38 +0000926 /*
927 * Debug callback
928 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000929 callbacks = 0;
Daniel Veillard0fb18932003-09-07 09:14:37 +0000930 if (sax2)
931 res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
932 else
933 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
Daniel Veillard5e873c42000-04-12 13:27:38 +0000934 if (res != 0) {
935 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
936 }
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000937 if (quiet)
938 fprintf(stdout, "%d callbacks generated\n", callbacks);
Daniel Veillard5e873c42000-04-12 13:27:38 +0000939 } else {
940 /*
941 * test 100x the SAX parse
942 */
943 int i;
944
945 for (i = 0; i<100;i++)
946 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
947 if (res != 0) {
948 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
949 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000950 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000951 }
952}
953
Daniel Veillard5099ae81999-04-21 20:12:07 +0000954
955int main(int argc, char **argv) {
956 int i;
957 int files = 0;
958
959 for (i = 1; i < argc ; i++) {
960 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
961 debug++;
962 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
963 copy++;
964 else if ((!strcmp(argv[i], "-recover")) ||
965 (!strcmp(argv[i], "--recover")))
966 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000967 else if ((!strcmp(argv[i], "-push")) ||
968 (!strcmp(argv[i], "--push")))
969 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000970 else if ((!strcmp(argv[i], "-speed")) ||
971 (!strcmp(argv[i], "--speed")))
972 speed++;
Daniel Veillard5997aca2002-03-18 18:36:20 +0000973 else if ((!strcmp(argv[i], "-noent")) ||
974 (!strcmp(argv[i], "--noent")))
975 noent++;
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000976 else if ((!strcmp(argv[i], "-quiet")) ||
977 (!strcmp(argv[i], "--quiet")))
978 quiet++;
Daniel Veillard0fb18932003-09-07 09:14:37 +0000979 else if ((!strcmp(argv[i], "-sax2")) ||
980 (!strcmp(argv[i], "--sax2")))
981 sax2++;
982 else if ((!strcmp(argv[i], "-nonull")) ||
983 (!strcmp(argv[i], "--nonull")))
984 nonull++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000985 }
Daniel Veillard5997aca2002-03-18 18:36:20 +0000986 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000987 for (i = 1; i < argc ; i++) {
988 if (argv[i][0] != '-') {
989 parseAndPrintFile(argv[i]);
990 files ++;
991 }
992 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000993 xmlCleanupParser();
994 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000995
996 return(0);
997}