blob: 009c6c146309b096c2a7f53c3a78c9356776fb25 [file] [log] [blame]
Daniel Veillard5099ae81999-04-21 20:12:07 +00001/*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002 * testSAX.c : a small tester program for parsing using the SAX API.
Daniel Veillard5099ae81999-04-21 20:12:07 +00003 *
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 Veillard807daf82004-02-22 22:13:27 +000011#ifdef HAVE_SYS_TIME_H
12#include <sys/time.h>
13#endif
Daniel Veillard3411d082004-03-01 13:21:26 +000014#ifdef HAVE_SYS_TIMEB_H
15#include <sys/timeb.h>
16#endif
Daniel Veillard807daf82004-02-22 22:13:27 +000017#ifdef HAVE_TIME_H
18#include <time.h>
19#endif
20
Daniel Veillard81273902003-09-30 00:43:48 +000021#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard7f7d1111999-09-22 09:46:25 +000022#include <string.h>
23#include <stdarg.h>
24
25#ifdef HAVE_SYS_TYPES_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000026#include <sys/types.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000027#endif
Daniel Veillard5099ae81999-04-21 20:12:07 +000028#ifdef HAVE_SYS_STAT_H
29#include <sys/stat.h>
30#endif
31#ifdef HAVE_FCNTL_H
32#include <fcntl.h>
33#endif
34#ifdef HAVE_UNISTD_H
35#include <unistd.h>
36#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000037#ifdef HAVE_STDLIB_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000038#include <stdlib.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000039#endif
Daniel Veillard7a66ee61999-09-26 11:31:02 +000040#ifdef HAVE_STRING_H
41#include <string.h>
42#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000043
Daniel Veillard5099ae81999-04-21 20:12:07 +000044
Daniel Veillardd0463562001-10-13 09:15:48 +000045#include <libxml/globals.h>
Daniel Veillardb71379b2000-10-09 12:30:39 +000046#include <libxml/xmlerror.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000047#include <libxml/parser.h>
48#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
49#include <libxml/tree.h>
50#include <libxml/debugXML.h>
51#include <libxml/xmlmemory.h>
Daniel Veillard5099ae81999-04-21 20:12:07 +000052
53static int debug = 0;
54static int copy = 0;
55static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000056static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000057static int speed = 0;
Daniel Veillard5997aca2002-03-18 18:36:20 +000058static int noent = 0;
Daniel Veillarde50f3b52002-03-20 19:24:21 +000059static int quiet = 0;
Daniel Veillard0fb18932003-09-07 09:14:37 +000060static int nonull = 0;
61static int sax2 = 0;
Daniel Veillard4773df22004-01-23 13:15:13 +000062static int repeat = 0;
Daniel Veillarde50f3b52002-03-20 19:24:21 +000063static int callbacks = 0;
Daniel Veillard807daf82004-02-22 22:13:27 +000064static int timing = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000065
Daniel Veillard807daf82004-02-22 22:13:27 +000066/*
67 * Timing routines.
68 */
69/*
70 * Internal timing routines to remove the necessity to have unix-specific
71 * function calls
72 */
73
74#ifndef HAVE_GETTIMEOFDAY
75#ifdef HAVE_SYS_TIMEB_H
76#ifdef HAVE_SYS_TIME_H
77#ifdef HAVE_FTIME
78
79static int
80my_gettimeofday(struct timeval *tvp, void *tzp)
81{
82 struct timeb timebuffer;
83
84 ftime(&timebuffer);
85 if (tvp) {
86 tvp->tv_sec = timebuffer.time;
87 tvp->tv_usec = timebuffer.millitm * 1000L;
88 }
89 return (0);
90}
91#define HAVE_GETTIMEOFDAY 1
92#define gettimeofday my_gettimeofday
93
94#endif /* HAVE_FTIME */
95#endif /* HAVE_SYS_TIME_H */
96#endif /* HAVE_SYS_TIMEB_H */
97#endif /* !HAVE_GETTIMEOFDAY */
98
99#if defined(HAVE_GETTIMEOFDAY)
100static struct timeval begin, end;
101
102/*
103 * startTimer: call where you want to start timing
104 */
105static void
106startTimer(void)
107{
108 gettimeofday(&begin, NULL);
109}
110
111/*
112 * endTimer: call where you want to stop timing and to print out a
113 * message about the timing performed; format is a printf
114 * type argument
115 */
116static void
117endTimer(const char *fmt, ...)
118{
119 long msec;
120 va_list ap;
121
122 gettimeofday(&end, NULL);
123 msec = end.tv_sec - begin.tv_sec;
124 msec *= 1000;
125 msec += (end.tv_usec - begin.tv_usec) / 1000;
126
127#ifndef HAVE_STDARG_H
128#error "endTimer required stdarg functions"
129#endif
130 va_start(ap, fmt);
131 vfprintf(stderr, fmt, ap);
132 va_end(ap);
133
134 fprintf(stderr, " took %ld ms\n", msec);
135}
136#elif defined(HAVE_TIME_H)
137/*
138 * No gettimeofday function, so we have to make do with calling clock.
139 * This is obviously less accurate, but there's little we can do about
140 * that.
141 */
142#ifndef CLOCKS_PER_SEC
143#define CLOCKS_PER_SEC 100
144#endif
145
146static clock_t begin, end;
147static void
148startTimer(void)
149{
150 begin = clock();
151}
152static void
153endTimer(const char *fmt, ...)
154{
155 long msec;
156 va_list ap;
157
158 end = clock();
159 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
160
161#ifndef HAVE_STDARG_H
162#error "endTimer required stdarg functions"
163#endif
164 va_start(ap, fmt);
165 vfprintf(stderr, fmt, ap);
166 va_end(ap);
167 fprintf(stderr, " took %ld ms\n", msec);
168}
169#else
170
171/*
172 * We don't have a gettimeofday or time.h, so we just don't do timing
173 */
174static void
175startTimer(void)
176{
177 /*
178 * Do nothing
179 */
180}
181static void
182endTimer(char *format, ...)
183{
184 /*
185 * We cannot do anything because we don't have a timing function
186 */
187#ifdef HAVE_STDARG_H
188 va_start(ap, format);
189 vfprintf(stderr, format, ap);
190 va_end(ap);
191 fprintf(stderr, " was not timed\n", msec);
192#else
193 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
194 * this ?!
195 */
196#endif
197}
198#endif
199
200/*
201 * empty SAX block
202 */
Daniel Veillard5099ae81999-04-21 20:12:07 +0000203xmlSAXHandler emptySAXHandlerStruct = {
204 NULL, /* internalSubset */
205 NULL, /* isStandalone */
206 NULL, /* hasInternalSubset */
207 NULL, /* hasExternalSubset */
208 NULL, /* resolveEntity */
209 NULL, /* getEntity */
210 NULL, /* entityDecl */
211 NULL, /* notationDecl */
212 NULL, /* attributeDecl */
213 NULL, /* elementDecl */
214 NULL, /* unparsedEntityDecl */
215 NULL, /* setDocumentLocator */
216 NULL, /* startDocument */
217 NULL, /* endDocument */
218 NULL, /* startElement */
219 NULL, /* endElement */
220 NULL, /* reference */
221 NULL, /* characters */
222 NULL, /* ignorableWhitespace */
223 NULL, /* processingInstruction */
224 NULL, /* comment */
225 NULL, /* xmlParserWarning */
226 NULL, /* xmlParserError */
227 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +0000228 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +0000229 NULL, /* cdataBlock; */
Daniel Veillard0fb18932003-09-07 09:14:37 +0000230 NULL, /* externalSubset; */
231 1,
232 NULL,
233 NULL, /* startElementNs */
William M. Brack871611b2003-10-18 04:53:14 +0000234 NULL, /* endElementNs */
235 NULL /* xmlStructuredErrorFunc */
Daniel Veillard5099ae81999-04-21 20:12:07 +0000236};
237
238xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +0000239extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000240
Daniel Veillard5099ae81999-04-21 20:12:07 +0000241/************************************************************************
242 * *
243 * Debug Handlers *
244 * *
245 ************************************************************************/
246
247/**
248 * isStandaloneDebug:
249 * @ctxt: An XML parser context
250 *
251 * Is this document tagged standalone ?
252 *
253 * Returns 1 if true
254 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000255static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000256isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000257{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000258 callbacks++;
259 if (quiet)
260 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000261 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000262 return(0);
263}
264
265/**
266 * hasInternalSubsetDebug:
267 * @ctxt: An XML parser context
268 *
269 * Does this document has an internal subset
270 *
271 * Returns 1 if true
272 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000273static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000274hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000275{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000276 callbacks++;
277 if (quiet)
278 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000279 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000280 return(0);
281}
282
283/**
284 * hasExternalSubsetDebug:
285 * @ctxt: An XML parser context
286 *
287 * Does this document has an external subset
288 *
289 * Returns 1 if true
290 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000291static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000292hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000293{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000294 callbacks++;
295 if (quiet)
296 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000297 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000298 return(0);
299}
300
301/**
Daniel Veillard06047432000-04-24 11:33:38 +0000302 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000303 * @ctxt: An XML parser context
304 *
305 * Does this document has an internal subset
306 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000307static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000308internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000309 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000310{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000311 callbacks++;
312 if (quiet)
313 return;
Daniel Veillard808a3f12000-08-17 13:50:51 +0000314 fprintf(stdout, "SAX.internalSubset(%s,", name);
315 if (ExternalID == NULL)
316 fprintf(stdout, " ,");
317 else
318 fprintf(stdout, " %s,", ExternalID);
319 if (SystemID == NULL)
320 fprintf(stdout, " )\n");
321 else
322 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000323}
324
325/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000326 * externalSubsetDebug:
327 * @ctxt: An XML parser context
328 *
329 * Does this document has an external subset
330 */
331static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000332externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000333 const xmlChar *ExternalID, const xmlChar *SystemID)
334{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000335 callbacks++;
336 if (quiet)
337 return;
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000338 fprintf(stdout, "SAX.externalSubset(%s,", name);
339 if (ExternalID == NULL)
340 fprintf(stdout, " ,");
341 else
342 fprintf(stdout, " %s,", ExternalID);
343 if (SystemID == NULL)
344 fprintf(stdout, " )\n");
345 else
346 fprintf(stdout, " %s)\n", SystemID);
347}
348
349/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000350 * resolveEntityDebug:
351 * @ctxt: An XML parser context
352 * @publicId: The public ID of the entity
353 * @systemId: The system ID of the entity
354 *
355 * Special entity resolver, better left to the parser, it has
356 * more context than the application layer.
357 * The default behaviour is to NOT resolve the entities, in that case
358 * the ENTITY_REF nodes are built in the structure (and the parameter
359 * values).
360 *
361 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
362 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000363static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000364resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000365{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000366 callbacks++;
367 if (quiet)
368 return(NULL);
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000369 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000370
Daniel Veillard14fff061999-06-22 21:49:07 +0000371
372 fprintf(stdout, "SAX.resolveEntity(");
373 if (publicId != NULL)
374 fprintf(stdout, "%s", (char *)publicId);
375 else
376 fprintf(stdout, " ");
377 if (systemId != NULL)
378 fprintf(stdout, ", %s)\n", (char *)systemId);
379 else
380 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000381/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000382 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000383 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000384 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000385 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000386 return(NULL);
387}
388
389/**
390 * getEntityDebug:
391 * @ctxt: An XML parser context
392 * @name: The entity name
393 *
394 * Get an entity by name
395 *
396 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
397 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000398static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000399getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000400{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000401 callbacks++;
402 if (quiet)
403 return(NULL);
Daniel Veillard27d88741999-05-29 11:51:49 +0000404 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000405 return(NULL);
406}
407
Daniel Veillardb05deb71999-08-10 19:04:08 +0000408/**
409 * getParameterEntityDebug:
410 * @ctxt: An XML parser context
411 * @name: The entity name
412 *
413 * Get a parameter entity by name
414 *
415 * Returns the xmlParserInputPtr
416 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000417static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000418getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000419{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000420 callbacks++;
421 if (quiet)
422 return(NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000423 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
424 return(NULL);
425}
426
Daniel Veillard5099ae81999-04-21 20:12:07 +0000427
428/**
429 * entityDeclDebug:
430 * @ctxt: An XML parser context
431 * @name: the entity name
432 * @type: the entity type
433 * @publicId: The public ID of the entity
434 * @systemId: The system ID of the entity
435 * @content: the entity value (without processing).
436 *
437 * An entity definition has been parsed
438 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000439static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000440entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000441 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000442{
William M. Brack09a726f2004-02-28 14:47:18 +0000443const xmlChar *nullstr = BAD_CAST "(null)";
444 /* not all libraries handle printing null pointers nicely */
445 if (publicId == NULL)
446 publicId = nullstr;
447 if (systemId == NULL)
448 systemId = nullstr;
449 if (content == NULL)
450 content = (xmlChar *)nullstr;
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000451 callbacks++;
452 if (quiet)
453 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000454 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000455 name, type, publicId, systemId, content);
456}
457
458/**
459 * attributeDeclDebug:
460 * @ctxt: An XML parser context
461 * @name: the attribute name
462 * @type: the attribute type
463 *
464 * An attribute definition has been parsed
465 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000466static void
Daniel Veillard07cb8222003-09-10 10:51:05 +0000467attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
468 const xmlChar * name, int type, int def,
469 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000470{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000471 callbacks++;
472 if (quiet)
Daniel Veillard07cb8222003-09-10 10:51:05 +0000473 return;
Daniel Veillard7e99c632000-10-06 12:59:53 +0000474 if (defaultValue == NULL)
Daniel Veillard07cb8222003-09-10 10:51:05 +0000475 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
476 elem, name, type, def);
Daniel Veillard7e99c632000-10-06 12:59:53 +0000477 else
Daniel Veillard07cb8222003-09-10 10:51:05 +0000478 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
479 elem, name, type, def, defaultValue);
480 xmlFreeEnumeration(tree);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000481}
482
483/**
484 * elementDeclDebug:
485 * @ctxt: An XML parser context
486 * @name: the element name
487 * @type: the element type
488 * @content: the element value (without processing).
489 *
490 * An element definition has been parsed
491 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000492static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000493elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
494 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000495{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000496 callbacks++;
497 if (quiet)
498 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000499 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000500 name, type);
501}
502
503/**
504 * notationDeclDebug:
505 * @ctxt: An XML parser context
506 * @name: The name of the notation
507 * @publicId: The public ID of the entity
508 * @systemId: The system ID of the entity
509 *
510 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000511 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000512static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000513notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000514 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000515{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000516 callbacks++;
517 if (quiet)
518 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000519 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000520 (char *) name, (char *) publicId, (char *) systemId);
521}
522
523/**
524 * unparsedEntityDeclDebug:
525 * @ctxt: An XML parser context
526 * @name: The name of the entity
527 * @publicId: The public ID of the entity
528 * @systemId: The system ID of the entity
529 * @notationName: the name of the notation
530 *
531 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000532 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000533static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000534unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000535 const xmlChar *publicId, const xmlChar *systemId,
536 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000537{
William M. Brack09a726f2004-02-28 14:47:18 +0000538const xmlChar *nullstr = BAD_CAST "(null)";
539
540 if (publicId == NULL)
541 publicId = nullstr;
542 if (systemId == NULL)
543 systemId = nullstr;
544 if (notationName == NULL)
545 notationName = nullstr;
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000546 callbacks++;
547 if (quiet)
548 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000549 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000550 (char *) name, (char *) publicId, (char *) systemId,
551 (char *) notationName);
552}
553
554/**
555 * setDocumentLocatorDebug:
556 * @ctxt: An XML parser context
557 * @loc: A SAX Locator
558 *
559 * Receive the document locator at startup, actually xmlDefaultSAXLocator
560 * Everything is available on the context, so this is useless in our case.
561 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000562static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000563setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000564{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000565 callbacks++;
566 if (quiet)
567 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000568 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000569}
570
571/**
572 * startDocumentDebug:
573 * @ctxt: An XML parser context
574 *
575 * called when the document start being processed.
576 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000577static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000578startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000579{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000580 callbacks++;
581 if (quiet)
582 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000583 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000584}
585
586/**
587 * endDocumentDebug:
588 * @ctxt: An XML parser context
589 *
590 * called when the document end has been detected.
591 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000592static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000593endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000594{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000595 callbacks++;
596 if (quiet)
597 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000598 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000599}
600
601/**
602 * startElementDebug:
603 * @ctxt: An XML parser context
604 * @name: The element name
605 *
606 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000607 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000608static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000609startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000610{
611 int i;
612
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000613 callbacks++;
614 if (quiet)
615 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000616 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000617 if (atts != NULL) {
618 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000619 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000620 if (atts[i] != NULL)
621 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000622 }
623 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000624 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000625}
626
627/**
628 * endElementDebug:
629 * @ctxt: An XML parser context
630 * @name: The element name
631 *
632 * called when the end of an element has been detected.
633 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000634static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000635endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000636{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000637 callbacks++;
638 if (quiet)
639 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000640 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000641}
642
643/**
644 * charactersDebug:
645 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000646 * @ch: a xmlChar string
647 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000648 *
649 * receiving some chars from the parser.
650 * Question: how much at a time ???
651 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000652static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000653charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000654{
Daniel Veillard87b95392000-08-12 21:12:04 +0000655 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000656 int i;
657
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000658 callbacks++;
659 if (quiet)
660 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000661 for (i = 0;(i<len) && (i < 30);i++)
662 output[i] = ch[i];
663 output[i] = 0;
664
665 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000666}
667
668/**
669 * referenceDebug:
670 * @ctxt: An XML parser context
671 * @name: The entity name
672 *
673 * called when an entity reference is detected.
674 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000675static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000676referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000677{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000678 callbacks++;
679 if (quiet)
680 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000681 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000682}
683
684/**
685 * ignorableWhitespaceDebug:
686 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000687 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000688 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000689 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000690 *
691 * receiving some ignorable whitespaces from the parser.
692 * Question: how much at a time ???
693 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000694static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000695ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000696{
Daniel Veillard87b95392000-08-12 21:12:04 +0000697 char output[40];
698 int i;
699
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000700 callbacks++;
701 if (quiet)
702 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000703 for (i = 0;(i<len) && (i < 30);i++)
704 output[i] = ch[i];
705 output[i] = 0;
706 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000707}
708
709/**
710 * processingInstructionDebug:
711 * @ctxt: An XML parser context
712 * @target: the target name
713 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000714 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000715 *
716 * A processing instruction has been parsed.
717 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000718static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000719processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000720 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000721{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000722 callbacks++;
723 if (quiet)
724 return;
Daniel Veillard4772af62003-10-27 16:23:43 +0000725 if (data != NULL)
726 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
727 (char *) target, (char *) data);
728 else
729 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
730 (char *) target);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000731}
732
733/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000734 * cdataBlockDebug:
735 * @ctx: the user data (XML parser context)
736 * @value: The pcdata content
737 * @len: the block length
738 *
739 * called when a pcdata block has been parsed
740 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000741static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000742cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000743{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000744 callbacks++;
745 if (quiet)
746 return;
Daniel Veillard39915622000-10-15 10:06:55 +0000747 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000748 (char *) value, len);
749}
750
751/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000752 * commentDebug:
753 * @ctxt: An XML parser context
754 * @value: the comment content
755 *
756 * A comment has been parsed.
757 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000758static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000759commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000760{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000761 callbacks++;
762 if (quiet)
763 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000764 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000765}
766
767/**
768 * warningDebug:
769 * @ctxt: An XML parser context
770 * @msg: the message to display/transmit
771 * @...: extra parameters for the message display
772 *
773 * Display and format a warning messages, gives file, line, position and
774 * extra parameters.
775 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000776static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000777warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000778{
779 va_list args;
780
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000781 callbacks++;
782 if (quiet)
783 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000784 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000785 fprintf(stdout, "SAX.warning: ");
786 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000787 va_end(args);
788}
789
790/**
791 * errorDebug:
792 * @ctxt: An XML parser context
793 * @msg: the message to display/transmit
794 * @...: extra parameters for the message display
795 *
796 * Display and format a error messages, gives file, line, position and
797 * extra parameters.
798 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000799static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000800errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000801{
802 va_list args;
803
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000804 callbacks++;
805 if (quiet)
806 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000807 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000808 fprintf(stdout, "SAX.error: ");
809 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000810 va_end(args);
811}
812
813/**
814 * fatalErrorDebug:
815 * @ctxt: An XML parser context
816 * @msg: the message to display/transmit
817 * @...: extra parameters for the message display
818 *
819 * Display and format a fatalError messages, gives file, line, position and
820 * extra parameters.
821 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000822static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000823fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000824{
825 va_list args;
826
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000827 callbacks++;
828 if (quiet)
829 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000830 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000831 fprintf(stdout, "SAX.fatalError: ");
832 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000833 va_end(args);
834}
835
836xmlSAXHandler debugSAXHandlerStruct = {
837 internalSubsetDebug,
838 isStandaloneDebug,
839 hasInternalSubsetDebug,
840 hasExternalSubsetDebug,
841 resolveEntityDebug,
842 getEntityDebug,
843 entityDeclDebug,
844 notationDeclDebug,
845 attributeDeclDebug,
846 elementDeclDebug,
847 unparsedEntityDeclDebug,
848 setDocumentLocatorDebug,
849 startDocumentDebug,
850 endDocumentDebug,
851 startElementDebug,
852 endElementDebug,
853 referenceDebug,
854 charactersDebug,
855 ignorableWhitespaceDebug,
856 processingInstructionDebug,
857 commentDebug,
858 warningDebug,
859 errorDebug,
860 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000861 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000862 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000863 externalSubsetDebug,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000864 1,
865 NULL,
866 NULL,
William M. Brack871611b2003-10-18 04:53:14 +0000867 NULL,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000868 NULL
Daniel Veillard5099ae81999-04-21 20:12:07 +0000869};
870
871xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
872
Daniel Veillard0fb18932003-09-07 09:14:37 +0000873/*
874 * SAX2 specific callbacks
875 */
876/**
Daniel Veillard07cb8222003-09-10 10:51:05 +0000877 * startElementNsDebug:
Daniel Veillard0fb18932003-09-07 09:14:37 +0000878 * @ctxt: An XML parser context
879 * @name: The element name
880 *
881 * called when an opening tag has been processed.
882 */
883static void
884startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
885 const xmlChar *localname,
886 const xmlChar *prefix,
887 const xmlChar *URI,
888 int nb_namespaces,
889 const xmlChar **namespaces,
Daniel Veillard07cb8222003-09-10 10:51:05 +0000890 int nb_attributes,
891 int nb_defaulted,
892 const xmlChar **attributes)
Daniel Veillard0fb18932003-09-07 09:14:37 +0000893{
894 int i;
895
896 callbacks++;
897 if (quiet)
898 return;
899 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
900 if (prefix == NULL)
901 fprintf(stdout, ", NULL");
902 else
903 fprintf(stdout, ", %s", (char *) prefix);
904 if (URI == NULL)
905 fprintf(stdout, ", NULL");
906 else
907 fprintf(stdout, ", '%s'", (char *) URI);
908 fprintf(stdout, ", %d", nb_namespaces);
909
910 if (namespaces != NULL) {
911 for (i = 0;i < nb_namespaces * 2;i++) {
912 fprintf(stdout, ", xmlns");
913 if (namespaces[i] != NULL)
914 fprintf(stdout, ":%s", namespaces[i]);
915 i++;
916 fprintf(stdout, "='%s'", namespaces[i]);
917 }
918 }
Daniel Veillard07cb8222003-09-10 10:51:05 +0000919 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
920 if (attributes != NULL) {
William M. Brack06112d12004-06-02 03:41:21 +0000921 for (i = 0;i < nb_attributes * 5;i += 5) {
Daniel Veillard07cb8222003-09-10 10:51:05 +0000922 if (attributes[i + 1] != NULL)
923 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
924 else
925 fprintf(stdout, ", %s='", attributes[i]);
926 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
William M. Brack76e95df2003-10-18 16:20:14 +0000927 (int)(attributes[i + 4] - attributes[i + 3]));
Daniel Veillard07cb8222003-09-10 10:51:05 +0000928 }
929 }
930 fprintf(stdout, ")\n");
Daniel Veillard0fb18932003-09-07 09:14:37 +0000931}
932
933/**
934 * endElementDebug:
935 * @ctxt: An XML parser context
936 * @name: The element name
937 *
938 * called when the end of an element has been detected.
939 */
940static void
941endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
942 const xmlChar *localname,
943 const xmlChar *prefix,
944 const xmlChar *URI)
945{
946 callbacks++;
947 if (quiet)
948 return;
949 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
950 if (prefix == NULL)
951 fprintf(stdout, ", NULL");
952 else
953 fprintf(stdout, ", %s", (char *) prefix);
954 if (URI == NULL)
955 fprintf(stdout, ", NULL)\n");
956 else
957 fprintf(stdout, ", '%s')\n", (char *) URI);
958}
959
Daniel Veillard0fb18932003-09-07 09:14:37 +0000960xmlSAXHandler debugSAX2HandlerStruct = {
961 internalSubsetDebug,
962 isStandaloneDebug,
963 hasInternalSubsetDebug,
964 hasExternalSubsetDebug,
965 resolveEntityDebug,
966 getEntityDebug,
967 entityDeclDebug,
968 notationDeclDebug,
969 attributeDeclDebug,
970 elementDeclDebug,
971 unparsedEntityDeclDebug,
972 setDocumentLocatorDebug,
973 startDocumentDebug,
974 endDocumentDebug,
975 NULL,
976 NULL,
977 referenceDebug,
978 charactersDebug,
979 ignorableWhitespaceDebug,
980 processingInstructionDebug,
981 commentDebug,
982 warningDebug,
983 errorDebug,
984 fatalErrorDebug,
985 getParameterEntityDebug,
986 cdataBlockDebug,
987 externalSubsetDebug,
Daniel Veillard07cb8222003-09-10 10:51:05 +0000988 XML_SAX2_MAGIC,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000989 NULL,
990 startElementNsDebug,
William M. Brack871611b2003-10-18 04:53:14 +0000991 endElementNsDebug,
992 NULL
Daniel Veillard0fb18932003-09-07 09:14:37 +0000993};
994
995xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
996
Daniel Veillard5099ae81999-04-21 20:12:07 +0000997/************************************************************************
998 * *
999 * Debug *
1000 * *
1001 ************************************************************************/
1002
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001003static void
1004parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +00001005 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001006
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001007 if (push) {
1008 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001009
Daniel Veillard0fb18932003-09-07 09:14:37 +00001010 if ((!quiet) && (!nonull)) {
1011 /*
1012 * Empty callbacks for checking
1013 */
1014 f = fopen(filename, "r");
1015 if (f != NULL) {
1016 int ret;
1017 char chars[10];
1018 xmlParserCtxtPtr ctxt;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001019
Daniel Veillard0fb18932003-09-07 09:14:37 +00001020 ret = fread(chars, 1, 4, f);
1021 if (ret > 0) {
1022 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
1023 chars, ret, filename);
1024 while ((ret = fread(chars, 1, 3, f)) > 0) {
1025 xmlParseChunk(ctxt, chars, ret, 0);
1026 }
1027 xmlParseChunk(ctxt, chars, 0, 1);
1028 xmlFreeParserCtxt(ctxt);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001029 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001030 fclose(f);
1031 } else {
1032 xmlGenericError(xmlGenericErrorContext,
1033 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001034 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001035 }
1036 /*
1037 * Debug callback
1038 */
1039 f = fopen(filename, "r");
1040 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001041 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001042 char chars[10];
1043 xmlParserCtxtPtr ctxt;
1044
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001045 ret = fread(chars, 1, 4, f);
1046 if (ret > 0) {
Daniel Veillard0fb18932003-09-07 09:14:37 +00001047 if (sax2)
1048 ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
1049 chars, ret, filename);
1050 else
1051 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
1052 chars, ret, filename);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001053 while ((ret = fread(chars, 1, 3, f)) > 0) {
1054 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001055 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001056 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001057 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001058 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001059 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001060 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001061 }
1062 }
1063 fclose(f);
1064 }
1065 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +00001066 if (!speed) {
1067 /*
1068 * Empty callbacks for checking
1069 */
Daniel Veillard0fb18932003-09-07 09:14:37 +00001070 if ((!quiet) && (!nonull)) {
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001071 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1072 if (res != 0) {
1073 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1074 }
Daniel Veillard5e873c42000-04-12 13:27:38 +00001075 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001076
Daniel Veillard5e873c42000-04-12 13:27:38 +00001077 /*
1078 * Debug callback
1079 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001080 callbacks = 0;
Daniel Veillard4773df22004-01-23 13:15:13 +00001081 if (repeat) {
1082 int i;
1083 for (i = 0;i < 99;i++) {
1084 if (sax2)
1085 res = xmlSAXUserParseFile(debugSAX2Handler, NULL,
1086 filename);
1087 else
1088 res = xmlSAXUserParseFile(debugSAXHandler, NULL,
1089 filename);
1090 }
1091 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001092 if (sax2)
1093 res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
1094 else
1095 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001096 if (res != 0) {
1097 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1098 }
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001099 if (quiet)
1100 fprintf(stdout, "%d callbacks generated\n", callbacks);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001101 } else {
1102 /*
1103 * test 100x the SAX parse
1104 */
1105 int i;
1106
1107 for (i = 0; i<100;i++)
1108 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1109 if (res != 0) {
1110 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1111 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001112 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001113 }
1114}
1115
Daniel Veillard5099ae81999-04-21 20:12:07 +00001116
1117int main(int argc, char **argv) {
1118 int i;
1119 int files = 0;
1120
William M. Brack06112d12004-06-02 03:41:21 +00001121 LIBXML_TEST_VERSION /* be safe, plus calls xmlInitParser */
1122
Daniel Veillard5099ae81999-04-21 20:12:07 +00001123 for (i = 1; i < argc ; i++) {
1124 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1125 debug++;
1126 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1127 copy++;
1128 else if ((!strcmp(argv[i], "-recover")) ||
1129 (!strcmp(argv[i], "--recover")))
1130 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001131 else if ((!strcmp(argv[i], "-push")) ||
1132 (!strcmp(argv[i], "--push")))
1133 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +00001134 else if ((!strcmp(argv[i], "-speed")) ||
1135 (!strcmp(argv[i], "--speed")))
1136 speed++;
Daniel Veillard807daf82004-02-22 22:13:27 +00001137 else if ((!strcmp(argv[i], "-timing")) ||
1138 (!strcmp(argv[i], "--timing"))) {
1139 nonull++;
1140 timing++;
1141 quiet++;
1142 } else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard4773df22004-01-23 13:15:13 +00001143 (!strcmp(argv[i], "--repeat"))) {
1144 repeat++;
1145 quiet++;
1146 } else if ((!strcmp(argv[i], "-noent")) ||
Daniel Veillard5997aca2002-03-18 18:36:20 +00001147 (!strcmp(argv[i], "--noent")))
1148 noent++;
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001149 else if ((!strcmp(argv[i], "-quiet")) ||
1150 (!strcmp(argv[i], "--quiet")))
1151 quiet++;
Daniel Veillard0fb18932003-09-07 09:14:37 +00001152 else if ((!strcmp(argv[i], "-sax2")) ||
1153 (!strcmp(argv[i], "--sax2")))
1154 sax2++;
1155 else if ((!strcmp(argv[i], "-nonull")) ||
1156 (!strcmp(argv[i], "--nonull")))
1157 nonull++;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001158 }
Daniel Veillard5997aca2002-03-18 18:36:20 +00001159 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +00001160 for (i = 1; i < argc ; i++) {
1161 if (argv[i][0] != '-') {
Daniel Veillard807daf82004-02-22 22:13:27 +00001162 if (timing) {
1163 startTimer();
1164 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001165 parseAndPrintFile(argv[i]);
Daniel Veillard807daf82004-02-22 22:13:27 +00001166 if (timing) {
1167 endTimer("Parsing");
1168 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001169 files ++;
1170 }
1171 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +00001172 xmlCleanupParser();
1173 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +00001174
1175 return(0);
1176}
Daniel Veillard81273902003-09-30 00:43:48 +00001177#else
1178int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1179 printf("%s : SAX1 parsing support not compiled in\n", argv[0]);
1180 return(0);
1181}
1182#endif /* LIBXML_SAX1_ENABLED */