summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2011-09-22 18:02:54 -0700
committerGravatar Linus Torvalds <torvalds@linux-foundation.org>2011-09-22 18:02:54 -0700
commit3a77eb85101a5fb1dc186b88a3a02d2ae27690c7 (patch)
treebf40abf756c788347830b1990423f9c5ce9968b8
parent50c2bb7c71b279237f05c1c0a530d494bad534c8 (diff)
downloadsubsurface-3a77eb85101a5fb1dc186b88a3a02d2ae27690c7.tar.gz
Start handling dive events
Parse them, save them, take them from libdivecomputer. This doesn't merge them or show them in the profile yet, though. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--dive.c23
-rw-r--r--dive.h18
-rw-r--r--libdivecomputer.c8
-rw-r--r--parse-xml.c45
-rw-r--r--save-xml.c26
5 files changed, 112 insertions, 8 deletions
diff --git a/dive.c b/dive.c
index 1de3759d1..67a78cc8a 100644
--- a/dive.c
+++ b/dive.c
@@ -5,6 +5,29 @@
#include "dive.h"
+void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name)
+{
+ struct event *ev, **p;
+ unsigned int size, len = strlen(name);
+
+ size = sizeof(*ev) + len + 1;
+ ev = malloc(size);
+ if (!ev)
+ return;
+ memset(ev, 0, size);
+ memcpy(ev->name, name, len);
+ ev->time.seconds = time;
+ ev->type = type;
+ ev->flags = flags;
+ ev->value = value;
+ ev->next = NULL;
+
+ p = &dive->events;
+ while (*p)
+ p = &(*p)->next;
+ *p = ev;
+}
+
double get_depth_units(unsigned int mm, int *frac, const char **units)
{
int decimals;
diff --git a/dive.h b/dive.h
index e1a5bc007..b121892e9 100644
--- a/dive.h
+++ b/dive.h
@@ -142,6 +142,21 @@ struct sample {
int cylinderindex;
};
+/*
+ * Events are currently pretty meaningless. This is
+ * just based on the random data that libdivecomputer
+ * gives us. I'm not sure what a real "architected"
+ * event model would actually look like, but right
+ * now you can associate a list of events with a dive,
+ * and we'll do something about it.
+ */
+struct event {
+ struct event *next;
+ duration_t time;
+ int type, flags, value;
+ char name[];
+};
+
#define MAX_CYLINDERS (8)
struct dive {
@@ -156,6 +171,7 @@ struct dive {
depth_t visibility;
temperature_t airtemp, watertemp;
cylinder_t cylinder[MAX_CYLINDERS];
+ struct event *events;
int samples, alloc_samples;
struct sample sample[];
};
@@ -227,6 +243,8 @@ extern struct dive *try_to_merge(struct dive *a, struct dive *b);
extern void renumber_dives(int nr);
+extern void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name);
+
/* UI related protopypes */
extern void init_ui(int argc, char **argv);
diff --git a/libdivecomputer.c b/libdivecomputer.c
index b20acdbec..806ea651f 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -118,7 +118,7 @@ static int parse_gasmixes(struct dive *dive, parser_t *parser, int ngases)
return PARSER_STATUS_SUCCESS;
}
-static void handle_event(struct dive **divep, struct sample *sample, parser_sample_value_t value)
+static void handle_event(struct dive *dive, struct sample *sample, parser_sample_value_t value)
{
int type, time;
static const char *events[] = {
@@ -152,9 +152,7 @@ static void handle_event(struct dive **divep, struct sample *sample, parser_samp
if (sample)
time += sample->time.seconds;
- printf(" <event type=\"%u\" time=\"%u:%02u\" flags=\"%u\" value=\"%u\" name=\"%s\" />\n",
- type, time / 60, time % 60,
- value.event.flags, value.event.value, name);
+ add_event(dive, time, type, value.event.flags, value.event.value, name);
}
void
@@ -188,7 +186,7 @@ sample_cb(parser_sample_type_t type, parser_sample_value_t value, void *userdata
sample->temperature.mkelvin = (value.temperature + 273.15) * 1000 + 0.5;
break;
case SAMPLE_TYPE_EVENT:
- handle_event(divep, sample, value);
+ handle_event(dive, sample, value);
break;
case SAMPLE_TYPE_RBT:
printf(" <rbt>%u</rbt>\n", value.rbt);
diff --git a/parse-xml.c b/parse-xml.c
index 1eb6e95fd..e6472735d 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -92,8 +92,14 @@ const struct units IMPERIAL_units = {
*/
static struct dive *dive;
static struct sample *sample;
+static struct {
+ int active;
+ duration_t time;
+ int type, flags, value;
+ const char *name;
+} event;
static struct tm tm;
-static int event_index, cylinder_index;
+static int cylinder_index;
static enum import_source {
UNKNOWN,
@@ -558,6 +564,32 @@ static int uddf_fill_sample(struct sample *sample, const char *name, int len, ch
0;
}
+static void eventtime(char *buffer, void *_duration)
+{
+ duration_t *duration = _duration;
+ sampletime(buffer, duration);
+ if (sample)
+ duration->seconds += sample->time.seconds;
+}
+
+static void try_to_fill_event(const char *name, char *buf)
+{
+ int len = strlen(name);
+
+ start_match("event", name, buf);
+ if (MATCH(".event", utf8_string, &event.name))
+ return;
+ if (MATCH(".name", utf8_string, &event.name))
+ return;
+ if (MATCH(".time", eventtime, &event.time))
+ return;
+ if (MATCH(".type", get_index, &event.type))
+ return;
+ if (MATCH(".flags", get_index, &event.flags))
+ return;
+ nonmatch("event", name, buf);
+}
+
/* We're in samples - try to convert the random xml value to something useful */
static void try_to_fill_sample(struct sample *sample, const char *name, char *buf)
{
@@ -1137,11 +1169,15 @@ static void dive_end(void)
static void event_start(void)
{
+ memset(&event, 0, sizeof(event));
+ event.active = 1;
}
static void event_end(void)
{
- event_index++;
+ if (event.name)
+ add_event(dive, event.time.seconds, event.type, event.flags, event.value, event.name);
+ event.active = 0;
}
static void cylinder_start(void)
@@ -1156,7 +1192,6 @@ static void cylinder_end(void)
static void sample_start(void)
{
sample = prepare_sample(&dive);
- event_index = 0;
}
static void sample_end(void)
@@ -1176,6 +1211,10 @@ static void entry(const char *name, int size, const char *raw)
return;
memcpy(buf, raw, size);
buf[size] = 0;
+ if (event.active) {
+ try_to_fill_event(name, buf);
+ return;
+ }
if (sample) {
try_to_fill_sample(sample, name, buf);
return;
diff --git a/save-xml.c b/save-xml.c
index e64b380a4..d6774b5c7 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -218,6 +218,12 @@ static void save_cylinder_info(FILE *f, struct dive *dive)
}
}
+static void show_index(FILE *f, int value, const char *pre, const char *post)
+{
+ if (value)
+ fprintf(f, " %s%d%s", pre, value, post);
+}
+
static void save_sample(FILE *f, struct sample *sample)
{
fprintf(f, " <sample time='%u:%02u min'", FRACTION(sample->time.seconds,60));
@@ -229,6 +235,25 @@ static void save_sample(FILE *f, struct sample *sample)
fprintf(f, " />\n");
}
+static void save_one_event(FILE *f, struct event *ev)
+{
+ fprintf(f, " <event time='%d:%02d min'", FRACTION(ev->time.seconds,60));
+ show_index(f, ev->type, "type='", "'");
+ show_index(f, ev->flags, "flags='", "'");
+ show_index(f, ev->value, "value='", "'");
+ show_utf8(f, ev->name, " name='", "'");
+ fprintf(f, " />\n");
+}
+
+
+static void save_events(FILE *f, struct event *ev)
+{
+ while (ev) {
+ save_one_event(f, ev);
+ ev = ev->next;
+ }
+}
+
static void save_dive(FILE *f, struct dive *dive)
{
int i;
@@ -245,6 +270,7 @@ static void save_dive(FILE *f, struct dive *dive)
FRACTION(dive->duration.seconds, 60));
save_overview(f, dive);
save_cylinder_info(f, dive);
+ save_events(f, dive->events);
for (i = 0; i < dive->samples; i++)
save_sample(f, dive->sample+i);
fprintf(f, "</dive>\n");