summaryrefslogtreecommitdiff
path: root/decoder.c
diff options
context:
space:
mode:
authorUwe Hermann <uwe@hermann-uwe.de>2019-12-30 16:31:25 +0100
committerUwe Hermann <uwe@hermann-uwe.de>2019-12-31 17:40:16 +0100
commit1734f4c263201ae4b3aeab6b9ffc7f0eb23fdffd (patch)
tree2406e54c67e1778c918306df9d05c69abbb76907 /decoder.c
parentb7d7e99011eb2a4bfd493bfca2f386ad9916a6a2 (diff)
downloadlibsigrokdecode-1734f4c263201ae4b3aeab6b9ffc7f0eb23fdffd.tar.gz
libsigrokdecode-1734f4c263201ae4b3aeab6b9ffc7f0eb23fdffd.zip
srd_decoder_load(): Error out upon various duplicate IDs.
Diffstat (limited to 'decoder.c')
-rw-r--r--decoder.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/decoder.c b/decoder.c
index cef4f29..fc6ae07 100644
--- a/decoder.c
+++ b/decoder.c
@@ -668,6 +668,53 @@ SRD_PRIV long srd_decoder_apiver(const struct srd_decoder *d)
return apiver;
}
+static gboolean contains_duplicates(GSList *list)
+{
+ for (GSList *l1 = list; l1; l1 = l1->next) {
+ for (GSList *l2 = l1->next; l2; l2 = l2->next)
+ if (!strcmp(l1->data, l2->data))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean contains_duplicate_ids(GSList *list1, GSList *list2)
+{
+ for (GSList *l1 = list1; l1; l1 = l1->next) {
+ unsigned int cnt = 0;
+ const char **s1 = l1->data;
+ for (GSList *l2 = list2; l2; l2 = l2->next) {
+ const char **s2 = l2->data;
+ if (!strcmp(s1[0], s2[0]))
+ cnt++;
+ if ((list1 == list2) && cnt > 1)
+ return TRUE;
+ if ((list1 != list2) && cnt > 0)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean contains_duplicate_row_ids(GSList *list1, GSList *list2)
+{
+ for (GSList *l1 = list1; l1; l1 = l1->next) {
+ unsigned int cnt = 0;
+ const struct srd_decoder_annotation_row *r1 = l1->data;
+ for (GSList *l2 = list2; l2; l2 = l2->next) {
+ const struct srd_decoder_annotation_row *r2 = l2->data;
+ if (!strcmp(r1->id, r2->id))
+ cnt++;
+ if (cnt > 1)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/**
* Load a protocol decoder module into the embedded Python interpreter.
*
@@ -842,6 +889,61 @@ SRD_API int srd_decoder_load(const char *module_name)
goto err_out;
}
+ if (contains_duplicates(d->inputs)) {
+ fail_txt = "duplicate input IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicates(d->outputs)) {
+ fail_txt = "duplicate output IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicates(d->tags)) {
+ fail_txt = "duplicate tags";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->channels, d->channels)) {
+ fail_txt = "duplicate channel IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->opt_channels, d->opt_channels)) {
+ fail_txt = "duplicate optional channel IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->channels, d->opt_channels)) {
+ fail_txt = "channel and optional channel IDs contain duplicates";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->options, d->options)) {
+ fail_txt = "duplicate option IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->annotations, d->annotations)) {
+ fail_txt = "duplicate annotation class IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicate_row_ids(d->annotation_rows, d->annotation_rows)) {
+ fail_txt = "duplicate annotation row IDs";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->annotations, d->annotation_rows)) {
+ fail_txt = "annotation class/row IDs contain duplicates";
+ goto err_out;
+ }
+
+ if (contains_duplicate_ids(d->binary, d->binary)) {
+ fail_txt = "duplicate binary class IDs";
+ goto err_out;
+ }
+
PyGILState_Release(gstate);
/* Append it to the list of loaded decoders. */