+ if (!(d->py_dec = PyObject_GetAttrString(d->py_mod, "Decoder"))) {
+ /* This generated an AttributeError exception. */
+ PyErr_Clear();
+ srd_err("Decoder class not found in protocol decoder %s.",
+ module_name);
+ goto err_out;
+ }
+
+ if (!(py_basedec = PyObject_GetAttrString(mod_sigrokdecode, "Decoder"))) {
+ srd_dbg("sigrokdecode module not loaded.");
+ goto err_out;
+ }
+
+ if (!PyObject_IsSubclass(d->py_dec, py_basedec)) {
+ srd_err("Decoder class in protocol decoder module %s is not "
+ "a subclass of sigrokdecode.Decoder.", module_name);
+ goto err_out;
+ }
+ Py_CLEAR(py_basedec);
+
+ /* Check for a proper start() method. */
+ if (!PyObject_HasAttrString(d->py_dec, "start")) {
+ srd_err("Protocol decoder %s has no start() method Decoder "
+ "class.", module_name);
+ goto err_out;
+ }
+ py_method = PyObject_GetAttrString(d->py_dec, "start");
+ if (!PyFunction_Check(py_method)) {
+ srd_err("Protocol decoder %s Decoder class attribute 'start' "
+ "is not a method.", module_name);
+ goto err_out;
+ }
+ Py_CLEAR(py_method);
+
+ /* Check for a proper decode() method. */
+ if (!PyObject_HasAttrString(d->py_dec, "decode")) {
+ srd_err("Protocol decoder %s has no decode() method Decoder "
+ "class.", module_name);
+ goto err_out;
+ }
+ py_method = PyObject_GetAttrString(d->py_dec, "decode");
+ if (!PyFunction_Check(py_method)) {
+ srd_err("Protocol decoder %s Decoder class attribute 'decode' "
+ "is not a method.", module_name);
+ goto err_out;
+ }
+ Py_CLEAR(py_method);
+
+ /* If present, options must be a dictionary. */
+ if (PyObject_HasAttrString(d->py_dec, "options")) {
+ py_attr = PyObject_GetAttrString(d->py_dec, "options");
+ if (!PyDict_Check(py_attr)) {
+ srd_err("Protocol decoder %s options attribute is not "
+ "a dictionary.", d->name);
+ Py_DecRef(py_attr);
+ goto err_out;
+ }
+ Py_DecRef(py_attr);