File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / error.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:22:22 2013 UTC (11 years ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_8_0p0, v2_8_0, HEAD
2.8.0

    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 (code == XML_ERR_OK)
  456:         return;
  457:     if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
  458:         return;
  459:     if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
  460:         (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
  461: 	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
  462: 	ctxt = (xmlParserCtxtPtr) ctx;
  463: 	if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
  464: 	    (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
  465: 	    (ctxt->sax->serror != NULL)) {
  466: 	    schannel = ctxt->sax->serror;
  467: 	    data = ctxt->userData;
  468: 	}
  469:     }
  470:     /*
  471:      * Check if structured error handler set
  472:      */
  473:     if (schannel == NULL) {
  474: 	schannel = xmlStructuredError;
  475: 	/*
  476: 	 * if user has defined handler, change data ptr to user's choice
  477: 	 */
  478: 	if (schannel != NULL)
  479: 	    data = xmlStructuredErrorContext;
  480:     }
  481:     /*
  482:      * Formatting the message
  483:      */
  484:     if (msg == NULL) {
  485:         str = (char *) xmlStrdup(BAD_CAST "No error message provided");
  486:     } else {
  487:         XML_GET_VAR_STR(msg, str);
  488:     }
  489: 
  490:     /*
  491:      * specific processing if a parser context is provided
  492:      */
  493:     if (ctxt != NULL) {
  494:         if (file == NULL) {
  495:             input = ctxt->input;
  496:             if ((input != NULL) && (input->filename == NULL) &&
  497:                 (ctxt->inputNr > 1)) {
  498:                 input = ctxt->inputTab[ctxt->inputNr - 2];
  499:             }
  500:             if (input != NULL) {
  501:                 file = input->filename;
  502:                 line = input->line;
  503:                 col = input->col;
  504:             }
  505:         }
  506:         to = &ctxt->lastError;
  507:     } else if ((node != NULL) && (file == NULL)) {
  508: 	int i;
  509: 
  510: 	if ((node->doc != NULL) && (node->doc->URL != NULL)) {
  511: 	    baseptr = node;
  512: /*	    file = (const char *) node->doc->URL; */
  513: 	}
  514: 	for (i = 0;
  515: 	     ((i < 10) && (node != NULL) && (node->type != XML_ELEMENT_NODE));
  516: 	     i++)
  517: 	     node = node->parent;
  518:         if ((baseptr == NULL) && (node != NULL) &&
  519: 	    (node->doc != NULL) && (node->doc->URL != NULL))
  520: 	    baseptr = node;
  521: 
  522: 	if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
  523: 	    line = node->line;
  524:     }
  525: 
  526:     /*
  527:      * Save the information about the error
  528:      */
  529:     xmlResetError(to);
  530:     to->domain = domain;
  531:     to->code = code;
  532:     to->message = str;
  533:     to->level = level;
  534:     if (file != NULL)
  535:         to->file = (char *) xmlStrdup((const xmlChar *) file);
  536:     else if (baseptr != NULL) {
  537: #ifdef LIBXML_XINCLUDE_ENABLED
  538: 	/*
  539: 	 * We check if the error is within an XInclude section and,
  540: 	 * if so, attempt to print out the href of the XInclude instead
  541: 	 * of the usual "base" (doc->URL) for the node (bug 152623).
  542: 	 */
  543:         xmlNodePtr prev = baseptr;
  544: 	int inclcount = 0;
  545: 	while (prev != NULL) {
  546: 	    if (prev->prev == NULL)
  547: 	        prev = prev->parent;
  548: 	    else {
  549: 	        prev = prev->prev;
  550: 		if (prev->type == XML_XINCLUDE_START) {
  551: 		    if (--inclcount < 0)
  552: 		        break;
  553: 		} else if (prev->type == XML_XINCLUDE_END)
  554: 		    inclcount++;
  555: 	    }
  556: 	}
  557: 	if (prev != NULL) {
  558: 	    if (prev->type == XML_XINCLUDE_START) {
  559: 		prev->type = XML_ELEMENT_NODE;
  560: 		to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
  561: 		prev->type = XML_XINCLUDE_START;
  562: 	    } else {
  563: 		to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
  564: 	    }
  565: 	} else
  566: #endif
  567: 	    to->file = (char *) xmlStrdup(baseptr->doc->URL);
  568: 	if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
  569: 	    to->file = (char *) xmlStrdup(node->doc->URL);
  570: 	}
  571:     }
  572:     to->line = line;
  573:     if (str1 != NULL)
  574:         to->str1 = (char *) xmlStrdup((const xmlChar *) str1);
  575:     if (str2 != NULL)
  576:         to->str2 = (char *) xmlStrdup((const xmlChar *) str2);
  577:     if (str3 != NULL)
  578:         to->str3 = (char *) xmlStrdup((const xmlChar *) str3);
  579:     to->int1 = int1;
  580:     to->int2 = col;
  581:     to->node = node;
  582:     to->ctxt = ctx;
  583: 
  584:     if (to != &xmlLastError)
  585:         xmlCopyError(to,&xmlLastError);
  586: 
  587:     if (schannel != NULL) {
  588: 	schannel(data, to);
  589: 	return;
  590:     }
  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: 	channel = xmlGenericError;
  604: 	if (!data)
  605: 	    data = xmlGenericErrorContext;
  606:     }
  607:     if (channel == NULL)
  608:         return;
  609: 
  610:     if ((channel == xmlParserError) ||
  611:         (channel == xmlParserWarning) ||
  612: 	(channel == xmlParserValidityError) ||
  613: 	(channel == xmlParserValidityWarning))
  614: 	xmlReportError(to, ctxt, str, NULL, NULL);
  615:     else if ((channel == (xmlGenericErrorFunc) fprintf) ||
  616:              (channel == xmlGenericErrorDefaultFunc))
  617: 	xmlReportError(to, ctxt, str, channel, data);
  618:     else
  619: 	channel(data, "%s", str);
  620: }
  621: 
  622: /**
  623:  * __xmlSimpleError:
  624:  * @domain: where the error comes from
  625:  * @code: the error code
  626:  * @node: the context node
  627:  * @extra:  extra informations
  628:  *
  629:  * Handle an out of memory condition
  630:  */
  631: void
  632: __xmlSimpleError(int domain, int code, xmlNodePtr node,
  633:                  const char *msg, const char *extra)
  634: {
  635: 
  636:     if (code == XML_ERR_NO_MEMORY) {
  637: 	if (extra)
  638: 	    __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
  639: 			    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
  640: 			    NULL, NULL, 0, 0,
  641: 			    "Memory allocation failed : %s\n", extra);
  642: 	else
  643: 	    __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
  644: 			    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
  645: 			    NULL, NULL, 0, 0, "Memory allocation failed\n");
  646:     } else {
  647: 	__xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
  648: 			code, XML_ERR_ERROR, NULL, 0, extra,
  649: 			NULL, NULL, 0, 0, msg, extra);
  650:     }
  651: }
  652: /**
  653:  * xmlParserError:
  654:  * @ctx:  an XML parser context
  655:  * @msg:  the message to display/transmit
  656:  * @...:  extra parameters for the message display
  657:  * 
  658:  * Display and format an error messages, gives file, line, position and
  659:  * extra parameters.
  660:  */
  661: void XMLCDECL
  662: xmlParserError(void *ctx, const char *msg, ...)
  663: {
  664:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  665:     xmlParserInputPtr input = NULL;
  666:     xmlParserInputPtr cur = NULL;
  667:     char * str;
  668: 
  669:     if (ctxt != NULL) {
  670: 	input = ctxt->input;
  671: 	if ((input != NULL) && (input->filename == NULL) &&
  672: 	    (ctxt->inputNr > 1)) {
  673: 	    cur = input;
  674: 	    input = ctxt->inputTab[ctxt->inputNr - 2];
  675: 	}
  676: 	xmlParserPrintFileInfo(input);
  677:     }
  678: 
  679:     xmlGenericError(xmlGenericErrorContext, "error: ");
  680:     XML_GET_VAR_STR(msg, str);
  681:     xmlGenericError(xmlGenericErrorContext, "%s", str);
  682:     if (str != NULL)
  683: 	xmlFree(str);
  684: 
  685:     if (ctxt != NULL) {
  686: 	xmlParserPrintFileContext(input);
  687: 	if (cur != NULL) {
  688: 	    xmlParserPrintFileInfo(cur);
  689: 	    xmlGenericError(xmlGenericErrorContext, "\n");
  690: 	    xmlParserPrintFileContext(cur);
  691: 	}
  692:     }
  693: }
  694: 
  695: /**
  696:  * xmlParserWarning:
  697:  * @ctx:  an XML parser context
  698:  * @msg:  the message to display/transmit
  699:  * @...:  extra parameters for the message display
  700:  * 
  701:  * Display and format a warning messages, gives file, line, position and
  702:  * extra parameters.
  703:  */
  704: void XMLCDECL
  705: xmlParserWarning(void *ctx, const char *msg, ...)
  706: {
  707:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  708:     xmlParserInputPtr input = NULL;
  709:     xmlParserInputPtr cur = NULL;
  710:     char * str;
  711: 
  712:     if (ctxt != NULL) {
  713: 	input = ctxt->input;
  714: 	if ((input != NULL) && (input->filename == NULL) &&
  715: 	    (ctxt->inputNr > 1)) {
  716: 	    cur = input;
  717: 	    input = ctxt->inputTab[ctxt->inputNr - 2];
  718: 	}
  719: 	xmlParserPrintFileInfo(input);
  720:     }
  721:         
  722:     xmlGenericError(xmlGenericErrorContext, "warning: ");
  723:     XML_GET_VAR_STR(msg, str);
  724:     xmlGenericError(xmlGenericErrorContext, "%s", str);
  725:     if (str != NULL)
  726: 	xmlFree(str);
  727: 
  728:     if (ctxt != NULL) {
  729: 	xmlParserPrintFileContext(input);
  730: 	if (cur != NULL) {
  731: 	    xmlParserPrintFileInfo(cur);
  732: 	    xmlGenericError(xmlGenericErrorContext, "\n");
  733: 	    xmlParserPrintFileContext(cur);
  734: 	}
  735:     }
  736: }
  737: 
  738: /************************************************************************
  739:  * 									*
  740:  * 			Handling of validation errors			*
  741:  * 									*
  742:  ************************************************************************/
  743: 
  744: /**
  745:  * xmlParserValidityError:
  746:  * @ctx:  an XML parser context
  747:  * @msg:  the message to display/transmit
  748:  * @...:  extra parameters for the message display
  749:  * 
  750:  * Display and format an validity error messages, gives file,
  751:  * line, position and extra parameters.
  752:  */
  753: void XMLCDECL
  754: xmlParserValidityError(void *ctx, const char *msg, ...)
  755: {
  756:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  757:     xmlParserInputPtr input = NULL;
  758:     char * str;
  759:     int len = xmlStrlen((const xmlChar *) msg);
  760:     static int had_info = 0;
  761: 
  762:     if ((len > 1) && (msg[len - 2] != ':')) {
  763: 	if (ctxt != NULL) {
  764: 	    input = ctxt->input;
  765: 	    if ((input->filename == NULL) && (ctxt->inputNr > 1))
  766: 		input = ctxt->inputTab[ctxt->inputNr - 2];
  767: 		
  768: 	    if (had_info == 0) {
  769: 		xmlParserPrintFileInfo(input);
  770: 	    }
  771: 	}
  772: 	xmlGenericError(xmlGenericErrorContext, "validity error: ");
  773: 	had_info = 0;
  774:     } else {
  775: 	had_info = 1;
  776:     }
  777: 
  778:     XML_GET_VAR_STR(msg, str);
  779:     xmlGenericError(xmlGenericErrorContext, "%s", str);
  780:     if (str != NULL)
  781: 	xmlFree(str);
  782: 
  783:     if ((ctxt != NULL) && (input != NULL)) {
  784: 	xmlParserPrintFileContext(input);
  785:     }
  786: }
  787: 
  788: /**
  789:  * xmlParserValidityWarning:
  790:  * @ctx:  an XML parser context
  791:  * @msg:  the message to display/transmit
  792:  * @...:  extra parameters for the message display
  793:  * 
  794:  * Display and format a validity warning messages, gives file, line,
  795:  * position and extra parameters.
  796:  */
  797: void XMLCDECL
  798: xmlParserValidityWarning(void *ctx, const char *msg, ...)
  799: {
  800:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  801:     xmlParserInputPtr input = NULL;
  802:     char * str;
  803:     int len = xmlStrlen((const xmlChar *) msg);
  804: 
  805:     if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
  806: 	input = ctxt->input;
  807: 	if ((input->filename == NULL) && (ctxt->inputNr > 1))
  808: 	    input = ctxt->inputTab[ctxt->inputNr - 2];
  809: 
  810: 	xmlParserPrintFileInfo(input);
  811:     }
  812:         
  813:     xmlGenericError(xmlGenericErrorContext, "validity warning: ");
  814:     XML_GET_VAR_STR(msg, str);
  815:     xmlGenericError(xmlGenericErrorContext, "%s", str);
  816:     if (str != NULL)
  817: 	xmlFree(str);
  818: 
  819:     if (ctxt != NULL) {
  820: 	xmlParserPrintFileContext(input);
  821:     }
  822: }
  823: 
  824: 
  825: /************************************************************************
  826:  *									*
  827:  *			Extended Error Handling				*
  828:  *									*
  829:  ************************************************************************/
  830: 
  831: /**
  832:  * xmlGetLastError:
  833:  *
  834:  * Get the last global error registered. This is per thread if compiled
  835:  * with thread support.
  836:  *
  837:  * Returns NULL if no error occured or a pointer to the error
  838:  */
  839: xmlErrorPtr
  840: xmlGetLastError(void)
  841: {
  842:     if (xmlLastError.code == XML_ERR_OK)
  843:         return (NULL);
  844:     return (&xmlLastError);
  845: }
  846: 
  847: /**
  848:  * xmlResetError:
  849:  * @err: pointer to the error.
  850:  *
  851:  * Cleanup the error.
  852:  */
  853: void
  854: xmlResetError(xmlErrorPtr err)
  855: {
  856:     if (err == NULL)
  857:         return;
  858:     if (err->code == XML_ERR_OK)
  859:         return;
  860:     if (err->message != NULL)
  861:         xmlFree(err->message);
  862:     if (err->file != NULL)
  863:         xmlFree(err->file);
  864:     if (err->str1 != NULL)
  865:         xmlFree(err->str1);
  866:     if (err->str2 != NULL)
  867:         xmlFree(err->str2);
  868:     if (err->str3 != NULL)
  869:         xmlFree(err->str3);
  870:     memset(err, 0, sizeof(xmlError));
  871:     err->code = XML_ERR_OK;
  872: }
  873: 
  874: /**
  875:  * xmlResetLastError:
  876:  *
  877:  * Cleanup the last global error registered. For parsing error
  878:  * this does not change the well-formedness result.
  879:  */
  880: void
  881: xmlResetLastError(void)
  882: {
  883:     if (xmlLastError.code == XML_ERR_OK)
  884:         return;
  885:     xmlResetError(&xmlLastError);
  886: }
  887: 
  888: /**
  889:  * xmlCtxtGetLastError:
  890:  * @ctx:  an XML parser context
  891:  *
  892:  * Get the last parsing error registered.
  893:  *
  894:  * Returns NULL if no error occured or a pointer to the error
  895:  */
  896: xmlErrorPtr
  897: xmlCtxtGetLastError(void *ctx)
  898: {
  899:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  900: 
  901:     if (ctxt == NULL)
  902:         return (NULL);
  903:     if (ctxt->lastError.code == XML_ERR_OK)
  904:         return (NULL);
  905:     return (&ctxt->lastError);
  906: }
  907: 
  908: /**
  909:  * xmlCtxtResetLastError:
  910:  * @ctx:  an XML parser context
  911:  *
  912:  * Cleanup the last global error registered. For parsing error
  913:  * this does not change the well-formedness result.
  914:  */
  915: void
  916: xmlCtxtResetLastError(void *ctx)
  917: {
  918:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  919: 
  920:     if (ctxt == NULL)
  921:         return;
  922:     ctxt->errNo = XML_ERR_OK;
  923:     if (ctxt->lastError.code == XML_ERR_OK)
  924:         return;
  925:     xmlResetError(&ctxt->lastError);
  926: }
  927: 
  928: /**
  929:  * xmlCopyError:
  930:  * @from:  a source error
  931:  * @to:  a target error
  932:  *
  933:  * Save the original error to the new place.
  934:  *
  935:  * Returns 0 in case of success and -1 in case of error.
  936:  */
  937: int
  938: xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) {
  939:     char *message, *file, *str1, *str2, *str3;
  940: 
  941:     if ((from == NULL) || (to == NULL))
  942:         return(-1);
  943: 
  944:     message = (char *) xmlStrdup((xmlChar *) from->message);
  945:     file = (char *) xmlStrdup ((xmlChar *) from->file);
  946:     str1 = (char *) xmlStrdup ((xmlChar *) from->str1);
  947:     str2 = (char *) xmlStrdup ((xmlChar *) from->str2);
  948:     str3 = (char *) xmlStrdup ((xmlChar *) from->str3);
  949: 
  950:     if (to->message != NULL)
  951:         xmlFree(to->message);
  952:     if (to->file != NULL)
  953:         xmlFree(to->file);
  954:     if (to->str1 != NULL)
  955:         xmlFree(to->str1);
  956:     if (to->str2 != NULL)
  957:         xmlFree(to->str2);
  958:     if (to->str3 != NULL)
  959:         xmlFree(to->str3);
  960:     to->domain = from->domain;
  961:     to->code = from->code;
  962:     to->level = from->level;
  963:     to->line = from->line;
  964:     to->node = from->node;
  965:     to->int1 = from->int1;
  966:     to->int2 = from->int2;
  967:     to->node = from->node;
  968:     to->ctxt = from->ctxt;
  969:     to->message = message;
  970:     to->file = file;
  971:     to->str1 = str1;
  972:     to->str2 = str2;
  973:     to->str3 = str3;
  974: 
  975:     return 0;
  976: }
  977: 
  978: #define bottom_error
  979: #include "elfgcchack.h"

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>