From e6d1647a8f95d2bbcd45663e10bb50fb1a15aa5a Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 15 May 2018 11:41:52 +0200 Subject: [PATCH] bindings: python: implement Chip.find_lines() Provide a method for looking up multiple lines by name at once. Signed-off-by: Bartosz Golaszewski --- bindings/python/gpiodmodule.c | 91 +++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/bindings/python/gpiodmodule.c b/bindings/python/gpiodmodule.c index 0e1c855..fa018cf 100644 --- a/bindings/python/gpiodmodule.c +++ b/bindings/python/gpiodmodule.c @@ -1398,6 +1398,91 @@ gpiod_Chip_get_lines(gpiod_ChipObject *self, PyObject *args) return bulk; } +PyDoc_STRVAR(gpiod_Chip_find_lines_doc, +"Look up a set of lines by their names."); + +static gpiod_LineBulkObject * +gpiod_Chip_find_lines(gpiod_ChipObject *self, PyObject *args) +{ + Py_ssize_t num_names, i; + PyObject *names, *lines, *iter, *next, *arg; + gpiod_LineObject *line; + gpiod_LineBulkObject *bulk; + int rv; + + rv = PyArg_ParseTuple(args, "O", &names); + if (!rv) + return NULL; + + num_names = PyObject_Size(names); + if (num_names < 1) { + PyErr_SetString(PyExc_TypeError, + "Argument must be a non-empty sequence of names"); + return NULL; + } + + lines = PyList_New(num_names); + if (!lines) + return NULL; + + iter = PyObject_GetIter(names); + if (!iter) { + Py_DECREF(lines); + return NULL; + } + + for (i = 0;;) { + next = PyIter_Next(iter); + if (!next) { + Py_DECREF(iter); + break; + } + + arg = PyTuple_Pack(1, next); + if (!arg) { + Py_DECREF(iter); + Py_DECREF(lines); + return NULL; + } + + line = gpiod_Chip_find_line(self, arg); + Py_DECREF(arg); + if (!line) { + Py_DECREF(iter); + Py_DECREF(lines); + return NULL; + } + + rv = PyList_SetItem(lines, i++, (PyObject *)line); + if (rv < 0) { + Py_DECREF(line); + Py_DECREF(iter); + Py_DECREF(lines); + return NULL; + } + } + + arg = PyTuple_Pack(1, lines); + Py_DECREF(lines); + if (!arg) + return NULL; + + bulk = PyObject_New(gpiod_LineBulkObject, &gpiod_LineBulkType); + if (!bulk) { + Py_DECREF(arg); + return NULL; + } + + rv = gpiod_LineBulkType.tp_init((PyObject *)bulk, arg, NULL); + Py_DECREF(arg); + if (rv < 0) { + Py_DECREF(bulk); + return NULL; + } + + return bulk; +} + static PyMethodDef gpiod_Chip_methods[] = { { .ml_name = "name", @@ -1435,6 +1520,12 @@ static PyMethodDef gpiod_Chip_methods[] = { .ml_flags = METH_VARARGS, .ml_doc = gpiod_Chip_get_lines_doc, }, + { + .ml_name = "find_lines", + .ml_meth = (PyCFunction)gpiod_Chip_find_lines, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_Chip_find_lines_doc, + }, { } }; -- 2.30.2