Annotation of embedaddon/libxml2/error.c, revision 1.1.1.3

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);                                      \
1.1.1.3 ! misho      36:        chars = vsnprintf(str, size, msg, ap);                  \
1.1       misho      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: /************************************************************************
1.1.1.3 ! misho      57:  *                                                                     *
        !            58:  *                     Handling of out of context errors               *
        !            59:  *                                                                     *
1.1       misho      60:  ************************************************************************/
                     61: 
                     62: /**
                     63:  * xmlGenericErrorDefaultFunc:
                     64:  * @ctx:  an error context
                     65:  * @msg:  the message to display/transmit
                     66:  * @...:  extra parameters for the message display
1.1.1.3 ! misho      67:  *
1.1       misho      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
1.1.1.3 ! misho      85:  *
1.1       misho      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: /************************************************************************
1.1.1.3 ! misho     140:  *                                                                     *
        !           141:  *                     Handling of parsing errors                      *
        !           142:  *                                                                     *
1.1       misho     143:  ************************************************************************/
                    144: 
                    145: /**
                    146:  * xmlParserPrintFileInfo:
                    147:  * @input:  an xmlParserInputPtr input
1.1.1.3 ! misho     148:  *
1.1       misho     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
1.1.1.3 ! misho     168:  *
1.1       misho     169:  * Displays current context within the input content for error tracking
                    170:  */
                    171: 
                    172: static void
1.1.1.3 ! misho     173: xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
1.1       misho     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) */
1.1.1.3 ! misho     189:     while ((n++ < (sizeof(content)-1)) && (cur > base) &&
        !           190:           (*(cur) != '\n') && (*(cur) != '\r'))
1.1       misho     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 */
1.1.1.3 ! misho     199:     while ((*cur != 0) && (*(cur) != '\n') &&
        !           200:           (*(cur) != '\r') && (n < sizeof(content)-1)) {
1.1       misho     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
1.1.1.3 ! misho     224:  *
1.1       misho     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);
1.1.1.3 ! misho     295:         else if ((line != 0) &&
        !           296:                 ((domain == XML_FROM_PARSER) || (domain == XML_FROM_SCHEMASV)||
        !           297:                  (domain == XML_FROM_SCHEMASP)||(domain == XML_FROM_DTD) ||
        !           298:                  (domain == XML_FROM_RELAXNGP)||(domain == XML_FROM_RELAXNGV)))
