version 1.43, 2020/12/17 20:06:09 |
version 1.44, 2020/12/18 21:36:24 |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <stdarg.h> |
#include <stdarg.h> |
#include <limits.h> |
#include <limits.h> |
|
#include <math.h> |
#include "awk.h" |
#include "awk.h" |
|
|
char EMPTY[] = { '\0' }; |
char EMPTY[] = { '\0' }; |
|
|
double r; |
double r; |
char *ep; |
char *ep; |
bool retval = false; |
bool retval = false; |
|
bool is_nan = false; |
|
bool is_inf = false; |
|
|
if (no_trailing) |
if (no_trailing) |
*no_trailing = false; |
*no_trailing = false; |
|
|
s++; |
s++; |
|
|
// no hex floating point, sorry |
// no hex floating point, sorry |
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) |
if (s[0] == '0' && tolower((uschar)s[1]) == 'x') |
return false; |
return false; |
|
|
// allow +nan, -nan, +inf, -inf, any other letter, no |
// allow +nan, -nan, +inf, -inf, any other letter, no |
if (s[0] == '+' || s[0] == '-') { |
if (s[0] == '+' || s[0] == '-') { |
if ((strncasecmp(s+1, "nan", 3) == 0 || |
is_nan = (strncasecmp(s+1, "nan", 3) == 0); |
strncasecmp(s+1, "inf", 3) == 0)) { |
is_inf = (strncasecmp(s+1, "inf", 3) == 0); |
trailing_stuff_ok = false; |
if ((is_nan || is_inf) |
ep = (char *)(long)s + 4; |
&& (isspace((uschar)s[4]) || s[4] == '\0')) |
if (isspace((uschar)*ep)) { |
goto convert; |
trailing_stuff_ok = true; |
else if (! isdigit((uschar)s[1]) && s[1] != '.') |
do { |
|
ep++; |
|
} while (isspace((uschar)*ep)); |
|
} |
|
if (no_trailing) |
|
*no_trailing = (*ep == '\0'); |
|
if (*ep != '\0' && !trailing_stuff_ok) |
|
return false; |
|
} else if (! isdigit((uschar)s[1]) && s[1] != '.') |
|
return false; |
return false; |
} else if (! isdigit((uschar)s[0]) && s[0] != '.') |
} |
|
else if (! isdigit((uschar)s[0]) && s[0] != '.') |
return false; |
return false; |
|
|
|
convert: |
errno = 0; |
errno = 0; |
r = strtod(s, &ep); |
r = strtod(s, &ep); |
if (ep == s || errno == ERANGE) |
if (ep == s || errno == ERANGE) |
return false; |
return false; |
|
|
|
if (isnan(r) && s[0] == '-' && signbit(r) == 0) |
|
r = -r; |
|
|
if (result != NULL) |
if (result != NULL) |
*result = r; |
*result = r; |
|
|
// check for trailing stuff |
retval = (isspace((uschar)*ep) || *ep == '\0' || trailing_stuff_ok); |
while (isspace((uschar)*ep)) |
|
ep++; |
|
|
|
if (no_trailing) |
if (no_trailing != NULL) |
*no_trailing = (*ep == '\0'); |
*no_trailing = (*ep == '\0'); |
|
|
// return true if found the end, or trailing stuff is allowed |
|
retval = (*ep == '\0') || trailing_stuff_ok; |
|
|
|
return retval; |
return retval; |
} |
} |