[PATCH 2/2] Move events and samples into a 'struct divecomputer'

Linus Torvalds torvalds at linux-foundation.org
Fri Nov 23 19:07:12 PST 2012


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Fri, 23 Nov 2012 16:51:27 -1000
Subject: [PATCH 2/2] Move events and samples into a 'struct divecomputer'

For now we only have one fixed divecomputer associated with each dive,
so this doesn't really change any current semantics.  But it will make
it easier for us to associate a dive with multiple dive computers.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

The patch is pretty big, because there's a *lot* of code that accesses the 
samples, and now we have to change it to use "dc->sample" instead of 
"dive->sample", and pass in the dive computer pointer rather than the 
dive.

We actually currently only have one (fixed) dive computer per dive, so the 
conversion *could* have been a purely mechanical "dive->sample" to 
"dive->dc.sample" conversion, but that would have been largely pointless 
for future work.

So instead, I try to actually pass in the dive computer pointer 
explicitly, so that once we start supporting saving data for multiple 
independent dive computers in the same dive (without mixing them up), we 
can do so with hopefully not oo many big changes.

However, there are still various pieces of code that knows that there is 
exactly one dive computer, so there are several cases where we do do that 
direct "&dive->dc" thing. But at least the *bulk* of the code now treats 
dive computer data as being separate from the dive.

 dive.c            | 103 ++++++++++++++++++++++++------------------------------
 dive.h            |  19 ++++++----
 divelist.c        |  26 +++++++-------
 file.c            |   4 +--
 libdivecomputer.c |  20 +++++------
 parse-xml.c       |   8 ++---
 profile.c         |  51 ++++++++++++++-------------
 save-xml.c        |   6 ++--
 uemis.c           |  51 ++++++++++++++-------------
 9 files changed, 144 insertions(+), 144 deletions(-)

diff --git a/dive.c b/dive.c
index be7d890f4c8b..605f4ce292c3 100644
--- a/dive.c
+++ b/dive.c
@@ -6,7 +6,7 @@
 
 #include "dive.h"
 
