]> sigrok.org Git - libsigrok.git/commitdiff
device: introduce common helpers for channel group allocation
authorGerhard Sittig <redacted>
Wed, 26 Jan 2022 21:08:02 +0000 (22:08 +0100)
committerGerhard Sittig <redacted>
Sun, 6 Feb 2022 17:53:53 +0000 (18:53 +0100)
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.

src/device.c
src/input/logicport.c
src/libsigrok-internal.h

index 5a144d97ebccf3b160117b64f17c3be604e9367f..5a450fad7ad5f186ab0facdcfd9f84db18e3c2a4 100644 (file)
@@ -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);
index 354330ab453e9f800d5926cc2df081a59906e3c2..ea4cb39b252bb406aaf31bcb4a343128ed2dab9b 100644 (file)
 #include <libsigrok/libsigrok.h>
 #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))
index 6a70e8b14f4fbc5c7974e22e2a0ec91057384525..eba74e7dd016d9c1c2899959b16d7f38d855dbd1 100644 (file)
@@ -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. */