blob: accd2f315d498c7baa3877b6d54092ac49d87c18 [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
14#ifdef HAVE_TIME_H
15#include <time.h>
16#endif
17
Daniel Veillard81273902003-09-30 00:43:48 +000018#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard7f7d1111999-09-22 09:46:25 +000019#include <string.h>
20#include <stdarg.h>
21
22#ifdef HAVE_SYS_TYPES_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000023#include <sys/types.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000024#endif
Daniel Veillard5099ae81999-04-21 20:12:07 +000025#ifdef HAVE_SYS_STAT_H
26#include <sys/stat.h>
27#endif
28#ifdef HAVE_FCNTL_H
29#include <fcntl.h>
30#endif
31#ifdef HAVE_UNISTD_H
32#include <unistd.h>
33#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000034#ifdef HAVE_STDLIB_H
Daniel Veillard5099ae81999-04-21 20:12:07 +000035#include <stdlib.h>
Daniel Veillard7f7d1111999-09-22 09:46:25 +000036#endif
Daniel Veillard7a66ee61999-09-26 11:31:02 +000037#ifdef HAVE_STRING_H
38#include <string.h>
39#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +000040
Daniel Veillard5099ae81999-04-21 20:12:07 +000041
Daniel Veillardd0463562001-10-13 09:15:48 +000042#include <libxml/globals.h>
Daniel Veillardb71379b2000-10-09 12:30:39 +000043#include <libxml/xmlerror.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000044#include <libxml/parser.h>
45#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
46#include <libxml/tree.h>
47#include <libxml/debugXML.h>
48#include <libxml/xmlmemory.h>
Daniel Veillard5099ae81999-04-21 20:12:07 +000049
50static int debug = 0;
51static int copy = 0;
52static int recovery = 0;
Daniel Veillarddbfd6411999-12-28 16:35:14 +000053static int push = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +000054static int speed = 0;
Daniel Veillard5997aca2002-03-18 18:36:20 +000055static int noent = 0;
Daniel Veillarde50f3b52002-03-20 19:24:21 +000056static int quiet = 0;
Daniel Veillard0fb18932003-09-07 09:14:37 +000057static int nonull = 0;
58static int sax2 = 0;
Daniel Veillard4773df22004-01-23 13:15:13 +000059static int repeat = 0;
Daniel Veillarde50f3b52002-03-20 19:24:21 +000060static int callbacks = 0;
Daniel Veillard807daf82004-02-22 22:13:27 +000061static int timing = 0;
Daniel Veillard5099ae81999-04-21 20:12:07 +000062
Daniel Veillard807daf82004-02-22 22:13:27 +000063/*
64 * Timing routines.
65 */
66/*
67 * Internal timing routines to remove the necessity to have unix-specific
68 * function calls
69 */
70
71#ifndef HAVE_GETTIMEOFDAY
72#ifdef HAVE_SYS_TIMEB_H
73#ifdef HAVE_SYS_TIME_H
74#ifdef HAVE_FTIME
75
76static int
77my_gettimeofday(struct timeval *tvp, void *tzp)
78{
79 struct timeb timebuffer;
80
81 ftime(&timebuffer);
82 if (tvp) {
83 tvp->tv_sec = timebuffer.time;
84 tvp->tv_usec = timebuffer.millitm * 1000L;
85 }
86 return (0);
87}
88#define HAVE_GETTIMEOFDAY 1
89#define gettimeofday my_gettimeofday
90
91#endif /* HAVE_FTIME */
92#endif /* HAVE_SYS_TIME_H */
93#endif /* HAVE_SYS_TIMEB_H */
94#endif /* !HAVE_GETTIMEOFDAY */
95
96#if defined(HAVE_GETTIMEOFDAY)
97static struct timeval begin, end;
98
99/*
100 * startTimer: call where you want to start timing
101 */
102static void
103startTimer(void)
104{
105 gettimeofday(&begin, NULL);
106}
107
108/*
109 * endTimer: call where you want to stop timing and to print out a
110 * message about the timing performed; format is a printf
111 * type argument
112 */
113static void
114endTimer(const char *fmt, ...)
115{
116 long msec;
117 va_list ap;
118
119 gettimeofday(&end, NULL);
120 msec = end.tv_sec - begin.tv_sec;
121 msec *= 1000;
122 msec += (end.tv_usec - begin.tv_usec) / 1000;
123
124#ifndef HAVE_STDARG_H
125#error "endTimer required stdarg functions"
126#endif
127 va_start(ap, fmt);
128 vfprintf(stderr, fmt, ap);
129 va_end(ap);
130
131 fprintf(stderr, " took %ld ms\n", msec);
132}
133#elif defined(HAVE_TIME_H)
134/*
135 * No gettimeofday function, so we have to make do with calling clock.
136 * This is obviously less accurate, but there's little we can do about
137 * that.
138 */
139#ifndef CLOCKS_PER_SEC
140#define CLOCKS_PER_SEC 100
141#endif
142
143static clock_t begin, end;
144static void
145startTimer(void)
146{
147 begin = clock();
148}
149static void
150endTimer(const char *fmt, ...)
151{
152 long msec;
153 va_list ap;
154
155 end = clock();
156 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
157
158#ifndef HAVE_STDARG_H
159#error "endTimer required stdarg functions"
160#endif
161 va_start(ap, fmt);
162 vfprintf(stderr, fmt, ap);
163 va_end(ap);
164 fprintf(stderr, " took %ld ms\n", msec);
165}
166#else
167
168/*
169 * We don't have a gettimeofday or time.h, so we just don't do timing
170 */
171static void
172startTimer(void)
173{
174 /*
175 * Do nothing
176 */
177}
178static void
179endTimer(char *format, ...)
180{
181 /*
182 * We cannot do anything because we don't have a timing function
183 */
184#ifdef HAVE_STDARG_H
185 va_start(ap, format);
186 vfprintf(stderr, format, ap);
187 va_end(ap);
188 fprintf(stderr, " was not timed\n", msec);
189#else
190 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
191 * this ?!
192 */
193#endif
194}
195#endif
196
197/*
198 * empty SAX block
199 */
Daniel Veillard5099ae81999-04-21 20:12:07 +0000200xmlSAXHandler emptySAXHandlerStruct = {
201 NULL, /* internalSubset */
202 NULL, /* isStandalone */
203 NULL, /* hasInternalSubset */
204 NULL, /* hasExternalSubset */
205 NULL, /* resolveEntity */
206 NULL, /* getEntity */
207 NULL, /* entityDecl */
208 NULL, /* notationDecl */
209 NULL, /* attributeDecl */
210 NULL, /* elementDecl */
211 NULL, /* unparsedEntityDecl */
212 NULL, /* setDocumentLocator */
213 NULL, /* startDocument */
214 NULL, /* endDocument */
215 NULL, /* startElement */
216 NULL, /* endElement */
217 NULL, /* reference */
218 NULL, /* characters */
219 NULL, /* ignorableWhitespace */
220 NULL, /* processingInstruction */
221 NULL, /* comment */
222 NULL, /* xmlParserWarning */
223 NULL, /* xmlParserError */
224 NULL, /* xmlParserError */
Daniel Veillardb05deb71999-08-10 19:04:08 +0000225 NULL, /* getParameterEntity */
Daniel Veillardcf461992000-03-14 18:30:20 +0000226 NULL, /* cdataBlock; */
Daniel Veillard0fb18932003-09-07 09:14:37 +0000227 NULL, /* externalSubset; */
228 1,
229 NULL,
230 NULL, /* startElementNs */
William M. Brack871611b2003-10-18 04:53:14 +0000231 NULL, /* endElementNs */
232 NULL /* xmlStructuredErrorFunc */
Daniel Veillard5099ae81999-04-21 20:12:07 +0000233};
234
235xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillard011b63c1999-06-02 17:44:04 +0000236extern xmlSAXHandlerPtr debugSAXHandler;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000237
Daniel Veillard5099ae81999-04-21 20:12:07 +0000238/************************************************************************
239 * *
240 * Debug Handlers *
241 * *
242 ************************************************************************/
243
244/**
245 * isStandaloneDebug:
246 * @ctxt: An XML parser context
247 *
248 * Is this document tagged standalone ?
249 *
250 * Returns 1 if true
251 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000252static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000253isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000254{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000255 callbacks++;
256 if (quiet)
257 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000258 fprintf(stdout, "SAX.isStandalone()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000259 return(0);
260}
261
262/**
263 * hasInternalSubsetDebug:
264 * @ctxt: An XML parser context
265 *
266 * Does this document has an internal subset
267 *
268 * Returns 1 if true
269 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000270static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000271hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000272{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000273 callbacks++;
274 if (quiet)
275 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000276 fprintf(stdout, "SAX.hasInternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000277 return(0);
278}
279
280/**
281 * hasExternalSubsetDebug:
282 * @ctxt: An XML parser context
283 *
284 * Does this document has an external subset
285 *
286 * Returns 1 if true
287 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000288static int
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000289hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000290{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000291 callbacks++;
292 if (quiet)
293 return(0);
Daniel Veillard27d88741999-05-29 11:51:49 +0000294 fprintf(stdout, "SAX.hasExternalSubset()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000295 return(0);
296}
297
298/**
Daniel Veillard06047432000-04-24 11:33:38 +0000299 * internalSubsetDebug:
Daniel Veillard5099ae81999-04-21 20:12:07 +0000300 * @ctxt: An XML parser context
301 *
302 * Does this document has an internal subset
303 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000304static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000305internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000306 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000307{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000308 callbacks++;
309 if (quiet)
310 return;
Daniel Veillard808a3f12000-08-17 13:50:51 +0000311 fprintf(stdout, "SAX.internalSubset(%s,", name);
312 if (ExternalID == NULL)
313 fprintf(stdout, " ,");
314 else
315 fprintf(stdout, " %s,", ExternalID);
316 if (SystemID == NULL)
317 fprintf(stdout, " )\n");
318 else
319 fprintf(stdout, " %s)\n", SystemID);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000320}
321
322/**
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000323 * externalSubsetDebug:
324 * @ctxt: An XML parser context
325 *
326 * Does this document has an external subset
327 */
328static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000329externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000330 const xmlChar *ExternalID, const xmlChar *SystemID)
331{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000332 callbacks++;
333 if (quiet)
334 return;
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000335 fprintf(stdout, "SAX.externalSubset(%s,", name);
336 if (ExternalID == NULL)
337 fprintf(stdout, " ,");
338 else
339 fprintf(stdout, " %s,", ExternalID);
340 if (SystemID == NULL)
341 fprintf(stdout, " )\n");
342 else
343 fprintf(stdout, " %s)\n", SystemID);
344}
345
346/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000347 * resolveEntityDebug:
348 * @ctxt: An XML parser context
349 * @publicId: The public ID of the entity
350 * @systemId: The system ID of the entity
351 *
352 * Special entity resolver, better left to the parser, it has
353 * more context than the application layer.
354 * The default behaviour is to NOT resolve the entities, in that case
355 * the ENTITY_REF nodes are built in the structure (and the parameter
356 * values).
357 *
358 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
359 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000360static xmlParserInputPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000361resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000362{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000363 callbacks++;
364 if (quiet)
365 return(NULL);
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000366 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000367
Daniel Veillard14fff061999-06-22 21:49:07 +0000368
369 fprintf(stdout, "SAX.resolveEntity(");
370 if (publicId != NULL)
371 fprintf(stdout, "%s", (char *)publicId);
372 else
373 fprintf(stdout, " ");
374 if (systemId != NULL)
375 fprintf(stdout, ", %s)\n", (char *)systemId);
376 else
377 fprintf(stdout, ", )\n");
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000378/*********
Daniel Veillard011b63c1999-06-02 17:44:04 +0000379 if (systemId != NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000380 return(xmlNewInputFromFile(ctxt, (char *) systemId));
Daniel Veillard011b63c1999-06-02 17:44:04 +0000381 }
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000382 *********/
Daniel Veillard5099ae81999-04-21 20:12:07 +0000383 return(NULL);
384}
385
386/**
387 * getEntityDebug:
388 * @ctxt: An XML parser context
389 * @name: The entity name
390 *
391 * Get an entity by name
392 *
393 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
394 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000395static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000396getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000397{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000398 callbacks++;
399 if (quiet)
400 return(NULL);
Daniel Veillard27d88741999-05-29 11:51:49 +0000401 fprintf(stdout, "SAX.getEntity(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000402 return(NULL);
403}
404
Daniel Veillardb05deb71999-08-10 19:04:08 +0000405/**
406 * getParameterEntityDebug:
407 * @ctxt: An XML parser context
408 * @name: The entity name
409 *
410 * Get a parameter entity by name
411 *
412 * Returns the xmlParserInputPtr
413 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000414static xmlEntityPtr
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000415getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000416{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000417 callbacks++;
418 if (quiet)
419 return(NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000420 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
421 return(NULL);
422}
423
Daniel Veillard5099ae81999-04-21 20:12:07 +0000424
425/**
426 * entityDeclDebug:
427 * @ctxt: An XML parser context
428 * @name: the entity name
429 * @type: the entity type
430 * @publicId: The public ID of the entity
431 * @systemId: The system ID of the entity
432 * @content: the entity value (without processing).
433 *
434 * An entity definition has been parsed
435 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000436static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000437entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000438 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000439{
William M. Brack09a726f2004-02-28 14:47:18 +0000440const xmlChar *nullstr = BAD_CAST "(null)";
441 /* not all libraries handle printing null pointers nicely */
442 if (publicId == NULL)
443 publicId = nullstr;
444 if (systemId == NULL)
445 systemId = nullstr;
446 if (content == NULL)
447 content = (xmlChar *)nullstr;
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000448 callbacks++;
449 if (quiet)
450 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000451 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000452 name, type, publicId, systemId, content);
453}
454
455/**
456 * attributeDeclDebug:
457 * @ctxt: An XML parser context
458 * @name: the attribute name
459 * @type: the attribute type
460 *
461 * An attribute definition has been parsed
462 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000463static void
Daniel Veillard07cb8222003-09-10 10:51:05 +0000464attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
465 const xmlChar * name, int type, int def,
466 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000467{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000468 callbacks++;
469 if (quiet)
Daniel Veillard07cb8222003-09-10 10:51:05 +0000470 return;
Daniel Veillard7e99c632000-10-06 12:59:53 +0000471 if (defaultValue == NULL)
Daniel Veillard07cb8222003-09-10 10:51:05 +0000472 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
473 elem, name, type, def);
Daniel Veillard7e99c632000-10-06 12:59:53 +0000474 else
Daniel Veillard07cb8222003-09-10 10:51:05 +0000475 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
476 elem, name, type, def, defaultValue);
477 xmlFreeEnumeration(tree);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000478}
479
480/**
481 * elementDeclDebug:
482 * @ctxt: An XML parser context
483 * @name: the element name
484 * @type: the element type
485 * @content: the element value (without processing).
486 *
487 * An element definition has been parsed
488 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000489static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000490elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
491 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000492{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000493 callbacks++;
494 if (quiet)
495 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000496 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000497 name, type);
498}
499
500/**
501 * notationDeclDebug:
502 * @ctxt: An XML parser context
503 * @name: The name of the notation
504 * @publicId: The public ID of the entity
505 * @systemId: The system ID of the entity
506 *
507 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000508 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000509static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000510notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000511 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000512{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000513 callbacks++;
514 if (quiet)
515 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000516 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000517 (char *) name, (char *) publicId, (char *) systemId);
518}
519
520/**
521 * unparsedEntityDeclDebug:
522 * @ctxt: An XML parser context
523 * @name: The name of the entity
524 * @publicId: The public ID of the entity
525 * @systemId: The system ID of the entity
526 * @notationName: the name of the notation
527 *
528 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000529 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000530static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000531unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000532 const xmlChar *publicId, const xmlChar *systemId,
533 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000534{
William M. Brack09a726f2004-02-28 14:47:18 +0000535const xmlChar *nullstr = BAD_CAST "(null)";
536
537 if (publicId == NULL)
538 publicId = nullstr;
539 if (systemId == NULL)
540 systemId = nullstr;
541 if (notationName == NULL)
542 notationName = nullstr;
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000543 callbacks++;
544 if (quiet)
545 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000546 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000547 (char *) name, (char *) publicId, (char *) systemId,
548 (char *) notationName);
549}
550
551/**
552 * setDocumentLocatorDebug:
553 * @ctxt: An XML parser context
554 * @loc: A SAX Locator
555 *
556 * Receive the document locator at startup, actually xmlDefaultSAXLocator
557 * Everything is available on the context, so this is useless in our case.
558 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000559static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000560setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000561{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000562 callbacks++;
563 if (quiet)
564 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000565 fprintf(stdout, "SAX.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000566}
567
568/**
569 * startDocumentDebug:
570 * @ctxt: An XML parser context
571 *
572 * called when the document start being processed.
573 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000574static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000575startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000576{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000577 callbacks++;
578 if (quiet)
579 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000580 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000581}
582
583/**
584 * endDocumentDebug:
585 * @ctxt: An XML parser context
586 *
587 * called when the document end has been detected.
588 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000589static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000590endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000591{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000592 callbacks++;
593 if (quiet)
594 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000595 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000596}
597
598/**
599 * startElementDebug:
600 * @ctxt: An XML parser context
601 * @name: The element name
602 *
603 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000604 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000605static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000606startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000607{
608 int i;
609
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000610 callbacks++;
611 if (quiet)
612 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000613 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000614 if (atts != NULL) {
615 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000616 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000617 if (atts[i] != NULL)
618 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000619 }
620 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000621 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000622}
623
624/**
625 * endElementDebug:
626 * @ctxt: An XML parser context
627 * @name: The element name
628 *
629 * called when the end of an element has been detected.
630 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000631static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000632endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000633{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000634 callbacks++;
635 if (quiet)
636 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000637 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000638}
639
640/**
641 * charactersDebug:
642 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000643 * @ch: a xmlChar string
644 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000645 *
646 * receiving some chars from the parser.
647 * Question: how much at a time ???
648 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000649static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000650charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000651{
Daniel Veillard87b95392000-08-12 21:12:04 +0000652 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000653 int i;
654
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000655 callbacks++;
656 if (quiet)
657 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000658 for (i = 0;(i<len) && (i < 30);i++)
659 output[i] = ch[i];
660 output[i] = 0;
661
662 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000663}
664
665/**
666 * referenceDebug:
667 * @ctxt: An XML parser context
668 * @name: The entity name
669 *
670 * called when an entity reference is detected.
671 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000672static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000673referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000674{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000675 callbacks++;
676 if (quiet)
677 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000678 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000679}
680
681/**
682 * ignorableWhitespaceDebug:
683 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000684 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000685 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000686 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000687 *
688 * receiving some ignorable whitespaces from the parser.
689 * Question: how much at a time ???
690 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000691static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000692ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000693{
Daniel Veillard87b95392000-08-12 21:12:04 +0000694 char output[40];
695 int i;
696
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000697 callbacks++;
698 if (quiet)
699 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000700 for (i = 0;(i<len) && (i < 30);i++)
701 output[i] = ch[i];
702 output[i] = 0;
703 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000704}
705
706/**
707 * processingInstructionDebug:
708 * @ctxt: An XML parser context
709 * @target: the target name
710 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000711 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000712 *
713 * A processing instruction has been parsed.
714 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000715static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000716processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000717 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000718{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000719 callbacks++;
720 if (quiet)
721 return;
Daniel Veillard4772af62003-10-27 16:23:43 +0000722 if (data != NULL)
723 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
724 (char *) target, (char *) data);
725 else
726 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
727 (char *) target);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000728}
729
730/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000731 * cdataBlockDebug:
732 * @ctx: the user data (XML parser context)
733 * @value: The pcdata content
734 * @len: the block length
735 *
736 * called when a pcdata block has been parsed
737 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000738static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000739cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000740{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000741 callbacks++;
742 if (quiet)
743 return;
Daniel Veillard39915622000-10-15 10:06:55 +0000744 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000745 (char *) value, len);
746}
747
748/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000749 * commentDebug:
750 * @ctxt: An XML parser context
751 * @value: the comment content
752 *
753 * A comment has been parsed.
754 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000755static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000756commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000757{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000758 callbacks++;
759 if (quiet)
760 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000761 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000762}
763
764/**
765 * warningDebug:
766 * @ctxt: An XML parser context
767 * @msg: the message to display/transmit
768 * @...: extra parameters for the message display
769 *
770 * Display and format a warning messages, gives file, line, position and
771 * extra parameters.
772 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000773static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000774warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000775{
776 va_list args;
777
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000778 callbacks++;
779 if (quiet)
780 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000781 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000782 fprintf(stdout, "SAX.warning: ");
783 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000784 va_end(args);
785}
786
787/**
788 * errorDebug:
789 * @ctxt: An XML parser context
790 * @msg: the message to display/transmit
791 * @...: extra parameters for the message display
792 *
793 * Display and format a error messages, gives file, line, position and
794 * extra parameters.
795 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000796static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000797errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000798{
799 va_list args;
800
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000801 callbacks++;
802 if (quiet)
803 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000804 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000805 fprintf(stdout, "SAX.error: ");
806 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000807 va_end(args);
808}
809
810/**
811 * fatalErrorDebug:
812 * @ctxt: An XML parser context
813 * @msg: the message to display/transmit
814 * @...: extra parameters for the message display
815 *
816 * Display and format a fatalError messages, gives file, line, position and
817 * extra parameters.
818 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000819static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000820fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000821{
822 va_list args;
823
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000824 callbacks++;
825 if (quiet)
826 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000827 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000828 fprintf(stdout, "SAX.fatalError: ");
829 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000830 va_end(args);
831}
832
833xmlSAXHandler debugSAXHandlerStruct = {
834 internalSubsetDebug,
835 isStandaloneDebug,
836 hasInternalSubsetDebug,
837 hasExternalSubsetDebug,
838 resolveEntityDebug,
839 getEntityDebug,
840 entityDeclDebug,
841 notationDeclDebug,
842 attributeDeclDebug,
843 elementDeclDebug,
844 unparsedEntityDeclDebug,
845 setDocumentLocatorDebug,
846 startDocumentDebug,
847 endDocumentDebug,
848 startElementDebug,
849 endElementDebug,
850 referenceDebug,
851 charactersDebug,
852 ignorableWhitespaceDebug,
853 processingInstructionDebug,
854 commentDebug,
855 warningDebug,
856 errorDebug,
857 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000858 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000859 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000860 externalSubsetDebug,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000861 1,
862 NULL,
863 NULL,
William M. Brack871611b2003-10-18 04:53:14 +0000864 NULL,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000865 NULL
Daniel Veillard5099ae81999-04-21 20:12:07 +0000866};
867
868xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
869
Daniel Veillard0fb18932003-09-07 09:14:37 +0000870/*
871 * SAX2 specific callbacks
872 */
873/**
Daniel Veillard07cb8222003-09-10 10:51:05 +0000874 * startElementNsDebug:
Daniel Veillard0fb18932003-09-07 09:14:37 +0000875 * @ctxt: An XML parser context
876 * @name: The element name
877 *
878 * called when an opening tag has been processed.
879 */
880static void
881startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
882 const xmlChar *localname,
883 const xmlChar *prefix,
884 const xmlChar *URI,
885 int nb_namespaces,
886 const xmlChar **namespaces,
Daniel Veillard07cb8222003-09-10 10:51:05 +0000887 int nb_attributes,
888 int nb_defaulted,
889 const xmlChar **attributes)
Daniel Veillard0fb18932003-09-07 09:14:37 +0000890{
891 int i;
892
893 callbacks++;
894 if (quiet)
895 return;
896 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
897 if (prefix == NULL)
898 fprintf(stdout, ", NULL");
899 else
900 fprintf(stdout, ", %s", (char *) prefix);
901 if (URI == NULL)
902 fprintf(stdout, ", NULL");
903 else
904 fprintf(stdout, ", '%s'", (char *) URI);
905 fprintf(stdout, ", %d", nb_namespaces);
906
907 if (namespaces != NULL) {
908 for (i = 0;i < nb_namespaces * 2;i++) {
909 fprintf(stdout, ", xmlns");
910 if (namespaces[i] != NULL)
911 fprintf(stdout, ":%s", namespaces[i]);
912 i++;
913 fprintf(stdout, "='%s'", namespaces[i]);
914 }
915 }
Daniel Veillard07cb8222003-09-10 10:51:05 +0000916 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
917 if (attributes != NULL) {
918 for (i = 0;i < nb_attributes;i += 5) {
919 if (attributes[i + 1] != NULL)
920 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
921 else
922 fprintf(stdout, ", %s='", attributes[i]);
923 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
William M. Brack76e95df2003-10-18 16:20:14 +0000924 (int)(attributes[i + 4] - attributes[i + 3]));
Daniel Veillard07cb8222003-09-10 10:51:05 +0000925 }
926 }
927 fprintf(stdout, ")\n");
Daniel Veillard0fb18932003-09-07 09:14:37 +0000928}
929
930/**
931 * endElementDebug:
932 * @ctxt: An XML parser context
933 * @name: The element name
934 *
935 * called when the end of an element has been detected.
936 */
937static void
938endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
939 const xmlChar *localname,
940 const xmlChar *prefix,
941 const xmlChar *URI)
942{
943 callbacks++;
944 if (quiet)
945 return;
946 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
947 if (prefix == NULL)
948 fprintf(stdout, ", NULL");
949 else
950 fprintf(stdout, ", %s", (char *) prefix);
951 if (URI == NULL)
952 fprintf(stdout, ", NULL)\n");
953 else
954 fprintf(stdout, ", '%s')\n", (char *) URI);
955}
956
Daniel Veillard0fb18932003-09-07 09:14:37 +0000957xmlSAXHandler debugSAX2HandlerStruct = {
958 internalSubsetDebug,
959 isStandaloneDebug,
960 hasInternalSubsetDebug,
961 hasExternalSubsetDebug,
962 resolveEntityDebug,
963 getEntityDebug,
964 entityDeclDebug,
965 notationDeclDebug,
966 attributeDeclDebug,
967 elementDeclDebug,
968 unparsedEntityDeclDebug,
969 setDocumentLocatorDebug,
970 startDocumentDebug,
971 endDocumentDebug,
972 NULL,
973 NULL,
974 referenceDebug,
975 charactersDebug,
976 ignorableWhitespaceDebug,
977 processingInstructionDebug,
978 commentDebug,
979 warningDebug,
980 errorDebug,
981 fatalErrorDebug,
982 getParameterEntityDebug,
983 cdataBlockDebug,
984 externalSubsetDebug,
Daniel Veillard07cb8222003-09-10 10:51:05 +0000985 XML_SAX2_MAGIC,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000986 NULL,
987 startElementNsDebug,
William M. Brack871611b2003-10-18 04:53:14 +0000988 endElementNsDebug,
989 NULL
Daniel Veillard0fb18932003-09-07 09:14:37 +0000990};
991
992xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
993
Daniel Veillard5099ae81999-04-21 20:12:07 +0000994/************************************************************************
995 * *
996 * Debug *
997 * *
998 ************************************************************************/
999
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001000static void
1001parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +00001002 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001003
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001004 if (push) {
1005 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001006
Daniel Veillard0fb18932003-09-07 09:14:37 +00001007 if ((!quiet) && (!nonull)) {
1008 /*
1009 * Empty callbacks for checking
1010 */
1011 f = fopen(filename, "r");
1012 if (f != NULL) {
1013 int ret;
1014 char chars[10];
1015 xmlParserCtxtPtr ctxt;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001016
Daniel Veillard0fb18932003-09-07 09:14:37 +00001017 ret = fread(chars, 1, 4, f);
1018 if (ret > 0) {
1019 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
1020 chars, ret, filename);
1021 while ((ret = fread(chars, 1, 3, f)) > 0) {
1022 xmlParseChunk(ctxt, chars, ret, 0);
1023 }
1024 xmlParseChunk(ctxt, chars, 0, 1);
1025 xmlFreeParserCtxt(ctxt);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001026 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001027 fclose(f);
1028 } else {
1029 xmlGenericError(xmlGenericErrorContext,
1030 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001031 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001032 }
1033 /*
1034 * Debug callback
1035 */
1036 f = fopen(filename, "r");
1037 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001038 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001039 char chars[10];
1040 xmlParserCtxtPtr ctxt;
1041
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001042 ret = fread(chars, 1, 4, f);
1043 if (ret > 0) {
Daniel Veillard0fb18932003-09-07 09:14:37 +00001044 if (sax2)
1045 ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
1046 chars, ret, filename);
1047 else
1048 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
1049 chars, ret, filename);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001050 while ((ret = fread(chars, 1, 3, f)) > 0) {
1051 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001052 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001053 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001054 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001055 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001056 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001057 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001058 }
1059 }
1060 fclose(f);
1061 }
1062 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +00001063 if (!speed) {
1064 /*
1065 * Empty callbacks for checking
1066 */
Daniel Veillard0fb18932003-09-07 09:14:37 +00001067 if ((!quiet) && (!nonull)) {
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001068 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1069 if (res != 0) {
1070 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1071 }
Daniel Veillard5e873c42000-04-12 13:27:38 +00001072 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001073
Daniel Veillard5e873c42000-04-12 13:27:38 +00001074 /*
1075 * Debug callback
1076 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001077 callbacks = 0;
Daniel Veillard4773df22004-01-23 13:15:13 +00001078 if (repeat) {
1079 int i;
1080 for (i = 0;i < 99;i++) {
1081 if (sax2)
1082 res = xmlSAXUserParseFile(debugSAX2Handler, NULL,
1083 filename);
1084 else
1085 res = xmlSAXUserParseFile(debugSAXHandler, NULL,
1086 filename);
1087 }
1088 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001089 if (sax2)
1090 res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
1091 else
1092 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001093 if (res != 0) {
1094 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1095 }
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001096 if (quiet)
1097 fprintf(stdout, "%d callbacks generated\n", callbacks);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001098 } else {
1099 /*
1100 * test 100x the SAX parse
1101 */
1102 int i;
1103
1104 for (i = 0; i<100;i++)
1105 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1106 if (res != 0) {
1107 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1108 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001109 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001110 }
1111}
1112
Daniel Veillard5099ae81999-04-21 20:12:07 +00001113
1114int main(int argc, char **argv) {
1115 int i;
1116 int files = 0;
1117
1118 for (i = 1; i < argc ; i++) {
1119 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1120 debug++;
1121 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1122 copy++;
1123 else if ((!strcmp(argv[i], "-recover")) ||
1124 (!strcmp(argv[i], "--recover")))
1125 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001126 else if ((!strcmp(argv[i], "-push")) ||
1127 (!strcmp(argv[i], "--push")))
1128 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +00001129 else if ((!strcmp(argv[i], "-speed")) ||
1130 (!strcmp(argv[i], "--speed")))
1131 speed++;
Daniel Veillard807daf82004-02-22 22:13:27 +00001132 else if ((!strcmp(argv[i], "-timing")) ||
1133 (!strcmp(argv[i], "--timing"))) {
1134 nonull++;
1135 timing++;
1136 quiet++;
1137 } else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard4773df22004-01-23 13:15:13 +00001138 (!strcmp(argv[i], "--repeat"))) {
1139 repeat++;
1140 quiet++;
1141 } else if ((!strcmp(argv[i], "-noent")) ||
Daniel Veillard5997aca2002-03-18 18:36:20 +00001142 (!strcmp(argv[i], "--noent")))
1143 noent++;
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001144 else if ((!strcmp(argv[i], "-quiet")) ||
1145 (!strcmp(argv[i], "--quiet")))
1146 quiet++;
Daniel Veillard0fb18932003-09-07 09:14:37 +00001147 else if ((!strcmp(argv[i], "-sax2")) ||
1148 (!strcmp(argv[i], "--sax2")))
1149 sax2++;
1150 else if ((!strcmp(argv[i], "-nonull")) ||
1151 (!strcmp(argv[i], "--nonull")))
1152 nonull++;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001153 }
Daniel Veillard5997aca2002-03-18 18:36:20 +00001154 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +00001155 for (i = 1; i < argc ; i++) {
1156 if (argv[i][0] != '-') {
Daniel Veillard807daf82004-02-22 22:13:27 +00001157 if (timing) {
1158 startTimer();
1159 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001160 parseAndPrintFile(argv[i]);
Daniel Veillard807daf82004-02-22 22:13:27 +00001161 if (timing) {
1162 endTimer("Parsing");
1163 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001164 files ++;
1165 }
1166 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +00001167 xmlCleanupParser();
1168 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +00001169
1170 return(0);
1171}
Daniel Veillard81273902003-09-30 00:43:48 +00001172#else
1173int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1174 printf("%s : SAX1 parsing support not compiled in\n", argv[0]);
1175 return(0);
1176}
1177#endif /* LIBXML_SAX1_ENABLED */