2001-02-23 20:55:21 +03:00
/*
* error . c : module displaying / handling XML parser errors
*
* See Copyright for the status of this software .
*
2001-06-24 16:13:24 +04:00
* Daniel Veillard < daniel @ veillard . com >
2001-02-23 20:55:21 +03:00
*/
2002-03-18 22:37:11 +03:00
# define IN_LIBXML
2001-04-21 20:57:29 +04:00
# include "libxml.h"
2001-02-23 20:55:21 +03:00
2003-10-03 02:28:19 +04:00
# include <string.h>
2001-02-23 20:55:21 +03:00
# include <stdarg.h>
# include <libxml/parser.h>
# include <libxml/xmlerror.h>
2001-03-10 15:32:04 +03:00
# include <libxml/xmlmemory.h>
2001-10-17 19:58:35 +04:00
# include <libxml/globals.h>
2001-02-23 20:55:21 +03:00
2001-10-29 14:48:19 +03:00
void xmlGenericErrorDefaultFunc ( void * ctx ATTRIBUTE_UNUSED ,
const char * msg ,
. . . ) ;
2001-06-05 21:12:52 +04:00
# define XML_GET_VAR_STR(msg, str) { \
int size ; \
int chars ; \
char * larger ; \
va_list ap ; \
\
str = ( char * ) xmlMalloc ( 150 ) ; \
2003-10-03 02:28:19 +04:00
if ( str ! = NULL ) { \
2001-06-05 21:12:52 +04:00
\
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 ) { \
2003-10-03 02:28:19 +04:00
break ; \
2001-06-05 21:12:52 +04:00
} \
str = larger ; \
2003-10-03 02:28:19 +04:00
} } \
2001-06-05 21:12:52 +04:00
}
2001-06-05 16:45:55 +04:00
2001-02-23 20:55:21 +03: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 14:48:19 +03:00
void
2001-03-26 20:28:29 +04:00
xmlGenericErrorDefaultFunc ( void * ctx ATTRIBUTE_UNUSED , const char * msg , . . . ) {
2001-02-23 20:55:21 +03: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 21:15:52 +03:00
/**
* initGenericErrorDefaultFunc :
* @ handler : the handler
*
* Set or reset ( if NULL ) the default handler for generic errors
2003-01-24 17:14:52 +03:00
* to the builtin error function .
2002-01-22 21:15:52 +03:00
*/
2001-10-13 13:15:48 +04:00
void
2002-01-18 14:49:26 +03:00
initGenericErrorDefaultFunc ( xmlGenericErrorFunc * handler )
2001-10-13 13:15:48 +04:00
{
2002-01-18 14:49:26 +03:00
if ( handler = = NULL )
xmlGenericError = xmlGenericErrorDefaultFunc ;
else
2004-04-20 13:45:26 +04:00
xmlGenericError = ( * handler ) ;
2001-10-13 13:15:48 +04:00
}
2001-02-23 20:55:21 +03: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 .
2004-08-14 15:15:13 +04:00
* For multi - threaded applications , this must be set separately for each thread .
2001-02-23 20:55:21 +03:00
*/
void
xmlSetGenericErrorFunc ( void * ctx , xmlGenericErrorFunc handler ) {
xmlGenericErrorContext = ctx ;
if ( handler ! = NULL )
xmlGenericError = handler ;
else
xmlGenericError = xmlGenericErrorDefaultFunc ;
}
2003-10-10 18:10:40 +04:00
/**
* xmlSetStructuredErrorFunc :
* @ ctx : the new error handling context
* @ handler : the new handler function
*
* Function to reset the handler and the error context for out of
* context structured 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
2004-08-14 15:15:13 +04:00
* For multi - threaded applications , this must be set separately for each thread .
2003-10-10 18:10:40 +04:00
*/
void
xmlSetStructuredErrorFunc ( void * ctx , xmlStructuredErrorFunc handler ) {
xmlGenericErrorContext = ctx ;
xmlStructuredError = handler ;
}
2001-02-23 20:55:21 +03:00
/************************************************************************
* *
* 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
*/
2003-10-03 02:28:19 +04:00
static void
xmlParserPrintFileContextInternal ( xmlParserInputPtr input ,
xmlGenericErrorFunc channel , void * data ) {
2002-03-21 00:55:57 +03:00
const xmlChar * cur , * base ;
2003-08-05 19:52:22 +04:00
unsigned int n , col ; /* GCC warns if signed, because compared with sizeof() */
2003-05-13 06:06:18 +04:00
xmlChar content [ 81 ] ; /* space for 80 chars + line terminator */
2001-03-27 04:32:28 +04:00
xmlChar * ctnt ;
2001-02-23 20:55:21 +03:00
2002-03-21 00:55:57 +03:00
if ( input = = NULL ) return ;
2001-02-23 20:55:21 +03:00
cur = input - > cur ;
base = input - > base ;
2001-03-27 04:32:28 +04:00
/* skip backwards over any end-of-lines */
2003-08-05 19:52:22 +04:00
while ( ( cur > base ) & & ( ( * ( cur ) = = ' \n ' ) | | ( * ( cur ) = = ' \r ' ) ) ) {
2002-03-21 00:55:57 +03:00
cur - - ;
2001-02-23 20:55:21 +03:00
}
n = 0 ;
2003-05-13 06:06:18 +04:00
/* search backwards for beginning-of-line (to max buff size) */
2003-08-05 19:52:22 +04:00
while ( ( n + + < ( sizeof ( content ) - 1 ) ) & & ( cur > base ) & &
( * ( cur ) ! = ' \n ' ) & & ( * ( cur ) ! = ' \r ' ) )
2001-02-23 20:55:21 +03:00
cur - - ;
2003-08-05 19:52:22 +04:00
if ( ( * ( cur ) = = ' \n ' ) | | ( * ( cur ) = = ' \r ' ) ) cur + + ;
2003-05-13 06:06:18 +04:00
/* calculate the error position in terms of the current position */
col = input - > cur - cur ;
/* search forward for end-of-line (to max buff size) */
2001-02-23 20:55:21 +03:00
n = 0 ;
2001-03-27 04:32:28 +04:00
ctnt = content ;
2003-05-13 06:06:18 +04:00
/* copy selected text to our buffer */
2003-08-05 19:52:22 +04:00
while ( ( * cur ! = 0 ) & & ( * ( cur ) ! = ' \n ' ) & &
( * ( cur ) ! = ' \r ' ) & & ( n < sizeof ( content ) - 1 ) ) {
2002-03-21 00:55:57 +03:00
* ctnt + + = * cur + + ;
n + + ;
2001-02-23 20:55:21 +03:00
}
2001-03-27 04:32:28 +04:00
* ctnt = 0 ;
2003-05-13 06:06:18 +04:00
/* print out the selected text */
2003-10-03 02:28:19 +04:00
channel ( data , " %s \n " , content ) ;
2001-03-27 04:32:28 +04:00
/* create blank line with problem pointer */
2001-02-23 20:55:21 +03:00
n = 0 ;
2001-04-24 19:52:00 +04:00
ctnt = content ;
2003-05-13 06:06:18 +04:00
/* (leave buffer space for pointer + line terminator) */
while ( ( n < col ) & & ( n + + < sizeof ( content ) - 2 ) & & ( * ctnt ! = 0 ) ) {
2003-08-05 19:52:22 +04:00
if ( * ( ctnt ) ! = ' \t ' )
* ( ctnt ) = ' ' ;
2003-09-22 04:24:51 +04:00
ctnt + + ;
2002-03-21 00:55:57 +03:00
}
2003-05-13 06:06:18 +04:00
* ctnt + + = ' ^ ' ;
* ctnt = 0 ;
2003-10-03 02:28:19 +04:00
channel ( data , " %s \n " , content ) ;
}
/**
* xmlParserPrintFileContext :
* @ input : an xmlParserInputPtr input
*
* Displays current context within the input content for error tracking
*/
void
xmlParserPrintFileContext ( xmlParserInputPtr input ) {
xmlParserPrintFileContextInternal ( input , xmlGenericError ,
xmlGenericErrorContext ) ;
2002-03-21 00:55:57 +03:00
}
/**
2003-10-03 02:28:19 +04:00
* xmlReportError :
2003-10-04 02:21:51 +04:00
* @ err : the error
2003-10-03 02:28:19 +04:00
* @ ctx : the parser context or NULL
* @ str : the formatted error message
2002-03-21 00:55:57 +03:00
*
2003-10-03 02:28:19 +04:00
* Report an erro with its context , replace the 4 old error / warning
* routines .
2002-03-21 00:55:57 +03:00
*/
2003-10-03 02:28:19 +04:00
static void
2003-10-07 15:33:24 +04:00
xmlReportError ( xmlErrorPtr err , xmlParserCtxtPtr ctxt , const char * str ,
xmlGenericErrorFunc channel , void * data )
2003-10-04 02:21:51 +04:00
{
2003-10-03 02:28:19 +04:00
char * file = NULL ;
int line = 0 ;
int code = - 1 ;
int domain ;
2003-10-07 15:33:24 +04:00
const xmlChar * name = NULL ;
xmlNodePtr node ;
2003-10-03 02:28:19 +04:00
xmlErrorLevel level ;
xmlParserInputPtr input = NULL ;
xmlParserInputPtr cur = NULL ;
2003-10-04 02:21:51 +04:00
if ( err = = NULL )
return ;
2003-10-03 02:28:19 +04:00
2003-10-07 15:33:24 +04:00
if ( channel = = NULL ) {
channel = xmlGenericError ;
data = xmlGenericErrorContext ;
}
2003-10-04 02:21:51 +04:00
file = err - > file ;
line = err - > line ;
code = err - > code ;
domain = err - > domain ;
level = err - > level ;
2003-10-07 15:33:24 +04:00
node = err - > node ;
2003-10-04 02:21:51 +04:00
2003-10-03 02:28:19 +04:00
if ( code = = XML_ERR_OK )
return ;
2003-10-07 15:33:24 +04:00
if ( ( node ! = NULL ) & & ( node - > type = = XML_ELEMENT_NODE ) )
name = node - > name ;
2003-10-03 02:28:19 +04:00
/*
* Maintain the compatibility with the legacy error handling
*/
2003-10-04 02:21:51 +04:00
if ( ctxt ! = NULL ) {
input = ctxt - > input ;
if ( ( input ! = NULL ) & & ( input - > filename = = NULL ) & &
( ctxt - > inputNr > 1 ) ) {
cur = input ;
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
if ( input ! = NULL ) {
if ( input - > filename )
channel ( data , " %s:%d: " , input - > filename , input - > line ) ;
2003-10-08 01:25:12 +04:00
else if ( ( line ! = 0 ) & & ( domain = = XML_FROM_PARSER ) )
2003-10-04 02:21:51 +04:00
channel ( data , " Entity: line %d: " , input - > line ) ;
}
} else {
if ( file ! = NULL )
channel ( data , " %s:%d: " , file , line ) ;
2003-10-08 01:25:12 +04:00
else if ( ( line ! = 0 ) & & ( domain = = XML_FROM_PARSER ) )
2003-10-04 02:21:51 +04:00
channel ( data , " Entity: line %d: " , line ) ;
2003-10-03 02:28:19 +04:00
}
2003-10-07 15:33:24 +04:00
if ( name ! = NULL ) {
channel ( data , " element %s: " , name ) ;
}
2003-10-03 02:28:19 +04:00
if ( code = = XML_ERR_OK )
return ;
switch ( domain ) {
case XML_FROM_PARSER :
channel ( data , " parser " ) ;
break ;
case XML_FROM_NAMESPACE :
channel ( data , " namespace " ) ;
break ;
case XML_FROM_DTD :
2003-10-28 18:44:17 +03:00
case XML_FROM_VALID :
2003-10-03 02:28:19 +04:00
channel ( data , " validity " ) ;
break ;
case XML_FROM_HTML :
channel ( data , " HTML parser " ) ;
break ;
case XML_FROM_MEMORY :
channel ( data , " memory " ) ;
break ;
case XML_FROM_OUTPUT :
channel ( data , " output " ) ;
break ;
case XML_FROM_IO :
channel ( data , " I/O " ) ;
break ;
case XML_FROM_XINCLUDE :
channel ( data , " XInclude " ) ;
break ;
case XML_FROM_XPATH :
channel ( data , " XPath " ) ;
break ;
case XML_FROM_XPOINTER :
channel ( data , " parser " ) ;
break ;
case XML_FROM_REGEXP :
channel ( data , " regexp " ) ;
break ;
2003-10-10 04:49:42 +04:00
case XML_FROM_SCHEMASV :
2003-10-10 14:52:58 +04:00
channel ( data , " Schemas validity " ) ;
2003-10-10 04:49:42 +04:00
break ;
case XML_FROM_SCHEMASP :
2003-10-10 14:52:58 +04:00
channel ( data , " Schemas parser " ) ;
2003-10-03 02:28:19 +04:00
break ;
2003-10-07 15:33:24 +04:00
case XML_FROM_RELAXNGP :
channel ( data , " Relax-NG parser " ) ;
break ;
case XML_FROM_RELAXNGV :
2003-10-10 04:49:42 +04:00
channel ( data , " Relax-NG validity " ) ;
2003-10-03 02:28:19 +04:00
break ;
case XML_FROM_CATALOG :
channel ( data , " Catalog " ) ;
break ;
case XML_FROM_C14N :
channel ( data , " C14N " ) ;
break ;
case XML_FROM_XSLT :
channel ( data , " XSLT " ) ;
break ;
default :
break ;
}
if ( code = = XML_ERR_OK )
return ;
switch ( level ) {
case XML_ERR_NONE :
channel ( data , " : " ) ;
2003-10-04 02:21:51 +04:00
break ;
2003-10-03 02:28:19 +04:00
case XML_ERR_WARNING :
channel ( data , " warning : " ) ;
2003-10-04 02:21:51 +04:00
break ;
2003-10-03 02:28:19 +04:00
case XML_ERR_ERROR :
channel ( data , " error : " ) ;
2003-10-04 02:21:51 +04:00
break ;
2003-10-03 02:28:19 +04:00
case XML_ERR_FATAL :
channel ( data , " error : " ) ;
2003-10-04 02:21:51 +04:00
break ;
2003-10-03 02:28:19 +04:00
}
if ( code = = XML_ERR_OK )
return ;
if ( str ! = NULL ) {
2003-10-08 23:19:10 +04:00
int len ;
len = xmlStrlen ( ( const xmlChar * ) str ) ;
if ( ( len > 0 ) & & ( str [ len - 1 ] ! = ' \n ' ) )
channel ( data , " %s \n " , str ) ;
2003-10-08 23:26:03 +04:00
else
channel ( data , " %s " , str ) ;
2003-10-03 02:28:19 +04:00
} else {
2003-10-08 23:19:10 +04:00
channel ( data , " %s \n " , " out of memory error " ) ;
2001-03-10 15:32:04 +03:00
}
2003-10-03 02:28:19 +04:00
if ( code = = XML_ERR_OK )
return ;
if ( ctxt ! = NULL ) {
xmlParserPrintFileContextInternal ( input , channel , data ) ;
if ( cur ! = NULL ) {
if ( cur - > filename )
channel ( data , " %s:%d: \n " , cur - > filename , cur - > line ) ;
2003-10-08 01:25:12 +04:00
else if ( ( line ! = 0 ) & & ( domain = = XML_FROM_PARSER ) )
2003-10-03 02:28:19 +04:00
channel ( data , " Entity: line %d: \n " , cur - > line ) ;
xmlParserPrintFileContextInternal ( cur , channel , data ) ;
}
}
2003-10-08 01:25:12 +04:00
if ( ( domain = = XML_FROM_XPATH ) & & ( err - > str1 ! = NULL ) & &
( err - > int1 < 100 ) & &
( err - > int1 < xmlStrlen ( ( const xmlChar * ) err - > str1 ) ) ) {
xmlChar buf [ 150 ] ;
int i ;
channel ( data , " %s \n " , err - > str1 ) ;
for ( i = 0 ; i < err - > int1 ; i + + )
buf [ i ] = ' ' ;
buf [ i + + ] = ' ^ ' ;
buf [ i ] = 0 ;
channel ( data , " %s \n " , buf ) ;
}
2003-10-03 02:28:19 +04:00
}
/**
2003-10-04 02:21:51 +04:00
* __xmlRaiseError :
2004-05-16 07:12:08 +04:00
* @ schannel : the structured callback channel
2003-10-10 18:10:40 +04:00
* @ channel : the old callback channel
2003-10-04 02:21:51 +04:00
* @ data : the callback data
* @ ctx : the parser context or NULL
2003-10-03 02:28:19 +04:00
* @ ctx : the parser context or NULL
* @ domain : the domain for the error
* @ code : the code for the error
* @ level : the xmlErrorLevel for the error
* @ file : the file source of the error ( or NULL )
* @ line : the line of the error or 0 if N / A
* @ str1 : extra string info
* @ str2 : extra string info
* @ str3 : extra string info
* @ int1 : extra int info
* @ int2 : extra int info
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
2004-05-16 07:12:08 +04:00
* Update the appropriate global or contextual error structure ,
2003-10-03 02:28:19 +04:00
* then forward the error message down the parser or generic
* error callback handler
*/
void
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( xmlStructuredErrorFunc schannel ,
xmlGenericErrorFunc channel , void * data , void * ctx ,
2003-10-04 02:21:51 +04:00
void * nod , int domain , int code , xmlErrorLevel level ,
2003-10-03 02:28:19 +04:00
const char * file , int line , const char * str1 ,
const char * str2 , const char * str3 , int int1 , int int2 ,
const char * msg , . . . )
{
2003-10-09 02:38:13 +04:00
xmlParserCtxtPtr ctxt = NULL ;
2003-10-04 02:21:51 +04:00
xmlNodePtr node = ( xmlNodePtr ) nod ;
2003-10-03 02:28:19 +04:00
char * str = NULL ;
xmlParserInputPtr input = NULL ;
xmlErrorPtr to = & xmlLastError ;
2004-10-02 07:54:00 +04:00
xmlNodePtr baseptr = NULL ;
2003-10-03 02:28:19 +04:00
2003-12-08 20:41:29 +03:00
if ( ( xmlGetWarningsDefaultValue = = 0 ) & & ( level = = XML_ERR_WARNING ) )
return ;
2003-10-09 02:38:13 +04:00
if ( ( domain = = XML_FROM_PARSER ) | | ( domain = = XML_FROM_HTML ) | |
( domain = = XML_FROM_DTD ) | | ( domain = = XML_FROM_NAMESPACE ) | |
2004-10-25 20:23:56 +04:00
( domain = = XML_FROM_IO ) | | ( domain = = XML_FROM_VALID ) ) {
2003-10-09 02:38:13 +04:00
ctxt = ( xmlParserCtxtPtr ) ctx ;
2003-10-10 18:10:40 +04:00
if ( ( schannel = = NULL ) & & ( ctxt ! = NULL ) & & ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > initialized = = XML_SAX2_MAGIC ) )
schannel = ctxt - > sax - > serror ;
2003-10-09 02:38:13 +04:00
}
2004-07-26 01:07:29 +04:00
/*
* Check if structured error handler set
*/
if ( schannel = = NULL ) {
2003-12-08 13:25:02 +03:00
schannel = xmlStructuredError ;
2004-07-26 01:07:29 +04:00
/*
* if user has defined handler , change data ptr to user ' s choice
*/
if ( schannel ! = NULL )
data = xmlGenericErrorContext ;
}
2003-10-28 18:44:17 +03:00
if ( ( domain = = XML_FROM_VALID ) & &
( ( channel = = xmlParserValidityError ) | |
( channel = = xmlParserValidityWarning ) ) ) {
ctxt = ( xmlParserCtxtPtr ) ctx ;
if ( ( schannel = = NULL ) & & ( ctxt ! = NULL ) & & ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > initialized = = XML_SAX2_MAGIC ) )
schannel = ctxt - > sax - > serror ;
}
2003-10-03 02:28:19 +04:00
if ( code = = XML_ERR_OK )
return ;
/*
* Formatting the message
*/
if ( msg = = NULL ) {
str = ( char * ) xmlStrdup ( BAD_CAST " No error message provided " ) ;
} else {
XML_GET_VAR_STR ( msg , str ) ;
}
/*
* specific processing if a parser context is provided
*/
if ( ctxt ! = NULL ) {
if ( file = = NULL ) {
input = ctxt - > input ;
if ( ( input ! = NULL ) & & ( input - > filename = = NULL ) & &
( ctxt - > inputNr > 1 ) ) {
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
if ( input ! = NULL ) {
file = input - > filename ;
line = input - > line ;
}
}
to = & ctxt - > lastError ;
2003-10-04 02:21:51 +04:00
} else if ( ( node ! = NULL ) & & ( file = = NULL ) ) {
int i ;
2003-10-07 15:33:24 +04:00
if ( ( node - > doc ! = NULL ) & & ( node - > doc - > URL ! = NULL ) )
2004-10-02 07:54:00 +04:00
baseptr = node ;
2003-10-04 02:21:51 +04:00
for ( i = 0 ;
( ( i < 10 ) & & ( node ! = NULL ) & & ( node - > type ! = XML_ELEMENT_NODE ) ) ;
i + + )
node = node - > parent ;
2004-10-02 07:54:00 +04:00
if ( ( baseptr = = NULL ) & & ( node ! = NULL ) & &
2003-10-07 15:33:24 +04:00
( node - > doc ! = NULL ) & & ( node - > doc - > URL ! = NULL ) )
2004-10-02 07:54:00 +04:00
baseptr = node ;
2003-10-07 15:33:24 +04:00
2003-10-04 02:21:51 +04:00
if ( ( node ! = NULL ) & & ( node - > type = = XML_ELEMENT_NODE ) )
2003-10-21 04:05:38 +04:00
line = node - > line ;
2003-10-03 02:28:19 +04:00
}
/*
2004-05-16 07:12:08 +04:00
* Save the information about the error
2003-10-03 02:28:19 +04:00
*/
xmlResetError ( to ) ;
to - > domain = domain ;
to - > code = code ;
to - > message = str ;
to - > level = level ;
if ( file ! = NULL )
to - > file = ( char * ) xmlStrdup ( ( const xmlChar * ) file ) ;
2004-10-02 07:54:00 +04:00
else if ( baseptr ! = NULL ) {
# ifdef LIBXML_XINCLUDE_ENABLED
/*
* We check if the error is within an XInclude section and ,
* if so , attempt to print out the href of the XInclude instead
* of the usual " base " ( doc - > URL ) for the node ( bug 152623 ) .
*/
xmlNodePtr prev = baseptr ;
int inclcount = 0 ;
while ( prev ! = NULL ) {
if ( prev - > prev = = NULL )
prev = prev - > parent ;
else {
prev = prev - > prev ;
if ( prev - > type = = XML_XINCLUDE_START ) {
if ( - - inclcount < 0 )
break ;
} else if ( prev - > type = = XML_XINCLUDE_END )
inclcount + + ;
}
}
if ( prev ! = NULL ) {
to - > file = ( char * ) xmlGetProp ( prev , BAD_CAST " href " ) ;
} else
# endif
to - > file = ( char * ) xmlStrdup ( baseptr - > doc - > URL ) ;
file = to - > file ;
2003-10-04 02:21:51 +04:00
}
2003-10-03 02:28:19 +04:00
to - > line = line ;
if ( str1 ! = NULL )
to - > str1 = ( char * ) xmlStrdup ( ( const xmlChar * ) str1 ) ;
if ( str2 ! = NULL )
to - > str2 = ( char * ) xmlStrdup ( ( const xmlChar * ) str2 ) ;
if ( str3 ! = NULL )
to - > str3 = ( char * ) xmlStrdup ( ( const xmlChar * ) str3 ) ;
to - > int1 = int1 ;
to - > int2 = int2 ;
2003-10-07 15:33:24 +04:00
to - > node = node ;
2003-10-09 02:38:13 +04:00
to - > ctxt = ctx ;
2003-10-03 02:28:19 +04:00
2004-01-02 23:26:01 +03:00
if ( to ! = & xmlLastError )
xmlCopyError ( to , & xmlLastError ) ;
2003-10-03 02:28:19 +04:00
/*
2004-07-26 01:07:29 +04:00
* Find the callback channel if channel param is NULL
2003-10-03 02:28:19 +04:00
*/
2004-07-28 11:40:12 +04:00
if ( ( ctxt ! = NULL ) & & ( channel = = NULL ) & & ( xmlStructuredError = = NULL ) & & ( ctxt - > sax ! = NULL ) ) {
2003-10-03 02:28:19 +04:00
if ( level = = XML_ERR_WARNING )
channel = ctxt - > sax - > warning ;
else
channel = ctxt - > sax - > error ;
2003-10-07 15:33:24 +04:00
data = ctxt - > userData ;
2003-10-04 02:21:51 +04:00
} else if ( channel = = NULL ) {
2003-10-10 18:10:40 +04:00
if ( xmlStructuredError ! = NULL )
schannel = xmlStructuredError ;
else
channel = xmlGenericError ;
2003-10-03 02:28:19 +04:00
data = xmlGenericErrorContext ;
}
2003-10-10 18:10:40 +04:00
if ( schannel ! = NULL ) {
schannel ( data , to ) ;
return ;
}
2003-10-03 02:28:19 +04:00
if ( channel = = NULL )
return ;
if ( ( channel = = xmlParserError ) | |
( channel = = xmlParserWarning ) | |
( channel = = xmlParserValidityError ) | |
( channel = = xmlParserValidityWarning ) )
2003-10-07 15:33:24 +04:00
xmlReportError ( to , ctxt , str , NULL , NULL ) ;
else if ( ( channel = = ( xmlGenericErrorFunc ) fprintf ) | |
( channel = = xmlGenericErrorDefaultFunc ) )
xmlReportError ( to , ctxt , str , channel , data ) ;
2003-10-03 02:28:19 +04:00
else
channel ( data , " %s " , str ) ;
2001-03-10 15:32:04 +03:00
}
2003-10-08 03:16:40 +04:00
/**
* __xmlSimpleError :
* @ domain : where the error comes from
* @ code : the error code
* @ node : the context node
* @ extra : extra informations
*
* Handle an out of memory condition
*/
void
__xmlSimpleError ( int domain , int code , xmlNodePtr node ,
const char * msg , const char * extra )
{
if ( code = = XML_ERR_NO_MEMORY ) {
if ( extra )
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( NULL , NULL , NULL , NULL , node , domain ,
2003-10-08 03:16:40 +04:00
XML_ERR_NO_MEMORY , XML_ERR_FATAL , NULL , 0 , extra ,
NULL , NULL , 0 , 0 ,
" Memory allocation failed : %s \n " , extra ) ;
else
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( NULL , NULL , NULL , NULL , node , domain ,
2003-10-08 03:16:40 +04:00
XML_ERR_NO_MEMORY , XML_ERR_FATAL , NULL , 0 , NULL ,
NULL , NULL , 0 , 0 , " Memory allocation failed \n " ) ;
} else {
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( NULL , NULL , NULL , NULL , node , domain ,
2003-10-08 03:16:40 +04:00
code , XML_ERR_ERROR , NULL , 0 , extra ,
NULL , NULL , 0 , 0 , msg , extra ) ;
}
}
2001-02-23 20:55:21 +03: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 15:32:04 +03:00
char * str ;
2001-02-23 20:55:21 +03: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 21:12:52 +04:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 14:48:19 +03:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-19 02:17:47 +03:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 20:55:21 +03: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 15:32:04 +03:00
char * str ;
2001-02-23 20:55:21 +03: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 21:12:52 +04:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 14:48:19 +03:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-19 02:17:47 +03:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 20:55:21 +03: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-19 02:17:47 +03:00
char * str ;
2002-09-05 18:21:15 +04:00
int len = xmlStrlen ( ( const xmlChar * ) msg ) ;
static int had_info = 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: " ) ;
had_info = 0 ;
} else {
had_info = 1 ;
2001-02-23 20:55:21 +03:00
}
2001-06-05 21:12:52 +04:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 14:48:19 +03:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-19 02:17:47 +03:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 20:55:21 +03:00
2002-09-05 18:21:15 +04:00
if ( ( ctxt ! = NULL ) & & ( input ! = NULL ) ) {
2001-02-23 20:55:21 +03: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-19 02:17:47 +03:00
char * str ;
2002-09-05 18:21:15 +04:00
int len = xmlStrlen ( ( const xmlChar * ) msg ) ;
2001-02-23 20:55:21 +03:00
2002-09-05 18:21:15 +04:00
if ( ( ctxt ! = NULL ) & & ( len ! = 0 ) & & ( msg [ len - 1 ] ! = ' : ' ) ) {
2001-02-23 20:55:21 +03: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 21:12:52 +04:00
XML_GET_VAR_STR ( msg , str ) ;
2001-10-29 14:48:19 +03:00
xmlGenericError ( xmlGenericErrorContext , " %s " , str ) ;
2001-03-19 02:17:47 +03:00
if ( str ! = NULL )
xmlFree ( str ) ;
2001-02-23 20:55:21 +03:00
if ( ctxt ! = NULL ) {
xmlParserPrintFileContext ( input ) ;
}
}
2003-10-03 02:28:19 +04:00
/************************************************************************
* *
* Extended Error Handling *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlGetLastError :
*
* Get the last global error registered . This is per thread if compiled
* with thread support .
*
* Returns NULL if no error occured or a pointer to the error
*/
xmlErrorPtr
xmlGetLastError ( void )
{
if ( xmlLastError . code = = XML_ERR_OK )
return ( NULL ) ;
return ( & xmlLastError ) ;
}
/**
* xmlResetError :
* @ err : pointer to the error .
*
* Cleanup the error .
*/
void
xmlResetError ( xmlErrorPtr err )
{
if ( err = = NULL )
return ;
if ( err - > code = = XML_ERR_OK )
return ;
if ( err - > message ! = NULL )
xmlFree ( err - > message ) ;
if ( err - > file ! = NULL )
xmlFree ( err - > file ) ;
if ( err - > str1 ! = NULL )
xmlFree ( err - > str1 ) ;
if ( err - > str2 ! = NULL )
xmlFree ( err - > str2 ) ;
if ( err - > str3 ! = NULL )
xmlFree ( err - > str3 ) ;
memset ( err , 0 , sizeof ( xmlError ) ) ;
err - > code = XML_ERR_OK ;
}
/**
* xmlResetLastError :
*
* Cleanup the last global error registered . For parsing error
* this does not change the well - formedness result .
*/
void
xmlResetLastError ( void )
{
if ( xmlLastError . code = = XML_ERR_OK )
return ;
xmlResetError ( & xmlLastError ) ;
}
/**
* xmlCtxtGetLastError :
* @ ctx : an XML parser context
*
* Get the last parsing error registered .
*
* Returns NULL if no error occured or a pointer to the error
*/
xmlErrorPtr
xmlCtxtGetLastError ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
if ( ctxt = = NULL )
return ( NULL ) ;
if ( ctxt - > lastError . code = = XML_ERR_OK )
return ( NULL ) ;
return ( & ctxt - > lastError ) ;
}
/**
* xmlCtxtResetLastError :
* @ ctx : an XML parser context
*
* Cleanup the last global error registered . For parsing error
* this does not change the well - formedness result .
*/
void
xmlCtxtResetLastError ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
if ( ctxt = = NULL )
return ;
if ( ctxt - > lastError . code = = XML_ERR_OK )
return ;
xmlResetError ( & ctxt - > lastError ) ;
}
/**
* xmlCopyError :
* @ from : a source error
* @ to : a target error
*
* Save the original error to the new place .
*
* Returns 0 in case of success and - 1 in case of error .
*/
int
xmlCopyError ( xmlErrorPtr from , xmlErrorPtr to ) {
2004-07-31 20:24:01 +04:00
char * message , * file , * str1 , * str2 , * str3 ;
2003-10-03 02:28:19 +04:00
if ( ( from = = NULL ) | | ( to = = NULL ) )
return ( - 1 ) ;
2004-07-31 20:24:01 +04:00
message = ( char * ) xmlStrdup ( ( xmlChar * ) from - > message ) ;
file = ( char * ) xmlStrdup ( ( xmlChar * ) from - > file ) ;
str1 = ( char * ) xmlStrdup ( ( xmlChar * ) from - > str1 ) ;
str2 = ( char * ) xmlStrdup ( ( xmlChar * ) from - > str2 ) ;
str3 = ( char * ) xmlStrdup ( ( xmlChar * ) from - > str3 ) ;
2003-10-03 02:28:19 +04:00
if ( to - > message ! = NULL )
xmlFree ( to - > message ) ;
if ( to - > file ! = NULL )
xmlFree ( to - > file ) ;
if ( to - > str1 ! = NULL )
xmlFree ( to - > str1 ) ;
if ( to - > str2 ! = NULL )
xmlFree ( to - > str2 ) ;
if ( to - > str3 ! = NULL )
xmlFree ( to - > str3 ) ;
to - > domain = from - > domain ;
to - > code = from - > code ;
to - > level = from - > level ;
to - > line = from - > line ;
2003-10-07 15:33:24 +04:00
to - > node = from - > node ;
2003-10-03 02:28:19 +04:00
to - > int1 = from - > int1 ;
to - > int2 = from - > int2 ;
2003-10-07 15:33:24 +04:00
to - > node = from - > node ;
to - > ctxt = from - > ctxt ;
2004-07-31 20:24:01 +04:00
to - > message = message ;
to - > file = file ;
to - > str1 = str1 ;
to - > str2 = str2 ;
to - > str3 = str3 ;
return 0 ;
2003-10-03 02:28:19 +04:00
}