summaryrefslogtreecommitdiff
path: root/usr.bin/awk/lib.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2020-12-18 21:36:25 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2020-12-18 21:36:25 +0000
commit9c20ce7e43f767b214436c2eb7f1f83012997fc4 (patch)
tree5913eb697db482fe0495bdb86ab010f353a82d53 /usr.bin/awk/lib.c
parent8523083623e5c13192c34543687c5b7c3a60522c (diff)
Update awk to December 18, 2020 version.
Includes the official fix for +-inf and +-nan handling.
Diffstat (limited to 'usr.bin/awk/lib.c')
-rw-r--r--usr.bin/awk/lib.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/usr.bin/awk/lib.c b/usr.bin/awk/lib.c
index 61d9b7a05ee..8cbdd6d29c6 100644
--- a/usr.bin/awk/lib.c
+++ b/usr.bin/awk/lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lib.c,v 1.43 2020/12/17 20:06:09 millert Exp $ */
+/* $OpenBSD: lib.c,v 1.44 2020/12/18 21:36:24 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -31,6 +31,7 @@ THIS SOFTWARE.
#include <stdlib.h>
#include <stdarg.h>
#include <limits.h>
+#include <math.h>
#include "awk.h"
char EMPTY[] = { '\0' };
@@ -784,6 +785,8 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
double r;
char *ep;
bool retval = false;
+ bool is_nan = false;
+ bool is_inf = false;
if (no_trailing)
*no_trailing = false;
@@ -792,47 +795,38 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
s++;
// 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;
// allow +nan, -nan, +inf, -inf, any other letter, no
if (s[0] == '+' || s[0] == '-') {
- if ((strncasecmp(s+1, "nan", 3) == 0 ||
- strncasecmp(s+1, "inf", 3) == 0)) {
- trailing_stuff_ok = false;
- ep = (char *)(long)s + 4;
- if (isspace((uschar)*ep)) {
- trailing_stuff_ok = true;
- 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] != '.')
+ is_nan = (strncasecmp(s+1, "nan", 3) == 0);
+ is_inf = (strncasecmp(s+1, "inf", 3) == 0);
+ if ((is_nan || is_inf)
+ && (isspace((uschar)s[4]) || s[4] == '\0'))
+ goto convert;
+ else if (! isdigit((uschar)s[1]) && s[1] != '.')
return false;
- } else if (! isdigit((uschar)s[0]) && s[0] != '.')
+ }
+ else if (! isdigit((uschar)s[0]) && s[0] != '.')
return false;
+convert:
errno = 0;
r = strtod(s, &ep);
if (ep == s || errno == ERANGE)
return false;
+ if (isnan(r) && s[0] == '-' && signbit(r) == 0)
+ r = -r;
+
if (result != NULL)
*result = r;
- // check for trailing stuff
- while (isspace((uschar)*ep))
- ep++;
+ retval = (isspace((uschar)*ep) || *ep == '\0' || trailing_stuff_ok);
- if (no_trailing)
+ if (no_trailing != NULL)
*no_trailing = (*ep == '\0');
- // return true if found the end, or trailing stuff is allowed
- retval = (*ep == '\0') || trailing_stuff_ok;
-
return retval;
}