Index: python/generator.py =================================================================== RCS file: /cvs/gnome/gnome-xml/python/generator.py,v retrieving revision 1.33 diff -c -r1.33 generator.py *** python/generator.py 10 Jan 2003 15:21:50 -0000 1.33 --- python/generator.py 14 Jan 2003 11:38:13 -0000 *************** *** 290,295 **** --- 290,297 ---- def skip_function(name): if name[0:12] == "xmlXPathWrap": return 1 + if name == "xmlFreeParserCtxt": + return 1 # if name[0:11] == "xmlXPathNew": # return 1 return 0 *************** *** 618,623 **** --- 620,626 ---- "xmlAttribute" : "xmlNode", "outputBuffer": "ioWriteWrapper", "inputBuffer": "ioReadWrapper", + "parserCtxt": "parserCtxtCore", } classes_destructors = { "parserCtxt": "xmlFreeParserCtxt", Index: python/libxml.c =================================================================== RCS file: /cvs/gnome/gnome-xml/python/libxml.c,v retrieving revision 1.34 diff -c -r1.34 libxml.c *** python/libxml.c 10 Jan 2003 13:14:40 -0000 1.34 --- python/libxml.c 14 Jan 2003 11:38:14 -0000 *************** *** 1176,1181 **** --- 1176,1207 ---- 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 * *************** *** 1185,1197 **** static PyObject *libxml_xmlPythonErrorFuncHandler = NULL; static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL; ! static void ! libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, ! ...) { int size; int chars; char *larger; va_list ap; char *str; PyObject *list; --- 1211,1253 ---- static PyObject *libxml_xmlPythonErrorFuncHandler = NULL; static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL; ! /* helper to build a xmlMalloc'ed string from a format and va_list */ ! static char * ! libxml_buildMessage(const char *msg, va_list ap) { int size; int chars; char *larger; + char *str; + + str = (char *) xmlMalloc(150); + if (str == NULL) + return NULL; + + size = 150; + + while (1) { + chars = vsnprintf(str, size, msg, ap); + if ((chars > -1) && (chars < size)) + break; + if (chars > -1) + size += chars + 1; + else + size += 100; + if ((larger = (char *) xmlRealloc(str, size)) == NULL) { + xmlFree(str); + return NULL; + } + str = larger; + } + + return str; + } + + static void + libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, + ...) + { va_list ap; char *str; PyObject *list; *************** *** 1208,1235 **** vfprintf(stdout, msg, ap); va_end(ap); } else { ! str = (char *) xmlMalloc(150); ! if (str == NULL) ! return; ! ! size = 150; ! ! while (1) { ! va_start(ap, msg); ! chars = vsnprintf(str, size, msg, ap); ! va_end(ap); ! if ((chars > -1) && (chars < size)) ! break; ! if (chars > -1) ! size += chars + 1; ! else ! size += 100; ! if ((larger = (char *) xmlRealloc(str, size)) == NULL) { ! xmlFree(str); ! return; ! } ! str = larger; ! } list = PyTuple_New(2); PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt); --- 1264,1272 ---- 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, libxml_xmlPythonErrorFuncCtxt); *************** *** 1287,1292 **** --- 1324,1470 ---- return (py_retval); } + + /************************************************************************ + * * + * Per parserCtxt error handler * + * * + ************************************************************************/ + + static void + libxml_xmlParserCtxtErrorFuncHandler(void *ctxt, const char *msg, ...) + { + char *str; + va_list ap; + PyObject *list; + PyObject *message; + PyObject *result; + xmlParserCtxtPyCtxtPtr pyCtxt; + + #ifdef DEBUG_ERROR + printf("libxml_xmlParserCtxtErrorFuncHandler(%p, %s, ...) called\n", ctx, msg); + #endif + + pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)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); + } + } + + PyObject * + libxml_xmlSetParserCtxtErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) + { + PyObject *py_retval; + xmlParserCtxtPtr ctxt; + PyObject *pyobj_ctxt; + PyObject *pyobj_f; + PyObject *pyobj_arg; + + if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtErrorHandler", + &pyobj_ctxt, &pyobj_f, &pyobj_arg)) + return(NULL); + ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); + if (ctxt->_private == NULL) { + xmlParserCtxtPyCtxt *pyCtxt; + + pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt)); + if (pyCtxt == NULL) { + py_retval = libxml_intWrap(-1); + return(py_retval); + } + memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt)); + ctxt->_private = pyCtxt; + } + /* TODO: check f is a function ! */ + Py_XINCREF(pyobj_f); + ((xmlParserCtxtPyCtxt *)ctxt->_private)->errorFunc = pyobj_f; + Py_XINCREF(pyobj_arg); + ((xmlParserCtxtPyCtxt *)ctxt->_private)->errorFuncArg = pyobj_arg; + + ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler; + ctxt->vctxt.error = libxml_xmlParserCtxtErrorFuncHandler; + + 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) + { + PyObject *py_retval; + xmlParserCtxtPtr ctxt; + PyObject *pyobj_ctxt; + PyObject *pyobj_f; + PyObject *pyobj_arg; + + if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtWarningHandler", &pyobj_ctxt, &pyobj_f, &pyobj_arg)) + return(NULL); + ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); + /* TODO: check f is a function ! */ + Py_XINCREF(pyobj_f); + ((xmlParserCtxtPyCtxt *)ctxt->_private)->warningFunc = pyobj_f; + Py_XINCREF(pyobj_arg); + ((xmlParserCtxtPyCtxt *)ctxt->_private)->warningFuncArg = pyobj_arg; + + ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler; + ctxt->vctxt.warning = libxml_xmlParserCtxtWarningFuncHandler; + + py_retval = libxml_intWrap(1); + return(py_retval); + } + /************************************************************************ * * * XPath extensions * *************** *** 2196,2201 **** --- 2374,2382 ---- {(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 *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL }, {NULL, NULL, 0, NULL} }; Index: python/libxml.py =================================================================== RCS file: /cvs/gnome/gnome-xml/python/libxml.py,v retrieving revision 1.20 diff -c -r1.20 libxml.py *** python/libxml.py 10 Jan 2003 13:14:40 -0000 1.20 --- python/libxml.py 14 Jan 2003 11:38:15 -0000 *************** *** 478,483 **** --- 478,502 ---- ret = libxslt.registerErrorHandler(f,ctx) return ret + class parserCtxtCore: + + def __init__(self, _obj=None): + if _obj != None: + self._o = _obj; + return + self._o = None + + def __del__(self): + if self._o != None: + libxml2mod.xmlFreeParserCtxt(self._o) + self._o = None + + def registerErrorHandler(self,f,arg): + libxml2mod.xmlSetParserCtxtErrorHandler(self._o,f,arg) + + def registerWarningHandler(self,f,arg): + libxml2mod.xmlSetParserCtxtWarningHandler(self._o,f,arg) + # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # # Everything before this line comes from libxml.py Index: python/libxml2class.txt =================================================================== RCS file: /cvs/gnome/gnome-xml/python/libxml2class.txt,v retrieving revision 1.34 diff -c -r1.34 libxml2class.txt *** python/libxml2class.txt 10 Jan 2003 13:14:40 -0000 1.34 --- python/libxml2class.txt 14 Jan 2003 11:38:15 -0000 *************** *** 662,668 **** xpathTrueFunction() xpathValueFlipSign() xpatherror() ! Class parserCtxt() # accessors doc() isValid() --- 662,670 ---- xpathTrueFunction() xpathValueFlipSign() xpatherror() ! ! ! Class parserCtxt(parserCtxtCore) # accessors doc() isValid() *************** *** 682,688 **** # functions from module parser clearParserCtxt() - freeParserCtxt() initParserCtxt() parseChunk() parseDocument() --- 684,689 ---- Index: python/libxml_wrap.h =================================================================== RCS file: /cvs/gnome/gnome-xml/python/libxml_wrap.h,v retrieving revision 1.14 diff -c -r1.14 libxml_wrap.h *** python/libxml_wrap.h 27 Dec 2002 11:58:25 -0000 1.14 --- python/libxml_wrap.h 14 Jan 2003 11:38:15 -0000 *************** *** 149,151 **** --- 149,165 ---- PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader); xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj); + + /* + * Data structure that makes the link from the parser context + * to the python wrapper. + */ + typedef struct + { + PyObject *errorFunc; + PyObject *errorFuncArg; + PyObject *warningFunc; + PyObject *warningFuncArg; + } xmlParserCtxtPyCtxt; + typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr; + Index: python/types.c =================================================================== RCS file: /cvs/gnome/gnome-xml/python/types.c,v retrieving revision 1.12 diff -c -r1.12 types.c *** python/types.c 14 Dec 2002 23:00:34 -0000 1.12 --- python/types.c 14 Jan 2003 11:38:15 -0000 *************** *** 323,328 **** --- 323,329 ---- Py_INCREF(Py_None); return (Py_None); } + ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL); Index: python/tests/Makefile.am =================================================================== RCS file: /cvs/gnome/gnome-xml/python/tests/Makefile.am,v retrieving revision 1.22 diff -c -r1.22 Makefile.am *** python/tests/Makefile.am 28 Dec 2002 22:56:33 -0000 1.22 --- python/tests/Makefile.am 14 Jan 2003 11:38:15 -0000 *************** *** 22,29 **** regexp.py \ reader.py \ reader2.py \ ! reader3.py ! XMLS= \ tst.xml \ --- 22,29 ---- regexp.py \ reader.py \ reader2.py \ ! reader3.py \ ! ctxterror.py XMLS= \ tst.xml \