blob: 559177c7c2d9b7072c0fee12585c941d062258f5 [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 Veillard5099ae81999-04-21 20:12:07 +000048
49xmlSAXHandler emptySAXHandlerStruct = {
50 NULL, /* internalSubset */
51 NULL, /* isStandalone */
52 NULL, /* hasInternalSubset */
53 NULL, /* hasExternalSubset */
54 NULL, /* resolveEntity */
55 NULL, /* getEntity */
56 NULL, /* entityDecl */
57 NULL, /* notationDecl */
58 NULL, /* attributeDecl */
59 NULL, /* elementDecl */
60 NULL, /* unparsedEntityDecl */
61 NULL, /* setDocumentLocator */
62 NULL, /* startDocument */
63 NULL, /* endDocument */
64 NULL, /* startElement */
65 NULL, /* endElement */
66 NULL, /* reference */
67 NULL, /* characters */
68 NULL, /* ignorableWhitespace */
69 NULL, /* processingInstruction */
70 NULL, /* comment */
71 NULL, /* xmlParserWarning */
72 NULL, /* xmlParserError */
73 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000074 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000075 NULL, /* cdataBlock; */
Daniel Veillardd0463562001-10-13 09:15:48 +000076 NULL, /* externalSubset; */
77 1
Daniel Veillard5099ae81999-04-21 20:12:07 +000078};
79
80xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000081extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000082
Daniel Veillard5099ae81999-04-21 20:12:07 +000083/************************************************************************
84 * *
85 * Debug Handlers *
86 * *
87 ************************************************************************/
88
89/**
90 * isStandaloneDebug:
91 * @ctxt: An XML parser context
92 *
93 * Is this document tagged standalone ?
94 *
95 * Returns 1 if true
96 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000097static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +000098isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +000099{
Daniel Veillard27d88741999-05-29 11:51:49 +0000100 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000101 return(0);
102}
103
104/**
105 * hasInternalSubsetDebug:
106 * @ctxt: An XML parser context
107 *
108 * Does this document has an internal subset
109 *
110 * Returns 1 if true
111 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000112static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000113hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000114{
Daniel Veillard27d88741999-05-29 11:51:49 +0000115 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000116 return(0);
117}
118
119/**
120 * hasExternalSubsetDebug:
121 * @ctxt: An XML parser context
122 *
123 * Does this document has an external subset
124 *
125 * Returns 1 if true
126 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000127static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000128hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000129{
Daniel Veillard27d88741999-05-29 11:51:49 +0000130 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000131 return(0);
132}
133
134/**
Daniel Veillard06047432000-04-24 11:33:38 +0000135 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000136 * @ctxt: An XML parser context
137 *
138 * Does this document has an internal subset
139 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000140static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000141internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000142 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000143{
Daniel Veillard808a3f12000-08-17 13:50:51 +0000144 fprintf(stdout, "SAX.internalSubset(%s,", name);
145 if (ExternalID == NULL)
146 fprintf(stdout, " ,");
147 else
148 fprintf(stdout, " %s,", ExternalID);
149 if (SystemID == NULL)
150 fprintf(stdout, " )\n");
151 else
152 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000153}
154
155/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000156 * externalSubsetDebug:
157 * @ctxt: An XML parser context
158 *
159 * Does this document has an external subset
160 */
161static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000162externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000163 const xmlChar *ExternalID, const xmlChar *SystemID)
164{
165 fprintf(stdout, "SAX.externalSubset(%s,", name);
166 if (ExternalID == NULL)
167 fprintf(stdout, " ,");
168 else
169 fprintf(stdout, " %s,", ExternalID);
170 if (SystemID == NULL)
171 fprintf(stdout, " )\n");
172 else
173 fprintf(stdout, " %s)\n", SystemID);
174}
175
176/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000177 * resolveEntityDebug:
178 * @ctxt: An XML parser context
179 * @publicId: The public ID of the entity
180 * @systemId: The system ID of the entity
181 *
182 * Special entity resolver, better left to the parser, it has
183 * more context than the application layer.
184 * The default behaviour is to NOT resolve the entities, in that case
185 * the ENTITY_REF nodes are built in the structure (and the parameter
186 * values).
187 *
188 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
189 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000190static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000191resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000192{
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000193 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000194
Daniel Veillard14fff061999-06-22 21:49:07 +0000195
196 fprintf(stdout, "SAX.resolveEntity(");
197 if (publicId != NULL)
198 fprintf(stdout, "%s", (char *)publicId);
199 else
200 fprintf(stdout, " ");
201 if (systemId != NULL)
202 fprintf(stdout, ", %s)\n", (char *)systemId);
203 else
204 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000205/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000206 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000207 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000208 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000209 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000210 return(NULL);
211}
212
213/**
214 * getEntityDebug:
215 * @ctxt: An XML parser context
216 * @name: The entity name
217 *
218 * Get an entity by name
219 *
220 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
221 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000222static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000223getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000224{
Daniel Veillard27d88741999-05-29 11:51:49 +0000225 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000226 return(NULL);
227}
228
Daniel Veillardb05deb71999-08-10 19:04:08 +0000229/**
230 * getParameterEntityDebug:
231 * @ctxt: An XML parser context
232 * @name: The entity name
233 *
234 * Get a parameter entity by name
235 *
236 * Returns the xmlParserInputPtr
237 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000238static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000239getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000240{
241 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
242 return(NULL);
243}
244
Daniel Veillard5099ae81999-04-21 20:12:07 +0000245
246/**
247 * entityDeclDebug:
248 * @ctxt: An XML parser context
249 * @name: the entity name
250 * @type: the entity type
251 * @publicId: The public ID of the entity
252 * @systemId: The system ID of the entity
253 * @content: the entity value (without processing).
254 *
255 * An entity definition has been parsed
256 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000257static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000258entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000259 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000260{
Daniel Veillard27d88741999-05-29 11:51:49 +0000261 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000262 name, type, publicId, systemId, content);
263}
264
265/**
266 * attributeDeclDebug:
267 * @ctxt: An XML parser context
268 * @name: the attribute name
269 * @type: the attribute type
270 *
271 * An attribute definition has been parsed
272 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000273static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000274attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000275 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000276 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000277{
Daniel Veillard7e99c632000-10-06 12:59:53 +0000278 if (defaultValue == NULL)
279 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
280 elem, name, type, def);
281 else
282 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000283 elem, name, type, def, defaultValue);
284}
285
286/**
287 * elementDeclDebug:
288 * @ctxt: An XML parser context
289 * @name: the element name
290 * @type: the element type
291 * @content: the element value (without processing).
292 *
293 * An element definition has been parsed
294 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000295static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000296elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
297 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000298{
Daniel Veillard27d88741999-05-29 11:51:49 +0000299 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000300 name, type);
301}
302
303/**
304 * notationDeclDebug:
305 * @ctxt: An XML parser context
306 * @name: The name of the notation
307 * @publicId: The public ID of the entity
308 * @systemId: The system ID of the entity
309 *
310 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000311 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000312static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000313notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000314 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000315{
Daniel Veillard27d88741999-05-29 11:51:49 +0000316 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000317 (char *) name, (char *) publicId, (char *) systemId);
318}
319
320/**
321 * unparsedEntityDeclDebug:
322 * @ctxt: An XML parser context
323 * @name: The name of the entity
324 * @publicId: The public ID of the entity
325 * @systemId: The system ID of the entity
326 * @notationName: the name of the notation
327 *
328 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000329 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000330static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000331unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000332 const xmlChar *publicId, const xmlChar *systemId,
333 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000334{
Daniel Veillard27d88741999-05-29 11:51:49 +0000335 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000336 (char *) name, (char *) publicId, (char *) systemId,
337 (char *) notationName);
338}
339
340/**
341 * setDocumentLocatorDebug:
342 * @ctxt: An XML parser context
343 * @loc: A SAX Locator
344 *
345 * Receive the document locator at startup, actually xmlDefaultSAXLocator
346 * Everything is available on the context, so this is useless in our case.
347 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000348static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000349setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000350{
Daniel Veillard27d88741999-05-29 11:51:49 +0000351 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000352}
353
354/**
355 * startDocumentDebug:
356 * @ctxt: An XML parser context
357 *
358 * called when the document start being processed.
359 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000360static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000361startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000362{
Daniel Veillard27d88741999-05-29 11:51:49 +0000363 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000364}
365
366/**
367 * endDocumentDebug:
368 * @ctxt: An XML parser context
369 *
370 * called when the document end has been detected.
371 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000372static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000373endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000374{
Daniel Veillard27d88741999-05-29 11:51:49 +0000375 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000376}
377
378/**
379 * startElementDebug:
380 * @ctxt: An XML parser context
381 * @name: The element name
382 *
383 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000384 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000385static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000386startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000387{
388 int i;
389
Daniel Veillard27d88741999-05-29 11:51:49 +0000390 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000391 if (atts != NULL) {
392 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000393 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000394 if (atts[i] != NULL)
395 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000396 }
397 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000398 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000399}
400
401/**
402 * endElementDebug:
403 * @ctxt: An XML parser context
404 * @name: The element name
405 *
406 * called when the end of an element has been detected.
407 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000408static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000409endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000410{
Daniel Veillard27d88741999-05-29 11:51:49 +0000411 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000412}
413
414/**
415 * charactersDebug:
416 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000417 * @ch: a xmlChar string
418 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000419 *
420 * receiving some chars from the parser.
421 * Question: how much at a time ???
422 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000423static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000424charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000425{
Daniel Veillard87b95392000-08-12 21:12:04 +0000426 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000427 int i;
428
Daniel Veillard87b95392000-08-12 21:12:04 +0000429 for (i = 0;(i<len) && (i < 30);i++)
430 output[i] = ch[i];
431 output[i] = 0;
432
433 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000434}
435
436/**
437 * referenceDebug:
438 * @ctxt: An XML parser context
439 * @name: The entity name
440 *
441 * called when an entity reference is detected.
442 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000443static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000444referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000445{
Daniel Veillard27d88741999-05-29 11:51:49 +0000446 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000447}
448
449/**
450 * ignorableWhitespaceDebug:
451 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000452 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000453 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000454 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000455 *
456 * receiving some ignorable whitespaces from the parser.
457 * Question: how much at a time ???
458 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000459static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000460ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000461{
Daniel Veillard87b95392000-08-12 21:12:04 +0000462 char output[40];
463 int i;
464
465 for (i = 0;(i<len) && (i < 30);i++)
466 output[i] = ch[i];
467 output[i] = 0;
468 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000469}
470
471/**
472 * processingInstructionDebug:
473 * @ctxt: An XML parser context
474 * @target: the target name
475 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000476 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000477 *
478 * A processing instruction has been parsed.
479 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000480static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000481processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000482 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000483{
Daniel Veillard27d88741999-05-29 11:51:49 +0000484 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000485 (char *) target, (char *) data);
486}
487
488/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000489 * cdataBlockDebug:
490 * @ctx: the user data (XML parser context)
491 * @value: The pcdata content
492 * @len: the block length
493 *
494 * called when a pcdata block has been parsed
495 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000496static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000497cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000498{
Daniel Veillard39915622000-10-15 10:06:55 +0000499 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000500 (char *) value, len);
501}
502
503/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000504 * commentDebug:
505 * @ctxt: An XML parser context
506 * @value: the comment content
507 *
508 * A comment has been parsed.
509 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000510static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000511commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000512{
Daniel Veillard27d88741999-05-29 11:51:49 +0000513 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000514}
515
516/**
517 * warningDebug:
518 * @ctxt: An XML parser context
519 * @msg: the message to display/transmit
520 * @...: extra parameters for the message display
521 *
522 * Display and format a warning messages, gives file, line, position and
523 * extra parameters.
524 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000525static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000526warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000527{
528 va_list args;
529
530 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000531 fprintf(stdout, "SAX.warning: ");
532 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000533 va_end(args);
534}
535
536/**
537 * errorDebug:
538 * @ctxt: An XML parser context
539 * @msg: the message to display/transmit
540 * @...: extra parameters for the message display
541 *
542 * Display and format a error messages, gives file, line, position and
543 * extra parameters.
544 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000545static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000546errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000547{
548 va_list args;
549
550 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000551 fprintf(stdout, "SAX.error: ");
552 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000553 va_end(args);
554}
555
556/**
557 * fatalErrorDebug:
558 * @ctxt: An XML parser context
559 * @msg: the message to display/transmit
560 * @...: extra parameters for the message display
561 *
562 * Display and format a fatalError messages, gives file, line, position and
563 * extra parameters.
564 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000565static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000566fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000567{
568 va_list args;
569
570 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000571 fprintf(stdout, "SAX.fatalError: ");
572 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000573 va_end(args);
574}
575
576xmlSAXHandler debugSAXHandlerStruct = {
577 internalSubsetDebug,
578 isStandaloneDebug,
579 hasInternalSubsetDebug,
580 hasExternalSubsetDebug,
581 resolveEntityDebug,
582 getEntityDebug,
583 entityDeclDebug,
584 notationDeclDebug,
585 attributeDeclDebug,
586 elementDeclDebug,
587 unparsedEntityDeclDebug,
588 setDocumentLocatorDebug,
589 startDocumentDebug,
590 endDocumentDebug,
591 startElementDebug,
592 endElementDebug,
593 referenceDebug,
594 charactersDebug,
595 ignorableWhitespaceDebug,
596 processingInstructionDebug,
597 commentDebug,
598 warningDebug,
599 errorDebug,
600 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000601 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000602 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000603 externalSubsetDebug,
604 1
Daniel Veillard5099ae81999-04-21 20:12:07 +0000605};
606
607xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
608
609/************************************************************************
610 * *
611 * Debug *
612 * *
613 ************************************************************************/
614
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000615static void
616parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000617 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000618
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000619 if (push) {
620 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000621
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000622 /*
623 * Empty callbacks for checking
624 */
625 f = fopen(filename, "r");
626 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000627 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000628 char chars[10];
629 xmlParserCtxtPtr ctxt;
630
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000631 ret = fread(chars, 1, 4, f);
632 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000633 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000634 chars, ret, filename);
635 while ((ret = fread(chars, 1, 3, f)) > 0) {
636 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000637 }
638 xmlParseChunk(ctxt, chars, 0, 1);
639 xmlFreeParserCtxt(ctxt);
640 }
641 fclose(f);
642 } else {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000643 xmlGenericError(xmlGenericErrorContext,
644 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000645 }
646 /*
647 * Debug callback
648 */
649 f = fopen(filename, "r");
650 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000651 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000652 char chars[10];
653 xmlParserCtxtPtr ctxt;
654
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000655 ret = fread(chars, 1, 4, f);
656 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000657 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000658 chars, ret, filename);
659 while ((ret = fread(chars, 1, 3, f)) > 0) {
660 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000661 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000662 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000663 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000664 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000665 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000666 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000667 }
668 }
669 fclose(f);
670 }
671 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000672 if (!speed) {
673 /*
674 * Empty callbacks for checking
675 */
676 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
677 if (res != 0) {
678 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
679 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000680
Daniel Veillard5e873c42000-04-12 13:27:38 +0000681 /*
682 * Debug callback
683 */
684 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
685 if (res != 0) {
686 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
687 }
688 } else {
689 /*
690 * test 100x the SAX parse
691 */
692 int i;
693
694 for (i = 0; i<100;i++)
695 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
696 if (res != 0) {
697 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
698 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000699 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000700 }
701}
702
Daniel Veillard5099ae81999-04-21 20:12:07 +0000703
704int main(int argc, char **argv) {
705 int i;
706 int files = 0;
707
708 for (i = 1; i < argc ; i++) {
709 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
710 debug++;
711 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
712 copy++;
713 else if ((!strcmp(argv[i], "-recover")) ||
714 (!strcmp(argv[i], "--recover")))
715 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000716 else if ((!strcmp(argv[i], "-push")) ||
717 (!strcmp(argv[i], "--push")))
718 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000719 else if ((!strcmp(argv[i], "-speed")) ||
720 (!strcmp(argv[i], "--speed")))
721 speed++;
Daniel Veillard5997aca2002-03-18 18:36:20 +0000722 else if ((!strcmp(argv[i], "-noent")) ||
723 (!strcmp(argv[i], "--noent")))
724 noent++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000725 }
Daniel Veillard5997aca2002-03-18 18:36:20 +0000726 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000727 for (i = 1; i < argc ; i++) {
728 if (argv[i][0] != '-') {
729 parseAndPrintFile(argv[i]);
730 files ++;
731 }
732 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000733 xmlCleanupParser();
734 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000735
736 return(0);
737}