Annotation of embedaddon/libxml2/testSAX.c, revision 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>