| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * error.c: module displaying/handling XML parser errors | 
|  | 3 | * | 
|  | 4 | * See Copyright for the status of this software. | 
|  | 5 | * | 
| Daniel Veillard | c5d6434 | 2001-06-24 12:13:24 +0000 | [diff] [blame] | 6 | * Daniel Veillard <daniel@veillard.com> | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 7 | */ | 
|  | 8 |  | 
| Daniel Veillard | 34ce8be | 2002-03-18 19:37:11 +0000 | [diff] [blame] | 9 | #define IN_LIBXML | 
| Bjorn Reese | 70a9da5 | 2001-04-21 16:57:29 +0000 | [diff] [blame] | 10 | #include "libxml.h" | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 11 |  | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 12 | #include <string.h> | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 13 | #include <stdarg.h> | 
|  | 14 | #include <libxml/parser.h> | 
|  | 15 | #include <libxml/xmlerror.h> | 
| Daniel Veillard | e356c28 | 2001-03-10 12:32:04 +0000 | [diff] [blame] | 16 | #include <libxml/xmlmemory.h> | 
| Daniel Veillard | 3c01b1d | 2001-10-17 15:58:35 +0000 | [diff] [blame] | 17 | #include <libxml/globals.h> | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 18 |  | 
| Daniel Veillard | 635ef72 | 2001-10-29 11:48:19 +0000 | [diff] [blame] | 19 | void xmlGenericErrorDefaultFunc	(void *ctx ATTRIBUTE_UNUSED, | 
|  | 20 | const char *msg, | 
|  | 21 | ...); | 
|  | 22 |  | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 23 | #define XML_GET_VAR_STR(msg, str) {				\ | 
|  | 24 | int       size;						\ | 
|  | 25 | int       chars;						\ | 
|  | 26 | char      *larger;						\ | 
|  | 27 | va_list   ap;						\ | 
|  | 28 | \ | 
|  | 29 | str = (char *) xmlMalloc(150);				\ | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 30 | if (str != NULL) {						\ | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 31 | \ | 
|  | 32 | size = 150;							\ | 
|  | 33 | \ | 
|  | 34 | while (1) {							\ | 
|  | 35 | va_start(ap, msg);					\ | 
|  | 36 | chars = vsnprintf(str, size, msg, ap);			\ | 
|  | 37 | va_end(ap);						\ | 
|  | 38 | if ((chars > -1) && (chars < size))			\ | 
|  | 39 | break;						\ | 
|  | 40 | if (chars > -1)						\ | 
|  | 41 | size += chars + 1;					\ | 
|  | 42 | else							\ | 
|  | 43 | size += 100;					\ | 
|  | 44 | if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\ | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 45 | break;						\ | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 46 | }							\ | 
|  | 47 | str = larger;						\ | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 48 | }}								\ | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 49 | } | 
| Bjorn Reese | 570ff08 | 2001-06-05 12:45:55 +0000 | [diff] [blame] | 50 |  | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 51 | /************************************************************************ | 
|  | 52 | * 									* | 
|  | 53 | * 			Handling of out of context errors		* | 
|  | 54 | * 									* | 
|  | 55 | ************************************************************************/ | 
|  | 56 |  | 
|  | 57 | /** | 
|  | 58 | * xmlGenericErrorDefaultFunc: | 
|  | 59 | * @ctx:  an error context | 
|  | 60 | * @msg:  the message to display/transmit | 
|  | 61 | * @...:  extra parameters for the message display | 
|  | 62 | * | 
|  | 63 | * Default handler for out of context error messages. | 
|  | 64 | */ | 
| Daniel Veillard | 635ef72 | 2001-10-29 11:48:19 +0000 | [diff] [blame] | 65 | void | 
| Daniel Veillard | c86a4fa | 2001-03-26 16:28:29 +0000 | [diff] [blame] | 66 | xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) { | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 67 | va_list args; | 
|  | 68 |  | 
|  | 69 | if (xmlGenericErrorContext == NULL) | 
|  | 70 | xmlGenericErrorContext = (void *) stderr; | 
|  | 71 |  | 
|  | 72 | va_start(args, msg); | 
|  | 73 | vfprintf((FILE *)xmlGenericErrorContext, msg, args); | 
|  | 74 | va_end(args); | 
|  | 75 | } | 
|  | 76 |  | 
| Daniel Veillard | 9d06d30 | 2002-01-22 18:15:52 +0000 | [diff] [blame] | 77 | /** | 
|  | 78 | * initGenericErrorDefaultFunc: | 
|  | 79 | * @handler:  the handler | 
|  | 80 | * | 
|  | 81 | * Set or reset (if NULL) the default handler for generic errors | 
| Daniel Veillard | 7424eb6 | 2003-01-24 14:14:52 +0000 | [diff] [blame] | 82 | * to the builtin error function. | 
| Daniel Veillard | 9d06d30 | 2002-01-22 18:15:52 +0000 | [diff] [blame] | 83 | */ | 
| Daniel Veillard | d046356 | 2001-10-13 09:15:48 +0000 | [diff] [blame] | 84 | void | 
| Daniel Veillard | db5850a | 2002-01-18 11:49:26 +0000 | [diff] [blame] | 85 | initGenericErrorDefaultFunc(xmlGenericErrorFunc * handler) | 
| Daniel Veillard | d046356 | 2001-10-13 09:15:48 +0000 | [diff] [blame] | 86 | { | 
| Daniel Veillard | db5850a | 2002-01-18 11:49:26 +0000 | [diff] [blame] | 87 | if (handler == NULL) | 
|  | 88 | xmlGenericError = xmlGenericErrorDefaultFunc; | 
|  | 89 | else | 
|  | 90 | (*handler) = xmlGenericErrorDefaultFunc; | 
| Daniel Veillard | d046356 | 2001-10-13 09:15:48 +0000 | [diff] [blame] | 91 | } | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 92 |  | 
|  | 93 | /** | 
|  | 94 | * xmlSetGenericErrorFunc: | 
|  | 95 | * @ctx:  the new error handling context | 
|  | 96 | * @handler:  the new handler function | 
|  | 97 | * | 
|  | 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. | 
|  | 105 | */ | 
|  | 106 | void | 
|  | 107 | xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) { | 
|  | 108 | xmlGenericErrorContext = ctx; | 
|  | 109 | if (handler != NULL) | 
|  | 110 | xmlGenericError = handler; | 
|  | 111 | else | 
|  | 112 | xmlGenericError = xmlGenericErrorDefaultFunc; | 
|  | 113 | } | 
|  | 114 |  | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 115 | /** | 
|  | 116 | * xmlSetStructuredErrorFunc: | 
|  | 117 | * @ctx:  the new error handling context | 
|  | 118 | * @handler:  the new handler function | 
|  | 119 | * | 
|  | 120 | * Function to reset the handler and the error context for out of | 
|  | 121 | * context structured error messages. | 
|  | 122 | * This simply means that @handler will be called for subsequent | 
|  | 123 | * error messages while not parsing nor validating. And @ctx will | 
|  | 124 | * be passed as first argument to @handler | 
|  | 125 | */ | 
|  | 126 | void | 
|  | 127 | xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) { | 
|  | 128 | xmlGenericErrorContext = ctx; | 
|  | 129 | xmlStructuredError = handler; | 
|  | 130 | } | 
|  | 131 |  | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 132 | /************************************************************************ | 
|  | 133 | * 									* | 
|  | 134 | * 			Handling of parsing errors			* | 
|  | 135 | * 									* | 
|  | 136 | ************************************************************************/ | 
|  | 137 |  | 
|  | 138 | /** | 
|  | 139 | * xmlParserPrintFileInfo: | 
|  | 140 | * @input:  an xmlParserInputPtr input | 
|  | 141 | * | 
|  | 142 | * Displays the associated file and line informations for the current input | 
|  | 143 | */ | 
|  | 144 |  | 
|  | 145 | void | 
|  | 146 | xmlParserPrintFileInfo(xmlParserInputPtr input) { | 
|  | 147 | if (input != NULL) { | 
|  | 148 | if (input->filename) | 
|  | 149 | xmlGenericError(xmlGenericErrorContext, | 
|  | 150 | "%s:%d: ", input->filename, | 
|  | 151 | input->line); | 
|  | 152 | else | 
|  | 153 | xmlGenericError(xmlGenericErrorContext, | 
|  | 154 | "Entity: line %d: ", input->line); | 
|  | 155 | } | 
|  | 156 | } | 
|  | 157 |  | 
|  | 158 | /** | 
|  | 159 | * xmlParserPrintFileContext: | 
|  | 160 | * @input:  an xmlParserInputPtr input | 
|  | 161 | * | 
|  | 162 | * Displays current context within the input content for error tracking | 
|  | 163 | */ | 
|  | 164 |  | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 165 | static void | 
|  | 166 | xmlParserPrintFileContextInternal(xmlParserInputPtr input , | 
|  | 167 | xmlGenericErrorFunc channel, void *data ) { | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 168 | const xmlChar *cur, *base; | 
| William M. Brack | c193956 | 2003-08-05 15:52:22 +0000 | [diff] [blame] | 169 | unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */ | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 170 | xmlChar  content[81]; /* space for 80 chars + line terminator */ | 
| Daniel Veillard | 2be3064 | 2001-03-27 00:32:28 +0000 | [diff] [blame] | 171 | xmlChar *ctnt; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 172 |  | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 173 | if (input == NULL) return; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 174 | cur = input->cur; | 
|  | 175 | base = input->base; | 
| Daniel Veillard | 2be3064 | 2001-03-27 00:32:28 +0000 | [diff] [blame] | 176 | /* skip backwards over any end-of-lines */ | 
| William M. Brack | c193956 | 2003-08-05 15:52:22 +0000 | [diff] [blame] | 177 | while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) { | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 178 | cur--; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 179 | } | 
|  | 180 | n = 0; | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 181 | /* search backwards for beginning-of-line (to max buff size) */ | 
| William M. Brack | c193956 | 2003-08-05 15:52:22 +0000 | [diff] [blame] | 182 | while ((n++ < (sizeof(content)-1)) && (cur > base) && | 
|  | 183 | (*(cur) != '\n') && (*(cur) != '\r')) | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 184 | cur--; | 
| William M. Brack | c193956 | 2003-08-05 15:52:22 +0000 | [diff] [blame] | 185 | if ((*(cur) == '\n') || (*(cur) == '\r')) cur++; | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 186 | /* calculate the error position in terms of the current position */ | 
|  | 187 | col = input->cur - cur; | 
|  | 188 | /* search forward for end-of-line (to max buff size) */ | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 189 | n = 0; | 
| Daniel Veillard | 2be3064 | 2001-03-27 00:32:28 +0000 | [diff] [blame] | 190 | ctnt = content; | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 191 | /* copy selected text to our buffer */ | 
| William M. Brack | c193956 | 2003-08-05 15:52:22 +0000 | [diff] [blame] | 192 | while ((*cur != 0) && (*(cur) != '\n') && | 
|  | 193 | (*(cur) != '\r') && (n < sizeof(content)-1)) { | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 194 | *ctnt++ = *cur++; | 
|  | 195 | n++; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 196 | } | 
| Daniel Veillard | 2be3064 | 2001-03-27 00:32:28 +0000 | [diff] [blame] | 197 | *ctnt = 0; | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 198 | /* print out the selected text */ | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 199 | channel(data ,"%s\n", content); | 
| Daniel Veillard | 2be3064 | 2001-03-27 00:32:28 +0000 | [diff] [blame] | 200 | /* create blank line with problem pointer */ | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 201 | n = 0; | 
| Daniel Veillard | 7533cc8 | 2001-04-24 15:52:00 +0000 | [diff] [blame] | 202 | ctnt = content; | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 203 | /* (leave buffer space for pointer + line terminator) */ | 
|  | 204 | while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) { | 
| William M. Brack | c193956 | 2003-08-05 15:52:22 +0000 | [diff] [blame] | 205 | if (*(ctnt) != '\t') | 
|  | 206 | *(ctnt) = ' '; | 
| William M. Brack | 6984830 | 2003-09-22 00:24:51 +0000 | [diff] [blame] | 207 | ctnt++; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 208 | } | 
| William M. Brack | 3dd57f7 | 2003-05-13 02:06:18 +0000 | [diff] [blame] | 209 | *ctnt++ = '^'; | 
|  | 210 | *ctnt = 0; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 211 | channel(data ,"%s\n", content); | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 212 | } | 
|  | 213 |  | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 214 | /** | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 215 | * xmlParserPrintFileContext: | 
|  | 216 | * @input:  an xmlParserInputPtr input | 
|  | 217 | * | 
|  | 218 | * Displays current context within the input content for error tracking | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 219 | */ | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 220 | void | 
|  | 221 | xmlParserPrintFileContext(xmlParserInputPtr input) { | 
|  | 222 | xmlParserPrintFileContextInternal(input, xmlGenericError, | 
|  | 223 | xmlGenericErrorContext); | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 224 | } | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 225 |  | 
|  | 226 | /** | 
|  | 227 | * xmlReportError: | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 228 | * @err: the error | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 229 | * @ctx: the parser context or NULL | 
|  | 230 | * @str: the formatted error message | 
|  | 231 | * | 
|  | 232 | * Report an erro with its context, replace the 4 old error/warning | 
|  | 233 | * routines. | 
|  | 234 | */ | 
|  | 235 | static void | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 236 | xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str, | 
|  | 237 | xmlGenericErrorFunc channel, void *data) | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 238 | { | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 239 | char *file = NULL; | 
|  | 240 | int line = 0; | 
|  | 241 | int code = -1; | 
|  | 242 | int domain; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 243 | const xmlChar *name = NULL; | 
|  | 244 | xmlNodePtr node; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 245 | xmlErrorLevel level; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 246 | xmlParserInputPtr input = NULL; | 
|  | 247 | xmlParserInputPtr cur = NULL; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 248 |  | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 249 | if (err == NULL) | 
|  | 250 | return; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 251 |  | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 252 | if (channel == NULL) { | 
|  | 253 | channel = xmlGenericError; | 
|  | 254 | data = xmlGenericErrorContext; | 
|  | 255 | } | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 256 | file = err->file; | 
|  | 257 | line = err->line; | 
|  | 258 | code = err->code; | 
|  | 259 | domain = err->domain; | 
|  | 260 | level = err->level; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 261 | node = err->node; | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 262 |  | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 263 | if (code == XML_ERR_OK) | 
|  | 264 | return; | 
|  | 265 |  | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 266 | if ((node != NULL) && (node->type == XML_ELEMENT_NODE)) | 
|  | 267 | name = node->name; | 
|  | 268 |  | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 269 | /* | 
|  | 270 | * Maintain the compatibility with the legacy error handling | 
|  | 271 | */ | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 272 | if (ctxt != NULL) { | 
|  | 273 | input = ctxt->input; | 
|  | 274 | if ((input != NULL) && (input->filename == NULL) && | 
|  | 275 | (ctxt->inputNr > 1)) { | 
|  | 276 | cur = input; | 
|  | 277 | input = ctxt->inputTab[ctxt->inputNr - 2]; | 
|  | 278 | } | 
|  | 279 | if (input != NULL) { | 
|  | 280 | if (input->filename) | 
|  | 281 | channel(data, "%s:%d: ", input->filename, input->line); | 
| Daniel Veillard | d96f6d3 | 2003-10-07 21:25:12 +0000 | [diff] [blame] | 282 | else if ((line != 0) && (domain == XML_FROM_PARSER)) | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 283 | channel(data, "Entity: line %d: ", input->line); | 
|  | 284 | } | 
|  | 285 | } else { | 
|  | 286 | if (file != NULL) | 
|  | 287 | channel(data, "%s:%d: ", file, line); | 
| Daniel Veillard | d96f6d3 | 2003-10-07 21:25:12 +0000 | [diff] [blame] | 288 | else if ((line != 0) && (domain == XML_FROM_PARSER)) | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 289 | channel(data, "Entity: line %d: ", line); | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 290 | } | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 291 | if (name != NULL) { | 
|  | 292 | channel(data, "element %s: ", name); | 
|  | 293 | } | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 294 | if (code == XML_ERR_OK) | 
|  | 295 | return; | 
|  | 296 | switch (domain) { | 
|  | 297 | case XML_FROM_PARSER: | 
|  | 298 | channel(data, "parser "); | 
|  | 299 | break; | 
|  | 300 | case XML_FROM_NAMESPACE: | 
|  | 301 | channel(data, "namespace "); | 
|  | 302 | break; | 
|  | 303 | case XML_FROM_DTD: | 
|  | 304 | channel(data, "validity "); | 
|  | 305 | break; | 
|  | 306 | case XML_FROM_HTML: | 
|  | 307 | channel(data, "HTML parser "); | 
|  | 308 | break; | 
|  | 309 | case XML_FROM_MEMORY: | 
|  | 310 | channel(data, "memory "); | 
|  | 311 | break; | 
|  | 312 | case XML_FROM_OUTPUT: | 
|  | 313 | channel(data, "output "); | 
|  | 314 | break; | 
|  | 315 | case XML_FROM_IO: | 
|  | 316 | channel(data, "I/O "); | 
|  | 317 | break; | 
|  | 318 | case XML_FROM_XINCLUDE: | 
|  | 319 | channel(data, "XInclude "); | 
|  | 320 | break; | 
|  | 321 | case XML_FROM_XPATH: | 
|  | 322 | channel(data, "XPath "); | 
|  | 323 | break; | 
|  | 324 | case XML_FROM_XPOINTER: | 
|  | 325 | channel(data, "parser "); | 
|  | 326 | break; | 
|  | 327 | case XML_FROM_REGEXP: | 
|  | 328 | channel(data, "regexp "); | 
|  | 329 | break; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 330 | case XML_FROM_SCHEMASV: | 
| Daniel Veillard | 87db3a8 | 2003-10-10 10:52:58 +0000 | [diff] [blame] | 331 | channel(data, "Schemas validity "); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 332 | break; | 
|  | 333 | case XML_FROM_SCHEMASP: | 
| Daniel Veillard | 87db3a8 | 2003-10-10 10:52:58 +0000 | [diff] [blame] | 334 | channel(data, "Schemas parser "); | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 335 | break; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 336 | case XML_FROM_RELAXNGP: | 
|  | 337 | channel(data, "Relax-NG parser "); | 
|  | 338 | break; | 
|  | 339 | case XML_FROM_RELAXNGV: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 340 | channel(data, "Relax-NG validity "); | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 341 | break; | 
|  | 342 | case XML_FROM_CATALOG: | 
|  | 343 | channel(data, "Catalog "); | 
|  | 344 | break; | 
|  | 345 | case XML_FROM_C14N: | 
|  | 346 | channel(data, "C14N "); | 
|  | 347 | break; | 
|  | 348 | case XML_FROM_XSLT: | 
|  | 349 | channel(data, "XSLT "); | 
|  | 350 | break; | 
|  | 351 | default: | 
|  | 352 | break; | 
|  | 353 | } | 
|  | 354 | if (code == XML_ERR_OK) | 
|  | 355 | return; | 
|  | 356 | switch (level) { | 
|  | 357 | case XML_ERR_NONE: | 
|  | 358 | channel(data, ": "); | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 359 | break; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 360 | case XML_ERR_WARNING: | 
|  | 361 | channel(data, "warning : "); | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 362 | break; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 363 | case XML_ERR_ERROR: | 
|  | 364 | channel(data, "error : "); | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 365 | break; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 366 | case XML_ERR_FATAL: | 
|  | 367 | channel(data, "error : "); | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 368 | break; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 369 | } | 
|  | 370 | if (code == XML_ERR_OK) | 
|  | 371 | return; | 
|  | 372 | if (str != NULL) { | 
| Daniel Veillard | 828ce83 | 2003-10-08 19:19:10 +0000 | [diff] [blame] | 373 | int len; | 
|  | 374 | len = xmlStrlen((const xmlChar *)str); | 
|  | 375 | if ((len > 0) && (str[len - 1] != '\n')) | 
| Daniel Veillard | 828ce83 | 2003-10-08 19:19:10 +0000 | [diff] [blame] | 376 | channel(data, "%s\n", str); | 
| Daniel Veillard | a885622 | 2003-10-08 19:26:03 +0000 | [diff] [blame] | 377 | else | 
|  | 378 | channel(data, "%s", str); | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 379 | } else { | 
| Daniel Veillard | 828ce83 | 2003-10-08 19:19:10 +0000 | [diff] [blame] | 380 | channel(data, "%s\n", "out of memory error"); | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 381 | } | 
|  | 382 | if (code == XML_ERR_OK) | 
|  | 383 | return; | 
|  | 384 |  | 
|  | 385 | if (ctxt != NULL) { | 
|  | 386 | xmlParserPrintFileContextInternal(input, channel, data); | 
|  | 387 | if (cur != NULL) { | 
|  | 388 | if (cur->filename) | 
|  | 389 | channel(data, "%s:%d: \n", cur->filename, cur->line); | 
| Daniel Veillard | d96f6d3 | 2003-10-07 21:25:12 +0000 | [diff] [blame] | 390 | else if ((line != 0) && (domain == XML_FROM_PARSER)) | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 391 | channel(data, "Entity: line %d: \n", cur->line); | 
|  | 392 | xmlParserPrintFileContextInternal(cur, channel, data); | 
|  | 393 | } | 
|  | 394 | } | 
| Daniel Veillard | d96f6d3 | 2003-10-07 21:25:12 +0000 | [diff] [blame] | 395 | if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) && | 
|  | 396 | (err->int1 < 100) && | 
|  | 397 | (err->int1 < xmlStrlen((const xmlChar *)err->str1))) { | 
|  | 398 | xmlChar buf[150]; | 
|  | 399 | int i; | 
|  | 400 |  | 
|  | 401 | channel(data, "%s\n", err->str1); | 
|  | 402 | for (i=0;i < err->int1;i++) | 
|  | 403 | buf[i] = ' '; | 
|  | 404 | buf[i++] = '^'; | 
|  | 405 | buf[i] = 0; | 
|  | 406 | channel(data, "%s\n", buf); | 
|  | 407 | } | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 408 | } | 
|  | 409 |  | 
|  | 410 | /** | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 411 | * __xmlRaiseError: | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 412 | * @channel: the structured callback channel | 
|  | 413 | * @channel: the old callback channel | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 414 | * @data: the callback data | 
|  | 415 | * @ctx: the parser context or NULL | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 416 | * @ctx: the parser context or NULL | 
|  | 417 | * @domain: the domain for the error | 
|  | 418 | * @code: the code for the error | 
|  | 419 | * @level: the xmlErrorLevel for the error | 
|  | 420 | * @file: the file source of the error (or NULL) | 
|  | 421 | * @line: the line of the error or 0 if N/A | 
|  | 422 | * @str1: extra string info | 
|  | 423 | * @str2: extra string info | 
|  | 424 | * @str3: extra string info | 
|  | 425 | * @int1: extra int info | 
|  | 426 | * @int2: extra int info | 
|  | 427 | * @msg:  the message to display/transmit | 
|  | 428 | * @...:  extra parameters for the message display | 
|  | 429 | * | 
|  | 430 | * Update teh appropriate global or contextual error structure, | 
|  | 431 | * then forward the error message down the parser or generic | 
|  | 432 | * error callback handler | 
|  | 433 | */ | 
|  | 434 | void | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 435 | __xmlRaiseError(xmlStructuredErrorFunc schannel, | 
|  | 436 | xmlGenericErrorFunc channel, void *data, void *ctx, | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 437 | void *nod, int domain, int code, xmlErrorLevel level, | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 438 | const char *file, int line, const char *str1, | 
|  | 439 | const char *str2, const char *str3, int int1, int int2, | 
|  | 440 | const char *msg, ...) | 
|  | 441 | { | 
| Daniel Veillard | cd6ff28 | 2003-10-08 22:38:13 +0000 | [diff] [blame] | 442 | xmlParserCtxtPtr ctxt = NULL; | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 443 | xmlNodePtr node = (xmlNodePtr) nod; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 444 | char *str = NULL; | 
|  | 445 | xmlParserInputPtr input = NULL; | 
|  | 446 | xmlErrorPtr to = &xmlLastError; | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 447 | xmlChar *base = NULL; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 448 |  | 
| Daniel Veillard | cd6ff28 | 2003-10-08 22:38:13 +0000 | [diff] [blame] | 449 | if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) || | 
|  | 450 | (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) || | 
|  | 451 | (domain == XML_FROM_IO)) { | 
|  | 452 | ctxt = (xmlParserCtxtPtr) ctx; | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 453 | if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) && | 
|  | 454 | (ctxt->sax->initialized == XML_SAX2_MAGIC)) | 
|  | 455 | schannel = ctxt->sax->serror; | 
| Daniel Veillard | cd6ff28 | 2003-10-08 22:38:13 +0000 | [diff] [blame] | 456 | } | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 457 | if (code == XML_ERR_OK) | 
|  | 458 | return; | 
|  | 459 | /* | 
|  | 460 | * Formatting the message | 
|  | 461 | */ | 
|  | 462 | if (msg == NULL) { | 
|  | 463 | str = (char *) xmlStrdup(BAD_CAST "No error message provided"); | 
|  | 464 | } else { | 
|  | 465 | XML_GET_VAR_STR(msg, str); | 
|  | 466 | } | 
|  | 467 |  | 
|  | 468 | /* | 
|  | 469 | * specific processing if a parser context is provided | 
|  | 470 | */ | 
|  | 471 | if (ctxt != NULL) { | 
|  | 472 | if (file == NULL) { | 
|  | 473 | input = ctxt->input; | 
|  | 474 | if ((input != NULL) && (input->filename == NULL) && | 
|  | 475 | (ctxt->inputNr > 1)) { | 
|  | 476 | input = ctxt->inputTab[ctxt->inputNr - 2]; | 
|  | 477 | } | 
|  | 478 | if (input != NULL) { | 
|  | 479 | file = input->filename; | 
|  | 480 | line = input->line; | 
|  | 481 | } | 
|  | 482 | } | 
|  | 483 | to = &ctxt->lastError; | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 484 | } else if ((node != NULL) && (file == NULL)) { | 
|  | 485 | int i; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 486 |  | 
|  | 487 | if ((node->doc != NULL) && (node->doc->URL != NULL)) | 
|  | 488 | base = xmlStrdup(node->doc->URL); | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 489 | for (i = 0; | 
|  | 490 | ((i < 10) && (node != NULL) && (node->type != XML_ELEMENT_NODE)); | 
|  | 491 | i++) | 
|  | 492 | node = node->parent; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 493 | if ((base == NULL) && (node != NULL) && | 
|  | 494 | (node->doc != NULL) && (node->doc->URL != NULL)) | 
|  | 495 | base = xmlStrdup(node->doc->URL); | 
|  | 496 |  | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 497 | if ((node != NULL) && (node->type == XML_ELEMENT_NODE)) | 
| Daniel Veillard | 3e35f8e | 2003-10-21 00:05:38 +0000 | [diff] [blame] | 498 | line = node->line; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 499 | } | 
|  | 500 |  | 
|  | 501 | /* | 
|  | 502 | * Save the informations about the error | 
|  | 503 | */ | 
|  | 504 | xmlResetError(to); | 
|  | 505 | to->domain = domain; | 
|  | 506 | to->code = code; | 
|  | 507 | to->message = str; | 
|  | 508 | to->level = level; | 
|  | 509 | if (file != NULL) | 
|  | 510 | to->file = (char *) xmlStrdup((const xmlChar *) file); | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 511 | else if (base != NULL) { | 
|  | 512 | to->file = (char *) base; | 
|  | 513 | file = (char *) base; | 
|  | 514 | } | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 515 | to->line = line; | 
|  | 516 | if (str1 != NULL) | 
|  | 517 | to->str1 = (char *) xmlStrdup((const xmlChar *) str1); | 
|  | 518 | if (str2 != NULL) | 
|  | 519 | to->str2 = (char *) xmlStrdup((const xmlChar *) str2); | 
|  | 520 | if (str3 != NULL) | 
|  | 521 | to->str3 = (char *) xmlStrdup((const xmlChar *) str3); | 
|  | 522 | to->int1 = int1; | 
|  | 523 | to->int2 = int2; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 524 | to->node = node; | 
| Daniel Veillard | cd6ff28 | 2003-10-08 22:38:13 +0000 | [diff] [blame] | 525 | to->ctxt = ctx; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 526 |  | 
|  | 527 | /* | 
|  | 528 | * Find the callback channel. | 
|  | 529 | */ | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 530 | if ((ctxt != NULL) && (channel == NULL)) { | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 531 | if (level == XML_ERR_WARNING) | 
|  | 532 | channel = ctxt->sax->warning; | 
|  | 533 | else | 
|  | 534 | channel = ctxt->sax->error; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 535 | data = ctxt->userData; | 
| Daniel Veillard | bb5abab | 2003-10-03 22:21:51 +0000 | [diff] [blame] | 536 | } else if (channel == NULL) { | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 537 | if (xmlStructuredError != NULL) | 
|  | 538 | schannel = xmlStructuredError; | 
|  | 539 | else | 
|  | 540 | channel = xmlGenericError; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 541 | data = xmlGenericErrorContext; | 
|  | 542 | } | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 543 | if (schannel != NULL) { | 
|  | 544 | schannel(data, to); | 
|  | 545 | return; | 
|  | 546 | } | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 547 | if (channel == NULL) | 
|  | 548 | return; | 
|  | 549 |  | 
|  | 550 | if ((channel == xmlParserError) || | 
|  | 551 | (channel == xmlParserWarning) || | 
|  | 552 | (channel == xmlParserValidityError) || | 
|  | 553 | (channel == xmlParserValidityWarning)) | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 554 | xmlReportError(to, ctxt, str, NULL, NULL); | 
|  | 555 | else if ((channel == (xmlGenericErrorFunc) fprintf) || | 
|  | 556 | (channel == xmlGenericErrorDefaultFunc)) | 
|  | 557 | xmlReportError(to, ctxt, str, channel, data); | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 558 | else | 
|  | 559 | channel(data, "%s", str); | 
|  | 560 | } | 
| Daniel Veillard | 561b7f8 | 2002-03-20 21:55:57 +0000 | [diff] [blame] | 561 |  | 
| Daniel Veillard | e356c28 | 2001-03-10 12:32:04 +0000 | [diff] [blame] | 562 | /** | 
| Daniel Veillard | 18ec16e | 2003-10-07 23:16:40 +0000 | [diff] [blame] | 563 | * __xmlSimpleError: | 
|  | 564 | * @domain: where the error comes from | 
|  | 565 | * @code: the error code | 
|  | 566 | * @node: the context node | 
|  | 567 | * @extra:  extra informations | 
|  | 568 | * | 
|  | 569 | * Handle an out of memory condition | 
|  | 570 | */ | 
|  | 571 | void | 
|  | 572 | __xmlSimpleError(int domain, int code, xmlNodePtr node, | 
|  | 573 | const char *msg, const char *extra) | 
|  | 574 | { | 
|  | 575 |  | 
|  | 576 | if (code == XML_ERR_NO_MEMORY) { | 
|  | 577 | if (extra) | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 578 | __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain, | 
| Daniel Veillard | 18ec16e | 2003-10-07 23:16:40 +0000 | [diff] [blame] | 579 | XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra, | 
|  | 580 | NULL, NULL, 0, 0, | 
|  | 581 | "Memory allocation failed : %s\n", extra); | 
|  | 582 | else | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 583 | __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain, | 
| Daniel Veillard | 18ec16e | 2003-10-07 23:16:40 +0000 | [diff] [blame] | 584 | XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL, | 
|  | 585 | NULL, NULL, 0, 0, "Memory allocation failed\n"); | 
|  | 586 | } else { | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 587 | __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain, | 
| Daniel Veillard | 18ec16e | 2003-10-07 23:16:40 +0000 | [diff] [blame] | 588 | code, XML_ERR_ERROR, NULL, 0, extra, | 
|  | 589 | NULL, NULL, 0, 0, msg, extra); | 
|  | 590 | } | 
|  | 591 | } | 
|  | 592 | /** | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 593 | * xmlParserError: | 
|  | 594 | * @ctx:  an XML parser context | 
|  | 595 | * @msg:  the message to display/transmit | 
|  | 596 | * @...:  extra parameters for the message display | 
|  | 597 | * | 
|  | 598 | * Display and format an error messages, gives file, line, position and | 
|  | 599 | * extra parameters. | 
|  | 600 | */ | 
|  | 601 | void | 
|  | 602 | xmlParserError(void *ctx, const char *msg, ...) | 
|  | 603 | { | 
|  | 604 | xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | 
|  | 605 | xmlParserInputPtr input = NULL; | 
|  | 606 | xmlParserInputPtr cur = NULL; | 
| Daniel Veillard | e356c28 | 2001-03-10 12:32:04 +0000 | [diff] [blame] | 607 | char * str; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 608 |  | 
|  | 609 | if (ctxt != NULL) { | 
|  | 610 | input = ctxt->input; | 
|  | 611 | if ((input != NULL) && (input->filename == NULL) && | 
|  | 612 | (ctxt->inputNr > 1)) { | 
|  | 613 | cur = input; | 
|  | 614 | input = ctxt->inputTab[ctxt->inputNr - 2]; | 
|  | 615 | } | 
|  | 616 | xmlParserPrintFileInfo(input); | 
|  | 617 | } | 
|  | 618 |  | 
|  | 619 | xmlGenericError(xmlGenericErrorContext, "error: "); | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 620 | XML_GET_VAR_STR(msg, str); | 
| Daniel Veillard | 635ef72 | 2001-10-29 11:48:19 +0000 | [diff] [blame] | 621 | xmlGenericError(xmlGenericErrorContext, "%s", str); | 
| Daniel Veillard | 9e7160d | 2001-03-18 23:17:47 +0000 | [diff] [blame] | 622 | if (str != NULL) | 
|  | 623 | xmlFree(str); | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 624 |  | 
|  | 625 | if (ctxt != NULL) { | 
|  | 626 | xmlParserPrintFileContext(input); | 
|  | 627 | if (cur != NULL) { | 
|  | 628 | xmlParserPrintFileInfo(cur); | 
|  | 629 | xmlGenericError(xmlGenericErrorContext, "\n"); | 
|  | 630 | xmlParserPrintFileContext(cur); | 
|  | 631 | } | 
|  | 632 | } | 
|  | 633 | } | 
|  | 634 |  | 
|  | 635 | /** | 
|  | 636 | * xmlParserWarning: | 
|  | 637 | * @ctx:  an XML parser context | 
|  | 638 | * @msg:  the message to display/transmit | 
|  | 639 | * @...:  extra parameters for the message display | 
|  | 640 | * | 
|  | 641 | * Display and format a warning messages, gives file, line, position and | 
|  | 642 | * extra parameters. | 
|  | 643 | */ | 
|  | 644 | void | 
|  | 645 | xmlParserWarning(void *ctx, const char *msg, ...) | 
|  | 646 | { | 
|  | 647 | xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | 
|  | 648 | xmlParserInputPtr input = NULL; | 
|  | 649 | xmlParserInputPtr cur = NULL; | 
| Daniel Veillard | e356c28 | 2001-03-10 12:32:04 +0000 | [diff] [blame] | 650 | char * str; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 651 |  | 
|  | 652 | if (ctxt != NULL) { | 
|  | 653 | input = ctxt->input; | 
|  | 654 | if ((input != NULL) && (input->filename == NULL) && | 
|  | 655 | (ctxt->inputNr > 1)) { | 
|  | 656 | cur = input; | 
|  | 657 | input = ctxt->inputTab[ctxt->inputNr - 2]; | 
|  | 658 | } | 
|  | 659 | xmlParserPrintFileInfo(input); | 
|  | 660 | } | 
|  | 661 |  | 
|  | 662 | xmlGenericError(xmlGenericErrorContext, "warning: "); | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 663 | XML_GET_VAR_STR(msg, str); | 
| Daniel Veillard | 635ef72 | 2001-10-29 11:48:19 +0000 | [diff] [blame] | 664 | xmlGenericError(xmlGenericErrorContext, "%s", str); | 
| Daniel Veillard | 9e7160d | 2001-03-18 23:17:47 +0000 | [diff] [blame] | 665 | if (str != NULL) | 
|  | 666 | xmlFree(str); | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 667 |  | 
|  | 668 | if (ctxt != NULL) { | 
|  | 669 | xmlParserPrintFileContext(input); | 
|  | 670 | if (cur != NULL) { | 
|  | 671 | xmlParserPrintFileInfo(cur); | 
|  | 672 | xmlGenericError(xmlGenericErrorContext, "\n"); | 
|  | 673 | xmlParserPrintFileContext(cur); | 
|  | 674 | } | 
|  | 675 | } | 
|  | 676 | } | 
|  | 677 |  | 
|  | 678 | /************************************************************************ | 
|  | 679 | * 									* | 
|  | 680 | * 			Handling of validation errors			* | 
|  | 681 | * 									* | 
|  | 682 | ************************************************************************/ | 
|  | 683 |  | 
|  | 684 | /** | 
|  | 685 | * xmlParserValidityError: | 
|  | 686 | * @ctx:  an XML parser context | 
|  | 687 | * @msg:  the message to display/transmit | 
|  | 688 | * @...:  extra parameters for the message display | 
|  | 689 | * | 
|  | 690 | * Display and format an validity error messages, gives file, | 
|  | 691 | * line, position and extra parameters. | 
|  | 692 | */ | 
|  | 693 | void | 
|  | 694 | xmlParserValidityError(void *ctx, const char *msg, ...) | 
|  | 695 | { | 
|  | 696 | xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | 
|  | 697 | xmlParserInputPtr input = NULL; | 
| Daniel Veillard | 9e7160d | 2001-03-18 23:17:47 +0000 | [diff] [blame] | 698 | char * str; | 
| Daniel Veillard | 7657576 | 2002-09-05 14:21:15 +0000 | [diff] [blame] | 699 | int len = xmlStrlen((const xmlChar *) msg); | 
|  | 700 | static int had_info = 0; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 701 |  | 
| Daniel Veillard | 7657576 | 2002-09-05 14:21:15 +0000 | [diff] [blame] | 702 | if ((len > 1) && (msg[len - 2] != ':')) { | 
|  | 703 | if (ctxt != NULL) { | 
|  | 704 | input = ctxt->input; | 
|  | 705 | if ((input->filename == NULL) && (ctxt->inputNr > 1)) | 
|  | 706 | input = ctxt->inputTab[ctxt->inputNr - 2]; | 
|  | 707 |  | 
|  | 708 | if (had_info == 0) { | 
|  | 709 | xmlParserPrintFileInfo(input); | 
|  | 710 | } | 
|  | 711 | } | 
|  | 712 | xmlGenericError(xmlGenericErrorContext, "validity error: "); | 
| Daniel Veillard | 7657576 | 2002-09-05 14:21:15 +0000 | [diff] [blame] | 713 | had_info = 0; | 
|  | 714 | } else { | 
|  | 715 | had_info = 1; | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 716 | } | 
|  | 717 |  | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 718 | XML_GET_VAR_STR(msg, str); | 
| Daniel Veillard | 635ef72 | 2001-10-29 11:48:19 +0000 | [diff] [blame] | 719 | xmlGenericError(xmlGenericErrorContext, "%s", str); | 
| Daniel Veillard | 9e7160d | 2001-03-18 23:17:47 +0000 | [diff] [blame] | 720 | if (str != NULL) | 
|  | 721 | xmlFree(str); | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 722 |  | 
| Daniel Veillard | 7657576 | 2002-09-05 14:21:15 +0000 | [diff] [blame] | 723 | if ((ctxt != NULL) && (input != NULL)) { | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 724 | xmlParserPrintFileContext(input); | 
|  | 725 | } | 
|  | 726 | } | 
|  | 727 |  | 
|  | 728 | /** | 
|  | 729 | * xmlParserValidityWarning: | 
|  | 730 | * @ctx:  an XML parser context | 
|  | 731 | * @msg:  the message to display/transmit | 
|  | 732 | * @...:  extra parameters for the message display | 
|  | 733 | * | 
|  | 734 | * Display and format a validity warning messages, gives file, line, | 
|  | 735 | * position and extra parameters. | 
|  | 736 | */ | 
|  | 737 | void | 
|  | 738 | xmlParserValidityWarning(void *ctx, const char *msg, ...) | 
|  | 739 | { | 
|  | 740 | xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | 
|  | 741 | xmlParserInputPtr input = NULL; | 
| Daniel Veillard | 9e7160d | 2001-03-18 23:17:47 +0000 | [diff] [blame] | 742 | char * str; | 
| Daniel Veillard | 7657576 | 2002-09-05 14:21:15 +0000 | [diff] [blame] | 743 | int len = xmlStrlen((const xmlChar *) msg); | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 744 |  | 
| Daniel Veillard | 7657576 | 2002-09-05 14:21:15 +0000 | [diff] [blame] | 745 | if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) { | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 746 | input = ctxt->input; | 
|  | 747 | if ((input->filename == NULL) && (ctxt->inputNr > 1)) | 
|  | 748 | input = ctxt->inputTab[ctxt->inputNr - 2]; | 
|  | 749 |  | 
|  | 750 | xmlParserPrintFileInfo(input); | 
|  | 751 | } | 
|  | 752 |  | 
|  | 753 | xmlGenericError(xmlGenericErrorContext, "validity warning: "); | 
| Daniel Veillard | 1c43dbf | 2001-06-05 17:12:52 +0000 | [diff] [blame] | 754 | XML_GET_VAR_STR(msg, str); | 
| Daniel Veillard | 635ef72 | 2001-10-29 11:48:19 +0000 | [diff] [blame] | 755 | xmlGenericError(xmlGenericErrorContext, "%s", str); | 
| Daniel Veillard | 9e7160d | 2001-03-18 23:17:47 +0000 | [diff] [blame] | 756 | if (str != NULL) | 
|  | 757 | xmlFree(str); | 
| Owen Taylor | 3473f88 | 2001-02-23 17:55:21 +0000 | [diff] [blame] | 758 |  | 
|  | 759 | if (ctxt != NULL) { | 
|  | 760 | xmlParserPrintFileContext(input); | 
|  | 761 | } | 
|  | 762 | } | 
|  | 763 |  | 
|  | 764 |  | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 765 | /************************************************************************ | 
|  | 766 | *									* | 
|  | 767 | *			Extended Error Handling				* | 
|  | 768 | *									* | 
|  | 769 | ************************************************************************/ | 
|  | 770 |  | 
|  | 771 | /** | 
|  | 772 | * xmlGetLastError: | 
|  | 773 | * | 
|  | 774 | * Get the last global error registered. This is per thread if compiled | 
|  | 775 | * with thread support. | 
|  | 776 | * | 
|  | 777 | * Returns NULL if no error occured or a pointer to the error | 
|  | 778 | */ | 
|  | 779 | xmlErrorPtr | 
|  | 780 | xmlGetLastError(void) | 
|  | 781 | { | 
|  | 782 | if (xmlLastError.code == XML_ERR_OK) | 
|  | 783 | return (NULL); | 
|  | 784 | return (&xmlLastError); | 
|  | 785 | } | 
|  | 786 |  | 
|  | 787 | /** | 
|  | 788 | * xmlResetError: | 
|  | 789 | * @err: pointer to the error. | 
|  | 790 | * | 
|  | 791 | * Cleanup the error. | 
|  | 792 | */ | 
|  | 793 | void | 
|  | 794 | xmlResetError(xmlErrorPtr err) | 
|  | 795 | { | 
|  | 796 | if (err == NULL) | 
|  | 797 | return; | 
|  | 798 | if (err->code == XML_ERR_OK) | 
|  | 799 | return; | 
|  | 800 | if (err->message != NULL) | 
|  | 801 | xmlFree(err->message); | 
|  | 802 | if (err->file != NULL) | 
|  | 803 | xmlFree(err->file); | 
|  | 804 | if (err->str1 != NULL) | 
|  | 805 | xmlFree(err->str1); | 
|  | 806 | if (err->str2 != NULL) | 
|  | 807 | xmlFree(err->str2); | 
|  | 808 | if (err->str3 != NULL) | 
|  | 809 | xmlFree(err->str3); | 
|  | 810 | memset(err, 0, sizeof(xmlError)); | 
|  | 811 | err->code = XML_ERR_OK; | 
|  | 812 | } | 
|  | 813 |  | 
|  | 814 | /** | 
|  | 815 | * xmlResetLastError: | 
|  | 816 | * | 
|  | 817 | * Cleanup the last global error registered. For parsing error | 
|  | 818 | * this does not change the well-formedness result. | 
|  | 819 | */ | 
|  | 820 | void | 
|  | 821 | xmlResetLastError(void) | 
|  | 822 | { | 
|  | 823 | if (xmlLastError.code == XML_ERR_OK) | 
|  | 824 | return; | 
|  | 825 | xmlResetError(&xmlLastError); | 
|  | 826 | } | 
|  | 827 |  | 
|  | 828 | /** | 
|  | 829 | * xmlCtxtGetLastError: | 
|  | 830 | * @ctx:  an XML parser context | 
|  | 831 | * | 
|  | 832 | * Get the last parsing error registered. | 
|  | 833 | * | 
|  | 834 | * Returns NULL if no error occured or a pointer to the error | 
|  | 835 | */ | 
|  | 836 | xmlErrorPtr | 
|  | 837 | xmlCtxtGetLastError(void *ctx) | 
|  | 838 | { | 
|  | 839 | xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | 
|  | 840 |  | 
|  | 841 | if (ctxt == NULL) | 
|  | 842 | return (NULL); | 
|  | 843 | if (ctxt->lastError.code == XML_ERR_OK) | 
|  | 844 | return (NULL); | 
|  | 845 | return (&ctxt->lastError); | 
|  | 846 | } | 
|  | 847 |  | 
|  | 848 | /** | 
|  | 849 | * xmlCtxtResetLastError: | 
|  | 850 | * @ctx:  an XML parser context | 
|  | 851 | * | 
|  | 852 | * Cleanup the last global error registered. For parsing error | 
|  | 853 | * this does not change the well-formedness result. | 
|  | 854 | */ | 
|  | 855 | void | 
|  | 856 | xmlCtxtResetLastError(void *ctx) | 
|  | 857 | { | 
|  | 858 | xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | 
|  | 859 |  | 
|  | 860 | if (ctxt == NULL) | 
|  | 861 | return; | 
|  | 862 | if (ctxt->lastError.code == XML_ERR_OK) | 
|  | 863 | return; | 
|  | 864 | xmlResetError(&ctxt->lastError); | 
|  | 865 | } | 
|  | 866 |  | 
|  | 867 | /** | 
|  | 868 | * xmlCopyError: | 
|  | 869 | * @from:  a source error | 
|  | 870 | * @to:  a target error | 
|  | 871 | * | 
|  | 872 | * Save the original error to the new place. | 
|  | 873 | * | 
|  | 874 | * Returns 0 in case of success and -1 in case of error. | 
|  | 875 | */ | 
|  | 876 | int | 
|  | 877 | xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) { | 
|  | 878 | if ((from == NULL) || (to == NULL)) | 
|  | 879 | return(-1); | 
|  | 880 | if (to->message != NULL) | 
|  | 881 | xmlFree(to->message); | 
|  | 882 | if (to->file != NULL) | 
|  | 883 | xmlFree(to->file); | 
|  | 884 | if (to->str1 != NULL) | 
|  | 885 | xmlFree(to->str1); | 
|  | 886 | if (to->str2 != NULL) | 
|  | 887 | xmlFree(to->str2); | 
|  | 888 | if (to->str3 != NULL) | 
|  | 889 | xmlFree(to->str3); | 
|  | 890 | to->domain = from->domain; | 
|  | 891 | to->code = from->code; | 
|  | 892 | to->level = from->level; | 
|  | 893 | to->line = from->line; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 894 | to->node = from->node; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 895 | to->int1 = from->int1; | 
|  | 896 | to->int2 = from->int2; | 
| Daniel Veillard | 4c00414 | 2003-10-07 11:33:24 +0000 | [diff] [blame] | 897 | to->node = from->node; | 
|  | 898 | to->ctxt = from->ctxt; | 
| Daniel Veillard | 2b8c4a1 | 2003-10-02 22:28:19 +0000 | [diff] [blame] | 899 | if (from->message != NULL) | 
|  | 900 | to->message = (char *) xmlStrdup((xmlChar *) from->message); | 
|  | 901 | else | 
|  | 902 | to->message = NULL; | 
|  | 903 | if (from->file != NULL) | 
|  | 904 | to->file = (char *) xmlStrdup((xmlChar *) from->file); | 
|  | 905 | else | 
|  | 906 | to->file = NULL; | 
|  | 907 | if (from->str1 != NULL) | 
|  | 908 | to->str1 = (char *) xmlStrdup((xmlChar *) from->str1); | 
|  | 909 | else | 
|  | 910 | to->str1 = NULL; | 
|  | 911 | if (from->str2 != NULL) | 
|  | 912 | to->str2 = (char *) xmlStrdup((xmlChar *) from->str2); | 
|  | 913 | else | 
|  | 914 | to->str2 = NULL; | 
|  | 915 | if (from->str3 != NULL) | 
|  | 916 | to->str3 = (char *) xmlStrdup((xmlChar *) from->str3); | 
|  | 917 | else | 
|  | 918 | to->str3 = NULL; | 
|  | 919 | return(0); | 
|  | 920 | } | 
|  | 921 |  |