blob: 806cdad56588652e9f7d28ddc1404b25bbff690f [file] [log] [blame]
Daniel Veillard260a68f1998-08-13 03:39:55 +00001/*
Daniel Veillard97b58771998-10-20 06:14:16 +00002 * error.c: module displaying/handling XML parser errors
3 *
Daniel Veillard39a1f9a1999-01-17 19:11:59 +00004 * See Copyright for the status of this software.
5 *
Daniel Veillard97b58771998-10-20 06:14:16 +00006 * Daniel Veillard <Daniel.Veillard@w3.org>
Daniel Veillard260a68f1998-08-13 03:39:55 +00007 */
8
Daniel Veillard3c558c31999-12-22 11:30:41 +00009#ifdef WIN32
10#include "win32config.h"
11#else
12#include "config.h"
13#endif
14
Daniel Veillard260a68f1998-08-13 03:39:55 +000015#include <stdio.h>
16#include <stdarg.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000017#include <libxml/parser.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000018#include <libxml/xmlerror.h>
19
20/************************************************************************
21 * *
22 * Handling of out of context errors *
23 * *
24 ************************************************************************/
25
26/**
27 * xmlGenericErrorDefaultFunc:
28 * @ctx: an error context
29 * @msg: the message to display/transmit
30 * @...: extra parameters for the message display
31 *
32 * Default handler for out of context error messages.
33 */
34void
35xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...) {
36 va_list args;
37
38 if (xmlGenericErrorContext == NULL)
39 xmlGenericErrorContext = (void *) stderr;
40
41 va_start(args, msg);
42 vfprintf((FILE *)xmlGenericErrorContext, msg, args);
43 va_end(args);
44}
45
46xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
47void *xmlGenericErrorContext = NULL;
48
49
50/**
51 * xmlSetGenericErrorFunc:
52 * @ctx: the new error handling context
53 * @handler: the new handler function
54 *
55 * Function to reset the handler and the error context for out of
56 * context error messages.
57 * This simply means that @handler will be called for subsequent
58 * error messages while not parsing nor validating. And @ctx will
59 * be passed as first argument to @handler
60 * One can simply force messages to be emitted to another FILE * than
61 * stderr by setting @ctx to this file handle and @handler to NULL.
62 */
63void
64xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
65 if (ctx != NULL)
66 xmlGenericErrorContext = ctx;
67 if (handler != NULL)
68 xmlGenericError = handler;
69}
70
71/************************************************************************
72 * *
73 * Handling of parsing errors *
74 * *
75 ************************************************************************/
Daniel Veillard260a68f1998-08-13 03:39:55 +000076
Daniel Veillardb96e6431999-08-29 21:02:19 +000077/**
78 * xmlParserPrintFileInfo:
79 * @input: an xmlParserInputPtr input
80 *
81 * Displays the associated file and line informations for the current input
82 */
83
84void
Daniel Veillardb05deb71999-08-10 19:04:08 +000085xmlParserPrintFileInfo(xmlParserInputPtr input) {
86 if (input != NULL) {
87 if (input->filename)
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000088 xmlGenericError(xmlGenericErrorContext,
89 "%s:%d: ", input->filename,
Daniel Veillardb05deb71999-08-10 19:04:08 +000090 input->line);
91 else
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000092 xmlGenericError(xmlGenericErrorContext,
93 "Entity: line %d: ", input->line);
Daniel Veillardb05deb71999-08-10 19:04:08 +000094 }
95}
96
Daniel Veillardb96e6431999-08-29 21:02:19 +000097/**
98 * xmlParserPrintFileContext:
99 * @input: an xmlParserInputPtr input
100 *
101 * Displays current context within the input content for error tracking
102 */
103
104void
Daniel Veillardb05deb71999-08-10 19:04:08 +0000105xmlParserPrintFileContext(xmlParserInputPtr input) {
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000106 const xmlChar *cur, *base;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000107 int n;
108
Daniel Veillard686d6b62000-01-03 11:08:02 +0000109 if (input == NULL) return;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000110 cur = input->cur;
111 base = input->base;
Daniel Veillard1e346af1999-02-22 10:33:01 +0000112 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000113 cur--;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000114 }
115 n = 0;
Daniel Veillardbc50b591999-03-01 12:28:53 +0000116 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
Daniel Veillard260a68f1998-08-13 03:39:55 +0000117 cur--;
118 if ((*cur == '\n') || (*cur == '\r')) cur++;
119 base = cur;
120 n = 0;
121 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000122 xmlGenericError(xmlGenericErrorContext,
123 "%c", (unsigned char) *cur++);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000124 n++;
125 }
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000126 xmlGenericError(xmlGenericErrorContext, "\n");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000127 cur = input->cur;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000128 while ((*cur == '\n') || (*cur == '\r'))
129 cur--;
130 n = 0;
Daniel Veillardbc50b591999-03-01 12:28:53 +0000131 while ((cur != base) && (n++ < 80)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000132 xmlGenericError(xmlGenericErrorContext, " ");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000133 base++;
134 }
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000135 xmlGenericError(xmlGenericErrorContext,"^\n");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000136}
137
Daniel Veillard97b58771998-10-20 06:14:16 +0000138/**
Daniel Veillardb05deb71999-08-10 19:04:08 +0000139 * xmlParserError:
140 * @ctx: an XML parser context
141 * @msg: the message to display/transmit
142 * @...: extra parameters for the message display
143 *
144 * Display and format an error messages, gives file, line, position and
145 * extra parameters.
146 */
147void
148xmlParserError(void *ctx, const char *msg, ...)
149{
150 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000151 xmlParserInputPtr input = NULL;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000152 xmlParserInputPtr cur = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000153 va_list args;
154
Daniel Veillard39c7d712000-09-10 16:14:55 +0000155 if (ctxt != NULL) {
156 input = ctxt->input;
157 if ((input != NULL) && (input->filename == NULL) &&
158 (ctxt->inputNr > 1)) {
159 cur = input;
160 input = ctxt->inputTab[ctxt->inputNr - 2];
161 }
162 xmlParserPrintFileInfo(input);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000163 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000164
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000165 xmlGenericError(xmlGenericErrorContext, "error: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000166 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000167 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000168 va_end(args);
169
Daniel Veillard39c7d712000-09-10 16:14:55 +0000170 if (ctxt != NULL) {
171 xmlParserPrintFileContext(input);
172 if (cur != NULL) {
173 xmlParserPrintFileInfo(cur);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000174 xmlGenericError(xmlGenericErrorContext, "\n");
Daniel Veillard39c7d712000-09-10 16:14:55 +0000175 xmlParserPrintFileContext(cur);
176 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000177 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000178}
179
180/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000181 * xmlParserWarning:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000182 * @ctx: an XML parser context
Daniel Veillard97b58771998-10-20 06:14:16 +0000183 * @msg: the message to display/transmit
184 * @...: extra parameters for the message display
185 *
186 * Display and format a warning messages, gives file, line, position and
187 * extra parameters.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000188 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000189void
Daniel Veillard27d88741999-05-29 11:51:49 +0000190xmlParserWarning(void *ctx, const char *msg, ...)
Daniel Veillard97b58771998-10-20 06:14:16 +0000191{
Daniel Veillard27d88741999-05-29 11:51:49 +0000192 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000193 xmlParserInputPtr input = NULL;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000194 xmlParserInputPtr cur = NULL;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000195 va_list args;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000196
Daniel Veillard39c7d712000-09-10 16:14:55 +0000197 if (ctxt != NULL) {
198 input = ctxt->input;
199 if ((input != NULL) && (input->filename == NULL) &&
200 (ctxt->inputNr > 1)) {
201 cur = input;
202 input = ctxt->inputTab[ctxt->inputNr - 2];
203 }
204 xmlParserPrintFileInfo(input);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000205 }
206
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000207 xmlGenericError(xmlGenericErrorContext, "warning: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000208 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000209 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillard64068b31999-03-24 20:42:16 +0000210 va_end(args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000211
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000212
Daniel Veillard39c7d712000-09-10 16:14:55 +0000213 if (ctxt != NULL) {
214 xmlParserPrintFileContext(input);
215 if (cur != NULL) {
216 xmlParserPrintFileInfo(cur);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000217 xmlGenericError(xmlGenericErrorContext, "\n");
Daniel Veillard39c7d712000-09-10 16:14:55 +0000218 xmlParserPrintFileContext(cur);
219 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000220 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000221}
222
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000223/************************************************************************
224 * *
225 * Handling of validation errors *
226 * *
227 ************************************************************************/
228
Daniel Veillardb05deb71999-08-10 19:04:08 +0000229/**
230 * xmlParserValidityError:
231 * @ctx: an XML parser context
232 * @msg: the message to display/transmit
233 * @...: extra parameters for the message display
234 *
235 * Display and format an validity error messages, gives file,
236 * line, position and extra parameters.
237 */
238void
239xmlParserValidityError(void *ctx, const char *msg, ...)
240{
241 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000242 xmlParserInputPtr input = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000243 va_list args;
244
Daniel Veillard39c7d712000-09-10 16:14:55 +0000245 if (ctxt != NULL) {
246 input = ctxt->input;
247 if ((input->filename == NULL) && (ctxt->inputNr > 1))
248 input = ctxt->inputTab[ctxt->inputNr - 2];
249
250 xmlParserPrintFileInfo(input);
251 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000252
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000253 xmlGenericError(xmlGenericErrorContext, "validity error: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000254 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000255 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000256 va_end(args);
257
Daniel Veillard39c7d712000-09-10 16:14:55 +0000258 if (ctxt != NULL) {
259 xmlParserPrintFileContext(input);
260 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000261}
262
263/**
264 * xmlParserValidityWarning:
265 * @ctx: an XML parser context
266 * @msg: the message to display/transmit
267 * @...: extra parameters for the message display
268 *
269 * Display and format a validity warning messages, gives file, line,
270 * position and extra parameters.
271 */
272void
273xmlParserValidityWarning(void *ctx, const char *msg, ...)
274{
275 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000276 xmlParserInputPtr input = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000277 va_list args;
278
Daniel Veillard39c7d712000-09-10 16:14:55 +0000279 if (ctxt != NULL) {
280 input = ctxt->input;
281 if ((input->filename == NULL) && (ctxt->inputNr > 1))
282 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardb05deb71999-08-10 19:04:08 +0000283
Daniel Veillard39c7d712000-09-10 16:14:55 +0000284 xmlParserPrintFileInfo(input);
285 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000286
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000287 xmlGenericError(xmlGenericErrorContext, "validity warning: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000288 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000289 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000290 va_end(args);
291
Daniel Veillard39c7d712000-09-10 16:14:55 +0000292 if (ctxt != NULL) {
293 xmlParserPrintFileContext(input);
294 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000295}
Daniel Veillard97b58771998-10-20 06:14:16 +0000296
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000297