2 * This file is part of the sigrok-test project.
4 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <libsigrokdecode/libsigrokdecode.h>
22 #include <libsigrok/libsigrok.h>
28 #include <sys/types.h>
33 #include <sys/resource.h>
40 static int debug
= FALSE
;
41 static int statistics
= FALSE
;
42 static char *coverage_report
;
43 static struct sr_context
*ctx
;
55 struct initial_pin_info
{
84 static struct cvg
*get_mod_cov(PyObject
*py_cov
, const char *module_name
);
85 static void cvg_add(struct cvg
*dst
, const struct cvg
*src
);
86 static struct cvg
*cvg_new(void);
87 static gboolean
find_missed_line(struct cvg
*cvg
, const char *linespec
);
89 static void logmsg(const char *prefix
, FILE *out
, const char *format
, va_list args
)
92 fprintf(out
, "%s", prefix
);
93 vfprintf(out
, format
, args
);
97 static void DBG(const char *format
, ...)
103 va_start(args
, format
);
104 logmsg("DBG: runtc: ", stdout
, format
, args
);
108 static void ERR(const char *format
, ...)
112 va_start(args
, format
);
113 logmsg("Error: ", stderr
, format
, args
);
117 static int sr_log(void *cb_data
, int loglevel
, const char *format
, va_list args
)
121 if (loglevel
== SR_LOG_ERR
|| loglevel
== SR_LOG_WARN
)
122 logmsg("Error: sr: ", stderr
, format
, args
);
124 logmsg("DBG: sr: ", stdout
, format
, args
);
129 static int srd_log(void *cb_data
, int loglevel
, const char *format
, va_list args
)
133 if (loglevel
== SRD_LOG_ERR
|| loglevel
== SRD_LOG_WARN
)
134 logmsg("Error: srd: ", stderr
, format
, args
);
136 logmsg("DBG: srd: ", stdout
, format
, args
);
141 static void usage(const char *msg
)
144 fprintf(stderr
, "%s\n", msg
);
146 printf("Usage: runtc [-dPpoiOfcS]\n");
147 printf(" -d (enables debug output)\n");
148 printf(" -P <protocol decoder>\n");
149 printf(" -p <channelname=channelnum> (optional)\n");
150 printf(" -o <channeloption=value> (optional)\n");
151 printf(" -N <channelname=initial-pin-value> (optional)\n");
152 printf(" -i <input file>\n");
153 printf(" -O <output-pd:output-type[:output-class]>\n");
154 printf(" -f <output file> (optional)\n");
155 printf(" -c <coverage report> (optional)\n");
156 printf(" -S (enables statistics)\n");
162 * This is a neutered version of libsigrokdecode's py_str_as_str(). It
163 * does no error checking, but then the only strings it processes are
164 * generated by Python's repr(), so are known good.
166 static char *py_str_as_str(const PyObject
*py_str
)
171 py_encstr
= PyUnicode_AsEncodedString((PyObject
*)py_str
, "utf-8", NULL
);
172 str
= PyBytes_AS_STRING(py_encstr
);
173 outstr
= g_strdup(str
);
174 Py_DecRef(py_encstr
);
180 * The following routines are callbacks for libsigrokdecode. They receive
181 * output from protocol decoders, optionally dropping data to only forward
182 * a selected decoder's or class' information. Output is written to either
183 * a specified file or stdout, an external process will compare captured
184 * output against expectations.
186 * Note that runtc(1) output emits the decoder "class" name instead of the
187 * instance name. So that generated output remains compatible with existing
188 * .output files which hold expected output of test cases. Without this
189 * approach, developers had to "anticipate" instance names from test.conf
190 * setups (and knowledge about internal implementation details of the srd
191 * library), and adjust .output files to reflect those names. Or specify
192 * instance names in each and every test.conf description (-o inst_id=ID).
194 * It's assumed that runtc(1) is used to check stacked decoders, but not
195 * multiple stacks in parallel and no stacks with multiple instances of
196 * decoders of the same type. When such configurations become desirable,
197 * runtc(1) needs to emit the instance name, and test configurations and
198 * output expectations need adjustment.
201 static void srd_cb_py(struct srd_proto_data
*pdata
, void *cb_data
)
204 PyObject
*pydata
, *pyrepr
;
208 DBG("Python output from %s", pdata
->pdo
->di
->inst_id
);
210 pydata
= pdata
->data
;
211 DBG("ptr %p", pydata
);
213 if (strcmp(pdata
->pdo
->di
->inst_id
, op
->pd_id
))
214 /* This is not the PD selected for output. */
217 if (!(pyrepr
= PyObject_Repr(pydata
))) {
218 ERR("Invalid Python object.");
221 s
= py_str_as_str(pyrepr
);
224 /* Output format for testing is '<ss>-<es> <decoder-id>: <repr>\n'. */
225 out
= g_string_sized_new(128);
226 g_string_printf(out
, "%" PRIu64
"-%" PRIu64
" %s: %s\n",
227 pdata
->start_sample
, pdata
->end_sample
,
228 pdata
->pdo
->di
->decoder
->id
, s
);
230 if (write(op
->outfd
, out
->str
, out
->len
) == -1)
231 ERR("SRD_OUTPUT_PYTHON callback write failure!");
232 DBG("wrote '%s'", out
->str
);
233 g_string_free(out
, TRUE
);
237 static void srd_cb_bin(struct srd_proto_data
*pdata
, void *cb_data
)
239 struct srd_proto_data_binary
*pdb
;
244 DBG("Binary output from %s", pdata
->pdo
->di
->inst_id
);
248 if (strcmp(pdata
->pdo
->di
->inst_id
, op
->pd_id
))
249 /* This is not the PD selected for output. */
252 if (op
->class_idx
!= -1 && op
->class_idx
!= pdb
->bin_class
)
254 * This output takes a specific binary class,
255 * but not the one that just came in.
259 out
= g_string_sized_new(128);
260 g_string_printf(out
, "%" PRIu64
"-%" PRIu64
" %s:",
261 pdata
->start_sample
, pdata
->end_sample
,
262 pdata
->pdo
->di
->decoder
->id
);
263 for (i
= 0; i
< pdb
->size
; i
++) {
264 g_string_append_printf(out
, " %.2x", pdb
->data
[i
]);
266 g_string_append(out
, "\n");
267 if (write(op
->outfd
, out
->str
, out
->len
) == -1)
268 ERR("SRD_OUTPUT_BINARY callback write failure!");
272 static void srd_cb_ann(struct srd_proto_data
*pdata
, void *cb_data
)
274 struct srd_decoder_inst
*di
;
275 struct srd_decoder
*dec
;
276 struct srd_proto_data_annotation
*pda
;
283 * Only inspect received annotations when they originate from
284 * the selected protocol decoder, and an optionally specified
285 * annotation class matches the received data.
291 DBG("Annotation output from %s", di
->inst_id
);
292 if (strcmp(di
->inst_id
, op
->pd_id
))
293 /* This is not the PD selected for output. */
296 if (op
->class_idx
!= -1 && op
->class_idx
!= pda
->ann_class
)
298 * This output takes a specific annotation class,
299 * but not the one that just came in.
304 * Print the annotation information in textual representation
305 * to the specified output file. Prefix the annotation strings
306 * with the start and end sample number, the decoder name, and
307 * the annotation name.
309 dec_ann
= g_slist_nth_data(dec
->annotations
, pda
->ann_class
);
310 line
= g_string_sized_new(256);
311 g_string_printf(line
, "%" PRIu64
"-%" PRIu64
" %s: %s:",
312 pdata
->start_sample
, pdata
->end_sample
,
313 dec
->id
, dec_ann
[0]);
314 for (i
= 0; pda
->ann_text
[i
]; i
++)
315 g_string_append_printf(line
, " \"%s\"", pda
->ann_text
[i
]);
316 g_string_append(line
, "\n");
317 if (write(op
->outfd
, line
->str
, line
->len
) == -1)
318 ERR("SRD_OUTPUT_ANN callback write failure!");
319 g_string_free(line
, TRUE
);
323 static void sr_cb(const struct sr_dev_inst
*sdi
,
324 const struct sr_datafeed_packet
*packet
, void *cb_data
)
326 static int samplecnt
= 0;
327 const struct sr_datafeed_logic
*logic
;
328 struct srd_session
*sess
;
332 struct sr_dev_driver
*driver
;
336 driver
= sr_dev_inst_driver_get(sdi
);
338 switch (packet
->type
) {
340 DBG("Received SR_DF_HEADER");
341 if (sr_config_get(driver
, sdi
, NULL
, SR_CONF_SAMPLERATE
,
343 ERR("Getting samplerate failed");
346 samplerate
= g_variant_get_uint64(gvar
);
347 g_variant_unref(gvar
);
348 if (srd_session_metadata_set(sess
, SRD_CONF_SAMPLERATE
,
349 g_variant_new_uint64(samplerate
)) != SRD_OK
) {
350 ERR("Setting samplerate failed");
353 if (srd_session_start(sess
) != SRD_OK
) {
354 ERR("Session start failed");
359 logic
= packet
->payload
;
360 num_samples
= logic
->length
/ logic
->unitsize
;
361 DBG("Received SR_DF_LOGIC (%"PRIu64
" bytes, unitsize = %d).",
362 logic
->length
, logic
->unitsize
);
363 srd_session_send(sess
, samplecnt
, samplecnt
+ num_samples
,
364 logic
->data
, logic
->length
, logic
->unitsize
);
365 samplecnt
+= num_samples
;
368 DBG("Received SR_DF_END");
374 static int run_testcase(const char *infile
, GSList
*pdlist
, struct output
*op
)
376 struct srd_session
*sess
;
377 struct srd_decoder
*dec
;
378 struct srd_decoder_inst
*di
, *prev_di
;
379 srd_pd_output_callback cb
;
381 struct channel
*channel
;
382 struct option
*option
;
384 GHashTable
*channels
, *opts
;
385 GSList
*pdl
, *l
, *l2
, *devices
;
388 char **decoder_class
;
389 struct sr_session
*sr_sess
;
392 GArray
*initial_pins
;
393 struct initial_pin_info
*initial_pin
;
396 if ((op
->outfd
= open(op
->outfile
, O_CREAT
|O_WRONLY
, 0600)) == -1) {
397 ERR("Unable to open %s for writing: %s", op
->outfile
,
403 if (sr_session_load(ctx
, infile
, &sr_sess
) != SR_OK
){
404 ERR("sr_session_load() failed");
408 sr_session_dev_list(sr_sess
, &devices
);
410 if (srd_session_new(&sess
) != SRD_OK
) {
411 ERR("srd_session_new() failed");
414 sr_session_datafeed_callback_add(sr_sess
, sr_cb
, sess
);
419 case SRD_OUTPUT_BINARY
:
422 case SRD_OUTPUT_PYTHON
:
426 ERR("Invalid op->type");
429 srd_pd_output_callback_add(sess
, op
->type
, cb
, op
);
433 for (pdl
= pdlist
; pdl
; pdl
= pdl
->next
) {
435 if (srd_decoder_load(pd
->name
) != SRD_OK
) {
436 ERR("srd_decoder_load() failed");
440 /* Instantiate decoder and pass in options. */
441 opts
= g_hash_table_new_full(g_str_hash
, g_str_equal
, NULL
,
442 (GDestroyNotify
)g_variant_unref
);
443 for (l
= pd
->options
; l
; l
= l
->next
) {
447 s
= g_variant_get_string(option
->value
, NULL
);
448 for (i
= 0; i
< (int)strlen(s
); i
++) {
454 /* Integer option value */
455 g_hash_table_insert(opts
, option
->key
,
456 g_variant_new_int64(strtoull(s
, NULL
, 10)));
458 /* String option value */
459 g_hash_table_insert(opts
, option
->key
, option
->value
);
462 if (!(di
= srd_inst_new(sess
, pd
->name
, opts
))) {
463 ERR("srd_inst_new() failed");
466 g_hash_table_destroy(opts
);
469 * Get (a reference to) the decoder instance's ID if we
470 * are about to receive PD output from it. We need to
471 * filter output that carries the decoder instance's name.
473 if (strcmp(pd
->name
, op
->pd
) == 0) {
474 op
->pd_id
= di
->inst_id
;
475 DBG("Decoder of type \"%s\" has instance ID \"%s\".",
481 channels
= g_hash_table_new_full(g_str_hash
, g_str_equal
, NULL
,
482 (GDestroyNotify
)g_variant_unref
);
484 for (l
= pd
->channels
; l
; l
= l
->next
) {
486 if (channel
->channel
> max_channel
)
487 max_channel
= channel
->channel
;
488 gvar
= g_variant_new_int32(channel
->channel
);
489 g_variant_ref_sink(gvar
);
490 g_hash_table_insert(channels
, channel
->name
, gvar
);
493 if (srd_inst_channel_set_all(di
, channels
) != SRD_OK
) {
494 ERR("srd_inst_channel_set_all() failed");
497 g_hash_table_destroy(channels
);
500 /* Set initial pins. */
501 if (pd
->initial_pins
) {
502 initial_pins
= g_array_sized_new(FALSE
, TRUE
, sizeof(uint8_t),
503 di
->dec_num_channels
);
504 g_array_set_size(initial_pins
, di
->dec_num_channels
);
505 memset(initial_pins
->data
, SRD_INITIAL_PIN_SAME_AS_SAMPLE0
,
506 di
->dec_num_channels
);
508 for (l
= pd
->channels
, idx
= 0; l
; l
= l
->next
, idx
++) {
510 for (l2
= pd
->initial_pins
; l2
; l2
= l2
->next
) {
511 initial_pin
= l2
->data
;
512 if (!strcmp(initial_pin
->name
, channel
->name
))
513 initial_pins
->data
[idx
] = initial_pin
->value
;
517 if (srd_inst_initial_pins_set_all(di
, initial_pins
) != SRD_OK
) {
518 ERR("srd_inst_initial_pins_set_all() failed");
521 g_array_free(initial_pins
, TRUE
);
525 * If this is not the first decoder in the list, stack it
526 * on top of the previous one.
529 if (srd_inst_stack(sess
, prev_di
, di
) != SRD_OK
) {
530 ERR("Failed to stack decoder instances.");
537 * Bail out if we haven't created an instance of the selected
538 * decoder type of which we shall grab output data from.
541 ERR("No / invalid decoder");
545 /* Resolve selected decoder's class index, so we can match. */
546 dec
= srd_decoder_get_by_id(pd
->name
);
548 if (op
->type
== SRD_OUTPUT_ANN
)
549 l
= dec
->annotations
;
550 else if (op
->type
== SRD_OUTPUT_BINARY
)
553 /* Only annotations and binary can have a class. */
554 ERR("Invalid decoder class");
559 decoder_class
= l
->data
;
560 if (!strcmp(decoder_class
[0], op
->class)) {
567 if (op
->class_idx
== -1) {
568 ERR("Output class '%s' not found in decoder %s.",
569 op
->class, pd
->name
);
572 DBG("Class %s index is %d", op
->class, op
->class_idx
);
575 sr_session_start(sr_sess
);
576 sr_session_run(sr_sess
);
577 sr_session_stop(sr_sess
);
579 srd_session_destroy(sess
);
587 static PyObject
*start_coverage(GSList
*pdlist
)
589 PyObject
*py_mod
, *py_pdlist
, *py_pd
, *py_func
, *py_args
, *py_kwargs
, *py_cov
;
593 DBG("Starting coverage.");
595 if (!(py_mod
= PyImport_ImportModule("coverage")))
598 if (!(py_pdlist
= PyList_New(0)))
600 for (l
= pdlist
; l
; l
= l
->next
) {
602 py_pd
= PyUnicode_FromFormat("*/%s/*.py", pd
->name
);
603 if (PyList_Append(py_pdlist
, py_pd
) < 0)
607 if (!(py_func
= PyObject_GetAttrString(py_mod
, "coverage")))
609 if (!(py_args
= PyTuple_New(0)))
611 if (!(py_kwargs
= Py_BuildValue("{sO}", "include", py_pdlist
)))
613 if (!(py_cov
= PyObject_Call(py_func
, py_args
, py_kwargs
)))
615 if (!(PyObject_CallMethod(py_cov
, "start", NULL
)))
617 Py_DecRef(py_pdlist
);
619 Py_DecRef(py_kwargs
);
625 static struct cvg
*get_mod_cov(PyObject
*py_cov
, const char *module_name
)
627 PyObject
*py_mod
, *py_pathlist
, *py_path
, *py_func
, *py_pd
;
628 PyObject
*py_result
, *py_missed
, *py_item
;
632 int num_lines
, num_missed
, linenum
, i
, j
;
633 char *path
, *linespec
;
635 if (!(py_mod
= PyImport_ImportModule(module_name
)))
639 py_pathlist
= PyObject_GetAttrString(py_mod
, "__path__");
640 for (i
= 0; i
< PyList_Size(py_pathlist
); i
++) {
641 py_path
= PyList_GetItem(py_pathlist
, i
);
642 PyUnicode_FSConverter(PyList_GetItem(py_pathlist
, i
), &py_path
);
643 path
= PyBytes_AS_STRING(py_path
);
644 if (!(d
= opendir(path
))) {
645 ERR("Invalid module path '%s'", path
);
648 while ((de
= readdir(d
))) {
649 if (strncmp(de
->d_name
+ strlen(de
->d_name
) - 3, ".py", 3))
652 if (!(py_func
= PyObject_GetAttrString(py_cov
, "analysis2")))
654 if (!(py_pd
= PyUnicode_FromFormat("%s/%s", path
, de
->d_name
)))
656 if (!(py_result
= PyObject_CallFunction(py_func
, "O", py_pd
)))
663 if (PyTuple_Size(py_result
) != 5) {
664 ERR("Invalid result from coverage of '%s/%s'", path
, de
->d_name
);
667 num_lines
= PyList_Size(PyTuple_GetItem(py_result
, 1));
668 py_missed
= PyTuple_GetItem(py_result
, 3);
669 num_missed
= PyList_Size(py_missed
);
670 cvg_mod
->num_lines
+= num_lines
;
671 cvg_mod
->num_missed
+= num_missed
;
672 for (j
= 0; j
< num_missed
; j
++) {
673 py_item
= PyList_GetItem(py_missed
, j
);
674 linenum
= PyLong_AsLong(py_item
);
675 linespec
= g_strdup_printf("%s/%s:%d", module_name
,
676 de
->d_name
, linenum
);
677 cvg_mod
->missed_lines
= g_slist_append(cvg_mod
->missed_lines
, linespec
);
679 DBG("Coverage for %s/%s: %d lines, %d missed.",
680 module_name
, de
->d_name
, num_lines
, num_missed
);
681 Py_DecRef(py_result
);
684 if (cvg_mod
->num_lines
)
685 cvg_mod
->coverage
= 100 - ((float)cvg_mod
->num_missed
/ (float)cvg_mod
->num_lines
* 100);
693 static struct cvg
*cvg_new(void)
697 cvg
= calloc(1, sizeof(struct cvg
));
702 static gboolean
find_missed_line(struct cvg
*cvg
, const char *linespec
)
706 for (l
= cvg
->missed_lines
; l
; l
= l
->next
)
707 if (!strcmp(l
->data
, linespec
))
713 static void cvg_add(struct cvg
*dst
, const struct cvg
*src
)
718 dst
->num_lines
+= src
->num_lines
;
719 dst
->num_missed
+= src
->num_missed
;
720 for (l
= src
->missed_lines
; l
; l
= l
->next
) {
722 if (!find_missed_line(dst
, linespec
))
723 dst
->missed_lines
= g_slist_append(dst
->missed_lines
, linespec
);
728 static int report_coverage(PyObject
*py_cov
, GSList
*pdlist
)
730 PyObject
*py_func
, *py_mod
, *py_args
, *py_kwargs
, *py_outfile
, *py_pct
;
733 struct cvg
*cvg_mod
, *cvg_all
;
734 float total_coverage
;
735 int lines
, missed
, cnt
;
737 DBG("Making coverage report.");
739 /* Get coverage for each module in the stack. */
742 for (cnt
= 0, l
= pdlist
; l
; l
= l
->next
, cnt
++) {
744 if (!(cvg_mod
= get_mod_cov(py_cov
, pd
->name
)))
746 printf("coverage: scope=%s coverage=%.0f%% lines=%d missed=%d "
747 "missed_lines=", pd
->name
, cvg_mod
->coverage
,
748 cvg_mod
->num_lines
, cvg_mod
->num_missed
);
749 for (ml
= cvg_mod
->missed_lines
; ml
; ml
= ml
->next
) {
750 if (ml
!= cvg_mod
->missed_lines
)
752 printf("%s", (char *)ml
->data
);
755 lines
+= cvg_mod
->num_lines
;
756 missed
+= cvg_mod
->num_missed
;
757 cvg_add(cvg_all
, cvg_mod
);
758 DBG("Coverage for module %s: %d lines, %d missed", pd
->name
,
759 cvg_mod
->num_lines
, cvg_mod
->num_missed
);
763 total_coverage
= 100 - ((float)missed
/ (float)lines
* 100);
765 /* Machine-readable stats on stdout. */
766 printf("coverage: scope=all coverage=%.0f%% lines=%d missed=%d\n",
767 total_coverage
, cvg_all
->num_lines
, cvg_all
->num_missed
);
769 /* Write text report to file. */
770 /* io.open(coverage_report, "w") */
771 if (!(py_mod
= PyImport_ImportModule("io")))
773 if (!(py_func
= PyObject_GetAttrString(py_mod
, "open")))
775 if (!(py_args
= PyTuple_New(0)))
777 if (!(py_kwargs
= Py_BuildValue("{ssss}", "file", coverage_report
,
780 if (!(py_outfile
= PyObject_Call(py_func
, py_args
, py_kwargs
)))
782 Py_DecRef(py_kwargs
);
785 /* py_cov.report(file=py_outfile) */
786 if (!(py_func
= PyObject_GetAttrString(py_cov
, "report")))
788 if (!(py_kwargs
= Py_BuildValue("{sO}", "file", py_outfile
)))
790 if (!(py_pct
= PyObject_Call(py_func
, py_args
, py_kwargs
)))
793 Py_DecRef(py_kwargs
);
796 /* py_outfile.close() */
797 if (!(py_func
= PyObject_GetAttrString(py_outfile
, "close")))
799 if (!PyObject_Call(py_func
, py_args
, NULL
))
801 Py_DecRef(py_outfile
);
809 int main(int argc
, char **argv
)
814 struct channel
*channel
;
815 struct option
*option
;
818 char *opt_infile
, **kv
, **opstr
;
819 struct initial_pin_info
*initial_pin
;
821 op
= malloc(sizeof(struct output
));
833 while ((c
= getopt(argc
, argv
, "dP:p:o:N:i:O:f:c:S")) != -1) {
839 pd
= g_malloc(sizeof(struct pd
));
840 pd
->name
= g_strdup(optarg
);
841 pd
->channels
= pd
->options
= pd
->initial_pins
= NULL
;
842 pdlist
= g_slist_append(pdlist
, pd
);
847 if (g_slist_length(pdlist
) == 0) {
848 /* No previous -P. */
849 ERR("Syntax error at '%s'", optarg
);
852 kv
= g_strsplit(optarg
, "=", 0);
853 if (!kv
[0] || (!kv
[1] || kv
[2])) {
855 ERR("Syntax error at '%s'", optarg
);
860 channel
= malloc(sizeof(struct channel
));
861 channel
->name
= g_strdup(kv
[0]);
862 channel
->channel
= strtoul(kv
[1], NULL
, 10);
863 /* Apply to last PD. */
864 pd
->channels
= g_slist_append(pd
->channels
, channel
);
865 } else if (c
== 'o') {
866 option
= malloc(sizeof(struct option
));
867 option
->key
= g_strdup(kv
[0]);
868 option
->value
= g_variant_new_string(kv
[1]);
869 g_variant_ref_sink(option
->value
);
870 /* Apply to last PD. */
871 pd
->options
= g_slist_append(pd
->options
, option
);
873 initial_pin
= malloc(sizeof(struct initial_pin_info
));
874 initial_pin
->name
= g_strdup(kv
[0]);
875 initial_pin
->value
= strtoul(kv
[1], NULL
, 10);
876 /* Apply to last PD. */
877 pd
->initial_pins
= g_slist_append(pd
->initial_pins
, initial_pin
);
884 opstr
= g_strsplit(optarg
, ":", 0);
885 if (!opstr
[0] || !opstr
[1]) {
886 /* Need at least abc:def. */
887 ERR("Syntax error at '%s'", optarg
);
891 op
->pd
= g_strdup(opstr
[0]);
892 if (!strcmp(opstr
[1], "annotation"))
893 op
->type
= SRD_OUTPUT_ANN
;
894 else if (!strcmp(opstr
[1], "binary"))
895 op
->type
= SRD_OUTPUT_BINARY
;
896 else if (!strcmp(opstr
[1], "python"))
897 op
->type
= SRD_OUTPUT_PYTHON
;
898 else if (!strcmp(opstr
[1], "exception"))
899 /* Doesn't matter, we just need it to bomb out. */
900 op
->type
= SRD_OUTPUT_PYTHON
;
902 ERR("Unknown output type '%s'", opstr
[1]);
907 op
->class = g_strdup(opstr
[2]);
911 op
->outfile
= g_strdup(optarg
);
915 coverage_report
= optarg
;
926 if (g_slist_length(pdlist
) == 0)
930 if (!op
->pd
|| op
->type
== -1)
933 sr_log_callback_set(sr_log
, NULL
);
934 if (sr_init(&ctx
) != SR_OK
)
937 srd_log_callback_set(srd_log
, NULL
);
938 if (srd_init(DECODERS_DIR
) != SRD_OK
)
941 if (coverage_report
) {
942 if (!(coverage
= start_coverage(pdlist
))) {
943 DBG("Failed to start coverage.");
944 if (PyErr_Occurred()) {
952 if (!run_testcase(opt_infile
, pdlist
, op
))
956 DBG("Stopping coverage.");
958 if (!(PyObject_CallMethod(coverage
, "stop", NULL
)))
959 ERR("Failed to stop coverage.");
960 else if (!(report_coverage(coverage
, pdlist
)))
961 ERR("Failed to make coverage report.");
963 DBG("Coverage report in %s", coverage_report
);
965 if (PyErr_Occurred()) {