Skip to content

Commit

Permalink
python: provide more C methods
Browse files Browse the repository at this point in the history
This provides the C methods for wrapping
callbacks and the upcoming Event/Field
classes.

Acked-by: Darren Hart <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
  • Loading branch information
jmberg committed May 25, 2010
1 parent 436458c commit c6ed0d9
Showing 1 changed file with 113 additions and 0 deletions.
113 changes: 113 additions & 0 deletions ctracecmd.i
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,119 @@
#include "trace-cmd.h"
%}


%typemap(in) PyObject *pyfunc {
if (!PyCallable_Check($input)) {
PyErr_SetString(PyExc_TypeError, "Need a callable object!");
return NULL;
}
$1 = $input;
}

%ignore python_callback;

%inline %{
static int python_callback(struct trace_seq *s,
struct record *record,
struct event_format *event,
void *context);

void py_pevent_register_event_handler(struct pevent *pevent, int id,
char *subsys, char *evname,
PyObject *pyfunc)
{
Py_INCREF(pyfunc);
pevent_register_event_handler(pevent, id, subsys, evname,
python_callback, pyfunc);
}

static PyObject *py_field_get_data(struct format_field *f, struct record *r)
{
if (!strncmp(f->type, "__data_loc ", 11)) {
unsigned long long val;
int len, offset;

if (pevent_read_number_field(f, r->data, &val)) {
PyErr_SetString(PyExc_TypeError,
"Field is not a valid number");
return NULL;
}

/*
* The actual length of the dynamic array is stored
* in the top half of the field, and the offset
* is in the bottom half of the 32 bit field.
*/
offset = val & 0xffff;
len = val >> 16;

return PyBuffer_FromMemory((char *)r->data + offset, len);
}

return PyBuffer_FromMemory((char *)r->data + f->offset, f->size);
}

static PyObject *py_format_get_keys(struct event_format *ef)
{
PyObject *list;
struct format_field *f;

list = PyList_New(0);

for (f = ef->format.fields; f; f = f->next) {
if (PyList_Append(list, PyString_FromString(f->name))) {
Py_DECREF(list);
return NULL;
}
}

return list;
}
%}


%wrapper %{
static int python_callback(struct trace_seq *s,
struct record *record,
struct event_format *event,
void *context)
{
PyObject *arglist, *result;
int r = 0;

record->ref_count++;

arglist = Py_BuildValue("(OOO)",
SWIG_NewPointerObj(SWIG_as_voidptr(s),
SWIGTYPE_p_trace_seq, 0),
SWIG_NewPointerObj(SWIG_as_voidptr(record),
SWIGTYPE_p_record, 0),
SWIG_NewPointerObj(SWIG_as_voidptr(event),
SWIGTYPE_p_event_format, 0));

result = PyEval_CallObject(context, arglist);
Py_XDECREF(arglist);
if (result && result != Py_None) {
if (!PyInt_Check(result)) {
PyErr_SetString(PyExc_TypeError,
"callback must return int");
PyErr_Print();
Py_XDECREF(result);
return 0;
}
r = PyInt_AS_LONG(result);
} else if (result == Py_None)
r = 0;
else
PyErr_Print();

Py_XDECREF(result);

return r;
}
%}


%ignore trace_seq_vprintf;

/* SWIG can't grok these, define them to nothing */
Expand Down

0 comments on commit c6ed0d9

Please sign in to comment.