blob: 51def3782b8e104f6defc09c46bb39cde326748b [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
Daniel Veillard56a4cb82001-03-24 17:00:36 +000047/************************************************************************
48 * *
49 * When running GCC in vaacum cleaner mode *
50 * *
51 ************************************************************************/
52
53#ifdef __GNUC__
54#define UNUSED __attribute__((__unused__))
55#else
56#define UNUSED
57#endif
58
Daniel Veillard5099ae81999-04-21 20:12:07 +000059static int debug = 0;
60static int copy = 0;
61static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000062static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000063static int speed = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000064
65xmlSAXHandler emptySAXHandlerStruct = {
66 NULL, /* internalSubset */
67 NULL, /* isStandalone */
68 NULL, /* hasInternalSubset */
69 NULL, /* hasExternalSubset */
70 NULL, /* resolveEntity */
71 NULL, /* getEntity */
72 NULL, /* entityDecl */
73 NULL, /* notationDecl */
74 NULL, /* attributeDecl */
75 NULL, /* elementDecl */
76 NULL, /* unparsedEntityDecl */
77 NULL, /* setDocumentLocator */
78 NULL, /* startDocument */
79 NULL, /* endDocument */
80 NULL, /* startElement */
81 NULL, /* endElement */
82 NULL, /* reference */
83 NULL, /* characters */
84 NULL, /* ignorableWhitespace */
85 NULL, /* processingInstruction */
86 NULL, /* comment */
87 NULL, /* xmlParserWarning */
88 NULL, /* xmlParserError */
89 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +000090 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +000091 NULL, /* cdataBlock; */
Daniel Veillard56a4cb82001-03-24 17:00:36 +000092 NULL /* externalSubset; */
Daniel Veillard5099ae81999-04-21 20:12:07 +000093};
94
95xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +000096extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +000097
Daniel Veillard5099ae81999-04-21 20:12:07 +000098/************************************************************************
99 * *
100 * Debug Handlers *
101 * *
102 ************************************************************************/
103
104/**
105 * isStandaloneDebug:
106 * @ctxt: An XML parser context
107 *
108 * Is this document tagged standalone ?
109 *
110 * Returns 1 if true
111 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000112static int
113isStandaloneDebug(void *ctx UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000114{
Daniel Veillard27d88741999-05-29 11:51:49 +0000115 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000116 return(0);
117}
118
119/**
120 * hasInternalSubsetDebug:
121 * @ctxt: An XML parser context
122 *
123 * Does this document has an internal subset
124 *
125 * Returns 1 if true
126 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000127static int
128hasInternalSubsetDebug(void *ctx UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000129{
Daniel Veillard27d88741999-05-29 11:51:49 +0000130 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000131 return(0);
132}
133
134/**
135 * hasExternalSubsetDebug:
136 * @ctxt: An XML parser context
137 *
138 * Does this document has an external subset
139 *
140 * Returns 1 if true
141 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000142static int
143hasExternalSubsetDebug(void *ctx UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000144{
Daniel Veillard27d88741999-05-29 11:51:49 +0000145 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000146 return(0);
147}
148
149/**
Daniel Veillard06047432000-04-24 11:33:38 +0000150 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000151 * @ctxt: An XML parser context
152 *
153 * Does this document has an internal subset
154 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000155static void
156internalSubsetDebug(void *ctx UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000157 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000158{
Daniel Veillard808a3f12000-08-17 13:50:51 +0000159 fprintf(stdout, "SAX.internalSubset(%s,", name);
160 if (ExternalID == NULL)
161 fprintf(stdout, " ,");
162 else
163 fprintf(stdout, " %s,", ExternalID);
164 if (SystemID == NULL)
165 fprintf(stdout, " )\n");
166 else
167 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000168}
169
170/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000171 * externalSubsetDebug:
172 * @ctxt: An XML parser context
173 *
174 * Does this document has an external subset
175 */
176static void
177externalSubsetDebug(void *ctx UNUSED, const xmlChar *name,
178 const xmlChar *ExternalID, const xmlChar *SystemID)
179{
180 fprintf(stdout, "SAX.externalSubset(%s,", name);
181 if (ExternalID == NULL)
182 fprintf(stdout, " ,");
183 else
184 fprintf(stdout, " %s,", ExternalID);
185 if (SystemID == NULL)
186 fprintf(stdout, " )\n");
187 else
188 fprintf(stdout, " %s)\n", SystemID);
189}
190
191/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000192 * resolveEntityDebug:
193 * @ctxt: An XML parser context
194 * @publicId: The public ID of the entity
195 * @systemId: The system ID of the entity
196 *
197 * Special entity resolver, better left to the parser, it has
198 * more context than the application layer.
199 * The default behaviour is to NOT resolve the entities, in that case
200 * the ENTITY_REF nodes are built in the structure (and the parameter
201 * values).
202 *
203 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
204 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000205static xmlParserInputPtr
206resolveEntityDebug(void *ctx UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000207{
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000208 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000209
Daniel Veillard14fff061999-06-22 21:49:07 +0000210
211 fprintf(stdout, "SAX.resolveEntity(");
212 if (publicId != NULL)
213 fprintf(stdout, "%s", (char *)publicId);
214 else
215 fprintf(stdout, " ");
216 if (systemId != NULL)
217 fprintf(stdout, ", %s)\n", (char *)systemId);
218 else
219 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000220/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000221 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000222 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000223 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000224 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000225 return(NULL);
226}
227
228/**
229 * getEntityDebug:
230 * @ctxt: An XML parser context
231 * @name: The entity name
232 *
233 * Get an entity by name
234 *
235 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
236 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000237static xmlEntityPtr
238getEntityDebug(void *ctx UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000239{
Daniel Veillard27d88741999-05-29 11:51:49 +0000240 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000241 return(NULL);
242}
243
Daniel Veillardb05deb71999-08-10 19:04:08 +0000244/**
245 * getParameterEntityDebug:
246 * @ctxt: An XML parser context
247 * @name: The entity name
248 *
249 * Get a parameter entity by name
250 *
251 * Returns the xmlParserInputPtr
252 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000253static xmlEntityPtr
254getParameterEntityDebug(void *ctx UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000255{
256 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
257 return(NULL);
258}
259
Daniel Veillard5099ae81999-04-21 20:12:07 +0000260
261/**
262 * entityDeclDebug:
263 * @ctxt: An XML parser context
264 * @name: the entity name
265 * @type: the entity type
266 * @publicId: The public ID of the entity
267 * @systemId: The system ID of the entity
268 * @content: the entity value (without processing).
269 *
270 * An entity definition has been parsed
271 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000272static void
273entityDeclDebug(void *ctx UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000274 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000275{
Daniel Veillard27d88741999-05-29 11:51:49 +0000276 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000277 name, type, publicId, systemId, content);
278}
279
280/**
281 * attributeDeclDebug:
282 * @ctxt: An XML parser context
283 * @name: the attribute name
284 * @type: the attribute type
285 *
286 * An attribute definition has been parsed
287 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000288static void
289attributeDeclDebug(void *ctx UNUSED, const xmlChar *elem, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000290 int type, int def, const xmlChar *defaultValue,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000291 xmlEnumerationPtr tree UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000292{
Daniel Veillard7e99c632000-10-06 12:59:53 +0000293 if (defaultValue == NULL)
294 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
295 elem, name, type, def);
296 else
297 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000298 elem, name, type, def, defaultValue);
299}
300
301/**
302 * elementDeclDebug:
303 * @ctxt: An XML parser context
304 * @name: the element name
305 * @type: the element type
306 * @content: the element value (without processing).
307 *
308 * An element definition has been parsed
309 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000310static void
311elementDeclDebug(void *ctx UNUSED, const xmlChar *name, int type,
312 xmlElementContentPtr content UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000313{
Daniel Veillard27d88741999-05-29 11:51:49 +0000314 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000315 name, type);
316}
317
318/**
319 * notationDeclDebug:
320 * @ctxt: An XML parser context
321 * @name: The name of the notation
322 * @publicId: The public ID of the entity
323 * @systemId: The system ID of the entity
324 *
325 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000326 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000327static void
328notationDeclDebug(void *ctx UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000329 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000330{
Daniel Veillard27d88741999-05-29 11:51:49 +0000331 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000332 (char *) name, (char *) publicId, (char *) systemId);
333}
334
335/**
336 * unparsedEntityDeclDebug:
337 * @ctxt: An XML parser context
338 * @name: The name of the entity
339 * @publicId: The public ID of the entity
340 * @systemId: The system ID of the entity
341 * @notationName: the name of the notation
342 *
343 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000344 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000345static void
346unparsedEntityDeclDebug(void *ctx UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000347 const xmlChar *publicId, const xmlChar *systemId,
348 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000349{
Daniel Veillard27d88741999-05-29 11:51:49 +0000350 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000351 (char *) name, (char *) publicId, (char *) systemId,
352 (char *) notationName);
353}
354
355/**
356 * setDocumentLocatorDebug:
357 * @ctxt: An XML parser context
358 * @loc: A SAX Locator
359 *
360 * Receive the document locator at startup, actually xmlDefaultSAXLocator
361 * Everything is available on the context, so this is useless in our case.
362 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000363static void
364setDocumentLocatorDebug(void *ctx UNUSED, xmlSAXLocatorPtr loc UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000365{
Daniel Veillard27d88741999-05-29 11:51:49 +0000366 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000367}
368
369/**
370 * startDocumentDebug:
371 * @ctxt: An XML parser context
372 *
373 * called when the document start being processed.
374 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000375static void
376startDocumentDebug(void *ctx UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000377{
Daniel Veillard27d88741999-05-29 11:51:49 +0000378 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000379}
380
381/**
382 * endDocumentDebug:
383 * @ctxt: An XML parser context
384 *
385 * called when the document end has been detected.
386 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000387static void
388endDocumentDebug(void *ctx UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000389{
Daniel Veillard27d88741999-05-29 11:51:49 +0000390 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000391}
392
393/**
394 * startElementDebug:
395 * @ctxt: An XML parser context
396 * @name: The element name
397 *
398 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000399 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000400static void
401startElementDebug(void *ctx UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000402{
403 int i;
404
Daniel Veillard27d88741999-05-29 11:51:49 +0000405 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000406 if (atts != NULL) {
407 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000408 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000409 if (atts[i] != NULL)
410 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000411 }
412 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000413 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000414}
415
416/**
417 * endElementDebug:
418 * @ctxt: An XML parser context
419 * @name: The element name
420 *
421 * called when the end of an element has been detected.
422 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000423static void
424endElementDebug(void *ctx UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000425{
Daniel Veillard27d88741999-05-29 11:51:49 +0000426 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000427}
428
429/**
430 * charactersDebug:
431 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000432 * @ch: a xmlChar string
433 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000434 *
435 * receiving some chars from the parser.
436 * Question: how much at a time ???
437 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000438static void
439charactersDebug(void *ctx UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000440{
Daniel Veillard87b95392000-08-12 21:12:04 +0000441 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000442 int i;
443
Daniel Veillard87b95392000-08-12 21:12:04 +0000444 for (i = 0;(i<len) && (i < 30);i++)
445 output[i] = ch[i];
446 output[i] = 0;
447
448 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000449}
450
451/**
452 * referenceDebug:
453 * @ctxt: An XML parser context
454 * @name: The entity name
455 *
456 * called when an entity reference is detected.
457 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000458static void
459referenceDebug(void *ctx UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000460{
Daniel Veillard27d88741999-05-29 11:51:49 +0000461 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000462}
463
464/**
465 * ignorableWhitespaceDebug:
466 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000467 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000468 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000469 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000470 *
471 * receiving some ignorable whitespaces from the parser.
472 * Question: how much at a time ???
473 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000474static void
475ignorableWhitespaceDebug(void *ctx UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000476{
Daniel Veillard87b95392000-08-12 21:12:04 +0000477 char output[40];
478 int i;
479
480 for (i = 0;(i<len) && (i < 30);i++)
481 output[i] = ch[i];
482 output[i] = 0;
483 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000484}
485
486/**
487 * processingInstructionDebug:
488 * @ctxt: An XML parser context
489 * @target: the target name
490 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000491 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000492 *
493 * A processing instruction has been parsed.
494 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000495static void
496processingInstructionDebug(void *ctx UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000497 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000498{
Daniel Veillard27d88741999-05-29 11:51:49 +0000499 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000500 (char *) target, (char *) data);
501}
502
503/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000504 * cdataBlockDebug:
505 * @ctx: the user data (XML parser context)
506 * @value: The pcdata content
507 * @len: the block length
508 *
509 * called when a pcdata block has been parsed
510 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000511static void
512cdataBlockDebug(void *ctx UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000513{
Daniel Veillard39915622000-10-15 10:06:55 +0000514 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000515 (char *) value, len);
516}
517
518/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000519 * commentDebug:
520 * @ctxt: An XML parser context
521 * @value: the comment content
522 *
523 * A comment has been parsed.
524 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000525static void
526commentDebug(void *ctx UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000527{
Daniel Veillard27d88741999-05-29 11:51:49 +0000528 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000529}
530
531/**
532 * warningDebug:
533 * @ctxt: An XML parser context
534 * @msg: the message to display/transmit
535 * @...: extra parameters for the message display
536 *
537 * Display and format a warning messages, gives file, line, position and
538 * extra parameters.
539 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000540static void
541warningDebug(void *ctx UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000542{
543 va_list args;
544
545 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000546 fprintf(stdout, "SAX.warning: ");
547 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000548 va_end(args);
549}
550
551/**
552 * errorDebug:
553 * @ctxt: An XML parser context
554 * @msg: the message to display/transmit
555 * @...: extra parameters for the message display
556 *
557 * Display and format a error messages, gives file, line, position and
558 * extra parameters.
559 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000560static void
561errorDebug(void *ctx UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000562{
563 va_list args;
564
565 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000566 fprintf(stdout, "SAX.error: ");
567 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000568 va_end(args);
569}
570
571/**
572 * fatalErrorDebug:
573 * @ctxt: An XML parser context
574 * @msg: the message to display/transmit
575 * @...: extra parameters for the message display
576 *
577 * Display and format a fatalError messages, gives file, line, position and
578 * extra parameters.
579 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000580static void
581fatalErrorDebug(void *ctx UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000582{
583 va_list args;
584
585 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000586 fprintf(stdout, "SAX.fatalError: ");
587 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000588 va_end(args);
589}
590
591xmlSAXHandler debugSAXHandlerStruct = {
592 internalSubsetDebug,
593 isStandaloneDebug,
594 hasInternalSubsetDebug,
595 hasExternalSubsetDebug,
596 resolveEntityDebug,
597 getEntityDebug,
598 entityDeclDebug,
599 notationDeclDebug,
600 attributeDeclDebug,
601 elementDeclDebug,
602 unparsedEntityDeclDebug,
603 setDocumentLocatorDebug,
604 startDocumentDebug,
605 endDocumentDebug,
606 startElementDebug,
607 endElementDebug,
608 referenceDebug,
609 charactersDebug,
610 ignorableWhitespaceDebug,
611 processingInstructionDebug,
612 commentDebug,
613 warningDebug,
614 errorDebug,
615 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000616 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000617 cdataBlockDebug,
618 externalSubsetDebug
Daniel Veillard5099ae81999-04-21 20:12:07 +0000619};
620
621xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
622
623/************************************************************************
624 * *
625 * Debug *
626 * *
627 ************************************************************************/
628
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000629static void
630parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000631 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000632
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000633 if (push) {
634 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000635
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000636 /*
637 * Empty callbacks for checking
638 */
639 f = fopen(filename, "r");
640 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000641 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000642 char chars[10];
643 xmlParserCtxtPtr ctxt;
644
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000645 ret = fread(chars, 1, 4, f);
646 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000647 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000648 chars, ret, filename);
649 while ((ret = fread(chars, 1, 3, f)) > 0) {
650 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000651 }
652 xmlParseChunk(ctxt, chars, 0, 1);
653 xmlFreeParserCtxt(ctxt);
654 }
655 fclose(f);
656 } else {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000657 xmlGenericError(xmlGenericErrorContext,
658 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000659 }
660 /*
661 * Debug callback
662 */
663 f = fopen(filename, "r");
664 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000665 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000666 char chars[10];
667 xmlParserCtxtPtr ctxt;
668
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000669 ret = fread(chars, 1, 4, f);
670 if (ret > 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000671 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000672 chars, ret, filename);
673 while ((ret = fread(chars, 1, 3, f)) > 0) {
674 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000675 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000676 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000677 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000678 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000679 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000680 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000681 }
682 }
683 fclose(f);
684 }
685 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000686 if (!speed) {
687 /*
688 * Empty callbacks for checking
689 */
690 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
691 if (res != 0) {
692 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
693 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000694
Daniel Veillard5e873c42000-04-12 13:27:38 +0000695 /*
696 * Debug callback
697 */
698 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
699 if (res != 0) {
700 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
701 }
702 } else {
703 /*
704 * test 100x the SAX parse
705 */
706 int i;
707
708 for (i = 0; i<100;i++)
709 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
710 if (res != 0) {
711 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
712 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000713 }
Daniel Veillard5099ae81999-04-21 20:12:07 +0000714 }
715}
716
Daniel Veillard5099ae81999-04-21 20:12:07 +0000717
718int main(int argc, char **argv) {
719 int i;
720 int files = 0;
721
722 for (i = 1; i < argc ; i++) {
723 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
724 debug++;
725 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
726 copy++;
727 else if ((!strcmp(argv[i], "-recover")) ||
728 (!strcmp(argv[i], "--recover")))
729 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000730 else if ((!strcmp(argv[i], "-push")) ||
731 (!strcmp(argv[i], "--push")))
732 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000733 else if ((!strcmp(argv[i], "-speed")) ||
734 (!strcmp(argv[i], "--speed")))
735 speed++;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000736 }
737 for (i = 1; i < argc ; i++) {
738 if (argv[i][0] != '-') {
739 parseAndPrintFile(argv[i]);
740 files ++;
741 }
742 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +0000743 xmlCleanupParser();
744 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +0000745
746 return(0);
747}