Flesh out the UDDF xml parsing a bit more

Commit 28aba5a206 ("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>
This commit is contained in:
Linus Torvalds 2013-02-22 16:18:39 -08:00 committed by Dirk Hohndel
parent 48de523f15
commit 0eb53fab52

View file

@ -195,28 +195,32 @@ static void divedatetime(char *buffer, void *_when)
} }
} }
union int_or_float {
double fp;
};
enum number_type { enum number_type {
NEITHER, NEITHER,
FLOAT FLOAT
}; };
static enum number_type parse_float(char *buffer, double *res, char **endp)
{
double val;
errno = 0;
val = g_ascii_strtod(buffer, endp);
if (errno || *endp == buffer)
return NEITHER;
*res = val;
return FLOAT;
}
union int_or_float {
double fp;
};
static enum number_type integer_or_float(char *buffer, union int_or_float *res) static enum number_type integer_or_float(char *buffer, union int_or_float *res)
{ {
char *end; char *end;
double fp; return parse_float(buffer, &res->fp, &end);
errno = 0;
fp = g_ascii_strtod(buffer, &end);
if (!errno && end != buffer) {
res->fp = fp;
return FLOAT;
}
return NEITHER;
} }
static void pressure(char *buffer, void *_press) 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) static void percent(char *buffer, void *_fraction)
{ {
fraction_t *fraction = _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: case FLOAT:
/* Turn fractions into percent.. */ /* Turn fractions into percent unless explicit.. */
if (val.fp <= 1.0) if (val <= 1.0) {
val.fp *= 100; while (isspace(*end))
/* Then turn percent into our integer permille format */ end++;
if (val.fp <= 100.0) if (*end != '%')
fraction->permille = val.fp * 10 + 0.5; val *= 100;
break; }
/* Then turn percent into our integer permille format */
if (val >= 0 && val <= 100.0) {
fraction->permille = val * 10 + 0.5;
break;
}
default: default:
printf("Strange percentage reading %s\n", buffer); printf("Strange percentage reading %s\n", buffer);
break; break;