mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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:
parent
5511a0e14e
commit
cb53a78674
4 changed files with 144 additions and 96 deletions
95
parse-xml.c
95
parse-xml.c
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue