blob: a6a0d799dd20e8ec38a918a88b10df808e873c75 [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 *
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 Veillard5099ae81999-04-21 20:12:07 +000047
48xmlSAXHandler emptySAXHandlerStruct = {
49 NULL, /* internalSubset */
50 NULL, /* isStandalone */
51 NULL, /* hasInternalSubset */
52 NULL, /* hasExternalSubset */
53 NULL, /* resolveEntity */
54 NULL, /* getEntity */
55 NULL, /* entityDecl */
56 NULL, /* notationDecl */
57 NULL, /* attributeDecl */
58 NULL, /* elementDecl */
59 NULL, /* unparsedEntityDecl */
60 NULL, /* setDocumentLocator */
61 NULL, /* startDocument */
62 NULL, /* endDocument */
63 NULL, /* startElement */
64 NULL, /* endElement */
65 NULL, /* reference */
66 NULL, /* characters */
67 NULL, /* ignorableWhitespace */
68 NULL, /* processingInstruction */
69 NULL, /* comment */
70 NULL, /* xmlParserWarning */
71 NULL, /* xmlParserError */
72 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000073 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000074 NULL, /* cdataBlock; */
Daniel Veillardd0463562001-10-13 09:15:48 +000075 NULL, /* externalSubset; */
76 1
Daniel Veillard5099ae81999-04-21 20:12:07 +000077};
78
79xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000080extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000081
Daniel Veillard5099ae81999-04-21 20:12:07 +000082/************************************************************************
83 * *
84 * Debug Handlers *
85 * *
86 ************************************************************************/
87
88/**
89 * isStandaloneDebug:
90 * @ctxt: An XML parser context
91 *
92 * Is this document tagged standalone ?
93 *
94 * Returns 1 if true
95 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000096static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +000097isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +000098{
Daniel Veillard27d88741999-05-29 11:51:49 +000099 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000100 return(0);
101}
102
103/**
104 * hasInternalSubsetDebug:
105 * @ctxt: An XML parser context
106 *
107 * Does this document has an internal subset
108 *
109 * Returns 1 if true
110 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000111static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000112hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000113{
Daniel Veillard27d88741999-05-29 11:51:49 +0000114 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000115 return(0);
116}
117
118/**
119 * hasExternalSubsetDebug:
120 * @ctxt: An XML parser context
121 *
122 * Does this document has an external subset
123 *
124 * Returns 1 if true
125 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000126static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000127hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000128{
Daniel Veillard27d88741999-05-29 11:51:49 +0000129 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000130 return(0);
131}
132
133/**
Daniel Veillard06047432000-04-24 11:33:38 +0000134 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000135 * @ctxt: An XML parser context
136 *
137 * Does this document has an internal subset
138 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000139static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000140internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000141 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000142{
Daniel Veillard808a3f12000-08-17 13:50:51 +0000143 fprintf(stdout, "SAX.internalSubset(%s,", name);
144 if (ExternalID == NULL)
145 fprintf(stdout, " ,");
146 else
147 fprintf(stdout, " %s,", ExternalID);
148 if (SystemID == NULL)
149 fprintf(stdout, " )\n");
150 else
151 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000152}
153
154/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000155 * externalSubsetDebug:
156 * @ctxt: An XML parser context
157 *
158 * Does this document has an external subset
159 */
160static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000161externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000162 const xmlChar *ExternalID, const xmlChar *SystemID)
163{
164 fprintf(stdout, "SAX.externalSubset(%s,", name);
165 if (ExternalID == NULL)
166 fprintf(stdout, " ,");
167 else
168 fprintf(stdout, " %s,", ExternalID);
169 if (SystemID == NULL)
170 fprintf(stdout, " )\n");
171 else
172 fprintf(stdout, " %s)\n", SystemID);
173}
174
175/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000176 * resolveEntityDebug:
177 * @ctxt: An XML parser context
178 * @publicId: The public ID of the entity
179 * @systemId: The system ID of the entity
180 *
181 * Special entity resolver, better left to the parser, it has
182 * more context than the application layer.
183 * The default behaviour is to NOT resolve the entities, in that case
184 * the ENTITY_REF nodes are built in the structure (and the parameter
185 * values).
186 *
187 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
188 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000189static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000190resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000191{
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000192 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000193
Daniel Veillard14fff061999-06-22 21:49:07 +0000194
195 fprintf(stdout, "SAX.resolveEntity(");
196 if (publicId != NULL)
197 fprintf(stdout, "%s", (char *)publicId);
198 else
199 fprintf(stdout, " ");
200 if (systemId != NULL)
201 fprintf(stdout, ", %s)\n", (char *)systemId);
202 else
203 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000204/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000205 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000206 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000207 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000208 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000209 return(NULL);
210}
211
212/**
213 * getEntityDebug:
214 * @ctxt: An XML parser context
215 * @name: The entity name
216 *
217 * Get an entity by name
218 *
219 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
220 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000221static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000222getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000223{
Daniel Veillard27d88741999-05-29 11:51:49 +0000224 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000225 return(NULL);
226}
227
Daniel Veillardb05deb71999-08-10 19:04:08 +0000228/**
229 * getParameterEntityDebug:
230 * @ctxt: An XML parser context
231 * @name: The entity name
232 *
233 * Get a parameter entity by name
234 *
235 * Returns the xmlParserInputPtr
236 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000237static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000238getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000239{
240 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
241 return(NULL);
242}
243
Daniel Veillard5099ae81999-04-21 20:12:07 +0000244
245/**
246 * entityDeclDebug:
247 * @ctxt: An XML parser context
248 * @name: the entity name
249 * @type: the entity type
250 * @publicId: The public ID of the entity
251 * @systemId: The system ID of the entity
252 * @content: the entity value (without processing).
253 *
254 * An entity definition has been parsed
255 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000256static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000257entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000258 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000259{
Daniel Veillard27d88741999-05-29 11:51:49 +0000260 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000261 name, type, publicId, systemId, content);
262}
263
264/**
265 * attributeDeclDebug:
266 * @ctxt: An XML parser context
267 * @name: the attribute name
268 * @type: the attribute type
269 *
270 * An attribute definition has been parsed
271 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000272static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000273attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000274 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000275 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000276{
Daniel Veillard7e99c632000-10-06 12:59:53 +0000277 if (defaultValue == NULL)
278 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
279 elem, name, type, def);
280 else
281 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000282 elem, name, type, def, defaultValue);
283}
284
285/**
286 * elementDeclDebug:
287 * @ctxt: An XML parser context
288 * @name: the element name
289 * @type: the element type
290 * @content: the element value (without processing).
291 *
292 * An element definition has been parsed
293 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000294static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000295elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
296 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000297{
Daniel Veillard27d88741999-05-29 11:51:49 +0000298 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000299 name, type);
300}
301
302/**
303 * notationDeclDebug:
304 * @ctxt: An XML parser context
305 * @name: The name of the notation
306 * @publicId: The public ID of the entity
307 * @systemId: The system ID of the entity
308 *
309 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000310 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000311static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000312notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000313 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000314{
Daniel Veillard27d88741999-05-29 11:51:49 +0000315 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000316 (char *) name, (char *) publicId, (char *) systemId);
317}
318
319/**
320 * unparsedEntityDeclDebug:
321 * @ctxt: An XML parser context
322 * @name: The name of the entity
323 * @publicId: The public ID of the entity
324 * @systemId: The system ID of the entity
325 * @notationName: the name of the notation
326 *
327 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000328 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000329static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000330unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000331 const xmlChar *publicId, const xmlChar *systemId,
332 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000333{
Daniel Veillard27d88741999-05-29 11:51:49 +0000334 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000335 (char *) name, (char *) publicId, (char *) systemId,
336 (char *) notationName);
337}
338
339/**
340 * setDocumentLocatorDebug:
341 * @ctxt: An XML parser context
342 * @loc: A SAX Locator
343 *
344 * Receive the document locator at startup, actually xmlDefaultSAXLocator
345 * Everything is available on the context, so this is useless in our case.
346 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000347static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000348setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000349{
Daniel Veillard27d88741999-05-29 11:51:49 +0000350 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000351}
352
353/**
354 * startDocumentDebug:
355 * @ctxt: An XML parser context
356 *
357 * called when the document start being processed.
358 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000359static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000360startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000361{
Daniel Veillard27d88741999-05-29 11:51:49 +0000362 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000363}
364
365/**
366 * endDocumentDebug:
367 * @ctxt: An XML parser context
368 *
369 * called when the document end has been detected.
370 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000371static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000372endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000373{
Daniel Veillard27d88741999-05-29 11:51:49 +0000374 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000375}
376
377/**
378 * startElementDebug:
379 * @ctxt: An XML parser context
380 * @name: The element name
381 *
382 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000383 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000384static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000385startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000386{
387 int i;
388
Daniel Veillard27d88741999-05-29 11:51:49 +0000389 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000390 if (atts != NULL) {
391 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000392 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000393 if (atts[i] != NULL)
394 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000395 }
396 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000397 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000398}
399
400/**
401 * endElementDebug:
402 * @ctxt: An XML parser context
403 * @name: The element name
404 *
405 * called when the end of an element has been detected.
406 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000407static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000408endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000409{
Daniel Veillard27d88741999-05-29 11:51:49 +0000410 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000411}
412
413/**
414 * charactersDebug:
415 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000416 * @ch: a xmlChar string
417 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000418 *
419 * receiving some chars from the parser.
420 * Question: how much at a time ???
421 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000422static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000423charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000424{
Daniel Veillard87b95392000-08-12 21:12:04 +0000425 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000426 int i;
427
Daniel Veillard87b95392000-08-12 21:12:04 +0000428 for (i = 0;(i<len) && (i < 30);i++)
429 output[i] = ch[i];
430 output[i] = 0;
431
432 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000433}
434
435/**
436 * referenceDebug:
437 * @ctxt: An XML parser context
438 * @name: The entity name
439 *
440 * called when an entity reference is detected.
441 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000442static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000443referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000444{
Daniel Veillard27d88741999-05-29 11:51:49 +0000445 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000446}
447
448/**
449 * ignorableWhitespaceDebug:
450 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000451 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000452 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000453 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000454 *
455 * receiving some ignorable whitespaces from the parser.
456 * Question: how much at a time ???
457 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000458static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000459ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000460{
Daniel Veillard87b95392000-08-12 21:12:04 +0000461 char output[40];
462 int i;
463
464 for (i = 0;(i<len) && (i < 30);i++)
465 output[i] = ch[i];
466 output[i] = 0;
467 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000468}
469
470/**
471 * processingInstructionDebug:
472 * @ctxt: An XML parser context
473 * @target: the target name
474 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000475 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000476 *
477 * A processing instruction has been parsed.
478 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000479static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000480processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000481 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000482{
Daniel Veillard27d88741999-05-29 11:51:49 +0000483 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000484 (char *) target, (char *) data);
485}
486
487/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000488 * cdataBlockDebug:
489 * @ctx: the user data (XML parser context)
490 * @value: The pcdata content
491 * @len: the block length
492 *
493 * called when a pcdata block has been parsed
494 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000495static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000496cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000497{
Daniel Veillard39915622000-10-15 10:06:55 +0000498 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000499 (char *) value, len);
500}
501
502/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000503 * commentDebug:
504 * @ctxt: An XML parser context
505 * @value: the comment content
506 *
507 * A comment has been parsed.
508 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000509static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000510commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000511{
Daniel Veillard27d88741999-05-29 11:51:49 +0000512 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000513}
514
515/**
516 * warningDebug:
517 * @ctxt: An XML parser context
518 * @msg: the message to display/transmit
519 * @...: extra parameters for the message display
520 *
521 * Display and format a warning messages, gives file, line, position and
522 * extra parameters.
523 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000524static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000525warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000526{
527 va_list args;
528
529 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000530 fprintf(stdout, "SAX.warning: ");
531 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000532 va_end(args);
533}
534
535/**
536 * errorDebug:
537 * @ctxt: An XML parser context
538 * @msg: the message to display/transmit
539 * @...: extra parameters for the message display
540 *
541 * Display and format a error messages, gives file, line, position and
542 * extra parameters.
543 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000544static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000545errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000546{
547 va_list args;
548
549 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000550 fprintf(stdout, "SAX.error: ");
551 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000552 va_end(args);
553}
554
555/**
556 * fatalErrorDebug:
557 * @ctxt: An XML parser context
558 * @msg: the message to display/transmit
559 * @...: extra parameters for the message display
560 *
561 * Display and format a fatalError messages, gives file, line, position and
562 * extra parameters.
563 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000564static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000565fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000566{
567 va_list args;
568
569 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000570 fprintf(stdout, "SAX.fatalError: ");
571 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000572 va_end(args);
573}
574
575xmlSAXHandler debugSAXHandlerStruct = {
576 internalSubsetDebug,
577 isStandaloneDebug,
578 hasInternalSubsetDebug,
579 hasExternalSubsetDebug,
580 resolveEntityDebug,
581 getEntityDebug,
582 entityDeclDebug,
583 notationDeclDebug,
584 attributeDeclDebug,
585 elementDeclDebug,
586 unparsedEntityDeclDebug,
587 setDocumentLocatorDebug,
588 startDocumentDebug,
589 endDocumentDebug,
590 startElementDebug,
591 endElementDebug,
592 referenceDebug,
593 charactersDebug,
594 ignorableWhitespaceDebug,
595 processingInstructionDebug,
596 commentDebug,
597 warningDebug,
598 errorDebug,
599 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000600 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000601 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000602 externalSubsetDebug,
603 1
Daniel Veillard5099ae81999-04-21 20:12:07 +0000604};
605
606xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
607
608/************************************************************************
609 * *
610 * Debug *
611 * *
612 ************************************************************************/
613
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000614static void
615parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000616 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000617
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000618 if (push) {
619 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000620
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000621 /*
622 * Empty callbacks for checking
623 */
624 f = fopen(filename, "r");
625 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000626 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000627 char chars[10];
628 xmlParserCtxtPtr ctxt;
629
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000630 ret = fread(chars, 1, 4, f);
631 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000632 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000633 chars, ret, filename);
634 while ((ret = fread(chars, 1, 3, f)) > 0) {
635 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000636 }
637 xmlParseChunk(ctxt, chars, 0, 1);
638 xmlFreeParserCtxt(ctxt);
639 }
640 fclose(f);
641 } else {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000642 xmlGenericError(xmlGenericErrorContext,
643 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000644 }
645 /*
646 * Debug callback
647 */
648 f = fopen(filename, "r");
649 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000650 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000651 char chars[10];
652 xmlParserCtxtPtr ctxt;
653
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000654 ret = fread(chars, 1, 4, f);
655 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000656 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000657 chars, ret, filename);
658 while ((ret = fread(chars, 1, 3, f)) > 0) {
659 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000660 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000661 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000662 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000663 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000664 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000665 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000666 }
667 }
668 fclose(f);
669 }
670 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000671 if (!speed) {
672 /*
673 * Empty callbacks for checking
674 */
675 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
676 if (res != 0) {
677 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
678 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000679
Daniel Veillard5e873c42000-04-12 13:27:38 +0000680 /*
681 * Debug callback
682 */
683 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
684 if (res != 0) {
685 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
686 }
687 } else {
688 /*
689 * test 100x the SAX parse
690 */
691 int i;
692
693 for (i = 0; i<100;i++)
694 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
695 if (res != 0) {
696 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
697 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000698 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000699 }
700}
701
Daniel Veillard5099ae81999-04-21 20:12:07 +0000702
703int main(int argc, char **argv) {
704 int i;
705 int files = 0;
706
707 for (i = 1; i < argc ; i++) {
708 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
709 debug++;
710 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
711 copy++;
712 else if ((!strcmp(argv[i], "-recover")) ||
713 (!strcmp(argv[i], "--recover")))
714 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000715 else if ((!strcmp(argv[i], "-push")) ||
716 (!strcmp(argv[i], "--push")))
717 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000718 else if ((!strcmp(argv[i], "-speed")) ||
719 (!strcmp(argv[i], "--speed")))
720 speed++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000721 }
722 for (i = 1; i < argc ; i++) {
723 if (argv[i][0] != '-') {
724 parseAndPrintFile(argv[i]);
725 files ++;
726 }
727 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000728 xmlCleanupParser();
729 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000730
731 return(0);
732}