dive_table.nr = nr+1;
}
+void record_trip(struct dive *trip)
+{
+ dive_trip_list = insert_trip(trip, dive_trip_list);
+}
+
+static void delete_dive_renumber(struct dive **dives, int i, int nr)
+{
+ struct dive *dive = dives[i];
+ int number = dive->number, j;
+
+ if (!number)
+ return;
+
+ /*
+ * Check that all numbered dives after the deleted
+ * ones are consecutive, return without renumbering
+ * if that is not the case.
+ */
+ for (j = i+1; j < nr; j++) {
+ struct dive *next = dives[j];
+ if (!next->number)
+ break;
+ number++;
+ if (next->number != number)
+ return;
+ }
+
+ /*
+ * Ok, we hit the end of the dives or a unnumbered
+ * dive - renumber.
+ */
+ for (j = i+1 ; j < nr; j++) {
+ struct dive *next = dives[j];
+ if (!next->number)
+ break;
+ next->number--;
+ }
+}
+
+/*
+ * Remove a dive from the dive_table array
+ */
+void delete_dive(struct dive *dive)
+{
+ int nr = dive_table.nr, i;
+ struct dive **dives = dive_table.dives;
+
+ /*
+ * Stupid. We know the dive table is sorted by date,
+ * we could do a binary lookup. Sue me.
+ */
+ for (i = 0; i < nr; i++) {
+ struct dive *d = dives[i];
+ if (d != dive)
+ continue;
+ /* should we re-number? */
+ delete_dive_renumber(dives, i, nr);
+ memmove(dives+i, dives+i+1, sizeof(struct dive *)*(nr-i-1));
+ dives[nr] = NULL;
+ dive_table.nr = nr-1;
+ break;
+ }
+}
+
static void start_match(const char *type, const char *name, char *buffer)
{
if (verbose > 2)
* technically the SI unit for pressure is Pascal, but
* we default to bar (10^5 pascal), which people
* actually use. Similarly, C instead of Kelvin.
+ * And kg instead of g.
*/
const struct units SI_units = {
.length = METERS,
/*
* Dive info as it is being built up..
*/
-static struct dive *cur_dive;
+static struct dive *cur_dive, *cur_trip = NULL;
static struct sample *cur_sample;
static struct {
int active;
const char *name;
} cur_event;
static struct tm cur_tm;
-static int cur_cylinder_index;
+static int cur_cylinder_index, cur_ws_index;
static enum import_source {
UNKNOWN,
free(buffer);
}
+static void weight(char *buffer, void *_weight)
+{
+ weight_t *weight = _weight;
+ union int_or_float val;
+
+ switch (integer_or_float(buffer, &val)) {
+ case FLOAT:
+ switch (input_units.weight) {
+ case KG:
+ weight->grams = val.fp * 1000 + 0.5;
+ break;
+ case LBS:
+ weight->grams = val.fp * 453.6 + 0.5;
+ break;
+ }
+ break;
+ default:
+ printf("Strange depth reading %s\n", buffer);
+ }
+}
+
static void temperature(char *buffer, void *_temperature)
{
temperature_t *temperature = _temperature;
free(buffer);
}
+static void get_tripflag(char *buffer, void *_tf)
+{
+ tripflag_t *tf = _tf;
+ tripflag_t i;
+
+ *tf = TF_NONE;
+ for (i = NO_TRIP; i < NUM_TRIPFLAGS; i++)
+ if(! strcmp(buffer, tripflag_names[i]))
+ *tf = i;
+}
+
static void centibar(char *buffer, void *_pressure)
{
pressure_t *pressure = _pressure;
return MATCH(".divetime", sampletime, &sample->time) ||
MATCH(".depth", depth, &sample->depth) ||
MATCH(".temperature", temperature, &sample->temperature) ||
+ MATCH(".tankpressure", pressure, &sample->cylinderpressure) ||
0;
}
if (MATCH(".number", get_index, &dive->number))
return;
+ if (MATCH(".tripflag", get_tripflag, &dive->tripflag))
+ return;
if (MATCH(".date", divedate, &dive->when))
return;
if (MATCH(".time", divetime, &dive->when))
return;
if (MATCH(".location", utf8_string, &dive->location))
return;
+ if (MATCH(".suit", utf8_string, &dive->suit))
+ return;
+ if (MATCH(".divesuit", utf8_string, &dive->suit))
+ return;
if (MATCH(".notes", utf8_string, &dive->notes))
return;
if (MATCH(".divemaster", utf8_string, &dive->divemaster))
return;
if (MATCH(".cylinder.end", pressure, &dive->cylinder[cur_cylinder_index].end))
return;
-
+ if (MATCH(".weightsystem.description", utf8_string, &dive->weightsystem[cur_ws_index].description))
+ return;
+ if (MATCH(".weightsystem.weight", weight, &dive->weightsystem[cur_ws_index].weight))
+ return;
+ if (MATCH("weight", weight, &dive->weightsystem[cur_ws_index].weight))
+ return;
if (MATCH(".o2", gasmix, &dive->cylinder[cur_cylinder_index].gasmix.o2))
return;
if (MATCH(".n2", gasmix_nitrogen, &dive->cylinder[cur_cylinder_index].gasmix))
nonmatch("dive", name, buf);
}
+/* We're in the top-level trip xml. Try to convert whatever value to a trip value */
+static void try_to_fill_trip(struct dive **divep, const char *name, char *buf)
+{
+ int len = strlen(name);
+
+ start_match("trip", name, buf);
+
+ struct dive *dive = *divep;
+
+ if (MATCH(".date", divedate, &dive->when)) {
+ dive->when = utc_mktime(&cur_tm);
+ return;
+ }
+ if (MATCH(".location", utf8_string, &dive->location))
+ return;
+ if (MATCH(".notes", utf8_string, &dive->notes))
+ return;
+
+ nonmatch("trip", name, buf);
+}
+
/*
* File boundaries are dive boundaries. But sometimes there are
* multiple dives per file, so there can be other events too that
record_dive(cur_dive);
cur_dive = NULL;
cur_cylinder_index = 0;
+ cur_ws_index = 0;
+}
+
+static void trip_start(void)
+{
+ if (cur_trip)
+ return;
+ cur_trip = alloc_dive();
+ memset(&cur_tm, 0, sizeof(cur_tm));
+}
+
+static void trip_end(void)
+{
+ if (!cur_trip)
+ return;
+ record_trip(cur_trip);
+ cur_trip = NULL;
}
static void event_start(void)
cur_cylinder_index++;
}
+static void ws_start(void)
+{
+}
+
+static void ws_end(void)
+{
+ cur_ws_index++;
+}
+
static void sample_start(void)
{
cur_sample = prepare_sample(&cur_dive);
try_to_fill_sample(cur_sample, name, buf);
return;
}
+ if (cur_trip) {
+ try_to_fill_trip(&cur_trip, name, buf);
+ return;
+ }
if (cur_dive) {
try_to_fill_dive(&cur_dive, name, buf);
return;
} nesting[] = {
{ "dive", dive_start, dive_end },
{ "Dive", dive_start, dive_end },
+ { "trip", trip_start, trip_end },
{ "sample", sample_start, sample_end },
{ "waypoint", sample_start, sample_end },
{ "SAMPLE", sample_start, sample_end },
{ "event", event_start, event_end },
{ "gasmix", cylinder_start, cylinder_end },
{ "cylinder", cylinder_start, cylinder_end },
+ { "weightsystem", ws_start, ws_end },
{ "P", sample_start, sample_end },
/* Import type recognition */
}
return;
}
- /* we assume that the last (or only) filename passed as argument is a
- * great filename to use as default when saving the dives */
+ /* we assume that the last (or only) filename passed as argument is a
+ * great filename to use as default when saving the dives */
set_filename(url);
reset_all();
dive_start();
static xsltStylesheetPtr get_stylesheet(const char *name)
{
- const char *path = xslt_path, *next;
+ const char *path, *next;
+
+ path = getenv("SUBSURFACE_XSLT_PATH");
+ if (!path)
+ path = xslt_path;
do {
int len;