From 3a77eb85101a5fb1dc186b88a3a02d2ae27690c7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 22 Sep 2011 18:02:54 -0700 Subject: [PATCH] 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 --- dive.c | 23 +++++++++++++++++++++++ dive.h | 18 ++++++++++++++++++ libdivecomputer.c | 8 +++----- parse-xml.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- save-xml.c | 26 ++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 8 deletions(-) diff --git a/dive.c b/dive.c index 1de3759..67a78cc 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 e1a5bc0..b121892 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 b20acdb..806ea65 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(" \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(" %u\n", value.rbt); diff --git a/parse-xml.c b/parse-xml.c index 1eb6e95..e647273 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 e64b380..d6774b5 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, " 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, " 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, "\n"); -- 2.43.0