diff --git a/src/emu/pv/prv.c b/src/emu/pv/prv.c index 95c527d..e22f869 100644 --- a/src/emu/pv/prv.c +++ b/src/emu/pv/prv.c @@ -52,11 +52,17 @@ prv_close(struct prv *prv) return 0; } +static long +get_id(struct prv *prv, long type, long row) +{ + return type * prv->nrows + row; +} + static struct prv_chan * -find_prv_chan(struct prv *prv, const char *name) +find_prv_chan(struct prv *prv, long id) { struct prv_chan *rchan = NULL; - HASH_FIND_STR(prv->channels, name, rchan); + HASH_FIND_LONG(prv->channels, &id, rchan); return rchan; } @@ -145,10 +151,11 @@ cb_prv(struct chan *chan, void *ptr) int prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags) { - /* FIXME: use the type instead of channel name as key */ - struct prv_chan *rchan = find_prv_chan(prv, chan->name); + long id = get_id(prv, type, row); + struct prv_chan *rchan = find_prv_chan(prv, id); if (rchan != NULL) { - err("channel %s already registered", chan->name); + err("row=%ld type=%ld has channel '%s' registered", + row, type, chan->name); return -1; } @@ -158,6 +165,7 @@ prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan return -1; } + rchan->id = id; rchan->chan = chan; rchan->row_base1 = row + 1; rchan->type = type; @@ -173,7 +181,7 @@ prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan } /* Add to hash table */ - HASH_ADD_STR(prv->channels, chan->name, rchan); + HASH_ADD_LONG(prv->channels, id, rchan); return 0; } diff --git a/src/emu/pv/prv.h b/src/emu/pv/prv.h index 5154a11..0a2d62a 100644 --- a/src/emu/pv/prv.h +++ b/src/emu/pv/prv.h @@ -18,6 +18,7 @@ enum prv_flags { struct prv_chan { struct prv *prv; struct chan *chan; + long id; long row_base1; long type; long flags; diff --git a/src/include/uthash.h b/src/include/uthash.h index b0c2d2e..46c1be6 100644 --- a/src/include/uthash.h +++ b/src/include/uthash.h @@ -510,6 +510,12 @@ typedef unsigned char uint8_t; HASH_ADD(hh, head, intfield, sizeof(int), add) #define HASH_REPLACE_INT(head, intfield, add, replaced) \ HASH_REPLACE(hh, head, intfield, sizeof(int), add, replaced) +#define HASH_FIND_LONG(head, findlong, out) \ + HASH_FIND(hh, head, findlong, sizeof(long), out) +#define HASH_ADD_LONG(head, longfield, add) \ + HASH_ADD(hh, head, longfield, sizeof(long), add) +#define HASH_REPLACE_LONG(head, longfield, add, replaced) \ + HASH_REPLACE(hh, head, longfield, sizeof(long), add, replaced) #define HASH_FIND_PTR(head, findptr, out) \ HASH_FIND(hh, head, findptr, sizeof(void *), out) #define HASH_ADD_PTR(head, ptrfield, add) \ diff --git a/test/unit/prv.c b/test/unit/prv.c index 96d5930..5f52539 100644 --- a/test/unit/prv.c +++ b/test/unit/prv.c @@ -1,5 +1,7 @@ #define _GNU_SOURCE +#include "unittest.h" + #include "emu/pv/prv.h" #include "common.h" @@ -108,6 +110,32 @@ test_duplicate(const char *path) err("test duplicate OK\n"); } +/* Detect same types being registered to the same row */ +static void +test_same_type(const char *path) +{ + long type = 100; + long row = 0; + + struct bay bay; + bay_init(&bay); + + struct prv prv; + prv_open(&prv, NROWS, path); + + struct chan chan; + chan_init(&chan, CHAN_SINGLE, "testchan"); + + /* Allow setting the same value in the channel */ + chan_prop_set(&chan, CHAN_DUPLICATES, 1); + + OK(bay_register(&bay, &chan)); + OK(prv_register(&prv, row, type, &bay, &chan, 0)); + ERR(prv_register(&prv, row, type, &bay, &chan, 0)); + + err("ok"); +} + int main(void) { /* Create temporary trace file */ @@ -118,6 +146,7 @@ int main(void) test_emit(fname); test_duplicate(fname); + test_same_type(fname); close(fd);