Setting up the framework for structured error reporting, touches a lot of

* HTMLparser.c c14n.c catalog.c error.c globals.c parser.c
  parserInternals.c relaxng.c valid.c xinclude.c xmlIO.c xmlregexp.c
  xmlschemas.c xpath.c xpointer.c include/libxml/globals.h
  include/libxml/parser.h include/libxml/valid.h
  include/libxml/xmlerror.h: Setting up the framework for structured
  error reporting, touches a lot of modules, but little code now
  the error handling trail has been cleaned up.
Daniel
diff --git a/ChangeLog b/ChangeLog
index aee4573..2a85f96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Oct 10 16:08:02 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c c14n.c catalog.c error.c globals.c parser.c
+	  parserInternals.c relaxng.c valid.c xinclude.c xmlIO.c xmlregexp.c
+	  xmlschemas.c xpath.c xpointer.c include/libxml/globals.h
+	  include/libxml/parser.h include/libxml/valid.h 
+	  include/libxml/xmlerror.h: Setting up the framework for structured
+	  error reporting, touches a lot of modules, but little code now
+	  the error handling trail has been cleaned up.
+
 Fri Oct 10 14:29:42 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
 	* c14n.c include/libxml/xmlerror.h: converted the C14N module too
diff --git a/HTMLparser.c b/HTMLparser.c
index 3ee37a4..68c54cb 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -79,12 +79,12 @@
         ctxt->disableSAX = 1;
     }
     if (extra)
-        __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                         NULL, NULL, 0, 0,
                         "Memory allocation failed : %s\n", extra);
     else
-        __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
                         NULL, NULL, 0, 0, "Memory allocation failed\n");
 }
@@ -104,7 +104,7 @@
              const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
                     XML_ERR_ERROR, NULL, 0,
 		    (const char *) str1, (const char *) str2,
 		    NULL, 0, 0,
@@ -126,7 +126,7 @@
              const char *msg, int val)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
                     XML_ERR_ERROR, NULL, 0, NULL, NULL,
 		    NULL, val, 0, msg, val);
     ctxt->wellFormed = 0;
