diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-22 16:18:39 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-02-22 20:17:39 -0800 |
commit | 0eb53fab52acdcca60a3a80d4d0d9e1e9fffb38b (patch) | |
tree | 6d48ad790d3f9c181a2494a62bf03c34b11e0bf2 /parse-xml.c | |
parent | 48de523f15a275bec106333fe64779dc8d3a4bb8 (diff) | |
download | subsurface-0eb53fab52acdcca60a3a80d4d0d9e1e9fffb38b.tar.gz |
Flesh out the UDDF xml parsing a bit more
Commit 28aba5a2062c ("Flesh out the UDDF xml parsing a bit more")
improved on parsing UDDF files by teaching "percent()" to also handle
pure fractions like UDDF uses. So in a UDDF file, an o2 value of "1.0"
means "100%".
But it turns out that I have a few dives with "1% He", and the "Turn
fractions into percent" logic also turns that into 100%.
So this makes the 'percent()' function a bit smarter. If it actually
finds a percentage-sign after the number, it knows it is already
percent, not a fraction. That disambiguates the two cases: "1.0" is
100%, but "1.0%" (note the explicit percentage sign) is 1%.
So now our native format cannot get confused, because it generally
tries to avoid naked numbers. Good choice.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'parse-xml.c')
-rw-r--r-- | parse-xml.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/parse-xml.c b/parse-xml.c index ddb3ba347..e23ebc0a9 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -195,28 +195,32 @@ static void divedatetime(char *buffer, void *_when) } } -union int_or_float { - double fp; -}; - enum number_type { NEITHER, FLOAT }; -static enum number_type integer_or_float(char *buffer, union int_or_float *res) +static enum number_type parse_float(char *buffer, double *res, char **endp) { - char *end; - double fp; + double val; errno = 0; - fp = g_ascii_strtod(buffer, &end); - if (!errno && end != buffer) { - res->fp = fp; - return FLOAT; - } + val = g_ascii_strtod(buffer, endp); + if (errno || *endp == buffer) + return NEITHER; + + *res = val; + return FLOAT; +} + +union int_or_float { + double fp; +}; - return NEITHER; +static enum number_type integer_or_float(char *buffer, union int_or_float *res) +{ + char *end; + return parse_float(buffer, &res->fp, &end); } static void pressure(char *buffer, void *_press) @@ -361,18 +365,24 @@ static void duration(char *buffer, void *_time) static void percent(char *buffer, void *_fraction) { fraction_t *fraction = _fraction; - union int_or_float val; + double val; + char *end; - switch (integer_or_float(buffer, &val)) { + switch (parse_float(buffer, &val, &end)) { case FLOAT: - /* Turn fractions into percent.. */ - if (val.fp <= 1.0) - val.fp *= 100; - /* Then turn percent into our integer permille format */ - if (val.fp <= 100.0) - fraction->permille = val.fp * 10 + 0.5; - break; + /* Turn fractions into percent unless explicit.. */ + if (val <= 1.0) { + while (isspace(*end)) + end++; + if (*end != '%') + val *= 100; + } + /* Then turn percent into our integer permille format */ + if (val >= 0 && val <= 100.0) { + fraction->permille = val * 10 + 0.5; + break; + } default: printf("Strange percentage reading %s\n", buffer); break; |