From: Gerhard Sittig Date: Wed, 26 Jan 2022 21:08:02 +0000 (+0100) Subject: device: introduce common helpers for channel group allocation X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=1e7468a8858768806a066f52d47d167a3721a8e4;p=libsigrok.git device: introduce common helpers for channel group allocation Provide common logic in device.c which allocates and releases an sr_channel_group struct. The logicport import module had a local implementation with a slightly different API. Accept an optional sdi reference to automatically extend the sdi->channel_groups member. --- diff --git a/src/device.c b/src/device.c index 5a144d97..5a450fad 100644 --- a/src/device.c +++ b/src/device.c @@ -255,6 +255,62 @@ SR_PRIV gboolean sr_channel_lists_differ(GSList *l1, GSList *l2) return FALSE; } +/** + * Allocate and initialize a new channel group, and add it to sdi. + * + * @param[in] sdi The device instance the channel group is connected to. + * Optional, can be NULL. + * @param[in] name @copydoc sr_channel_group::name + * @param[in] priv @copydoc sr_channel_group::priv + * + * @return A pointer to a new struct sr_channel_group, NULL upon error. + * + * @private + */ +SR_PRIV struct sr_channel_group *sr_channel_group_new(struct sr_dev_inst *sdi, + const char *name, void *priv) +{ + struct sr_channel_group *cg; + + cg = g_malloc0(sizeof(*cg)); + if (name && *name) + cg->name = g_strdup(name); + cg->priv = priv; + + if (sdi) + sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); + + return cg; +} + +/** + * Release a previously allocated struct sr_channel_group. + * + * @param[in] cg Pointer to struct sr_channel_group. + * + * @private + */ +SR_PRIV void sr_channel_group_free(struct sr_channel_group *cg) +{ + if (!cg) + return; + + g_free(cg->name); + g_slist_free(cg->channels); + g_free(cg->priv); + g_free(cg); +} + +/** + * Wrapper around sr_channel_group_free(), suitable for glib iterators. + * + * @private + */ +SR_PRIV void sr_channel_group_free_cb(void *cg) +{ + return sr_channel_group_free(cg); +} + /** * Determine whether the specified device instance has the specified * capability. @@ -448,7 +504,6 @@ SR_API int sr_dev_inst_channel_add(struct sr_dev_inst *sdi, int index, int type, SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi) { struct sr_channel *ch; - struct sr_channel_group *cg; GSList *l; if (!sdi) @@ -459,15 +514,7 @@ SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi) sr_channel_free(ch); } g_slist_free(sdi->channels); - - for (l = sdi->channel_groups; l; l = l->next) { - cg = l->data; - g_free(cg->name); - g_slist_free(cg->channels); - g_free(cg->priv); - g_free(cg); - } - g_slist_free(sdi->channel_groups); + g_slist_free_full(sdi->channel_groups, sr_channel_group_free_cb); if (sdi->session) sr_session_dev_remove(sdi->session, sdi); diff --git a/src/input/logicport.c b/src/input/logicport.c index 354330ab..ea4cb39b 100644 --- a/src/input/logicport.c +++ b/src/input/logicport.c @@ -60,10 +60,6 @@ #include #include "libsigrok-internal.h" -/* TODO: Move these helpers to some library API routine group. */ -struct sr_channel_group *sr_channel_group_new(const char *name, void *priv); -void sr_channel_group_free(struct sr_channel_group *cg); - #define LOG_PREFIX "input/logicport" #define MAX_CHANNELS 34 @@ -155,26 +151,6 @@ static void free_signal_group(struct signal_group_desc *desc) g_free(desc); } -struct sr_channel_group *sr_channel_group_new(const char *name, void *priv) -{ - struct sr_channel_group *cg; - - cg = g_malloc0(sizeof(*cg)); - if (name && *name) - cg->name = g_strdup(name); - cg->priv = priv; - - return cg; -} - -void sr_channel_group_free(struct sr_channel_group *cg) -{ - if (!cg) - return; - g_free(cg->name); - g_slist_free(cg->channels); -} - /* Wrapper for GDestroyNotify compatibility. */ static void sg_free(void *p) { @@ -802,10 +778,9 @@ static int create_channels_groups(struct sr_input *in) sdi = in->sdi; for (l = inc->signal_groups; l; l = l->next) { desc = l->data; - cg = sr_channel_group_new(desc->name, NULL); + cg = sr_channel_group_new(sdi, desc->name, NULL); if (!cg) return SR_ERR_MALLOC; - sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); mask = UINT64_C(1); for (idx = 0; idx < inc->channel_count; idx++, mask <<= 1) { if (!(desc->mask & mask)) diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index 6a70e8b1..eba74e7d 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -1645,6 +1645,11 @@ SR_PRIV struct sr_channel *sr_next_enabled_channel(const struct sr_dev_inst *sdi SR_PRIV gboolean sr_channels_differ(struct sr_channel *ch1, struct sr_channel *ch2); SR_PRIV gboolean sr_channel_lists_differ(GSList *l1, GSList *l2); +SR_PRIV struct sr_channel_group *sr_channel_group_new(struct sr_dev_inst *sdi, + const char *name, void *priv); +SR_PRIV void sr_channel_group_free(struct sr_channel_group *cg); +SR_PRIV void sr_channel_group_free_cb(void *cg); + /** Device instance data */ struct sr_dev_inst { /** Device driver. */