diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-12-16 13:15:37 +0100 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-12-16 13:15:37 +0100 |
commit | 93d5d8a317ec9294bbd6dcc6bd8baec0c2b63b1b (patch) | |
tree | 3f81e8ba74efd5510bef5b8f8fdba36c00d4ae9c | |
parent | 75ead03a87172bc3a60ab5628a9c78e01f74ad03 (diff) | |
download | abrt-93d5d8a317ec9294bbd6dcc6bd8baec0c2b63b1b.tar.gz abrt-93d5d8a317ec9294bbd6dcc6bd8baec0c2b63b1b.tar.xz abrt-93d5d8a317ec9294bbd6dcc6bd8baec0c2b63b1b.zip |
report-python/run_event.c: python wrappers for run_event.h API
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r-- | src/report-python/Makefile.am | 1 | ||||
-rw-r--r-- | src/report-python/common.h | 1 | ||||
-rw-r--r-- | src/report-python/reportmodule.c | 13 | ||||
-rw-r--r-- | src/report-python/run_event.c | 203 | ||||
-rwxr-xr-x | src/report-python/test_run_event_state | 13 | ||||
-rwxr-xr-x | src/report-python/test_run_event_state1 | 27 |
6 files changed, 255 insertions, 3 deletions
diff --git a/src/report-python/Makefile.am b/src/report-python/Makefile.am index 650ae45b..1c4d55ec 100644 --- a/src/report-python/Makefile.am +++ b/src/report-python/Makefile.am @@ -8,6 +8,7 @@ _pyreport_la_SOURCES = \ reportmodule.c \ crash_dump.c \ dump_dir.c \ + run_event.c \ common.h _pyreport_la_CPPFLAGS = \ -I$(srcdir)/../include/report -I$(srcdir)/../include \ diff --git a/src/report-python/common.h b/src/report-python/common.h index f0e8727a..99c311cd 100644 --- a/src/report-python/common.h +++ b/src/report-python/common.h @@ -24,6 +24,7 @@ extern PyObject *ReportError; /* type objects */ extern PyTypeObject p_crash_data_type; extern PyTypeObject p_dump_dir_type; +extern PyTypeObject p_run_event_state_type; /* module-level functions */ PyObject *p_dd_opendir(PyObject *module, PyObject *args); diff --git a/src/report-python/reportmodule.c b/src/report-python/reportmodule.c index 4d38eeab..db9f52d9 100644 --- a/src/report-python/reportmodule.c +++ b/src/report-python/reportmodule.c @@ -34,8 +34,6 @@ static PyMethodDef module_methods[] = { PyMODINIT_FUNC init_pyreport(void) { - PyObject* m; - if (PyType_Ready(&p_crash_data_type) < 0) { printf("PyType_Ready(&p_crash_data_type) < 0\n"); @@ -46,8 +44,13 @@ init_pyreport(void) printf("PyType_Ready(&p_dump_dir_type) < 0\n"); return; } + if (PyType_Ready(&p_run_event_state_type) < 0) + { + printf("PyType_Ready(&p_run_event_state_type) < 0\n"); + return; + } - m = Py_InitModule("_pyreport", module_methods); + PyObject *m = Py_InitModule("_pyreport", module_methods); //m = Py_InitModule3("_pyreport", module_methods, "Python wrapper for libreport"); if (!m) { @@ -60,9 +63,13 @@ init_pyreport(void) Py_INCREF(ReportError); PyModule_AddObject(m, "error", ReportError); + /* init type objects */ Py_INCREF(&p_crash_data_type); PyModule_AddObject(m, "crash_data", (PyObject *)&p_crash_data_type); Py_INCREF(&p_dump_dir_type); PyModule_AddObject(m, "dump_dir", (PyObject *)&p_dump_dir_type); + + Py_INCREF(&p_run_event_state_type); + PyModule_AddObject(m, "run_event_state", (PyObject *)&p_run_event_state_type); } diff --git a/src/report-python/run_event.c b/src/report-python/run_event.c new file mode 100644 index 00000000..8923fd7c --- /dev/null +++ b/src/report-python/run_event.c @@ -0,0 +1,203 @@ +/* + Copyright (C) 2010 Abrt team. + Copyright (C) 2010 RedHat inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include <Python.h> +#include <structmember.h> + +#include <errno.h> +#include "run_event.h" +#include "common.h" + +typedef struct { + PyObject_HEAD + struct run_event_state *state; + PyObject *post_run_callback; + PyObject *logging_callback; +} p_run_event_state; + + +/*** initialization/freeing code ***/ + +static int post_run_callback(const char *dump_dir_name, void *param); +static char *logging_callback(char *log_line, void *param); + +static PyObject *p_run_event_state_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + p_run_event_state *self = (p_run_event_state *)type->tp_alloc(type, 0); + if (self) + { + self->state = new_run_event_state(); + self->state->post_run_callback = post_run_callback; + self->state->logging_callback = logging_callback; + self->state->post_run_param = self; + self->state->logging_param = self; + } + return (PyObject *)self; +} + +static void p_run_event_state_dealloc(PyObject *pself) +{ + p_run_event_state *self = (p_run_event_state*)pself; + free_run_event_state(self->state); + self->state = NULL; + Py_XDECREF(self->post_run_callback); + self->post_run_callback = NULL; + Py_XDECREF(self->logging_callback); + self->logging_callback = NULL; + self->ob_type->tp_free(pself); +} + +//static int +//p_run_event_state_init(PyObject *pself, PyObject *args, PyObject *kwds) +//{ +// return 0; +//} + + +/*** methods ***/ + +/* First, C-level callback helpers for run_event(): */ +static int post_run_callback(const char *dump_dir_name, void *param) +{ + PyObject *obj = (PyObject*)param; + PyObject *ret = PyObject_CallMethod(obj, "post_run_callback", "(s)", dump_dir_name); + int r = 0; + if (ret) + { + r = PyInt_AsLong(ret); + Py_DECREF(ret); + } + // TODO: handle exceptions: if (PyErr_Occurred()) ... + return r; +} +static char *logging_callback(char *log_line, void *param) +{ + PyObject *obj = (PyObject*)param; + PyObject *ret = PyObject_CallMethod(obj, "logging_callback", "(s)", log_line); + Py_XDECREF(ret); + // TODO: handle exceptions: if (PyErr_Occurred()) ... + return log_line; /* signaling to caller that we didnt consume the string */ +} + +/* int run_event(struct run_event_state *state, const char *dump_dir_name, const char *event); */ +static PyObject *p_run_event(PyObject *pself, PyObject *args) +{ + p_run_event_state *self = (p_run_event_state*)pself; + const char *dump_dir_name; + const char *event; + if (!PyArg_ParseTuple(args, "ss", &dump_dir_name, &event)) + { + return NULL; + } + int r = run_event(self->state, dump_dir_name, event); + PyObject *obj = Py_BuildValue("i", r); + return obj; +} + +/* TODO: char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx); */ + + +/*** attribute getters/setters ***/ + +static PyObject *get_post_run_callback(PyObject *pself, void *unused) +{ + p_run_event_state *self = (p_run_event_state*)pself; + if (self->post_run_callback) + { + Py_INCREF(self->post_run_callback); + return self->post_run_callback; + } + Py_RETURN_NONE; +} + +static PyObject *get_logging_callback(PyObject *pself, void *unused) +{ + p_run_event_state *self = (p_run_event_state*)pself; + if (self->logging_callback) + { + Py_INCREF(self->logging_callback); + return self->logging_callback; + } + Py_RETURN_NONE; +} + +static int set_post_run_callback(PyObject *pself, PyObject *callback, void *unused) +{ + p_run_event_state *self = (p_run_event_state*)pself; +//WRONG: we aren't a Python function, calling convention is different +// PyObject *callback; +// if (!PyArg_ParseTuple(args, "O", &callback)) +// return -1; + if (!PyCallable_Check(callback)) + { + PyErr_SetString(PyExc_TypeError, "parameter must be callable"); + return -1; + } + Py_INCREF(callback); + Py_XDECREF(self->post_run_callback); + self->post_run_callback = callback; + return 0; +} + +static int set_logging_callback(PyObject *pself, PyObject *callback, void *unused) +{ + p_run_event_state *self = (p_run_event_state*)pself; + if (!PyCallable_Check(callback)) + { + PyErr_SetString(PyExc_TypeError, "parameter must be callable"); + return -1; + } + Py_INCREF(callback); + Py_XDECREF(self->logging_callback); + self->logging_callback = callback; + return 0; +} + + +/*** type object ***/ + +//static PyMemberDef p_run_event_state_members[] = { +// { NULL } +//}; + +static PyMethodDef p_run_event_state_methods[] = { + /* method_name, func, flags, doc_string */ + { "run_event", p_run_event, METH_VARARGS }, + { NULL } +}; + +static PyGetSetDef p_run_event_state_getset[] = { + /* attr_name, getter_func, setter_func, doc_string, void_param */ + { "post_run_callback", get_post_run_callback, set_post_run_callback }, + { "logging_callback" , get_logging_callback , set_logging_callback }, + { NULL } +}; + +PyTypeObject p_run_event_state_type = { + PyObject_HEAD_INIT(NULL) + .tp_name = "report.run_event_state", + .tp_basicsize = sizeof(p_run_event_state), + /* Py_TPFLAGS_BASETYPE means "can be subtyped": */ + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_new = p_run_event_state_new, + .tp_dealloc = p_run_event_state_dealloc, + //.tp_init = p_run_event_state_init, + //.tp_members = p_run_event_state_members, + .tp_methods = p_run_event_state_methods, + .tp_getset = p_run_event_state_getset, +}; diff --git a/src/report-python/test_run_event_state b/src/report-python/test_run_event_state new file mode 100755 index 00000000..3e391407 --- /dev/null +++ b/src/report-python/test_run_event_state @@ -0,0 +1,13 @@ +#!/usr/bin/python + +from report import * + +def func(): + return 0 + +res = run_event_state() +print res +print res.post_run_callback +res.post_run_callback = func +res.logging_callback = func +print res.post_run_callback diff --git a/src/report-python/test_run_event_state1 b/src/report-python/test_run_event_state1 new file mode 100755 index 00000000..fa5d61a8 --- /dev/null +++ b/src/report-python/test_run_event_state1 @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import sys +from report import * + +def post_run_callback(dump_dir_name): + return 0 + +def logging_callback(line): + print "LOG:", line + return + +res = run_event_state() +res.post_run_callback = post_run_callback +res.logging_callback = logging_callback + +dd = dd_create("testdir", 0) +if not dd: + sys.exit(1) +dd.save_text("analyzer", "foo") +dd.close() + +res.run_event("testdir", "post-create") + +dd = dd_opendir("testdir") +#dd.delete() +dd.close() |