diff --git a/c14n.c b/c14n.c
index a8030fa..01c46b1 100644
--- a/c14n.c
+++ b/c14n.c
@@ -132,7 +132,7 @@
 static void
 xmlC14NErrMemory(const char *extra)
 {
-    __xmlRaiseError(NULL, NULL, NULL, NULL, XML_FROM_C14N,
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
 		    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
 		    NULL, NULL, 0, 0,
 		    "Memory allocation failed : %s\n", extra);
@@ -154,7 +154,7 @@
 {
     if (ctxt != NULL)
         ctxt->error = error;
-    __xmlRaiseError(NULL, NULL,
+    __xmlRaiseError(NULL, NULL, NULL,
 		    ctxt, node, XML_FROM_C14N, error,
 		    XML_ERR_ERROR, NULL, 0,
 		    NULL, NULL, NULL, 0, 0, msg);
@@ -1490,7 +1490,7 @@
               int exclusive, xmlChar ** inclusive_ns_prefixes,
               int with_comments, xmlOutputBufferPtr buf)
 {
-    xmlC14NCtxPtr ctx;
+    xmlC14NCtxPtr ctx = NULL;
 
     if ((doc == NULL) || (buf == NULL)) {
 #ifdef DEBUG_C14N
diff --git a/catalog.c b/catalog.c
index c013c97..06dbb52 100644
--- a/catalog.c
+++ b/catalog.c
@@ -197,7 +197,7 @@
 static void
 xmlCatalogErrMemory(const char *extra)
 {
-    __xmlRaiseError(NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
                     XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
 		    extra, NULL, NULL, 0, 0,
 		    "Memory allocation failed : %s\n", extra);
@@ -217,7 +217,7 @@
                const char *msg, const xmlChar *str1, const xmlChar *str2,
 	       const xmlChar *str3)
 {
-    __xmlRaiseError(NULL, NULL, catal, node, XML_FROM_CATALOG,
+    __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
                     error, XML_ERR_ERROR, NULL, 0,
 		    (const char *) str1, (const char *) str2,
 		    (const char *) str3, 0, 0,
diff --git a/error.c b/error.c
index fcc0fdd..e450f1f 100644
--- a/error.c
+++ b/error.c
@@ -112,6 +112,23 @@
 	xmlGenericError = xmlGenericErrorDefaultFunc;
 }
 
+/**
+ * xmlSetStructuredErrorFunc:
+ * @ctx:  the new error handling context
+ * @handler:  the new handler function
+ *
+ * Function to reset the handler and the error context for out of
+ * context structured error messages.
+ * This simply means that @handler will be called for subsequent
+ * error messages while not parsing nor validating. And @ctx will
+ * be passed as first argument to @handler
+ */
+void
+xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
+    xmlGenericErrorContext = ctx;
+    xmlStructuredError = handler;
+}
+
 /************************************************************************
  * 									*
  * 			Handling of parsing errors			*
@@ -392,7 +409,8 @@
 
 /**
  * __xmlRaiseError:
- * @channel: the callback channel
+ * @channel: the structured callback channel
+ * @channel: the old callback channel
  * @data: the callback data
  * @ctx: the parser context or NULL
  * @ctx: the parser context or NULL
@@ -414,7 +432,8 @@
  * error callback handler
  */
 void
-__xmlRaiseError(xmlGenericErrorFunc channel, void *data, void *ctx,
+__xmlRaiseError(xmlStructuredErrorFunc schannel,
+              xmlGenericErrorFunc channel, void *data, void *ctx,
               void *nod, int domain, int code, xmlErrorLevel level,
               const char *file, int line, const char *str1,
               const char *str2, const char *str3, int int1, int int2,
@@ -431,6 +450,9 @@
         (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
 	(domain == XML_FROM_IO)) {
 	ctxt = (xmlParserCtxtPtr) ctx;
+	if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
+	    (ctxt->sax->initialized == XML_SAX2_MAGIC))
+	    schannel = ctxt->sax->serror;
     }
     if (code == XML_ERR_OK)
         return;
@@ -512,9 +534,16 @@
 	    channel = ctxt->sax->error;
 	data = ctxt->userData;
     } else if (channel == NULL) {
-	channel = xmlGenericError;
+        if (xmlStructuredError != NULL)
+	    schannel = xmlStructuredError;
+	else
+	    channel = xmlGenericError;
 	data = xmlGenericErrorContext;
     }
+    if (schannel != NULL) {
+        schannel(data, to);
+	return;
+    }
     if (channel == NULL)
         return;
 
@@ -546,16 +575,16 @@
 
     if (code == XML_ERR_NO_MEMORY) {
 	if (extra)
-	    __xmlRaiseError(NULL, NULL, NULL, node, domain,
+	    __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
 			    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
 			    NULL, NULL, 0, 0,
 			    "Memory allocation failed : %s\n", extra);
 	else
-	    __xmlRaiseError(NULL, NULL, NULL, node, domain,
+	    __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
 			    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
 			    NULL, NULL, 0, 0, "Memory allocation failed\n");
     } else {
-	__xmlRaiseError(NULL, NULL, NULL, node, domain,
+	__xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
 			code, XML_ERR_ERROR, NULL, 0, extra,
 			NULL, NULL, 0, 0, msg, extra);
     }
diff --git a/globals.c b/globals.c
index fd61cf4..8de87e4 100644
--- a/globals.c
+++ b/globals.c
@@ -136,6 +136,7 @@
 #undef	xmlDefaultSAXLocator
 #undef	xmlDoValidityCheckingDefaultValue
 #undef	xmlGenericError
+#undef	xmlStructuredError
 #undef	xmlGenericErrorContext
 #undef	xmlGetWarningsDefaultValue
 #undef	xmlIndentTreeOutput
@@ -288,6 +289,13 @@
 xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
 static xmlGenericErrorFunc xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
 /**
+ * xmlStructuredError:
+ *
+ * Global setting: function used for structured error callbacks
+ */
+xmlStructuredErrorFunc xmlStructuredError = NULL;
+static xmlStructuredErrorFunc xmlStructuredErrorThrDef = NULL;
+/**
  * xmlGenericErrorContext:
  *
  * Global setting passed to generic error callbacks
@@ -523,6 +531,7 @@
         xmlSubstituteEntitiesDefaultValueThrDef;
 
     gs->xmlGenericError = xmlGenericErrorThrDef;
+    gs->xmlStructuredError = xmlStructuredErrorThrDef;
     gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
     gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
     gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
@@ -542,6 +551,14 @@
     xmlMutexUnlock(xmlThrDefMutex);
 }
 
+void
+xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
+    xmlMutexLock(xmlThrDefMutex);
+    xmlGenericErrorContextThrDef = ctx;
+    xmlStructuredErrorThrDef = handler;
+    xmlMutexUnlock(xmlThrDefMutex);
+}
+
 /**
  * xmlRegisterNodeDefault:
  * @func: function pointer to the new RegisterNodeFunc
@@ -736,6 +753,15 @@
 	return (&xmlGetGlobalState()->xmlGenericError);
 }
 
+#undef	xmlStructuredError
+xmlStructuredErrorFunc *
+__xmlStructuredError(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlStructuredError);
+    else
+	return (&xmlGetGlobalState()->xmlStructuredError);
+}
+
 #undef	xmlGenericErrorContext
 void * *
 __xmlGenericErrorContext(void) {
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index f380db1..733632c 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -42,6 +42,7 @@
 #undef	xmlDoValidityCheckingDefaultValue
 #undef	xmlFree
 #undef	xmlGenericError
+#undef	xmlStructuredError
 #undef	xmlGenericErrorContext
 #undef	xmlGetWarningsDefaultValue
 #undef	xmlIndentTreeOutput
@@ -82,6 +83,7 @@
 	xmlReallocFunc xmlRealloc;
 
 	xmlGenericErrorFunc xmlGenericError;
+	xmlStructuredErrorFunc xmlStructuredError;
 	void *xmlGenericErrorContext;
 
 	int oldXMLWDcompatibility;
@@ -121,6 +123,8 @@
 
 XMLPUBFUN void XMLCALL xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler);
 
+XMLPUBFUN void XMLCALL xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler);
+
 XMLPUBFUN xmlRegisterNodeFunc XMLCALL xmlRegisterNodeDefault(xmlRegisterNodeFunc func);
 XMLPUBFUN xmlRegisterNodeFunc XMLCALL xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
 XMLPUBFUN xmlDeregisterNodeFunc XMLCALL xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func);
@@ -279,6 +283,14 @@
 XMLPUBVAR xmlGenericErrorFunc xmlGenericError;
 #endif
 
+XMLPUBFUN xmlStructuredErrorFunc * XMLCALL __xmlStructuredError(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlStructuredError \
+(*(__xmlStructuredError()))
+#else
+XMLPUBVAR xmlStructuredErrorFunc xmlStructuredError;
+#endif
+
 XMLPUBFUN void * * XMLCALL __xmlGenericErrorContext(void);
 #ifdef LIBXML_THREAD_ENABLED
 #define xmlGenericErrorContext \
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 70ee4b7..9da48cb 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -716,6 +716,7 @@
     void *_private;
     startElementNsSAX2Func startElementNs;
     endElementNsSAX2Func endElementNs;
+    xmlStructuredErrorFunc serror;
 };
 
 /*
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
index cb7ff2c..07b4f8f 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -11,6 +11,7 @@
 #define __XML_VALID_H__
 
 #include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
 #include <libxml/tree.h>
 #include <libxml/list.h>
 #include <libxml/xmlautomata.h>
@@ -86,6 +87,8 @@
     void                     *am;
     void                  *state;
 #endif
+
+    xmlStructuredErrorFunc serror;   /* structured error reporting capability */
 };
 
 /*
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 8f03403..8510a80 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -580,6 +580,9 @@
 XMLPUBFUN void XMLCALL	
     initGenericErrorDefaultFunc	(xmlGenericErrorFunc *handler);
 
+XMLPUBFUN void XMLCALL	
+    xmlSetStructuredErrorFunc	(void *ctx,
+				 xmlStructuredErrorFunc handler);
 /*
  * Default message routines used by SAX and Valid context for error
  * and warning reporting.
@@ -627,7 +630,8 @@
  * Internal callback reporting routine
  */
 XMLPUBFUN void XMLCALL 
-    __xmlRaiseError		(xmlGenericErrorFunc channel,
+    __xmlRaiseError		(xmlStructuredErrorFunc schannel,
+    				 xmlGenericErrorFunc channel,
     				 void *data,
                                  void *ctx,
     				 void *node,
diff --git a/parser.c b/parser.c
index 656e4bd..69a9c4c 100644
--- a/parser.c
+++ b/parser.c
@@ -142,12 +142,12 @@
 {
     ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
     if (prefix == NULL)
-        __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                         ctxt->errNo, XML_ERR_FATAL, NULL, 0,
                         (const char *) localname, NULL, NULL, 0, 0,
                         "Attribute %s redefined\n", localname);
     else
-        __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                         ctxt->errNo, XML_ERR_FATAL, NULL, 0,
                         (const char *) prefix, (const char *) localname,
                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
@@ -350,7 +350,7 @@
             errmsg = "Unregistered error message\n";
     }
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
                     info);
     ctxt->wellFormed = 0;
@@ -371,7 +371,7 @@
                const char *msg)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
     ctxt->wellFormed = 0;
     if (ctxt->recovery == 0)
@@ -393,7 +393,9 @@
               const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
     ctxt->errNo = error;
-    __xmlRaiseError((ctxt->sax) ? ctxt->sax->warning : NULL, ctxt->userData,
+    __xmlRaiseError((ctxt->sax) ? ctxt->sax->serror : NULL,
+                    (ctxt->sax) ? ctxt->sax->warning : NULL,
+                    ctxt->userData,
                     ctxt, NULL, XML_FROM_PARSER, error,
                     XML_ERR_WARNING, NULL, 0,
 		    (const char *) str1, (const char *) str2, NULL, 0, 0,
@@ -414,7 +416,8 @@
               const char *msg, const xmlChar *str1)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(ctxt->vctxt.error, ctxt->vctxt.userData,
+    __xmlRaiseError(ctxt->vctxt.serror,
+                    ctxt->vctxt.error, ctxt->vctxt.userData,
                     ctxt, NULL, XML_FROM_DTD, error,
                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
 		    NULL, NULL, 0, 0,
@@ -436,7 +439,7 @@
                   const char *msg, int val)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL,
+    __xmlRaiseError(NULL, NULL, NULL,
                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
     ctxt->wellFormed = 0;
@@ -461,7 +464,7 @@
 		  const xmlChar *str2)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL,
+    __xmlRaiseError(NULL, NULL, NULL,
                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                     NULL, 0, (const char *) str1, (const char *) str2,
 		    NULL, val, 0, msg, str1, val, str2);
@@ -484,7 +487,7 @@
                   const char *msg, const xmlChar * val)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
                     XML_FROM_PARSER, error, XML_ERR_FATAL,
                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                     val);
@@ -507,7 +510,7 @@
                   const char *msg, const xmlChar * val)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
                     XML_FROM_PARSER, error, XML_ERR_ERROR,
                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                     val);
