diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-15 07:10:56 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2020-08-15 09:46:19 -0700 |
commit | 77a11400a1ae2ab70ab5dc776c613c163549e183 (patch) | |
tree | e116083b41fd8c28ff1f0714eab8f5f493e37b8c /core | |
parent | e3a158624bd5b15451626907a30185ec4aaf0d87 (diff) | |
download | subsurface-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.c | 21 |
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; |