pd_ann_visible = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
- pd_probe_maps = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- (GDestroyNotify)g_hash_table_destroy);
ret = 0;
pd_name = NULL;
- pd_opthash = options = probes = NULL;
+ pd_opthash = options = probes = pd_probe_maps = NULL;
pdtokens = g_strsplit(opt_pds, ",", 0);
for (pdtok = pdtokens; *pdtok; pdtok++) {
if (!(pd_opthash = parse_generic_arg(*pdtok, TRUE))) {
break;
}
- /* Save the probe setup for later. */
- g_hash_table_insert(pd_probe_maps, g_strdup(di->inst_id), probes);
- probes = NULL;
+ if (pdtok == pdtokens) {
+ /* Save the probe setup for later, but only on the first
+ * decoder -- stacked decoders don't get probes. */
+ pd_probe_maps = g_hash_table_new_full(g_str_hash,
+ g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy);
+ g_hash_table_insert(pd_probe_maps, g_strdup(di->inst_id), probes);
+ probes = NULL;
+ }
/* If no annotation list was specified, add them all in now.
* This will be pared down later to leave only the last PD
* in the stack.
*/
if (!opt_pd_annotations)
- g_hash_table_insert(pd_ann_visible,
- g_strdup(di->inst_id), GINT_TO_POINTER(-1));
+ g_hash_table_insert(pd_ann_visible, g_strdup(di->inst_id),
+ g_slist_append(NULL, GINT_TO_POINTER(-1)));
}
g_strfreev(pdtokens);
struct srd_decoder_inst *di;
GVariant *var;
void *probe_id;
- void *probe_target;
- struct sr_probe *probe;
+ void *channel_target;
+ struct sr_channel *ch;
GHashTableIter iter;
- int num_probes;
+ int num_channels;
probe_map = value;
probe_list = user_data;
(GDestroyNotify)g_variant_unref);
g_hash_table_iter_init(&iter, probe_map);
- while (g_hash_table_iter_next(&iter, &probe_id, &probe_target)) {
- probe = find_probe(probe_list, probe_target);
- if (!probe) {
- g_printerr("cli: No probe with name \"%s\" found.\n",
- (char *)probe_target);
+ while (g_hash_table_iter_next(&iter, &probe_id, &channel_target)) {
+ ch = find_channel(probe_list, channel_target);
+ if (!ch) {
+ g_printerr("cli: No channel with name \"%s\" found.\n",
+ (char *)channel_target);
continue;
}
- if (!probe->enabled)
- g_printerr("cli: Target probe \"%s\" not enabled.\n",
- (char *)probe_target);
+ if (!ch->enabled)
+ g_printerr("cli: Target channel \"%s\" not enabled.\n",
+ (char *)channel_target);
- var = g_variant_new_int32(probe->index);
+ var = g_variant_new_int32(ch->index);
g_variant_ref_sink(var);
g_hash_table_insert(probe_indices, g_strdup(probe_id), var);
}
- num_probes = g_slist_length(probe_list);
- srd_inst_probe_set_all(di, probe_indices, (num_probes + 7) / 8);
+ num_channels = g_slist_length(probe_list);
+ srd_inst_probe_set_all(di, probe_indices, (num_channels + 7) / 8);
}
void map_pd_probes(struct sr_dev_inst *sdi)
{
if (pd_probe_maps) {
g_hash_table_foreach(pd_probe_maps, &map_pd_inst_probes,
- sdi->probes);
+ sdi->channels);
g_hash_table_destroy(pd_probe_maps);
pd_probe_maps = NULL;
}
* the annotation list was specifically provided).
*/
if (!opt_pd_annotations)
- g_hash_table_remove(pd_ann_visible,
- di_from->inst_id);
+ g_hash_table_remove(pd_ann_visible, di_from->inst_id);
di_from = di_to;
}
int setup_pd_annotations(char *opt_pd_annotations)
{
- GSList *l;
+ GSList *l, *l_ann;
struct srd_decoder *dec;
int ann_class;
- char **pds, **pdtok, **keyval, **ann_descr;
+ char **pds, **pdtok, **keyval, **annlist, **ann, **ann_descr;
/* Set up custom list of PDs and annotations to show. */
pds = g_strsplit(opt_pd_annotations, ",", 0);
g_critical("Protocol decoder '%s' has no annotations.", keyval[0]);
return 1;
}
- ann_class = 0;
- if (g_strv_length(keyval) == 2) {
- for (l = dec->annotations; l; l = l->next, ann_class++) {
- ann_descr = l->data;
- if (!canon_cmp(ann_descr[0], keyval[1]))
- /* Found it. */
- break;
- }
- if (!l) {
- g_critical("Annotation '%s' not found "
- "for protocol decoder '%s'.", keyval[1], keyval[0]);
- return 1;
+ if (g_strv_length(keyval) == 2 && keyval[1][0] != '\0') {
+ annlist = g_strsplit(keyval[1], ":", 0);
+ for (ann = annlist; *ann && **ann; ann++) {
+ ann_class = 0;
+ for (l = dec->annotations; l; l = l->next, ann_class++) {
+ ann_descr = l->data;
+ if (!canon_cmp(ann_descr[0], *ann))
+ /* Found it. */
+ break;
+ }
+ if (!l) {
+ g_critical("Annotation '%s' not found "
+ "for protocol decoder '%s'.", *ann, keyval[0]);
+ return 1;
+ }
+ l_ann = g_hash_table_lookup(pd_ann_visible, keyval[0]);
+ l_ann = g_slist_append(l_ann, GINT_TO_POINTER(ann_class));
+ g_hash_table_replace(pd_ann_visible, g_strdup(keyval[0]), l_ann);
+ g_debug("cli: Showing protocol decoder %s annotation "
+ "class %d (%s).", keyval[0], ann_class, ann_descr[0]);
}
- g_debug("cli: Showing protocol decoder %s annotation "
- "class %d (%s).", keyval[0], ann_class, ann_descr[0]);
} else {
/* No class specified: show all of them. */
- ann_class = -1;
+ g_hash_table_insert(pd_ann_visible, g_strdup(keyval[0]),
+ g_slist_append(NULL, GINT_TO_POINTER(-1)));
g_debug("cli: Showing all annotation classes for protocol "
"decoder %s.", keyval[0]);
}
- g_hash_table_insert(pd_ann_visible, g_strdup(keyval[0]), GINT_TO_POINTER(ann_class));
g_strfreev(keyval);
}
g_strfreev(pds);
{
struct srd_decoder *dec;
struct srd_proto_data_annotation *pda;
- gpointer ann_format;
- int format, i;
+ GSList *ann_list, *l;
+ int i;
char **ann_descr;
+ gboolean show;
/* 'cb_data' is not used in this specific callback. */
(void)cb_data;
return;
if (!g_hash_table_lookup_extended(pd_ann_visible, pdata->pdo->di->inst_id,
- NULL, &ann_format))
+ NULL, (void **)&ann_list))
/* Not in the list of PDs whose annotations we're showing. */
return;
- format = GPOINTER_TO_INT(ann_format);
dec = pdata->pdo->di->decoder;
pda = pdata->data;
- if (format != -1 && pda->ann_format != format)
- /* We don't want this particular format from the PD. */
+ show = FALSE;
+ for (l = ann_list; l; l = l->next) {
+ if (GPOINTER_TO_INT(l->data) == -1
+ || GPOINTER_TO_INT(l->data) == pda->ann_format) {
+ show = TRUE;
+ break;
+ }
+ }
+ if (!show)
return;
if (opt_loglevel <= SR_LOG_WARN) {