diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-19 14:11:37 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2017-02-19 15:23:46 -0800 |
commit | 4a550e4d7d5ec11640bb511d28097fa7644cdd3b (patch) | |
tree | f89ca8ee5c890a1d185a1f2c8aea8b3e1a0227b6 /core/divesite.c | |
parent | fc55620d2d2942f7f8d95b5e73f8b58ec17ffdb9 (diff) | |
download | subsurface-4a550e4d7d5ec11640bb511d28097fa7644cdd3b.tar.gz |
Properly handle dive sites loaded from XML
We used to always create a new dive site structure when loading dive
site data from XML.
That is completely bogus, because it can (and does) create duplicate
dive sites with the same UUID. Which makes the whole UUID pointless.
So instead, look up the existing dive site associated with the UUID
loaded from the XML, and try to merge the data properly if we already
had dive site information for that UUID.
Reported-by: Alessandro Volpi <volpial@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'core/divesite.c')
-rw-r--r-- | core/divesite.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/core/divesite.c b/core/divesite.c index e9eed2a07..2d7bdbefe 100644 --- a/core/divesite.c +++ b/core/divesite.c @@ -2,6 +2,7 @@ #include "divesite.h" #include "dive.h" #include "divelist.h" +#include "membuffer.h" #include <math.h> @@ -105,12 +106,10 @@ static uint32_t dive_site_getUniqId() struct dive_site *alloc_or_get_dive_site(uint32_t uuid) { struct dive_site *ds; - if (uuid) { - if ((ds = get_dive_site_by_uuid(uuid)) != NULL) { - fprintf(stderr, "PROBLEM: refusing to create dive site with the same uuid %08x\n", uuid); - return ds; - } - } + + if (uuid && (ds = get_dive_site_by_uuid(uuid)) != NULL) + return ds; + int nr = dive_site_table.nr; int allocated = dive_site_table.allocated; struct dive_site **sites = dive_site_table.dive_sites; @@ -205,7 +204,6 @@ uint32_t create_dive_site(const char *name, timestamp_t divetime) uint32_t uuid = create_divesite_uuid(name, divetime); struct dive_site *ds = alloc_or_get_dive_site(uuid); ds->name = copy_string(name); - return uuid; } @@ -273,6 +271,36 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy) } } +static void merge_string(char **a, char **b) +{ + char *s1 = *a, *s2 = *b; + + if (same_string(s1, s2)) + return; + + if (!s1) { + *a = strdup(s2); + return; + } + + *a = format_string("(%s) or (%s)", s1, s2); + free(s1); +} + +void merge_dive_site(struct dive_site *a, struct dive_site *b) +{ + if (!a->latitude.udeg) a->latitude.udeg = b->latitude.udeg; + if (!a->longitude.udeg) a->longitude.udeg = b->longitude.udeg; + merge_string(&a->name, &b->name); + merge_string(&a->notes, &b->notes); + merge_string(&a->description, &b->description); + + if (!a->taxonomy.category) { + a->taxonomy = b->taxonomy; + memset(&b->taxonomy, 0, sizeof(b->taxonomy)); + } +} + void clear_dive_site(struct dive_site *ds) { free(ds->name); |