blob: 538c8d7a29b0c4ca03b9338707767a4ae133e99d [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{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000440 callbacks++;
441 if (quiet)
442 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000443 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000444 name, type, publicId, systemId, content);
445}
446
447/**
448 * attributeDeclDebug:
449 * @ctxt: An XML parser context
450 * @name: the attribute name
451 * @type: the attribute type
452 *
453 * An attribute definition has been parsed
454 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000455static void
Daniel Veillard07cb8222003-09-10 10:51:05 +0000456attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
457 const xmlChar * name, int type, int def,
458 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000459{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000460 callbacks++;
461 if (quiet)
Daniel Veillard07cb8222003-09-10 10:51:05 +0000462 return;
Daniel Veillard7e99c632000-10-06 12:59:53 +0000463 if (defaultValue == NULL)
Daniel Veillard07cb8222003-09-10 10:51:05 +0000464 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
465 elem, name, type, def);
Daniel Veillard7e99c632000-10-06 12:59:53 +0000466 else
Daniel Veillard07cb8222003-09-10 10:51:05 +0000467 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
468 elem, name, type, def, defaultValue);
469 xmlFreeEnumeration(tree);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000470}
471
472/**
473 * elementDeclDebug:
474 * @ctxt: An XML parser context
475 * @name: the element name
476 * @type: the element type
477 * @content: the element value (without processing).
478 *
479 * An element definition has been parsed
480 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000481static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000482elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
483 xmlElementContentPtr content ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000484{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000485 callbacks++;
486 if (quiet)
487 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000488 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000489 name, type);
490}
491
492/**
493 * notationDeclDebug:
494 * @ctxt: An XML parser context
495 * @name: The name of the notation
496 * @publicId: The public ID of the entity
497 * @systemId: The system ID of the entity
498 *
499 * What to do when a notation declaration has been parsed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000500 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000501static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000502notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000503 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000504{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000505 callbacks++;
506 if (quiet)
507 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000508 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000509 (char *) name, (char *) publicId, (char *) systemId);
510}
511
512/**
513 * unparsedEntityDeclDebug:
514 * @ctxt: An XML parser context
515 * @name: The name of the entity
516 * @publicId: The public ID of the entity
517 * @systemId: The system ID of the entity
518 * @notationName: the name of the notation
519 *
520 * What to do when an unparsed entity declaration is parsed
Daniel Veillard5099ae81999-04-21 20:12:07 +0000521 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000522static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000523unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000524 const xmlChar *publicId, const xmlChar *systemId,
525 const xmlChar *notationName)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000526{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000527 callbacks++;
528 if (quiet)
529 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000530 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard5099ae81999-04-21 20:12:07 +0000531 (char *) name, (char *) publicId, (char *) systemId,
532 (char *) notationName);
533}
534
535/**
536 * setDocumentLocatorDebug:
537 * @ctxt: An XML parser context
538 * @loc: A SAX Locator
539 *
540 * Receive the document locator at startup, actually xmlDefaultSAXLocator
541 * Everything is available on the context, so this is useless in our case.
542 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000543static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000544setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000545{
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.setDocumentLocator()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000550}
551
552/**
553 * startDocumentDebug:
554 * @ctxt: An XML parser context
555 *
556 * called when the document start being processed.
557 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000558static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000559startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000560{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000561 callbacks++;
562 if (quiet)
563 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000564 fprintf(stdout, "SAX.startDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000565}
566
567/**
568 * endDocumentDebug:
569 * @ctxt: An XML parser context
570 *
571 * called when the document end has been detected.
572 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000573static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000574endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000575{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000576 callbacks++;
577 if (quiet)
578 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000579 fprintf(stdout, "SAX.endDocument()\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000580}
581
582/**
583 * startElementDebug:
584 * @ctxt: An XML parser context
585 * @name: The element name
586 *
587 * called when an opening tag has been processed.
Daniel Veillard5099ae81999-04-21 20:12:07 +0000588 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000589static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000590startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000591{
592 int i;
593
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000594 callbacks++;
595 if (quiet)
596 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000597 fprintf(stdout, "SAX.startElement(%s", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000598 if (atts != NULL) {
599 for (i = 0;(atts[i] != NULL);i++) {
Daniel Veillard27d88741999-05-29 11:51:49 +0000600 fprintf(stdout, ", %s='", atts[i++]);
Daniel Veillard808a3f12000-08-17 13:50:51 +0000601 if (atts[i] != NULL)
602 fprintf(stdout, "%s'", atts[i]);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000603 }
604 }
Daniel Veillard27d88741999-05-29 11:51:49 +0000605 fprintf(stdout, ")\n");
Daniel Veillard5099ae81999-04-21 20:12:07 +0000606}
607
608/**
609 * endElementDebug:
610 * @ctxt: An XML parser context
611 * @name: The element name
612 *
613 * called when the end of an element has been detected.
614 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000615static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000616endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000617{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000618 callbacks++;
619 if (quiet)
620 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000621 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000622}
623
624/**
625 * charactersDebug:
626 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000627 * @ch: a xmlChar string
628 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000629 *
630 * receiving some chars from the parser.
631 * Question: how much at a time ???
632 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000633static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000634charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000635{
Daniel Veillard87b95392000-08-12 21:12:04 +0000636 char output[40];
Daniel Veillarde2d034d1999-07-27 19:52:06 +0000637 int i;
638
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000639 callbacks++;
640 if (quiet)
641 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000642 for (i = 0;(i<len) && (i < 30);i++)
643 output[i] = ch[i];
644 output[i] = 0;
645
646 fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000647}
648
649/**
650 * referenceDebug:
651 * @ctxt: An XML parser context
652 * @name: The entity name
653 *
654 * called when an entity reference is detected.
655 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000656static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000657referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000658{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000659 callbacks++;
660 if (quiet)
661 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000662 fprintf(stdout, "SAX.reference(%s)\n", name);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000663}
664
665/**
666 * ignorableWhitespaceDebug:
667 * @ctxt: An XML parser context
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000668 * @ch: a xmlChar string
Daniel Veillard5099ae81999-04-21 20:12:07 +0000669 * @start: the first char in the string
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000670 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000671 *
672 * receiving some ignorable whitespaces from the parser.
673 * Question: how much at a time ???
674 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000675static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000676ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000677{
Daniel Veillard87b95392000-08-12 21:12:04 +0000678 char output[40];
679 int i;
680
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000681 callbacks++;
682 if (quiet)
683 return;
Daniel Veillard87b95392000-08-12 21:12:04 +0000684 for (i = 0;(i<len) && (i < 30);i++)
685 output[i] = ch[i];
686 output[i] = 0;
687 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000688}
689
690/**
691 * processingInstructionDebug:
692 * @ctxt: An XML parser context
693 * @target: the target name
694 * @data: the PI data's
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000695 * @len: the number of xmlChar
Daniel Veillard5099ae81999-04-21 20:12:07 +0000696 *
697 * A processing instruction has been parsed.
698 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000699static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000700processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000701 const xmlChar *data)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000702{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000703 callbacks++;
704 if (quiet)
705 return;
Daniel Veillard4772af62003-10-27 16:23:43 +0000706 if (data != NULL)
707 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
708 (char *) target, (char *) data);
709 else
710 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
711 (char *) target);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000712}
713
714/**
Daniel Veillardcf461992000-03-14 18:30:20 +0000715 * cdataBlockDebug:
716 * @ctx: the user data (XML parser context)
717 * @value: The pcdata content
718 * @len: the block length
719 *
720 * called when a pcdata block has been parsed
721 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000722static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000723cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardcf461992000-03-14 18:30:20 +0000724{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000725 callbacks++;
726 if (quiet)
727 return;
Daniel Veillard39915622000-10-15 10:06:55 +0000728 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000729 (char *) value, len);
730}
731
732/**
Daniel Veillard5099ae81999-04-21 20:12:07 +0000733 * commentDebug:
734 * @ctxt: An XML parser context
735 * @value: the comment content
736 *
737 * A comment has been parsed.
738 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000739static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000740commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000741{
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000742 callbacks++;
743 if (quiet)
744 return;
Daniel Veillard27d88741999-05-29 11:51:49 +0000745 fprintf(stdout, "SAX.comment(%s)\n", value);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000746}
747
748/**
749 * warningDebug:
750 * @ctxt: An XML parser context
751 * @msg: the message to display/transmit
752 * @...: extra parameters for the message display
753 *
754 * Display and format a warning messages, gives file, line, position and
755 * extra parameters.
756 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000757static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000758warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000759{
760 va_list args;
761
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000762 callbacks++;
763 if (quiet)
764 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000765 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000766 fprintf(stdout, "SAX.warning: ");
767 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000768 va_end(args);
769}
770
771/**
772 * errorDebug:
773 * @ctxt: An XML parser context
774 * @msg: the message to display/transmit
775 * @...: extra parameters for the message display
776 *
777 * Display and format a error messages, gives file, line, position and
778 * extra parameters.
779 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000780static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000781errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000782{
783 va_list args;
784
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000785 callbacks++;
786 if (quiet)
787 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000788 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000789 fprintf(stdout, "SAX.error: ");
790 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000791 va_end(args);
792}
793
794/**
795 * fatalErrorDebug:
796 * @ctxt: An XML parser context
797 * @msg: the message to display/transmit
798 * @...: extra parameters for the message display
799 *
800 * Display and format a fatalError messages, gives file, line, position and
801 * extra parameters.
802 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000803static void
Daniel Veillardc86a4fa2001-03-26 16:28:29 +0000804fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillard5099ae81999-04-21 20:12:07 +0000805{
806 va_list args;
807
Daniel Veillarde50f3b52002-03-20 19:24:21 +0000808 callbacks++;
809 if (quiet)
810 return;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000811 va_start(args, msg);
Daniel Veillard27d88741999-05-29 11:51:49 +0000812 fprintf(stdout, "SAX.fatalError: ");
813 vfprintf(stdout, msg, args);
Daniel Veillard5099ae81999-04-21 20:12:07 +0000814 va_end(args);
815}
816
817xmlSAXHandler debugSAXHandlerStruct = {
818 internalSubsetDebug,
819 isStandaloneDebug,
820 hasInternalSubsetDebug,
821 hasExternalSubsetDebug,
822 resolveEntityDebug,
823 getEntityDebug,
824 entityDeclDebug,
825 notationDeclDebug,
826 attributeDeclDebug,
827 elementDeclDebug,
828 unparsedEntityDeclDebug,
829 setDocumentLocatorDebug,
830 startDocumentDebug,
831 endDocumentDebug,
832 startElementDebug,
833 endElementDebug,
834 referenceDebug,
835 charactersDebug,
836 ignorableWhitespaceDebug,
837 processingInstructionDebug,
838 commentDebug,
839 warningDebug,
840 errorDebug,
841 fatalErrorDebug,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000842 getParameterEntityDebug,
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000843 cdataBlockDebug,
Daniel Veillardd0463562001-10-13 09:15:48 +0000844 externalSubsetDebug,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000845 1,
846 NULL,
847 NULL,
William M. Brack871611b2003-10-18 04:53:14 +0000848 NULL,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000849 NULL
Daniel Veillard5099ae81999-04-21 20:12:07 +0000850};
851
852xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
853
Daniel Veillard0fb18932003-09-07 09:14:37 +0000854/*
855 * SAX2 specific callbacks
856 */
857/**
Daniel Veillard07cb8222003-09-10 10:51:05 +0000858 * startElementNsDebug:
Daniel Veillard0fb18932003-09-07 09:14:37 +0000859 * @ctxt: An XML parser context
860 * @name: The element name
861 *
862 * called when an opening tag has been processed.
863 */
864static void
865startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
866 const xmlChar *localname,
867 const xmlChar *prefix,
868 const xmlChar *URI,
869 int nb_namespaces,
870 const xmlChar **namespaces,
Daniel Veillard07cb8222003-09-10 10:51:05 +0000871 int nb_attributes,
872 int nb_defaulted,
873 const xmlChar **attributes)
Daniel Veillard0fb18932003-09-07 09:14:37 +0000874{
875 int i;
876
877 callbacks++;
878 if (quiet)
879 return;
880 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
881 if (prefix == NULL)
882 fprintf(stdout, ", NULL");
883 else
884 fprintf(stdout, ", %s", (char *) prefix);
885 if (URI == NULL)
886 fprintf(stdout, ", NULL");
887 else
888 fprintf(stdout, ", '%s'", (char *) URI);
889 fprintf(stdout, ", %d", nb_namespaces);
890
891 if (namespaces != NULL) {
892 for (i = 0;i < nb_namespaces * 2;i++) {
893 fprintf(stdout, ", xmlns");
894 if (namespaces[i] != NULL)
895 fprintf(stdout, ":%s", namespaces[i]);
896 i++;
897 fprintf(stdout, "='%s'", namespaces[i]);
898 }
899 }
Daniel Veillard07cb8222003-09-10 10:51:05 +0000900 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
901 if (attributes != NULL) {
902 for (i = 0;i < nb_attributes;i += 5) {
903 if (attributes[i + 1] != NULL)
904 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
905 else
906 fprintf(stdout, ", %s='", attributes[i]);
907 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
William M. Brack76e95df2003-10-18 16:20:14 +0000908 (int)(attributes[i + 4] - attributes[i + 3]));
Daniel Veillard07cb8222003-09-10 10:51:05 +0000909 }
910 }
911 fprintf(stdout, ")\n");
Daniel Veillard0fb18932003-09-07 09:14:37 +0000912}
913
914/**
915 * endElementDebug:
916 * @ctxt: An XML parser context
917 * @name: The element name
918 *
919 * called when the end of an element has been detected.
920 */
921static void
922endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
923 const xmlChar *localname,
924 const xmlChar *prefix,
925 const xmlChar *URI)
926{
927 callbacks++;
928 if (quiet)
929 return;
930 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
931 if (prefix == NULL)
932 fprintf(stdout, ", NULL");
933 else
934 fprintf(stdout, ", %s", (char *) prefix);
935 if (URI == NULL)
936 fprintf(stdout, ", NULL)\n");
937 else
938 fprintf(stdout, ", '%s')\n", (char *) URI);
939}
940
Daniel Veillard0fb18932003-09-07 09:14:37 +0000941xmlSAXHandler debugSAX2HandlerStruct = {
942 internalSubsetDebug,
943 isStandaloneDebug,
944 hasInternalSubsetDebug,
945 hasExternalSubsetDebug,
946 resolveEntityDebug,
947 getEntityDebug,
948 entityDeclDebug,
949 notationDeclDebug,
950 attributeDeclDebug,
951 elementDeclDebug,
952 unparsedEntityDeclDebug,
953 setDocumentLocatorDebug,
954 startDocumentDebug,
955 endDocumentDebug,
956 NULL,
957 NULL,
958 referenceDebug,
959 charactersDebug,
960 ignorableWhitespaceDebug,
961 processingInstructionDebug,
962 commentDebug,
963 warningDebug,
964 errorDebug,
965 fatalErrorDebug,
966 getParameterEntityDebug,
967 cdataBlockDebug,
968 externalSubsetDebug,
Daniel Veillard07cb8222003-09-10 10:51:05 +0000969 XML_SAX2_MAGIC,
Daniel Veillard0fb18932003-09-07 09:14:37 +0000970 NULL,
971 startElementNsDebug,
William M. Brack871611b2003-10-18 04:53:14 +0000972 endElementNsDebug,
973 NULL
Daniel Veillard0fb18932003-09-07 09:14:37 +0000974};
975
976xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
977
Daniel Veillard5099ae81999-04-21 20:12:07 +0000978/************************************************************************
979 * *
980 * Debug *
981 * *
982 ************************************************************************/
983
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000984static void
985parseAndPrintFile(char *filename) {
Daniel Veillard7a66ee61999-09-26 11:31:02 +0000986 int res;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000987
Daniel Veillarddbfd6411999-12-28 16:35:14 +0000988 if (push) {
989 FILE *f;
Daniel Veillard5099ae81999-04-21 20:12:07 +0000990
Daniel Veillard0fb18932003-09-07 09:14:37 +0000991 if ((!quiet) && (!nonull)) {
992 /*
993 * Empty callbacks for checking
994 */
995 f = fopen(filename, "r");
996 if (f != NULL) {
997 int ret;
998 char chars[10];
999 xmlParserCtxtPtr ctxt;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001000
Daniel Veillard0fb18932003-09-07 09:14:37 +00001001 ret = fread(chars, 1, 4, f);
1002 if (ret > 0) {
1003 ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
1004 chars, ret, filename);
1005 while ((ret = fread(chars, 1, 3, f)) > 0) {
1006 xmlParseChunk(ctxt, chars, ret, 0);
1007 }
1008 xmlParseChunk(ctxt, chars, 0, 1);
1009 xmlFreeParserCtxt(ctxt);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001010 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001011 fclose(f);
1012 } else {
1013 xmlGenericError(xmlGenericErrorContext,
1014 "Cannot read file %s\n", filename);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001015 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001016 }
1017 /*
1018 * Debug callback
1019 */
1020 f = fopen(filename, "r");
1021 if (f != NULL) {
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001022 int ret;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001023 char chars[10];
1024 xmlParserCtxtPtr ctxt;
1025
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001026 ret = fread(chars, 1, 4, f);
1027 if (ret > 0) {
Daniel Veillard0fb18932003-09-07 09:14:37 +00001028 if (sax2)
1029 ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
1030 chars, ret, filename);
1031 else
1032 ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
1033 chars, ret, filename);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001034 while ((ret = fread(chars, 1, 3, f)) > 0) {
1035 xmlParseChunk(ctxt, chars, ret, 0);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001036 }
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001037 ret = xmlParseChunk(ctxt, chars, 0, 1);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001038 xmlFreeParserCtxt(ctxt);
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001039 if (ret != 0) {
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001040 fprintf(stdout,
Daniel Veillard56a4cb82001-03-24 17:00:36 +00001041 "xmlSAXUserParseFile returned error %d\n", ret);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001042 }
1043 }
1044 fclose(f);
1045 }
1046 } else {
Daniel Veillard5e873c42000-04-12 13:27:38 +00001047 if (!speed) {
1048 /*
1049 * Empty callbacks for checking
1050 */
Daniel Veillard0fb18932003-09-07 09:14:37 +00001051 if ((!quiet) && (!nonull)) {
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001052 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1053 if (res != 0) {
1054 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1055 }
Daniel Veillard5e873c42000-04-12 13:27:38 +00001056 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001057
Daniel Veillard5e873c42000-04-12 13:27:38 +00001058 /*
1059 * Debug callback
1060 */
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001061 callbacks = 0;
Daniel Veillard4773df22004-01-23 13:15:13 +00001062 if (repeat) {
1063 int i;
1064 for (i = 0;i < 99;i++) {
1065 if (sax2)
1066 res = xmlSAXUserParseFile(debugSAX2Handler, NULL,
1067 filename);
1068 else
1069 res = xmlSAXUserParseFile(debugSAXHandler, NULL,
1070 filename);
1071 }
1072 }
Daniel Veillard0fb18932003-09-07 09:14:37 +00001073 if (sax2)
1074 res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
1075 else
1076 res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001077 if (res != 0) {
1078 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1079 }
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001080 if (quiet)
1081 fprintf(stdout, "%d callbacks generated\n", callbacks);
Daniel Veillard5e873c42000-04-12 13:27:38 +00001082 } else {
1083 /*
1084 * test 100x the SAX parse
1085 */
1086 int i;
1087
1088 for (i = 0; i<100;i++)
1089 res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1090 if (res != 0) {
1091 fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1092 }
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001093 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001094 }
1095}
1096
Daniel Veillard5099ae81999-04-21 20:12:07 +00001097
1098int main(int argc, char **argv) {
1099 int i;
1100 int files = 0;
1101
1102 for (i = 1; i < argc ; i++) {
1103 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1104 debug++;
1105 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1106 copy++;
1107 else if ((!strcmp(argv[i], "-recover")) ||
1108 (!strcmp(argv[i], "--recover")))
1109 recovery++;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001110 else if ((!strcmp(argv[i], "-push")) ||
1111 (!strcmp(argv[i], "--push")))
1112 push++;
Daniel Veillard5e873c42000-04-12 13:27:38 +00001113 else if ((!strcmp(argv[i], "-speed")) ||
1114 (!strcmp(argv[i], "--speed")))
1115 speed++;
Daniel Veillard807daf82004-02-22 22:13:27 +00001116 else if ((!strcmp(argv[i], "-timing")) ||
1117 (!strcmp(argv[i], "--timing"))) {
1118 nonull++;
1119 timing++;
1120 quiet++;
1121 } else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard4773df22004-01-23 13:15:13 +00001122 (!strcmp(argv[i], "--repeat"))) {
1123 repeat++;
1124 quiet++;
1125 } else if ((!strcmp(argv[i], "-noent")) ||
Daniel Veillard5997aca2002-03-18 18:36:20 +00001126 (!strcmp(argv[i], "--noent")))
1127 noent++;
Daniel Veillarde50f3b52002-03-20 19:24:21 +00001128 else if ((!strcmp(argv[i], "-quiet")) ||
1129 (!strcmp(argv[i], "--quiet")))
1130 quiet++;
Daniel Veillard0fb18932003-09-07 09:14:37 +00001131 else if ((!strcmp(argv[i], "-sax2")) ||
1132 (!strcmp(argv[i], "--sax2")))
1133 sax2++;
1134 else if ((!strcmp(argv[i], "-nonull")) ||
1135 (!strcmp(argv[i], "--nonull")))
1136 nonull++;
Daniel Veillard5099ae81999-04-21 20:12:07 +00001137 }
Daniel Veillard5997aca2002-03-18 18:36:20 +00001138 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard5099ae81999-04-21 20:12:07 +00001139 for (i = 1; i < argc ; i++) {
1140 if (argv[i][0] != '-') {
Daniel Veillard807daf82004-02-22 22:13:27 +00001141 if (timing) {
1142 startTimer();
1143 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001144 parseAndPrintFile(argv[i]);
Daniel Veillard807daf82004-02-22 22:13:27 +00001145 if (timing) {
1146 endTimer("Parsing");
1147 }
Daniel Veillard5099ae81999-04-21 20:12:07 +00001148 files ++;
1149 }
1150 }
Daniel Veillardf5c2c871999-12-01 09:51:45 +00001151 xmlCleanupParser();
1152 xmlMemoryDump();
Daniel Veillard5099ae81999-04-21 20:12:07 +00001153
1154 return(0);
1155}
Daniel Veillard81273902003-09-30 00:43:48 +00001156#else
1157int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1158 printf("%s : SAX1 parsing support not compiled in\n", argv[0]);
1159 return(0);
1160}
1161#endif /* LIBXML_SAX1_ENABLED */