+ /* Get the 'register' function name as Python callable object. */
+ py_func = PyObject_GetAttrString(py_mod, "register"); /* NEWREF */
+ if (!py_func || !PyCallable_Check(py_func)) {
+ if (PyErr_Occurred())
+ PyErr_Print(); /* Returns void. */
+ Py_XDECREF(py_mod);
+ return SRD_ERR_PYTHON; /* TODO: More specific error? */
+ }
+
+ /* Call the 'register' function without arguments, get the result. */
+ if (!(py_res = PyObject_CallFunction(py_func, NULL))) { /* NEWREF */
+ PyErr_Print(); /* Returns void. */
+ Py_XDECREF(py_func);
+ Py_XDECREF(py_mod);
+ return SRD_ERR_PYTHON; /* TODO: More specific error? */
+ }
+
+ if (!(d = malloc(sizeof(struct srd_decoder))))
+ return SRD_ERR_MALLOC;
+
+ if ((r = h_str(py_res, py_func, py_mod, "id", &(d->id))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "name", &(d->name))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "longname",
+ &(d->longname))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "desc", &(d->desc))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "longdesc",
+ &(d->longdesc))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "author", &(d->author))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "email", &(d->email))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_func, py_mod, "license", &(d->license))) < 0)
+ return r;
+
+ d->py_mod = py_mod;
+
+ Py_XDECREF(py_res);
+ Py_XDECREF(py_func);
+
+ /* Get the 'decode' function name as Python callable object. */
+ py_func = PyObject_GetAttrString(py_mod, "decode"); /* NEWREF */
+ if (!py_func || !PyCallable_Check(py_func)) {
+ if (PyErr_Occurred())
+ PyErr_Print(); /* Returns void. */
+ Py_XDECREF(py_mod);
+ return SRD_ERR_PYTHON; /* TODO: More specific error? */
+ }
+
+ d->py_func = py_func;
+
+ /* TODO: Handle func, inputformats, outputformats. */
+ /* Note: They must at least be set to NULL, will segfault otherwise. */
+ d->func = NULL;
+ d->inputformats = NULL;
+ d->outputformats = NULL;
+
+ *dec = d;
+
+ return SRD_OK;