summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2013-02-22 16:18:39 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-02-22 20:17:39 -0800
commit0eb53fab52acdcca60a3a80d4d0d9e1e9fffb38b (patch)
tree6d48ad790d3f9c181a2494a62bf03c34b11e0bf2
parent48de523f15a275bec106333fe64779dc8d3a4bb8 (diff)
downloadsubsurface-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>
-rw-r--r--parse-xml.c54
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;