Add PRV_SKIPDUPNULL flag

This flag allows to only skip duplicates if the value is null, otherwise
the value is emitted. Invalid combinations of PRV_* flags are also
checked on prv_register().
This commit is contained in:
Rodrigo Arias 2023-10-16 12:25:00 +02:00
parent 989685b134
commit bdd5696641
2 changed files with 42 additions and 9 deletions

View File

@ -94,15 +94,21 @@ emit(struct prv *prv, struct prv_chan *rchan)
return -1;
}
/* Only test for duplicates if not emitting them */
/* Only test for duplicates without PRV_EMITDUP */
if (~rchan->flags & PRV_EMITDUP) {
if (is_value_dup(rchan, &value)) {
if (rchan->flags & PRV_SKIPDUP)
return 0;
err("error duplicated value %s for channel %s",
value_str(value), chan->name);
return -1;
else if (rchan->flags & PRV_SKIPDUPNULL) {
if (value_is_null(value)) {
return 0;
}
/* Otherwise emit ... */
} else {
err("error duplicated value %s for channel %s",
value_str(value), chan->name);
return -1;
}
}
/* Only set when caring about duplicates */
@ -145,6 +151,27 @@ cb_prv(struct chan *chan, void *ptr)
return emit(prv, rchan);
}
static int
check_flags(long flags)
{
if ((flags & PRV_EMITDUP) && (flags & PRV_SKIPDUPNULL)) {
err("flags PRV_EMITDUP and PRV_SKIPDUPNULL are mutually exclusive");
return -1;
}
if ((flags & PRV_EMITDUP) && (flags & PRV_SKIPDUP)) {
err("flags PRV_EMITDUP and PRV_SKIPDUP are mutually exclusive");
return -1;
}
if ((flags & PRV_SKIPDUP) && (flags & PRV_SKIPDUPNULL)) {
err("flags PRV_SKIPDUP and PRV_SKIPDUPNULL are mutually exclusive");
return -1;
}
return 0;
}
int
prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags)
{
@ -162,6 +189,11 @@ prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan
return -1;
}
if (check_flags(flags) != 0) {
err("check_flags failed");
return -1;
}
rchan->id = id;
rchan->chan = chan;
rchan->row_base1 = row + 1;

View File

@ -13,10 +13,11 @@ struct bay;
struct chan;
enum prv_flags {
PRV_EMITDUP = 1<<0, /* Emit duplicates (no error, emit) */
PRV_SKIPDUP = 1<<1, /* Skip duplicates (no error, no emit) */
PRV_NEXT = 1<<2, /* Add one to the channel value */
PRV_ZERO = 1<<3, /* Value 0 is allowed */
PRV_EMITDUP = 1<<0, /* Emit duplicates (no error, emit) */
PRV_SKIPDUP = 1<<1, /* Skip duplicates (no error, no emit) */
PRV_NEXT = 1<<2, /* Add one to the channel value */
PRV_ZERO = 1<<3, /* Value 0 is allowed */
PRV_SKIPDUPNULL = 1<<4, /* Skip duplicates if the value is null (no error, no emit) */
};
struct prv_chan {