From: Gerhard Sittig Date: Sat, 13 Oct 2018 06:19:00 +0000 (+0200) Subject: device: introduce routines to compare channels and channel lists X-Git-Url: http://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=712f981dffbcb19291e86f41d565bf4627f3a5f4 device: introduce routines to compare channels and channel lists 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. --- diff --git a/src/device.c b/src/device.c index dbbb2e26..34d80a9d 100644 --- a/src/device.c +++ b/src/device.c @@ -18,8 +18,9 @@ */ #include -#include #include +#include +#include #include #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. diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index 6f43e8da..317cad4a 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -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 {