From dcfda29da6d5539c602935f3518749942dad2153 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 11 Feb 2015 11:22:00 -0800 Subject: Add dive site data structure This leaves location and gps coordinates in the struct dive to allow a step by step migration. Signed-off-by: Dirk Hohndel --- divesite.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 divesite.h (limited to 'divesite.h') diff --git a/divesite.h b/divesite.h new file mode 100644 index 000000000..e11a10738 --- /dev/null +++ b/divesite.h @@ -0,0 +1,47 @@ +#ifndef DIVESITE_H +#define DIVESITE_H + +#include "units.h" +#include + +struct dive_site +{ + uint32_t uuid; + char *name; + degrees_t latitude, longitude; + char *description; + char *notes; +}; + +struct dive_site_table { + int nr, allocated; + struct dive_site **dive_sites; +}; + +extern struct dive_site_table dive_site_table; + +static inline struct dive_site *get_dive_site(int nr) +{ + if (nr >= dive_site_table.nr || nr < 0) + return NULL; + return dive_site_table.dive_sites[nr]; +} + +static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) +{ + for (int i = 0; i < dive_site_table.nr; i++) + if (get_dive_site(i)->uuid == uuid) + return get_dive_site(i); + return NULL; +} + +/* there could be multiple sites of the same name - return the first one */ +static inline struct dive_site *get_dive_site_by_name(const char *name) +{ + for (int i = 0; i < dive_site_table.nr; i++) + if (get_dive_site(i)->name == name) + return get_dive_site(i); + return NULL; +} + +#endif // DIVESITE_H -- cgit v1.2.3-70-g09d2 From e720c82aa1abac491ee48f39a69fe88620115bfc Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 12 Feb 2015 11:19:05 -0800 Subject: Some dive site helper functions Signed-off-by: Dirk Hohndel --- divesite.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ divesite.h | 10 +++++++--- 2 files changed, 64 insertions(+), 3 deletions(-) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index 1d3bb1c0d..21efaf2e6 100644 --- a/divesite.c +++ b/divesite.c @@ -1,2 +1,59 @@ /* divesite.c */ #include "divesite.h" +#include "dive.h" + +struct dive_site_table dive_site_table; + +/* try to create a uniqe ID - fingers crossed */ +static uint32_t dive_site_getUniqId() +{ + uint32_t id = 0; + + while (id == 0 || get_dive_site_by_uuid(id)) + id = random() + random(); + + return id; +} + +struct dive_site *alloc_dive_site() +{ + int nr = dive_site_table.nr, allocated = dive_site_table.allocated; + struct dive_site **sites = dive_site_table.dive_sites; + + if (nr >= allocated) { + allocated = (nr + 32) * 3 / 2; + sites = realloc(sites, allocated * sizeof(struct dive_site *)); + if (!sites) + exit(1); + dive_site_table.dive_sites = sites; + dive_site_table.allocated = allocated; + } + struct dive_site *ds = calloc(1, sizeof(*ds)); + if (!ds) + exit(1); + sites[nr] = ds; + dive_site_table.nr = nr + 1; + return ds; +} + +/* allocate a new site and add it to the table */ +uint32_t create_dive_site(const char *name, degrees_t latitude, degrees_t longitude) +{ + struct dive_site *ds = alloc_dive_site(); + ds->uuid = dive_site_getUniqId(); + ds->name = copy_string(name); + ds->latitude = latitude; + ds->longitude = longitude; + + return ds->uuid; +} + +/* this either returns the uuid for a site with that name or creates an entry */ +uint32_t dive_site_uuid_by_name(const char *name) +{ + uint32_t id = get_dive_site_uuid_by_name(name); + if (id == 0) + id = create_dive_site(name, (degrees_t){0}, (degrees_t){0}); + + return id; +} diff --git a/divesite.h b/divesite.h index e11a10738..da0a78983 100644 --- a/divesite.h +++ b/divesite.h @@ -36,12 +36,16 @@ static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) } /* there could be multiple sites of the same name - return the first one */ -static inline struct dive_site *get_dive_site_by_name(const char *name) +static inline uint32_t get_dive_site_uuid_by_name(const char *name) { for (int i = 0; i < dive_site_table.nr; i++) if (get_dive_site(i)->name == name) - return get_dive_site(i); - return NULL; + return get_dive_site(i)->uuid; + return 0; } +struct dive_site *alloc_dive_site(); +uint32_t create_dive_site(const char *name, degrees_t latitude, degrees_t longitude); +uint32_t dive_site_uuid_by_name(const char *name); + #endif // DIVESITE_H -- cgit v1.2.3-70-g09d2 From 801e584029688eca38d35542e8ab3d644833231b Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 12 Feb 2015 01:26:57 -0800 Subject: Another helper: for_each_dive_site() This doesn't make the code necessarily more compact, but easier to read and is consistent with our other patterns. Signed-off-by: Dirk Hohndel --- divesite.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'divesite.h') diff --git a/divesite.h b/divesite.h index da0a78983..2a4d8c616 100644 --- a/divesite.h +++ b/divesite.h @@ -27,10 +27,16 @@ static inline struct dive_site *get_dive_site(int nr) return dive_site_table.dive_sites[nr]; } +/* iterate over each dive site */ +#define for_each_dive_site(_i, _x) \ + for ((_i) = 0; ((_x) = get_dive_site(_i)) != NULL; (_i)++) + static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) { - for (int i = 0; i < dive_site_table.nr; i++) - if (get_dive_site(i)->uuid == uuid) + int i; + struct dive_site *ds; + for_each_dive_site (i, ds) + if (ds->uuid == uuid) return get_dive_site(i); return NULL; } @@ -38,9 +44,11 @@ static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) /* there could be multiple sites of the same name - return the first one */ static inline uint32_t get_dive_site_uuid_by_name(const char *name) { - for (int i = 0; i < dive_site_table.nr; i++) - if (get_dive_site(i)->name == name) - return get_dive_site(i)->uuid; + int i; + struct dive_site *ds; + for_each_dive_site (i, ds) + if (ds->name == name) + return ds->uuid; return 0; } -- cgit v1.2.3-70-g09d2 From cd28e88bee085b1f12561764b87a9b8ffc0a8212 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 12 Feb 2015 01:59:16 -0800 Subject: Improve helper functions Sometimes we want to create a dive site just based on a name, sometimes we have both a name and GPS coordinates. Let's make a helper for either case. Signed-off-by: Dirk Hohndel --- divesite.c | 14 ++++++++++++-- divesite.h | 10 +++++++++- parse-xml.c | 10 +++++----- 3 files changed, 26 insertions(+), 8 deletions(-) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index 21efaf2e6..c3bb45950 100644 --- a/divesite.c +++ b/divesite.c @@ -37,7 +37,17 @@ struct dive_site *alloc_dive_site() } /* allocate a new site and add it to the table */ -uint32_t create_dive_site(const char *name, degrees_t latitude, degrees_t longitude) +uint32_t create_dive_site(const char *name) +{ + struct dive_site *ds = alloc_dive_site(); + ds->uuid = dive_site_getUniqId(); + ds->name = copy_string(name); + + return ds->uuid; +} + +/* same as before, but with GPS data */ +uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude) { struct dive_site *ds = alloc_dive_site(); ds->uuid = dive_site_getUniqId(); @@ -53,7 +63,7 @@ uint32_t dive_site_uuid_by_name(const char *name) { uint32_t id = get_dive_site_uuid_by_name(name); if (id == 0) - id = create_dive_site(name, (degrees_t){0}, (degrees_t){0}); + id = create_dive_site(name); return id; } diff --git a/divesite.h b/divesite.h index 2a4d8c616..b3487c341 100644 --- a/divesite.h +++ b/divesite.h @@ -4,6 +4,10 @@ #include "units.h" #include +#ifdef __cplusplus +extern "C" { +#endif + struct dive_site { uint32_t uuid; @@ -53,7 +57,11 @@ static inline uint32_t get_dive_site_uuid_by_name(const char *name) } struct dive_site *alloc_dive_site(); -uint32_t create_dive_site(const char *name, degrees_t latitude, degrees_t longitude); +uint32_t create_dive_site(const char *name); +uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude); uint32_t dive_site_uuid_by_name(const char *name); +#ifdef __cplusplus +} +#endif #endif // DIVESITE_H diff --git a/parse-xml.c b/parse-xml.c index 4377a32cb..54e74b953 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -983,7 +983,7 @@ static void divinglog_place(char *place, uint32_t *uuid) country ? country : ""); *uuid = get_dive_site_uuid_by_name(buffer); if (*uuid == 0) - *uuid = create_dive_site(buffer, (degrees_t){0}, (degrees_t){0}); + *uuid = create_dive_site(buffer); city = NULL; country = NULL; @@ -1156,7 +1156,7 @@ static void gps_in_dive(char *buffer, struct dive *dive) uint32_t uuid = dive->dive_site_uuid; if (uuid == 0) { fprintf(stderr, "found no uuid in dive, creating a divesite without name and above GPS\n"); - dive->dive_site_uuid = create_dive_site("", latitude, longitude); + dive->dive_site_uuid = create_dive_site_with_gps("", latitude, longitude); } else { fprintf(stderr, "found uuid in dive, checking to see if we should add GPS\n"); struct dive_site *ds = get_dive_site_by_uuid(uuid); @@ -1193,7 +1193,7 @@ static void add_dive_site(char *buffer, struct dive *dive) exit(1); } } else { - dive->dive_site_uuid = create_dive_site(buffer, (degrees_t){0}, (degrees_t){0}); + dive->dive_site_uuid = create_dive_site(buffer); } } } @@ -1437,7 +1437,7 @@ static void dive_site_end(void) if (!cur_dive_site) return; if (cur_dive_site->uuid) { - uint32_t tmp = create_dive_site(cur_dive_site->name, cur_dive_site->latitude, cur_dive_site->longitude); + uint32_t tmp = create_dive_site_with_gps(cur_dive_site->name, cur_dive_site->latitude, cur_dive_site->longitude); struct dive_site *ds = get_dive_site_by_uuid(tmp); ds->uuid = cur_dive_site->uuid; ds->notes = cur_dive_site->notes; @@ -2502,7 +2502,7 @@ extern int cobalt_location(void *handle, int columns, char **data, char **column sprintf(tmp, "%s / %s", location, data[0]); free(location); location = NULL; - cur_dive->dive_site_uuid = create_dive_site(tmp, (degrees_t){0}, (degrees_t){0}); + cur_dive->dive_site_uuid = create_dive_site(tmp); } else { location = strdup(data[0]); } -- cgit v1.2.3-70-g09d2 From 0ce215e0d90e8d7612917b75f73bb703b9ada9ae Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 12 Feb 2015 12:28:54 -0800 Subject: Fix dive site creation from v2 git storage Clearly didn't test that part well enough. Signed-off-by: Dirk Hohndel --- divesite.c | 14 ++++++++++++++ divesite.h | 1 + load-git.c | 23 +++++++++++++++-------- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index c9dbb095a..d9351e1af 100644 --- a/divesite.c +++ b/divesite.c @@ -67,3 +67,17 @@ uint32_t dive_site_uuid_by_name(const char *name) return id; } + +/* if the uuid is valid, just get the site, otherwise create it first; + * so you can call this with dive->dive_site_uuid and you'll either get the existing + * dive site or it will create a new one - so make sure you assign the uuid back to + * dive->dive_site_uuid when using this function! */ +struct dive_site *get_or_create_dive_site_by_uuid(uint32_t uuid) +{ + struct dive_site *ds = get_dive_site_by_uuid(uuid); + + if (!ds) + ds = alloc_dive_site(); + + return ds; +} diff --git a/divesite.h b/divesite.h index b3487c341..f0cf08067 100644 --- a/divesite.h +++ b/divesite.h @@ -60,6 +60,7 @@ struct dive_site *alloc_dive_site(); uint32_t create_dive_site(const char *name); uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude); uint32_t dive_site_uuid_by_name(const char *name); +struct dive_site *get_or_create_dive_site_by_uuid(uint32_t uuid); #ifdef __cplusplus } diff --git a/load-git.c b/load-git.c index 7bd020bd5..4fcf1f600 100644 --- a/load-git.c +++ b/load-git.c @@ -23,13 +23,6 @@ struct keyword_action { #define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) extern degrees_t parse_degrees(char *buf, char **end); -static void parse_dive_gps(char *line, struct membuffer *str, void *_dive) -{ - struct dive *dive = _dive; - - dive->latitude = parse_degrees(line, &line); - dive->longitude = parse_degrees(line, &line); -} static char *get_utf8(struct membuffer *b) { @@ -145,8 +138,22 @@ static int get_index(const char *line) static int get_hex(const char *line) { return strtoul(line, NULL, 16); } +static void parse_dive_gps(char *line, struct membuffer *str, void *_dive) +{ + struct dive *dive = _dive; + struct dive_site *ds = get_or_create_dive_site_by_uuid(dive->dive_site_uuid); + dive->dive_site_uuid = ds->uuid; + ds->latitude = parse_degrees(line, &line); + ds->longitude = parse_degrees(line, &line); +} + static void parse_dive_location(char *line, struct membuffer *str, void *_dive) -{ struct dive *dive = _dive; dive->location = get_utf8(str); } +{ + struct dive *dive = _dive; + struct dive_site *ds = get_or_create_dive_site_by_uuid(dive->dive_site_uuid); + dive->dive_site_uuid = ds->uuid; + ds->name = get_utf8(str); +} static void parse_dive_divemaster(char *line, struct membuffer *str, void *_dive) { struct dive *dive = _dive; dive->divemaster = get_utf8(str); } -- cgit v1.2.3-70-g09d2 From 8c3efd2a22959f684b7604a405d66abc0831a9e1 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 13 Feb 2015 00:04:14 -0800 Subject: Improve parsing of older XML files in order to auto create dive sites While the existing code worked with a couple of hand crafted examples it turns out it did a poor job with most of my files. Oops. Depending on whether we find name or coordinates first, we need to identify existing sites in either case and do the right thing. The challeng here are multiple dives at the same site with slightly different GPS coordinates. If the name is read first, these all get merged into one (and we warn about the different GPS data). But if GPS gets read first, we create separate dive sites with the same name. We need a sane UI to consolidate these - but we can't completely automate this... it's possible that these ARE the same site and the GPS data is just imprecise (for example, multiple dives at the same time with GPS locations from the Subsurface companion app). The user should be able to either pick one of the GPS locations, or keep multiple (for example, different buoyes for the same site and you want to keep the different markers). Signed-off-by: Dirk Hohndel --- divesite.c | 10 ---------- divesite.h | 26 ++++++++++++++++++++++---- parse-xml.c | 54 ++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 60 insertions(+), 30 deletions(-) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index d9351e1af..bccbe37e2 100644 --- a/divesite.c +++ b/divesite.c @@ -58,16 +58,6 @@ uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees return ds->uuid; } -/* this either returns the uuid for a site with that name or creates an entry */ -uint32_t dive_site_uuid_by_name(const char *name) -{ - uint32_t id = get_dive_site_uuid_by_name(name); - if (id == 0) - id = create_dive_site(name); - - return id; -} - /* if the uuid is valid, just get the site, otherwise create it first; * so you can call this with dive->dive_site_uuid and you'll either get the existing * dive site or it will create a new one - so make sure you assign the uuid back to diff --git a/divesite.h b/divesite.h index f0cf08067..5b1d1959d 100644 --- a/divesite.h +++ b/divesite.h @@ -46,20 +46,38 @@ static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) } /* there could be multiple sites of the same name - return the first one */ -static inline uint32_t get_dive_site_uuid_by_name(const char *name) +static inline uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp) { int i; struct dive_site *ds; - for_each_dive_site (i, ds) - if (ds->name == name) + for_each_dive_site (i, ds) { + if (ds->name == name) { + if (dsp) + *dsp = ds; + return ds->uuid; + } + } + return 0; +} + +/* there could be multiple sites at the same GPS fix - return the first one */ +static inline uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp) +{ + int i; + struct dive_site *ds; + for_each_dive_site (i, ds) { + if (ds->latitude.udeg == latitude.udeg && ds->longitude.udeg == longitude.udeg) { + if (dsp) + *dsp = ds; return ds->uuid; + } + } return 0; } struct dive_site *alloc_dive_site(); uint32_t create_dive_site(const char *name); uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude); -uint32_t dive_site_uuid_by_name(const char *name); struct dive_site *get_or_create_dive_site_by_uuid(uint32_t uuid); #ifdef __cplusplus diff --git a/parse-xml.c b/parse-xml.c index 6cc2d881a..55744d275 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -982,7 +982,7 @@ static void divinglog_place(char *place, uint32_t *uuid) city ? city : "", country ? ", " : "", country ? country : ""); - *uuid = get_dive_site_uuid_by_name(buffer); + *uuid = get_dive_site_uuid_by_name(buffer, NULL); if (*uuid == 0) *uuid = create_dive_site(buffer); @@ -1165,14 +1165,20 @@ static void gps_location(char *buffer, struct dive_site *ds) static void gps_in_dive(char *buffer, struct dive *dive) { char *end; - fprintf(stderr, "called gps_in_dive with buffer |%s|\n", buffer); + struct dive_site *ds = NULL; degrees_t latitude = parse_degrees(buffer, &end); degrees_t longitude = parse_degrees(end, &end); fprintf(stderr, "got lat %f lon %f\n", latitude.udeg / 1000000.0, longitude.udeg / 1000000.0); uint32_t uuid = dive->dive_site_uuid; if (uuid == 0) { - fprintf(stderr, "found no uuid in dive, creating a divesite without name and above GPS\n"); - dive->dive_site_uuid = create_dive_site_with_gps("", latitude, longitude); + uuid = get_dive_site_uuid_by_gps(latitude, longitude, &ds); + if (ds) { + fprintf(stderr, "found dive site {%s} with these coordinates\n", ds->name); + dive->dive_site_uuid = uuid; + } else { + fprintf(stderr, "found no uuid in dive, no existing dive site with these coordinates, creating a new divesite without name and above GPS\n"); + dive->dive_site_uuid = create_dive_site_with_gps("", latitude, longitude); + } } else { fprintf(stderr, "found uuid in dive, checking to see if we should add GPS\n"); struct dive_site *ds = get_dive_site_by_uuid(uuid); @@ -1183,6 +1189,13 @@ static void gps_in_dive(char *buffer, struct dive *dive) fprintf(stderr, "dive site uuid in dive, but gps location (%10.6f/%10.6f) different from dive location (%10.6f/%10.6f)\n", ds->latitude.udeg / 1000000.0, ds->longitude.udeg / 1000000.0, latitude.udeg / 1000000.0, longitude.udeg / 1000000.0); + int len = ds->notes ? strlen(ds->notes) : 0; + len += sizeof("\nalternative coordinates") + 24; + char *notes = malloc(len); + snprintf(notes, len, "%s\nalternative coordinates %11.6f/%11.6f", + ds->notes ?: "", latitude.udeg / 1000000.0, longitude.udeg / 1000000.0); + free(ds->notes); + ds->notes = notes; } else { fprintf(stderr, "let's add the gps coordinates to divesite with uuid %8x and name %s\n", ds->uuid, ds->name ?: "(none)"); ds->latitude = latitude; @@ -1194,21 +1207,30 @@ static void gps_in_dive(char *buffer, struct dive *dive) static void add_dive_site(char *buffer, struct dive *dive) { fprintf(stderr, "add_dive_site with name %s\n", buffer); - int size; - size = trimspace(buffer); + int size = trimspace(buffer); if(size) { - if (dive->dive_site_uuid) { - // we have a uuid, let's hope there's no name - struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid); - if (!ds) { - fprintf(stderr, "dive contains a non-existing dive site uuid %x\n", dive->dive_site_uuid); - exit(1); - } - if (!same_string(ds->name, buffer)) { - fprintf(stderr, "dive links to dive site of different name %s / %s\n", ds->name, buffer); - exit(1); + uint32_t uuid = dive->dive_site_uuid; + struct dive_site *ds = get_dive_site_by_uuid(uuid); + if (uuid && !ds) { + // that's strange - we have a uuid but it doesn't exist - let's just ignore it + fprintf(stderr, "dive contains a non-existing dive site uuid %x\n", dive->dive_site_uuid); + uuid = 0; + } + if (!uuid) + // if the dive doesn't have a uuid, check if there's already a dive site by this name + uuid = get_dive_site_uuid_by_name(buffer, &ds); + if (ds) { + // we have a uuid, let's hope there isn't a different name + fprintf(stderr, "have existing site with name {%s} gps %f/%f ", ds->name, ds->latitude.udeg / 1000000.0, ds->longitude.udeg / 1000000.0); + if (same_string(ds->name, "")) { + fprintf(stderr, "so now add name {%s}\n", buffer); + ds->name = copy_string(buffer); + } else if (!same_string(ds->name, buffer)) { + // coin toss, let's just keep the first name we found + fprintf(stderr, "which means the dive already links to dive site of different name {%s} / {%s}\n", ds->name, buffer); } } else { + fprintf(stderr, "no uuid, create new dive site with name {%s}\n", buffer); dive->dive_site_uuid = create_dive_site(buffer); } } -- cgit v1.2.3-70-g09d2 From d2baa3631270f8b9bcd612f971d269f5d06fca79 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 13 Feb 2015 01:14:33 -0800 Subject: Improve dive site creation from v2 git storage Fix broken helper function, move helper functions into the .c file (there really wasn't a good reason for these to be inline), fix the logic that decides if we want to create a new dive site or use an existing one. Signed-off-by: Dirk Hohndel --- divesite.c | 44 ++++++++++++++++++++++++++++++-------------- divesite.h | 33 ++------------------------------- load-git.c | 35 ++++++++++++++++++++++++++++------- 3 files changed, 60 insertions(+), 52 deletions(-) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index bccbe37e2..4339a658a 100644 --- a/divesite.c +++ b/divesite.c @@ -4,6 +4,36 @@ struct dive_site_table dive_site_table; +/* there could be multiple sites of the same name - return the first one */ +uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp) +{ + int i; + struct dive_site *ds; + for_each_dive_site (i, ds) { + if (same_string(ds->name, name)) { + if (dsp) + *dsp = ds; + return ds->uuid; + } + } + return 0; +} + +/* there could be multiple sites at the same GPS fix - return the first one */ +uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp) +{ + int i; + struct dive_site *ds; + for_each_dive_site (i, ds) { + if (ds->latitude.udeg == latitude.udeg && ds->longitude.udeg == longitude.udeg) { + if (dsp) + *dsp = ds; + return ds->uuid; + } + } + return 0; +} + /* try to create a uniqe ID - fingers crossed */ static uint32_t dive_site_getUniqId() { @@ -57,17 +87,3 @@ uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees return ds->uuid; } - -/* if the uuid is valid, just get the site, otherwise create it first; - * so you can call this with dive->dive_site_uuid and you'll either get the existing - * dive site or it will create a new one - so make sure you assign the uuid back to - * dive->dive_site_uuid when using this function! */ -struct dive_site *get_or_create_dive_site_by_uuid(uint32_t uuid) -{ - struct dive_site *ds = get_dive_site_by_uuid(uuid); - - if (!ds) - ds = alloc_dive_site(); - - return ds; -} diff --git a/divesite.h b/divesite.h index 5b1d1959d..4dca3ee9d 100644 --- a/divesite.h +++ b/divesite.h @@ -45,40 +45,11 @@ static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) return NULL; } -/* there could be multiple sites of the same name - return the first one */ -static inline uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp) -{ - int i; - struct dive_site *ds; - for_each_dive_site (i, ds) { - if (ds->name == name) { - if (dsp) - *dsp = ds; - return ds->uuid; - } - } - return 0; -} - -/* there could be multiple sites at the same GPS fix - return the first one */ -static inline uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp) -{ - int i; - struct dive_site *ds; - for_each_dive_site (i, ds) { - if (ds->latitude.udeg == latitude.udeg && ds->longitude.udeg == longitude.udeg) { - if (dsp) - *dsp = ds; - return ds->uuid; - } - } - return 0; -} - struct dive_site *alloc_dive_site(); uint32_t create_dive_site(const char *name); uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude); -struct dive_site *get_or_create_dive_site_by_uuid(uint32_t uuid); +uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp); +uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp); #ifdef __cplusplus } diff --git a/load-git.c b/load-git.c index 4fcf1f600..7cebb038a 100644 --- a/load-git.c +++ b/load-git.c @@ -140,19 +140,40 @@ static int get_hex(const char *line) static void parse_dive_gps(char *line, struct membuffer *str, void *_dive) { + uint32_t uuid; + degrees_t latitude = parse_degrees(line, &line); + degrees_t longitude = parse_degrees(line, &line); struct dive *dive = _dive; - struct dive_site *ds = get_or_create_dive_site_by_uuid(dive->dive_site_uuid); - dive->dive_site_uuid = ds->uuid; - ds->latitude = parse_degrees(line, &line); - ds->longitude = parse_degrees(line, &line); + struct dive_site *ds = get_dive_site_for_dive(dive); + if (!ds) { + uuid = get_dive_site_uuid_by_gps(latitude, longitude, NULL); + if (!uuid) + uuid = create_dive_site_with_gps("", latitude, longitude); + dive->dive_site_uuid = uuid; + } else { + ds->latitude = latitude; + ds->longitude = longitude; + } + } static void parse_dive_location(char *line, struct membuffer *str, void *_dive) { + uint32_t uuid; + char *name = get_utf8(str); struct dive *dive = _dive; - struct dive_site *ds = get_or_create_dive_site_by_uuid(dive->dive_site_uuid); - dive->dive_site_uuid = ds->uuid; - ds->name = get_utf8(str); + struct dive_site *ds = get_dive_site_for_dive(dive); + fprintf(stderr, "looking for a site named {%s} ", name); + if (!ds) { + uuid = get_dive_site_uuid_by_name(name, NULL); + if (!uuid) { fprintf(stderr, "found none, creating\n"); + uuid = create_dive_site(name); + } else { fprintf(stderr, "found one with uuid %8x\n", uuid); } + dive->dive_site_uuid = uuid; + } else { + fprintf(stderr, "dive had site with uuid %8x and name {%s}\n", ds->uuid, ds->name); + ds->name = name; + } } static void parse_dive_divemaster(char *line, struct membuffer *str, void *_dive) -- cgit v1.2.3-70-g09d2 From d8146445fcf962e456af91c592536481fdc2753f Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 13 Feb 2015 07:02:26 -0800 Subject: Add another helper funtion We need to be able to get rid of dive sites as well. Signed-off-by: Dirk Hohndel --- divesite.c | 19 +++++++++++++++++++ divesite.h | 1 + 2 files changed, 20 insertions(+) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index 4339a658a..492ba9d82 100644 --- a/divesite.c +++ b/divesite.c @@ -67,6 +67,25 @@ struct dive_site *alloc_dive_site() return ds; } +void delete_dive_site(uint32_t id) +{ + int nr = dive_site_table.nr; + for (int i = 0; i < nr; i++) { + struct dive_site *ds = get_dive_site(i); + if (ds->uuid == id) { + free(ds->name); + free(ds->notes); + free(ds); + if (nr - 1 > i) + memmove(&dive_site_table.dive_sites[i], + &dive_site_table.dive_sites[i+1], + (nr - 1 - i) * sizeof(dive_site_table.dive_sites[0])); + dive_site_table.nr = nr - 1; + break; + } + } +} + /* allocate a new site and add it to the table */ uint32_t create_dive_site(const char *name) { diff --git a/divesite.h b/divesite.h index 4dca3ee9d..4702913aa 100644 --- a/divesite.h +++ b/divesite.h @@ -46,6 +46,7 @@ static inline struct dive_site *get_dive_site_by_uuid(uint32_t uuid) } struct dive_site *alloc_dive_site(); +void delete_dive_site(uint32_t id); uint32_t create_dive_site(const char *name); uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude); uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp); -- cgit v1.2.3-70-g09d2 From 7ca3d859dc304674fe9e48c3ab3925303615a1c2 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 13 Feb 2015 22:53:03 -0800 Subject: Add helper function to detect empty dive sites No point in keeping those. Signed-off-by: Dirk Hohndel --- divesite.c | 10 ++++++++++ divesite.h | 3 +++ 2 files changed, 13 insertions(+) (limited to 'divesite.h') diff --git a/divesite.c b/divesite.c index 492ba9d82..4f236017f 100644 --- a/divesite.c +++ b/divesite.c @@ -106,3 +106,13 @@ uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees return ds->uuid; } + +/* a uuid is always present - but if all the other fields are empty, the dive site is pointless */ +bool dive_site_is_empty(struct dive_site *ds) +{ + return same_string(ds->name, "") && + same_string(ds->description, "") && + same_string(ds->notes, "") && + ds->latitude.udeg == 0 && + ds->longitude.udeg == 0; +} diff --git a/divesite.h b/divesite.h index 4702913aa..ca650259a 100644 --- a/divesite.h +++ b/divesite.h @@ -6,6 +6,8 @@ #ifdef __cplusplus extern "C" { +#else +#include #endif struct dive_site @@ -51,6 +53,7 @@ uint32_t create_dive_site(const char *name); uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude); uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp); uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp); +bool dive_site_is_empty(struct dive_site *ds); #ifdef __cplusplus } -- cgit v1.2.3-70-g09d2