patch from Joachim Bauch + cleanup for Relax NG error callbacks in python

* python/generator.py python/libxml.c python/libxml2class.txt:
  patch from Joachim Bauch + cleanup for Relax NG error callbacks
  in python
Daniel
diff --git a/ChangeLog b/ChangeLog
index 05d90f9..e1ed6bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Jul 29 16:43:48 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml2class.txt:
+	  patch from Joachim Bauch + cleanup for Relax NG error callbacks
+	  in python
+
 Tue Jul 29 12:46:08 EDT 2003 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c parserInternals.c tree.c: applied Peter Jacobi encoding
diff --git a/python/generator.py b/python/generator.py
index b444443..c65728c 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -300,6 +300,9 @@
         return 1
 #    if name[0:11] == "xmlXPathNew":
 #        return 1
+    # the next function is defined in libxml.c
+    if name == "xmlRelaxNGFreeValidCtxt":
+        return 1
     return 0
 
 def print_function_wrapper(name, output, export, include):
diff --git a/python/libxml.c b/python/libxml.c
index e372835..ea0aed7 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -58,10 +58,12 @@
  *									*
  ************************************************************************/
 
+#if 0
 extern void xmlMemFree(void *ptr);
 extern void *xmlMemMalloc(size_t size);
 extern void *xmlMemRealloc(void *ptr, size_t size);
 extern char *xmlMemoryStrdup(const char *str);
+#endif
 
 static int libxmlMemoryDebugActivated = 0;
 static long libxmlMemoryAllocatedBase = 0;
@@ -467,7 +469,7 @@
 	    if (result == NULL) {
 		Py_DECREF(ret);
 	    } else if (URL != NULL) {
-		result->filename = xmlStrdup(URL);
+		result->filename = xmlStrdup((const xmlChar *)URL);
 		result->directory = xmlParserGetDirectory((const char *) URL);
 	    }
 	}