1.1       misho     299:             channel(data, "Entity: line %d: ", line);
                    300:     }
                    301:     if (name != NULL) {
                    302:         channel(data, "element %s: ", name);
                    303:     }
                    304:     switch (domain) {
                    305:         case XML_FROM_PARSER:
                    306:             channel(data, "parser ");
                    307:             break;
                    308:         case XML_FROM_NAMESPACE:
                    309:             channel(data, "namespace ");
                    310:             break;
                    311:         case XML_FROM_DTD:
                    312:         case XML_FROM_VALID:
                    313:             channel(data, "validity ");
                    314:             break;
                    315:         case XML_FROM_HTML:
                    316:             channel(data, "HTML parser ");
                    317:             break;
                    318:         case XML_FROM_MEMORY:
                    319:             channel(data, "memory ");
                    320:             break;
                    321:         case XML_FROM_OUTPUT:
                    322:             channel(data, "output ");
                    323:             break;
                    324:         case XML_FROM_IO:
                    325:             channel(data, "I/O ");
                    326:             break;
                    327:         case XML_FROM_XINCLUDE:
                    328:             channel(data, "XInclude ");
                    329:             break;
                    330:         case XML_FROM_XPATH:
                    331:             channel(data, "XPath ");
                    332:             break;
                    333:         case XML_FROM_XPOINTER:
                    334:             channel(data, "parser ");
                    335:             break;
                    336:         case XML_FROM_REGEXP:
                    337:             channel(data, "regexp ");
                    338:             break;
                    339:         case XML_FROM_MODULE:
                    340:             channel(data, "module ");
                    341:             break;
                    342:         case XML_FROM_SCHEMASV:
                    343:             channel(data, "Schemas validity ");
                    344:             break;
                    345:         case XML_FROM_SCHEMASP:
                    346:             channel(data, "Schemas parser ");
                    347:             break;
                    348:         case XML_FROM_RELAXNGP:
                    349:             channel(data, "Relax-NG parser ");
                    350:             break;
                    351:         case XML_FROM_RELAXNGV:
                    352:             channel(data, "Relax-NG validity ");
                    353:             break;
                    354:         case XML_FROM_CATALOG:
                    355:             channel(data, "Catalog ");
                    356:             break;
                    357:         case XML_FROM_C14N:
                    358:             channel(data, "C14N ");
                    359:             break;
                    360:         case XML_FROM_XSLT:
                    361:             channel(data, "XSLT ");
                    362:             break;
                    363:         case XML_FROM_I18N:
                    364:             channel(data, "encoding ");
                    365:             break;
1.1.1.3 ! misho     366:         case XML_FROM_SCHEMATRONV:
        !           367:             channel(data, "schematron ");
        !           368:             break;
        !           369:         case XML_FROM_BUFFER:
        !           370:             channel(data, "internal buffer ");
        !           371:             break;
        !           372:         case XML_FROM_URI:
        !           373:             channel(data, "URI ");
        !           374:             break;
1.1       misho     375:         default:
                    376:             break;
                    377:     }
                    378:     switch (level) {
                    379:         case XML_ERR_NONE:
                    380:             channel(data, ": ");
                    381:             break;
                    382:         case XML_ERR_WARNING:
                    383:             channel(data, "warning : ");
                    384:             break;
                    385:         case XML_ERR_ERROR:
                    386:             channel(data, "error : ");
                    387:             break;
                    388:         case XML_ERR_FATAL:
                    389:             channel(data, "error : ");
                    390:             break;
                    391:     }
                    392:     if (str != NULL) {
                    393:         int len;
                    394:        len = xmlStrlen((const xmlChar *)str);
                    395:        if ((len > 0) && (str[len - 1] != '\n'))
                    396:            channel(data, "%s\n", str);
                    397:        else
                    398:            channel(data, "%s", str);
                    399:     } else {
                    400:         channel(data, "%s\n", "out of memory error");
                    401:     }
                    402: 
                    403:     if (ctxt != NULL) {
                    404:         xmlParserPrintFileContextInternal(input, channel, data);
                    405:         if (cur != NULL) {
                    406:             if (cur->filename)
                    407:                 channel(data, "%s:%d: \n", cur->filename, cur->line);
                    408:             else if ((line != 0) && (domain == XML_FROM_PARSER))
                    409:                 channel(data, "Entity: line %d: \n", cur->line);
                    410:             xmlParserPrintFileContextInternal(cur, channel, data);
                    411:         }
                    412:     }
                    413:     if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
                    414:         (err->int1 < 100) &&
                    415:        (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
                    416:        xmlChar buf[150];
                    417:        int i;
                    418: 
                    419:        channel(data, "%s\n", err->str1);
                    420:        for (i=0;i < err->int1;i++)
                    421:             buf[i] = ' ';
                    422:        buf[i++] = '^';
                    423:        buf[i] = 0;
                    424:        channel(data, "%s\n", buf);
                    425:     }
                    426: }
                    427: 
                    428: /**
                    429:  * __xmlRaiseError:
                    430:  * @schannel: the structured callback channel
                    431:  * @channel: the old callback channel
                    432:  * @data: the callback data
                    433:  * @ctx: the parser context or NULL
                    434:  * @ctx: the parser context or NULL
                    435:  * @domain: the domain for the error
                    436:  * @code: the code for the error
                    437:  * @level: the xmlErrorLevel for the error
                    438:  * @file: the file source of the error (or NULL)
                    439:  * @line: the line of the error or 0 if N/A
                    440:  * @str1: extra string info
                    441:  * @str2: extra string info
                    442:  * @str3: extra string info
                    443:  * @int1: extra int info
1.1.1.3 ! misho     444:  * @col: column number of the error or 0 if N/A
1.1       misho     445:  * @msg:  the message to display/transmit
                    446:  * @...:  extra parameters for the message display
                    447:  *
                    448:  * Update the appropriate global or contextual error structure,
                    449:  * then forward the error message down the parser or generic
                    450:  * error callback handler
                    451:  */
                    452: void XMLCDECL
                    453: __xmlRaiseError(xmlStructuredErrorFunc schannel,
                    454:               xmlGenericErrorFunc channel, void *data, void *ctx,
                    455:               void *nod, int domain, int code, xmlErrorLevel level,
                    456:               const char *file, int line, const char *str1,
                    457:               const char *str2, const char *str3, int int1, int col,
                    458:              const char *msg, ...)
                    459: {
                    460:     xmlParserCtxtPtr ctxt = NULL;
                    461:     xmlNodePtr node = (xmlNodePtr) nod;
                    462:     char *str = NULL;
                    463:     xmlParserInputPtr input = NULL;
                    464:     xmlErrorPtr to = &xmlLastError;
                    465:     xmlNodePtr baseptr = NULL;
                    466: 
1.1.1.2   misho     467:     if (code == XML_ERR_OK)
                    468:         return;
1.1       misho     469:     if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
                    470:         return;
                    471:     if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
                    472:         (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
                    473:        (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
                    474:        ctxt = (xmlParserCtxtPtr) ctx;
                    475:        if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
1.1.1.2   misho     476:            (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
                    477:            (ctxt->sax->serror != NULL)) {
1.1       misho     478:            schannel = ctxt->sax->serror;
1.1.1.2   misho     479:            data = ctxt->userData;
                    480:        }
1.1       misho     481:     }
                    482:     /*
                    483:      * Check if structured error handler set
                    484:      */
                    485:     if (schannel == NULL) {
                    486:        schannel = xmlStructuredError;
                    487:        /*
                    488:         * if user has defined handler, change data ptr to user's choice
                    489:         */
                    490:        if (schannel != NULL)
                    491:            data = xmlStructuredErrorContext;
                    492:     }
                    493:     /*
                    494:      * Formatting the message
                    495:      */
                    496:     if (msg == NULL) {
                    497:         str = (char *) xmlStrdup(BAD_CAST "No error message provided");
                    498:     } else {
                    499:         XML_GET_VAR_STR(msg, str);
                    500:     }
                    501: 
                    502:     /*
                    503:      * specific processing if a parser context is provided
                    504:      */
                    505:     if (ctxt != NULL) {
                    506:         if (file == NULL) {
                    507:             input = ctxt->input;
                    508:             if ((input != NULL) && (input->filename == NULL) &&
                    509:                 (ctxt->inputNr > 1)) {
                    510:                 input = ctxt->inputTab[ctxt->inputNr - 2];
                    511:             }
                    512:             if (input != NULL) {
                    513:                 file = input->filename;
                    514:                 line = input->line;
                    515:                 col = input->col;
                    516:             }
                    517:         }
                    518:         to = &ctxt->lastError;
                    519:     } else if ((node != NULL) && (file == NULL)) {
                    520:        int i;
                    521: 
                    522:        if ((node->doc != NULL) && (node->doc->URL != NULL)) {
                    523:            baseptr = node;
                    524: /*         file = (const char *) node->doc->URL; */
                    525:        }
                    526:        for (i = 0;
                    527:             ((i < 10) && (node != NULL) && (node->type != XML_ELEMENT_NODE));
                    528:             i++)
                    529:             node = node->parent;
                    530:         if ((baseptr == NULL) && (node != NULL) &&
                    531:            (node->doc != NULL) && (node->doc->URL != NULL))
                    532:            baseptr = node;
                    533: 
                    534:        if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
                    535:            line = node->line;
1.1.1.3 ! misho     536:        if ((line == 0) || (line == 65535))
        !           537:            line = xmlGetLineNo(node);
1.1       misho     538:     }
                    539: 
                    540:     /*
                    541:      * Save the information about the error
                    542:      */
                    543:     xmlResetError(to);
                    544:     to->domain = domain;
                    545:     to->code = code;
                    546:     to->message = str;
                    547:     to->level = level;
                    548:     if (file != NULL)
                    549:         to->file = (char *) xmlStrdup((const xmlChar *) file);
                    550:     else if (baseptr != NULL) {
                    551: #ifdef LIBXML_XINCLUDE_ENABLED
                    552:        /*
                    553:         * We check if the error is within an XInclude section and,
                    554:         * if so, attempt to print out the href of the XInclude instead
                    555:         * of the usual "base" (doc->URL) for the node (bug 152623).
                    556:         */
                    557:         xmlNodePtr prev = baseptr;
                    558:        int inclcount = 0;
                    559:        while (prev != NULL) {
                    560:            if (prev->prev == NULL)
                    561:                prev = prev->parent;
                    562:            else {
                    563:                prev = prev->prev;
                    564:                if (prev->type == XML_XINCLUDE_START) {
                    565:                    if (--inclcount < 0)
                    566:                        break;
                    567:                } else if (prev->type == XML_XINCLUDE_END)
                    568:                    inclcount++;
                    569:            }
                    570:        }
                    571:        if (prev != NULL) {
                    572:            if (prev->type == XML_XINCLUDE_START) {
                    573:                prev->type = XML_ELEMENT_NODE;
                    574:                to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
                    575:                prev->type = XML_XINCLUDE_START;
                    576:            } else {
                    577:                to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
                    578:            }
                    579:        } else
                    580: #endif
                    581:            to->file = (char *) xmlStrdup(baseptr->doc->URL);
                    582:        if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
                    583:            to->file = (char *) xmlStrdup(node->doc->URL);
                    584:        }
                    585:     }
                    586:     to->line = line;
                    587:     if (str1 != NULL)
                    588:         to->str1 = (char *) xmlStrdup((const xmlChar *) str1);
                    589:     if (str2 != NULL)
                    590:         to->str2 = (char *) xmlStrdup((const xmlChar *) str2);
                    591:     if (str3 != NULL)
                    592:         to->str3 = (char *) xmlStrdup((const xmlChar *) str3);
                    593:     to->int1 = int1;
                    594:     to->int2 = col;
                    595:     to->node = node;
                    596:     to->ctxt = ctx;
                    597: 
                    598:     if (to != &xmlLastError)
                    599:         xmlCopyError(to,&xmlLastError);
                    600: 
1.1.1.2   misho     601:     if (schannel != NULL) {
                    602:        schannel(data, to);
                    603:        return;
                    604:     }
                    605: 
1.1       misho     606:     /*
                    607:      * Find the callback channel if channel param is NULL
                    608:      */
                    609:     if ((ctxt != NULL) && (channel == NULL) &&
                    610:         (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
                    611:         if (level == XML_ERR_WARNING)
                    612:            channel = ctxt->sax->warning;
                    613:         else
                    614:            channel = ctxt->sax->error;
                    615:        data = ctxt->userData;
                    616:     } else if (channel == NULL) {
1.1.1.2   misho     617:        channel = xmlGenericError;
1.1.1.3 ! misho     618:        if (ctxt != NULL) {
        !           619:            data = ctxt;
        !           620:        } else {
1.1.1.2   misho     621:            data = xmlGenericErrorContext;
1.1.1.3 ! misho     622:        }
1.1       misho     623:     }
                    624:     if (channel == NULL)
                    625:         return;
                    626: 
                    627:     if ((channel == xmlParserError) ||
                    628:         (channel == xmlParserWarning) ||
                    629:        (channel == xmlParserValidityError) ||
                    630:        (channel == xmlParserValidityWarning))
                    631:        xmlReportError(to, ctxt, str, NULL, NULL);
                    632:     else if ((channel == (xmlGenericErrorFunc) fprintf) ||
                    633:              (channel == xmlGenericErrorDefaultFunc))
                    634:        xmlReportError(to, ctxt, str, channel, data);
                    635:     else
                    636:        channel(data, "%s", str);
                    637: }
                    638: 
                    639: /**
                    640:  * __xmlSimpleError:
                    641:  * @domain: where the error comes from
                    642:  * @code: the error code
                    643:  * @node: the context node
                    644:  * @extra:  extra informations
                    645:  *
                    646:  * Handle an out of memory condition
                    647:  */
                    648: void
                    649: __xmlSimpleError(int domain, int code, xmlNodePtr node,
                    650:                  const char *msg, const char *extra)
                    651: {
                    652: 
                    653:     if (code == XML_ERR_NO_MEMORY) {
                    654:        if (extra)
                    655:            __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
                    656:                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                    657:                            NULL, NULL, 0, 0,
                    658:                            "Memory allocation failed : %s\n", extra);
                    659:        else
                    660:            __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
                    661:                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
                    662:                            NULL, NULL, 0, 0, "Memory allocation failed\n");
                    663:     } else {
                    664:        __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
                    665:                        code, XML_ERR_ERROR, NULL, 0, extra,
                    666:                        NULL, NULL, 0, 0, msg, extra);
                    667:     }
                    668: }
                    669: /**
                    670:  * xmlParserError:
                    671:  * @ctx:  an XML parser context
                    672:  * @msg:  the message to display/transmit
                    673:  * @...:  extra parameters for the message display
1.1.1.3 ! misho     674:  *
1.1       misho     675:  * Display and format an error messages, gives file, line, position and
                    676:  * extra parameters.
                    677:  */
                    678: void XMLCDECL
                    679: xmlParserError(void *ctx, const char *msg, ...)
                    680: {
                    681:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    682:     xmlParserInputPtr input = NULL;
                    683:     xmlParserInputPtr cur = NULL;
                    684:     char * str;
                    685: 
                    686:     if (ctxt != NULL) {
                    687:        input = ctxt->input;
                    688:        if ((input != NULL) && (input->filename == NULL) &&
                    689:            (ctxt->inputNr > 1)) {
                    690:            cur = input;
                    691:            input = ctxt->inputTab[ctxt->inputNr - 2];
                    692:        }
                    693:        xmlParserPrintFileInfo(input);
                    694:     }
                    695: 
                    696:     xmlGenericError(xmlGenericErrorContext, "error: ");
                    697:     XML_GET_VAR_STR(msg, str);
                    698:     xmlGenericError(xmlGenericErrorContext, "%s", str);
                    699:     if (str != NULL)
                    700:        xmlFree(str);
                    701: 
                    702:     if (ctxt != NULL) {
                    703:        xmlParserPrintFileContext(input);
                    704:        if (cur != NULL) {
                    705:            xmlParserPrintFileInfo(cur);
                    706:            xmlGenericError(xmlGenericErrorContext, "\n");
                    707:            xmlParserPrintFileContext(cur);
                    708:        }
                    709:     }
                    710: }
                    711: 
                    712: /**
                    713:  * xmlParserWarning:
                    714:  * @ctx:  an XML parser context
                    715:  * @msg:  the message to display/transmit
                    716:  * @...:  extra parameters for the message display
1.1.1.3 ! misho     717:  *
1.1       misho     718:  * Display and format a warning messages, gives file, line, position and
                    719:  * extra parameters.
                    720:  */
                    721: void XMLCDECL
                    722: xmlParserWarning(void *ctx, const char *msg, ...)
                    723: {
                    724:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    725:     xmlParserInputPtr input = NULL;
                    726:     xmlParserInputPtr cur = NULL;
                    727:     char * str;
                    728: 
                    729:     if (ctxt != NULL) {
                    730:        input = ctxt->input;
                    731:        if ((input != NULL) && (input->filename == NULL) &&
                    732:            (ctxt->inputNr > 1)) {
                    733:            cur = input;
                    734:            input = ctxt->inputTab[ctxt->inputNr - 2];
                    735:        }
                    736:        xmlParserPrintFileInfo(input);
                    737:     }
1.1.1.3 ! misho     738: 
1.1       misho     739:     xmlGenericError(xmlGenericErrorContext, "warning: ");
                    740:     XML_GET_VAR_STR(msg, str);
                    741:     xmlGenericError(xmlGenericErrorContext, "%s", str);
                    742:     if (str != NULL)
                    743:        xmlFree(str);
                    744: 
                    745:     if (ctxt != NULL) {
                    746:        xmlParserPrintFileContext(input);
                    747:        if (cur != NULL) {
                    748:            xmlParserPrintFileInfo(cur);
                    749:            xmlGenericError(xmlGenericErrorContext, "\n");
                    750:            xmlParserPrintFileContext(cur);
                    751:        }
                    752:     }
                    753: }
                    754: 
                    755: /************************************************************************
1.1.1.3 ! misho     756:  *                                                                     *
        !           757:  *                     Handling of validation errors                   *
        !           758:  *                                                                     *
1.1       misho     759:  ************************************************************************/
                    760: 
                    761: /**
                    762:  * xmlParserValidityError:
                    763:  * @ctx:  an XML parser context
                    764:  * @msg:  the message to display/transmit
                    765:  * @...:  extra parameters for the message display
1.1.1.3 ! misho     766:  *
1.1       misho     767:  * Display and format an validity error messages, gives file,
                    768:  * line, position and extra parameters.
                    769:  */
                    770: void XMLCDECL
                    771: xmlParserValidityError(void *ctx, const char *msg, ...)
                    772: {
                    773:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    774:     xmlParserInputPtr input = NULL;
                    775:     char * str;
                    776:     int len = xmlStrlen((const xmlChar *) msg);
                    777:     static int had_info = 0;
                    778: 
                    779:     if ((len > 1) && (msg[len - 2] != ':')) {
                    780:        if (ctxt != NULL) {
                    781:            input = ctxt->input;
                    782:            if ((input->filename == NULL) && (ctxt->inputNr > 1))
                    783:                input = ctxt->inputTab[ctxt->inputNr - 2];
1.1.1.3 ! misho     784: 
1.1       misho     785:            if (had_info == 0) {
                    786:                xmlParserPrintFileInfo(input);
                    787:            }
                    788:        }
                    789:        xmlGenericError(xmlGenericErrorContext, "validity error: ");
                    790:        had_info = 0;
                    791:     } else {
                    792:        had_info = 1;
                    793:     }
                    794: 
                    795:     XML_GET_VAR_STR(msg, str);
                    796:     xmlGenericError(xmlGenericErrorContext, "%s", str);
                    797:     if (str != NULL)
                    798:        xmlFree(str);
                    799: 
                    800:     if ((ctxt != NULL) && (input != NULL)) {
                    801:        xmlParserPrintFileContext(input);
                    802:     }
                    803: }
                    804: 
                    805: /**
                    806:  * xmlParserValidityWarning:
                    807:  * @ctx:  an XML parser context
                    808:  * @msg:  the message to display/transmit
                    809:  * @...:  extra parameters for the message display
1.1.1.3 ! misho     810:  *
1.1       misho     811:  * Display and format a validity warning messages, gives file, line,
                    812:  * position and extra parameters.
                    813:  */
                    814: void XMLCDECL
                    815: xmlParserValidityWarning(void *ctx, const char *msg, ...)
                    816: {
                    817:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    818:     xmlParserInputPtr input = NULL;
                    819:     char * str;
                    820:     int len = xmlStrlen((const xmlChar *) msg);
                    821: 
                    822:     if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
                    823:        input = ctxt->input;
                    824:        if ((input->filename == NULL) && (ctxt->inputNr > 1))
                    825:            input = ctxt->inputTab[ctxt->inputNr - 2];
                    826: 
                    827:        xmlParserPrintFileInfo(input);
                    828:     }
