1999-04-22 00:12:07 +04:00
/*
* tester . c : a small tester program for parsing using the SAX API .
*
* See Copyright for the status of this software .
*
* Daniel . Veillard @ w3 . org
*/
# ifdef WIN32
# define HAVE_FCNTL_H
# include <io.h>
# else
# include <config.h>
# endif
# include <sys/types.h>
# 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
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <stdarg.h>
# include "parser.h"
1999-06-02 21:44:04 +04:00
# include "parserInternals.h" /* only for xmlNewInputFromFile() */
1999-04-22 00:12:07 +04:00
# include "tree.h"
# include "debugXML.h"
static int debug = 0 ;
static int copy = 0 ;
static int recovery = 0 ;
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 */
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
/*
* Note : there is a couple of errors introduced on purpose .
*/
static CHAR buffer [ ] =
" <?xml version= \" 1.0 \" ?> \n \
< ? xml : namespace ns = \ " http://www.ietf.org/standards/dav/ \" prefix = \" D \" ?> \n \
< ? xml : namespace ns = \ " http://www.w3.com/standards/z39.50/ \" prefix = \" Z \" ?> \n \
< D : propertyupdate > \ n \
< D : set a = \ " 'toto' \" b> \n \
< D : prop > \ n \
< Z : authors > \ n \
< Z : Author > Jim Whitehead < / Z : Author > \ n \
< Z : Author > Roy Fielding < / Z : Author > \ n \
< / Z : authors > \ n \
< / D : prop > \ n \
< / D : set > \ n \
< D : remove > \ n \
< D : prop > < Z : Copyright - Owner / > < / D : prop > \ n \
< / D : remove > \ n \
< / D : propertyupdate > \ n \
\ n \
" ;
/************************************************************************
* *
* Debug Handlers *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* isStandaloneDebug :
* @ ctxt : An XML parser context
*
* Is this document tagged standalone ?
*
* Returns 1 if true
*/
int
1999-08-30 01:02:19 +04:00
isStandaloneDebug ( void * ctx )
1999-04-22 00:12:07 +04:00
{
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
*/
int
1999-08-30 01:02:19 +04:00
hasInternalSubsetDebug ( void * ctx )
1999-04-22 00:12:07 +04:00
{
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
*/
int
1999-08-30 01:02:19 +04:00
hasExternalSubsetDebug ( void * ctx )
1999-04-22 00:12:07 +04:00
{
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.hasExternalSubset() \n " ) ;
1999-04-22 00:12:07 +04:00
return ( 0 ) ;
}
/**
* hasInternalSubsetDebug :
* @ ctxt : An XML parser context
*
* Does this document has an internal subset
*/
void
1999-08-30 01:02:19 +04:00
internalSubsetDebug ( void * ctx , const CHAR * name ,
1999-04-22 00:12:07 +04:00
const CHAR * ExternalID , const CHAR * SystemID )
{
1999-06-02 21:44:04 +04:00
xmlDtdPtr externalSubset ;
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.internalSubset(%s, %s, %s) \n " ,
1999-04-22 00:12:07 +04:00
name , ExternalID , SystemID ) ;
1999-06-02 21:44:04 +04:00
if ( ( ExternalID ! = NULL ) | | ( SystemID ! = NULL ) ) {
1999-08-10 23:04:08 +04:00
externalSubset = xmlParseDTD ( ExternalID , SystemID ) ;
if ( externalSubset ! = NULL ) {
xmlFreeDtd ( externalSubset ) ;
}
1999-06-02 21:44:04 +04:00
}
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 .
*/
xmlParserInputPtr
1999-08-30 01:02:19 +04:00
resolveEntityDebug ( void * ctx , const CHAR * publicId , const CHAR * systemId )
1999-04-22 00:12:07 +04:00
{
1999-08-30 01:02:19 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
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-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-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 .
*/
xmlEntityPtr
1999-08-30 01:02:19 +04:00
getEntityDebug ( void * ctx , const CHAR * name )
1999-04-22 00:12:07 +04:00
{
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
*/
xmlEntityPtr
1999-08-30 01:02:19 +04:00
getParameterEntityDebug ( void * ctx , const CHAR * name )
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
*/
void
1999-08-30 01:02:19 +04:00
entityDeclDebug ( void * ctx , const CHAR * name , int type ,
1999-04-22 00:12:07 +04:00
const CHAR * publicId , const CHAR * systemId , CHAR * content )
{
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
*/
void
1999-08-30 01:02:19 +04:00
attributeDeclDebug ( void * ctx , const CHAR * elem , const CHAR * name ,
1999-04-22 00:12:07 +04:00
int type , int def , const CHAR * defaultValue ,
xmlEnumerationPtr tree )
{
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.attributeDecl(%s, %s, %d, %d, %s, ...) \n " ,
1999-04-22 00:12:07 +04:00
elem , name , type , def , defaultValue ) ;
}
/**
* 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
*/
void
1999-08-30 01:02:19 +04:00
elementDeclDebug ( void * ctx , const CHAR * name , int type ,
1999-04-22 00:12:07 +04:00
xmlElementContentPtr content )
{
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 .
*/
void
1999-08-30 01:02:19 +04:00
notationDeclDebug ( void * ctx , const CHAR * name ,
1999-04-22 00:12:07 +04:00
const CHAR * publicId , const CHAR * systemId )
{
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
*/
void
1999-08-30 01:02:19 +04:00
unparsedEntityDeclDebug ( void * ctx , const CHAR * name ,
1999-04-22 00:12:07 +04:00
const CHAR * publicId , const CHAR * systemId ,
const CHAR * notationName )
{
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 .
*/
void
1999-08-30 01:02:19 +04:00
setDocumentLocatorDebug ( void * ctx , xmlSAXLocatorPtr loc )
1999-04-22 00:12:07 +04:00
{
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 .
*/
void
1999-08-30 01:02:19 +04:00
startDocumentDebug ( void * ctx )
1999-04-22 00:12:07 +04:00
{
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 .
*/
void
1999-08-30 01:02:19 +04:00
endDocumentDebug ( void * ctx )
1999-04-22 00:12:07 +04:00
{
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 .
*/
void
1999-08-30 01:02:19 +04:00
startElementDebug ( void * ctx , const CHAR * name , const CHAR * * atts )
1999-04-22 00:12:07 +04:00
{
int i ;
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 + + ] ) ;
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 .
*/
void
1999-08-30 01:02:19 +04:00
endElementDebug ( void * ctx , const CHAR * name )
1999-04-22 00:12:07 +04:00
{
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
* @ ch : a CHAR string
* @ len : the number of CHAR
*
* receiving some chars from the parser .
* Question : how much at a time ? ? ?
*/
void
1999-08-30 01:02:19 +04:00
charactersDebug ( void * ctx , const CHAR * ch , int len )
1999-04-22 00:12:07 +04:00
{
1999-07-27 23:52:06 +04:00
int i ;
fprintf ( stdout , " SAX.characters( " ) ;
for ( i = 0 ; ( i < len ) & & ( i < 30 ) ; i + + )
fprintf ( stdout , " %c " , ch [ i ] ) ;
fprintf ( stdout , " , %d) \n " , 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 .
*/
void
1999-08-30 01:02:19 +04:00
referenceDebug ( void * ctx , const CHAR * name )
1999-04-22 00:12:07 +04:00
{
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
* @ ch : a CHAR string
* @ start : the first char in the string
* @ len : the number of CHAR
*
* receiving some ignorable whitespaces from the parser .
* Question : how much at a time ? ? ?
*/
void
1999-08-30 01:02:19 +04:00
ignorableWhitespaceDebug ( void * ctx , const CHAR * ch , int len )
1999-04-22 00:12:07 +04:00
{
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.ignorableWhitespace(%.30s, %d) \n " ,
1999-04-22 00:12:07 +04:00
( char * ) ch , len ) ;
}
/**
* processingInstructionDebug :
* @ ctxt : An XML parser context
* @ target : the target name
* @ data : the PI data ' s
* @ len : the number of CHAR
*
* A processing instruction has been parsed .
*/
void
1999-08-30 01:02:19 +04:00
processingInstructionDebug ( void * ctx , const CHAR * target ,
1999-04-22 00:12:07 +04:00
const CHAR * data )
{
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " SAX.processingInstruction(%s, %s) \n " ,
1999-04-22 00:12:07 +04:00
( char * ) target , ( char * ) data ) ;
}
/**
* commentDebug :
* @ ctxt : An XML parser context
* @ value : the comment content
*
* A comment has been parsed .
*/
void
1999-08-30 01:02:19 +04:00
commentDebug ( void * ctx , const CHAR * value )
1999-04-22 00:12:07 +04:00
{
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 .
*/
void
1999-08-30 01:02:19 +04:00
warningDebug ( void * ctx , const char * msg , . . . )
1999-04-22 00:12:07 +04:00
{
va_list args ;
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 .
*/
void
1999-08-30 01:02:19 +04:00
errorDebug ( void * ctx , const char * msg , . . . )
1999-04-22 00:12:07 +04:00
{
va_list args ;
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 .
*/
void
1999-08-30 01:02:19 +04:00
fatalErrorDebug ( void * ctx , const char * msg , . . . )
1999-04-22 00:12:07 +04:00
{
va_list args ;
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 ,
1999-04-22 00:12:07 +04:00
} ;
xmlSAXHandlerPtr debugSAXHandler = & debugSAXHandlerStruct ;
/************************************************************************
* *
* Debug *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void parseAndPrintFile ( char * filename ) {
xmlDocPtr doc ;
/*
* Empty callbacks for checking
*/
doc = xmlSAXParseFile ( emptySAXHandler , filename , 0 ) ;
if ( doc ! = NULL ) {
1999-05-29 15:51:49 +04:00
fprintf ( stdout , " xmlSAXParseFile returned non-NULL \n " ) ;
1999-04-22 00:12:07 +04:00
xmlDocDump ( stdout , doc ) ;
}
/*
* Debug callback
*/
doc = xmlSAXParseFile ( debugSAXHandler , filename , 0 ) ;
if ( doc ! = NULL ) {
fprintf ( stderr , " xmlSAXParseFile returned non-NULL \n " ) ;
xmlDocDump ( stdout , doc ) ;
}
}
void parseAndPrintBuffer ( CHAR * buf ) {
xmlDocPtr doc ;
/*
* Empty callbacks for checking
*/
doc = xmlSAXParseDoc ( emptySAXHandler , buf , 0 ) ;
if ( doc ! = NULL ) {
fprintf ( stderr , " xmlSAXParseDoc returned non-NULL \n " ) ;
xmlDocDump ( stdout , doc ) ;
}
/*
* Debug callback
*/
doc = xmlSAXParseDoc ( debugSAXHandler , buf , 0 ) ;
if ( doc ! = NULL ) {
fprintf ( stderr , " xmlSAXParseDoc returned non-NULL \n " ) ;
xmlDocDump ( stdout , doc ) ;
}
}
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 + + ;
}
for ( i = 1 ; i < argc ; i + + ) {
if ( argv [ i ] [ 0 ] ! = ' - ' ) {
parseAndPrintFile ( argv [ i ] ) ;
files + + ;
}
}
if ( files = = 0 ) {
printf ( " \n First test for the parser, with errors \n " ) ;
parseAndPrintBuffer ( buffer ) ;
}
return ( 0 ) ;
}