blob: 47b100a0f75ee21e2dda4a68569cb57b5f3b0435 [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 Veillardb71379b2000-10-09 12:30:39 +000034#include <libxml/xmlerror.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000035#include <libxml/parser.h>
36#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
37#include <libxml/tree.h>
38#include <libxml/debugXML.h>
39#include <libxml/xmlmemory.h>
Daniel Veillard5099ae81999-04-21 20:12:07 +000040
41static int debug = 0;
42static int copy = 0;
43static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000044static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000045static int speed = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000046
47xmlSAXHandler emptySAXHandlerStruct = {
48 NULL, /* internalSubset */
49 NULL, /* isStandalone */
50 NULL, /* hasInternalSubset */
51 NULL, /* hasExternalSubset */
52 NULL, /* resolveEntity */
53 NULL, /* getEntity */
54 NULL, /* entityDecl */
55 NULL, /* notationDecl */
56 NULL, /* attributeDecl */
57 NULL, /* elementDecl */
58 NULL, /* unparsedEntityDecl */
59 NULL, /* setDocumentLocator */
60 NULL, /* startDocument */
61 NULL, /* endDocument */
62 NULL, /* startElement */
63 NULL, /* endElement */
64 NULL, /* reference */
65 NULL, /* characters */
66 NULL, /* ignorableWhitespace */
67 NULL, /* processingInstruction */
68 NULL, /* comment */
69 NULL, /* xmlParserWarning */
70 NULL, /* xmlParserError */
71 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000072 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000073 NULL, /* cdataBlock; */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000074 NULL /* externalSubset; */
Daniel Veillard5099ae81999-04-21 20:12:07 +000075};
76
77xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000078extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000079
Daniel Veillard5099ae81999-04-21 20:12:07 +000080/************************************************************************
81 * *
82 * Debug Handlers *
83 * *
84 ************************************************************************/
85
86/**
87 * isStandaloneDebug:
88 * @ctxt: An XML parser context
89 *
90 * Is this document tagged standalone ?
91 *
92 * Returns 1 if true
93 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000094static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +000095isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +000096{
Daniel Veillard27d88741999-05-29 11:51:49 +000097 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +000098 return(0);
99}
100
101/**
102 * hasInternalSubsetDebug:
103 * @ctxt: An XML parser context
104 *
105 * Does this document has an internal subset
106 *
107 * Returns 1 if true
108 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000109static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000110hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000111{
Daniel Veillard27d88741999-05-29 11:51:49 +0000112 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000113 return(0);
114}
115
116/**
117 * hasExternalSubsetDebug:
118 * @ctxt: An XML parser context
119 *
120 * Does this document has an external subset
121 *
122 * Returns 1 if true
123 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000124static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000125hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000126{
Daniel Veillard27d88741999-05-29 11:51:49 +0000127 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000128 return(0);
129}
130
131/**
Daniel Veillard06047432000-04-24 11:33:38 +0000132 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000133 * @ctxt: An XML parser context
134 *
135 * Does this document has an internal subset
136 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000137static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000138internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000139 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000140{
Daniel Veillard808a3f12000-08-17 13:50:51 +0000141 fprintf(stdout, "SAX.internalSubset(%s,", name);
142 if (ExternalID == NULL)
143 fprintf(stdout, " ,");
144 else
145 fprintf(stdout, " %s,", ExternalID);
146 if (SystemID == NULL)
147 fprintf(stdout, " )\n");
148 else
149 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000150}
151
152/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000153 * externalSubsetDebug:
154 * @ctxt: An XML parser context
155 *
156 * Does this document has an external subset
157 */
158static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000159externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000160 const xmlChar *ExternalID, const xmlChar *SystemID)
161{
162 fprintf(stdout, "SAX.externalSubset(%s,", name);
163 if (ExternalID == NULL)
164 fprintf(stdout, " ,");
165 else
166 fprintf(stdout, " %s,", ExternalID);
167 if (SystemID == NULL)
168 fprintf(stdout, " )\n");
169 else
170 fprintf(stdout, " %s)\n", SystemID);
171}
172
173/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000174 * resolveEntityDebug:
175 * @ctxt: An XML parser context
176 * @publicId: The public ID of the entity
177 * @systemId: The system ID of the entity
178 *
179 * Special entity resolver, better left to the parser, it has
180 * more context than the application layer.
181 * The default behaviour is to NOT resolve the entities, in that case
182 * the ENTITY_REF nodes are built in the structure (and the parameter
183 * values).
184 *
185 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
186 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000187static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000188resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000189{
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000190 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000191
Daniel Veillard14fff061999-06-22 21:49:07 +0000192
193 fprintf(stdout, "SAX.resolveEntity(");
194 if (publicId != NULL)
195 fprintf(stdout, "%s", (char *)publicId);
196 else
197 fprintf(stdout, " ");
198 if (systemId != NULL)
199 fprintf(stdout, ", %s)\n", (char *)systemId);
200 else
201 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000202/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000203 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000204 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000205 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000206 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000207 return(NULL);
208}
209
210/**
211 * getEntityDebug:
212 * @ctxt: An XML parser context
213 * @name: The entity name
214 *
215 * Get an entity by name
216 *
217 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
218 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000219static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000220getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000221{
Daniel Veillard27d88741999-05-29 11:51:49 +0000222 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000223 return(NULL);
224}
225
Daniel Veillardb05deb71999-08-10 19:04:08 +0000226/**
227 * getParameterEntityDebug:
228 * @ctxt: An XML parser context
229 * @name: The entity name
230 *
231 * Get a parameter entity by name
232 *
233 * Returns the xmlParserInputPtr
234 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000235static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000236getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000237{
238 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
239 return(NULL);
240}
241
Daniel Veillard5099ae81999-04-21 20:12:07 +0000242
243/**
244 * entityDeclDebug:
245 * @ctxt: An XML parser context
246 * @name: the entity name
247 * @type: the entity type
248 * @publicId: The public ID of the entity
249 * @systemId: The system ID of the entity
250 * @content: the entity value (without processing).
251 *
252 * An entity definition has been parsed
253 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000254static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000255entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000256 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000257{
Daniel Veillard27d88741999-05-29 11:51:49 +0000258 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000259 name, type, publicId, systemId, content);
260}
261
262/**
263 * attributeDeclDebug:
264 * @ctxt: An XML parser context
265 * @name: the attribute name
266 * @type: the attribute type
267 *
268 * An attribute definition has been parsed
269 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000270static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000271attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000272 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000273 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000274{
Daniel Veillard7e99c632000-10-06 12:59:53 +0000275 if (defaultValue == NULL)
276 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
277 elem, name, type, def);
278 else
279 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000280 elem, name, type, def, defaultValue);
281}
282
283/**
284 * elementDeclDebug:
285 * @ctxt: An XML parser context
286 * @name: the element name
287 * @type: the element type
288 * @content: the element value (without processing).
289 *
290 * An element definition has been parsed
291 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000292static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000293elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
294 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000295{
Daniel Veillard27d88741999-05-29 11:51:49 +0000296 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000297 name, type);
298}
299
300/**
301 * notationDeclDebug:
302 * @ctxt: An XML parser context
303 * @name: The name of the notation
304 * @publicId: The public ID of the entity
305 * @systemId: The system ID of the entity
306 *
307 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000308 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000309static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000310notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000311 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000312{
Daniel Veillard27d88741999-05-29 11:51:49 +0000313 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000314 (char *) name, (char *) publicId, (char *) systemId);
315}
316
317/**
318 * unparsedEntityDeclDebug:
319 * @ctxt: An XML parser context
320 * @name: The name of the entity
321 * @publicId: The public ID of the entity
322 * @systemId: The system ID of the entity
323 * @notationName: the name of the notation
324 *
325 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000326 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000327static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000328unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000329 const xmlChar *publicId, const xmlChar *systemId,
330 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000331{
Daniel Veillard27d88741999-05-29 11:51:49 +0000332 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000333 (char *) name, (char *) publicId, (char *) systemId,
334 (char *) notationName);
335}
336
337/**
338 * setDocumentLocatorDebug:
339 * @ctxt: An XML parser context
340 * @loc: A SAX Locator
341 *
342 * Receive the document locator at startup, actually xmlDefaultSAXLocator
343 * Everything is available on the context, so this is useless in our case.
344 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000345static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000346setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000347{
Daniel Veillard27d88741999-05-29 11:51:49 +0000348 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000349}
350
351/**
352 * startDocumentDebug:
353 * @ctxt: An XML parser context
354 *
355 * called when the document start being processed.
356 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000357static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000358startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000359{
Daniel Veillard27d88741999-05-29 11:51:49 +0000360 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000361}
362
363/**
364 * endDocumentDebug:
365 * @ctxt: An XML parser context
366 *
367 * called when the document end has been detected.
368 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000369static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000370endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000371{
Daniel Veillard27d88741999-05-29 11:51:49 +0000372 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000373}
374
375/**
376 * startElementDebug:
377 * @ctxt: An XML parser context
378 * @name: The element name
379 *
380 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000381 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000382static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000383startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000384{
385 int i;
386
Daniel Veillard27d88741999-05-29 11:51:49 +0000387 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000388 if (atts != NULL) {
389 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000390 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000391 if (atts[i] != NULL)
392 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000393 }
394 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000395 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000396}
397
398/**
399 * endElementDebug:
400 * @ctxt: An XML parser context
401 * @name: The element name
402 *
403 * called when the end of an element has been detected.
404 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000405static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000406endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000407{
Daniel Veillard27d88741999-05-29 11:51:49 +0000408 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000409}
410
411/**
412 * charactersDebug:
413 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000414 * @ch: a xmlChar string
415 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000416 *
417 * receiving some chars from the parser.
418 * Question: how much at a time ???
419 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000420static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000421charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000422{
Daniel Veillard87b95392000-08-12 21:12:04 +0000423 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000424 int i;
425
Daniel Veillard87b95392000-08-12 21:12:04 +0000426 for (i = 0;(i<len) && (i < 30);i++)
427 output[i] = ch[i];
428 output[i] = 0;
429
430 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000431}
432
433/**
434 * referenceDebug:
435 * @ctxt: An XML parser context
436 * @name: The entity name
437 *
438 * called when an entity reference is detected.
439 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000440static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000441referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000442{
Daniel Veillard27d88741999-05-29 11:51:49 +0000443 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000444}
445
446/**
447 * ignorableWhitespaceDebug:
448 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000449 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000450 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000451 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000452 *
453 * receiving some ignorable whitespaces from the parser.
454 * Question: how much at a time ???
455 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000456static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000457ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000458{
Daniel Veillard87b95392000-08-12 21:12:04 +0000459 char output[40];
460 int i;
461
462 for (i = 0;(i<len) && (i < 30);i++)
463 output[i] = ch[i];
464 output[i] = 0;
465 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000466}
467
468/**
469 * processingInstructionDebug:
470 * @ctxt: An XML parser context
471 * @target: the target name
472 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000473 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000474 *
475 * A processing instruction has been parsed.
476 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000477static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000478processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000479 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000480{
Daniel Veillard27d88741999-05-29 11:51:49 +0000481 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000482 (char *) target, (char *) data);
483}
484
485/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000486 * cdataBlockDebug:
487 * @ctx: the user data (XML parser context)
488 * @value: The pcdata content
489 * @len: the block length
490 *
491 * called when a pcdata block has been parsed
492 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000493static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000494cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000495{
Daniel Veillard39915622000-10-15 10:06:55 +0000496 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000497 (char *) value, len);
498}
499
500/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000501 * commentDebug:
502 * @ctxt: An XML parser context
503 * @value: the comment content
504 *
505 * A comment has been parsed.
506 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000507static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000508commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000509{
Daniel Veillard27d88741999-05-29 11:51:49 +0000510 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000511}
512
513/**
514 * warningDebug:
515 * @ctxt: An XML parser context
516 * @msg: the message to display/transmit
517 * @...: extra parameters for the message display
518 *
519 * Display and format a warning messages, gives file, line, position and
520 * extra parameters.
521 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000522static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000523warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000524{
525 va_list args;
526
527 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000528 fprintf(stdout, "SAX.warning: ");
529 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000530 va_end(args);
531}
532
533/**
534 * errorDebug:
535 * @ctxt: An XML parser context
536 * @msg: the message to display/transmit
537 * @...: extra parameters for the message display
538 *
539 * Display and format a error messages, gives file, line, position and
540 * extra parameters.
541 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000542static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000543errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000544{
545 va_list args;
546
547 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000548 fprintf(stdout, "SAX.error: ");
549 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000550 va_end(args);
551}
552
553/**
554 * fatalErrorDebug:
555 * @ctxt: An XML parser context
556 * @msg: the message to display/transmit
557 * @...: extra parameters for the message display
558 *
559 * Display and format a fatalError messages, gives file, line, position and
560 * extra parameters.
561 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000562static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000563fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000564{
565 va_list args;
566
567 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000568 fprintf(stdout, "SAX.fatalError: ");
569 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000570 va_end(args);
571}
572
573xmlSAXHandler debugSAXHandlerStruct = {
574 internalSubsetDebug,
575 isStandaloneDebug,
576 hasInternalSubsetDebug,
577 hasExternalSubsetDebug,
578 resolveEntityDebug,
579 getEntityDebug,
580 entityDeclDebug,
581 notationDeclDebug,
582 attributeDeclDebug,
583 elementDeclDebug,
584 unparsedEntityDeclDebug,
585 setDocumentLocatorDebug,
586 startDocumentDebug,
587 endDocumentDebug,
588 startElementDebug,
589 endElementDebug,
590 referenceDebug,
591 charactersDebug,
592 ignorableWhitespaceDebug,
593 processingInstructionDebug,
594 commentDebug,
595 warningDebug,
596 errorDebug,
597 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000598 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000599 cdataBlockDebug,
600 externalSubsetDebug
Daniel Veillard5099ae81999-04-21 20:12:07 +0000601};
602
603xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
604
605/************************************************************************
606 * *
607 * Debug *
608 * *
609 ************************************************************************/
610
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000611static void
612parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000613 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000614
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000615 if (push) {
616 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000617
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000618 /*
619 * Empty callbacks for checking
620 */
621 f = fopen(filename, "r");
622 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000623 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000624 char chars[10];
625 xmlParserCtxtPtr ctxt;
626
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000627 ret = fread(chars, 1, 4, f);
628 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000629 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000630 chars, ret, filename);
631 while ((ret = fread(chars, 1, 3, f)) > 0) {
632 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000633 }
634 xmlParseChunk(ctxt, chars, 0, 1);
635 xmlFreeParserCtxt(ctxt);
636 }
637 fclose(f);
638 } else {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000639 xmlGenericError(xmlGenericErrorContext,
640 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000641 }
642 /*
643 * Debug callback
644 */
645 f = fopen(filename, "r");
646 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000647 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000648 char chars[10];
649 xmlParserCtxtPtr ctxt;
650
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000651 ret = fread(chars, 1, 4, f);
652 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000653 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000654 chars, ret, filename);
655 while ((ret = fread(chars, 1, 3, f)) > 0) {
656 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000657 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000658 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000659 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000660 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000661 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000662 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000663 }
664 }
665 fclose(f);
666 }
667 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000668 if (!speed) {
669 /*
670 * Empty callbacks for checking
671 */
672 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
673 if (res != 0) {
674 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
675 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000676
Daniel Veillard5e873c42000-04-12 13:27:38 +0000677 /*
678 * Debug callback
679 */
680 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
681 if (res != 0) {
682 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
683 }
684 } else {
685 /*
686 * test 100x the SAX parse
687 */
688 int i;
689
690 for (i = 0; i<100;i++)
691 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
692 if (res != 0) {
693 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
694 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000695 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000696 }
697}
698
Daniel Veillard5099ae81999-04-21 20:12:07 +0000699
700int main(int argc, char **argv) {
701 int i;
702 int files = 0;
703
704 for (i = 1; i < argc ; i++) {
705 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
706 debug++;
707 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
708 copy++;
709 else if ((!strcmp(argv[i], "-recover")) ||
710 (!strcmp(argv[i], "--recover")))
711 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000712 else if ((!strcmp(argv[i], "-push")) ||
713 (!strcmp(argv[i], "--push")))
714 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000715 else if ((!strcmp(argv[i], "-speed")) ||
716 (!strcmp(argv[i], "--speed")))
717 speed++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000718 }
719 for (i = 1; i < argc ; i++) {
720 if (argv[i][0] != '-') {
721 parseAndPrintFile(argv[i]);
722 files ++;
723 }
724 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000725 xmlCleanupParser();
726 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000727
728 return(0);
729}