extern SRD_PRIV GSList *sessions;
-static void srd_inst_join_decode_thread(struct srd_decoder_inst *di);
-static void srd_inst_reset_state(struct srd_decoder_inst *di);
-SRD_PRIV void oldpins_array_seed(struct srd_decoder_inst *di);
-SRD_PRIV void oldpins_array_free(struct srd_decoder_inst *di);
-
/** @endcond */
/**
* @{
*/
+static void oldpins_array_seed(struct srd_decoder_inst *di)
+{
+ size_t count;
+ GArray *arr;
+
+ if (!di)
+ return;
+ if (di->old_pins_array)
+ return;
+
+ count = di->dec_num_channels;
+ arr = g_array_sized_new(FALSE, TRUE, sizeof(uint8_t), count);
+ g_array_set_size(arr, count);
+ if (arr->data)
+ memset(arr->data, SRD_INITIAL_PIN_SAME_AS_SAMPLE0, count);
+ di->old_pins_array = arr;
+}
+
+static void oldpins_array_free(struct srd_decoder_inst *di)
+{
+ if (!di)
+ return;
+ if (!di->old_pins_array)
+ return;
+
+ srd_dbg("%s: Releasing initial pin state.", di->inst_id);
+
+ g_array_free(di->old_pins_array, TRUE);
+ di->old_pins_array = NULL;
+}
+
/**
* Set one or more options in a decoder instance.
*
Py_DECREF(py_di_options);
py_di_options = PyDict_New();
PyObject_SetAttrString(di->py_inst, "options", py_di_options);
+ Py_DECREF(py_di_options);
for (l = di->decoder->options; l; l = l->next) {
sdo = l->data;
}
} else if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT64)) {
val_int = g_variant_get_int64(value);
- if (!(py_optval = PyLong_FromLong(val_int))) {
+ if (!(py_optval = PyLong_FromLongLong(val_int))) {
/* ValueError Exception */
PyErr_Clear();
srd_err("Option '%s' has invalid integer value.", sdo->id);
goto err_out;
}
}
- if (PyDict_SetItemString(py_di_options, sdo->id, py_optval) == -1)
+ if (PyDict_SetItemString(py_di_options, sdo->id, py_optval) == -1) {
+ Py_XDECREF(py_optval);
goto err_out;
+ }
/* Not harmful even if we used the default. */
g_hash_table_remove(options, sdo->id);
+ Py_XDECREF(py_optval);
}
if (g_hash_table_size(options) != 0)
srd_warn("Unknown options specified for '%s'", di->inst_id);
ret = SRD_OK;
err_out:
- Py_XDECREF(py_optval);
if (PyErr_Occurred()) {
srd_exception_catch("Stray exception in srd_inst_option_set()");
ret = SRD_ERR_PYTHON;
PyGILState_STATE gstate;
i = 1;
- srd_dbg("Creating new %s instance.", decoder_id);
if (!sess)
return NULL;
/* Instance takes input from a frontend by default. */
sess->di_list = g_slist_append(sess->di_list, di);
- srd_dbg("Created new %s instance with ID %s.", decoder_id, di->inst_id);
+ srd_dbg("Creating new %s instance %s.", decoder_id, di->inst_id);
return di;
}
sess->di_list = g_slist_remove(sess->di_list, di_top);
}
+ /*
+ * Check if there's at least one matching input/output pair
+ * for the stacked PDs. We warn if that's not the case, but it's
+ * not a hard error for the time being.
+ */
+ gboolean at_least_one_match = FALSE;
+ for (GSList *out = di_bottom->decoder->outputs; out; out = out->next) {
+ const char *o = out->data;
+ for (GSList *in = di_top->decoder->inputs; in; in = in->next) {
+ const char *i = in->data;
+ if (!strcmp(o, i)) {
+ at_least_one_match = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!at_least_one_match)
+ srd_warn("No matching in-/output when stacking %s onto %s.",
+ di_top->inst_id, di_bottom->inst_id);
+
/* Stack on top of source di. */
di_bottom->next_di = g_slist_append(di_bottom->next_di, di_top);
- srd_dbg("Stacked %s onto %s.", di_top->inst_id, di_bottom->inst_id);
+ srd_dbg("Stacking %s onto %s.", di_top->inst_id, di_bottom->inst_id);
return SRD_OK;
}
return SRD_OK;
}
-/** @private */
-SRD_PRIV void oldpins_array_seed(struct srd_decoder_inst *di)
-{
- size_t count;
- GArray *arr;
-
- if (!di)
- return;
- if (di->old_pins_array)
- return;
-
- srd_dbg("%s: Seeding old pins, %s().", di->inst_id, __func__);
- count = di->dec_num_channels;
- arr = g_array_sized_new(FALSE, TRUE, sizeof(uint8_t), count);
- g_array_set_size(arr, count);
- memset(arr->data, SRD_INITIAL_PIN_SAME_AS_SAMPLE0, count);
- di->old_pins_array = arr;
-}
-
-/** @private */
-SRD_PRIV void oldpins_array_free(struct srd_decoder_inst *di)
-{
- if (!di)
- return;
- if (!di->old_pins_array)
- return;
-
- srd_dbg("%s: Releasing initial pin state.", di->inst_id);
-
- g_array_free(di->old_pins_array, TRUE);
- di->old_pins_array = NULL;
-}
-
/** @private */
SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di)
{
- PyObject *py_res;
+ PyObject *py_res, *py_samplenum;
GSList *l;
struct srd_decoder_inst *next_di;
int ret;
PyGILState_STATE gstate;
- srd_dbg("Calling start() method on protocol decoder instance %s.",
- di->inst_id);
+ srd_dbg("Calling start() of instance %s.", di->inst_id);
gstate = PyGILState_Ensure();
PyGILState_Release(gstate);
return SRD_ERR_PYTHON;
}
- Py_DecRef(py_res);
+ Py_DECREF(py_res);
/* Set self.samplenum to 0. */
- PyObject_SetAttrString(di->py_inst, "samplenum", PyLong_FromLong(0));
+ py_samplenum = PyLong_FromUnsignedLongLong(0);
+ PyObject_SetAttrString(di->py_inst, "samplenum", py_samplenum);
+ Py_DECREF(py_samplenum);
/* Set self.matched to None. */
PyObject_SetAttrString(di->py_inst, "matched", Py_None);
g_slist_free_full(ll, g_free);
}
+ g_slist_free(di->condition_list);
di->condition_list = NULL;
}
oldpins_array_seed(di);
for (i = 0; i < di->dec_num_channels; i++) {
+ if (di->dec_channelmap[i] == -1)
+ continue; /* Ignore unused optional channels. */
byte_offset = di->dec_channelmap[i] / 8;
bit_offset = di->dec_channelmap[i] % 8;
sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
for (i = 0; i < di->dec_num_channels; i++) {
if (di->old_pins_array->data[i] != SRD_INITIAL_PIN_SAME_AS_SAMPLE0)
continue;
+ if (di->dec_channelmap[i] == -1)
+ continue; /* Ignore unused optional channels. */
byte_offset = di->dec_channelmap[i] / 8;
bit_offset = di->dec_channelmap[i] % 8;
sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
for (l = cond; l; l = l->next) {
term = l->data;
+ if (term->type == SRD_TERM_ALWAYS_FALSE)
+ return FALSE;
if (!term_matches(di, term, sample_pos))
return FALSE;
}
* Call self.decode(). Only returns if the PD throws an exception.
* "Regular" termination of the decode() method is not expected.
*/
- Py_IncRef(di->py_inst);
- srd_dbg("%s: Calling decode() method.", di->inst_id);
+ Py_INCREF(di->py_inst);
+ srd_dbg("%s: Calling decode().", di->inst_id);
py_res = PyObject_CallMethod(di->py_inst, "decode", NULL);
- srd_dbg("%s: decode() method terminated.", di->inst_id);
+ srd_dbg("%s: decode() terminated.", di->inst_id);
if (!py_res)
di->decoder_state = SRD_ERR;
* decode() will re-start another thread transparently.
*/
srd_dbg("%s: decode() terminated (req %d).", di->inst_id, wanted_term);
- Py_DecRef(py_res);
+ Py_DECREF(py_res);
PyErr_Clear();
PyGILState_Release(gstate);
*/
gstate = PyGILState_Ensure();
if (PyObject_HasAttrString(di->py_inst, "reset")) {
- srd_dbg("Calling .reset() of instance %s", di->inst_id);
+ srd_dbg("Calling reset() of instance %s", di->inst_id);
py_ret = PyObject_CallMethod(di->py_inst, "reset", NULL);
Py_XDECREF(py_ret);
}
srd_inst_reset_state(di);
gstate = PyGILState_Ensure();
- Py_DecRef(di->py_inst);
+ Py_DECREF(di->py_inst);
PyGILState_Release(gstate);
g_free(di->inst_id);