@@ -530,7 +533,7 @@
          const xmlChar * info3)
 {
     ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
                     (const char *) info2, (const char *) info3, 0, 0, msg,
                     info1, info2, info3);
diff --git a/parserInternals.c b/parserInternals.c
index ccc5eed..562c578 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -110,12 +110,12 @@
         ctxt->disableSAX = 1;
     }
     if (extra)
-        __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                         NULL, NULL, 0, 0,
                         "Memory allocation failed : %s\n", extra);
     else
-        __xmlRaiseError(NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
                         NULL, NULL, 0, 0, "Memory allocation failed\n");
 }
@@ -136,7 +136,7 @@
 {
     if (ctxt != NULL)
         ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL,
+    __xmlRaiseError(NULL, NULL, NULL,
                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                     NULL, 0, (const char *) str1, (const char *) str2,
                     NULL, 0, 0, msg, str1, str2);
@@ -160,7 +160,7 @@
 {
     if (ctxt != NULL)
         ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-    __xmlRaiseError(NULL, NULL,
+    __xmlRaiseError(NULL, NULL, NULL,
                     ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
                     XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
                     0, 0, msg, str);
@@ -186,7 +186,7 @@
 {
     if (ctxt != NULL)
         ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL,
+    __xmlRaiseError(NULL, NULL, NULL,
                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
     if (ctxt != NULL) {
diff --git a/relaxng.c b/relaxng.c
index c6e577d..0330bec 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -202,6 +202,7 @@
     void *userData;             /* user specific data block */
     xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
     xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
+    xmlStructuredErrorFunc serror;
     xmlRelaxNGValidErr err;
 
     xmlRelaxNGPtr schema;       /* The schema in use */
@@ -342,6 +343,7 @@
     void *userData;             /* user specific data block */
     xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
     xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
+    xmlStructuredErrorFunc serror;
     int nbErrors;               /* number of errors in validation */
 
     xmlRelaxNGPtr schema;       /* The schema in use */
@@ -425,6 +427,7 @@
 static void
 xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
 
@@ -432,15 +435,16 @@
         channel = ctxt->error;
         data = ctxt->userData;
         ctxt->nbErrors++;
+        schannel = ctxt->serror;
     }
     if (extra)
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         NULL, NULL, XML_FROM_RELAXNGP,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                         NULL, NULL, 0, 0,
                         "Memory allocation failed : %s\n", extra);
     else
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         NULL, NULL, XML_FROM_RELAXNGP,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
                         NULL, NULL, 0, 0, "Memory allocation failed\n");
@@ -456,6 +460,7 @@
 static void
 xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
 
@@ -463,15 +468,16 @@
         channel = ctxt->error;
         data = ctxt->userData;
         ctxt->nbErrors++;
+        schannel = ctxt->serror;
     }
     if (extra)
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         NULL, NULL, XML_FROM_RELAXNGV,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                         NULL, NULL, 0, 0,
                         "Memory allocation failed : %s\n", extra);
     else
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         NULL, NULL, XML_FROM_RELAXNGV,
                         XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
                         NULL, NULL, 0, 0, "Memory allocation failed\n");
