File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / testSAX.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 19:53:29 2014 UTC (10 years ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, HEAD
libxml2 2.9.1

    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>