1999-04-22 00:12:07 +04:00
/*
2001-12-31 19:16:02 +03:00
* testSAX . c : a small tester program for parsing using the SAX API .
1999-04-22 00:12:07 +04:00
*
* See Copyright for the status of this software .
*
2001-06-24 16:13:24 +04:00
* daniel @ veillard . com
1999-04-22 00:12:07 +04:00
*/
2001-04-21 20:57:29 +04:00
# include "libxml.h"
2004-02-23 01:13:27 +03:00
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# endif
# ifdef HAVE_TIME_H
# include <time.h>
# endif
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
1999-09-22 13:46:25 +04:00
# include <string.h>
# include <stdarg.h>
# ifdef HAVE_SYS_TYPES_H
1999-04-22 00:12:07 +04:00
# include <sys/types.h>
1999-09-22 13:46:25 +04:00
# endif
1999-04-22 00:12:07 +04:00
# ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
# endif
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
1999-09-22 13:46:25 +04:00
# ifdef HAVE_STDLIB_H
1999-04-22 00:12:07 +04:00
# include <stdlib.h>
1999-09-22 13:46:25 +04:00
# endif
1999-09-26 15:31:02 +04:00
# ifdef HAVE_STRING_H
# include <string.h>
# endif
1999-09-22 13:46:25 +04:00
1999-04-22 00:12:07 +04:00
2001-10-13 13:15:48 +04:00
# include <libxml/globals.h>
2000-10-09 16:30:39 +04:00
# include <libxml/xmlerror.h>
2000-04-03 23:48:13 +04:00
# include <libxml/parser.h>
# include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
# include <libxml/tree.h>
# include <libxml/debugXML.h>
# include <libxml/xmlmemory.h>
1999-04-22 00:12:07 +04:00
static int debug = 0 ;
static int copy = 0 ;
static int recovery = 0 ;
1999-12-28 19:35:14 +03:00
static int push = 0 ;
2000-04-12 17:27:38 +04:00
static int speed = 0 ;
2002-03-18 21:36:20 +03:00
static int noent = 0 ;
2002-03-20 22:24:21 +03:00
static int quiet = 0 ;
2003-09-07 13:14:37 +04:00
static int nonull = 0 ;
static int sax2 = 0 ;
2004-01-23 16:15:13 +03:00
static int repeat = 0 ;
2002-03-20 22:24:21 +03:00
static int callbacks = 0 ;
2004-02-23 01:13:27 +03:00
static int timing = 0 ;
/*
* Timing routines .
*/
/*
* Internal timing routines to remove the necessity to have unix - specific
* function calls
*/
# ifndef HAVE_GETTIMEOFDAY
# ifdef HAVE_SYS_TIMEB_H
# ifdef HAVE_SYS_TIME_H
# ifdef HAVE_FTIME
static int
my_gettimeofday ( struct timeval * tvp , void * tzp )
{
struct timeb timebuffer ;
ftime ( & timebuffer ) ;
if ( tvp ) {
tvp - > tv_sec = timebuffer . time ;
tvp - > tv_usec = timebuffer . millitm * 1000L ;
}
return ( 0 ) ;
}
# define HAVE_GETTIMEOFDAY 1
# define gettimeofday my_gettimeofday
# endif /* HAVE_FTIME */
# endif /* HAVE_SYS_TIME_H */
# endif /* HAVE_SYS_TIMEB_H */
# endif /* !HAVE_GETTIMEOFDAY */
# if defined(HAVE_GETTIMEOFDAY)
static struct timeval begin , end ;
1999-04-22 00:12:07 +04:00
2004-02-23 01:13:27 +03:00
/*
* startTimer : call where you want to start timing
*/
static void
startTimer ( void )
{
gettimeofday ( & begin , NULL ) ;
}
/*
* endTimer : call where you want to stop timing and to print out a
* message about the timing performed ; format is a printf
* type argument
*/
static void
endTimer ( const char * fmt , . . . )
{
long msec ;
va_list ap ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
# ifndef HAVE_STDARG_H
# error "endTimer required stdarg functions"
# endif
va_start ( ap , fmt ) ;
vfprintf ( stderr , fmt , ap ) ;
va_end ( ap ) ;
fprintf ( stderr , " took %ld ms \n " , msec ) ;
}
# elif defined(HAVE_TIME_H)
/*
* No gettimeofday function , so we have to make do with calling clock .
* This is obviously less accurate , but there ' s little we can do about
* that .
*/
# ifndef CLOCKS_PER_SEC
# define CLOCKS_PER_SEC 100
# endif
static clock_t begin , end ;
static void
startTimer ( void )
{
begin = clock ( ) ;
}
static void
endTimer ( const char * fmt , . . . )
{
long msec ;
va_list ap ;
end = clock ( ) ;
msec = ( ( end - begin ) * 1000 ) / CLOCKS_PER_SEC ;
# ifndef HAVE_STDARG_H
# error "endTimer required stdarg functions"
# endif
va_start ( ap , fmt ) ;
vfprintf ( stderr , fmt , ap ) ;
va_end ( ap ) ;
fprintf ( stderr , " took %ld ms \n " , msec ) ;
}
# else
/*
* We don ' t have a gettimeofday or time . h , so we just don ' t do timing
*/
static void
startTimer ( void )
{
/*
* Do nothing
*/
}
static void
endTimer ( char * format , . . . )
{
/*
* We cannot do anything because we don ' t have a timing function
*/
# ifdef HAVE_STDARG_H
va_start ( ap , format ) ;
vfprintf ( stderr , format , ap ) ;
va_end ( ap ) ;
fprintf ( stderr , " was not timed \n " , msec ) ;
# else
/* We don't have gettimeofday, time or stdarg.h, what crazy world is
* this ? !
*/
# endif
}
# endif
/*
* empty SAX block
*/
1999-04-22 00:12:07 +04:00
xmlSAXHandler emptySAXHandlerStruct = {
NULL , /* internalSubset */
NULL , /* isStandalone */
NULL , /* hasInternalSubset */
NULL , /* hasExternalSubset */
NULL , /* resolveEntity */
NULL , /* getEntity */
NULL , /* entityDecl */
NULL , /* notationDecl */
NULL , /* attributeDecl */
NULL , /* elementDecl */
NULL , /* unparsedEntityDecl */
NULL , /* setDocumentLocator */
NULL , /* startDocument */
NULL , /* endDocument */
NULL , /* startElement */
NULL , /* endElement */
NULL , /* reference */
NULL , /* characters */
NULL , /* ignorableWhitespace */
NULL , /* processingInstruction */
NULL , /* comment */
NULL , /* xmlParserWarning */
NULL , /* xmlParserError */
NULL , /* xmlParserError */
1999-08-10 23:04:08 +04:00
NULL , /* getParameterEntity */
2000-03-14 21:30:20 +03:00
NULL , /* cdataBlock; */
2003-09-07 13:14:37 +04:00
NULL , /* externalSubset; */
1 ,
NULL ,
NULL , /* startElementNs */
2003-10-18 08:53:14 +04:00
NULL , /* endElementNs */
NULL /* xmlStructuredErrorFunc */
1999-04-22 00:12:07 +04:00
} ;
xmlSAXHandlerPtr emptySAXHandler = & emptySAXHandlerStruct ;
1999-06-02 21:44:04 +04:00
extern xmlSAXHandlerPtr debugSAXHandler ;
1999-04-22 00:12:07 +04:00
/************************************************************************
* *
* Debug Handlers *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* isStandaloneDebug :
* @ ctxt : An XML parser context
*
* Is this document tagged standalone ?
*
* Returns 1 if true
*/
2001-03-24 20:00:36 +03:00
static int
2001-03-26 20:28:29 +04:00
isStandaloneDebug ( void * ctx ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ( 0 ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.isStandalone() \n " ) ;
1999-04-22 00:12:07 +04:00
return ( 0 ) ;
}
/**
* hasInternalSubsetDebug :
* @ ctxt : An XML parser context
*
* Does this document has an internal subset
*
* Returns 1 if true
*/
2001-03-24 20:00:36 +03:00
static int
2001-03-26 20:28:29 +04:00
hasInternalSubsetDebug ( void * ctx ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ( 0 ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.hasInternalSubset() \n " ) ;
1999-04-22 00:12:07 +04:00
return ( 0 ) ;
}
/**
* hasExternalSubsetDebug :
* @ ctxt : An XML parser context
*
* Does this document has an external subset
*
* Returns 1 if true
*/
2001-03-24 20:00:36 +03:00
static int
2001-03-26 20:28:29 +04:00
hasExternalSubsetDebug ( void * ctx ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ( 0 ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.hasExternalSubset() \n " ) ;
1999-04-22 00:12:07 +04:00
return ( 0 ) ;
}
/**
2000-04-24 15:33:38 +04:00
* internalSubsetDebug :
1999-04-22 00:12:07 +04:00
* @ ctxt : An XML parser context
*
* Does this document has an internal subset
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
internalSubsetDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name ,
1999-09-24 02:19:22 +04:00
const xmlChar * ExternalID , const xmlChar * SystemID )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
2000-08-17 17:50:51 +04:00
fprintf ( stdout , " SAX.internalSubset(%s, " , name ) ;
if ( ExternalID = = NULL )
fprintf ( stdout , " , " ) ;
else
fprintf ( stdout , " %s, " , ExternalID ) ;
if ( SystemID = = NULL )
fprintf ( stdout , " ) \n " ) ;
else
fprintf ( stdout , " %s) \n " , SystemID ) ;
1999-04-22 00:12:07 +04:00
}
2001-03-24 20:00:36 +03:00
/**
* externalSubsetDebug :
* @ ctxt : An XML parser context
*
* Does this document has an external subset
*/
static void
2001-03-26 20:28:29 +04:00
externalSubsetDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name ,
2001-03-24 20:00:36 +03:00
const xmlChar * ExternalID , const xmlChar * SystemID )
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
2001-03-24 20:00:36 +03:00
fprintf ( stdout , " SAX.externalSubset(%s, " , name ) ;
if ( ExternalID = = NULL )
fprintf ( stdout , " , " ) ;
else
fprintf ( stdout , " %s, " , ExternalID ) ;
if ( SystemID = = NULL )
fprintf ( stdout , " ) \n " ) ;
else
fprintf ( stdout , " %s) \n " , SystemID ) ;
}
1999-04-22 00:12:07 +04:00
/**
* resolveEntityDebug :
* @ ctxt : An XML parser context
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
* Special entity resolver , better left to the parser , it has
* more context than the application layer .
* The default behaviour is to NOT resolve the entities , in that case
* the ENTITY_REF nodes are built in the structure ( and the parameter
* values ) .
*
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour .
*/
2001-03-24 20:00:36 +03:00
static xmlParserInputPtr
2001-03-26 20:28:29 +04:00
resolveEntityDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * publicId , const xmlChar * systemId )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ( NULL ) ;
1999-09-26 15:31:02 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1999-08-30 01:02:19 +04:00
1999-06-23 01:49:07 +04:00
fprintf ( stdout , " SAX.resolveEntity( " ) ;
if ( publicId ! = NULL )
fprintf ( stdout , " %s " , ( char * ) publicId ) ;
else
fprintf ( stdout , " " ) ;
if ( systemId ! = NULL )
fprintf ( stdout , " , %s) \n " , ( char * ) systemId ) ;
else
fprintf ( stdout , " , ) \n " ) ;
1999-09-26 15:31:02 +04:00
/*********
1999-06-02 21:44:04 +04:00
if ( systemId ! = NULL ) {
1999-08-30 01:02:19 +04:00
return ( xmlNewInputFromFile ( ctxt , ( char * ) systemId ) ) ;
1999-06-02 21:44:04 +04:00
}
1999-09-26 15:31:02 +04:00
* * * * * * * * */
1999-04-22 00:12:07 +04:00
return ( NULL ) ;
}
/**
* getEntityDebug :
* @ ctxt : An XML parser context
* @ name : The entity name
*
* Get an entity by name
*
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour .
*/
2001-03-24 20:00:36 +03:00
static xmlEntityPtr
2001-03-26 20:28:29 +04:00
getEntityDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ( NULL ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.getEntity(%s) \n " , name ) ;
1999-04-22 00:12:07 +04:00
return ( NULL ) ;
}
1999-08-10 23:04:08 +04:00
/**
* getParameterEntityDebug :
* @ ctxt : An XML parser context
* @ name : The entity name
*
* Get a parameter entity by name
*
* Returns the xmlParserInputPtr
*/
2001-03-24 20:00:36 +03:00
static xmlEntityPtr
2001-03-26 20:28:29 +04:00
getParameterEntityDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name )
1999-08-10 23:04:08 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ( NULL ) ;
1999-08-10 23:04:08 +04:00
fprintf ( stdout , " SAX.getParameterEntity(%s) \n " , name ) ;
return ( NULL ) ;
}
1999-04-22 00:12:07 +04:00
/**
* entityDeclDebug :
* @ ctxt : An XML parser context
* @ name : the entity name
* @ type : the entity type
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
* @ content : the entity value ( without processing ) .
*
* An entity definition has been parsed
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
entityDeclDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name , int type ,
1999-09-24 02:19:22 +04:00
const xmlChar * publicId , const xmlChar * systemId , xmlChar * content )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.entityDecl(%s, %d, %s, %s, %s) \n " ,
1999-04-22 00:12:07 +04:00
name , type , publicId , systemId , content ) ;
}
/**
* attributeDeclDebug :
* @ ctxt : An XML parser context
* @ name : the attribute name
* @ type : the attribute type
*
* An attribute definition has been parsed
*/
2001-03-24 20:00:36 +03:00
static void
2003-09-10 14:51:05 +04:00
attributeDeclDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * elem ,
const xmlChar * name , int type , int def ,
const xmlChar * defaultValue , xmlEnumerationPtr tree )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
2003-09-10 14:51:05 +04:00
return ;
2000-10-06 16:59:53 +04:00
if ( defaultValue = = NULL )
2003-09-10 14:51:05 +04:00
fprintf ( stdout , " SAX.attributeDecl(%s, %s, %d, %d, NULL, ...) \n " ,
elem , name , type , def ) ;
2000-10-06 16:59:53 +04:00
else
2003-09-10 14:51:05 +04:00
fprintf ( stdout , " SAX.attributeDecl(%s, %s, %d, %d, %s, ...) \n " ,
elem , name , type , def , defaultValue ) ;
xmlFreeEnumeration ( tree ) ;
1999-04-22 00:12:07 +04:00
}
/**
* elementDeclDebug :
* @ ctxt : An XML parser context
* @ name : the element name
* @ type : the element type
* @ content : the element value ( without processing ) .
*
* An element definition has been parsed
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
elementDeclDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name , int type ,
xmlElementContentPtr content ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.elementDecl(%s, %d, ...) \n " ,
1999-04-22 00:12:07 +04:00
name , type ) ;
}
/**
* notationDeclDebug :
* @ ctxt : An XML parser context
* @ name : The name of the notation
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
* What to do when a notation declaration has been parsed .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
notationDeclDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name ,
1999-09-24 02:19:22 +04:00
const xmlChar * publicId , const xmlChar * systemId )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.notationDecl(%s, %s, %s) \n " ,
1999-04-22 00:12:07 +04:00
( char * ) name , ( char * ) publicId , ( char * ) systemId ) ;
}
/**
* unparsedEntityDeclDebug :
* @ ctxt : An XML parser context
* @ name : The name of the entity
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
* @ notationName : the name of the notation
*
* What to do when an unparsed entity declaration is parsed
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
unparsedEntityDeclDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name ,
1999-09-24 02:19:22 +04:00
const xmlChar * publicId , const xmlChar * systemId ,
const xmlChar * notationName )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.unparsedEntityDecl(%s, %s, %s, %s) \n " ,
1999-04-22 00:12:07 +04:00
( char * ) name , ( char * ) publicId , ( char * ) systemId ,
( char * ) notationName ) ;
}
/**
* setDocumentLocatorDebug :
* @ ctxt : An XML parser context
* @ loc : A SAX Locator
*
* Receive the document locator at startup , actually xmlDefaultSAXLocator
* Everything is available on the context , so this is useless in our case .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
setDocumentLocatorDebug ( void * ctx ATTRIBUTE_UNUSED , xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.setDocumentLocator() \n " ) ;
1999-04-22 00:12:07 +04:00
}
/**
* startDocumentDebug :
* @ ctxt : An XML parser context
*
* called when the document start being processed .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
startDocumentDebug ( void * ctx ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.startDocument() \n " ) ;
1999-04-22 00:12:07 +04:00
}
/**
* endDocumentDebug :
* @ ctxt : An XML parser context
*
* called when the document end has been detected .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
endDocumentDebug ( void * ctx ATTRIBUTE_UNUSED )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.endDocument() \n " ) ;
1999-04-22 00:12:07 +04:00
}
/**
* startElementDebug :
* @ ctxt : An XML parser context
* @ name : The element name
*
* called when an opening tag has been processed .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
startElementDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name , const xmlChar * * atts )
1999-04-22 00:12:07 +04:00
{
int i ;
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.startElement(%s " , ( char * ) name ) ;
1999-04-22 00:12:07 +04:00
if ( atts ! = NULL ) {
for ( i = 0 ; ( atts [ i ] ! = NULL ) ; i + + ) {
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " , %s=' " , atts [ i + + ] ) ;
2000-08-17 17:50:51 +04:00
if ( atts [ i ] ! = NULL )
fprintf ( stdout , " %s' " , atts [ i ] ) ;
1999-04-22 00:12:07 +04:00
}
}
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " ) \n " ) ;
1999-04-22 00:12:07 +04:00
}
/**
* endElementDebug :
* @ ctxt : An XML parser context
* @ name : The element name
*
* called when the end of an element has been detected .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
endElementDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.endElement(%s) \n " , ( char * ) name ) ;
1999-04-22 00:12:07 +04:00
}
/**
* charactersDebug :
* @ ctxt : An XML parser context
1999-09-24 02:19:22 +04:00
* @ ch : a xmlChar string
* @ len : the number of xmlChar
1999-04-22 00:12:07 +04:00
*
* receiving some chars from the parser .
* Question : how much at a time ? ? ?
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
charactersDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * ch , int len )
1999-04-22 00:12:07 +04:00
{
2000-08-13 01:12:04 +04:00
char output [ 40 ] ;
1999-07-27 23:52:06 +04:00
int i ;
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
2000-08-13 01:12:04 +04:00
for ( i = 0 ; ( i < len ) & & ( i < 30 ) ; i + + )
output [ i ] = ch [ i ] ;
output [ i ] = 0 ;
fprintf ( stdout , " SAX.characters(%s, %d) \n " , output , len ) ;
1999-04-22 00:12:07 +04:00
}
/**
* referenceDebug :
* @ ctxt : An XML parser context
* @ name : The entity name
*
* called when an entity reference is detected .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
referenceDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * name )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.reference(%s) \n " , name ) ;
1999-04-22 00:12:07 +04:00
}
/**
* ignorableWhitespaceDebug :
* @ ctxt : An XML parser context
1999-09-24 02:19:22 +04:00
* @ ch : a xmlChar string
1999-04-22 00:12:07 +04:00
* @ start : the first char in the string
1999-09-24 02:19:22 +04:00
* @ len : the number of xmlChar
1999-04-22 00:12:07 +04:00
*
* receiving some ignorable whitespaces from the parser .
* Question : how much at a time ? ? ?
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
ignorableWhitespaceDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * ch , int len )
1999-04-22 00:12:07 +04:00
{
2000-08-13 01:12:04 +04:00
char output [ 40 ] ;
int i ;
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
2000-08-13 01:12:04 +04:00
for ( i = 0 ; ( i < len ) & & ( i < 30 ) ; i + + )
output [ i ] = ch [ i ] ;
output [ i ] = 0 ;
fprintf ( stdout , " SAX.ignorableWhitespace(%s, %d) \n " , output , len ) ;
1999-04-22 00:12:07 +04:00
}
/**
* processingInstructionDebug :
* @ ctxt : An XML parser context
* @ target : the target name
* @ data : the PI data ' s
1999-09-24 02:19:22 +04:00
* @ len : the number of xmlChar
1999-04-22 00:12:07 +04:00
*
* A processing instruction has been parsed .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
processingInstructionDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * target ,
1999-09-24 02:19:22 +04:00
const xmlChar * data )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
2003-10-27 19:23:43 +03:00
if ( data ! = NULL )
fprintf ( stdout , " SAX.processingInstruction(%s, %s) \n " ,
( char * ) target , ( char * ) data ) ;
else
fprintf ( stdout , " SAX.processingInstruction(%s, NULL) \n " ,
( char * ) target ) ;
1999-04-22 00:12:07 +04:00
}
2000-03-14 21:30:20 +03:00
/**
* cdataBlockDebug :
* @ ctx : the user data ( XML parser context )
* @ value : The pcdata content
* @ len : the block length
*
* called when a pcdata block has been parsed
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
cdataBlockDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * value , int len )
2000-03-14 21:30:20 +03:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
2000-10-15 14:06:55 +04:00
fprintf ( stdout , " SAX.pcdata(%.20s, %d) \n " ,
2000-03-14 21:30:20 +03:00
( char * ) value , len ) ;
}
1999-04-22 00:12:07 +04:00
/**
* commentDebug :
* @ ctxt : An XML parser context
* @ value : the comment content
*
* A comment has been parsed .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
commentDebug ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * value )
1999-04-22 00:12:07 +04:00
{
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.comment(%s) \n " , value ) ;
1999-04-22 00:12:07 +04:00
}
/**
* warningDebug :
* @ ctxt : An XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format a warning messages , gives file , line , position and
* extra parameters .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
warningDebug ( void * ctx ATTRIBUTE_UNUSED , const char * msg , . . . )
1999-04-22 00:12:07 +04:00
{
va_list args ;
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-04-22 00:12:07 +04:00
va_start ( args , msg ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.warning: " ) ;
vfprintf ( stdout , msg , args ) ;
1999-04-22 00:12:07 +04:00
va_end ( args ) ;
}
/**
* errorDebug :
* @ ctxt : An XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format a error messages , gives file , line , position and
* extra parameters .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
errorDebug ( void * ctx ATTRIBUTE_UNUSED , const char * msg , . . . )
1999-04-22 00:12:07 +04:00
{
va_list args ;
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-04-22 00:12:07 +04:00
va_start ( args , msg ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.error: " ) ;
vfprintf ( stdout , msg , args ) ;
1999-04-22 00:12:07 +04:00
va_end ( args ) ;
}
/**
* fatalErrorDebug :
* @ ctxt : An XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format a fatalError messages , gives file , line , position and
* extra parameters .
*/
2001-03-24 20:00:36 +03:00
static void
2001-03-26 20:28:29 +04:00
fatalErrorDebug ( void * ctx ATTRIBUTE_UNUSED , const char * msg , . . . )
1999-04-22 00:12:07 +04:00
{
va_list args ;
2002-03-20 22:24:21 +03:00
callbacks + + ;
if ( quiet )
return ;
1999-04-22 00:12:07 +04:00
va_start ( args , msg ) ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.fatalError: " ) ;
vfprintf ( stdout , msg , args ) ;
1999-04-22 00:12:07 +04:00
va_end ( args ) ;
}
xmlSAXHandler debugSAXHandlerStruct = {
internalSubsetDebug ,
isStandaloneDebug ,
hasInternalSubsetDebug ,
hasExternalSubsetDebug ,
resolveEntityDebug ,
getEntityDebug ,
entityDeclDebug ,
notationDeclDebug ,
attributeDeclDebug ,
elementDeclDebug ,
unparsedEntityDeclDebug ,
setDocumentLocatorDebug ,
startDocumentDebug ,
endDocumentDebug ,
startElementDebug ,
endElementDebug ,
referenceDebug ,
charactersDebug ,
ignorableWhitespaceDebug ,
processingInstructionDebug ,
commentDebug ,
warningDebug ,
errorDebug ,
fatalErrorDebug ,
1999-08-10 23:04:08 +04:00
getParameterEntityDebug ,
2001-03-24 20:00:36 +03:00
cdataBlockDebug ,
2001-10-13 13:15:48 +04:00
externalSubsetDebug ,
2003-09-07 13:14:37 +04:00
1 ,
NULL ,
NULL ,
2003-10-18 08:53:14 +04:00
NULL ,
2003-09-07 13:14:37 +04:00
NULL
1999-04-22 00:12:07 +04:00
} ;
xmlSAXHandlerPtr debugSAXHandler = & debugSAXHandlerStruct ;
2003-09-07 13:14:37 +04:00
/*
* SAX2 specific callbacks
*/
/**
2003-09-10 14:51:05 +04:00
* startElementNsDebug :
2003-09-07 13:14:37 +04:00
* @ ctxt : An XML parser context
* @ name : The element name
*
* called when an opening tag has been processed .
*/
static void
startElementNsDebug ( void * ctx ATTRIBUTE_UNUSED ,
const xmlChar * localname ,
const xmlChar * prefix ,
const xmlChar * URI ,
int nb_namespaces ,
const xmlChar * * namespaces ,
2003-09-10 14:51:05 +04:00
int nb_attributes ,
int nb_defaulted ,
const xmlChar * * attributes )
2003-09-07 13:14:37 +04:00
{
int i ;
callbacks + + ;
if ( quiet )
return ;
fprintf ( stdout , " SAX.startElementNs(%s " , ( char * ) localname ) ;
if ( prefix = = NULL )
fprintf ( stdout , " , NULL " ) ;
else
fprintf ( stdout , " , %s " , ( char * ) prefix ) ;
if ( URI = = NULL )
fprintf ( stdout , " , NULL " ) ;
else
fprintf ( stdout , " , '%s' " , ( char * ) URI ) ;
fprintf ( stdout , " , %d " , nb_namespaces ) ;
if ( namespaces ! = NULL ) {
for ( i = 0 ; i < nb_namespaces * 2 ; i + + ) {
fprintf ( stdout , " , xmlns " ) ;
if ( namespaces [ i ] ! = NULL )
fprintf ( stdout , " :%s " , namespaces [ i ] ) ;
i + + ;
fprintf ( stdout , " ='%s' " , namespaces [ i ] ) ;
}
}
2003-09-10 14:51:05 +04:00
fprintf ( stdout , " , %d, %d " , nb_attributes , nb_defaulted ) ;
if ( attributes ! = NULL ) {
for ( i = 0 ; i < nb_attributes ; i + = 5 ) {
if ( attributes [ i + 1 ] ! = NULL )
fprintf ( stdout , " , %s:%s=' " , attributes [ i + 1 ] , attributes [ i ] ) ;
else
fprintf ( stdout , " , %s=' " , attributes [ i ] ) ;
fprintf ( stdout , " %.4s...', %d " , attributes [ i + 3 ] ,
2003-10-18 20:20:14 +04:00
( int ) ( attributes [ i + 4 ] - attributes [ i + 3 ] ) ) ;
2003-09-10 14:51:05 +04:00
}
}
fprintf ( stdout , " ) \n " ) ;
2003-09-07 13:14:37 +04:00
}
/**
* endElementDebug :
* @ ctxt : An XML parser context
* @ name : The element name
*
* called when the end of an element has been detected .
*/
static void
endElementNsDebug ( void * ctx ATTRIBUTE_UNUSED ,
const xmlChar * localname ,
const xmlChar * prefix ,
const xmlChar * URI )
{
callbacks + + ;
if ( quiet )
return ;
fprintf ( stdout , " SAX.endElementNs(%s " , ( char * ) localname ) ;
if ( prefix = = NULL )
fprintf ( stdout , " , NULL " ) ;
else
fprintf ( stdout , " , %s " , ( char * ) prefix ) ;
if ( URI = = NULL )
fprintf ( stdout , " , NULL) \n " ) ;
else
fprintf ( stdout , " , '%s') \n " , ( char * ) URI ) ;
}
xmlSAXHandler debugSAX2HandlerStruct = {
internalSubsetDebug ,
isStandaloneDebug ,
hasInternalSubsetDebug ,
hasExternalSubsetDebug ,
resolveEntityDebug ,
getEntityDebug ,
entityDeclDebug ,
notationDeclDebug ,
attributeDeclDebug ,
elementDeclDebug ,
unparsedEntityDeclDebug ,
setDocumentLocatorDebug ,
startDocumentDebug ,
endDocumentDebug ,
NULL ,
NULL ,
referenceDebug ,
charactersDebug ,
ignorableWhitespaceDebug ,
processingInstructionDebug ,
commentDebug ,
warningDebug ,
errorDebug ,
fatalErrorDebug ,
getParameterEntityDebug ,
cdataBlockDebug ,
externalSubsetDebug ,
2003-09-10 14:51:05 +04:00
XML_SAX2_MAGIC ,
2003-09-07 13:14:37 +04:00
NULL ,
startElementNsDebug ,
2003-10-18 08:53:14 +04:00
endElementNsDebug ,
NULL
2003-09-07 13:14:37 +04:00
} ;
xmlSAXHandlerPtr debugSAX2Handler = & debugSAX2HandlerStruct ;
1999-04-22 00:12:07 +04:00
/************************************************************************
* *
* Debug *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-24 20:00:36 +03:00
static void
parseAndPrintFile ( char * filename ) {
1999-09-26 15:31:02 +04:00
int res ;
1999-04-22 00:12:07 +04:00
1999-12-28 19:35:14 +03:00
if ( push ) {
FILE * f ;
2003-09-07 13:14:37 +04:00
if ( ( ! quiet ) & & ( ! nonull ) ) {
/*
* Empty callbacks for checking
*/
f = fopen ( filename , " r " ) ;
if ( f ! = NULL ) {
int ret ;
char chars [ 10 ] ;
xmlParserCtxtPtr ctxt ;
ret = fread ( chars , 1 , 4 , f ) ;
if ( ret > 0 ) {
ctxt = xmlCreatePushParserCtxt ( emptySAXHandler , NULL ,
chars , ret , filename ) ;
while ( ( ret = fread ( chars , 1 , 3 , f ) ) > 0 ) {
xmlParseChunk ( ctxt , chars , ret , 0 ) ;
}
xmlParseChunk ( ctxt , chars , 0 , 1 ) ;
xmlFreeParserCtxt ( ctxt ) ;
1999-12-28 19:35:14 +03:00
}
2003-09-07 13:14:37 +04:00
fclose ( f ) ;
} else {
xmlGenericError ( xmlGenericErrorContext ,
" Cannot read file %s \n " , filename ) ;
1999-12-28 19:35:14 +03:00
}
}
/*
* Debug callback
*/
f = fopen ( filename , " r " ) ;
if ( f ! = NULL ) {
2001-03-24 20:00:36 +03:00
int ret ;
1999-12-28 19:35:14 +03:00
char chars [ 10 ] ;
xmlParserCtxtPtr ctxt ;
2001-03-24 20:00:36 +03:00
ret = fread ( chars , 1 , 4 , f ) ;
if ( ret > 0 ) {
2003-09-07 13:14:37 +04:00
if ( sax2 )
ctxt = xmlCreatePushParserCtxt ( debugSAX2Handler , NULL ,
chars , ret , filename ) ;
else
ctxt = xmlCreatePushParserCtxt ( debugSAXHandler , NULL ,
chars , ret , filename ) ;
2001-03-24 20:00:36 +03:00
while ( ( ret = fread ( chars , 1 , 3 , f ) ) > 0 ) {
xmlParseChunk ( ctxt , chars , ret , 0 ) ;
1999-12-28 19:35:14 +03:00
}
2001-03-24 20:00:36 +03:00
ret = xmlParseChunk ( ctxt , chars , 0 , 1 ) ;
1999-12-28 19:35:14 +03:00
xmlFreeParserCtxt ( ctxt ) ;
2001-03-24 20:00:36 +03:00
if ( ret ! = 0 ) {
1999-12-28 19:35:14 +03:00
fprintf ( stdout ,
2001-03-24 20:00:36 +03:00
" xmlSAXUserParseFile returned error %d \n " , ret ) ;
1999-12-28 19:35:14 +03:00
}
}
fclose ( f ) ;
}
} else {
2000-04-12 17:27:38 +04:00
if ( ! speed ) {
/*
* Empty callbacks for checking
*/
2003-09-07 13:14:37 +04:00
if ( ( ! quiet ) & & ( ! nonull ) ) {
2002-03-20 22:24:21 +03:00
res = xmlSAXUserParseFile ( emptySAXHandler , NULL , filename ) ;
if ( res ! = 0 ) {
fprintf ( stdout , " xmlSAXUserParseFile returned error %d \n " , res ) ;
}
2000-04-12 17:27:38 +04:00
}
1999-04-22 00:12:07 +04:00
2000-04-12 17:27:38 +04:00
/*
* Debug callback
*/
2002-03-20 22:24:21 +03:00
callbacks = 0 ;
2004-01-23 16:15:13 +03:00
if ( repeat ) {
int i ;
for ( i = 0 ; i < 99 ; i + + ) {
if ( sax2 )
res = xmlSAXUserParseFile ( debugSAX2Handler , NULL ,
filename ) ;
else
res = xmlSAXUserParseFile ( debugSAXHandler , NULL ,
filename ) ;
}
}
2003-09-07 13:14:37 +04:00
if ( sax2 )
res = xmlSAXUserParseFile ( debugSAX2Handler , NULL , filename ) ;
else
res = xmlSAXUserParseFile ( debugSAXHandler , NULL , filename ) ;
2000-04-12 17:27:38 +04:00
if ( res ! = 0 ) {
fprintf ( stdout , " xmlSAXUserParseFile returned error %d \n " , res ) ;
}
2002-03-20 22:24:21 +03:00
if ( quiet )
fprintf ( stdout , " %d callbacks generated \n " , callbacks ) ;
2000-04-12 17:27:38 +04:00
} else {
/*
* test 100 x the SAX parse
*/
int i ;
for ( i = 0 ; i < 100 ; i + + )
res = xmlSAXUserParseFile ( emptySAXHandler , NULL , filename ) ;
if ( res ! = 0 ) {
fprintf ( stdout , " xmlSAXUserParseFile returned error %d \n " , res ) ;
}
1999-12-28 19:35:14 +03:00
}
1999-04-22 00:12:07 +04:00
}
}
int main ( int argc , char * * argv ) {
int i ;
int files = 0 ;
for ( i = 1 ; i < argc ; i + + ) {
if ( ( ! strcmp ( argv [ i ] , " -debug " ) ) | | ( ! strcmp ( argv [ i ] , " --debug " ) ) )
debug + + ;
else if ( ( ! strcmp ( argv [ i ] , " -copy " ) ) | | ( ! strcmp ( argv [ i ] , " --copy " ) ) )
copy + + ;
else if ( ( ! strcmp ( argv [ i ] , " -recover " ) ) | |
( ! strcmp ( argv [ i ] , " --recover " ) ) )
recovery + + ;
1999-12-28 19:35:14 +03:00
else if ( ( ! strcmp ( argv [ i ] , " -push " ) ) | |
( ! strcmp ( argv [ i ] , " --push " ) ) )
push + + ;
2000-04-12 17:27:38 +04:00
else if ( ( ! strcmp ( argv [ i ] , " -speed " ) ) | |
( ! strcmp ( argv [ i ] , " --speed " ) ) )
speed + + ;
2004-02-23 01:13:27 +03:00
else if ( ( ! strcmp ( argv [ i ] , " -timing " ) ) | |
( ! strcmp ( argv [ i ] , " --timing " ) ) ) {
nonull + + ;
timing + + ;
quiet + + ;
} else if ( ( ! strcmp ( argv [ i ] , " -repeat " ) ) | |
2004-01-23 16:15:13 +03:00
( ! strcmp ( argv [ i ] , " --repeat " ) ) ) {
repeat + + ;
quiet + + ;
} else if ( ( ! strcmp ( argv [ i ] , " -noent " ) ) | |
2002-03-18 21:36:20 +03:00
( ! strcmp ( argv [ i ] , " --noent " ) ) )
noent + + ;
2002-03-20 22:24:21 +03:00
else if ( ( ! strcmp ( argv [ i ] , " -quiet " ) ) | |
( ! strcmp ( argv [ i ] , " --quiet " ) ) )
quiet + + ;
2003-09-07 13:14:37 +04:00
else if ( ( ! strcmp ( argv [ i ] , " -sax2 " ) ) | |
( ! strcmp ( argv [ i ] , " --sax2 " ) ) )
sax2 + + ;
else if ( ( ! strcmp ( argv [ i ] , " -nonull " ) ) | |
( ! strcmp ( argv [ i ] , " --nonull " ) ) )
nonull + + ;
1999-04-22 00:12:07 +04:00
}
2002-03-18 21:36:20 +03:00
if ( noent ! = 0 ) xmlSubstituteEntitiesDefault ( 1 ) ;
1999-04-22 00:12:07 +04:00
for ( i = 1 ; i < argc ; i + + ) {
if ( argv [ i ] [ 0 ] ! = ' - ' ) {
2004-02-23 01:13:27 +03:00
if ( timing ) {
startTimer ( ) ;
}
1999-04-22 00:12:07 +04:00
parseAndPrintFile ( argv [ i ] ) ;
2004-02-23 01:13:27 +03:00
if ( timing ) {
endTimer ( " Parsing " ) ;
}
1999-04-22 00:12:07 +04:00
files + + ;
}
}
1999-12-01 12:51:45 +03:00
xmlCleanupParser ( ) ;
xmlMemoryDump ( ) ;
1999-04-22 00:12:07 +04:00
return ( 0 ) ;
}
2003-09-30 04:43:48 +04:00
# else
int main ( int argc ATTRIBUTE_UNUSED , char * * argv ATTRIBUTE_UNUSED ) {
printf ( " %s : SAX1 parsing support not compiled in \n " , argv [ 0 ] ) ;
return ( 0 ) ;
}
# endif /* LIBXML_SAX1_ENABLED */