2 * error.c: module displaying/handling XML parser errors
4 * See Copyright for the status of this software.
6 * Daniel Veillard <daniel@veillard.com>
13 #include <libxml/parser.h>
14 #include <libxml/xmlerror.h>
15 #include <libxml/xmlmemory.h>
16 #include <libxml/globals.h>
18 void xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED
,
22 #define XML_GET_VAR_STR(msg, str) { \
28 str = (char *) xmlMalloc(150); \
36 chars = vsnprintf(str, size, msg, ap); \
38 if ((chars > -1) && (chars < size)) \
44 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
52 /************************************************************************
54 * Handling of out of context errors *
56 ************************************************************************/
59 * xmlGenericErrorDefaultFunc:
60 * @ctx: an error context
61 * @msg: the message to display/transmit
62 * @...: extra parameters for the message display
64 * Default handler for out of context error messages.
67 xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED
, const char *msg
, ...) {
70 if (xmlGenericErrorContext
== NULL
)
71 xmlGenericErrorContext
= (void *) stderr
;
74 vfprintf((FILE *)xmlGenericErrorContext
, msg
, args
);
79 * initGenericErrorDefaultFunc:
80 * @handler: the handler
82 * Set or reset (if NULL) the default handler for generic errors
85 initGenericErrorDefaultFunc(xmlGenericErrorFunc
* handler
)
88 xmlGenericError
= xmlGenericErrorDefaultFunc
;
90 (*handler
) = xmlGenericErrorDefaultFunc
;
94 * xmlSetGenericErrorFunc:
95 * @ctx: the new error handling context
96 * @handler: the new handler function
98 * Function to reset the handler and the error context for out of
99 * context error messages.
100 * This simply means that @handler will be called for subsequent
101 * error messages while not parsing nor validating. And @ctx will
102 * be passed as first argument to @handler
103 * One can simply force messages to be emitted to another FILE * than
104 * stderr by setting @ctx to this file handle and @handler to NULL.
107 xmlSetGenericErrorFunc(void *ctx
, xmlGenericErrorFunc handler
) {
108 xmlGenericErrorContext
= ctx
;
110 xmlGenericError
= handler
;
112 xmlGenericError
= xmlGenericErrorDefaultFunc
;
115 /************************************************************************
117 * Handling of parsing errors *
119 ************************************************************************/
122 * xmlParserPrintFileInfo:
123 * @input: an xmlParserInputPtr input
125 * Displays the associated file and line informations for the current input
129 xmlParserPrintFileInfo(xmlParserInputPtr input
) {
132 xmlGenericError(xmlGenericErrorContext
,
133 "%s:%d: ", input
->filename
,
136 xmlGenericError(xmlGenericErrorContext
,
137 "Entity: line %d: ", input
->line
);
142 * xmlParserPrintFileContext:
143 * @input: an xmlParserInputPtr input
145 * Displays current context within the input content for error tracking
149 xmlParserPrintFileContext(xmlParserInputPtr input
) {
150 const xmlChar
*cur
, *base
;
155 if (input
== NULL
) return;
158 /* skip backwards over any end-of-lines */
159 while ((cur
> base
) && ((*cur
== '\n') || (*cur
== '\r'))) {
163 /* search backwards for beginning-of-line maximum 80 characters */
164 while ((n
++ < 80) && (cur
> base
) && (*cur
!= '\n') && (*cur
!= '\r'))
166 if ((*cur
== '\n') || (*cur
== '\r')) cur
++;
167 /* search forward for end-of-line maximum 80 characters */
170 while ((*cur
!= 0) && (*cur
!= '\n') && (*cur
!= '\r') && (n
< 79)) {
175 xmlGenericError(xmlGenericErrorContext
,"%s\n", content
);
176 /* create blank line with problem pointer */
178 while ((cur
> base
) && ((*cur
== '\n') || (*cur
== '\r'))) {
183 while ((n
++ < 79) && (cur
> base
) && (*cur
!= '\n') && (*cur
!= '\r')) {
187 if (ctnt
> content
) {
194 xmlGenericError(xmlGenericErrorContext
,"%s\n", content
);
200 * @msg: the message format
201 * @args: a va_list argument list
204 * Get an arbitrary-sized string for an error argument
205 * The caller must free() the returned string
208 xmlGetVarStr(const char * msg
, va_list args
) {
215 str
= (char *) xmlMalloc(150);
223 left
= size
- length
;
224 /* Try to print in the allocated space. */
226 chars
= vsnprintf(str
+ length
, left
, msg
, ap
);
228 /* If that worked, we're done. */
229 if ((chars
> -1) && (chars
< left
))
231 /* Else try again with more space. */
232 if (chars
> -1) /* glibc 2.1 */
233 size
+= chars
+ 1; /* precisely what is needed */
236 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
248 * @ctx: an XML parser context
249 * @msg: the message to display/transmit
250 * @...: extra parameters for the message display
252 * Display and format an error messages, gives file, line, position and
256 xmlParserError(void *ctx
, const char *msg
, ...)
258 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
259 xmlParserInputPtr input
= NULL
;
260 xmlParserInputPtr cur
= NULL
;
265 if ((input
!= NULL
) && (input
->filename
== NULL
) &&
266 (ctxt
->inputNr
> 1)) {
268 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
270 xmlParserPrintFileInfo(input
);
273 xmlGenericError(xmlGenericErrorContext
, "error: ");
274 XML_GET_VAR_STR(msg
, str
);
275 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
280 xmlParserPrintFileContext(input
);
282 xmlParserPrintFileInfo(cur
);
283 xmlGenericError(xmlGenericErrorContext
, "\n");
284 xmlParserPrintFileContext(cur
);
291 * @ctx: an XML parser context
292 * @msg: the message to display/transmit
293 * @...: extra parameters for the message display
295 * Display and format a warning messages, gives file, line, position and
299 xmlParserWarning(void *ctx
, const char *msg
, ...)
301 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
302 xmlParserInputPtr input
= NULL
;
303 xmlParserInputPtr cur
= NULL
;
308 if ((input
!= NULL
) && (input
->filename
== NULL
) &&
309 (ctxt
->inputNr
> 1)) {
311 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
313 xmlParserPrintFileInfo(input
);
316 xmlGenericError(xmlGenericErrorContext
, "warning: ");
317 XML_GET_VAR_STR(msg
, str
);
318 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
323 xmlParserPrintFileContext(input
);
325 xmlParserPrintFileInfo(cur
);
326 xmlGenericError(xmlGenericErrorContext
, "\n");
327 xmlParserPrintFileContext(cur
);
332 /************************************************************************
334 * Handling of validation errors *
336 ************************************************************************/
339 * xmlParserValidityError:
340 * @ctx: an XML parser context
341 * @msg: the message to display/transmit
342 * @...: extra parameters for the message display
344 * Display and format an validity error messages, gives file,
345 * line, position and extra parameters.
348 xmlParserValidityError(void *ctx
, const char *msg
, ...)
350 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
351 xmlParserInputPtr input
= NULL
;
353 int len
= xmlStrlen((const xmlChar
*) msg
);
354 static int had_info
= 0;
355 int need_context
= 0;
357 if ((len
> 1) && (msg
[len
- 2] != ':')) {
360 if ((input
->filename
== NULL
) && (ctxt
->inputNr
> 1))
361 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
364 xmlParserPrintFileInfo(input
);
367 xmlGenericError(xmlGenericErrorContext
, "validity error: ");
374 XML_GET_VAR_STR(msg
, str
);
375 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
379 if ((ctxt
!= NULL
) && (input
!= NULL
)) {
380 xmlParserPrintFileContext(input
);
385 * xmlParserValidityWarning:
386 * @ctx: an XML parser context
387 * @msg: the message to display/transmit
388 * @...: extra parameters for the message display
390 * Display and format a validity warning messages, gives file, line,
391 * position and extra parameters.
394 xmlParserValidityWarning(void *ctx
, const char *msg
, ...)
396 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
397 xmlParserInputPtr input
= NULL
;
399 int len
= xmlStrlen((const xmlChar
*) msg
);
401 if ((ctxt
!= NULL
) && (len
!= 0) && (msg
[len
- 1] != ':')) {
403 if ((input
->filename
== NULL
) && (ctxt
->inputNr
> 1))
404 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
406 xmlParserPrintFileInfo(input
);
409 xmlGenericError(xmlGenericErrorContext
, "validity warning: ");
410 XML_GET_VAR_STR(msg
, str
);
411 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
416 xmlParserPrintFileContext(input
);