blob: b22a360ec70b98d9b20631207e51b84a570de50b [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 Veillard5099ae81999-04-21 20:12:07 +000011#ifdef WIN32
Daniel Veillardc2def842000-11-07 14:21:01 +000012#undef LIBXML_DLL_IMPORT
Daniel Veillard5099ae81999-04-21 20:12:07 +000013#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000014
Daniel Veillard7f7d1111999-09-22 09:46:25 +000015#include <string.h>
16#include <stdarg.h>
17
18#ifdef HAVE_SYS_TYPES_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000019#include <sys/types.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000020#endif
Daniel Veillard5099ae81999-04-21 20:12:07 +000021#ifdef HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#ifdef HAVE_FCNTL_H
25#include <fcntl.h>
26#endif
27#ifdef HAVE_UNISTD_H
28#include <unistd.h>
29#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000030#ifdef HAVE_STDLIB_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000031#include <stdlib.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000032#endif
Daniel Veillard7a66ee61999-09-26 11:31:02 +000033#ifdef HAVE_STRING_H
34#include <string.h>
35#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000036
Daniel Veillard5099ae81999-04-21 20:12:07 +000037
Daniel Veillardb71379b2000-10-09 12:30:39 +000038#include <libxml/xmlerror.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000039#include <libxml/parser.h>
40#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
41#include <libxml/tree.h>
42#include <libxml/debugXML.h>
43#include <libxml/xmlmemory.h>
Daniel Veillard5099ae81999-04-21 20:12:07 +000044
45static int debug = 0;
46static int copy = 0;
47static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000048static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000049static int speed = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000050
51xmlSAXHandler emptySAXHandlerStruct = {
52 NULL, /* internalSubset */
53 NULL, /* isStandalone */
54 NULL, /* hasInternalSubset */
55 NULL, /* hasExternalSubset */
56 NULL, /* resolveEntity */
57 NULL, /* getEntity */
58 NULL, /* entityDecl */
59 NULL, /* notationDecl */
60 NULL, /* attributeDecl */
61 NULL, /* elementDecl */
62 NULL, /* unparsedEntityDecl */
63 NULL, /* setDocumentLocator */
64 NULL, /* startDocument */
65 NULL, /* endDocument */
66 NULL, /* startElement */
67 NULL, /* endElement */
68 NULL, /* reference */
69 NULL, /* characters */
70 NULL, /* ignorableWhitespace */
71 NULL, /* processingInstruction */
72 NULL, /* comment */
73 NULL, /* xmlParserWarning */
74 NULL, /* xmlParserError */
75 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000076 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000077 NULL, /* cdataBlock; */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000078 NULL /* externalSubset; */
Daniel Veillard5099ae81999-04-21 20:12:07 +000079};
80
81xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000082extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000083
Daniel Veillard5099ae81999-04-21 20:12:07 +000084/************************************************************************
85 * *
86 * Debug Handlers *
87 * *
88 ************************************************************************/
89
90/**
91 * isStandaloneDebug:
92 * @ctxt: An XML parser context
93 *
94 * Is this document tagged standalone ?
95 *
96 * Returns 1 if true
97 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000098static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +000099isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000100{
Daniel Veillard27d88741999-05-29 11:51:49 +0000101 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000102 return(0);
103}
104
105/**
106 * hasInternalSubsetDebug:
107 * @ctxt: An XML parser context
108 *
109 * Does this document has an internal subset
110 *
111 * Returns 1 if true
112 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000113static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000114hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000115{
Daniel Veillard27d88741999-05-29 11:51:49 +0000116 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000117 return(0);
118}
119
120/**
121 * hasExternalSubsetDebug:
122 * @ctxt: An XML parser context
123 *
124 * Does this document has an external subset
125 *
126 * Returns 1 if true
127 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000128static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000129hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000130{
Daniel Veillard27d88741999-05-29 11:51:49 +0000131 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000132 return(0);
133}
134
135/**
Daniel Veillard06047432000-04-24 11:33:38 +0000136 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000137 * @ctxt: An XML parser context
138 *
139 * Does this document has an internal subset
140 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000141static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000142internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000143 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000144{
Daniel Veillard808a3f12000-08-17 13:50:51 +0000145 fprintf(stdout, "SAX.internalSubset(%s,", name);
146 if (ExternalID == NULL)
147 fprintf(stdout, " ,");
148 else
149 fprintf(stdout, " %s,", ExternalID);
150 if (SystemID == NULL)
151 fprintf(stdout, " )\n");
152 else
153 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000154}
155
156/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000157 * externalSubsetDebug:
158 * @ctxt: An XML parser context
159 *
160 * Does this document has an external subset
161 */
162static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000163externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000164 const xmlChar *ExternalID, const xmlChar *SystemID)
165{
166 fprintf(stdout, "SAX.externalSubset(%s,", name);
167 if (ExternalID == NULL)
168 fprintf(stdout, " ,");
169 else
170 fprintf(stdout, " %s,", ExternalID);
171 if (SystemID == NULL)
172 fprintf(stdout, " )\n");
173 else
174 fprintf(stdout, " %s)\n", SystemID);
175}
176
177/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000178 * resolveEntityDebug:
179 * @ctxt: An XML parser context
180 * @publicId: The public ID of the entity
181 * @systemId: The system ID of the entity
182 *
183 * Special entity resolver, better left to the parser, it has
184 * more context than the application layer.
185 * The default behaviour is to NOT resolve the entities, in that case
186 * the ENTITY_REF nodes are built in the structure (and the parameter
187 * values).
188 *
189 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
190 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000191static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000192resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000193{
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000194 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000195
Daniel Veillard14fff061999-06-22 21:49:07 +0000196
197 fprintf(stdout, "SAX.resolveEntity(");
198 if (publicId != NULL)
199 fprintf(stdout, "%s", (char *)publicId);
200 else
201 fprintf(stdout, " ");
202 if (systemId != NULL)
203 fprintf(stdout, ", %s)\n", (char *)systemId);
204 else
205 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000206/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000207 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000208 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000209 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000210 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000211 return(NULL);
212}
213
214/**
215 * getEntityDebug:
216 * @ctxt: An XML parser context
217 * @name: The entity name
218 *
219 * Get an entity by name
220 *
221 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
222 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000223static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000224getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000225{
Daniel Veillard27d88741999-05-29 11:51:49 +0000226 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000227 return(NULL);
228}
229
Daniel Veillardb05deb71999-08-10 19:04:08 +0000230/**
231 * getParameterEntityDebug:
232 * @ctxt: An XML parser context
233 * @name: The entity name
234 *
235 * Get a parameter entity by name
236 *
237 * Returns the xmlParserInputPtr
238 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000239static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000240getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000241{
242 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
243 return(NULL);
244}
245
Daniel Veillard5099ae81999-04-21 20:12:07 +0000246
247/**
248 * entityDeclDebug:
249 * @ctxt: An XML parser context
250 * @name: the entity name
251 * @type: the entity type
252 * @publicId: The public ID of the entity
253 * @systemId: The system ID of the entity
254 * @content: the entity value (without processing).
255 *
256 * An entity definition has been parsed
257 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000258static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000259entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000260 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000261{
Daniel Veillard27d88741999-05-29 11:51:49 +0000262 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000263 name, type, publicId, systemId, content);
264}
265
266/**
267 * attributeDeclDebug:
268 * @ctxt: An XML parser context
269 * @name: the attribute name
270 * @type: the attribute type
271 *
272 * An attribute definition has been parsed
273 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000274static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000275attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000276 int type, int def, const xmlChar *defaultValue,
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000277 xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000278{
Daniel Veillard7e99c632000-10-06 12:59:53 +0000279 if (defaultValue == NULL)
280 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
281 elem, name, type, def);
282 else
283 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000284 elem, name, type, def, defaultValue);
285}
286
287/**
288 * elementDeclDebug:
289 * @ctxt: An XML parser context
290 * @name: the element name
291 * @type: the element type
292 * @content: the element value (without processing).
293 *
294 * An element definition has been parsed
295 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000296static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000297elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
298 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000299{
Daniel Veillard27d88741999-05-29 11:51:49 +0000300 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000301 name, type);
302}
303
304/**
305 * notationDeclDebug:
306 * @ctxt: An XML parser context
307 * @name: The name of the notation
308 * @publicId: The public ID of the entity
309 * @systemId: The system ID of the entity
310 *
311 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000312 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000313static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000314notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000315 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000316{
Daniel Veillard27d88741999-05-29 11:51:49 +0000317 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000318 (char *) name, (char *) publicId, (char *) systemId);
319}
320
321/**
322 * unparsedEntityDeclDebug:
323 * @ctxt: An XML parser context
324 * @name: The name of the entity
325 * @publicId: The public ID of the entity
326 * @systemId: The system ID of the entity
327 * @notationName: the name of the notation
328 *
329 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000330 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000331static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000332unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000333 const xmlChar *publicId, const xmlChar *systemId,
334 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000335{
Daniel Veillard27d88741999-05-29 11:51:49 +0000336 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000337 (char *) name, (char *) publicId, (char *) systemId,
338 (char *) notationName);
339}
340
341/**
342 * setDocumentLocatorDebug:
343 * @ctxt: An XML parser context
344 * @loc: A SAX Locator
345 *
346 * Receive the document locator at startup, actually xmlDefaultSAXLocator
347 * Everything is available on the context, so this is useless in our case.
348 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000349static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000350setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000351{
Daniel Veillard27d88741999-05-29 11:51:49 +0000352 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000353}
354
355/**
356 * startDocumentDebug:
357 * @ctxt: An XML parser context
358 *
359 * called when the document start being processed.
360 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000361static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000362startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000363{
Daniel Veillard27d88741999-05-29 11:51:49 +0000364 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000365}
366
367/**
368 * endDocumentDebug:
369 * @ctxt: An XML parser context
370 *
371 * called when the document end has been detected.
372 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000373static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000374endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000375{
Daniel Veillard27d88741999-05-29 11:51:49 +0000376 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000377}
378
379/**
380 * startElementDebug:
381 * @ctxt: An XML parser context
382 * @name: The element name
383 *
384 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000385 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000386static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000387startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000388{
389 int i;
390
Daniel Veillard27d88741999-05-29 11:51:49 +0000391 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000392 if (atts != NULL) {
393 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000394 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000395 if (atts[i] != NULL)
396 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000397 }
398 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000399 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000400}
401
402/**
403 * endElementDebug:
404 * @ctxt: An XML parser context
405 * @name: The element name
406 *
407 * called when the end of an element has been detected.
408 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000409static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000410endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000411{
Daniel Veillard27d88741999-05-29 11:51:49 +0000412 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000413}
414
415/**
416 * charactersDebug:
417 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000418 * @ch: a xmlChar string
419 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000420 *
421 * receiving some chars from the parser.
422 * Question: how much at a time ???
423 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000424static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000425charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000426{
Daniel Veillard87b95392000-08-12 21:12:04 +0000427 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000428 int i;
429
Daniel Veillard87b95392000-08-12 21:12:04 +0000430 for (i = 0;(i<len) && (i < 30);i++)
431 output[i] = ch[i];
432 output[i] = 0;
433
434 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000435}
436
437/**
438 * referenceDebug:
439 * @ctxt: An XML parser context
440 * @name: The entity name
441 *
442 * called when an entity reference is detected.
443 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000444static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000445referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000446{
Daniel Veillard27d88741999-05-29 11:51:49 +0000447 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000448}
449
450/**
451 * ignorableWhitespaceDebug:
452 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000453 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000454 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000455 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000456 *
457 * receiving some ignorable whitespaces from the parser.
458 * Question: how much at a time ???
459 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000460static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000461ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000462{
Daniel Veillard87b95392000-08-12 21:12:04 +0000463 char output[40];
464 int i;
465
466 for (i = 0;(i<len) && (i < 30);i++)
467 output[i] = ch[i];
468 output[i] = 0;
469 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000470}
471
472/**
473 * processingInstructionDebug:
474 * @ctxt: An XML parser context
475 * @target: the target name
476 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000477 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000478 *
479 * A processing instruction has been parsed.
480 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000481static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000482processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000483 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000484{
Daniel Veillard27d88741999-05-29 11:51:49 +0000485 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000486 (char *) target, (char *) data);
487}
488
489/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000490 * cdataBlockDebug:
491 * @ctx: the user data (XML parser context)
492 * @value: The pcdata content
493 * @len: the block length
494 *
495 * called when a pcdata block has been parsed
496 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000497static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000498cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000499{
Daniel Veillard39915622000-10-15 10:06:55 +0000500 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000501 (char *) value, len);
502}
503
504/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000505 * commentDebug:
506 * @ctxt: An XML parser context
507 * @value: the comment content
508 *
509 * A comment has been parsed.
510 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000511static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000512commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000513{
Daniel Veillard27d88741999-05-29 11:51:49 +0000514 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000515}
516
517/**
518 * warningDebug:
519 * @ctxt: An XML parser context
520 * @msg: the message to display/transmit
521 * @...: extra parameters for the message display
522 *
523 * Display and format a warning messages, gives file, line, position and
524 * extra parameters.
525 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000526static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000527warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000528{
529 va_list args;
530
531 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000532 fprintf(stdout, "SAX.warning: ");
533 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000534 va_end(args);
535}
536
537/**
538 * errorDebug:
539 * @ctxt: An XML parser context
540 * @msg: the message to display/transmit
541 * @...: extra parameters for the message display
542 *
543 * Display and format a error messages, gives file, line, position and
544 * extra parameters.
545 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000546static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000547errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000548{
549 va_list args;
550
551 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000552 fprintf(stdout, "SAX.error: ");
553 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000554 va_end(args);
555}
556
557/**
558 * fatalErrorDebug:
559 * @ctxt: An XML parser context
560 * @msg: the message to display/transmit
561 * @...: extra parameters for the message display
562 *
563 * Display and format a fatalError messages, gives file, line, position and
564 * extra parameters.
565 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000566static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000567fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000568{
569 va_list args;
570
571 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000572 fprintf(stdout, "SAX.fatalError: ");
573 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000574 va_end(args);
575}
576
577xmlSAXHandler debugSAXHandlerStruct = {
578 internalSubsetDebug,
579 isStandaloneDebug,
580 hasInternalSubsetDebug,
581 hasExternalSubsetDebug,
582 resolveEntityDebug,
583 getEntityDebug,
584 entityDeclDebug,
585 notationDeclDebug,
586 attributeDeclDebug,
587 elementDeclDebug,
588 unparsedEntityDeclDebug,
589 setDocumentLocatorDebug,
590 startDocumentDebug,
591 endDocumentDebug,
592 startElementDebug,
593 endElementDebug,
594 referenceDebug,
595 charactersDebug,
596 ignorableWhitespaceDebug,
597 processingInstructionDebug,
598 commentDebug,
599 warningDebug,
600 errorDebug,
601 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000602 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000603 cdataBlockDebug,
604 externalSubsetDebug
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 Veillard5099ae81999-04-21 20:12:07 +0000722 }
723 for (i = 1; i < argc ; i++) {
724 if (argv[i][0] != '-') {
725 parseAndPrintFile(argv[i]);
726 files ++;
727 }
728 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000729 xmlCleanupParser();
730 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000731
732 return(0);
733}