@@ -1270,7 +1272,7 @@
     xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
                                PyObject * args)
 {
@@ -1392,7 +1394,7 @@
     va_end(ap);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) 
 {
     PyObject *py_retval;
@@ -1443,7 +1445,7 @@
     return(py_retval);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) 
 {
     PyObject *py_retval;
@@ -1474,7 +1476,7 @@
     return(py_retval);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
     xmlParserCtxtPtr ctxt;
     PyObject *pyobj_ctxt;
@@ -1537,7 +1539,7 @@
     Py_XDECREF(result);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
 {
     xmlTextReaderPtr reader;
@@ -1555,7 +1557,7 @@
     /* clear previous error handler */
     xmlTextReaderGetErrorHandler(reader,&f,&arg);
     if (arg != NULL) {
-	if (f == libxml_xmlTextReaderErrorCallback) {
+	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
 	    /* ok, it's our error handler! */
 	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
 	    Py_XDECREF(pyCtxt->f);
@@ -1585,14 +1587,16 @@
 	pyCtxt->f = pyobj_f;
 	Py_XINCREF(pyobj_arg);
 	pyCtxt->arg = pyobj_arg;
-	xmlTextReaderSetErrorHandler(reader,libxml_xmlTextReaderErrorCallback,pyCtxt);
+	xmlTextReaderSetErrorHandler(reader,
+	    (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback,
+	                             pyCtxt);
     }
 
     py_retval = libxml_intWrap(1);
     return(py_retval);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
 {
     xmlTextReaderPtr reader;
@@ -1607,7 +1611,7 @@
     reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
     xmlTextReaderGetErrorHandler(reader,&f,&arg);
     py_retval = PyTuple_New(2);
-    if (f == libxml_xmlTextReaderErrorCallback) {
+    if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
 	/* ok, it's our error handler! */
 	pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
 	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
@@ -1626,7 +1630,7 @@
     return(py_retval);
 }
 
-PyObject *
+static PyObject *
 libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
     xmlTextReaderPtr reader;
     PyObject *pyobj_reader;
@@ -1640,7 +1644,7 @@
 
     xmlTextReaderGetErrorHandler(reader,&f,&arg);
     if (arg != NULL) {
-	if (f == libxml_xmlTextReaderErrorCallback) {
+	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
 	    /* ok, it's our error handler! */
 	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
 	    Py_XDECREF(pyCtxt->f);
@@ -2576,6 +2580,180 @@
     return (Py_None);
 }
 
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+/************************************************************************
+ *                                                                      *
+ * RelaxNG error handler registration                                   *
+ *                                                                      *
+ ************************************************************************/
+
+typedef struct 
+{
+    PyObject *warn;
+    PyObject *error;
+    PyObject *arg;
+} xmlRelaxNGValidCtxtPyCtxt;
+typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
+
+static void
+libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str) 
+{
+    PyObject *list;
+    PyObject *result;
+    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
+    
+#ifdef DEBUG_ERROR
+    printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
+#endif
+
+    pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
+
+    list = PyTuple_New(2);
+    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
+    PyTuple_SetItem(list, 1, pyCtxt->arg);
+    Py_XINCREF(pyCtxt->arg);
+    result = PyEval_CallObject(pyCtxt->error, list);
+    if (result == NULL) 
+    {
+        /* TODO: manage for the exception to be propagated... */
+        PyErr_Print();
+    }
+    Py_XDECREF(list);
+    Py_XDECREF(result);
+}
+
+static void
+libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str) 
+{
+    PyObject *list;
+    PyObject *result;
+    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
+    
+#ifdef DEBUG_ERROR
+    printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
+#endif
+
+    pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
+
+    list = PyTuple_New(2);
+    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
+    PyTuple_SetItem(list, 1, pyCtxt->arg);
+    Py_XINCREF(pyCtxt->arg);
+    result = PyEval_CallObject(pyCtxt->warn, list);
+    if (result == NULL) 
+    {
+        /* TODO: manage for the exception to be propagated... */
+        PyErr_Print();
+    }
+    Py_XDECREF(list);
+    Py_XDECREF(result);
+}
+
+static void
+libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
+{
+    va_list ap;
+
+    va_start(ap, msg);
+    libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
+    va_end(ap);
+}
+
+static void
+libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
+{
+    va_list ap;
+
+    va_start(ap, msg);
+    libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
+    va_end(ap);
+}
+
+static PyObject *
+libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
+{
+    PyObject *py_retval;
+    PyObject *pyobj_error;
+    PyObject *pyobj_warn;
+    PyObject *pyobj_ctx;
+    PyObject *pyobj_arg = Py_None;
+    xmlRelaxNGValidCtxtPtr ctxt;
+    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
+
+    if (!PyArg_ParseTuple
+        (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
+        return (NULL);
+
+#ifdef DEBUG_ERROR
+    printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
+#endif
+
+    ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
+    if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, &pyCtxt) == -1)
+    {
+        py_retval = libxml_intWrap(-1);
+        return(py_retval);
+    }
+    
+    if (pyCtxt == NULL)
+    {
+        /* first time to set the error handlers */
+        pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
+        if (pyCtxt == NULL) {
+            py_retval = libxml_intWrap(-1);
+            return(py_retval);
+        }
+        memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
+    }
+    
+    /* TODO: check warn and error is a function ! */
+    Py_XDECREF(pyCtxt->error);
+    Py_XINCREF(pyobj_error);
+    pyCtxt->error = pyobj_error;
+    
+    Py_XDECREF(pyCtxt->warn);
+    Py_XINCREF(pyobj_warn);
+    pyCtxt->warn = pyobj_warn;
+    
+    Py_XDECREF(pyCtxt->arg);
+    Py_XINCREF(pyobj_arg);
+    pyCtxt->arg = pyobj_arg;
+
+    xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
+
+    py_retval = libxml_intWrap(1);
+    return (py_retval);
+}
+
+static PyObject *
+libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
+    xmlRelaxNGValidCtxtPtr ctxt;
+    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
+    PyObject *pyobj_ctxt;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
+        return(NULL);
+    ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
+
+    if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, &pyCtxt) == 0)
+    {
+        if (pyCtxt != NULL)
+        {
+            Py_XDECREF(pyCtxt->error);
+            Py_XDECREF(pyCtxt->warn);
+            Py_XDECREF(pyCtxt->arg);
+            xmlFree(pyCtxt);
+        }
+    }
+    
+    xmlRelaxNGFreeValidCtxt(ctxt);
+    Py_INCREF(Py_None);
+    return(Py_None);
+}
+
+#endif
+
 /************************************************************************
  *									*
  *			The registration stuff				*
@@ -2606,6 +2784,10 @@
     {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
     {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
     {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
+#ifdef LIBXML_SCHEMAS_ENABLED
+    {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
+    {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
+#endif
     {NULL, NULL, 0, NULL}
 };
 
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index b33c873..f7ae984 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -705,7 +705,6 @@
 Class relaxNgValidCtxt()
 
     # functions from module relaxng
-    relaxNGFreeValidCtxt()
     relaxNGValidateDoc()
     relaxNGValidateFullElement()
     relaxNGValidatePopElement()