?? error.c
字號:
/* * error.c: module displaying/handling XML parser errors * * See Copyright for the status of this software. * * Daniel Veillard <daniel@veillard.com> */#define IN_LIBXML#include "libxml.h"#include <string.h>#include <stdarg.h>#include <libxml/parser.h>#include <libxml/xmlerror.h>#include <libxml/xmlmemory.h>#include <libxml/globals.h>void XMLCDECL xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED, const char *msg, ...);#define XML_GET_VAR_STR(msg, str) { \ int size, prev_size = -1; \ int chars; \ char *larger; \ va_list ap; \ \ str = (char *) xmlMalloc(150); \ if (str != NULL) { \ \ size = 150; \ \ while (1) { \ va_start(ap, msg); \ chars = vsnprintf(str, size, msg, ap); \ va_end(ap); \ if ((chars > -1) && (chars < size)) { \ if (prev_size == chars) { \ break; \ } else { \ prev_size = chars; \ } \ } \ if (chars > -1) \ size += chars + 1; \ else \ size += 100; \ if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\ break; \ } \ str = larger; \ }} \}/************************************************************************ * * * Handling of out of context errors * * * ************************************************************************//** * xmlGenericErrorDefaultFunc: * @ctx: an error context * @msg: the message to display/transmit * @...: extra parameters for the message display * * Default handler for out of context error messages. */void XMLCDECLxmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) { va_list args; if (xmlGenericErrorContext == NULL) xmlGenericErrorContext = (void *) stderr; va_start(args, msg); vfprintf((FILE *)xmlGenericErrorContext, msg, args); va_end(args);}/** * initGenericErrorDefaultFunc: * @handler: the handler * * Set or reset (if NULL) the default handler for generic errors * to the builtin error function. */voidinitGenericErrorDefaultFunc(xmlGenericErrorFunc * handler){ if (handler == NULL) xmlGenericError = xmlGenericErrorDefaultFunc; else xmlGenericError = (*handler);}/** * xmlSetGenericErrorFunc: * @ctx: the new error handling context * @handler: the new handler function * * Function to reset the handler and the error context for out of * context error messages. * This simply means that @handler will be called for subsequent * error messages while not parsing nor validating. And @ctx will * be passed as first argument to @handler * One can simply force messages to be emitted to another FILE * than * stderr by setting @ctx to this file handle and @handler to NULL. * For multi-threaded applications, this must be set separately for each thread. */voidxmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) { xmlGenericErrorContext = ctx; if (handler != NULL) xmlGenericError = handler; else xmlGenericError = xmlGenericErrorDefaultFunc;}/** * xmlSetStructuredErrorFunc: * @ctx: the new error handling context * @handler: the new handler function * * Function to reset the handler and the error context for out of * context structured error messages. * This simply means that @handler will be called for subsequent * error messages while not parsing nor validating. And @ctx will * be passed as first argument to @handler * For multi-threaded applications, this must be set separately for each thread. */voidxmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) { xmlGenericErrorContext = ctx; xmlStructuredError = handler;}/************************************************************************ * * * Handling of parsing errors * * * ************************************************************************//** * xmlParserPrintFileInfo: * @input: an xmlParserInputPtr input * * Displays the associated file and line informations for the current input */voidxmlParserPrintFileInfo(xmlParserInputPtr input) { if (input != NULL) { if (input->filename) xmlGenericError(xmlGenericErrorContext, "%s:%d: ", input->filename, input->line); else xmlGenericError(xmlGenericErrorContext, "Entity: line %d: ", input->line); }}/** * xmlParserPrintFileContext: * @input: an xmlParserInputPtr input * * Displays current context within the input content for error tracking */static voidxmlParserPrintFileContextInternal(xmlParserInputPtr input , xmlGenericErrorFunc channel, void *data ) { const xmlChar *cur, *base; unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */ xmlChar content[81]; /* space for 80 chars + line terminator */ xmlChar *ctnt; if (input == NULL) return; cur = input->cur; base = input->base; /* skip backwards over any end-of-lines */ while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) { cur--; } n = 0; /* search backwards for beginning-of-line (to max buff size) */ while ((n++ < (sizeof(content)-1)) && (cur > base) && (*(cur) != '\n') && (*(cur) != '\r')) cur--; if ((*(cur) == '\n') || (*(cur) == '\r')) cur++; /* calculate the error position in terms of the current position */ col = input->cur - cur; /* search forward for end-of-line (to max buff size) */ n = 0; ctnt = content; /* copy selected text to our buffer */ while ((*cur != 0) && (*(cur) != '\n') && (*(cur) != '\r') && (n < sizeof(content)-1)) { *ctnt++ = *cur++; n++; } *ctnt = 0; /* print out the selected text */ channel(data ,"%s\n", content); /* create blank line with problem pointer */ n = 0; ctnt = content; /* (leave buffer space for pointer + line terminator) */ while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) { if (*(ctnt) != '\t') *(ctnt) = ' '; ctnt++; } *ctnt++ = '^'; *ctnt = 0; channel(data ,"%s\n", content);}/** * xmlParserPrintFileContext: * @input: an xmlParserInputPtr input * * Displays current context within the input content for error tracking */voidxmlParserPrintFileContext(xmlParserInputPtr input) { xmlParserPrintFileContextInternal(input, xmlGenericError, xmlGenericErrorContext);}/** * xmlReportError: * @err: the error * @ctx: the parser context or NULL * @str: the formatted error message * * Report an erro with its context, replace the 4 old error/warning * routines. */static voidxmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str, xmlGenericErrorFunc channel, void *data){ char *file = NULL; int line = 0; int code = -1; int domain; const xmlChar *name = NULL; xmlNodePtr node; xmlErrorLevel level; xmlParserInputPtr input = NULL; xmlParserInputPtr cur = NULL; if (err == NULL) return; if (channel == NULL) { channel = xmlGenericError; data = xmlGenericErrorContext; } file = err->file; line = err->line; code = err->code; domain = err->domain; level = err->level; node = err->node; if (code == XML_ERR_OK) return; if ((node != NULL) && (node->type == XML_ELEMENT_NODE)) name = node->name; /* * Maintain the compatibility with the legacy error handling */ if (ctxt != NULL) { input = ctxt->input; if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) { cur = input; input = ctxt->inputTab[ctxt->inputNr - 2]; } if (input != NULL) { if (input->filename) channel(data, "%s:%d: ", input->filename, input->line); else if ((line != 0) && (domain == XML_FROM_PARSER)) channel(data, "Entity: line %d: ", input->line); } } else { if (file != NULL) channel(data, "%s:%d: ", file, line); else if ((line != 0) && (domain == XML_FROM_PARSER)) channel(data, "Entity: line %d: ", line); } if (name != NULL) { channel(data, "element %s: ", name); } switch (domain) { case XML_FROM_PARSER: channel(data, "parser "); break; case XML_FROM_NAMESPACE: channel(data, "namespace "); break; case XML_FROM_DTD: case XML_FROM_VALID: channel(data, "validity "); break; case XML_FROM_HTML: channel(data, "HTML parser "); break; case XML_FROM_MEMORY: channel(data, "memory "); break; case XML_FROM_OUTPUT: channel(data, "output "); break; case XML_FROM_IO: channel(data, "I/O "); break; case XML_FROM_XINCLUDE: channel(data, "XInclude "); break; case XML_FROM_XPATH: channel(data, "XPath "); break; case XML_FROM_XPOINTER: channel(data, "parser "); break; case XML_FROM_REGEXP: channel(data, "regexp "); break; case XML_FROM_MODULE: channel(data, "module "); break; case XML_FROM_SCHEMASV: channel(data, "Schemas validity "); break; case XML_FROM_SCHEMASP: channel(data, "Schemas parser "); break; case XML_FROM_RELAXNGP: channel(data, "Relax-NG parser "); break; case XML_FROM_RELAXNGV: channel(data, "Relax-NG validity "); break; case XML_FROM_CATALOG: channel(data, "Catalog "); break; case XML_FROM_C14N: channel(data, "C14N "); break; case XML_FROM_XSLT: channel(data, "XSLT "); break; case XML_FROM_I18N: channel(data, "encoding "); break; default: break; } switch (level) { case XML_ERR_NONE: channel(data, ": "); break; case XML_ERR_WARNING: channel(data, "warning : "); break; case XML_ERR_ERROR: channel(data, "error : "); break; case XML_ERR_FATAL: channel(data, "error : "); break; } if (str != NULL) { int len; len = xmlStrlen((const xmlChar *)str); if ((len > 0) && (str[len - 1] != '\n')) channel(data, "%s\n", str); else channel(data, "%s", str); } else { channel(data, "%s\n", "out of memory error"); } if (ctxt != NULL) { xmlParserPrintFileContextInternal(input, channel, data); if (cur != NULL) { if (cur->filename) channel(data, "%s:%d: \n", cur->filename, cur->line); else if ((line != 0) && (domain == XML_FROM_PARSER)) channel(data, "Entity: line %d: \n", cur->line); xmlParserPrintFileContextInternal(cur, channel, data); } } if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) && (err->int1 < 100) && (err->int1 < xmlStrlen((const xmlChar *)err->str1))) { xmlChar buf[150]; int i; channel(data, "%s\n", err->str1); for (i=0;i < err->int1;i++) buf[i] = ' '; buf[i++] = '^'; buf[i] = 0; channel(data, "%s\n", buf); }}/** * __xmlRaiseError: * @schannel: the structured callback channel * @channel: the old callback channel * @data: the callback data * @ctx: the parser context or NULL * @ctx: the parser context or NULL * @domain: the domain for the error * @code: the code for the error * @level: the xmlErrorLevel for the error * @file: the file source of the error (or NULL) * @line: the line of the error or 0 if N/A * @str1: extra string info * @str2: extra string info * @str3: extra string info * @int1: extra int info * @col: column number of the error or 0 if N/A * @msg: the message to display/transmit * @...: extra parameters for the message display * * Update the appropriate global or contextual error structure, * then forward the error message down the parser or generic * error callback handler */void XMLCDECL__xmlRaiseError(xmlStructuredErrorFunc schannel, xmlGenericErrorFunc channel, void *data, void *ctx, void *nod, int domain, int code, xmlErrorLevel level, const char *file, int line, const char *str1, const char *str2, const char *str3, int int1, int col, const char *msg, ...){ xmlParserCtxtPtr ctxt = NULL; xmlNodePtr node = (xmlNodePtr) nod; char *str = NULL; xmlParserInputPtr input = NULL; xmlErrorPtr to = &xmlLastError; xmlNodePtr baseptr = NULL; if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING)) return; if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) || (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) || (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) { ctxt = (xmlParserCtxtPtr) ctx; if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) schannel = ctxt->sax->serror; } /* * Check if structured error handler set */ if (schannel == NULL) { schannel = xmlStructuredError; /* * if user has defined handler, change data ptr to user's choice */ if (schannel != NULL) data = xmlGenericErrorContext; } if ((domain == XML_FROM_VALID) && ((channel == xmlParserValidityError) || (channel == xmlParserValidityWarning))) { ctxt = (xmlParserCtxtPtr) ctx; if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) schannel = ctxt->sax->serror; } if (code == XML_ERR_OK) return; /* * Formatting the message */ if (msg == NULL) { str = (char *) xmlStrdup(BAD_CAST "No error message provided"); } else { XML_GET_VAR_STR(msg, str); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -