diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-10-16 07:41:48 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-10-16 06:20:33 -0400 |
commit | c61cf991e01f562cbcbd228c42e057db6690fea8 (patch) | |
tree | 708ed38ed96d92c97f8bcd2df0f0d86849c76e7e | |
parent | 763c3683e58684f296d6b66835ca6d84e14b3900 (diff) | |
download | subsurface-c61cf991e01f562cbcbd228c42e057db6690fea8.tar.gz |
Core: copy and free extra_data of dive computer structure
On dive computer copy, the extra data (a list of key/value pairs)
was simply copied as a pointer. This worked because the list was
never freed nor modified. Copy and free the list on dive computer
copy and free, respectively.
This made it necessary to move the STRUCTURE_LIST_* macros up in
the dive.c file.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/dive.c | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/core/dive.c b/core/dive.c index 345b59c2c..303288b4e 100644 --- a/core/dive.c +++ b/core/dive.c @@ -473,10 +473,42 @@ struct dive *alloc_dive(void) return dive; } +/* Clear everything but the first element; + * this works for taglist, picturelist, even dive computers */ +#define STRUCTURED_LIST_FREE(_type, _start, _free) \ + { \ + _type *_ptr = _start; \ + while (_ptr) { \ + _type *_next = _ptr->next; \ + _free(_ptr); \ + _ptr = _next; \ + } \ + } + +#define STRUCTURED_LIST_COPY(_type, _first, _dest, _cpy) \ + { \ + _type *_sptr = _first; \ + _type **_dptr = &_dest; \ + while (_sptr) { \ + *_dptr = malloc(sizeof(_type)); \ + _cpy(_sptr, *_dptr); \ + _sptr = _sptr->next; \ + _dptr = &(*_dptr)->next; \ + } \ + *_dptr = 0; \ + } + static void free_dc(struct divecomputer *dc); static void free_dc_contents(struct divecomputer *dc); static void free_pic(struct picture *picture); +/* copy an element in a list of dive computer extra data */ +static void copy_extra_data(struct extra_data *sed, struct extra_data *ded) +{ + ded->key = copy_string(sed->key); + ded->value = copy_string(sed->value); +} + /* this is very different from the copy_divecomputer later in this file; * this function actually makes full copies of the content */ static void copy_dc(const struct divecomputer *sdc, struct divecomputer *ddc) @@ -485,6 +517,7 @@ static void copy_dc(const struct divecomputer *sdc, struct divecomputer *ddc) ddc->model = copy_string(sdc->model); copy_samples(sdc, ddc); copy_events(sdc, ddc); + STRUCTURED_LIST_COPY(struct extra_data, sdc->extra_data, ddc->extra_data, copy_extra_data); } static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, const int mapping[]); @@ -495,10 +528,7 @@ static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, con static void copy_dc_renumber(struct dive *d, const struct divecomputer *sdc, struct divecomputer *ddc, const int cylinders_map[]) { for (;;) { - *ddc = *sdc; - ddc->model = copy_string(sdc->model); - copy_samples(sdc, ddc); - copy_events(sdc, ddc); + copy_dc(sdc, ddc); dc_cylinder_renumber(d, ddc, cylinders_map); if (!sdc->next) break; @@ -524,31 +554,6 @@ static void copy_tl(struct tag_entry *st, struct tag_entry *dt) dt->tag->source = copy_string(st->tag->source); } -/* Clear everything but the first element; - * this works for taglist, picturelist, even dive computers */ -#define STRUCTURED_LIST_FREE(_type, _start, _free) \ - { \ - _type *_ptr = _start; \ - while (_ptr) { \ - _type *_next = _ptr->next; \ - _free(_ptr); \ - _ptr = _next; \ - } \ - } - -#define STRUCTURED_LIST_COPY(_type, _first, _dest, _cpy) \ - { \ - _type *_sptr = _first; \ - _type **_dptr = &_dest; \ - while (_sptr) { \ - *_dptr = malloc(sizeof(_type)); \ - _cpy(_sptr, *_dptr); \ - _sptr = _sptr->next; \ - _dptr = &(*_dptr)->next; \ - } \ - *_dptr = 0; \ - } - static void free_dive_structures(struct dive *d) { if (!d) @@ -2961,11 +2966,18 @@ void free_events(struct event *ev) } } +static void free_extra_data(struct extra_data *ed) +{ + free((void *)ed->key); + free((void *)ed->value); +} + static void free_dc_contents(struct divecomputer *dc) { free(dc->sample); free((void *)dc->model); free_events(dc->events); + STRUCTURED_LIST_FREE(struct extra_data, dc->extra_data, free_extra_data); } static void free_dc(struct divecomputer *dc) @@ -3075,11 +3087,11 @@ static const struct divecomputer *find_matching_computer(const struct divecomput return p; } - static void copy_dive_computer(struct divecomputer *res, const struct divecomputer *a) { *res = *a; res->model = copy_string(a->model); + STRUCTURED_LIST_COPY(struct extra_data, a->extra_data, res->extra_data, copy_extra_data); res->samples = res->alloc_samples = 0; res->sample = NULL; res->events = NULL; |