From 39aedc34ab864e95a395558f8b8d4be3beb11371 Mon Sep 17 00:00:00 2001 From: Daniel Elstner Date: Fri, 21 Feb 2014 20:10:09 +0100 Subject: [PATCH] decode: Defer probe setup until after the input probes are known --- decode.c | 137 ++++++++++++++++++++++++++++++++++++--------------- main.c | 29 +++++------ parsers.c | 2 +- sigrok-cli.h | 2 + 4 files changed, 114 insertions(+), 56 deletions(-) diff --git a/decode.c b/decode.c index 0b7d9ee..63679d4 100644 --- a/decode.c +++ b/decode.c @@ -25,6 +25,7 @@ static GHashTable *pd_ann_visible = NULL; static GHashTable *pd_meta_visible = NULL; static GHashTable *pd_binary_visible = NULL; +static GHashTable *pd_probe_maps = NULL; extern struct srd_session *srd_sess; extern gint opt_loglevel; @@ -74,42 +75,38 @@ static int opts_to_gvar(struct srd_decoder *dec, GHashTable *hash, return ret; } -static int probes_to_gvar(struct srd_decoder *dec, GHashTable *hash, - GHashTable **probes) +static int move_hash_element(GHashTable *src, GHashTable *dest, void *key) { + void *orig_key, *value; + + if (!g_hash_table_lookup_extended(src, key, &orig_key, &value)) + /* Not specified. */ + return FALSE; + g_hash_table_steal(src, orig_key); + g_hash_table_insert(dest, orig_key, value); + + return TRUE; +} + +static GHashTable *extract_probe_map(struct srd_decoder *dec, GHashTable *hash) +{ + GHashTable *probe_map; struct srd_probe *p; - GSList *all_probes, *l; - GVariant *gvar; - gint32 val_int; - int ret; - char *val_str, *conv; + GSList *l; - ret = TRUE; - *probes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)g_variant_unref); + probe_map = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_free); - all_probes = g_slist_copy(dec->probes); - all_probes = g_slist_concat(all_probes, g_slist_copy(dec->opt_probes)); - for (l = all_probes; l; l = l->next) { + for (l = dec->probes; l; l = l->next) { p = l->data; - if (!(val_str = g_hash_table_lookup(hash, p->id))) - /* Not specified. */ - continue; - val_int = strtoll(val_str, &conv, 10); - if (!conv || conv == val_str) { - g_critical("Protocol decoder '%s' probes '%s' " - "is not a number.", dec->name, p->id); - ret = FALSE; - break; - } - gvar = g_variant_new_int32(val_int); - g_variant_ref_sink(gvar); - g_hash_table_insert(*probes, g_strdup(p->id), gvar); - g_hash_table_remove(hash, p->id); + move_hash_element(hash, probe_map, p->id); + } + for (l = dec->opt_probes; l; l = l->next) { + p = l->data; + move_hash_element(hash, probe_map, p->id); } - g_slist_free(all_probes); - return ret; + return probe_map; } /* Register the given PDs for this session. @@ -126,8 +123,10 @@ int register_pds(const char *opt_pds, char *opt_pd_annotations) int ret; char **pdtokens, **pdtok, *pd_name; - pd_ann_visible = g_hash_table_new_full(g_str_hash, g_int_equal, - g_free, NULL); + 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; @@ -152,10 +151,8 @@ int register_pds(const char *opt_pds, char *opt_pd_annotations) ret = 1; break; } - if (!probes_to_gvar(dec, pd_opthash, &probes)) { - ret = 1; - break; - } + probes = extract_probe_map(dec, pd_opthash); + if (g_hash_table_size(pd_opthash) > 0) { leftover = g_hash_table_get_keys(pd_opthash); for (l = leftover; l; l = l->next) @@ -170,6 +167,10 @@ int register_pds(const char *opt_pds, char *opt_pd_annotations) break; } + /* Save the probe setup for later. */ + 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. @@ -177,12 +178,6 @@ int register_pds(const char *opt_pds, char *opt_pd_annotations) if (!opt_pd_annotations) g_hash_table_insert(pd_ann_visible, g_strdup(di->inst_id), GINT_TO_POINTER(-1)); - - /* Remap the probes if needed. */ - if (srd_inst_probe_set_all(di, probes, (g_hash_table_size(probes) + 7) / 8) != SRD_OK) { - ret = 1; - break; - } } g_strfreev(pdtokens); @@ -198,6 +193,66 @@ int register_pds(const char *opt_pds, char *opt_pd_annotations) return ret; } +static void map_pd_inst_probes(void *key, void *value, void *user_data) +{ + GHashTable *probe_map; + GHashTable *probe_indices; + GSList *probe_list; + struct srd_decoder_inst *di; + GVariant *var; + void *probe_id; + void *probe_target; + struct sr_probe *probe; + GHashTableIter iter; + int num_probes; + + probe_map = value; + probe_list = user_data; + + di = srd_inst_find_by_id(srd_sess, key); + if (!di) { + g_critical("Protocol decoder instance \"%s\" not found.", + (char *)key); + return; + } + probe_indices = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + (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); + continue; + } + if (probe->enabled) + g_printerr("cli: Mapping probe \"%s\" to \"%s\" " + "(index %d).\n", (char *)probe_id, + (char *)probe_target, probe->index); + else + g_printerr("cli: Target probe \"%s\" not enabled.\n", + (char *)probe_target); + + var = g_variant_new_int32(probe->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); +} + +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); + g_hash_table_destroy(pd_probe_maps); + pd_probe_maps = NULL; + } +} + int setup_pd_stack(char *opt_pds, char *opt_pd_stack, char *opt_pd_annotations) { struct srd_decoder_inst *di_from, *di_to; diff --git a/main.c b/main.c index 5dcee2c..271d28a 100644 --- a/main.c +++ b/main.c @@ -134,21 +134,22 @@ int select_probes(struct sr_dev_inst *sdi) struct sr_probe *probe; GSList *selected_probes, *l; - if (!opt_probes) - return SR_OK; - - if (!(selected_probes = parse_probestring(sdi, opt_probes))) - return SR_ERR; - - for (l = sdi->probes; l; l = l->next) { - probe = l->data; - if (g_slist_find(selected_probes, probe)) - probe->enabled = TRUE; - else - probe->enabled = FALSE; + if (opt_probes) { + if (!(selected_probes = parse_probestring(sdi, opt_probes))) + return SR_ERR; + + for (l = sdi->probes; l; l = l->next) { + probe = l->data; + if (g_slist_find(selected_probes, probe)) + probe->enabled = TRUE; + else + probe->enabled = FALSE; + } + g_slist_free(selected_probes); } - g_slist_free(selected_probes); - +#ifdef HAVE_SRD + map_pd_probes(sdi); +#endif return SR_OK; } diff --git a/parsers.c b/parsers.c index 43b61b6..d575dce 100644 --- a/parsers.c +++ b/parsers.c @@ -24,7 +24,7 @@ #include #include -static struct sr_probe *find_probe(GSList *probelist, const char *probename) +struct sr_probe *find_probe(GSList *probelist, const char *probename) { struct sr_probe *probe; GSList *l; diff --git a/sigrok-cli.h b/sigrok-cli.h index 4d2f0f2..6d63511 100644 --- a/sigrok-cli.h +++ b/sigrok-cli.h @@ -63,9 +63,11 @@ int setup_pd_binary(char *opt_pd_binary); void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data); void show_pd_meta(struct srd_proto_data *pdata, void *cb_data); void show_pd_binary(struct srd_proto_data *pdata, void *cb_data); +void map_pd_probes(struct sr_dev_inst *sdi); #endif /* parsers.c */ +struct sr_probe *find_probe(GSList *probelist, const char *probename); GSList *parse_probestring(struct sr_dev_inst *sdi, const char *probestring); GHashTable *parse_generic_arg(const char *arg, gboolean sep_first); int canon_cmp(const char *str1, const char *str2); -- 2.30.2