From bdd569664141ad3fa987caaae4266a473f006a87 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Mon, 16 Oct 2023 12:25:00 +0200 Subject: [PATCH] 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(). --- src/emu/pv/prv.c | 42 +++++++++++++++++++++++++++++++++++++----- src/emu/pv/prv.h | 9 +++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/emu/pv/prv.c b/src/emu/pv/prv.c index e7428b1..66e1453 100644 --- a/src/emu/pv/prv.c +++ b/src/emu/pv/prv.c @@ -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; diff --git a/src/emu/pv/prv.h b/src/emu/pv/prv.h index 67f503c..a15f939 100644 --- a/src/emu/pv/prv.h +++ b/src/emu/pv/prv.h @@ -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 {