X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=parse-xml.c;h=24acb1c1cc9f7f003e490de5c732b503d6b20866;hb=42f627b8b1cf7e929a30c0a07a5fb44a4cec9e1f;hp=4fd4dcfe6415f1495c414b05a69785579355a821;hpb=ed4b739f5f618fa9fb316dcec4c67224bb4f2bb8;p=ext%2Fsubsurface.git diff --git a/parse-xml.c b/parse-xml.c index 4fd4dcf..24acb1c 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -16,7 +16,7 @@ struct dive_table dive_table; /* * Add a dive into the dive_table array */ -static void record_dive(struct dive *dive) +void record_dive(struct dive *dive) { int nr = dive_table.nr, allocated = dive_table.allocated; struct dive **dives = dive_table.dives; @@ -90,7 +90,6 @@ const struct units IMPERIAL_units = { /* * Dive info as it is being built up.. */ -static int alloc_samples; static struct dive *dive; static struct sample *sample; static struct tm tm; @@ -105,7 +104,7 @@ static enum import_source { UDDF, } import_source; -static time_t utc_mktime(struct tm *tm) +time_t utc_mktime(struct tm *tm) { static const int mdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 @@ -410,11 +409,11 @@ static void utf8_string(char *buffer, void *_res) static void water_pressure(char *buffer, void *_depth) { depth_t *depth = _depth; - union int_or_float val; + union int_or_float val; double atm, cm; - switch (integer_or_float(buffer, &val)) { - case FLOAT: + switch (integer_or_float(buffer, &val)) { + case FLOAT: if (!val.fp) break; /* cbar to atm */ @@ -462,10 +461,10 @@ static void centibar(char *buffer, void *_pressure) static void decicelsius(char *buffer, void *_temp) { temperature_t *temp = _temp; - union int_or_float val; + union int_or_float val; - switch (integer_or_float(buffer, &val)) { - case FLOAT: + switch (integer_or_float(buffer, &val)) { + case FLOAT: temp->mkelvin = (val.fp/10 + 273.15) * 1000 + 0.5; break; default: @@ -488,6 +487,16 @@ static int uemis_fill_sample(struct sample *sample, const char *name, int len, c * Divinglog is crazy. The temperatures are in celsius. EXCEPT * for the sample temperatures, that are in Fahrenheit. * WTF? + * + * Oh, and I think Diving Log *internally* probably kept them + * in celsius, because I'm seeing entries like + * + * 32.0 + * + * in there. Which is freezing, aka 0 degC. I bet the "0" is + * what Diving Log uses for "no temperature". + * + * So throw away crap like that. */ static void fahrenheit(char *buffer, void *_temperature) { @@ -496,6 +505,9 @@ static void fahrenheit(char *buffer, void *_temperature) switch (integer_or_float(buffer, &val)) { case FLOAT: + /* Floating point equality is evil, but works for small integers */ + if (val.fp == 32.0) + break; temperature->mkelvin = (val.fp + 459.67) * 5000/9; break; default: @@ -504,12 +516,37 @@ static void fahrenheit(char *buffer, void *_temperature) free(buffer); } +/* + * Did I mention how bat-shit crazy divinglog is? The sample + * pressures are in PSI. But the tank working pressure is in + * bar. WTF^2? + * + * Crazy stuff like this is why diveclog has everything in + * these inconvenient typed structures, and you have to say + * "pressure->mbar" to get the actual value. Exactly so that + * you can never have unit confusion. + */ +static void psi(char *buffer, void *_pressure) +{ + pressure_t *pressure = _pressure; + union int_or_float val; + + switch (integer_or_float(buffer, &val)) { + case FLOAT: + pressure->mbar = val.fp * 68.95 + 0.5; + break; + default: + fprintf(stderr, "Crazy Diving Log PSI reading %s\n", buffer); + } + free(buffer); +} + static int divinglog_fill_sample(struct sample *sample, const char *name, int len, char *buf) { return MATCH(".p.time", sampletime, &sample->time) || MATCH(".p.depth", depth, &sample->depth) || MATCH(".p.temp", fahrenheit, &sample->temperature) || - MATCH(".p.press1", pressure, &sample->cylinderpressure) || + MATCH(".p.press1", psi, &sample->cylinderpressure) || 0; } @@ -613,7 +650,7 @@ static int divinglog_dive_match(struct dive *dive, const char *name, int len, ch MATCH(".entrytime", divetime, &dive->when) || MATCH(".depth", depth, &dive->maxdepth) || MATCH(".tanksize", cylindersize, &dive->cylinder[0].type.size) || - MATCH(".tanktype", utf8_string, &dive->cylinder[0].type.description) || + MATCH(".presw", pressure, &dive->cylinder[0].type.workingpressure) || MATCH(".comments", utf8_string, &dive->notes) || MATCH(".country.name", utf8_string, &country) || MATCH(".city.name", utf8_string, &city) || @@ -667,10 +704,10 @@ static void uemis_date_unit(char *buffer, void *_unused) static void uemis_date_time(char *buffer, void *_when) { time_t *when = _when; - union int_or_float val; + union int_or_float val; - switch (integer_or_float(buffer, &val)) { - case FLOAT: + switch (integer_or_float(buffer, &val)) { + case FLOAT: *when = (val.fp - 40587) * 86400; break; default: @@ -876,6 +913,8 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf) break; } + if (MATCH(".number", get_index, &dive->number)) + return; if (MATCH(".date", divedate, &dive->when)) return; if (MATCH(".time", divetime, &dive->when)) @@ -944,21 +983,13 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf) */ static void dive_start(void) { - unsigned int size; - if (dive) return; - - alloc_samples = 5; - size = dive_size(alloc_samples); - dive = malloc(size); - if (!dive) - exit(1); - memset(dive, 0, size); + dive = alloc_dive(); memset(&tm, 0, sizeof(tm)); } -static void sanitize_gasmix(gasmix_t *mix) +static void sanitize_gasmix(struct gasmix *mix) { unsigned int o2, he; @@ -989,7 +1020,8 @@ static void sanitize_gasmix(gasmix_t *mix) */ static void match_standard_cylinder(cylinder_type_t *type) { - int psi, cuft, len; + double cuft; + int psi, len; const char *fmt; char buffer[20], *p; @@ -997,7 +1029,8 @@ static void match_standard_cylinder(cylinder_type_t *type) if (type->description) return; - cuft = type->size.mliter / 1000; + cuft = type->size.mliter / 28317.0; + cuft *= type->workingpressure.mbar / 1013.25; psi = type->workingpressure.mbar / 68.95; switch (psi) { @@ -1005,7 +1038,7 @@ static void match_standard_cylinder(cylinder_type_t *type) fmt = "LP%d"; break; case 2600 ... 2700: /* 2640 psi: LP+10% */ - fmt = "LP%d+"; + fmt = "LP%d"; break; case 2900 ... 3100: /* 3000 psi: ALx tank */ fmt = "AL%d"; @@ -1019,7 +1052,7 @@ static void match_standard_cylinder(cylinder_type_t *type) default: return; } - len = snprintf(buffer, sizeof(buffer), fmt, cuft); + len = snprintf(buffer, sizeof(buffer), fmt, (int) (cuft+0.5)); p = malloc(len+1); if (!p) return; @@ -1050,15 +1083,15 @@ static void sanitize_cylinder_type(cylinder_type_t *type) if (!type->size.mliter) return; - /* Ok, we have both size and pressure: try to match a description */ - match_standard_cylinder(type); - if (input_units.volume == CUFT || import_source == SUUNTO) { volume_of_air = type->size.mliter * 28.317; /* milli-cu ft to milliliter */ atm = type->workingpressure.mbar / 1013.25; /* working pressure in atm */ volume = volume_of_air / atm; /* milliliters at 1 atm: "true size" */ type->size.mliter = volume + 0.5; } + + /* Ok, we have both size and pressure: try to match a description */ + match_standard_cylinder(type); } static void sanitize_cylinder_info(struct dive *dive) @@ -1101,22 +1134,7 @@ static void cylinder_end(void) static void sample_start(void) { - int nr; - - if (!dive) - return; - nr = dive->samples; - if (nr >= alloc_samples) { - unsigned int size; - - alloc_samples = (alloc_samples * 3)/2 + 10; - size = dive_size(alloc_samples); - dive = realloc(dive, size); - if (!dive) - return; - } - sample = dive->sample + nr; - memset(sample, 0, sizeof(*sample)); + sample = prepare_sample(&dive); event_index = 0; } @@ -1125,8 +1143,8 @@ static void sample_end(void) if (!dive) return; + finish_sample(dive, sample); sample = NULL; - dive->samples++; } static void entry(const char *name, int size, const char *raw) @@ -1246,10 +1264,12 @@ static void DivingLog_importer(void) * * Temperatures are in C, except in samples, * when they are in Fahrenheit. Depths are in - * meters, but pressure is in PSI. + * meters, an dpressure is in PSI in the samples, + * but in bar when it comes to working pressure. + * + * Crazy f*%^ morons. */ input_units = SI_units; - input_units.pressure = PSI; } static void uddf_importer(void) @@ -1333,9 +1353,9 @@ void parse_xml_file(const char *filename, GError **error) if (error != NULL) { *error = g_error_new(g_quark_from_string("divelog"), - DIVE_ERROR_PARSE, - "Failed to parse '%s'", - filename); + DIVE_ERROR_PARSE, + "Failed to parse '%s'", + filename); } return; }