From 9084bbae578b3996d8e8c7adb74ef9bb25da6720 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 29 Apr 2017 16:21:41 -0700 Subject: Fix event merging when interleaving dives The core to avoid adding redundant gas switch events was completely buggered, and caused the result list to be corrupted if it ever triggered. This should fix it. Fixes: b5de08b7 ("No gas change event on merging dives with same gas") Reported-by: Jan Mulder Cc: Miika Turkia Cc: Dirk Hohndel Signed-off-by: Linus Torvalds Signed-off-by: Dirk Hohndel --- core/dive.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'core/dive.c') diff --git a/core/dive.c b/core/dive.c index b4a015c1f..e71249413 100644 --- a/core/dive.c +++ b/core/dive.c @@ -1783,6 +1783,7 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st { struct event *a, *b; struct event **p = &res->events; + struct event *last_gas = NULL; /* Always use positive offsets */ if (offset < 0) { @@ -1804,6 +1805,8 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st while (a || b) { int s; + struct event *pick; + if (!b) { *p = a; break; @@ -1814,32 +1817,34 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st } s = sort_event(a, b); - /* No gas change event when continuing with same gas */ - if (same_gas(a, b)) { - if (s > 0) { - p = &b->next; - b = b->next; - } else { - p = &a->next; - a = a->next; - } + /* Identical events? Just skip one of them (we pick a) */ + if (!s) { + a = a->next; continue; } - /* Pick b */ - if (s > 0) { - *p = b; - p = &b->next; + /* Otherwise, pick the one that sorts first */ + if (s < 0) { + pick = a; + a = a->next; + } else { + pick = b; b = b->next; - continue; } - /* Pick 'a' or neither */ - if (s < 0) { - *p = a; - p = &a->next; + + /* + * If that's a gas-change that matches the previous + * gas change, we'll just skip it + */ + if (event_is_gaschange(pick)) { + if (last_gas && same_gas(pick, last_gas)) + continue; + last_gas = pick; } - a = a->next; - continue; + + /* Add it to the target list */ + *p = pick; + p = &pick->next; } } -- cgit v1.2.3-70-g09d2