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>
This commit is contained in:
Linus Torvalds 2020-08-15 07:10:56 -07:00 committed by Dirk Hohndel
parent e3a158624b
commit 77a11400a1

View file

@ -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;