blob: cf76016f83b8cdcd192b2a4f9581e99a7362223e [file] [log] [blame]
Owen Taylor3473f882001-02-23 17:55:21 +00001/*
2 * error.c: module displaying/handling XML parser errors
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel Veillard <Daniel.Veillard@w3.org>
7 */
8
9#ifdef WIN32
10#include "win32config.h"
11#else
12#include "config.h"
13#endif
14
15#include <stdio.h>
16#include <stdarg.h>
17#include <libxml/parser.h>
18#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 xmlGenericErrorContext = ctx;
66 if (handler != NULL)
67 xmlGenericError = handler;
68 else
69 xmlGenericError = xmlGenericErrorDefaultFunc;
70}
71
72/************************************************************************
73 * *
74 * Handling of parsing errors *
75 * *
76 ************************************************************************/
77
78/**
79 * xmlParserPrintFileInfo:
80 * @input: an xmlParserInputPtr input
81 *
82 * Displays the associated file and line informations for the current input
83 */
84
85void
86xmlParserPrintFileInfo(xmlParserInputPtr input) {
87 if (input != NULL) {
88 if (input->filename)
89 xmlGenericError(xmlGenericErrorContext,
90 "%s:%d: ", input->filename,
91 input->line);
92 else
93 xmlGenericError(xmlGenericErrorContext,
94 "Entity: line %d: ", input->line);
95 }
96}
97
98/**
99 * xmlParserPrintFileContext:
100 * @input: an xmlParserInputPtr input
101 *
102 * Displays current context within the input content for error tracking
103 */
104
105void
106xmlParserPrintFileContext(xmlParserInputPtr input) {
107 const xmlChar *cur, *base;
108 int n;
109
110 if (input == NULL) return;
111 cur = input->cur;
112 base = input->base;
113 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
114 cur--;
115 }
116 n = 0;
117 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
118 cur--;
119 if ((*cur == '\n') || (*cur == '\r')) cur++;
120 base = cur;
121 n = 0;
122 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
123 xmlGenericError(xmlGenericErrorContext,
124 "%c", (unsigned char) *cur++);
125 n++;
126 }
127 xmlGenericError(xmlGenericErrorContext, "\n");
128 cur = input->cur;
129 while ((*cur == '\n') || (*cur == '\r'))
130 cur--;
131 n = 0;
132 while ((cur != base) && (n++ < 80)) {
133 xmlGenericError(xmlGenericErrorContext, " ");
134 base++;
135 }
136 xmlGenericError(xmlGenericErrorContext,"^\n");
137}
138
139/**
140 * 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;
152 xmlParserInputPtr input = NULL;
153 xmlParserInputPtr cur = NULL;
154 va_list args;
155
156 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);
164 }
165
166 xmlGenericError(xmlGenericErrorContext, "error: ");
167 va_start(args, msg);
168 vfprintf(xmlGenericErrorContext, msg, args);
169 va_end(args);
170
171 if (ctxt != NULL) {
172 xmlParserPrintFileContext(input);
173 if (cur != NULL) {
174 xmlParserPrintFileInfo(cur);
175 xmlGenericError(xmlGenericErrorContext, "\n");
176 xmlParserPrintFileContext(cur);
177 }
178 }
179}
180
181/**
182 * xmlParserWarning:
183 * @ctx: an XML parser context
184 * @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.
189 */
190void
191xmlParserWarning(void *ctx, const char *msg, ...)
192{
193 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
194 xmlParserInputPtr input = NULL;
195 xmlParserInputPtr cur = NULL;
196 va_list args;
197
198 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);
206 }
207
208 xmlGenericError(xmlGenericErrorContext, "warning: ");
209 va_start(args, msg);
210 vfprintf(xmlGenericErrorContext, msg, args);
211 va_end(args);
212
213
214 if (ctxt != NULL) {
215 xmlParserPrintFileContext(input);
216 if (cur != NULL) {
217 xmlParserPrintFileInfo(cur);
218 xmlGenericError(xmlGenericErrorContext, "\n");
219 xmlParserPrintFileContext(cur);
220 }
221 }
222}
223
224/************************************************************************
225 * *
226 * Handling of validation errors *
227 * *
228 ************************************************************************/
229
230/**
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;
243 xmlParserInputPtr input = NULL;
244 va_list args;
245
246 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 }
253
254 xmlGenericError(xmlGenericErrorContext, "validity error: ");
255 va_start(args, msg);
256 vfprintf(xmlGenericErrorContext, msg, args);
257 va_end(args);
258
259 if (ctxt != NULL) {
260 xmlParserPrintFileContext(input);
261 }
262}
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;
277 xmlParserInputPtr input = NULL;
278 va_list args;
279
280 if (ctxt != NULL) {
281 input = ctxt->input;
282 if ((input->filename == NULL) && (ctxt->inputNr > 1))
283 input = ctxt->inputTab[ctxt->inputNr - 2];
284
285 xmlParserPrintFileInfo(input);
286 }
287
288 xmlGenericError(xmlGenericErrorContext, "validity warning: ");
289 va_start(args, msg);
290 vfprintf(xmlGenericErrorContext, msg, args);
291 va_end(args);
292
293 if (ctxt != NULL) {
294 xmlParserPrintFileContext(input);
295 }
296}
297
298