]> sigrok.org Git - libsigrok.git/commitdiff
device: introduce routines to compare channels and channel lists
authorGerhard Sittig <redacted>
Sat, 13 Oct 2018 06:19:00 +0000 (08:19 +0200)
committerUwe Hermann <redacted>
Sat, 13 Oct 2018 13:17:51 +0000 (15:17 +0200)
Applications are not prepared to handle changes in the channel list
between multiple acquisitions from the same source (device drivers
or input modules). Introduce common helpers to compare channels and
channel lists.

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

index dbbb2e26ac122e446f4c4c4efcf66e16260a5a2a..34d80a9dadf45771b3751c1ba1a5917aba034900 100644 (file)
@@ -18,8 +18,9 @@
  */
 
 #include <config.h>
-#include <stdio.h>
 #include <glib.h>
+#include <stdio.h>
+#include <string.h>
 #include <libsigrok/libsigrok.h>
 #include "libsigrok-internal.h"
 
@@ -188,6 +189,69 @@ SR_PRIV struct sr_channel *sr_next_enabled_channel(const struct sr_dev_inst *sdi
        return next_channel;
 }
 
+/**
+ * Compare two channels, return whether they differ.
+ *
+ * The channels' names and types are checked. The enabled state is not
+ * considered a condition for difference. The test is motivated by the
+ * desire to detect changes in the configuration of acquisition setups
+ * between re-reads of an input file.
+ *
+ * @param[in] ch1 First channel.
+ * @param[in] ch2 Second channel.
+ *
+ * @return #TRUE upon differences or unexpected input, #FALSE otherwise.
+ *
+ * @internal
+ */
+SR_PRIV gboolean sr_channels_differ(struct sr_channel *ch1, struct sr_channel *ch2)
+{
+       if (!ch1 || !ch2)
+               return TRUE;
+
+       if (ch1->type != ch2->type)
+               return TRUE;
+       if (strcmp(ch1->name, ch2->name))
+               return TRUE;
+
+       return FALSE;
+}
+
+/**
+ * Compare two channel lists, return whether they differ.
+ *
+ * Listing the same set of channels but in a different order is considered
+ * a difference in the lists.
+ *
+ * @param[in] l1 First channel list.
+ * @param[in] l2 Second channel list.
+ *
+ * @return #TRUE upon differences or unexpected input, #FALSE otherwise.
+ *
+ * @internal
+ */
+SR_PRIV gboolean sr_channel_lists_differ(GSList *l1, GSList *l2)
+{
+       struct sr_channel *ch1, *ch2;
+
+       while (l1 && l2) {
+               ch1 = l1->data;
+               ch2 = l2->data;
+               l1 = l1->next;
+               l2 = l2->next;
+               if (!ch1 || !ch2)
+                       return TRUE;
+               if (sr_channels_differ(ch1, ch2))
+                       return TRUE;
+               if (ch1->index != ch2->index)
+                       return TRUE;
+       }
+       if (l1 || l2)
+               return TRUE;
+
+       return FALSE;
+}
+
 /**
  * Determine whether the specified device instance has the specified
  * capability.
index 6f43e8da78ac63d04c3de550dcd4d9e2b347994e..317cad4afd38e73558aebe19de7ce677f6476c70 100644 (file)
@@ -786,6 +786,8 @@ SR_PRIV void sr_channel_free(struct sr_channel *ch);
 SR_PRIV void sr_channel_free_cb(void *p);
 SR_PRIV struct sr_channel *sr_next_enabled_channel(const struct sr_dev_inst *sdi,
                struct sr_channel *cur_channel);
+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);
 
 /** Device instance data */
 struct sr_dev_inst {