mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 19:13:24 +00:00
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>
This commit is contained in:
parent
763c3683e5
commit
c61cf991e0
1 changed files with 64 additions and 52 deletions
116
core/dive.c
116
core/dive.c
|
@ -473,57 +473,6 @@ struct dive *alloc_dive(void)
|
|||
return dive;
|
||||
}
|
||||
|
||||
static void free_dc(struct divecomputer *dc);
|
||||
static void free_dc_contents(struct divecomputer *dc);
|
||||
static void free_pic(struct picture *picture);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
*ddc = *sdc;
|
||||
ddc->model = copy_string(sdc->model);
|
||||
copy_samples(sdc, ddc);
|
||||
copy_events(sdc, ddc);
|
||||
}
|
||||
|
||||
static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, const int mapping[]);
|
||||
|
||||
/* copy dive computer list and renumber the cylinders
|
||||
* space for the first divecomputer is provided by the
|
||||
* caller, the remainder is allocated */
|
||||
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);
|
||||
dc_cylinder_renumber(d, ddc, cylinders_map);
|
||||
if (!sdc->next)
|
||||
break;
|
||||
sdc = sdc->next;
|
||||
ddc->next = calloc(1, sizeof(struct divecomputer));
|
||||
ddc = ddc->next;
|
||||
}
|
||||
ddc->next = NULL;
|
||||
}
|
||||
|
||||
/* copy an element in a list of pictures */
|
||||
static void copy_pl(struct picture *sp, struct picture *dp)
|
||||
{
|
||||
*dp = *sp;
|
||||
dp->filename = copy_string(sp->filename);
|
||||
}
|
||||
|
||||
/* copy an element in a list of tags */
|
||||
static void copy_tl(struct tag_entry *st, struct tag_entry *dt)
|
||||
{
|
||||
dt->tag = malloc(sizeof(struct divetag));
|
||||
dt->tag->name = copy_string(st->tag->name);
|
||||
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) \
|
||||
|
@ -549,6 +498,62 @@ static void copy_tl(struct tag_entry *st, struct tag_entry *dt)
|
|||
*_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)
|
||||
{
|
||||
*ddc = *sdc;
|
||||
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[]);
|
||||
|
||||
/* copy dive computer list and renumber the cylinders
|
||||
* space for the first divecomputer is provided by the
|
||||
* caller, the remainder is allocated */
|
||||
static void copy_dc_renumber(struct dive *d, const struct divecomputer *sdc, struct divecomputer *ddc, const int cylinders_map[])
|
||||
{
|
||||
for (;;) {
|
||||
copy_dc(sdc, ddc);
|
||||
dc_cylinder_renumber(d, ddc, cylinders_map);
|
||||
if (!sdc->next)
|
||||
break;
|
||||
sdc = sdc->next;
|
||||
ddc->next = calloc(1, sizeof(struct divecomputer));
|
||||
ddc = ddc->next;
|
||||
}
|
||||
ddc->next = NULL;
|
||||
}
|
||||
|
||||
/* copy an element in a list of pictures */
|
||||
static void copy_pl(struct picture *sp, struct picture *dp)
|
||||
{
|
||||
*dp = *sp;
|
||||
dp->filename = copy_string(sp->filename);
|
||||
}
|
||||
|
||||
/* copy an element in a list of tags */
|
||||
static void copy_tl(struct tag_entry *st, struct tag_entry *dt)
|
||||
{
|
||||
dt->tag = malloc(sizeof(struct divetag));
|
||||
dt->tag->name = copy_string(st->tag->name);
|
||||
dt->tag->source = copy_string(st->tag->source);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue