blob: c18dd0ad065206c0bc45209603464ddef1e2610a [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 */
William M. Brack3403add2004-06-27 02:07:51 +00001014#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1015 f = fopen(filename, "rb");
1016#else
Daniel Veillard0fb18932003-09-07 09:14:37 +00001017 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00001018#endif
Daniel Veillard0fb18932003-09-07 09:14:37 +00001019 if (f != NULL) {
1020 int ret;
1021 char chars[10];
1022 xmlParserCtxtPtr ctxt;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001023
Daniel Veillard0fb18932003-09-07 09:14:37 +00001024 ret = fread(chars, 1, 4, f);
1025 if (ret > 0) {
1026 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
1027 chars, ret, filename);
1028 while ((ret = fread(chars, 1, 3, f)) > 0) {
1029 xmlParseChunk(ctxt, chars, ret, 0);
1030 }
1031 xmlParseChunk(ctxt, chars, 0, 1);
1032 xmlFreeParserCtxt(ctxt);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001033 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001034 fclose(f);
1035 } else {
1036 xmlGenericError(xmlGenericErrorContext,
1037 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001038 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001039 }
1040 /*
1041 * Debug callback
1042 */
William M. Brack3403add2004-06-27 02:07:51 +00001043#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1044 f = fopen(filename, "rb");
1045#else
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001046 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00001047#endif
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001048 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001049 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001050 char chars[10];
1051 xmlParserCtxtPtr ctxt;
1052
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001053 ret = fread(chars, 1, 4, f);
1054 if (ret > 0) {
Daniel Veillard0fb18932003-09-07 09:14:37 +00001055 if (sax2)
1056 ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
1057 chars, ret, filename);
1058 else
1059 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
1060 chars, ret, filename);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001061 while ((ret = fread(chars, 1, 3, f)) > 0) {
1062 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001063 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001064 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001065 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001066 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001067 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001068 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001069 }
1070 }
1071 fclose(f);
1072 }
1073 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +00001074 if (!speed) {
1075 /*
1076 * Empty callbacks for checking
1077 */
Daniel Veillard0fb18932003-09-07 09:14:37 +00001078 if ((!quiet) && (!nonull)) {
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001079 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1080 if (res != 0) {
1081 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1082 }
Daniel Veillard5e873c42000-04-12 13:27:38 +00001083 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001084
Daniel Veillard5e873c42000-04-12 13:27:38 +00001085 /*
1086 * Debug callback
1087 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001088 callbacks = 0;
Daniel Veillard4773df22004-01-23 13:15:13 +00001089 if (repeat) {
1090 int i;
1091 for (i = 0;i < 99;i++) {
1092 if (sax2)
1093 res = xmlSAXUserParseFile(debugSAX2Handler, NULL,
1094 filename);
1095 else
1096 res = xmlSAXUserParseFile(debugSAXHandler, NULL,
1097 filename);
1098 }
1099 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001100 if (sax2)
1101 res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
1102 else
1103 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001104 if (res != 0) {
1105 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1106 }
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001107 if (quiet)
1108 fprintf(stdout, "%d callbacks generated\n", callbacks);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001109 } else {
1110 /*
1111 * test 100x the SAX parse
1112 */
1113 int i;
1114
1115 for (i = 0; i<100;i++)
1116 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1117 if (res != 0) {
1118 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1119 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001120 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001121 }
1122}
1123
Daniel Veillard5099ae81999-04-21 20:12:07 +00001124
1125int main(int argc, char **argv) {
1126 int i;
1127 int files = 0;
1128
William M. Brack06112d12004-06-02 03:41:21 +00001129 LIBXML_TEST_VERSION /* be safe, plus calls xmlInitParser */
1130
Daniel Veillard5099ae81999-04-21 20:12:07 +00001131 for (i = 1; i < argc ; i++) {
1132 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1133 debug++;
1134 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1135 copy++;
1136 else if ((!strcmp(argv[i], "-recover")) ||
1137 (!strcmp(argv[i], "--recover")))
1138 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001139 else if ((!strcmp(argv[i], "-push")) ||
1140 (!strcmp(argv[i], "--push")))
1141 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +00001142 else if ((!strcmp(argv[i], "-speed")) ||
1143 (!strcmp(argv[i], "--speed")))
1144 speed++;
Daniel Veillard807daf82004-02-22 22:13:27 +00001145 else if ((!strcmp(argv[i], "-timing")) ||
1146 (!strcmp(argv[i], "--timing"))) {
1147 nonull++;
1148 timing++;
1149 quiet++;
1150 } else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard4773df22004-01-23 13:15:13 +00001151 (!strcmp(argv[i], "--repeat"))) {
1152 repeat++;
1153 quiet++;
1154 } else if ((!strcmp(argv[i], "-noent")) ||
Daniel Veillard5997aca2002-03-18 18:36:20 +00001155 (!strcmp(argv[i], "--noent")))
1156 noent++;
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001157 else if ((!strcmp(argv[i], "-quiet")) ||
1158 (!strcmp(argv[i], "--quiet")))
1159 quiet++;
Daniel Veillard0fb18932003-09-07 09:14:37 +00001160 else if ((!strcmp(argv[i], "-sax2")) ||
1161 (!strcmp(argv[i], "--sax2")))
1162 sax2++;
1163 else if ((!strcmp(argv[i], "-nonull")) ||
1164 (!strcmp(argv[i], "--nonull")))
1165 nonull++;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001166 }
Daniel Veillard5997aca2002-03-18 18:36:20 +00001167 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +00001168 for (i = 1; i < argc ; i++) {
1169 if (argv[i][0] != '-') {
Daniel Veillard807daf82004-02-22 22:13:27 +00001170 if (timing) {
1171 startTimer();
1172 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001173 parseAndPrintFile(argv[i]);
Daniel Veillard807daf82004-02-22 22:13:27 +00001174 if (timing) {
1175 endTimer("Parsing");
1176 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001177 files ++;
1178 }
1179 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +00001180 xmlCleanupParser();
1181 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +00001182
1183 return(0);
1184}
Daniel Veillard81273902003-09-30 00:43:48 +00001185#else
1186int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1187 printf("%s : SAX1 parsing support not compiled in\n", argv[0]);
1188 return(0);
1189}
1190#endif /* LIBXML_SAX1_ENABLED */