Annotation of embedaddon/libxml2/testSAX.c, revision 1.1.1.1
1.1 misho 1: /*
2: * testSAX.c : a small tester program for parsing using the SAX API.
3: *
4: * See Copyright for the status of this software.
5: *
6: * daniel@veillard.com
7: */
8:
9: #include "libxml.h"
10:
11: #ifdef HAVE_SYS_TIME_H
12: #include <sys/time.h>
13: #endif
14: #ifdef HAVE_SYS_TIMEB_H
15: #include <sys/timeb.h>
16: #endif
17: #ifdef HAVE_TIME_H
18: #include <time.h>
19: #endif
20:
21: #ifdef LIBXML_SAX1_ENABLED
22: #include <string.h>
23: #include <stdarg.h>
24:
25: #ifdef HAVE_SYS_TYPES_H
26: #include <sys/types.h>
27: #endif
28: #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
37: #ifdef HAVE_STDLIB_H
38: #include <stdlib.h>
39: #endif
40: #ifdef HAVE_STRING_H
41: #include <string.h>
42: #endif
43:
44:
45: #include <libxml/globals.h>
46: #include <libxml/xmlerror.h>
47: #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>
52:
53: static int debug = 0;
54: static int copy = 0;
55: static int recovery = 0;
56: static int push = 0;
57: static int speed = 0;
58: static int noent = 0;
59: static int quiet = 0;
60: static int nonull = 0;
61: static int sax2 = 0;
62: static int repeat = 0;
63: static int callbacks = 0;
64: static int timing = 0;
65:
66: /*
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:
79: static int
80: my_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)
100: static struct timeval begin, end;
101:
102: /*
103: * startTimer: call where you want to start timing
104: */
105: static void
106: startTimer(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: */
116: static void XMLCDECL
117: endTimer(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:
146: static clock_t begin, end;
147: static void
148: startTimer(void)
149: {
150: begin = clock();
151: }
152: static void XMLCDECL
153: endTimer(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: */
174: static void
175: startTimer(void)
176: {
177: /*
178: * Do nothing
179: */
180: }
181: static void XMLCDECL
182: endTimer(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: */
203: static xmlSAXHandler 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 */
228: NULL, /* getParameterEntity */
229: NULL, /* cdataBlock; */
230: NULL, /* externalSubset; */
231: 1,
232: NULL,
233: NULL, /* startElementNs */
234: NULL, /* endElementNs */
235: NULL /* xmlStructuredErrorFunc */
236: };
237:
238: static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
239: extern xmlSAXHandlerPtr debugSAXHandler;
240:
241: /************************************************************************
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: */
255: static int
256: isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
257: {
258: callbacks++;
259: if (quiet)
260: return(0);
261: fprintf(stdout, "SAX.isStandalone()\n");
262: 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: */
273: static int
274: hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
275: {
276: callbacks++;
277: if (quiet)
278: return(0);
279: fprintf(stdout, "SAX.hasInternalSubset()\n");
280: 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: */
291: static int
292: hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
293: {
294: callbacks++;
295: if (quiet)
296: return(0);
297: fprintf(stdout, "SAX.hasExternalSubset()\n");
298: return(0);
299: }
300:
301: /**
302: * internalSubsetDebug:
303: * @ctxt: An XML parser context
304: *
305: * Does this document has an internal subset
306: */
307: static void
308: internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
309: const xmlChar *ExternalID, const xmlChar *SystemID)
310: {
311: callbacks++;
312: if (quiet)
313: return;
314: 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);
323: }
324:
325: /**
326: * externalSubsetDebug:
327: * @ctxt: An XML parser context
328: *
329: * Does this document has an external subset
330: */
331: static void
332: externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
333: const xmlChar *ExternalID, const xmlChar *SystemID)
334: {
335: callbacks++;
336: if (quiet)
337: return;
338: 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: /**
350: * 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: */
363: static xmlParserInputPtr
364: resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
365: {
366: callbacks++;
367: if (quiet)
368: return(NULL);
369: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
370:
371:
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");
381: /*********
382: if (systemId != NULL) {
383: return(xmlNewInputFromFile(ctxt, (char *) systemId));
384: }
385: *********/
386: 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: */
398: static xmlEntityPtr
399: getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
400: {
401: callbacks++;
402: if (quiet)
403: return(NULL);
404: fprintf(stdout, "SAX.getEntity(%s)\n", name);
405: return(NULL);
406: }
407:
408: /**
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: */
417: static xmlEntityPtr
418: getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
419: {
420: callbacks++;
421: if (quiet)
422: return(NULL);
423: fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
424: return(NULL);
425: }
426:
427:
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: */
439: static void
440: entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
441: const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
442: {
443: const 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;
451: callbacks++;
452: if (quiet)
453: return;
454: fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
455: 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: */
466: static void
467: attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
468: const xmlChar * name, int type, int def,
469: const xmlChar * defaultValue, xmlEnumerationPtr tree)
470: {
471: callbacks++;
472: if (quiet)
473: return;
474: if (defaultValue == NULL)
475: fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
476: elem, name, type, def);
477: else
478: fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
479: elem, name, type, def, defaultValue);
480: xmlFreeEnumeration(tree);
481: }
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: */
492: static void
493: elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
494: xmlElementContentPtr content ATTRIBUTE_UNUSED)
495: {
496: callbacks++;
497: if (quiet)
498: return;
499: fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
500: 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.
511: */
512: static void
513: notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
514: const xmlChar *publicId, const xmlChar *systemId)
515: {
516: callbacks++;
517: if (quiet)
518: return;
519: fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
520: (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
532: */
533: static void
534: unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
535: const xmlChar *publicId, const xmlChar *systemId,
536: const xmlChar *notationName)
537: {
538: const 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;
546: callbacks++;
547: if (quiet)
548: return;
549: fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
550: (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: */
562: static void
563: setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
564: {
565: callbacks++;
566: if (quiet)
567: return;
568: fprintf(stdout, "SAX.setDocumentLocator()\n");
569: }
570:
571: /**
572: * startDocumentDebug:
573: * @ctxt: An XML parser context
574: *
575: * called when the document start being processed.
576: */
577: static void
578: startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
579: {
580: callbacks++;
581: if (quiet)
582: return;
583: fprintf(stdout, "SAX.startDocument()\n");
584: }
585:
586: /**
587: * endDocumentDebug:
588: * @ctxt: An XML parser context
589: *
590: * called when the document end has been detected.
591: */
592: static void
593: endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
594: {
595: callbacks++;
596: if (quiet)
597: return;
598: fprintf(stdout, "SAX.endDocument()\n");
599: }
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.
607: */
608: static void
609: startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
610: {
611: int i;
612:
613: callbacks++;
614: if (quiet)
615: return;
616: fprintf(stdout, "SAX.startElement(%s", (char *) name);
617: if (atts != NULL) {
618: for (i = 0;(atts[i] != NULL);i++) {
619: fprintf(stdout, ", %s='", atts[i++]);
620: if (atts[i] != NULL)
621: fprintf(stdout, "%s'", atts[i]);
622: }
623: }
624: fprintf(stdout, ")\n");
625: }
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: */
634: static void
635: endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
636: {
637: callbacks++;
638: if (quiet)
639: return;
640: fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
641: }
642:
643: /**
644: * charactersDebug:
645: * @ctxt: An XML parser context
646: * @ch: a xmlChar string
647: * @len: the number of xmlChar
648: *
649: * receiving some chars from the parser.
650: * Question: how much at a time ???
651: */
652: static void
653: charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
654: {
655: char output[40];
656: int i;
657:
658: callbacks++;
659: if (quiet)
660: return;
661: 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);
666: }
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: */
675: static void
676: referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
677: {
678: callbacks++;
679: if (quiet)
680: return;
681: fprintf(stdout, "SAX.reference(%s)\n", name);
682: }
683:
684: /**
685: * ignorableWhitespaceDebug:
686: * @ctxt: An XML parser context
687: * @ch: a xmlChar string
688: * @start: the first char in the string
689: * @len: the number of xmlChar
690: *
691: * receiving some ignorable whitespaces from the parser.
692: * Question: how much at a time ???
693: */
694: static void
695: ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
696: {
697: char output[40];
698: int i;
699:
700: callbacks++;
701: if (quiet)
702: return;
703: 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);
707: }
708:
709: /**
710: * processingInstructionDebug:
711: * @ctxt: An XML parser context
712: * @target: the target name
713: * @data: the PI data's
714: * @len: the number of xmlChar
715: *
716: * A processing instruction has been parsed.
717: */
718: static void
719: processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
720: const xmlChar *data)
721: {
722: callbacks++;
723: if (quiet)
724: return;
725: 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);
731: }
732:
733: /**
734: * 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: */
741: static void
742: cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
743: {
744: callbacks++;
745: if (quiet)
746: return;
747: fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
748: (char *) value, len);
749: }
750:
751: /**
752: * commentDebug:
753: * @ctxt: An XML parser context
754: * @value: the comment content
755: *
756: * A comment has been parsed.
757: */
758: static void
759: commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
760: {
761: callbacks++;
762: if (quiet)
763: return;
764: fprintf(stdout, "SAX.comment(%s)\n", value);
765: }
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: */
776: static void XMLCDECL
777: warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
778: {
779: va_list args;
780:
781: callbacks++;
782: if (quiet)
783: return;
784: va_start(args, msg);
785: fprintf(stdout, "SAX.warning: ");
786: vfprintf(stdout, msg, args);
787: 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: */
799: static void XMLCDECL
800: errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
801: {
802: va_list args;
803:
804: callbacks++;
805: if (quiet)
806: return;
807: va_start(args, msg);
808: fprintf(stdout, "SAX.error: ");
809: vfprintf(stdout, msg, args);
810: 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: */
822: static void XMLCDECL
823: fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
824: {
825: va_list args;
826:
827: callbacks++;
828: if (quiet)
829: return;
830: va_start(args, msg);
831: fprintf(stdout, "SAX.fatalError: ");
832: vfprintf(stdout, msg, args);
833: va_end(args);
834: }
835:
836: static xmlSAXHandler 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,
861: getParameterEntityDebug,
862: cdataBlockDebug,
863: externalSubsetDebug,
864: 1,
865: NULL,
866: NULL,
867: NULL,
868: NULL
869: };
870:
871: xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
872:
873: /*
874: * SAX2 specific callbacks
875: */
876: /**
877: * startElementNsDebug:
878: * @ctxt: An XML parser context
879: * @name: The element name
880: *
881: * called when an opening tag has been processed.
882: */
883: static void
884: startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
885: const xmlChar *localname,
886: const xmlChar *prefix,
887: const xmlChar *URI,
888: int nb_namespaces,
889: const xmlChar **namespaces,
890: int nb_attributes,
891: int nb_defaulted,
892: const xmlChar **attributes)
893: {
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: }
919: fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
920: if (attributes != NULL) {
921: for (i = 0;i < nb_attributes * 5;i += 5) {
922: 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],
927: (int)(attributes[i + 4] - attributes[i + 3]));
928: }
929: }
930: fprintf(stdout, ")\n");
931: }
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: */
940: static void
941: endElementNsDebug(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:
960: static xmlSAXHandler 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,
988: XML_SAX2_MAGIC,
989: NULL,
990: startElementNsDebug,
991: endElementNsDebug,
992: NULL
993: };
994:
995: static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
996:
997: /************************************************************************
998: * *
999: * Debug *
1000: * *
1001: ************************************************************************/
1002:
1003: static void
1004: parseAndPrintFile(char *filename) {
1005: int res;
1006:
1007: #ifdef LIBXML_PUSH_ENABLED
1008: if (push) {
1009: FILE *f;
1010:
1011: if ((!quiet) && (!nonull)) {
1012: /*
1013: * Empty callbacks for checking
1014: */
1015: #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1016: f = fopen(filename, "rb");
1017: #else
1018: f = fopen(filename, "r");
1019: #endif
1020: if (f != NULL) {
1021: int ret;
1022: char chars[10];
1023: xmlParserCtxtPtr ctxt;
1024:
1025: ret = fread(chars, 1, 4, f);
1026: if (ret > 0) {
1027: ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
1028: chars, ret, filename);
1029: while ((ret = fread(chars, 1, 3, f)) > 0) {
1030: xmlParseChunk(ctxt, chars, ret, 0);
1031: }
1032: xmlParseChunk(ctxt, chars, 0, 1);
1033: xmlFreeParserCtxt(ctxt);
1034: }
1035: fclose(f);
1036: } else {
1037: xmlGenericError(xmlGenericErrorContext,
1038: "Cannot read file %s\n", filename);
1039: }
1040: }
1041: /*
1042: * Debug callback
1043: */
1044: #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1045: f = fopen(filename, "rb");
1046: #else
1047: f = fopen(filename, "r");
1048: #endif
1049: if (f != NULL) {
1050: int ret;
1051: char chars[10];
1052: xmlParserCtxtPtr ctxt;
1053:
1054: ret = fread(chars, 1, 4, f);
1055: if (ret > 0) {
1056: if (sax2)
1057: ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
1058: chars, ret, filename);
1059: else
1060: ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
1061: chars, ret, filename);
1062: while ((ret = fread(chars, 1, 3, f)) > 0) {
1063: xmlParseChunk(ctxt, chars, ret, 0);
1064: }
1065: ret = xmlParseChunk(ctxt, chars, 0, 1);
1066: xmlFreeParserCtxt(ctxt);
1067: if (ret != 0) {
1068: fprintf(stdout,
1069: "xmlSAXUserParseFile returned error %d\n", ret);
1070: }
1071: }
1072: fclose(f);
1073: }
1074: } else {
1075: #endif /* LIBXML_PUSH_ENABLED */
1076: if (!speed) {
1077: /*
1078: * Empty callbacks for checking
1079: */
1080: if ((!quiet) && (!nonull)) {
1081: res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1082: if (res != 0) {
1083: fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1084: }
1085: }
1086:
1087: /*
1088: * Debug callback
1089: */
1090: callbacks = 0;
1091: if (repeat) {
1092: int i;
1093: for (i = 0;i < 99;i++) {
1094: if (sax2)
1095: res = xmlSAXUserParseFile(debugSAX2Handler, NULL,
1096: filename);
1097: else
1098: res = xmlSAXUserParseFile(debugSAXHandler, NULL,
1099: filename);
1100: }
1101: }
1102: if (sax2)
1103: res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
1104: else
1105: res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
1106: if (res != 0) {
1107: fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1108: }
1109: if (quiet)
1110: fprintf(stdout, "%d callbacks generated\n", callbacks);
1111: } else {
1112: /*
1113: * test 100x the SAX parse
1114: */
1115: int i;
1116:
1117: for (i = 0; i<100;i++)
1118: res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
1119: if (res != 0) {
1120: fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
1121: }
1122: }
1123: #ifdef LIBXML_PUSH_ENABLED
1124: }
1125: #endif
1126: }
1127:
1128:
1129: int main(int argc, char **argv) {
1130: int i;
1131: int files = 0;
1132:
1133: LIBXML_TEST_VERSION /* be safe, plus calls xmlInitParser */
1134:
1135: for (i = 1; i < argc ; i++) {
1136: if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1137: debug++;
1138: else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1139: copy++;
1140: else if ((!strcmp(argv[i], "-recover")) ||
1141: (!strcmp(argv[i], "--recover")))
1142: recovery++;
1143: else if ((!strcmp(argv[i], "-push")) ||
1144: (!strcmp(argv[i], "--push")))
1145: #ifdef LIBXML_PUSH_ENABLED
1146: push++;
1147: #else
1148: fprintf(stderr,"'push' not enabled in library - ignoring\n");
1149: #endif /* LIBXML_PUSH_ENABLED */
1150: else if ((!strcmp(argv[i], "-speed")) ||
1151: (!strcmp(argv[i], "--speed")))
1152: speed++;
1153: else if ((!strcmp(argv[i], "-timing")) ||
1154: (!strcmp(argv[i], "--timing"))) {
1155: nonull++;
1156: timing++;
1157: quiet++;
1158: } else if ((!strcmp(argv[i], "-repeat")) ||
1159: (!strcmp(argv[i], "--repeat"))) {
1160: repeat++;
1161: quiet++;
1162: } else if ((!strcmp(argv[i], "-noent")) ||
1163: (!strcmp(argv[i], "--noent")))
1164: noent++;
1165: else if ((!strcmp(argv[i], "-quiet")) ||
1166: (!strcmp(argv[i], "--quiet")))
1167: quiet++;
1168: else if ((!strcmp(argv[i], "-sax2")) ||
1169: (!strcmp(argv[i], "--sax2")))
1170: sax2++;
1171: else if ((!strcmp(argv[i], "-nonull")) ||
1172: (!strcmp(argv[i], "--nonull")))
1173: nonull++;
1174: }
1175: if (noent != 0) xmlSubstituteEntitiesDefault(1);
1176: for (i = 1; i < argc ; i++) {
1177: if (argv[i][0] != '-') {
1178: if (timing) {
1179: startTimer();
1180: }
1181: parseAndPrintFile(argv[i]);
1182: if (timing) {
1183: endTimer("Parsing");
1184: }
1185: files ++;
1186: }
1187: }
1188: xmlCleanupParser();
1189: xmlMemoryDump();
1190:
1191: return(0);
1192: }
1193: #else
1194: int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1195: printf("%s : SAX1 parsing support not compiled in\n", argv[0]);
1196: return(0);
1197: }
1198: #endif /* LIBXML_SAX1_ENABLED */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>