@@ -492,6 +498,7 @@
 xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
            const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
 
@@ -499,8 +506,9 @@
         channel = ctxt->error;
         data = ctxt->userData;
         ctxt->nbErrors++;
+        schannel = ctxt->serror;
     }
-    __xmlRaiseError(channel, data,
+    __xmlRaiseError(schannel, channel, data,
                     NULL, node, XML_FROM_RELAXNGP,
                     error, XML_ERR_ERROR, NULL, 0,
                     (const char *) str1, (const char *) str2, NULL, 0, 0,
@@ -522,6 +530,7 @@
 xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
            const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
 
@@ -529,8 +538,9 @@
         channel = ctxt->error;
         data = ctxt->userData;
         ctxt->nbErrors++;
+        schannel = ctxt->serror;
     }
-    __xmlRaiseError(channel, data,
+    __xmlRaiseError(schannel, channel, data,
                     NULL, node, XML_FROM_RELAXNGV,
                     error, XML_ERR_ERROR, NULL, 0,
                     (const char *) str1, (const char *) str2, NULL, 0, 0,
diff --git a/valid.c b/valid.c
index 34f93df..bec4f9a 100644
--- a/valid.c
+++ b/valid.c
@@ -53,6 +53,7 @@
 static void
 xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     void *data = NULL;
@@ -61,14 +62,15 @@
         channel = ctxt->error;
         data = ctxt->userData;
 	pctxt = ctxt->userData;
+        schannel = ctxt->serror;
     }
     if (extra)
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         pctxt, NULL, XML_FROM_DTD, XML_ERR_NO_MEMORY,
                         XML_ERR_FATAL, NULL, 0, extra, NULL, NULL, 0, 0,
                         "Memory allocation failed : %s\n", extra);
     else
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         pctxt, NULL, XML_FROM_DTD, XML_ERR_NO_MEMORY,
                         XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0,
                         "Memory allocation failed\n");
