blob: 8afafca602ab8b6eff71ce2d0aa8aef95ad1ba83 [file] [log] [blame]
Daniel Veillard5099ae81999-04-21 20:12:07 +00001/*
2 * tester.c : a small tester program for parsing using the SAX API.
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel.Veillard@w3.org
7 */
8
9#ifdef WIN32
Daniel Veillard3c558c31999-12-22 11:30:41 +000010#include "win32config.h"
Daniel Veillardc2def842000-11-07 14:21:01 +000011#undef LIBXML_DLL_IMPORT
Daniel Veillard5099ae81999-04-21 20:12:07 +000012#else
Daniel Veillard7f7d1111999-09-22 09:46:25 +000013#include "config.h"
Daniel Veillard5099ae81999-04-21 20:12:07 +000014#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000015
16#include <stdio.h>
17#include <string.h>
18#include <stdarg.h>
19
20#ifdef HAVE_SYS_TYPES_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000021#include <sys/types.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000022#endif
Daniel Veillard5099ae81999-04-21 20:12:07 +000023#ifdef HAVE_SYS_STAT_H
24#include <sys/stat.h>
25#endif
26#ifdef HAVE_FCNTL_H
27#include <fcntl.h>
28#endif
29#ifdef HAVE_UNISTD_H
30#include <unistd.h>
31#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000032#ifdef HAVE_STDLIB_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000033#include <stdlib.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000034#endif
Daniel Veillard7a66ee61999-09-26 11:31:02 +000035#ifdef HAVE_STRING_H
36#include <string.h>
37#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000038
Daniel Veillard5099ae81999-04-21 20:12:07 +000039
Daniel Veillardb71379b2000-10-09 12:30:39 +000040#include <libxml/xmlerror.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000041#include <libxml/parser.h>
42#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
43#include <libxml/tree.h>
44#include <libxml/debugXML.h>
45#include <libxml/xmlmemory.h>
Daniel Veillard5099ae81999-04-21 20:12:07 +000046
47static int debug = 0;
48static int copy = 0;
49static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000050static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000051static int speed = 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 Veillard56a4cb82001-03-24 17:00:36 +000080 NULL /* externalSubset; */
Daniel Veillard5099ae81999-04-21 20:12:07 +000081};
82
83xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000084extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000085
Daniel Veillard5099ae81999-04-21 20:12:07 +000086/************************************************************************
87 * *
88 * Debug Handlers *
89 * *
90 ************************************************************************/
91
92/**
93 * isStandaloneDebug:
94 * @ctxt: An XML parser context
95 *
96 * Is this document tagged standalone ?
97 *
98 * Returns 1 if true
99 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000100static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000101isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000102{
Daniel Veillard27d88741999-05-29 11:51:49 +0000103 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000104 return(0);
105}
106
107/**
108 * hasInternalSubsetDebug:
109 * @ctxt: An XML parser context
110 *
111 * Does this document has an internal subset
112 *
113 * Returns 1 if true
114 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000115static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000116hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000117{
Daniel Veillard27d88741999-05-29 11:51:49 +0000118 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000119 return(0);
120}
121
122/**
123 * hasExternalSubsetDebug:
124 * @ctxt: An XML parser context
125 *
126 * Does this document has an external subset
127 *
128 * Returns 1 if true
129 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000130static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000131hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000132{
Daniel Veillard27d88741999-05-29 11:51:49 +0000133 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000134 return(0);
135}
136
137/**
Daniel Veillard06047432000-04-24 11:33:38 +0000138 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000139 * @ctxt: An XML parser context
140 *
141 * Does this document has an internal subset
142 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000143static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000144internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000145 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000146{
Daniel Veillard808a3f12000-08-17 13:50:51 +0000147 fprintf(stdout, "SAX.internalSubset(%s,", name);
148 if (ExternalID == NULL)
149 fprintf(stdout, " ,");
150 else
151 fprintf(stdout, " %s,", ExternalID);
152 if (SystemID == NULL)
153 fprintf(stdout, " )\n");
154 else
155 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000156}
157
158/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000159 * externalSubsetDebug:
160 * @ctxt: An XML parser context
161 *
162 * Does this document has an external subset
163 */
164static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000165externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000166 const xmlChar *ExternalID, const xmlChar *SystemID)
167{
168 fprintf(stdout, "SAX.externalSubset(%s,", name);
169 if (ExternalID == NULL)
170 fprintf(stdout, " ,");
171 else
172 fprintf(stdout, " %s,", ExternalID);
173 if (SystemID == NULL)
174 fprintf(stdout, " )\n");
175 else
176 fprintf(stdout, " %s)\n", SystemID);
177}
178
179/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000180 * resolveEntityDebug:
181 * @ctxt: An XML parser context
182 * @publicId: The public ID of the entity
183 * @systemId: The system ID of the entity
184 *
185 * Special entity resolver, better left to the parser, it has
186 * more context than the application layer.
187 * The default behaviour is to NOT resolve the entities, in that case
188 * the ENTITY_REF nodes are built in the structure (and the parameter
189 * values).
190 *
191 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
192 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000193static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000194resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000195{
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000196 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000197
Daniel Veillard14fff061999-06-22 21:49:07 +0000198
199 fprintf(stdout, "SAX.resolveEntity(");
200 if (publicId != NULL)
201 fprintf(stdout, "%s", (char *)publicId);
202 else
203 fprintf(stdout, " ");
204 if (systemId != NULL)
205 fprintf(stdout, ", %s)\n", (char *)systemId);
206 else
207 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000208/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000209 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000210 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000211 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000212 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000213 return(NULL);
214}
215
216/**
217 * getEntityDebug:
218 * @ctxt: An XML parser context
219 * @name: The entity name
220 *
221 * Get an entity by name
222 *
223 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
224 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000225static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000226getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000227{
Daniel Veillard27d88741999-05-29 11:51:49 +0000228 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000229 return(NULL);
230}
231
Daniel Veillardb05deb71999-08-10 19:04:08 +0000232/**
233 * getParameterEntityDebug:
234 * @ctxt: An XML parser context
235 * @name: The entity name
236 *
237 * Get a parameter entity by name
238 *
239 * Returns the xmlParserInputPtr
240 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000241static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000242getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000243{
244 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
245 return(NULL);
246}
247
Daniel Veillard5099ae81999-04-21 20:12:07 +0000248
249/**
250 * entityDeclDebug:
251 * @ctxt: An XML parser context
252 * @name: the entity name
253 * @type: the entity type
254 * @publicId: The public ID of the entity
255 * @systemId: The system ID of the entity
256 * @content: the entity value (without processing).
257 *
258 * An entity definition has been parsed
259 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000260static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000261entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000262 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000263{
Daniel Veillard27d88741999-05-29 11:51:49 +0000264 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000265 name, type, publicId, systemId, content);
266}
267
268/**
269 * attributeDeclDebug:
270 * @ctxt: An XML parser context
271 * @name: the attribute name
272 * @type: the attribute type
273 *
274 * An attribute definition has been parsed
275 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000276static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000277attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000278 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000279 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000280{
Daniel Veillard7e99c632000-10-06 12:59:53 +0000281 if (defaultValue == NULL)
282 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
283 elem, name, type, def);
284 else
285 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000286 elem, name, type, def, defaultValue);
287}
288
289/**
290 * elementDeclDebug:
291 * @ctxt: An XML parser context
292 * @name: the element name
293 * @type: the element type
294 * @content: the element value (without processing).
295 *
296 * An element definition has been parsed
297 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000298static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000299elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
300 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000301{
Daniel Veillard27d88741999-05-29 11:51:49 +0000302 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000303 name, type);
304}
305
306/**
307 * notationDeclDebug:
308 * @ctxt: An XML parser context
309 * @name: The name of the notation
310 * @publicId: The public ID of the entity
311 * @systemId: The system ID of the entity
312 *
313 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000314 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000315static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000316notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000317 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000318{
Daniel Veillard27d88741999-05-29 11:51:49 +0000319 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000320 (char *) name, (char *) publicId, (char *) systemId);
321}
322
323/**
324 * unparsedEntityDeclDebug:
325 * @ctxt: An XML parser context
326 * @name: The name of the entity
327 * @publicId: The public ID of the entity
328 * @systemId: The system ID of the entity
329 * @notationName: the name of the notation
330 *
331 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000332 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000333static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000334unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000335 const xmlChar *publicId, const xmlChar *systemId,
336 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000337{
Daniel Veillard27d88741999-05-29 11:51:49 +0000338 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000339 (char *) name, (char *) publicId, (char *) systemId,
340 (char *) notationName);
341}
342
343/**
344 * setDocumentLocatorDebug:
345 * @ctxt: An XML parser context
346 * @loc: A SAX Locator
347 *
348 * Receive the document locator at startup, actually xmlDefaultSAXLocator
349 * Everything is available on the context, so this is useless in our case.
350 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000351static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000352setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000353{
Daniel Veillard27d88741999-05-29 11:51:49 +0000354 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000355}
356
357/**
358 * startDocumentDebug:
359 * @ctxt: An XML parser context
360 *
361 * called when the document start being processed.
362 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000363static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000364startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000365{
Daniel Veillard27d88741999-05-29 11:51:49 +0000366 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000367}
368
369/**
370 * endDocumentDebug:
371 * @ctxt: An XML parser context
372 *
373 * called when the document end has been detected.
374 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000375static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000376endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000377{
Daniel Veillard27d88741999-05-29 11:51:49 +0000378 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000379}
380
381/**
382 * startElementDebug:
383 * @ctxt: An XML parser context
384 * @name: The element name
385 *
386 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000387 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000388static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000389startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000390{
391 int i;
392
Daniel Veillard27d88741999-05-29 11:51:49 +0000393 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000394 if (atts != NULL) {
395 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000396 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000397 if (atts[i] != NULL)
398 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000399 }
400 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000401 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000402}
403
404/**
405 * endElementDebug:
406 * @ctxt: An XML parser context
407 * @name: The element name
408 *
409 * called when the end of an element has been detected.
410 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000411static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000412endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000413{
Daniel Veillard27d88741999-05-29 11:51:49 +0000414 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000415}
416
417/**
418 * charactersDebug:
419 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000420 * @ch: a xmlChar string
421 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000422 *
423 * receiving some chars from the parser.
424 * Question: how much at a time ???
425 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000426static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000427charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000428{
Daniel Veillard87b95392000-08-12 21:12:04 +0000429 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000430 int i;
431
Daniel Veillard87b95392000-08-12 21:12:04 +0000432 for (i = 0;(i<len) && (i < 30);i++)
433 output[i] = ch[i];
434 output[i] = 0;
435
436 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000437}
438
439/**
440 * referenceDebug:
441 * @ctxt: An XML parser context
442 * @name: The entity name
443 *
444 * called when an entity reference is detected.
445 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000446static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000447referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000448{
Daniel Veillard27d88741999-05-29 11:51:49 +0000449 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000450}
451
452/**
453 * ignorableWhitespaceDebug:
454 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000455 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000456 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000457 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000458 *
459 * receiving some ignorable whitespaces from the parser.
460 * Question: how much at a time ???
461 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000462static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000463ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000464{
Daniel Veillard87b95392000-08-12 21:12:04 +0000465 char output[40];
466 int i;
467
468 for (i = 0;(i<len) && (i < 30);i++)
469 output[i] = ch[i];
470 output[i] = 0;
471 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000472}
473
474/**
475 * processingInstructionDebug:
476 * @ctxt: An XML parser context
477 * @target: the target name
478 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000479 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000480 *
481 * A processing instruction has been parsed.
482 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000483static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000484processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000485 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000486{
Daniel Veillard27d88741999-05-29 11:51:49 +0000487 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000488 (char *) target, (char *) data);
489}
490
491/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000492 * cdataBlockDebug:
493 * @ctx: the user data (XML parser context)
494 * @value: The pcdata content
495 * @len: the block length
496 *
497 * called when a pcdata block has been parsed
498 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000499static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000500cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000501{
Daniel Veillard39915622000-10-15 10:06:55 +0000502 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000503 (char *) value, len);
504}
505
506/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000507 * commentDebug:
508 * @ctxt: An XML parser context
509 * @value: the comment content
510 *
511 * A comment has been parsed.
512 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000513static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000514commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000515{
Daniel Veillard27d88741999-05-29 11:51:49 +0000516 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000517}
518
519/**
520 * warningDebug:
521 * @ctxt: An XML parser context
522 * @msg: the message to display/transmit
523 * @...: extra parameters for the message display
524 *
525 * Display and format a warning messages, gives file, line, position and
526 * extra parameters.
527 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000528static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000529warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000530{
531 va_list args;
532
533 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000534 fprintf(stdout, "SAX.warning: ");
535 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000536 va_end(args);
537}
538
539/**
540 * errorDebug:
541 * @ctxt: An XML parser context
542 * @msg: the message to display/transmit
543 * @...: extra parameters for the message display
544 *
545 * Display and format a error messages, gives file, line, position and
546 * extra parameters.
547 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000548static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000549errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000550{
551 va_list args;
552
553 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000554 fprintf(stdout, "SAX.error: ");
555 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000556 va_end(args);
557}
558
559/**
560 * fatalErrorDebug:
561 * @ctxt: An XML parser context
562 * @msg: the message to display/transmit
563 * @...: extra parameters for the message display
564 *
565 * Display and format a fatalError messages, gives file, line, position and
566 * extra parameters.
567 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000568static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000569fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000570{
571 va_list args;
572
573 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000574 fprintf(stdout, "SAX.fatalError: ");
575 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000576 va_end(args);
577}
578
579xmlSAXHandler debugSAXHandlerStruct = {
580 internalSubsetDebug,
581 isStandaloneDebug,
582 hasInternalSubsetDebug,
583 hasExternalSubsetDebug,
584 resolveEntityDebug,
585 getEntityDebug,
586 entityDeclDebug,
587 notationDeclDebug,
588 attributeDeclDebug,
589 elementDeclDebug,
590 unparsedEntityDeclDebug,
591 setDocumentLocatorDebug,
592 startDocumentDebug,
593 endDocumentDebug,
594 startElementDebug,
595 endElementDebug,
596 referenceDebug,
597 charactersDebug,
598 ignorableWhitespaceDebug,
599 processingInstructionDebug,
600 commentDebug,
601 warningDebug,
602 errorDebug,
603 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000604 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000605 cdataBlockDebug,
606 externalSubsetDebug
Daniel Veillard5099ae81999-04-21 20:12:07 +0000607};
608
609xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
610
611/************************************************************************
612 * *
613 * Debug *
614 * *
615 ************************************************************************/
616
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000617static void
618parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000619 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000620
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000621 if (push) {
622 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000623
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000624 /*
625 * Empty callbacks for checking
626 */
627 f = fopen(filename, "r");
628 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000629 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000630 char chars[10];
631 xmlParserCtxtPtr ctxt;
632
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000633 ret = fread(chars, 1, 4, f);
634 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000635 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000636 chars, ret, filename);
637 while ((ret = fread(chars, 1, 3, f)) > 0) {
638 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000639 }
640 xmlParseChunk(ctxt, chars, 0, 1);
641 xmlFreeParserCtxt(ctxt);
642 }
643 fclose(f);
644 } else {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000645 xmlGenericError(xmlGenericErrorContext,
646 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000647 }
648 /*
649 * Debug callback
650 */
651 f = fopen(filename, "r");
652 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000653 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000654 char chars[10];
655 xmlParserCtxtPtr ctxt;
656
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000657 ret = fread(chars, 1, 4, f);
658 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000659 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000660 chars, ret, filename);
661 while ((ret = fread(chars, 1, 3, f)) > 0) {
662 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000663 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000664 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000665 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000666 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000667 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000668 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000669 }
670 }
671 fclose(f);
672 }
673 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000674 if (!speed) {
675 /*
676 * Empty callbacks for checking
677 */
678 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
679 if (res != 0) {
680 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
681 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000682
Daniel Veillard5e873c42000-04-12 13:27:38 +0000683 /*
684 * Debug callback
685 */
686 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
687 if (res != 0) {
688 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
689 }
690 } else {
691 /*
692 * test 100x the SAX parse
693 */
694 int i;
695
696 for (i = 0; i<100;i++)
697 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
698 if (res != 0) {
699 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
700 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000701 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000702 }
703}
704
Daniel Veillard5099ae81999-04-21 20:12:07 +0000705
706int main(int argc, char **argv) {
707 int i;
708 int files = 0;
709
710 for (i = 1; i < argc ; i++) {
711 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
712 debug++;
713 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
714 copy++;
715 else if ((!strcmp(argv[i], "-recover")) ||
716 (!strcmp(argv[i], "--recover")))
717 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000718 else if ((!strcmp(argv[i], "-push")) ||
719 (!strcmp(argv[i], "--push")))
720 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000721 else if ((!strcmp(argv[i], "-speed")) ||
722 (!strcmp(argv[i], "--speed")))
723 speed++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000724 }
725 for (i = 1; i < argc ; i++) {
726 if (argv[i][0] != '-') {
727 parseAndPrintFile(argv[i]);
728 files ++;
729 }
730 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000731 xmlCleanupParser();
732 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000733
734 return(0);
735}