return tests
-def diff_textfiles(f1, f2):
+def diff_text(f1, f2):
t1 = open(f1).readlines()
t2 = open(f2).readlines()
diff = []
return diff
-def compare_binfiles(f1, f2):
+def compare_binary(f1, f2):
h1 = md5()
h1.update(open(f1, 'rb').read())
h2 = md5()
match = os.path.join(decoders_dir, op['pd'], 'test', op['match'])
try:
diff = diff_error = None
- if op['type'] == 'annotation':
- diff = diff_textfiles(match, outfile)
+ if op['type'] in ('annotation', 'python'):
+ diff = diff_text(match, outfile)
elif op['type'] == 'binary':
- diff = compare_binfiles(match, outfile)
+ diff = compare_binary(match, outfile)
else:
diff = ["Unsupported output type '%s'." % op['type']]
except Exception as e:
if (msg)
fprintf(stderr, "%s\n", msg);
- //while((c = getopt(argc, argv, "dP:p:o:i:O:f:S")) != -1) {
printf("Usage: runtc [-dPpoiOf]\n");
printf(" -d Debug\n");
printf(" -P <protocol decoder>\n");
}
-static void srd_cb_bin(struct srd_proto_data *pdata, void *cb_data)
+/* This is a neutered version of libsigrokdecode's py_str_as_str(). It
+ * does no error checking, but then the only strings it processes are
+ * generated by Python's repr(), so are known good. */
+char *py_str_as_str(const PyObject *py_str)
+{
+ PyObject *py_encstr;
+ char *str, *outstr;
+
+ py_encstr = PyUnicode_AsEncodedString((PyObject *)py_str, "utf-8", NULL);
+ str = PyBytes_AS_STRING(py_encstr);
+ outstr = g_strdup(str);
+ Py_DecRef(py_encstr);
+
+ return outstr;
+}
+
+static void srd_cb_py(struct srd_proto_data *pdata, void *cb_data)
{
- struct srd_proto_data_binary *pdb;
struct output *op;
+ PyObject *pydata, *pyrepr;
+ GString *out;
+ char *s;
+ DBG("Python output from %s", pdata->pdo->di->inst_id);
op = cb_data;
- if (op->type != SRD_OUTPUT_BINARY)
+ pydata = pdata->data;
+ DBG("ptr %p", pydata);
+
+ if (strcmp(pdata->pdo->di->inst_id, op->pd))
+ /* This is not the PD selected for output. */
+ return;
+
+ if (!(pyrepr = PyObject_Repr(pydata))) {
+ ERR("Invalid Python object.");
return;
+ }
+ s = py_str_as_str(pyrepr);
+ Py_DecRef(pyrepr);
+
+ /* Output format for testing is '<ss>-<es> <inst-id>: <repr>\n' */
+ out = g_string_sized_new(128);
+ g_string_printf(out, "%"PRIu64"-%"PRIu64" %s: %s\n",
+ pdata->start_sample, pdata->end_sample,
+ pdata->pdo->di->inst_id, s);
+ g_free(s);
+ if (write(op->outfd, out->str, out->len) == -1)
+ ERR("SRD_OUTPUT_PYTHON callback write failure!");
+ DBG("wrote '%s'", out->str);
+ g_string_free(out, TRUE);
+
+}
+
+static void srd_cb_bin(struct srd_proto_data *pdata, void *cb_data)
+{
+ struct srd_proto_data_binary *pdb;
+ struct output *op;
DBG("Binary output from %s", pdata->pdo->di->inst_id);
+ op = cb_data;
pdb = pdata->data;
if (strcmp(pdata->pdo->di->inst_id, op->pd))
return;
if (write(op->outfd, pdb->data, pdb->size) == -1)
- ERR("Oops!");
+ ERR("SRD_OUTPUT_BINARY callback write failure!");
}
int i;
char **dec_ann;
- op = cb_data;
- if (op->type != SRD_OUTPUT_ANN)
- return;
-
DBG("Annotation output from %s", pdata->pdo->di->inst_id);
+ op = cb_data;
pda = pdata->data;
dec = pdata->pdo->di->decoder;
if (strcmp(pdata->pdo->di->inst_id, op->pd))
g_string_append_printf(line, " \"%s\"", pda->ann_text[i]);
g_string_append(line, "\n");
if (write(op->outfd, line->str, line->len) == -1)
- ERR("Oops!");
+ ERR("SRD_OUTPUT_ANN callback write failure!");
g_string_free(line, TRUE);
}
struct srd_session *sess;
struct srd_decoder *dec;
struct srd_decoder_inst *di, *prev_di;
+ srd_pd_output_callback_t cb;
struct pd *pd;
struct probe *probe;
struct option *option;
if (srd_session_new(&sess) != SRD_OK)
return FALSE;
sr_session_datafeed_callback_add(sr_cb, sess);
- srd_pd_output_callback_add(sess, SRD_OUTPUT_ANN, srd_cb_ann, op);
- srd_pd_output_callback_add(sess, SRD_OUTPUT_BINARY, srd_cb_bin, op);
+ switch (op->type) {
+ case SRD_OUTPUT_ANN:
+ cb = srd_cb_ann;
+ break;
+ case SRD_OUTPUT_BINARY:
+ cb = srd_cb_bin;
+ break;
+ case SRD_OUTPUT_PYTHON:
+ cb = srd_cb_py;
+ break;
+ default:
+ return FALSE;
+ }
+ srd_pd_output_callback_add(sess, op->type, cb, op);
prev_di = NULL;
pd = NULL;
g_hash_table_destroy(probes);
}
-
/* If this is not the first decoder in the list, stack it
* on top of the previous one. */
if (prev_di) {
else if (op->type == SRD_OUTPUT_BINARY)
l = dec->binary;
else
- /* Only annotations and binary for now. */
+ /* Only annotations and binary can have a class. */
return FALSE;
idx = 0;
while(l) {