@@ -86,22 +88,24 @@
 xmlErrValid(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlParserErrors error,
             const char *msg, const char *extra)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     void *data = NULL;
 
     if (ctxt != NULL) {
         channel = ctxt->error;
+        schannel = ctxt->serror;
         data = ctxt->userData;
 	pctxt = ctxt->userData;
     }
     if (extra)
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         pctxt, NULL, XML_FROM_DTD, error,
                         XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0,
                         msg, extra);
     else
-        __xmlRaiseError(channel, data,
+        __xmlRaiseError(schannel, channel, data,
                         pctxt, NULL, XML_FROM_DTD, error,
                         XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0,
                         msg);
@@ -124,6 +128,7 @@
                 const char *msg, const xmlChar * str1,
                 int int2, const xmlChar * str3)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     void *data = NULL;
@@ -132,8 +137,9 @@
         channel = ctxt->error;
         data = ctxt->userData;
 	pctxt = ctxt->userData;
+	pctxt = ctxt->userData;
     }
-    __xmlRaiseError(channel, data, pctxt, node, XML_FROM_DTD, error,
+    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_DTD, error,
                     XML_ERR_ERROR, NULL, 0,
                     (const char *) str1,
                     (const char *) str3,
@@ -156,6 +162,7 @@
                 const char *msg, const xmlChar * str1,
                 const xmlChar * str2, const xmlChar * str3)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     void *data = NULL;
