2 * error.c: module displaying/handling XML parser errors
4 * See Copyright for the status of this software.
6 * Daniel Veillard <daniel@veillard.com>
14 #include <libxml/parser.h>
15 #include <libxml/xmlerror.h>
16 #include <libxml/xmlmemory.h>
17 #include <libxml/globals.h>
19 #include "private/error.h"
21 #define XML_MAX_ERRORS 100
23 #define XML_GET_VAR_STR(msg, str) { \
24 int size, prev_size = -1; \
29 str = (char *) xmlMalloc(150); \
34 while (size < 64000) { \
36 chars = vsnprintf(str, size, msg, ap); \
38 if ((chars > -1) && (chars < size)) { \
39 if (prev_size == chars) { \
49 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
56 /************************************************************************
58 * Handling of out of context errors *
60 ************************************************************************/
63 * xmlGenericErrorDefaultFunc:
64 * @ctx: an error context
65 * @msg: the message to display/transmit
66 * @...: extra parameters for the message display
68 * Default handler for out of context error messages.
71 xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED
, const char *msg
, ...) {
74 if (xmlGenericErrorContext
== NULL
)
75 xmlGenericErrorContext
= (void *) stderr
;
78 vfprintf((FILE *)xmlGenericErrorContext
, msg
, args
);
83 * initGenericErrorDefaultFunc:
84 * @handler: the handler
86 * DEPRECATED: Use xmlSetGenericErrorFunc.
88 * Set or reset (if NULL) the default handler for generic errors
89 * to the builtin error function.
92 initGenericErrorDefaultFunc(xmlGenericErrorFunc
* handler
)
95 xmlGenericError
= xmlGenericErrorDefaultFunc
;
97 xmlGenericError
= (*handler
);
101 * xmlSetGenericErrorFunc:
102 * @ctx: the new error handling context
103 * @handler: the new handler function
105 * Function to reset the handler and the error context for out of
106 * context error messages.
107 * This simply means that @handler will be called for subsequent
108 * error messages while not parsing nor validating. And @ctx will
109 * be passed as first argument to @handler
110 * One can simply force messages to be emitted to another FILE * than
111 * stderr by setting @ctx to this file handle and @handler to NULL.
112 * For multi-threaded applications, this must be set separately for each thread.
115 xmlSetGenericErrorFunc(void *ctx
, xmlGenericErrorFunc handler
) {
116 xmlGenericErrorContext
= ctx
;
118 xmlGenericError
= handler
;
120 xmlGenericError
= xmlGenericErrorDefaultFunc
;
124 * xmlSetStructuredErrorFunc:
125 * @ctx: the new error handling context
126 * @handler: the new handler function
128 * Function to reset the handler and the error context for out of
129 * context structured error messages.
130 * This simply means that @handler will be called for subsequent
131 * error messages while not parsing nor validating. And @ctx will
132 * be passed as first argument to @handler
133 * For multi-threaded applications, this must be set separately for each thread.
136 xmlSetStructuredErrorFunc(void *ctx
, xmlStructuredErrorFunc handler
) {
137 xmlStructuredErrorContext
= ctx
;
138 xmlStructuredError
= handler
;
141 /************************************************************************
143 * Handling of parsing errors *
145 ************************************************************************/
148 * xmlParserPrintFileInfo:
149 * @input: an xmlParserInputPtr input
151 * Displays the associated file and line information for the current input
155 xmlParserPrintFileInfo(xmlParserInputPtr input
) {
158 xmlGenericError(xmlGenericErrorContext
,
159 "%s:%d: ", input
->filename
,
162 xmlGenericError(xmlGenericErrorContext
,
163 "Entity: line %d: ", input
->line
);
168 * xmlParserPrintFileContextInternal:
169 * @input: an xmlParserInputPtr input
171 * Displays current context within the input content for error tracking
175 xmlParserPrintFileContextInternal(xmlParserInputPtr input
,
176 xmlGenericErrorFunc channel
, void *data
) {
177 const xmlChar
*cur
, *base
, *start
;
178 unsigned int n
, col
; /* GCC warns if signed, because compared with sizeof() */
179 xmlChar content
[81]; /* space for 80 chars + line terminator */
182 if ((input
== NULL
) || (input
->cur
== NULL
))
187 /* skip backwards over any end-of-lines */
188 while ((cur
> base
) && ((*(cur
) == '\n') || (*(cur
) == '\r'))) {
192 /* search backwards for beginning-of-line (to max buff size) */
193 while ((n
< sizeof(content
) - 1) && (cur
> base
) &&
194 (*cur
!= '\n') && (*cur
!= '\r')) {
198 if ((n
> 0) && ((*cur
== '\n') || (*cur
== '\r'))) {
201 /* skip over continuation bytes */
202 while ((cur
< input
->cur
) && ((*cur
& 0xC0) == 0x80))
205 /* calculate the error position in terms of the current position */
206 col
= input
->cur
- cur
;
207 /* search forward for end-of-line (to max buff size) */
210 /* copy selected text to our buffer */
211 while ((*cur
!= 0) && (*(cur
) != '\n') && (*(cur
) != '\r')) {
212 int len
= input
->end
- cur
;
213 int c
= xmlGetUTF8Char(cur
, &len
);
215 if ((c
< 0) || (n
+ len
> sizeof(content
)-1))
220 memcpy(content
, start
, n
);
222 /* print out the selected text */
223 channel(data
,"%s\n", content
);
224 /* create blank line with problem pointer */
227 /* (leave buffer space for pointer + line terminator) */
228 while ((n
<col
) && (n
++ < sizeof(content
)-2) && (*ctnt
!= 0)) {
235 channel(data
,"%s\n", content
);
239 * xmlParserPrintFileContext:
240 * @input: an xmlParserInputPtr input
242 * Displays current context within the input content for error tracking
245 xmlParserPrintFileContext(xmlParserInputPtr input
) {
246 xmlParserPrintFileContextInternal(input
, xmlGenericError
,
247 xmlGenericErrorContext
);
253 * @ctx: the parser context or NULL
254 * @str: the formatted error message
256 * Report an error with its context, replace the 4 old error/warning
260 xmlReportError(xmlErrorPtr err
, xmlParserCtxtPtr ctxt
, const char *str
,
261 xmlGenericErrorFunc channel
, void *data
)
267 const xmlChar
*name
= NULL
;
270 xmlParserInputPtr input
= NULL
;
271 xmlParserInputPtr cur
= NULL
;
276 if (channel
== NULL
) {
277 channel
= xmlGenericError
;
278 data
= xmlGenericErrorContext
;
283 domain
= err
->domain
;
287 if (code
== XML_ERR_OK
)
290 if ((node
!= NULL
) && (node
->type
== XML_ELEMENT_NODE
))
294 * Maintain the compatibility with the legacy error handling
298 if ((input
!= NULL
) && (input
->filename
== NULL
) &&
299 (ctxt
->inputNr
> 1)) {
301 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
305 channel(data
, "%s:%d: ", input
->filename
, input
->line
);
306 else if ((line
!= 0) && (domain
== XML_FROM_PARSER
))
307 channel(data
, "Entity: line %d: ", input
->line
);
311 channel(data
, "%s:%d: ", file
, line
);
312 else if ((line
!= 0) &&
313 ((domain
== XML_FROM_PARSER
) || (domain
== XML_FROM_SCHEMASV
)||
314 (domain
== XML_FROM_SCHEMASP
)||(domain
== XML_FROM_DTD
) ||
315 (domain
== XML_FROM_RELAXNGP
)||(domain
== XML_FROM_RELAXNGV
)))
316 channel(data
, "Entity: line %d: ", line
);
319 channel(data
, "element %s: ", name
);
322 case XML_FROM_PARSER
:
323 channel(data
, "parser ");
325 case XML_FROM_NAMESPACE
:
326 channel(data
, "namespace ");
330 channel(data
, "validity ");
333 channel(data
, "HTML parser ");
335 case XML_FROM_MEMORY
:
336 channel(data
, "memory ");
338 case XML_FROM_OUTPUT
:
339 channel(data
, "output ");
342 channel(data
, "I/O ");
344 case XML_FROM_XINCLUDE
:
345 channel(data
, "XInclude ");
348 channel(data
, "XPath ");
350 case XML_FROM_XPOINTER
:
351 channel(data
, "parser ");
353 case XML_FROM_REGEXP
:
354 channel(data
, "regexp ");
356 case XML_FROM_MODULE
:
357 channel(data
, "module ");
359 case XML_FROM_SCHEMASV
:
360 channel(data
, "Schemas validity ");
362 case XML_FROM_SCHEMASP
:
363 channel(data
, "Schemas parser ");
365 case XML_FROM_RELAXNGP
:
366 channel(data
, "Relax-NG parser ");
368 case XML_FROM_RELAXNGV
:
369 channel(data
, "Relax-NG validity ");
371 case XML_FROM_CATALOG
:
372 channel(data
, "Catalog ");
375 channel(data
, "C14N ");
378 channel(data
, "XSLT ");
381 channel(data
, "encoding ");
383 case XML_FROM_SCHEMATRONV
:
384 channel(data
, "schematron ");
386 case XML_FROM_BUFFER
:
387 channel(data
, "internal buffer ");
390 channel(data
, "URI ");
399 case XML_ERR_WARNING
:
400 channel(data
, "warning : ");
403 channel(data
, "error : ");
406 channel(data
, "error : ");
411 len
= xmlStrlen((const xmlChar
*)str
);
412 if ((len
> 0) && (str
[len
- 1] != '\n'))
413 channel(data
, "%s\n", str
);
415 channel(data
, "%s", str
);
417 channel(data
, "%s\n", "out of memory error");
421 xmlParserPrintFileContextInternal(input
, channel
, data
);
424 channel(data
, "%s:%d: \n", cur
->filename
, cur
->line
);
425 else if ((line
!= 0) && (domain
== XML_FROM_PARSER
))
426 channel(data
, "Entity: line %d: \n", cur
->line
);
427 xmlParserPrintFileContextInternal(cur
, channel
, data
);
430 if ((domain
== XML_FROM_XPATH
) && (err
->str1
!= NULL
) &&
432 (err
->int1
< xmlStrlen((const xmlChar
*)err
->str1
))) {
436 channel(data
, "%s\n", err
->str1
);
437 for (i
=0;i
< err
->int1
;i
++)
441 channel(data
, "%s\n", buf
);
447 * @schannel: the structured callback channel
448 * @channel: the old callback channel
449 * @data: the callback data
450 * @ctx: the parser context or NULL
451 * @ctx: the parser context or NULL
452 * @domain: the domain for the error
453 * @code: the code for the error
454 * @level: the xmlErrorLevel for the error
455 * @file: the file source of the error (or NULL)
456 * @line: the line of the error or 0 if N/A
457 * @str1: extra string info
458 * @str2: extra string info
459 * @str3: extra string info
460 * @int1: extra int info
461 * @col: column number of the error or 0 if N/A
462 * @msg: the message to display/transmit
463 * @...: extra parameters for the message display
465 * Update the appropriate global or contextual error structure,
466 * then forward the error message down the parser or generic
467 * error callback handler
470 __xmlRaiseError(xmlStructuredErrorFunc schannel
,
471 xmlGenericErrorFunc channel
, void *data
, void *ctx
,
472 void *nod
, int domain
, int code
, xmlErrorLevel level
,
473 const char *file
, int line
, const char *str1
,
474 const char *str2
, const char *str3
, int int1
, int col
,
475 const char *msg
, ...)
477 xmlParserCtxtPtr ctxt
= NULL
;
478 xmlNodePtr node
= (xmlNodePtr
) nod
;
480 xmlParserInputPtr input
= NULL
;
481 xmlErrorPtr to
= &xmlLastError
;
482 xmlNodePtr baseptr
= NULL
;
484 if (code
== XML_ERR_OK
)
486 if ((xmlGetWarningsDefaultValue
== 0) && (level
== XML_ERR_WARNING
))
488 if ((domain
== XML_FROM_PARSER
) || (domain
== XML_FROM_HTML
) ||
489 (domain
== XML_FROM_DTD
) || (domain
== XML_FROM_NAMESPACE
) ||
490 (domain
== XML_FROM_IO
) || (domain
== XML_FROM_VALID
)) {
491 ctxt
= (xmlParserCtxtPtr
) ctx
;
494 if (level
== XML_ERR_WARNING
) {
495 if (ctxt
->nbWarnings
>= XML_MAX_ERRORS
)
497 ctxt
->nbWarnings
+= 1;
499 if (ctxt
->nbErrors
>= XML_MAX_ERRORS
)
504 if ((schannel
== NULL
) && (ctxt
->sax
!= NULL
) &&
505 (ctxt
->sax
->initialized
== XML_SAX2_MAGIC
) &&
506 (ctxt
->sax
->serror
!= NULL
)) {
507 schannel
= ctxt
->sax
->serror
;
508 data
= ctxt
->userData
;
513 * Check if structured error handler set
515 if (schannel
== NULL
) {
516 schannel
= xmlStructuredError
;
518 * if user has defined handler, change data ptr to user's choice
520 if (schannel
!= NULL
)
521 data
= xmlStructuredErrorContext
;
524 * Formatting the message
527 str
= (char *) xmlStrdup(BAD_CAST
"No error message provided");
529 XML_GET_VAR_STR(msg
, str
);
533 * specific processing if a parser context is provided
538 if ((input
!= NULL
) && (input
->filename
== NULL
) &&
539 (ctxt
->inputNr
> 1)) {
540 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
543 file
= input
->filename
;
548 to
= &ctxt
->lastError
;
549 } else if ((node
!= NULL
) && (file
== NULL
)) {
552 if ((node
->doc
!= NULL
) && (node
->doc
->URL
!= NULL
)) {
554 /* file = (const char *) node->doc->URL; */
557 ((i
< 10) && (node
!= NULL
) && (node
->type
!= XML_ELEMENT_NODE
));
560 if ((baseptr
== NULL
) && (node
!= NULL
) &&
561 (node
->doc
!= NULL
) && (node
->doc
->URL
!= NULL
))
564 if ((node
!= NULL
) && (node
->type
== XML_ELEMENT_NODE
))
566 if ((line
== 0) || (line
== 65535))
567 line
= xmlGetLineNo(node
);
571 * Save the information about the error
579 to
->file
= (char *) xmlStrdup((const xmlChar
*) file
);
580 else if (baseptr
!= NULL
) {
581 #ifdef LIBXML_XINCLUDE_ENABLED
583 * We check if the error is within an XInclude section and,
584 * if so, attempt to print out the href of the XInclude instead
585 * of the usual "base" (doc->URL) for the node (bug 152623).
587 xmlNodePtr prev
= baseptr
;
590 while (prev
!= NULL
) {
591 if (prev
->prev
== NULL
)
595 if (prev
->type
== XML_XINCLUDE_START
) {
599 href
= (char *) xmlGetProp(prev
, BAD_CAST
"href");
603 } else if (prev
->type
== XML_XINCLUDE_END
)
611 to
->file
= (char *) xmlStrdup(baseptr
->doc
->URL
);
612 if ((to
->file
== NULL
) && (node
!= NULL
) && (node
->doc
!= NULL
)) {
613 to
->file
= (char *) xmlStrdup(node
->doc
->URL
);
618 to
->str1
= (char *) xmlStrdup((const xmlChar
*) str1
);
620 to
->str2
= (char *) xmlStrdup((const xmlChar
*) str2
);
622 to
->str3
= (char *) xmlStrdup((const xmlChar
*) str3
);
628 if (to
!= &xmlLastError
)
629 xmlCopyError(to
,&xmlLastError
);
631 if (schannel
!= NULL
) {
637 * Find the callback channel if channel param is NULL
639 if ((ctxt
!= NULL
) && (channel
== NULL
) &&
640 (xmlStructuredError
== NULL
) && (ctxt
->sax
!= NULL
)) {
641 if (level
== XML_ERR_WARNING
)
642 channel
= ctxt
->sax
->warning
;
644 channel
= ctxt
->sax
->error
;
645 data
= ctxt
->userData
;
646 } else if (channel
== NULL
) {
647 channel
= xmlGenericError
;
651 data
= xmlGenericErrorContext
;
657 if ((channel
== xmlParserError
) ||
658 (channel
== xmlParserWarning
) ||
659 (channel
== xmlParserValidityError
) ||
660 (channel
== xmlParserValidityWarning
))
661 xmlReportError(to
, ctxt
, str
, NULL
, NULL
);
662 else if (((void(*)(void)) channel
== (void(*)(void)) fprintf
) ||
663 (channel
== xmlGenericErrorDefaultFunc
))
664 xmlReportError(to
, ctxt
, str
, channel
, data
);
666 channel(data
, "%s", str
);
671 * @domain: where the error comes from
672 * @code: the error code
673 * @node: the context node
674 * @extra: extra information
676 * Handle an out of memory condition
679 __xmlSimpleError(int domain
, int code
, xmlNodePtr node
,
680 const char *msg
, const char *extra
)
683 if (code
== XML_ERR_NO_MEMORY
) {
685 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, node
, domain
,
686 XML_ERR_NO_MEMORY
, XML_ERR_FATAL
, NULL
, 0, extra
,
688 "Memory allocation failed : %s\n", extra
);
690 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, node
, domain
,
691 XML_ERR_NO_MEMORY
, XML_ERR_FATAL
, NULL
, 0, NULL
,
692 NULL
, NULL
, 0, 0, "Memory allocation failed\n");
694 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, node
, domain
,
695 code
, XML_ERR_ERROR
, NULL
, 0, extra
,
696 NULL
, NULL
, 0, 0, msg
, extra
);
701 * @ctx: an XML parser context
702 * @msg: the message to display/transmit
703 * @...: extra parameters for the message display
705 * Display and format an error messages, gives file, line, position and
709 xmlParserError(void *ctx
, const char *msg
, ...)
711 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
712 xmlParserInputPtr input
= NULL
;
713 xmlParserInputPtr cur
= NULL
;
718 if ((input
!= NULL
) && (input
->filename
== NULL
) &&
719 (ctxt
->inputNr
> 1)) {
721 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
723 xmlParserPrintFileInfo(input
);
726 xmlGenericError(xmlGenericErrorContext
, "error: ");
727 XML_GET_VAR_STR(msg
, str
);
728 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
733 xmlParserPrintFileContext(input
);
735 xmlParserPrintFileInfo(cur
);
736 xmlGenericError(xmlGenericErrorContext
, "\n");
737 xmlParserPrintFileContext(cur
);
744 * @ctx: an XML parser context
745 * @msg: the message to display/transmit
746 * @...: extra parameters for the message display
748 * Display and format a warning messages, gives file, line, position and
752 xmlParserWarning(void *ctx
, const char *msg
, ...)
754 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
755 xmlParserInputPtr input
= NULL
;
756 xmlParserInputPtr cur
= NULL
;
761 if ((input
!= NULL
) && (input
->filename
== NULL
) &&
762 (ctxt
->inputNr
> 1)) {
764 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
766 xmlParserPrintFileInfo(input
);
769 xmlGenericError(xmlGenericErrorContext
, "warning: ");
770 XML_GET_VAR_STR(msg
, str
);
771 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
776 xmlParserPrintFileContext(input
);
778 xmlParserPrintFileInfo(cur
);
779 xmlGenericError(xmlGenericErrorContext
, "\n");
780 xmlParserPrintFileContext(cur
);
785 /************************************************************************
787 * Handling of validation errors *
789 ************************************************************************/
792 * xmlParserValidityError:
793 * @ctx: an XML parser context
794 * @msg: the message to display/transmit
795 * @...: extra parameters for the message display
797 * Display and format an validity error messages, gives file,
798 * line, position and extra parameters.
801 xmlParserValidityError(void *ctx
, const char *msg
, ...)
803 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
804 xmlParserInputPtr input
= NULL
;
806 int len
= xmlStrlen((const xmlChar
*) msg
);
807 static int had_info
= 0;
809 if ((len
> 1) && (msg
[len
- 2] != ':')) {
812 if ((input
->filename
== NULL
) && (ctxt
->inputNr
> 1))
813 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
816 xmlParserPrintFileInfo(input
);
819 xmlGenericError(xmlGenericErrorContext
, "validity error: ");
825 XML_GET_VAR_STR(msg
, str
);
826 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
830 if ((ctxt
!= NULL
) && (input
!= NULL
)) {
831 xmlParserPrintFileContext(input
);
836 * xmlParserValidityWarning:
837 * @ctx: an XML parser context
838 * @msg: the message to display/transmit
839 * @...: extra parameters for the message display
841 * Display and format a validity warning messages, gives file, line,
842 * position and extra parameters.
845 xmlParserValidityWarning(void *ctx
, const char *msg
, ...)
847 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
848 xmlParserInputPtr input
= NULL
;
850 int len
= xmlStrlen((const xmlChar
*) msg
);
852 if ((ctxt
!= NULL
) && (len
!= 0) && (msg
[len
- 1] != ':')) {
854 if ((input
->filename
== NULL
) && (ctxt
->inputNr
> 1))
855 input
= ctxt
->inputTab
[ctxt
->inputNr
- 2];
857 xmlParserPrintFileInfo(input
);
860 xmlGenericError(xmlGenericErrorContext
, "validity warning: ");
861 XML_GET_VAR_STR(msg
, str
);
862 xmlGenericError(xmlGenericErrorContext
, "%s", str
);
867 xmlParserPrintFileContext(input
);
872 /************************************************************************
874 * Extended Error Handling *
876 ************************************************************************/
881 * Get the last global error registered. This is per thread if compiled
882 * with thread support.
884 * Returns NULL if no error occurred or a pointer to the error
887 xmlGetLastError(void)
889 if (xmlLastError
.code
== XML_ERR_OK
)
891 return (&xmlLastError
);
896 * @err: pointer to the error.
901 xmlResetError(xmlErrorPtr err
)
905 if (err
->code
== XML_ERR_OK
)
907 if (err
->message
!= NULL
)
908 xmlFree(err
->message
);
909 if (err
->file
!= NULL
)
911 if (err
->str1
!= NULL
)
913 if (err
->str2
!= NULL
)
915 if (err
->str3
!= NULL
)
917 memset(err
, 0, sizeof(xmlError
));
918 err
->code
= XML_ERR_OK
;
924 * Cleanup the last global error registered. For parsing error
925 * this does not change the well-formedness result.
928 xmlResetLastError(void)
930 if (xmlLastError
.code
== XML_ERR_OK
)
932 xmlResetError(&xmlLastError
);
936 * xmlCtxtGetLastError:
937 * @ctx: an XML parser context
939 * Get the last parsing error registered.
941 * Returns NULL if no error occurred or a pointer to the error
944 xmlCtxtGetLastError(void *ctx
)
946 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
950 if (ctxt
->lastError
.code
== XML_ERR_OK
)
952 return (&ctxt
->lastError
);
956 * xmlCtxtResetLastError:
957 * @ctx: an XML parser context
959 * Cleanup the last global error registered. For parsing error
960 * this does not change the well-formedness result.
963 xmlCtxtResetLastError(void *ctx
)
965 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
969 ctxt
->errNo
= XML_ERR_OK
;
970 if (ctxt
->lastError
.code
== XML_ERR_OK
)
972 xmlResetError(&ctxt
->lastError
);
977 * @from: a source error
978 * @to: a target error
980 * Save the original error to the new place.
982 * Returns 0 in case of success and -1 in case of error.
985 xmlCopyError(xmlErrorPtr from
, xmlErrorPtr to
) {
986 char *message
, *file
, *str1
, *str2
, *str3
;
988 if ((from
== NULL
) || (to
== NULL
))
991 message
= (char *) xmlStrdup((xmlChar
*) from
->message
);
992 file
= (char *) xmlStrdup ((xmlChar
*) from
->file
);
993 str1
= (char *) xmlStrdup ((xmlChar
*) from
->str1
);
994 str2
= (char *) xmlStrdup ((xmlChar
*) from
->str2
);
995 str3
= (char *) xmlStrdup ((xmlChar
*) from
->str3
);
997 if (to
->message
!= NULL
)
998 xmlFree(to
->message
);
999 if (to
->file
!= NULL
)
1001 if (to
->str1
!= NULL
)
1003 if (to
->str2
!= NULL
)
1005 if (to
->str3
!= NULL
)
1007 to
->domain
= from
->domain
;
1008 to
->code
= from
->code
;
1009 to
->level
= from
->level
;
1010 to
->line
= from
->line
;
1011 to
->node
= from
->node
;
1012 to
->int1
= from
->int1
;
1013 to
->int2
= from
->int2
;
1014 to
->node
= from
->node
;
1015 to
->ctxt
= from
->ctxt
;
1016 to
->message
= message
;