+ cylinder_t *cylinder = _cylinder;
+ unsigned int index = cylinder - cur_dive->cylinder;
+
+ if (index > 6) {
+ fprintf(stderr, "Uemis cylinder pointer calculations broken\n");
+ return -1;
+ }
+ switch(uemis_gas_template) {
+ case 1: /* Dive uses tank 1 */
+ index -= 1;
+ /* Fallthrough */
+ case 0: /* Dive uses tank 0 */
+ if (index)
+ index = -1;
+ break;
+ case 2: /* Dive uses tanks 2-3 */
+ index -= 2;
+ if (index > 1)
+ index = -1;
+ break;
+ case 3: /* Dive uses tanks 4-6 */
+ index -= 4;
+ if (index > 2)
+ index = -1;
+ break;
+ }
+ return index;
+}
+
+static void uemis_cylindersize(char *buffer, void *_cylinder)
+{
+ int index = uemis_cylinder_index(_cylinder);
+ if (index >= 0)
+ cylindersize(buffer, &cur_dive->cylinder[index].type.size);
+}
+
+static void uemis_percent(char *buffer, void *_cylinder)
+{
+ int index = uemis_cylinder_index(_cylinder);
+ if (index >= 0)
+ percent(buffer, &cur_dive->cylinder[index].gasmix.o2);
+}
+
+static int uemis_dive_match(struct dive **divep, const char *name, int len, char *buf)
+{
+ struct dive *dive = *divep;
+
+ return MATCH(".units.length", uemis_length_unit, &input_units) ||
+ MATCH(".units.volume", uemis_volume_unit, &input_units) ||
+ MATCH(".units.pressure", uemis_pressure_unit, &input_units) ||
+ MATCH(".units.temperature", uemis_temperature_unit, &input_units) ||
+ MATCH(".units.weight", uemis_weight_unit, &input_units) ||
+ MATCH(".units.time", uemis_time_unit, &input_units) ||
+ MATCH(".units.date", uemis_date_unit, &input_units) ||
+ MATCH(".date_time", uemis_date_time, &dive->when) ||
+ MATCH(".time_zone", uemis_time_zone, &dive->when) ||
+ MATCH(".ambient.temperature", decicelsius, &dive->airtemp) ||
+ MATCH(".gas.template", get_index, &uemis_gas_template) ||
+ MATCH(".air.bottom_tank.size", uemis_cylindersize, dive->cylinder + 0) ||
+ MATCH(".air.bottom_tank.oxygen", uemis_percent, dive->cylinder + 0) ||
+ MATCH(".nitrox_1.bottom_tank.size", uemis_cylindersize, dive->cylinder + 1) ||
+ MATCH(".nitrox_1.bottom_tank.oxygen", uemis_percent, dive->cylinder + 1) ||
+ MATCH(".nitrox_2.bottom_tank.size", uemis_cylindersize, dive->cylinder + 2) ||
+ MATCH(".nitrox_2.bottom_tank.oxygen", uemis_percent, dive->cylinder + 2) ||
+ MATCH(".nitrox_2.deco_tank.size", uemis_cylindersize, dive->cylinder + 3) ||
+ MATCH(".nitrox_2.deco_tank.oxygen", uemis_percent, dive->cylinder + 3) ||
+ MATCH(".nitrox_3.bottom_tank.size", uemis_cylindersize, dive->cylinder + 4) ||
+ MATCH(".nitrox_3.bottom_tank.oxygen", uemis_percent, dive->cylinder + 4) ||
+ MATCH(".nitrox_3.deco_tank.size", uemis_cylindersize, dive->cylinder + 5) ||
+ MATCH(".nitrox_3.deco_tank.oxygen", uemis_percent, dive->cylinder + 5) ||
+ MATCH(".nitrox_3.travel_tank.size", uemis_cylindersize, dive->cylinder + 6) ||
+ MATCH(".nitrox_3.travel_tank.oxygen", uemis_percent, dive->cylinder + 6) ||
+ MATCH(".dive.val.float", uemis_duration, &dive->duration) ||
+ MATCH(".dive.val.ts", uemis_ts, &dive->when) ||
+ MATCH(".dive.val.bin", uemis_parse_divelog_binary, divep) ||
+ 0;
+}
+
+/*
+ * Uddf specifies ISO 8601 time format.
+ *
+ * There are many variations on that. This handles the useful cases.
+ */
+static void uddf_datetime(char *buffer, void *_when)
+{
+ char c;
+ int y,m,d,hh,mm,ss;
+ time_t *when = _when;
+ struct tm tm = { 0 };
+ int i;
+
+ i = sscanf(buffer, "%d-%d-%d%c%d:%d:%d", &y, &m, &d, &c, &hh, &mm, &ss);
+ if (i == 7)
+ goto success;
+ ss = 0;
+ if (i == 6)
+ goto success;
+
+ i = sscanf(buffer, "%04d%02d%02d%c%02d%02d%02d", &y, &m, &d, &c, &hh, &mm, &ss);
+ if (i == 7)
+ goto success;
+ ss = 0;
+ if (i == 6)
+ goto success;
+bad_date:
+ printf("Bad date time %s\n", buffer);
+ free(buffer);
+ return;
+
+success:
+ if (c != 'T' && c != ' ')
+ goto bad_date;
+ tm.tm_year = y;
+ tm.tm_mon = m - 1;
+ tm.tm_mday = d;
+ tm.tm_hour = hh;
+ tm.tm_min = mm;
+ tm.tm_sec = ss;
+ *when = utc_mktime(&tm);
+ free(buffer);
+}
+
+static int uddf_dive_match(struct dive **divep, const char *name, int len, char *buf)
+{
+ struct dive *dive = *divep;
+
+ return MATCH(".datetime", uddf_datetime, &dive->when) ||
+ MATCH(".diveduration", duration, &dive->duration) ||
+ MATCH(".greatestdepth", depth, &dive->maxdepth) ||
+ 0;
+}
+
+static void gps_location(char *buffer, void *_dive)
+{
+ int i;
+ struct dive *dive = _dive;
+ double latitude, longitude;
+
+ i = sscanf(buffer, "%lf %lf", &latitude, &longitude);
+ if (i == 2) {
+ dive->latitude = latitude;
+ dive->longitude = longitude;
+ }
+ free(buffer);