@@ -164,8 +171,9 @@
         channel = ctxt->error;
         data = ctxt->userData;
 	pctxt = ctxt->userData;
+	pctxt = ctxt->userData;
     }
-    __xmlRaiseError(channel, data, pctxt, node, XML_FROM_DTD, error,
+    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_DTD, error,
                     XML_ERR_ERROR, NULL, 0,
                     (const char *) str1,
                     (const char *) str1,
@@ -188,6 +196,7 @@
                 const char *msg, const xmlChar * str1,
                 const xmlChar * str2, const xmlChar * str3)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     void *data = NULL;
@@ -196,8 +205,9 @@
         channel = ctxt->error;
         data = ctxt->userData;
 	pctxt = ctxt->userData;
+	pctxt = ctxt->userData;
     }
-    __xmlRaiseError(channel, data, pctxt, node, XML_FROM_DTD, error,
+    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_DTD, error,
                     XML_ERR_WARNING, NULL, 0,
                     (const char *) str1,
                     (const char *) str1,
diff --git a/xinclude.c b/xinclude.c
index 04d827f..c992b58 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -112,7 +112,7 @@
 {
     if (ctxt != NULL)
 	ctxt->nbErrors++;
-    __xmlRaiseError(NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
                     XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
 		    extra, NULL, NULL, 0, 0,
 		    "Memory allocation failed : %s\n", extra);
@@ -133,7 +133,7 @@
 {
     if (ctxt != NULL)
 	ctxt->nbErrors++;
-    __xmlRaiseError(NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
                     error, XML_ERR_ERROR, NULL, 0,
 		    (const char *) extra, NULL, NULL, 0, 0,
 		    msg, (const char *) extra);
diff --git a/xmlIO.c b/xmlIO.c
index 6642a59..41a7d9c 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -350,6 +350,7 @@
 static void
 xmlLoaderErr(xmlParserCtxtPtr ctxt, const char *msg, const char *filename)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
     xmlErrorLevel level = XML_ERR_ERROR;
@@ -362,9 +363,10 @@
 	    channel = ctxt->sax->warning;
 	    level = XML_ERR_WARNING;
 	}
+	schannel = ctxt->sax->serror;
 	data = ctxt->userData;
     }
-    __xmlRaiseError(channel, data, ctxt, NULL, XML_FROM_IO,
+    __xmlRaiseError(schannel, channel, data, ctxt, NULL, XML_FROM_IO,
                     XML_IO_LOAD_ERROR, level, NULL, 0,
 		    filename, NULL, NULL, 0, 0,
 		    msg, filename);
diff --git a/xmlregexp.c b/xmlregexp.c
index dd8e464..76635fe 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -331,7 +331,7 @@
         regexp = (const char *) ctxt->string;
 	ctxt->error = XML_ERR_NO_MEMORY;
     }
-    __xmlRaiseError(NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
 		    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
 		    regexp, NULL, 0, 0,
 		    "Memory allocation failed : %s\n", extra);
@@ -354,7 +354,7 @@
 	idx = ctxt->cur - ctxt->string;
 	ctxt->error = XML_REGEXP_COMPILE_ERROR;
     }
