patch from Stéphane Bidoul for better per context error message APIs
* xmlreader.c python/drv_libxml2.py python/generator.py
python/libxml.c python/libxml.py python/libxml_wrap.h
python/types.c: patch from Stéphane Bidoul for better per
context error message APIs
* python/tests/ctxterror.py python/tests/readererr.py:
update of the tests
Daniel
diff --git a/python/libxml.c b/python/libxml.c
index a762ac7..0603950 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -1177,32 +1177,6 @@
return (Py_None);
}
-PyObject *
-libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
- xmlParserCtxtPtr ctxt;
- PyObject *pyobj_ctxt;
- xmlParserCtxtPyCtxtPtr pyCtxt;
-
- if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
- return(NULL);
- ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
-
- if (ctxt != NULL) {
- pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
- if (pyCtxt) {
- Py_XDECREF(pyCtxt->errorFunc);
- Py_XDECREF(pyCtxt->errorFuncArg);
- Py_XDECREF(pyCtxt->warningFunc);
- Py_XDECREF(pyCtxt->warningFuncArg);
- xmlFree(pyCtxt);
- }
- xmlFreeParserCtxt(ctxt);
- }
-
- Py_INCREF(Py_None);
- return(Py_None);
-}
-
/************************************************************************
* *
* Error message callback *
@@ -1332,44 +1306,87 @@
* *
************************************************************************/
-static void
-libxml_xmlParserCtxtErrorFuncHandler(void *ctxt, const char *msg, ...)
+typedef struct
{
- char *str;
- va_list ap;
+ PyObject *f;
+ PyObject *arg;
+} xmlParserCtxtPyCtxt;
+typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
+
+static void
+libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
+{
PyObject *list;
- PyObject *message;
PyObject *result;
+ xmlParserCtxtPtr ctxt;
xmlParserCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR
- printf("libxml_xmlParserCtxtErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
+ printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
#endif
- pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
+ ctxt = (xmlParserCtxtPtr)ctx;
+ pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
- if (pyCtxt->errorFunc == NULL) {
- va_start(ap, msg);
- vfprintf(stdout, msg, ap);
- va_end(ap);
- } else {
- va_start(ap, msg);
- str = libxml_buildMessage(msg,ap);
- va_end(ap);
-
- list = PyTuple_New(2);
- PyTuple_SetItem(list, 0, pyCtxt->errorFuncArg);
- Py_XINCREF(pyCtxt->errorFuncArg);
- message = libxml_charPtrWrap(str);
- PyTuple_SetItem(list, 1, message);
- result = PyEval_CallObject(pyCtxt->errorFunc, list);
- Py_XDECREF(list);
- Py_XDECREF(result);
+ list = PyTuple_New(4);
+ PyTuple_SetItem(list, 0, pyCtxt->arg);
+ Py_XINCREF(pyCtxt->arg);
+ PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
+ PyTuple_SetItem(list, 2, libxml_intWrap(severity));
+ PyTuple_SetItem(list, 3, Py_None);
+ Py_INCREF(Py_None);
+ result = PyEval_CallObject(pyCtxt->f, list);
+ if (result == NULL)
+ {
+ /* TODO: manage for the exception to be propagated... */
+ PyErr_Print();
}
+ Py_XDECREF(list);
+ Py_XDECREF(result);
+}
+
+static void
+libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
+ va_end(ap);
+}
+
+static void
+libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
+ va_end(ap);
+}
+
+static void
+libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
+ va_end(ap);
+}
+
+static void
+libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
+ va_end(ap);
}
PyObject *
-libxml_xmlSetParserCtxtErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
+libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
{
PyObject *py_retval;
xmlParserCtxtPtr ctxt;
@@ -1378,7 +1395,7 @@
PyObject *pyobj_f;
PyObject *pyobj_arg;
- if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtErrorHandler",
+ if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
&pyobj_ctxt, &pyobj_f, &pyobj_arg))
return(NULL);
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
@@ -1392,99 +1409,88 @@
ctxt->_private = pyCtxt;
}
else {
- pyCtxt = ctxt->_private;
+ pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
}
/* TODO: check f is a function ! */
- Py_XDECREF(pyCtxt->errorFunc);
+ Py_XDECREF(pyCtxt->f);
Py_XINCREF(pyobj_f);
- pyCtxt->errorFunc = pyobj_f;
- Py_XDECREF(pyCtxt->errorFuncArg);
+ pyCtxt->f = pyobj_f;
+ Py_XDECREF(pyCtxt->arg);
Py_XINCREF(pyobj_arg);
- pyCtxt->errorFuncArg = pyobj_arg;
+ pyCtxt->arg = pyobj_arg;
- ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
- ctxt->vctxt.error = libxml_xmlParserCtxtErrorFuncHandler;
+ if (pyobj_f != Py_None) {
+ ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
+ ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
+ ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
+ ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
+ }
+ else {
+ ctxt->sax->error = xmlParserError;
+ ctxt->vctxt.error = xmlParserValidityError;
+ ctxt->sax->warning = xmlParserWarning;
+ ctxt->vctxt.warning = xmlParserValidityWarning;
+ }
py_retval = libxml_intWrap(1);
return(py_retval);
}
-static void
-libxml_xmlParserCtxtWarningFuncHandler(void *ctxt, const char *msg, ...)
-{
- char *str;
- va_list ap;
- PyObject *list;
- PyObject *message;
- PyObject *result;
- xmlParserCtxtPyCtxtPtr pyCtxt;
-
-#ifdef DEBUG_ERROR
- printf("libxml_xmlParserCtxtWarningFuncHandler(%p, %s, ...) called\n", ctx, msg);
-#endif
-
- pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
-
- if (pyCtxt->warningFunc == NULL) {
- va_start(ap, msg);
- vfprintf(stdout, msg, ap);
- va_end(ap);
- } else {
- va_start(ap, msg);
- str = libxml_buildMessage(msg,ap);
- va_end(ap);
-
- list = PyTuple_New(2);
- PyTuple_SetItem(list, 0, pyCtxt->warningFuncArg);
- Py_XINCREF(pyCtxt->warningFuncArg);
- message = libxml_charPtrWrap(str);
- PyTuple_SetItem(list, 1, message);
- result = PyEval_CallObject(pyCtxt->warningFunc, list);
- Py_XDECREF(list);
- Py_XDECREF(result);
- }
-}
-
PyObject *
-libxml_xmlSetParserCtxtWarningHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
+libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
{
PyObject *py_retval;
xmlParserCtxtPtr ctxt;
xmlParserCtxtPyCtxtPtr pyCtxt;
PyObject *pyobj_ctxt;
- PyObject *pyobj_f;
- PyObject *pyobj_arg;
- if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtWarningHandler", &pyobj_ctxt, &pyobj_f, &pyobj_arg))
+ if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
+ &pyobj_ctxt))
return(NULL);
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
- if (ctxt->_private == NULL) {
- pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
- if (pyCtxt == NULL) {
- py_retval = libxml_intWrap(-1);
- return(py_retval);
- }
- memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
- ctxt->_private = pyCtxt;
+ py_retval = PyTuple_New(2);
+ if (ctxt->_private != NULL) {
+ pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
+
+ PyTuple_SetItem(py_retval, 0, pyCtxt->f);
+ Py_XINCREF(pyCtxt->f);
+ PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
+ Py_XINCREF(pyCtxt->arg);
}
else {
- pyCtxt = ctxt->_private;
+ /* no python error handler registered */
+ PyTuple_SetItem(py_retval, 0, Py_None);
+ Py_XINCREF(Py_None);
+ PyTuple_SetItem(py_retval, 1, Py_None);
+ Py_XINCREF(Py_None);
}
- /* TODO: check f is a function ! */
- Py_XDECREF(pyCtxt->warningFunc);
- Py_XINCREF(pyobj_f);
- pyCtxt->warningFunc = pyobj_f;
- Py_XDECREF(pyCtxt->warningFuncArg);
- Py_XINCREF(pyobj_arg);
- pyCtxt->warningFuncArg = pyobj_arg;
-
- ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
- ctxt->vctxt.warning = libxml_xmlParserCtxtWarningFuncHandler;
-
- py_retval = libxml_intWrap(1);
return(py_retval);
}
+PyObject *
+libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
+ xmlParserCtxtPtr ctxt;
+ PyObject *pyobj_ctxt;
+ xmlParserCtxtPyCtxtPtr pyCtxt;
+
+ if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
+ return(NULL);
+ ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
+
+ if (ctxt != NULL) {
+ pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
+ if (pyCtxt) {
+ Py_XDECREF(pyCtxt->f);
+ Py_XDECREF(pyCtxt->arg);
+ xmlFree(pyCtxt);
+ }
+ xmlFreeParserCtxt(ctxt);
+ }
+
+ Py_INCREF(Py_None);
+ return(Py_None);
+}
+
/************************************************************************
* *
* Per xmlTextReader error handler *
@@ -1501,27 +1507,23 @@
static void
libxml_xmlTextReaderErrorCallback(void *arg,
const char *msg,
- int line,
- int col,
- const char *URI,
- int severity)
+ int severity,
+ xmlTextReaderLocatorPtr locator)
{
xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
PyObject *list;
PyObject *result;
- list = PyTuple_New(6);
+ list = PyTuple_New(4);
PyTuple_SetItem(list, 0, pyCtxt->arg);
Py_XINCREF(pyCtxt->arg);
PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
- PyTuple_SetItem(list, 2, libxml_intWrap(line));
- PyTuple_SetItem(list, 3, libxml_intWrap(col));
- PyTuple_SetItem(list, 4, libxml_charPtrConstWrap(URI));
- PyTuple_SetItem(list, 5, libxml_intWrap(severity));
+ PyTuple_SetItem(list, 2, libxml_intWrap(severity));
+ PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
result = PyEval_CallObject(pyCtxt->f, list);
if (result == NULL)
{
- /* TODO: manage for the exception to be go up... */
+ /* TODO: manage for the exception to be propagated... */
PyErr_Print();
}
Py_XDECREF(list);
@@ -2558,8 +2560,8 @@
{(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
{(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
{(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
- {(char *)"xmlSetParserCtxtErrorHandler", libxml_xmlSetParserCtxtErrorHandler, METH_VARARGS, NULL },
- {(char *)"xmlSetParserCtxtWarningHandler", libxml_xmlSetParserCtxtWarningHandler, METH_VARARGS, NULL },
+ {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
+ {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
{(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
{(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
{(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },