From 63529e1ec3600dfe4c8df6f81444a0d3f9f0ba7e Mon Sep 17 00:00:00 2001 From: Tomas Mlcoch Date: Fri, 31 May 2013 21:55:05 +0200 Subject: [PATCH] python: xml_parsers now store reference to a pkg object while parsing to the object --- src/python/xml_parser-py.c | 157 ++++++++++++++++++++++++++++----------------- 1 file changed, 99 insertions(+), 58 deletions(-) diff --git a/src/python/xml_parser-py.c b/src/python/xml_parser-py.c index c4f6f5c..97d52e5 100644 --- a/src/python/xml_parser-py.c +++ b/src/python/xml_parser-py.c @@ -28,6 +28,13 @@ #include "package-py.h" #include "exception-py.h" +typedef struct { + PyObject *py_newpkgcb; + PyObject *py_pkgcb; + PyObject *py_warningcb; + PyObject *py_pkg; /*!< Current processed package */ +} CbData; + static int c_newpkgcb(cr_Package **pkg, const char *pkgId, @@ -37,9 +44,16 @@ c_newpkgcb(cr_Package **pkg, GError **err) { PyObject *arglist, *result; + CbData *data = cbdata; + + if (data->py_pkg) { + // Decref ref count on previous processed package + Py_DECREF(data->py_pkg); + data->py_pkg = NULL; + } arglist = Py_BuildValue("(sss)", pkgId, name, arch); - result = PyObject_CallObject(cbdata, arglist); + result = PyObject_CallObject(data->py_newpkgcb, arglist); Py_DECREF(arglist); if (result == NULL) { @@ -51,12 +65,13 @@ c_newpkgcb(cr_Package **pkg, if (!PackageObject_Check(result) && result != Py_None) { PyErr_SetString(PyExc_TypeError, "Expected a cr_Package or None as a callback return value"); + Py_DECREF(result); return CR_CB_RET_ERR; } *pkg = Package_FromPyObject(result); + data->py_pkg = result; // Store reference to current package - Py_DECREF(result); return CR_CB_RET_OK; } @@ -66,10 +81,17 @@ c_pkgcb(cr_Package *pkg, GError **err) { PyObject *result; + CbData *data = cbdata; CR_UNUSED(pkg); - result = PyObject_CallObject(cbdata, NULL); + if (data->py_pkg) { + // Decref ref count on processed package + Py_DECREF(data->py_pkg); + data->py_pkg = NULL; + } + + result = PyObject_CallObject(data->py_pkgcb, NULL); if (result == NULL) { // Exception raised @@ -88,9 +110,10 @@ c_warningcb(cr_XmlParserWarningType type, GError **err) { PyObject *arglist, *result; + CbData *data = cbdata; arglist = Py_BuildValue("(is)", type, msg); - result = PyObject_CallObject(cbdata, arglist); + result = PyObject_CallObject(data->py_warningcb, arglist); Py_DECREF(arglist); if (result == NULL) { @@ -110,58 +133,64 @@ py_xml_parse_primary(PyObject *self, PyObject *args) char *filename; int do_files; - PyObject *newpkgcb, *pkgcb, *warningcb; + PyObject *py_newpkgcb, *py_pkgcb, *py_warningcb; + CbData cbdata; GError *tmp_err = NULL; if (!PyArg_ParseTuple(args, "sOOOi:py_xml_parse_primary", &filename, - &newpkgcb, - &pkgcb, - &warningcb, + &py_newpkgcb, + &py_pkgcb, + &py_warningcb, &do_files)) { return NULL; } - if (!PyCallable_Check(newpkgcb)) { + if (!PyCallable_Check(py_newpkgcb)) { PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable"); return NULL; } - if (!PyCallable_Check(pkgcb) && pkgcb != Py_None) { + if (!PyCallable_Check(py_pkgcb) && py_pkgcb != Py_None) { PyErr_SetString(PyExc_TypeError, "pkgcb must be callable or None"); return NULL; } - if (!PyCallable_Check(warningcb) && warningcb != Py_None) { + if (!PyCallable_Check(py_warningcb) && py_warningcb != Py_None) { PyErr_SetString(PyExc_TypeError, "warningcb must be callable or None"); return NULL; } - Py_XINCREF(newpkgcb); - Py_XINCREF(pkgcb); - Py_XINCREF(warningcb); + Py_XINCREF(py_newpkgcb); + Py_XINCREF(py_pkgcb); + Py_XINCREF(py_warningcb); cr_XmlParserPkgCb ptr_c_pkgcb = NULL; cr_XmlParserWarningCb ptr_c_warningcb = NULL; - if (pkgcb != Py_None) + if (py_pkgcb != Py_None) ptr_c_pkgcb = c_pkgcb; - if (warningcb != Py_None) + if (py_warningcb != Py_None) ptr_c_warningcb = c_warningcb; + cbdata.py_newpkgcb = py_newpkgcb; + cbdata.py_pkgcb = py_pkgcb; + cbdata.py_warningcb = py_warningcb; + cbdata.py_pkg = NULL; + cr_xml_parse_primary(filename, c_newpkgcb, - newpkgcb, + &cbdata, ptr_c_pkgcb, - pkgcb, + &cbdata, ptr_c_warningcb, - warningcb, + &cbdata, do_files, &tmp_err); - Py_XDECREF(newpkgcb); - Py_XDECREF(pkgcb); - Py_XDECREF(warningcb); + Py_XDECREF(py_newpkgcb); + Py_XDECREF(py_pkgcb); + Py_XDECREF(py_warningcb); if (tmp_err) { PyErr_Format(CrErr_Exception, "%s", tmp_err->message); @@ -178,56 +207,62 @@ py_xml_parse_filelists(PyObject *self, PyObject *args) CR_UNUSED(self); char *filename; - PyObject *newpkgcb, *pkgcb, *warningcb; + PyObject *py_newpkgcb, *py_pkgcb, *py_warningcb; + CbData cbdata; GError *tmp_err = NULL; if (!PyArg_ParseTuple(args, "sOOO:py_xml_parse_filelists", &filename, - &newpkgcb, - &pkgcb, - &warningcb)) { + &py_newpkgcb, + &py_pkgcb, + &py_warningcb)) { return NULL; } - if (!PyCallable_Check(newpkgcb)) { + if (!PyCallable_Check(py_newpkgcb)) { PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable"); return NULL; } - if (!PyCallable_Check(pkgcb) && pkgcb != Py_None) { + if (!PyCallable_Check(py_pkgcb) && py_pkgcb != Py_None) { PyErr_SetString(PyExc_TypeError, "pkgcb must be callable or None"); return NULL; } - if (!PyCallable_Check(warningcb) && warningcb != Py_None) { + if (!PyCallable_Check(py_warningcb) && py_warningcb != Py_None) { PyErr_SetString(PyExc_TypeError, "warningcb must be callable or None"); return NULL; } - Py_XINCREF(newpkgcb); - Py_XINCREF(pkgcb); - Py_XINCREF(warningcb); + Py_XINCREF(py_newpkgcb); + Py_XINCREF(py_pkgcb); + Py_XINCREF(py_warningcb); cr_XmlParserPkgCb ptr_c_pkgcb = NULL; cr_XmlParserWarningCb ptr_c_warningcb = NULL; - if (pkgcb != Py_None) + if (py_pkgcb != Py_None) ptr_c_pkgcb = c_pkgcb; - if (warningcb != Py_None) + if (py_warningcb != Py_None) ptr_c_warningcb = c_warningcb; + cbdata.py_newpkgcb = py_newpkgcb; + cbdata.py_pkgcb = py_pkgcb; + cbdata.py_warningcb = py_warningcb; + cbdata.py_pkg = NULL; + cr_xml_parse_filelists(filename, c_newpkgcb, - newpkgcb, + &cbdata, ptr_c_pkgcb, - pkgcb, + &cbdata, ptr_c_warningcb, - warningcb, + &cbdata, &tmp_err); - Py_XDECREF(newpkgcb); - Py_XDECREF(pkgcb); - Py_XDECREF(warningcb); + Py_XDECREF(py_newpkgcb); + Py_XDECREF(py_pkgcb); + Py_XDECREF(py_warningcb); if (tmp_err) { PyErr_Format(CrErr_Exception, "%s", tmp_err->message); @@ -244,56 +279,62 @@ py_xml_parse_other(PyObject *self, PyObject *args) CR_UNUSED(self); char *filename; - PyObject *newpkgcb, *pkgcb, *warningcb; + PyObject *py_newpkgcb, *py_pkgcb, *py_warningcb; + CbData cbdata; GError *tmp_err = NULL; if (!PyArg_ParseTuple(args, "sOOO:py_xml_parse_other", &filename, - &newpkgcb, - &pkgcb, - &warningcb)) { + &py_newpkgcb, + &py_pkgcb, + &py_warningcb)) { return NULL; } - if (!PyCallable_Check(newpkgcb)) { + if (!PyCallable_Check(py_newpkgcb)) { PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable"); return NULL; } - if (!PyCallable_Check(pkgcb) && pkgcb != Py_None) { + if (!PyCallable_Check(py_pkgcb) && py_pkgcb != Py_None) { PyErr_SetString(PyExc_TypeError, "pkgcb must be callable or None"); return NULL; } - if (!PyCallable_Check(warningcb) && warningcb != Py_None) { + if (!PyCallable_Check(py_warningcb) && py_warningcb != Py_None) { PyErr_SetString(PyExc_TypeError, "warningcb must be callable or None"); return NULL; } - Py_XINCREF(newpkgcb); - Py_XINCREF(pkgcb); - Py_XINCREF(warningcb); + Py_XINCREF(py_newpkgcb); + Py_XINCREF(py_pkgcb); + Py_XINCREF(py_warningcb); cr_XmlParserPkgCb ptr_c_pkgcb = NULL; cr_XmlParserWarningCb ptr_c_warningcb = NULL; - if (pkgcb != Py_None) + if (py_pkgcb != Py_None) ptr_c_pkgcb = c_pkgcb; - if (warningcb != Py_None) + if (py_warningcb != Py_None) ptr_c_warningcb = c_warningcb; + cbdata.py_newpkgcb = py_newpkgcb; + cbdata.py_pkgcb = py_pkgcb; + cbdata.py_warningcb = py_warningcb; + cbdata.py_pkg = NULL; + cr_xml_parse_other(filename, c_newpkgcb, - newpkgcb, + &cbdata, ptr_c_pkgcb, - pkgcb, + &cbdata, ptr_c_warningcb, - warningcb, + &cbdata, &tmp_err); - Py_XDECREF(newpkgcb); - Py_XDECREF(pkgcb); - Py_XDECREF(warningcb); + Py_XDECREF(py_newpkgcb); + Py_XDECREF(py_pkgcb); + Py_XDECREF(py_warningcb); if (tmp_err) { PyErr_Format(CrErr_Exception, "%s", tmp_err->message); -- 2.7.4