1.1.1.3 ! misho     829: 
1.1       misho     830:     xmlGenericError(xmlGenericErrorContext, "validity warning: ");
                    831:     XML_GET_VAR_STR(msg, str);
                    832:     xmlGenericError(xmlGenericErrorContext, "%s", str);
                    833:     if (str != NULL)
                    834:        xmlFree(str);
                    835: 
                    836:     if (ctxt != NULL) {
                    837:        xmlParserPrintFileContext(input);
                    838:     }
                    839: }
                    840: 
                    841: 
                    842: /************************************************************************
                    843:  *                                                                     *
                    844:  *                     Extended Error Handling                         *
                    845:  *                                                                     *
                    846:  ************************************************************************/
                    847: 
                    848: /**
                    849:  * xmlGetLastError:
                    850:  *
                    851:  * Get the last global error registered. This is per thread if compiled
                    852:  * with thread support.
                    853:  *
                    854:  * Returns NULL if no error occured or a pointer to the error
                    855:  */
                    856: xmlErrorPtr
                    857: xmlGetLastError(void)
                    858: {
                    859:     if (xmlLastError.code == XML_ERR_OK)
                    860:         return (NULL);
                    861:     return (&xmlLastError);
                    862: }
                    863: 
                    864: /**
                    865:  * xmlResetError:
                    866:  * @err: pointer to the error.
                    867:  *
                    868:  * Cleanup the error.
                    869:  */
                    870: void
                    871: xmlResetError(xmlErrorPtr err)
                    872: {
                    873:     if (err == NULL)
                    874:         return;
                    875:     if (err->code == XML_ERR_OK)
                    876:         return;
                    877:     if (err->message != NULL)
                    878:         xmlFree(err->message);
                    879:     if (err->file != NULL)
                    880:         xmlFree(err->file);
                    881:     if (err->str1 != NULL)
                    882:         xmlFree(err->str1);
                    883:     if (err->str2 != NULL)
                    884:         xmlFree(err->str2);
                    885:     if (err->str3 != NULL)
                    886:         xmlFree(err->str3);
                    887:     memset(err, 0, sizeof(xmlError));
                    888:     err->code = XML_ERR_OK;
                    889: }
                    890: 
                    891: /**
                    892:  * xmlResetLastError:
                    893:  *
                    894:  * Cleanup the last global error registered. For parsing error
                    895:  * this does not change the well-formedness result.
                    896:  */
                    897: void
                    898: xmlResetLastError(void)
                    899: {
                    900:     if (xmlLastError.code == XML_ERR_OK)
                    901:         return;
                    902:     xmlResetError(&xmlLastError);
                    903: }
                    904: 
                    905: /**
                    906:  * xmlCtxtGetLastError:
                    907:  * @ctx:  an XML parser context
                    908:  *
                    909:  * Get the last parsing error registered.
                    910:  *
                    911:  * Returns NULL if no error occured or a pointer to the error
                    912:  */
                    913: xmlErrorPtr
                    914: xmlCtxtGetLastError(void *ctx)
                    915: {
                    916:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    917: 
                    918:     if (ctxt == NULL)
                    919:         return (NULL);
                    920:     if (ctxt->lastError.code == XML_ERR_OK)
                    921:         return (NULL);
                    922:     return (&ctxt->lastError);
                    923: }
                    924: 
                    925: /**
                    926:  * xmlCtxtResetLastError:
                    927:  * @ctx:  an XML parser context
                    928:  *
                    929:  * Cleanup the last global error registered. For parsing error
                    930:  * this does not change the well-formedness result.
                    931:  */
                    932: void
                    933: xmlCtxtResetLastError(void *ctx)
                    934: {
                    935:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    936: 
                    937:     if (ctxt == NULL)
                    938:         return;
                    939:     ctxt->errNo = XML_ERR_OK;
                    940:     if (ctxt->lastError.code == XML_ERR_OK)
                    941:         return;
                    942:     xmlResetError(&ctxt->lastError);
                    943: }
                    944: 
                    945: /**
                    946:  * xmlCopyError:
                    947:  * @from:  a source error
                    948:  * @to:  a target error
                    949:  *
                    950:  * Save the original error to the new place.
                    951:  *
                    952:  * Returns 0 in case of success and -1 in case of error.
                    953:  */
                    954: int
                    955: xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) {
                    956:     char *message, *file, *str1, *str2, *str3;
                    957: 
                    958:     if ((from == NULL) || (to == NULL))
                    959:         return(-1);
                    960: 
                    961:     message = (char *) xmlStrdup((xmlChar *) from->message);
                    962:     file = (char *) xmlStrdup ((xmlChar *) from->file);
                    963:     str1 = (char *) xmlStrdup ((xmlChar *) from->str1);
                    964:     str2 = (char *) xmlStrdup ((xmlChar *) from->str2);
                    965:     str3 = (char *) xmlStrdup ((xmlChar *) from->str3);
                    966: 
                    967:     if (to->message != NULL)
                    968:         xmlFree(to->message);
                    969:     if (to->file != NULL)
                    970:         xmlFree(to->file);
                    971:     if (to->str1 != NULL)
                    972:         xmlFree(to->str1);
                    973:     if (to->str2 != NULL)
                    974:         xmlFree(to->str2);
                    975:     if (to->str3 != NULL)
                    976:         xmlFree(to->str3);
                    977:     to->domain = from->domain;
                    978:     to->code = from->code;
                    979:     to->level = from->level;
                    980:     to->line = from->line;
                    981:     to->node = from->node;
                    982:     to->int1 = from->int1;
                    983:     to->int2 = from->int2;
                    984:     to->node = from->node;
                    985:     to->ctxt = from->ctxt;
                    986:     to->message = message;
                    987:     to->file = file;
                    988:     to->str1 = str1;
                    989:     to->str2 = str2;
                    990:     to->str3 = str3;
                    991: 
                    992:     return 0;
                    993: }
                    994: 
                    995: #define bottom_error
                    996: #include "elfgcchack.h"

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