-    __xmlRaiseError(NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
 		    XML_REGEXP_COMPILE_ERROR, XML_ERR_FATAL, NULL, 0, extra,
 		    regexp, NULL, idx, 0,
 		    "failed to compile: %s\n", extra);
diff --git a/xmlschemas.c b/xmlschemas.c
index 234c7e7..76c41af 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -65,6 +65,7 @@
     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
     xmlSchemaValidError err;
     int nberrors;
+    xmlStructuredErrorFunc serror;
 
     xmlSchemaPtr schema;        /* The schema in use */
     xmlChar *container;         /* the current element, group, ... */
@@ -106,6 +107,7 @@
     void *userData;             /* user specific data block */
     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
+    xmlStructuredErrorFunc serror;
 
     xmlSchemaPtr schema;        /* The schema in use */
     xmlDocPtr doc;
@@ -180,14 +182,16 @@
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
     xmlGenericErrorFunc channel = NULL;
+    xmlStructuredErrorFunc schannel = NULL;
     void *data = NULL;
 
     if (ctxt != NULL) {
         ctxt->nberrors++;
         channel = ctxt->error;
         data = ctxt->userData;
+	schannel = ctxt->serror;
     }
-    __xmlRaiseError(channel, data, ctxt, node, XML_FROM_SCHEMASP,
+    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
                     error, XML_ERR_ERROR, NULL, 0,
                     (const char *) str1, (const char *) str2, NULL, 0, 0,
                     msg, str1, str2);
@@ -252,6 +256,7 @@
                const char *msg, const xmlChar *str1, const xmlChar *str2,
 	       const xmlChar *str3)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
 
@@ -259,11 +264,12 @@
         ctxt->nberrors++;
 	ctxt->err = error;
         channel = ctxt->error;
+        schannel = ctxt->serror;
         data = ctxt->userData;
     }
     /* reajust to global error numbers */
     error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
