From 79d0013e85ca5ee5086ece1528b4403777a01f96 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 28 Nov 2016 17:31:55 +0000 Subject: Look up instances by ID in the full stack srd_inst_find_by_id() previously only searched for instance IDs at the bottom of any stacked decoders. Make it properly search all stacks, just like srd_inst_find_by_obj() and more usefully when trying to generate unique instance IDs. No external API change, only the explicit behaviour of the API. This fixes parts of bug #868. Signed-off-by: Karl Palsson --- instance.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/instance.c b/instance.c index 79b72e1..5b98336 100644 --- a/instance.c +++ b/instance.c @@ -423,11 +423,43 @@ SRD_API int srd_inst_stack(struct srd_session *sess, return SRD_OK; } +/** + * Search a decoder instance and its stack for instance ID. + * + * @param[in] inst_id ID to search for. + * @param[in] stack A decoder instance, potentially with stacked instances. + * + * @return The matching instance, or NULL. + */ +static struct srd_decoder_inst *srd_inst_find_by_id_stack(const char *inst_id, + struct srd_decoder_inst *stack) +{ + const GSList *l; + struct srd_decoder_inst *tmp, *di; + + if (!strcmp(stack->inst_id, inst_id)) + return stack; + + /* Otherwise, look recursively in our stack. */ + di = NULL; + if (stack->next_di) { + for (l = stack->next_di; l; l = l->next) { + tmp = l->data; + if (!strcmp(tmp->inst_id, inst_id)) { + di = tmp; + break; + } + } + } + + return di; +} + /** * Find a decoder instance by its instance ID. * - * Only the bottom level of instances are searched -- instances already stacked - * on top of another one will not be found. + * This will recurse to find the instance anywhere in the stack tree of the + * given session. * * @param sess The session holding the protocol decoder instance. * @param inst_id The instance ID to be found. @@ -450,10 +482,8 @@ SRD_API struct srd_decoder_inst *srd_inst_find_by_id(struct srd_session *sess, di = NULL; for (l = sess->di_list; l; l = l->next) { tmp = l->data; - if (!strcmp(tmp->inst_id, inst_id)) { - di = tmp; + if (di = srd_inst_find_by_id_stack(inst_id, tmp)) break; - } } return di; -- cgit v1.2.3-70-g09d2