Annotation of embedaddon/libxml2/error.c, revision 1.1.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>