+ struct srd_decoder *d;
+ PyObject *py_mod, *py_func, *py_res, *py_instance = NULL, *py_args, *py_value/* , *py_tuple */;
+ int r;
+ fprintf(stdout, "\n%s\n", name);
+
+ /* "Import" the Python module. */
+ if (!(py_mod = PyImport_ImportModule(name))) { /* NEWREF */
+ PyErr_Print(); /* Returns void. */
+ return SRD_ERR_PYTHON; /* TODO: More specific error? */
+ }
+
+ /* Get the 'register' dictionary as Python object. */
+ py_res = PyObject_GetAttrString(py_mod, "register"); /* NEWREF */
+ if (!py_res || PyCallable_Check(py_res)) {
+ if (PyErr_Occurred())
+ PyErr_Print(); /* Returns void. */
+ Py_XDECREF(py_mod);
+ fprintf(stderr, "register dictionary was not found or is declared a function.\n");
+ 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_mod, "id", &(d->id))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "name", &(d->name))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "longname",
+ &(d->longname))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "desc", &(d->desc))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "longdesc",
+ &(d->longdesc))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "author", &(d->author))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "email", &(d->email))) < 0)
+ return r;
+
+ if ((r = h_str(py_res, py_mod, "license", &(d->license))) < 0)
+ return r;
+
+ d->py_mod = py_mod;
+
+ Py_XDECREF(py_res);
+
+
+ /* Get the 'Decoder' class as Python object. */
+ py_res = PyObject_GetAttrString(py_mod, "Decoder"); /* NEWREF */
+ if (!py_res) {
+ if (PyErr_Occurred())
+ PyErr_Print(); /* Returns void. */
+ //Py_XDECREF(py_mod);
+ fprintf(stderr, "Decoder class not found in PD module %s\n", name);
+ //return SRD_ERR_PYTHON; /* TODO: More specific error? */
+
+
+ /* 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? */
+ }
+ } else {
+ PyObject_Print(py_res, stdout, Py_PRINT_RAW);
+ fprintf(stdout, "\n");
+
+ /* Create a Python tuple of size 1. */
+ if (!(py_args = PyTuple_New(0))) { /* NEWREF */
+ if (PyErr_Occurred())
+ PyErr_Print(); /* Returns void. */
+
+ Py_XDECREF(py_res);
+ Py_XDECREF(py_mod);
+
+ return SRD_ERR_PYTHON; /* TODO: More specific error? */
+ }
+
+ py_value = Py_BuildValue("{sssisd}",
+ "driver", "demo",
+ "unitsize", _unitsize, //FIXME: Pass in a unitsize that matches the selected LA
+ "starttime", 129318231823.0 //TODO: Fill with something reasonable.
+ );
+ /* Create an instance of the Decoder class */
+ py_instance = PyObject_Call(py_res, py_args, py_value);
+ if (!py_instance) {
+ if (PyErr_Occurred())
+ PyErr_Print(); /* Returns void. */
+ Py_XDECREF(py_value); /* TODO: Ref. stolen upon error? */
+ Py_XDECREF(py_res);
+ Py_XDECREF(py_mod);
+ fprintf(stderr, "Unable to create instance of Decoder class in PD module %s\n", name);
+ return SRD_ERR_PYTHON; /* TODO: More specific error? */
+ }
+ }
+
+ d->py_instance = py_instance;
+
+ /* 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;