2001-02-23 17:55:21 +00:00
/*
* error . c : module displaying / handling XML parser errors
*
* See Copyright for the status of this software .
*
2001-06-24 12:13:24 +00:00
* Daniel Veillard < daniel @ veillard . com >
2001-02-23 17:55:21 +00:00
*/
2002-03-18 19:37:11 +00:00
# define IN_LIBXML
2001-04-21 16:57:29 +00:00
# include "libxml.h"
2001-02-23 17:55:21 +00:00
# include <stdarg.h>
# include <libxml/parser.h>
# include <libxml/xmlerror.h>
2001-03-10 12:32:04 +00:00
# include <libxml/xmlmemory.h>
2001-10-17 15:58:35 +00:00
# include <libxml/globals.h>
2001-02-23 17:55:21 +00:00
2001-10-29 11:48:19 +00:00
void xmlGenericErrorDefaultFunc ( void * ctx ATTRIBUTE_UNUSED ,
const char * msg ,
. . . ) ;
2001-06-05 17:12:52 +00:00
# define XML_GET_VAR_STR(msg, str) { \
int size ; \
int chars ; \
char * larger ; \
va_list ap ; \
\
str = ( char * ) xmlMalloc ( 150 ) ; \
if ( str = = NULL ) \
return ; \
\
size = 150 ; \
\
while ( 1 ) { \
va_start ( ap , msg ) ; \
chars = vsnprintf ( str , size , msg , ap ) ; \
va_end ( ap ) ; \
if ( ( chars > - 1 ) & & ( chars < size ) ) \
break ; \
if ( chars > - 1 ) \
size + = chars + 1 ; \
else \
size + = 100 ; \
if ( ( larger = ( char * ) xmlRealloc ( str , size ) ) = = NULL ) { \
xmlFree ( str ) ; \
return ; \
} \
str = larger ; \
} \
}
2001-06-05 12:45:55 +00:00
2001-02-23 17:55:21 +00:00
/************************************************************************
* *
* Handling of out of context errors *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlGenericErrorDefaultFunc :
* @ ctx : an error context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Default handler for out of context error messages .
*/
2001-10-29 11:48:19 +00:00
void
2001-03-26 16:28:29 +00:00
xmlGenericErrorDefaultFunc ( void * ctx ATTRIBUTE_UNUSED , const char * msg , . . . ) {
2001-02-23 17:55:21 +00:00
va_list args ;
if ( xmlGenericErrorContext = = NULL )
xmlGenericErrorContext = ( void * ) stderr ;
va_start ( args , msg ) ;
vfprintf ( ( FILE * ) xmlGenericErrorContext , msg , args ) ;
va_end ( args ) ;
}
2002-01-22 18:15:52 +00:00
/**
* initGenericErrorDefaultFunc :
* @ handler : the handler
*
* Set or reset ( if NULL ) the default handler for generic errors
2003-01-24 14:14:52 +00:00
* to the builtin error function .
2002-01-22 18:15:52 +00:00
*/
2001-10-13 09:15:48 +00:00
void
2002-01-18 11:49:26 +00:00
initGenericErrorDefaultFunc ( xmlGenericErrorFunc * handler )
2001-10-13 09:15:48 +00:00
{
2002-01-18 11:49:26 +00:00
if ( handler = = NULL )
xmlGenericError = xmlGenericErrorDefaultFunc ;
else
( * handler ) = xmlGenericErrorDefaultFunc ;
2001-10-13 09:15:48 +00:00
}
2001-02-23 17:55:21 +00:00
/**
* xmlSetGenericErrorFunc :
* @ ctx : the new error handling context
* @ handler : the new handler function
*
* Function to reset the handler and the error context for out of
* context error messages .
* This simply means that @ handler will be called for subsequent
* error messages while not parsing nor validating . And @ ctx will
* be passed as first argument to @ handler
* One can simply force messages to be emitted to another FILE * than
* stderr by setting @ ctx to this file handle and @ handler to NULL .
*/
void
xmlSetGenericErrorFunc ( void * ctx , xmlGenericErrorFunc handler ) {
xmlGenericErrorContext = ctx ;
if ( handler ! = NULL )
xmlGenericError = handler ;
else
xmlGenericError = xmlGenericErrorDefaultFunc ;
}
/************************************************************************
* *
* Handling of parsing errors *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlParserPrintFileInfo :
* @ input : an xmlParserInputPtr input
*
* Displays the associated file and line informations for the current input
*/
void
xmlParserPrintFileInfo ( xmlParserInputPtr input ) {
if ( input ! = NULL ) {
if ( input - > filename )
xmlGenericError ( xmlGenericErrorContext ,
" %s:%d: " , input - > filename ,
input - > line ) ;
else
xmlGenericError ( xmlGenericErrorContext ,
" Entity: line %d: " , input - > line ) ;
}
}
/**
* xmlParserPrintFileContext :
* @ input : an xmlParserInputPtr input
*
* Displays current context within the input content for error tracking
*/
void
2002-03-20 21:55:57 +00:00
xmlParserPrintFileContext ( xmlParserInputPtr input ) {
const xmlChar * cur , * base ;
2001-02-23 17:55:21 +00:00
int n ;
2002-03-20 21:55:57 +00:00
xmlChar content [ 81 ] ;
2001-03-27 00:32:28 +00:00
xmlChar * ctnt ;
2001-02-23 17:55:21 +00:00
2002-03-20 21:55:57 +00:00
if ( input = = NULL ) return ;
2001-02-23 17:55:21 +00:00
cur = input - > cur ;
base = input - > base ;
2001-03-27 00:32:28 +00:00
/* skip backwards over any end-of-lines */
2002-03-20 21:55:57 +00:00
while ( ( cur > base ) & & ( ( * cur = = ' \n ' ) | | ( * cur = = ' \r ' ) ) ) {
cur - - ;
2001-02-23 17:55:21 +00:00
}
n = 0 ;
2001-03-27 00:32:28 +00:00
/* search backwards for beginning-of-line maximum 80 characters */
2002-03-20 21:55:57 +00:00
while ( ( n + + < 80 ) & & ( cur > base ) & & ( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) )
2001-02-23 17:55:21 +00:00
cur - - ;
2002-03-20 21:55:57 +00:00
if ( ( * cur = = ' \n ' ) | | ( * cur = = ' \r ' ) ) cur + + ;
/* search forward for end-of-line maximum 80 characters */
2001-02-23 17:55:21 +00:00
n = 0 ;
2001-03-27 00:32:28 +00:00
ctnt = content ;
2002-03-20 21:55:57 +00:00
while ( ( * cur ! = 0 ) & & ( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) & & ( n < 79 ) ) {
* ctnt + + = * cur + + ;
n + + ;
2001-02-23 17:55:21 +00:00
}
2001-03-27 00:32:28 +00:00
* ctnt = 0 ;
2002-03-20 21:55:57 +00:00
xmlGenericError ( xmlGenericErrorContext , " %s \n " , content ) ;
2001-03-27 00:32:28 +00:00
/* create blank line with problem pointer */
2001-02-23 17:55:21 +00:00
cur = input - > cur ;
2002-03-20 21:55:57 +00:00
while ( ( cur > base ) & & ( ( * cur = = ' \n ' ) | | ( * cur = = ' \r ' ) ) ) {
cur - - ;
}
2001-02-23 17:55:21 +00:00
n = 0 ;
2001-04-24 15:52:00 +00:00
ctnt = content ;
2002-03-20 21:55:57 +00:00
while ( ( n + + < 79 ) & & ( cur > base ) & & ( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) ) {
* ctnt + + = ' ' ;
cur - - ;
2001-02-23 17:55:21 +00:00
}
2001-04-26 09:16:13 +00:00
if ( ctnt > content ) {
2002-03-20 21:55:57 +00:00
* ( - - ctnt ) = ' ^ ' ;
* ( + + ctnt ) = 0 ;
2001-04-26 09:16:13 +00:00
} else {
2002-03-20 21:55:57 +00:00
* ctnt = ' ^ ' ;
* ( + + ctnt ) = 0 ;
}
xmlGenericError ( xmlGenericErrorContext , " %s \n " , content ) ;
}
#if 0
/**
* xmlGetVarStr :
* @ msg : the message format
* @ args : a va_list argument list
*
* SGS contribution
* Get an arbitrary - sized string for an error argument
* The caller must free ( ) the returned string
*/
static char *
xmlGetVarStr ( const char * msg , va_list args ) {
int size ;
int length ;
int chars , left ;
char * str , * larger ;
va_list ap ;
str = ( char * ) xmlMalloc ( 150 ) ;
if ( str = = NULL )
return ( NULL ) ;
size = 150 ;
length = 0 ;
while ( 1 ) {
left = size - length ;
/* Try to print in the allocated space. */
va_start ( msg , ap ) ;
chars = vsnprintf ( str + length , left , msg , ap ) ;
va_end ( ap ) ;
/* If that worked, we're done. */
if ( ( chars > - 1 ) & & ( chars < left ) )
break ;
/* Else try again with more space. */
if ( chars > - 1 ) /* glibc 2.1 */
size + = chars + 1 ; /* precisely what is needed */
else /* glibc 2.0 */
size + = 100 ;
if ( ( larger = ( char * ) xmlRealloc ( str , size ) ) = = NULL ) {
xmlFree ( str ) ;
return ( NULL ) ;
}
str = larger ;
2001-03-10 12:32:04 +00:00
}
2002-03-20 21:55:57 +00:00
return ( str ) ;
2001-03-10 12:32:04 +00:00
}
2002-03-20 21:55:57 +00:00
# endif
2001-03-10 12:32:04 +00:00
2001-02-23 17:55:21 +00:00
/**
* xmlParserError :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format an error messages , gives file , line , position and
* extra parameters .
*/
void
xmlParserError ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input = NULL ;
xmlParserInputPtr cur = NULL ;
2001-03-10 12:32:04 +00:00
char * str ;
2001-02-23 17:55:21 +00:00
if ( ctxt ! = NULL ) {
input = ctxt - > input ;
if ( ( input ! = NULL ) & & ( input - > filename = = NULL ) & &
( ctxt - > inputNr > 1 ) ) {
cur = input ;
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
xmlParserPrintFileInfo ( input ) ;
}
xmlGenericError ( xmlGenericErrorContext , " error: " ) ;
2001-06-05 17:12:52 +00:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 11:48:19 +00:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-18 23:17:47 +00:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 17:55:21 +00:00
if ( ctxt ! = NULL ) {
xmlParserPrintFileContext ( input ) ;
if ( cur ! = NULL ) {
xmlParserPrintFileInfo ( cur ) ;
xmlGenericError ( xmlGenericErrorContext , " \n " ) ;
xmlParserPrintFileContext ( cur ) ;
}
}
}
/**
* xmlParserWarning :
* @ ctx : 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
xmlParserWarning ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input = NULL ;
xmlParserInputPtr cur = NULL ;
2001-03-10 12:32:04 +00:00
char * str ;
2001-02-23 17:55:21 +00:00
if ( ctxt ! = NULL ) {
input = ctxt - > input ;
if ( ( input ! = NULL ) & & ( input - > filename = = NULL ) & &
( ctxt - > inputNr > 1 ) ) {
cur = input ;
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
xmlParserPrintFileInfo ( input ) ;
}
xmlGenericError ( xmlGenericErrorContext , " warning: " ) ;
2001-06-05 17:12:52 +00:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 11:48:19 +00:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-18 23:17:47 +00:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 17:55:21 +00:00
if ( ctxt ! = NULL ) {
xmlParserPrintFileContext ( input ) ;
if ( cur ! = NULL ) {
xmlParserPrintFileInfo ( cur ) ;
xmlGenericError ( xmlGenericErrorContext , " \n " ) ;
xmlParserPrintFileContext ( cur ) ;
}
}
}
/************************************************************************
* *
* Handling of validation errors *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlParserValidityError :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format an validity error messages , gives file ,
* line , position and extra parameters .
*/
void
xmlParserValidityError ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input = NULL ;
2001-03-18 23:17:47 +00:00
char * str ;
2002-09-05 14:21:15 +00:00
int len = xmlStrlen ( ( const xmlChar * ) msg ) ;
static int had_info = 0 ;
int need_context = 0 ;
if ( ( len > 1 ) & & ( msg [ len - 2 ] ! = ' : ' ) ) {
if ( ctxt ! = NULL ) {
input = ctxt - > input ;
if ( ( input - > filename = = NULL ) & & ( ctxt - > inputNr > 1 ) )
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
if ( had_info = = 0 ) {
xmlParserPrintFileInfo ( input ) ;
}
}
xmlGenericError ( xmlGenericErrorContext , " validity error: " ) ;
need_context = 1 ;
had_info = 0 ;
} else {
had_info = 1 ;
2001-02-23 17:55:21 +00:00
}
2001-06-05 17:12:52 +00:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 11:48:19 +00:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-18 23:17:47 +00:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 17:55:21 +00:00
2002-09-05 14:21:15 +00:00
if ( ( ctxt ! = NULL ) & & ( input ! = NULL ) ) {
2001-02-23 17:55:21 +00:00
xmlParserPrintFileContext ( input ) ;
}
}
/**
* xmlParserValidityWarning :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format a validity warning messages , gives file , line ,
* position and extra parameters .
*/
void
xmlParserValidityWarning ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input = NULL ;
2001-03-18 23:17:47 +00:00
char * str ;
2002-09-05 14:21:15 +00:00
int len = xmlStrlen ( ( const xmlChar * ) msg ) ;
2001-02-23 17:55:21 +00:00
2002-09-05 14:21:15 +00:00
if ( ( ctxt ! = NULL ) & & ( len ! = 0 ) & & ( msg [ len - 1 ] ! = ' : ' ) ) {
2001-02-23 17:55:21 +00:00
input = ctxt - > input ;
if ( ( input - > filename = = NULL ) & & ( ctxt - > inputNr > 1 ) )
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
xmlParserPrintFileInfo ( input ) ;
}
xmlGenericError ( xmlGenericErrorContext , " validity warning: " ) ;
2001-06-05 17:12:52 +00:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 11:48:19 +00:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-18 23:17:47 +00:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 17:55:21 +00:00
if ( ctxt ! = NULL ) {
xmlParserPrintFileContext ( input ) ;
}
}