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