-void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name)
+void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name)
 {
 	struct event *ev, **p;
 	unsigned int size, len = strlen(name);
@@ -23,7 +23,7 @@ void add_event(struct dive *dive, int time, int type, int flags, int value, cons
 	ev->value = value;
 	ev->next = NULL;
 
-	p = &dive->events;
+	p = &dc->events;
 	while (*p)
 		p = &(*p)->next;
 	*p = ev;
@@ -154,32 +154,32 @@ struct dive *alloc_dive(void)
 	return dive;
 }
 
-struct sample *prepare_sample(struct dive *dive)
+struct sample *prepare_sample(struct divecomputer *dc)
 {
-	if (dive) {
-		int nr = dive->samples;
-		int alloc_samples = dive->alloc_samples;
+	if (dc) {
+		int nr = dc->samples;
+		int alloc_samples = dc->alloc_samples;
 		struct sample *sample;
 		if (nr >= alloc_samples) {
 			struct sample *newsamples;
 
 			alloc_samples = (alloc_samples * 3)/2 + 10;
-			newsamples = realloc(dive->sample, alloc_samples * sizeof(struct sample));
+			newsamples = realloc(dc->sample, alloc_samples * sizeof(struct sample));
 			if (!newsamples)
 				return NULL;
-			dive->alloc_samples = alloc_samples;
-			dive->sample = newsamples;
+			dc->alloc_samples = alloc_samples;
+			dc->sample = newsamples;
 		}
-		sample = dive->sample + nr;
+		sample = dc->sample + nr;
 		memset(sample, 0, sizeof(*sample));
 		return sample;
 	}
 	return NULL;
 }
 
-void finish_sample(struct dive *dive)
+void finish_sample(struct divecomputer *dc)
 {
-	dive->samples++;
+	dc->samples++;
 }
 
 /*
@@ -380,9 +380,9 @@ static gboolean is_potentially_redundant(struct event *event)
 }
 
 /* match just by name - we compare the details in the code that uses this helper */
-static struct event *find_previous_event(struct dive *dive, struct event *event)
+static struct event *find_previous_event(struct divecomputer *dc, struct event *event)
 {
-	struct event *ev = dive->events;
+	struct event *ev = dc->events;
 	struct event *previous = NULL;
 
 	if (!event->name)
@@ -406,6 +406,7 @@ struct dive *fixup_dive(struct dive *dive)
 	int lastdepth = 0;
 	int lasttemp = 0, lastpressure = 0;
 	int pressure_delta[MAX_CYLINDERS] = {INT_MAX, };
+	struct divecomputer *dc;
 	struct event *event;
 
 	add_people(dive->buddy);
@@ -413,8 +414,9 @@ struct dive *fixup_dive(struct dive *dive)
 	add_location(dive->location);
 	add_suit(dive->suit);
 	sanitize_cylinder_info(dive);
-	for (i = 0; i < dive->samples; i++) {
-		struct sample *sample = dive->sample + i;
+	dc = &dive->dc;
+	for (i = 0; i < dc->samples; i++) {
+		struct sample *sample = dc->sample + i;
 		int time = sample->time.seconds;
 		int depth = sample->depth.mm;
 		int temp = sample->temperature.mkelvin;
@@ -491,9 +493,9 @@ struct dive *fixup_dive(struct dive *dive)
 	for (j = 0; j < MAX_CYLINDERS; j++) {
 		if (abs(pressure_delta[j]) != INT_MAX) {
 			cylinder_t *cyl = dive->cylinder + j;
-			for (i = 0; i < dive->samples; i++)
-				if (dive->sample[i].cylinderindex == j)
-					dive->sample[i].cylinderpressure.mbar = 0;
+			for (i = 0; i < dc->samples; i++)
+				if (dc->sample[i].cylinderindex == j)
+					dc->sample[i].cylinderpressure.mbar = 0;
 			if (! cyl->start.mbar)
 				cyl->start.mbar = cyl->sample_start.mbar;
 			if (! cyl->end.mbar)
@@ -552,11 +554,11 @@ struct dive *fixup_dive(struct dive *dive)
 	 * profile with)
 	 * We first only mark the events for deletion so that we
 	 * still know when the previous event happened. */
-	event = dive->events;
+	event = dc->events;
 	while (event) {
 		struct event *prev;
 		if (is_potentially_redundant(event)) {
-			prev = find_previous_event(dive, event);
+			prev = find_previous_event(dc, event);
 			if (prev && prev->value == event->value &&
 			    prev->flags == event->flags &&
 			    event->time.seconds - prev->time.seconds < 61)
@@ -564,7 +566,7 @@ struct dive *fixup_dive(struct dive *dive)
 		}
 		event = event->next;
 	}
-	event = dive->events;
+	event = dc->events;
 	while (event) {
 		if (event->next && event->next->deleted) {
 			struct event *nextnext = event->next->next;
@@ -587,14 +589,14 @@ struct dive *fixup_dive(struct dive *dive)
 #define MERGE_MAX_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : MAX(a->n, b->n)
 #define MERGE_MIN_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n)
 
-static struct sample *add_sample(struct sample *sample, int time, struct dive *dive)
+static struct sample *add_sample(struct sample *sample, int time, struct divecomputer *dc)
 {
-	struct sample *p = prepare_sample(dive);
+	struct sample *p = prepare_sample(dc);
 
 	if (p) {
 		*p = *sample;
 		p->time.seconds = time;
-		finish_sample(dive);
+		finish_sample(dc);
 	}
 	return p;
 }
@@ -607,25 +609,25 @@ static struct sample *add_sample(struct sample *sample, int time, struct dive *d
  * that the time in between the dives is at the surface, not some "last
  * sample that happened to be at a depth of 1.2m".
  */
-static void merge_one_sample(struct sample *sample, int time, struct dive *dive)
+static void merge_one_sample(struct sample *sample, int time, struct divecomputer *dc)
 {
-	int last = dive->samples-1;
+	int last = dc->samples-1;
 	if (last >= 0) {
 		static struct sample surface;
-		int last_time = dive->sample[last].time.seconds;
+		int last_time = dc->sample[last].time.seconds;
 		if (time > last_time + 60) {
-			add_sample(&surface, last_time+20, dive);
-			add_sample(&surface, time - 20, dive);
+			add_sample(&surface, last_time+20, dc);
+			add_sample(&surface, time - 20, dc);
 		}
 	}
-	add_sample(sample, time, dive);
+	add_sample(sample, time, dc);
 }
 
 
 /*
  * Merge samples. Dive 'a' is "offset" seconds before Dive 'b'
  */
-static struct dive *merge_samples(struct dive *res, struct dive *a, struct dive *b, int offset)
+static void merge_samples(struct divecomputer *res, struct divecomputer *a, struct divecomputer *b, int offset)
 {
 	int asamples = a->samples;
 	int bsamples = b->samples;
@@ -652,14 +654,14 @@ static struct dive *merge_samples(struct dive *res, struct dive *a, struct dive
 		struct sample sample;
 
 		if (!res)
-			return NULL;
+			return;
 
 		at = asamples ? as->time.seconds : -1;
 		bt = bsamples ? bs->time.seconds + offset : -1;
 
 		/* No samples? All done! */
 		if (at < 0 && bt < 0)
-			return fixup_dive(res);
+			return;
 
 		/* Only samples from a? */
 		if (bt < 0) {
@@ -704,20 +706,6 @@ add_sample_b:
 	}
 }
 
-static struct dive *copy_samples(struct dive *res, struct dive *src)
-{
-	int samples = src->samples;
-	struct sample *s = src->sample;
-	while (samples) {
-		if (!res)
-			return NULL;
-		add_sample(s, s->time.seconds, res);
-		s++;
-		samples--;
-	}
-	return fixup_dive(res);
-}
-
 static char *merge_text(const char *a, const char *b)
 {
 	char *res;
@@ -747,14 +735,14 @@ static int sort_event(struct event *a, struct event *b)
 	return strcmp(a->name, b->name);
 }
 
-static void merge_events(struct dive *res, struct dive *src1, struct dive *src2, int offset)
+static void merge_events(struct divecomputer *res, struct divecomputer *src1, struct divecomputer *src2, int offset)
 {
 	struct event *a, *b;
 	struct event **p = &res->events;
 
 	/* Always use positive offsets */
 	if (offset < 0) {
-		struct dive *tmp;
+		struct divecomputer *tmp;
 
 		offset = -offset;
 		tmp = src1;
@@ -933,7 +921,7 @@ static int compare_sample(struct sample *s, struct sample *a, struct sample *b,
  * the offset in seconds between them. Use this to find the best
  * match of samples between two different dive computers.
  */
-static unsigned long sample_difference(struct dive *a, struct dive *b, int offset)
+static unsigned long sample_difference(struct divecomputer *a, struct divecomputer *b, int offset)
 {
 	int asamples = a->samples;
 	int bsamples = b->samples;
@@ -1017,7 +1005,7 @@ static unsigned long sample_difference(struct dive *a, struct dive *b, int offse
  *
  * If we cannot find a shared offset, don't try to merge.
  */
-static int find_sample_offset(struct dive *a, struct dive *b)
+static int find_sample_offset(struct divecomputer *a, struct divecomputer *b)
 {
 	int offset, best;
 	unsigned long max;
@@ -1075,7 +1063,7 @@ struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer_downlo
 		return NULL;
 	if (!prefer_downloaded) {
 		/* Dive 'a' is 'offset' seconds before dive 'b' */
-		offset = find_sample_offset(a, b);
+		offset = find_sample_offset(&a->dc, &b->dc);
 		if (offset > 120 || offset < -120)
 			return NULL;
 	}
@@ -1114,10 +1102,11 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean pr
 	MERGE_MIN_PREFDL(res, dl, a, b, watertemp.mkelvin);
 	merge_equipment(res, a, b);
 	if (dl) {
-		res->events = dl->events;
-		return copy_samples(res, dl);
+		res->dc = dl->dc;
 	} else {
-		merge_events(res, a, b, offset);
-		return merge_samples(res, a, b, offset);
+		merge_events(&res->dc, &a->dc, &b->dc, offset);
+		merge_samples(&res->dc, &a->dc, &b->dc, offset);
 	}
+	fixup_dive(res);
+	return res;
 }
diff --git a/dive.h b/dive.h
index dbcd38090c43..ef3f22941e22 100644
--- a/dive.h
+++ b/dive.h
@@ -237,6 +237,13 @@ struct event {
 	char name[];
 };
 
+struct divecomputer {
+	int samples, alloc_samples;
+	struct sample *sample;
+
+	struct event *events;
+};
+
 #define MAX_CYLINDERS (8)
 #define MAX_WEIGHTSYSTEMS (4)
 #define W_IDX_PRIMARY 0
@@ -279,9 +286,9 @@ struct dive {
 	weightsystem_t weightsystem[MAX_WEIGHTSYSTEMS];
 	char *suit;
 	int sac, otu;
-	struct event *events;
-	int samples, alloc_samples;
-	struct sample *sample;
+
+	/* Eventually we'll do multiple dive computers */
+	struct divecomputer dc;
 };
 
 /* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
@@ -422,8 +429,8 @@ extern struct dive *alloc_dive(void);
 extern void record_dive(struct dive *dive);
 extern void delete_dive(struct dive *dive);
 
-extern struct sample *prepare_sample(struct dive *dive);
-extern void finish_sample(struct dive *dive);
+extern struct sample *prepare_sample(struct divecomputer *dc);
+extern void finish_sample(struct divecomputer *dc);
 
 extern void report_dives(gboolean imported, gboolean prefer_imported);
 extern struct dive *fixup_dive(struct dive *dive);
@@ -432,7 +439,7 @@ extern struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer
 
 extern void renumber_dives(int nr);
 
-extern void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name);
+extern void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
 
 /* UI related protopypes */
 
diff --git a/divelist.c b/divelist.c
index 5c704b98a73c..aaaec572b89e 100644
--- a/divelist.c
+++ b/divelist.c
@@ -697,15 +697,15 @@ static void otu_data_func(GtkTreeViewColumn *col,
 }
 
 /* calculate OTU for a dive */
-static int calculate_otu(struct dive *dive)
+static int calculate_otu(struct dive *dive, struct divecomputer *dc)
 {
 	int i;
 	double otu = 0.0;
 
-	for (i = 1; i < dive->samples; i++) {
+	for (i = 1; i < dc->samples; i++) {
 		int t;
 		double po2;
-		struct sample *sample = dive->sample + i;
+		struct sample *sample = dc->sample + i;
 		struct sample *psample = sample - 1;
 		t = sample->time.seconds - psample->time.seconds;
 		int o2 = dive->cylinder[sample->cylinderindex].gasmix.o2.permille;
@@ -744,7 +744,7 @@ static double calculate_airuse(struct dive *dive)
 	return airuse;
 }
 
-static int calculate_sac(struct dive *dive)
+static int calculate_sac(struct dive *dive, struct divecomputer *dc)
 {
 	double airuse, pressure, sac;
 	int duration, i;
@@ -757,16 +757,16 @@ static int calculate_sac(struct dive *dive)
 
 	/* find and eliminate long surface intervals */
 	duration = dive->duration.seconds;
-	for (i = 0; i < dive->samples; i++) {
-		if (dive->sample[i].depth.mm < 100) { /* less than 10cm */
+	for (i = 0; i < dc->samples; i++) {
+		if (dc->sample[i].depth.mm < 100) { /* less than 10cm */
 			int end = i + 1;
-			while (end < dive->samples && dive->sample[end].depth.mm < 100)
+			while (end < dc->samples && dc->sample[end].depth.mm < 100)
 				end++;
 			/* we only want the actual surface time during a dive */
-			if (end < dive->samples) {
+			if (end < dc->samples) {
 				end--;
-				duration -= dive->sample[end].time.seconds -
-						dive->sample[i].time.seconds;
+				duration -= dc->sample[end].time.seconds -
+						dc->sample[i].time.seconds;
 				i = end + 1;
 			}
 		}
@@ -782,8 +782,8 @@ static int calculate_sac(struct dive *dive)
 void update_cylinder_related_info(struct dive *dive)
 {
 	if (dive != NULL) {
-		dive->sac = calculate_sac(dive);
-		dive->otu = calculate_otu(dive);
+		dive->sac = calculate_sac(dive, &dive->dc);
+		dive->otu = calculate_otu(dive, &dive->dc);
 	}
 }
 
@@ -1931,7 +1931,7 @@ void delete_single_dive(int idx)
 	dive_table.nr--;
 	if (dive->selected)
 		amount_selected--;
-	free(dive->sample);
+	free(dive->dc.sample);
 	free(dive);
 }
 
diff --git a/file.c b/file.c
index d675d8dc6e63..ecbc53df8f4d 100644
--- a/file.c
+++ b/file.c
@@ -204,10 +204,10 @@ static int try_to_open_csv(const char *filename, struct memblock *mem, enum csv_
 		if (errno)
 			break;
 
-		sample = prepare_sample(dive);
+		sample = prepare_sample(&dive->dc);
 		sample->time.seconds = time;
 		add_sample_data(sample, type, val);
-		finish_sample(dive);
+		finish_sample(&dive->dc);
 
 		time++;
 		dive->duration.seconds = time;
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 6ced23a481ac..27ce8458ec4d 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -71,7 +71,7 @@ static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t
 	return DC_STATUS_SUCCESS;
 }
 
-static void handle_event(struct dive *dive, struct sample *sample, dc_sample_value_t value)
+static void handle_event(struct divecomputer *dc, struct sample *sample, dc_sample_value_t value)
 {
 	int type, time;
 	/* we mark these for translation here, but we store the untranslated strings
@@ -108,27 +108,27 @@ static void handle_event(struct dive *dive, struct sample *sample, dc_sample_val
 	if (sample)
 		time += sample->time.seconds;
 
-	add_event(dive, time, type, value.event.flags, value.event.value, name);
+	add_event(dc, time, type, value.event.flags, value.event.value, name);
 }
 
 void
 sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
 {
 	int i;
-	struct dive *dive = userdata;
+	struct divecomputer *dc = userdata;
 	struct sample *sample;
 
 	/*
 	 * We fill in the "previous" sample - except for DC_SAMPLE_TIME,
 	 * which creates a new one.
 	 */
-	sample = dive->samples ? dive->sample+dive->samples-1 : NULL;
+	sample = dc->samples ? dc->sample+dc->samples-1 : NULL;
 
 	switch (type) {
 	case DC_SAMPLE_TIME:
-		sample = prepare_sample(dive);
+		sample = prepare_sample(dc);
 		sample->time.seconds = value.time;
-		finish_sample(dive);
+		finish_sample(dc);
 		break;
 	case DC_SAMPLE_DEPTH:
 		sample->depth.mm = value.depth * 1000 + 0.5;
@@ -141,7 +141,7 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
 		sample->temperature.mkelvin = (value.temperature + 273.15) * 1000 + 0.5;
 		break;
 	case DC_SAMPLE_EVENT:
-		handle_event(dive, sample, value);
+		handle_event(dc, sample, value);
 		break;
 	case DC_SAMPLE_RBT:
 		printf("   <rbt>%u</rbt>\n", value.rbt);
@@ -176,10 +176,10 @@ static void dev_info(device_data_t *devdata, const char *fmt, ...)
 
 static int import_dive_number = 0;
 
-static int parse_samples(device_data_t *devdata, struct dive *dive, dc_parser_t *parser)
+static int parse_samples(device_data_t *devdata, struct divecomputer *dc, dc_parser_t *parser)
 {
 	// Parse the sample data.
-	return dc_parser_samples_foreach(parser, sample_cb, dive);
+	return dc_parser_samples_foreach(parser, sample_cb, dc);
 }
 
 /*
@@ -302,7 +302,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
 	}
 
 	// Initialize the sample data.
-	rc = parse_samples(devdata, dive, parser);
+	rc = parse_samples(devdata, &dive->dc, parser);
 	if (rc != DC_STATUS_SUCCESS) {
 		dev_info(devdata, _("Error parsing the samples"));
 		dc_parser_destroy(parser);
diff --git a/parse-xml.c b/parse-xml.c
index 6b8afa1f3aa5..ce1f3b93e7e0 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -1198,7 +1198,7 @@ static void try_to_fill_trip(dive_trip_t **dive_trip_p, const char *name, char *
 static gboolean is_dive(void)
 {
 	return (cur_dive &&
-		(cur_dive->location || cur_dive->when || cur_dive->samples));
+		(cur_dive->location || cur_dive->when || cur_dive->dc.samples));
 }
 
 static void dive_start(void)
@@ -1252,7 +1252,7 @@ static void event_start(void)
 static void event_end(void)
 {
 	if (cur_event.name && strcmp(cur_event.name, "surface") != 0)
-		add_event(cur_dive, cur_event.time.seconds,
+		add_event(&cur_dive->dc, cur_event.time.seconds,
 			cur_event.type, cur_event.flags,
 			cur_event.value, cur_event.name);
 	cur_event.active = 0;
@@ -1278,7 +1278,7 @@ static void ws_end(void)
 
 static void sample_start(void)
 {
-	cur_sample = prepare_sample(cur_dive);
+	cur_sample = prepare_sample(&cur_dive->dc);
 }
 
 static void sample_end(void)
@@ -1286,7 +1286,7 @@ static void sample_end(void)
 	if (!cur_dive)
 		return;
 
-	finish_sample(cur_dive);
+	finish_sample(&cur_dive->dc);
 	cur_sample = NULL;
 }
 
diff --git a/profile.c b/profile.c
index 4eaad87e7ab7..bbc8c5361e27 100644
--- a/profile.c
+++ b/profile.c
@@ -393,10 +393,10 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
 	attach_tooltip(x-15, y-6, 12, 12, buffer);
 }
 
-static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct dive *dive)
+static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc)
 {
 	static const text_render_options_t tro = {14, EVENTS, CENTER, TOP};
-	struct event *event = dive->events;
+	struct event *event = dc->events;
 
 	if (gc->printer)
 		return;
@@ -1643,10 +1643,10 @@ static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, un
 	return i;
 }
 
-static void check_gas_change_events(struct dive *dive, struct plot_info *pi)
+static void check_gas_change_events(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
 {
 	int i = 0, cylinderindex = 0;
-	struct event *ev = get_next_event(dive->events, "gaschange");
+	struct event *ev = get_next_event(dc->events, "gaschange");
 
 	if (!ev)
 		return;
@@ -1660,10 +1660,10 @@ static void check_gas_change_events(struct dive *dive, struct plot_info *pi)
 }
 
 /* for computers that track gas changes through events */
-static int count_gas_change_events(struct dive *dive)
+static int count_gas_change_events(struct divecomputer *dc)
 {
 	int count = 0;
-	struct event *ev = get_next_event(dive->events, "gaschange");
+	struct event *ev = get_next_event(dc->events, "gaschange");
 
 	while (ev) {
 		count++;
@@ -1679,7 +1679,7 @@ static int count_gas_change_events(struct dive *dive)
  * sides, so that you can do end-points without having to worry
  * about it.
  */
-static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, struct sample *dive_sample)
+static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc)
 {
 	int cylinderindex = -1;
 	int lastdepth, lastindex;
@@ -1694,7 +1694,7 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
 	double amb_pressure;
 
 	/* we want to potentially add synthetic plot_info elements for the gas changes */
-	nr = nr_samples + 4 + 2 * count_gas_change_events(dive);
+	nr = dc->samples + 4 + 2 * count_gas_change_events(dc);
 	alloc_size = plot_info_size(nr);
 	pi = malloc(alloc_size);
 	if (!pi)
@@ -1703,27 +1703,27 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
 	pi->nr = nr;
 	pi_idx = 2; /* the two extra events at the start */
 	/* check for gas changes before the samples start */
-	ev = get_next_event(dive->events, "gaschange");
-	while (ev && ev->time.seconds < dive_sample->time.seconds) {
+	ev = get_next_event(dive->dc.events, "gaschange");
+	while (ev && ev->time.seconds < dc->sample->time.seconds) {
 		entry = pi->entry + pi_idx;
 		entry->sec = ev->time.seconds;
 		entry->depth = 0; /* is that always correct ? */
 		pi_idx++;
 		ev = get_next_event(ev->next, "gaschange");
 	}
-	if (ev && ev->time.seconds == dive_sample->time.seconds) {
+	if (ev && ev->time.seconds == dc->sample->time.seconds) {
 		/* we already have a sample at the time of the event */
 		ev = get_next_event(ev->next, "gaschange");
 	}
 	/* find the first deco/ceiling event (if any) */
-	ceil_ev = get_next_event(dive->events, "ceiling");
+	ceil_ev = get_next_event(dive->dc.events, "ceiling");
 	sec = 0;
 	lastindex = 0;
 	lastdepth = -1;
-	for (i = 0; i < nr_samples; i++) {
+	for (i = 0; i < dc->samples; i++) {
 		int depth;
 		int delay = 0;
-		struct sample *sample = dive_sample+i;
+		struct sample *sample = dc->sample+i;
 
 		if ((dive->start > -1 && sample->time.seconds < dive->start) ||
 		    (dive->end > -1 && sample->time.seconds > dive->end)) {
@@ -1799,8 +1799,8 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
 		entry = pi->entry + i + pi_idx;
 		ev = get_next_event(ev->next, "gaschange");
 	}
-	nr = nr_samples + pi_idx - 2;
-	check_gas_change_events(dive, pi);
+	nr = dc->samples + pi_idx - 2;
+	check_gas_change_events(dive, dc, pi);
 
 	for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) /* initialize the start pressures */
 		track_pr[cyl] = pr_track_alloc(dive->cylinder[cyl].start.mbar, -1);
@@ -1934,14 +1934,18 @@ static void plot_set_scale(scale_mode_t scale)
 void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale)
 {
 	struct plot_info *pi;
-	static struct sample fake[4];
-	struct sample *sample = dive->sample;
+	struct divecomputer *dc = &dive->dc;
 	cairo_rectangle_t *drawing_area = &gc->drawing_area;
-	int nr = dive->samples;
 
 	plot_set_scale(scale);
 
-	if (!nr) {
+	if (!dc->samples) {
+		static struct sample fake[4];
+		static struct divecomputer fakedc = {
+			.sample = fake,
+			.samples = 4
+		};
+
 		/* The dive has no samples, so create a few fake ones.  This assumes an
 		ascent/descent rate of 9 m/min, which is just below the limit for FAST. */
 		int duration = dive->duration.seconds;
@@ -1949,16 +1953,15 @@ void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale)
 		int asc_desc_time = dive->maxdepth.mm*60/9000;
 		if (asc_desc_time * 2 >= duration)
 			asc_desc_time = duration / 2;
-		sample = fake;
 		fake[1].time.seconds = asc_desc_time;
 		fake[1].depth.mm = maxdepth;
 		fake[2].time.seconds = duration - asc_desc_time;
 		fake[2].depth.mm = maxdepth;
 		fake[3].time.seconds = duration * 1.00;
-		nr = 4;
+		dc = &fakedc;
 	}
 
-	pi = create_plot_info(dive, nr, sample);
+	pi = create_plot_info(dive, dc);
 
 	/* shift the drawing area so we have a nice margin around it */
 	cairo_translate(gc->cr, drawing_area->x, drawing_area->y);
@@ -1978,7 +1981,7 @@ void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale)
 
 	/* Depth profile */
 	plot_depth_profile(gc, pi);
-	plot_events(gc, pi, dive);
+	plot_events(gc, pi, dc);
 
 	/* Temperature profile */
 	plot_temperature_profile(gc, pi);
diff --git a/save-xml.c b/save-xml.c
index a70aacc3e543..db7d321bde1a 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -372,9 +372,9 @@ static void save_dive(FILE *f, struct dive *dive)
 	save_overview(f, dive);
 	save_cylinder_info(f, dive);
 	save_weightsystem_info(f, dive);
-	save_events(f, dive->events);
-	for (i = 0; i < dive->samples; i++)
-		save_sample(f, dive->sample+i);
+	save_events(f, dive->dc.events);
+	for (i = 0; i < dive->dc.samples; i++)
+		save_sample(f, dive->dc.sample+i);
 	fprintf(f, "</dive>\n");
 }
 
diff --git a/uemis.c b/uemis.c
index d8bec845d208..dd98012a4d8d 100644
--- a/uemis.c
+++ b/uemis.c
@@ -113,50 +113,50 @@ static gboolean in_deco;
  * when we write them to the XML file we'll always have the English strings,
  * regardless of locale
  */
-void uemis_event(struct dive *dive, struct sample *sample, uemis_sample_t *u_sample)
+static void uemis_event(struct dive *dive, struct divecomputer *dc, struct sample *sample, uemis_sample_t *u_sample)
 {
 	uint8_t *flags = u_sample->flags;
 
 	if (flags[1] & 0x01)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Safety Stop Violation"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Safety Stop Violation"));
 	if (flags[1] & 0x08)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Speed Alarm"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Speed Alarm"));
 #if WANT_CRAZY_WARNINGS
 	if (flags[1] & 0x06) /* both bits 1 and 2 are a warning */
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Speed Warning"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Speed Warning"));
 	if (flags[1] & 0x10)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("PO2 Green Warning"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("PO2 Green Warning"));
 #endif
 	if (flags[1] & 0x20)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("PO2 Ascend Warning"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("PO2 Ascend Warning"));
 	if (flags[1] & 0x40)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("PO2 Ascend Alarm"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("PO2 Ascend Alarm"));
 	/* flags[2] reflects the deco / time bar
 	 * flags[3] reflects more display details on deco and pO2 */
 	if (flags[4] & 0x01)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Tank Pressure Info"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Tank Pressure Info"));
 	if (flags[4] & 0x04)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("RGT Warning"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("RGT Warning"));
 	if (flags[4] & 0x08)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("RGT Alert"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("RGT Alert"));
 	if (flags[4] & 0x40)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Tank Change Suggested"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Tank Change Suggested"));
 	if (flags[4] & 0x80)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Depth Limit Exceeded"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Depth Limit Exceeded"));
 	if (flags[5] & 0x01)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Max Deco Time Warning"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Max Deco Time Warning"));
 	if (flags[5] & 0x04)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Dive Time Info"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Dive Time Info"));
 	if (flags[5] & 0x08)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Dive Time Alert"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Dive Time Alert"));
 	if (flags[5] & 0x10)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Marker"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Marker"));
 	if (flags[6] & 0x02)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("No Tank Data"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("No Tank Data"));
 	if (flags[6] & 0x04)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Low Battery Warning"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Low Battery Warning"));
 	if (flags[6] & 0x08)
-		add_event(dive, sample->time.seconds, 0, 0, 0, N_("Low Battery Alert"));
+		add_event(dc, sample->time.seconds, 0, 0, 0, N_("Low Battery Alert"));
 	/* flags[7] reflects the little on screen icons that remind of previous
 	 * warnings / alerts - not useful for events */
 
@@ -164,14 +164,14 @@ void uemis_event(struct dive *dive, struct sample *sample, uemis_sample_t *u_sam
 	if (u_sample->p_amb_tol > dive->surface_pressure.mbar &&
 	    u_sample->hold_time &&
 	    u_sample->hold_time < 99) {
-		add_event(dive, sample->time.seconds, SAMPLE_EVENT_CEILING, SAMPLE_FLAGS_BEGIN,
+		add_event(dc, sample->time.seconds, SAMPLE_EVENT_CEILING, SAMPLE_FLAGS_BEGIN,
 			u_sample->hold_depth * 10, N_("ceiling"));
-		add_event(dive, sample->time.seconds, SAMPLE_EVENT_DECOSTOP, 0,
+		add_event(dc, sample->time.seconds, SAMPLE_EVENT_DECOSTOP, 0,
 			u_sample->hold_time * 60, N_("deco"));
 		in_deco = TRUE;
 	} else if (in_deco) {
 		in_deco = FALSE;
-		add_event(dive, sample->time.seconds, SAMPLE_EVENT_CEILING, SAMPLE_FLAGS_END,
+		add_event(dc, sample->time.seconds, SAMPLE_EVENT_CEILING, SAMPLE_FLAGS_END,
 			0, N_("ceiling"));
 	}
 }
@@ -186,6 +186,7 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
 	struct sample *sample;
 	uemis_sample_t *u_sample;
 	struct dive *dive = datap;
+	struct divecomputer *dc = &dive->dc;
 	int template, gasoffset;
 
 	in_deco = FALSE;
@@ -235,15 +236,15 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
 		 * duration in the header is a) in minutes and b) up to 3 minutes short */
 		if (u_sample->dive_time > dive->duration.seconds + 180)
 			break;
-		sample = prepare_sample(dive);
+		sample = prepare_sample(dc);
 		sample->time.seconds = u_sample->dive_time;
 		sample->depth.mm = rel_mbar_to_depth(u_sample->water_pressure, dive);
 		sample->temperature.mkelvin = (u_sample->dive_temperature * 100) + 273150;
 		sample->cylinderindex = u_sample->active_tank;
 		sample->cylinderpressure.mbar =
 			(u_sample->tank_pressure_high * 256 + u_sample->tank_pressure_low) * 10;
-		uemis_event(dive, sample, u_sample);
-		finish_sample(dive);
+		uemis_event(dive, dc, sample, u_sample);
+		finish_sample(dc);
 		i += 0x25;
 		u_sample++;
 	}
-- 
1.8.0



More information about the subsurface mailing list