Make our 'ascii_strtod()' helper more generic

We'll want to do sane parsing of strings, but the C library makes it
hard to handle user input sanely and the Qt toDouble() function
interface was designed by a retarded chipmunk.

So just extend our existing hacky "ascii_strtod()" to allow a more
generic interface.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Linus Torvalds 2014-01-02 20:35:35 -08:00 committed by Dirk Hohndel
parent 5511a0e14e
commit cb53a78674
4 changed files with 144 additions and 96 deletions

View file

@ -263,101 +263,6 @@ enum number_type {
FLOAT
};
double ascii_strtod(char *str, char **ptr)
{
char *p = str, c, *ep;
double val = 0.0;
double decimal = 1.0;
int sign = 0, esign = 0;
int numbers = 0, dot = 0;
/* skip spaces */
while (isspace(c = *p++))
/* */;
/* optional sign */
switch (c) {
case '-':
sign = 1;
/* fallthrough */
case '+':
c = *p++;
}
/* Mantissa */
for (;;c = *p++) {
if (c == '.') {
if (dot)
goto done;
dot = 1;
continue;
}
if (c >= '0' && c <= '9') {
numbers++;
if (dot) {
decimal /= 10;
val += (c - '0') * decimal;
} else {
val = (val * 10) + (c - '0');
}
continue;
}
if (c != 'e' && c != 'E')
goto done;
break;
}
if (!numbers)
goto done;
/* Exponent */
ep = p;
c = *ep++;
switch (c) {
case '-':
esign = 1;
/* fallthrough */
case '+':
c = *ep++;
}
if (c >= '0' && c <= '9') {
p = ep;
int exponent = c - '0';
for (;;) {
c = *p++;
if (c < '0' || c > '9')
break;
exponent *= 10;
exponent += c - '0';
}
/* We're not going to bother playing games */
if (exponent > 308)
exponent = 308;
while (exponent-- > 0) {
if (esign)
val /= 10;
else
val *= 10;
}
}
done:
if (!numbers)
goto no_conversion;
if (ptr)
*ptr = p-1;
return sign ? -val : val;
no_conversion:
if (ptr)
*ptr = str;
return 0.0;
}
static enum number_type parse_float(char *buffer, double *res, char **endp)
{
double val;