mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Merge extra_data list when merging two dives of the same dive computer
When merging two dives into a longer one, merge the dive computer extra_data list too. We just pick all the extra-data (but avoid entirely duplicate key/value entries). Note that this can cause confusing extra-data, in that both dives migth have things like "battery percentage at beginning/end of dive" keys, and if the values are different, you'll now get *both* of those values, but that's better than randomly just taking one of them. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
3184830f51
commit
baeb0ba280
1 changed files with 53 additions and 0 deletions
53
core/dive.c
53
core/dive.c
|
@ -2009,6 +2009,58 @@ static void merge_samples(struct divecomputer *res,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Does the extradata key/value pair already exist in the
|
||||
* supplied dive computer data?
|
||||
*
|
||||
* This is not hugely efficient (with the whole "do this for
|
||||
* every value you merge" it's O(n**2)) but it's not like we
|
||||
* have very many extra_data entries per dive computer anyway.
|
||||
*/
|
||||
static bool extra_data_exists(const struct extra_data *ed, const struct divecomputer *dc)
|
||||
{
|
||||
const struct extra_data *p;
|
||||
|
||||
for (p = dc->extra_data; p; p = p->next) {
|
||||
if (strcmp(p->key, ed->key))
|
||||
continue;
|
||||
if (strcmp(p->value, ed->value))
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merge extra_data.
|
||||
*
|
||||
* The extra data from 'a' has already been copied into 'res'. So
|
||||
* we really should just copy over the data from 'b' too.
|
||||
*/
|
||||
static void merge_extra_data(struct divecomputer *res,
|
||||
const struct divecomputer *a, const struct divecomputer *b)
|
||||
{
|
||||
struct extra_data **ed, *src;
|
||||
|
||||
// Find the place to add things in the result
|
||||
ed = &res->extra_data;
|
||||
while (*ed)
|
||||
ed = &(*ed)->next;
|
||||
|
||||
for (src = b->extra_data; src; src = src->next) {
|
||||
if (extra_data_exists(src, a))
|
||||
continue;
|
||||
*ed = malloc(sizeof(struct extra_data));
|
||||
if (!*ed)
|
||||
break;
|
||||
copy_extra_data(src, *ed);
|
||||
ed = &(*ed)->next;
|
||||
}
|
||||
|
||||
// Terminate the result list
|
||||
*ed = NULL;
|
||||
}
|
||||
|
||||
static char *merge_text(const char *a, const char *b, const char *sep)
|
||||
{
|
||||
char *res;
|
||||
|
@ -3110,6 +3162,7 @@ static void interleave_dive_computers(struct dive *d, struct divecomputer *res,
|
|||
if (match) {
|
||||
merge_events(d, res, a, match, cylinders_map_a, cylinders_map_b, offset);
|
||||
merge_samples(res, a, match, cylinders_map_a, cylinders_map_b, offset);
|
||||
merge_extra_data(res, a, match);
|
||||
/* Use the diveid of the later dive! */
|
||||
if (offset > 0)
|
||||
res->diveid = match->diveid;
|
||||
|
|
Loading…
Reference in a new issue