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