diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-04-06 11:29:42 -1000 |
---|---|---|
committer | bstoeger <32835590+bstoeger@users.noreply.github.com> | 2019-04-07 20:11:32 +0200 |
commit | baeb0ba28029d1e9b348ac3933eaedecf3e15e81 (patch) | |
tree | ab654369e576d409a8350152f48971eb89c7008e /core/dive.c | |
parent | 3184830f513f7928f3d97cfb14b810d80c3bceb4 (diff) | |
download | subsurface-baeb0ba28029d1e9b348ac3933eaedecf3e15e81.tar.gz |
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>
Diffstat (limited to 'core/dive.c')
-rw-r--r-- | core/dive.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/core/dive.c b/core/dive.c index 3ee8e5e2c..7e3b30be9 100644 --- a/core/dive.c +++ b/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; |