-    __xmlRaiseError(channel, data, ctxt, node, XML_FROM_SCHEMASV,
+    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV,
                     error, XML_ERR_ERROR, NULL, 0,
                     (const char *) str1, (const char *) str2,
 		    (const char *) str3, 0, 0,
@@ -284,6 +290,7 @@
 xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
+    xmlStructuredErrorFunc schannel = NULL;
     xmlGenericErrorFunc channel = NULL;
     void *data = NULL;
 
@@ -292,10 +299,11 @@
 	ctxt->err = error;
         channel = ctxt->error;
         data = ctxt->userData;
+        schannel = ctxt->serror;
     }
     /* reajust to global error numbers */
     error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
-    __xmlRaiseError(channel, data, ctxt, node, XML_FROM_SCHEMASV,
+    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV,
                     error, XML_ERR_ERROR, NULL, 0,
                     (const char *) str1, (const char *) str2, NULL, 0, 0,
                     msg, str1, str2);
diff --git a/xpath.c b/xpath.c
index 1775c2e..90312db 100644
--- a/xpath.c
+++ b/xpath.c
@@ -230,13 +230,13 @@
 	    ctxt->error(ctxt->userData, &ctxt->lastError);
     } else {
         if (extra)
-            __xmlRaiseError(NULL, NULL,
+            __xmlRaiseError(NULL, NULL, NULL,
                             NULL, NULL, XML_FROM_XPATH,
                             XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
                             extra, NULL, NULL, 0, 0,
                             "Memory allocation failed : %s\n", extra);
         else
-            __xmlRaiseError(NULL, NULL,
+            __xmlRaiseError(NULL, NULL, NULL,
                             NULL, NULL, XML_FROM_XPATH,
                             XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
                             NULL, NULL, NULL, 0, 0,
@@ -278,7 +278,7 @@
     if (ctxt != NULL)
         ctxt->error = error;
     if ((ctxt == NULL) || (ctxt->context == NULL)) {
-	__xmlRaiseError(NULL, NULL,
+	__xmlRaiseError(NULL, NULL, NULL,
 			NULL, NULL, XML_FROM_XPATH,
 			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
 			XML_ERR_ERROR, NULL, 0,
@@ -297,7 +297,7 @@
 	ctxt->context->error(ctxt->context->userData,
 	                     &ctxt->context->lastError);
     } else {
-	__xmlRaiseError(NULL, NULL,
+	__xmlRaiseError(NULL, NULL, NULL,
 			NULL, ctxt->context->debugNode, XML_FROM_XPATH,
 			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
 			XML_ERR_ERROR, NULL, 0,
diff --git a/xpointer.c b/xpointer.c
index 3ef5acf..e215153 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -72,7 +72,7 @@
 static void
 xmlXPtrErrMemory(const char *extra)
 {
-    __xmlRaiseError(NULL, NULL, NULL, NULL, XML_FROM_XPOINTER,
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_XPOINTER,
 		    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
 		    NULL, NULL, 0, 0,
 		    "Memory allocation failed : %s\n", extra);
@@ -92,7 +92,7 @@
     if (ctxt != NULL)
         ctxt->error = error;
     if ((ctxt == NULL) || (ctxt->context == NULL)) {
-	__xmlRaiseError(NULL, NULL,
+	__xmlRaiseError(NULL, NULL, NULL,
 			NULL, NULL, XML_FROM_XPOINTER, error,
 			XML_ERR_ERROR, NULL, 0,
 			(const char *) extra, NULL, NULL, 0, 0,
@@ -109,7 +109,7 @@
 	ctxt->context->error(ctxt->context->userData,
 	                     &ctxt->context->lastError);
     } else {
-	__xmlRaiseError(NULL, NULL,
+	__xmlRaiseError(NULL, NULL, NULL,
 			NULL, ctxt->context->debugNode, XML_FROM_XPOINTER,
 			error, XML_ERR_ERROR, NULL, 0,
 			(const char *) extra, (const char *) ctxt->base, NULL,