blob: cf2846784f94f51ff11a7e6220debb4d211b4358 [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;
49static int callbacks = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000050
51xmlSAXHandler emptySAXHandlerStruct = {
52 NULL, /* internalSubset */
53 NULL, /* isStandalone */
54 NULL, /* hasInternalSubset */
55 NULL, /* hasExternalSubset */
56 NULL, /* resolveEntity */
57 NULL, /* getEntity */
58 NULL, /* entityDecl */
59 NULL, /* notationDecl */
60 NULL, /* attributeDecl */
61 NULL, /* elementDecl */
62 NULL, /* unparsedEntityDecl */
63 NULL, /* setDocumentLocator */
64 NULL, /* startDocument */
65 NULL, /* endDocument */
66 NULL, /* startElement */
67 NULL, /* endElement */
68 NULL, /* reference */
69 NULL, /* characters */
70 NULL, /* ignorableWhitespace */
71 NULL, /* processingInstruction */
72 NULL, /* comment */
73 NULL, /* xmlParserWarning */
74 NULL, /* xmlParserError */
75 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000076 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000077 NULL, /* cdataBlock; */
Daniel Veillardd0463562001-10-13 09:15:48 +000078 NULL, /* externalSubset; */
79 1
Daniel Veillard5099ae81999-04-21 20:12:07 +000080};
81
82xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000083extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000084
Daniel Veillard5099ae81999-04-21 20:12:07 +000085/************************************************************************
86 * *
87 * Debug Handlers *
88 * *
89 ************************************************************************/
90
91/**
92 * isStandaloneDebug:
93 * @ctxt: An XML parser context
94 *
95 * Is this document tagged standalone ?
96 *
97 * Returns 1 if true
98 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000099static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000100isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000101{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000102 callbacks++;
103 if (quiet)
104 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000105 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000106 return(0);
107}
108
109/**
110 * hasInternalSubsetDebug:
111 * @ctxt: An XML parser context
112 *
113 * Does this document has an internal subset
114 *
115 * Returns 1 if true
116 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000117static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000118hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000119{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000120 callbacks++;
121 if (quiet)
122 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000123 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000124 return(0);
125}
126
127/**
128 * hasExternalSubsetDebug:
129 * @ctxt: An XML parser context
130 *
131 * Does this document has an external subset
132 *
133 * Returns 1 if true
134 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000135static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000136hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000137{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000138 callbacks++;
139 if (quiet)
140 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000141 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000142 return(0);
143}
144
145/**
Daniel Veillard06047432000-04-24 11:33:38 +0000146 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000147 * @ctxt: An XML parser context
148 *
149 * Does this document has an internal subset
150 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000151static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000152internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000153 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000154{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000155 callbacks++;
156 if (quiet)
157 return;
Daniel Veillard808a3f12000-08-17 13:50:51 +0000158 fprintf(stdout, "SAX.internalSubset(%s,", name);
159 if (ExternalID == NULL)
160 fprintf(stdout, " ,");
161 else
162 fprintf(stdout, " %s,", ExternalID);
163 if (SystemID == NULL)
164 fprintf(stdout, " )\n");
165 else
166 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000167}
168
169/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000170 * externalSubsetDebug:
171 * @ctxt: An XML parser context
172 *
173 * Does this document has an external subset
174 */
175static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000176externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000177 const xmlChar *ExternalID, const xmlChar *SystemID)
178{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000179 callbacks++;
180 if (quiet)
181 return;
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000182 fprintf(stdout, "SAX.externalSubset(%s,", name);
183 if (ExternalID == NULL)
184 fprintf(stdout, " ,");
185 else
186 fprintf(stdout, " %s,", ExternalID);
187 if (SystemID == NULL)
188 fprintf(stdout, " )\n");
189 else
190 fprintf(stdout, " %s)\n", SystemID);
191}
192
193/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000194 * resolveEntityDebug:
195 * @ctxt: An XML parser context
196 * @publicId: The public ID of the entity
197 * @systemId: The system ID of the entity
198 *
199 * Special entity resolver, better left to the parser, it has
200 * more context than the application layer.
201 * The default behaviour is to NOT resolve the entities, in that case
202 * the ENTITY_REF nodes are built in the structure (and the parameter
203 * values).
204 *
205 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
206 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000207static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000208resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000209{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000210 callbacks++;
211 if (quiet)
212 return(NULL);
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000213 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000214
Daniel Veillard14fff061999-06-22 21:49:07 +0000215
216 fprintf(stdout, "SAX.resolveEntity(");
217 if (publicId != NULL)
218 fprintf(stdout, "%s", (char *)publicId);
219 else
220 fprintf(stdout, " ");
221 if (systemId != NULL)
222 fprintf(stdout, ", %s)\n", (char *)systemId);
223 else
224 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000225/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000226 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000227 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000228 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000229 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000230 return(NULL);
231}
232
233/**
234 * getEntityDebug:
235 * @ctxt: An XML parser context
236 * @name: The entity name
237 *
238 * Get an entity by name
239 *
240 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
241 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000242static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000243getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000244{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000245 callbacks++;
246 if (quiet)
247 return(NULL);
Daniel Veillard27d88741999-05-29 11:51:49 +0000248 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000249 return(NULL);
250}
251
Daniel Veillardb05deb71999-08-10 19:04:08 +0000252/**
253 * getParameterEntityDebug:
254 * @ctxt: An XML parser context
255 * @name: The entity name
256 *
257 * Get a parameter entity by name
258 *
259 * Returns the xmlParserInputPtr
260 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000261static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000262getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000263{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000264 callbacks++;
265 if (quiet)
266 return(NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000267 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
268 return(NULL);
269}
270
Daniel Veillard5099ae81999-04-21 20:12:07 +0000271
272/**
273 * entityDeclDebug:
274 * @ctxt: An XML parser context
275 * @name: the entity name
276 * @type: the entity type
277 * @publicId: The public ID of the entity
278 * @systemId: The system ID of the entity
279 * @content: the entity value (without processing).
280 *
281 * An entity definition has been parsed
282 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000283static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000284entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000285 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000286{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000287 callbacks++;
288 if (quiet)
289 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000290 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000291 name, type, publicId, systemId, content);
292}
293
294/**
295 * attributeDeclDebug:
296 * @ctxt: An XML parser context
297 * @name: the attribute name
298 * @type: the attribute type
299 *
300 * An attribute definition has been parsed
301 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000302static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000303attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000304 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000305 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000306{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000307 callbacks++;
308 if (quiet)
309 return;
Daniel Veillard7e99c632000-10-06 12:59:53 +0000310 if (defaultValue == NULL)
311 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
312 elem, name, type, def);
313 else
314 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000315 elem, name, type, def, defaultValue);
316}
317
318/**
319 * elementDeclDebug:
320 * @ctxt: An XML parser context
321 * @name: the element name
322 * @type: the element type
323 * @content: the element value (without processing).
324 *
325 * An element definition has been parsed
326 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000327static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000328elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
329 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000330{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000331 callbacks++;
332 if (quiet)
333 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000334 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000335 name, type);
336}
337
338/**
339 * notationDeclDebug:
340 * @ctxt: An XML parser context
341 * @name: The name of the notation
342 * @publicId: The public ID of the entity
343 * @systemId: The system ID of the entity
344 *
345 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000346 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000347static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000348notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000349 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000350{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000351 callbacks++;
352 if (quiet)
353 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000354 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000355 (char *) name, (char *) publicId, (char *) systemId);
356}
357
358/**
359 * unparsedEntityDeclDebug:
360 * @ctxt: An XML parser context
361 * @name: The name of the entity
362 * @publicId: The public ID of the entity
363 * @systemId: The system ID of the entity
364 * @notationName: the name of the notation
365 *
366 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000367 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000368static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000369unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000370 const xmlChar *publicId, const xmlChar *systemId,
371 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000372{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000373 callbacks++;
374 if (quiet)
375 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000376 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000377 (char *) name, (char *) publicId, (char *) systemId,
378 (char *) notationName);
379}
380
381/**
382 * setDocumentLocatorDebug:
383 * @ctxt: An XML parser context
384 * @loc: A SAX Locator
385 *
386 * Receive the document locator at startup, actually xmlDefaultSAXLocator
387 * Everything is available on the context, so this is useless in our case.
388 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000389static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000390setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000391{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000392 callbacks++;
393 if (quiet)
394 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000395 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000396}
397
398/**
399 * startDocumentDebug:
400 * @ctxt: An XML parser context
401 *
402 * called when the document start being processed.
403 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000404static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000405startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000406{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000407 callbacks++;
408 if (quiet)
409 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000410 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000411}
412
413/**
414 * endDocumentDebug:
415 * @ctxt: An XML parser context
416 *
417 * called when the document end has been detected.
418 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000419static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000420endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000421{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000422 callbacks++;
423 if (quiet)
424 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000425 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000426}
427
428/**
429 * startElementDebug:
430 * @ctxt: An XML parser context
431 * @name: The element name
432 *
433 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000434 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000435static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000436startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000437{
438 int i;
439
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000440 callbacks++;
441 if (quiet)
442 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000443 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000444 if (atts != NULL) {
445 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000446 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000447 if (atts[i] != NULL)
448 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000449 }
450 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000451 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000452}
453
454/**
455 * endElementDebug:
456 * @ctxt: An XML parser context
457 * @name: The element name
458 *
459 * called when the end of an element has been detected.
460 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000461static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000462endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000463{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000464 callbacks++;
465 if (quiet)
466 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000467 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000468}
469
470/**
471 * charactersDebug:
472 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000473 * @ch: a xmlChar string
474 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000475 *
476 * receiving some chars from the parser.
477 * Question: how much at a time ???
478 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000479static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000480charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000481{
Daniel Veillard87b95392000-08-12 21:12:04 +0000482 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000483 int i;
484
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000485 callbacks++;
486 if (quiet)
487 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000488 for (i = 0;(i<len) && (i < 30);i++)
489 output[i] = ch[i];
490 output[i] = 0;
491
492 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000493}
494
495/**
496 * referenceDebug:
497 * @ctxt: An XML parser context
498 * @name: The entity name
499 *
500 * called when an entity reference is detected.
501 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000502static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000503referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000504{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000505 callbacks++;
506 if (quiet)
507 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000508 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000509}
510
511/**
512 * ignorableWhitespaceDebug:
513 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000514 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000515 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000516 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000517 *
518 * receiving some ignorable whitespaces from the parser.
519 * Question: how much at a time ???
520 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000521static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000522ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000523{
Daniel Veillard87b95392000-08-12 21:12:04 +0000524 char output[40];
525 int i;
526
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000527 callbacks++;
528 if (quiet)
529 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000530 for (i = 0;(i<len) && (i < 30);i++)
531 output[i] = ch[i];
532 output[i] = 0;
533 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000534}
535
536/**
537 * processingInstructionDebug:
538 * @ctxt: An XML parser context
539 * @target: the target name
540 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000541 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000542 *
543 * A processing instruction has been parsed.
544 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000545static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000546processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000547 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000548{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000549 callbacks++;
550 if (quiet)
551 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000552 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000553 (char *) target, (char *) data);
554}
555
556/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000557 * cdataBlockDebug:
558 * @ctx: the user data (XML parser context)
559 * @value: The pcdata content
560 * @len: the block length
561 *
562 * called when a pcdata block has been parsed
563 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000564static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000565cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000566{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000567 callbacks++;
568 if (quiet)
569 return;
Daniel Veillard39915622000-10-15 10:06:55 +0000570 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000571 (char *) value, len);
572}
573
574/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000575 * commentDebug:
576 * @ctxt: An XML parser context
577 * @value: the comment content
578 *
579 * A comment has been parsed.
580 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000581static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000582commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000583{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000584 callbacks++;
585 if (quiet)
586 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000587 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000588}
589
590/**
591 * warningDebug:
592 * @ctxt: An XML parser context
593 * @msg: the message to display/transmit
594 * @...: extra parameters for the message display
595 *
596 * Display and format a warning messages, gives file, line, position and
597 * extra parameters.
598 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000599static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000600warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000601{
602 va_list args;
603
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000604 callbacks++;
605 if (quiet)
606 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000607 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000608 fprintf(stdout, "SAX.warning: ");
609 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000610 va_end(args);
611}
612
613/**
614 * errorDebug:
615 * @ctxt: An XML parser context
616 * @msg: the message to display/transmit
617 * @...: extra parameters for the message display
618 *
619 * Display and format a error messages, gives file, line, position and
620 * extra parameters.
621 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000622static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000623errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000624{
625 va_list args;
626
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000627 callbacks++;
628 if (quiet)
629 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000630 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000631 fprintf(stdout, "SAX.error: ");
632 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000633 va_end(args);
634}
635
636/**
637 * fatalErrorDebug:
638 * @ctxt: An XML parser context
639 * @msg: the message to display/transmit
640 * @...: extra parameters for the message display
641 *
642 * Display and format a fatalError messages, gives file, line, position and
643 * extra parameters.
644 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000645static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000646fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000647{
648 va_list args;
649
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000650 callbacks++;
651 if (quiet)
652 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000653 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000654 fprintf(stdout, "SAX.fatalError: ");
655 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000656 va_end(args);
657}
658
659xmlSAXHandler debugSAXHandlerStruct = {
660 internalSubsetDebug,
661 isStandaloneDebug,
662 hasInternalSubsetDebug,
663 hasExternalSubsetDebug,
664 resolveEntityDebug,
665 getEntityDebug,
666 entityDeclDebug,
667 notationDeclDebug,
668 attributeDeclDebug,
669 elementDeclDebug,
670 unparsedEntityDeclDebug,
671 setDocumentLocatorDebug,
672 startDocumentDebug,
673 endDocumentDebug,
674 startElementDebug,
675 endElementDebug,
676 referenceDebug,
677 charactersDebug,
678 ignorableWhitespaceDebug,
679 processingInstructionDebug,
680 commentDebug,
681 warningDebug,
682 errorDebug,
683 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000684 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000685 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000686 externalSubsetDebug,
687 1
Daniel Veillard5099ae81999-04-21 20:12:07 +0000688};
689
690xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
691
692/************************************************************************
693 * *
694 * Debug *
695 * *
696 ************************************************************************/
697
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000698static void
699parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000700 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000701
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000702 if (push) {
703 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000704
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000705 /*
706 * Empty callbacks for checking
707 */
708 f = fopen(filename, "r");
709 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000710 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000711 char chars[10];
712 xmlParserCtxtPtr ctxt;
713
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000714 ret = fread(chars, 1, 4, f);
715 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000716 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000717 chars, ret, filename);
718 while ((ret = fread(chars, 1, 3, f)) > 0) {
719 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000720 }
721 xmlParseChunk(ctxt, chars, 0, 1);
722 xmlFreeParserCtxt(ctxt);
723 }
724 fclose(f);
725 } else {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000726 xmlGenericError(xmlGenericErrorContext,
727 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000728 }
729 /*
730 * Debug callback
731 */
732 f = fopen(filename, "r");
733 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000734 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000735 char chars[10];
736 xmlParserCtxtPtr ctxt;
737
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000738 ret = fread(chars, 1, 4, f);
739 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000740 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000741 chars, ret, filename);
742 while ((ret = fread(chars, 1, 3, f)) > 0) {
743 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000744 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000745 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000746 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000747 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000748 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000749 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000750 }
751 }
752 fclose(f);
753 }
754 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000755 if (!speed) {
756 /*
757 * Empty callbacks for checking
758 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000759 if (!quiet) {
760 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
761 if (res != 0) {
762 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
763 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000764 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000765
Daniel Veillard5e873c42000-04-12 13:27:38 +0000766 /*
767 * Debug callback
768 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000769 callbacks = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000770 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
771 if (res != 0) {
772 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
773 }
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000774 if (quiet)
775 fprintf(stdout, "%d callbacks generated\n", callbacks);
Daniel Veillard5e873c42000-04-12 13:27:38 +0000776 } else {
777 /*
778 * test 100x the SAX parse
779 */
780 int i;
781
782 for (i = 0; i<100;i++)
783 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
784 if (res != 0) {
785 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
786 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000787 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000788 }
789}
790
Daniel Veillard5099ae81999-04-21 20:12:07 +0000791
792int main(int argc, char **argv) {
793 int i;
794 int files = 0;
795
796 for (i = 1; i < argc ; i++) {
797 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
798 debug++;
799 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
800 copy++;
801 else if ((!strcmp(argv[i], "-recover")) ||
802 (!strcmp(argv[i], "--recover")))
803 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000804 else if ((!strcmp(argv[i], "-push")) ||
805 (!strcmp(argv[i], "--push")))
806 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000807 else if ((!strcmp(argv[i], "-speed")) ||
808 (!strcmp(argv[i], "--speed")))
809 speed++;
Daniel Veillard5997aca2002-03-18 18:36:20 +0000810 else if ((!strcmp(argv[i], "-noent")) ||
811 (!strcmp(argv[i], "--noent")))
812 noent++;
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000813 else if ((!strcmp(argv[i], "-quiet")) ||
814 (!strcmp(argv[i], "--quiet")))
815 quiet++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000816 }
Daniel Veillard5997aca2002-03-18 18:36:20 +0000817 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000818 for (i = 1; i < argc ; i++) {
819 if (argv[i][0] != '-') {
820 parseAndPrintFile(argv[i]);
821 files ++;
822 }
823 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000824 xmlCleanupParser();
825 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000826
827 return(0);
828}