blob: cf76016f83b8cdcd192b2a4f9581e99a7362223e [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) {
Daniel Veillard58770e72000-11-25 00:48:47 +000065 xmlGenericErrorContext = ctx;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000066 if (handler != NULL)
67 xmlGenericError = handler;
Daniel Veillard58770e72000-11-25 00:48:47 +000068 else
69 xmlGenericError = xmlGenericErrorDefaultFunc;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000070}
71
72/************************************************************************
73 * *
74 * Handling of parsing errors *
75 * *
76 ************************************************************************/
Daniel Veillard260a68f1998-08-13 03:39:55 +000077
Daniel Veillardb96e6431999-08-29 21:02:19 +000078/**
79 * xmlParserPrintFileInfo:
80 * @input: an xmlParserInputPtr input
81 *
82 * Displays the associated file and line informations for the current input
83 */
84
85void
Daniel Veillardb05deb71999-08-10 19:04:08 +000086xmlParserPrintFileInfo(xmlParserInputPtr input) {
87 if (input != NULL) {
88 if (input->filename)
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000089 xmlGenericError(xmlGenericErrorContext,
90 "%s:%d: ", input->filename,
Daniel Veillardb05deb71999-08-10 19:04:08 +000091 input->line);
92 else
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000093 xmlGenericError(xmlGenericErrorContext,
94 "Entity: line %d: ", input->line);
Daniel Veillardb05deb71999-08-10 19:04:08 +000095 }
96}
97
Daniel Veillardb96e6431999-08-29 21:02:19 +000098/**
99 * xmlParserPrintFileContext:
100 * @input: an xmlParserInputPtr input
101 *
102 * Displays current context within the input content for error tracking
103 */
104
105void
Daniel Veillardb05deb71999-08-10 19:04:08 +0000106xmlParserPrintFileContext(xmlParserInputPtr input) {
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000107 const xmlChar *cur, *base;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000108 int n;
109
Daniel Veillard686d6b62000-01-03 11:08:02 +0000110 if (input == NULL) return;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000111 cur = input->cur;
112 base = input->base;
Daniel Veillard1e346af1999-02-22 10:33:01 +0000113 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000114 cur--;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000115 }
116 n = 0;
Daniel Veillardbc50b591999-03-01 12:28:53 +0000117 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
Daniel Veillard260a68f1998-08-13 03:39:55 +0000118 cur--;
119 if ((*cur == '\n') || (*cur == '\r')) cur++;
120 base = cur;
121 n = 0;
122 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000123 xmlGenericError(xmlGenericErrorContext,
124 "%c", (unsigned char) *cur++);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000125 n++;
126 }
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000127 xmlGenericError(xmlGenericErrorContext, "\n");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000128 cur = input->cur;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000129 while ((*cur == '\n') || (*cur == '\r'))
130 cur--;
131 n = 0;
Daniel Veillardbc50b591999-03-01 12:28:53 +0000132 while ((cur != base) && (n++ < 80)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000133 xmlGenericError(xmlGenericErrorContext, " ");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000134 base++;
135 }
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000136 xmlGenericError(xmlGenericErrorContext,"^\n");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000137}
138
Daniel Veillard97b58771998-10-20 06:14:16 +0000139/**
Daniel Veillardb05deb71999-08-10 19:04:08 +0000140 * xmlParserError:
141 * @ctx: an XML parser context
142 * @msg: the message to display/transmit
143 * @...: extra parameters for the message display
144 *
145 * Display and format an error messages, gives file, line, position and
146 * extra parameters.
147 */
148void
149xmlParserError(void *ctx, const char *msg, ...)
150{
151 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000152 xmlParserInputPtr input = NULL;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000153 xmlParserInputPtr cur = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000154 va_list args;
155
Daniel Veillard39c7d712000-09-10 16:14:55 +0000156 if (ctxt != NULL) {
157 input = ctxt->input;
158 if ((input != NULL) && (input->filename == NULL) &&
159 (ctxt->inputNr > 1)) {
160 cur = input;
161 input = ctxt->inputTab[ctxt->inputNr - 2];
162 }
163 xmlParserPrintFileInfo(input);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000164 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000165
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000166 xmlGenericError(xmlGenericErrorContext, "error: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000167 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000168 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000169 va_end(args);
170
Daniel Veillard39c7d712000-09-10 16:14:55 +0000171 if (ctxt != NULL) {
172 xmlParserPrintFileContext(input);
173 if (cur != NULL) {
174 xmlParserPrintFileInfo(cur);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000175 xmlGenericError(xmlGenericErrorContext, "\n");
Daniel Veillard39c7d712000-09-10 16:14:55 +0000176 xmlParserPrintFileContext(cur);
177 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000178 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000179}
180
181/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000182 * xmlParserWarning:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000183 * @ctx: an XML parser context
Daniel Veillard97b58771998-10-20 06:14:16 +0000184 * @msg: the message to display/transmit
185 * @...: extra parameters for the message display
186 *
187 * Display and format a warning messages, gives file, line, position and
188 * extra parameters.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000189 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000190void
Daniel Veillard27d88741999-05-29 11:51:49 +0000191xmlParserWarning(void *ctx, const char *msg, ...)
Daniel Veillard97b58771998-10-20 06:14:16 +0000192{
Daniel Veillard27d88741999-05-29 11:51:49 +0000193 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000194 xmlParserInputPtr input = NULL;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000195 xmlParserInputPtr cur = NULL;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000196 va_list args;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000197
Daniel Veillard39c7d712000-09-10 16:14:55 +0000198 if (ctxt != NULL) {
199 input = ctxt->input;
200 if ((input != NULL) && (input->filename == NULL) &&
201 (ctxt->inputNr > 1)) {
202 cur = input;
203 input = ctxt->inputTab[ctxt->inputNr - 2];
204 }
205 xmlParserPrintFileInfo(input);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000206 }
207
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000208 xmlGenericError(xmlGenericErrorContext, "warning: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000209 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000210 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillard64068b31999-03-24 20:42:16 +0000211 va_end(args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000212
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000213
Daniel Veillard39c7d712000-09-10 16:14:55 +0000214 if (ctxt != NULL) {
215 xmlParserPrintFileContext(input);
216 if (cur != NULL) {
217 xmlParserPrintFileInfo(cur);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000218 xmlGenericError(xmlGenericErrorContext, "\n");
Daniel Veillard39c7d712000-09-10 16:14:55 +0000219 xmlParserPrintFileContext(cur);
220 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000221 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000222}
223
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000224/************************************************************************
225 * *
226 * Handling of validation errors *
227 * *
228 ************************************************************************/
229
Daniel Veillardb05deb71999-08-10 19:04:08 +0000230/**
231 * xmlParserValidityError:
232 * @ctx: an XML parser context
233 * @msg: the message to display/transmit
234 * @...: extra parameters for the message display
235 *
236 * Display and format an validity error messages, gives file,
237 * line, position and extra parameters.
238 */
239void
240xmlParserValidityError(void *ctx, const char *msg, ...)
241{
242 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000243 xmlParserInputPtr input = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000244 va_list args;
245
Daniel Veillard39c7d712000-09-10 16:14:55 +0000246 if (ctxt != NULL) {
247 input = ctxt->input;
248 if ((input->filename == NULL) && (ctxt->inputNr > 1))
249 input = ctxt->inputTab[ctxt->inputNr - 2];
250
251 xmlParserPrintFileInfo(input);
252 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000253
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000254 xmlGenericError(xmlGenericErrorContext, "validity error: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000255 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000256 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000257 va_end(args);
258
Daniel Veillard39c7d712000-09-10 16:14:55 +0000259 if (ctxt != NULL) {
260 xmlParserPrintFileContext(input);
261 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000262}
263
264/**
265 * xmlParserValidityWarning:
266 * @ctx: an XML parser context
267 * @msg: the message to display/transmit
268 * @...: extra parameters for the message display
269 *
270 * Display and format a validity warning messages, gives file, line,
271 * position and extra parameters.
272 */
273void
274xmlParserValidityWarning(void *ctx, const char *msg, ...)
275{
276 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000277 xmlParserInputPtr input = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000278 va_list args;
279
Daniel Veillard39c7d712000-09-10 16:14:55 +0000280 if (ctxt != NULL) {
281 input = ctxt->input;
282 if ((input->filename == NULL) && (ctxt->inputNr > 1))
283 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardb05deb71999-08-10 19:04:08 +0000284
Daniel Veillard39c7d712000-09-10 16:14:55 +0000285 xmlParserPrintFileInfo(input);
286 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000287
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000288 xmlGenericError(xmlGenericErrorContext, "validity warning: ");
Daniel Veillardb05deb71999-08-10 19:04:08 +0000289 va_start(args, msg);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000290 vfprintf(xmlGenericErrorContext, msg, args);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000291 va_end(args);
292
Daniel Veillard39c7d712000-09-10 16:14:55 +0000293 if (ctxt != NULL) {
294 xmlParserPrintFileContext(input);
295 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000296}
Daniel Veillard97b58771998-10-20 06:14:16 +0000297
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000298