summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2020-08-15 07:10:56 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2020-08-15 09:46:19 -0700
commit77a11400a1ae2ab70ab5dc776c613c163549e183 (patch)
treee116083b41fd8c28ff1f0714eab8f5f493e37b8c /core
parente3a158624bd5b15451626907a30185ec4aaf0d87 (diff)
downloadsubsurface-77a11400a1ae2ab70ab5dc776c613c163549e183.tar.gz
Fix event merging when merging dives
The merge_events() function was subtly and not-so-subtly broken in a couple of ways: - in commit 8c2383b49 ("Undo: don't modify source-dives on merge"), we stopped walking the event list after we merged the first event from a dive when the other dive computer had run out of events. In particular, this meant that when merging consecutive dives, the second dive only had the first event copied over to the merged dive. This happened because the original code just moved the whole old list over when there was nothing left from the other dive, so the old code didn't need to iterate over the event list. The new code didn't realize that the pointer movement used to copy the whole rest of the list, and also stopped iterating. In all fairness, the new code did get the time offset right, which the old code didn't. So this was always buggy. - similarly, the "avoid redundant gas changes" case was not handled for the "we ran out of events for the other dive computer" case. This fixes both issues. Cc: Berthold Stoeger <bstoeger@mail.tuwien.ac.at> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'core')
-rw-r--r--core/dive.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/core/dive.c b/core/dive.c
index b2f29db8b..d2a4ea23c 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -1962,20 +1962,15 @@ static void merge_events(struct dive *d, struct divecomputer *res,
const int *cylinders_map;
int event_offset;
- if (!b) {
- *p = clone_event(a);
- event_renumber(*p, cylinders_map1);
- break;
- }
- if (!a) {
- *p = clone_event(b);
- (*p)->time.seconds += offset;
- event_renumber(*p, cylinders_map2);
- break;
- }
+ if (!b)
+ goto pick_a;
+
+ if (!a)
+ goto pick_b;
+
s = sort_event(a, b, a->time.seconds, b->time.seconds + offset);
- /* Identical events? Just skip one of them (we pick a) */
+ /* Identical events? Just skip one of them (we skip a) */
if (!s) {
a = a->next;
continue;
@@ -1983,11 +1978,13 @@ static void merge_events(struct dive *d, struct divecomputer *res,
/* Otherwise, pick the one that sorts first */
if (s < 0) {
+pick_a:
pick = a;
a = a->next;
event_offset = 0;
cylinders_map = cylinders_map1;
} else {
+pick_b:
pick = b;
b = b->next;
event_offset = offset;