summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2015-01-26 20:52:41 -0500
committerJarkko Hietaniemi <jhi@iki.fi>2015-01-28 06:52:33 -0500
commitbf8c8f7f2000866d6e5e9e29cb9acdef10025521 (patch)
tree01a68036807fcd13a15e145d7684a521be893de8 /numeric.c
parent13393a5ecffaadc319ca5f8a99d3ca491686fef7 (diff)
downloadperl-bf8c8f7f2000866d6e5e9e29cb9acdef10025521.tar.gz
infnan: actually use grok_hex() for nan payload
And grok_bin() while we are at it. The payload is still unused, but we now at least parse the syntax.
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c77
1 files changed, 47 insertions, 30 deletions
diff --git a/numeric.c b/numeric.c
index b9c9b0a02f..c1a24883de 100644
--- a/numeric.c
+++ b/numeric.c
@@ -655,7 +655,6 @@ Perl_grok_infnan(const char** sp, const char* send)
if (*s == '(') {
/* C99 style "nan(123)" or Perlish equivalent "nan($uv)". */
const char *t;
- UV nanval;
s++;
if (s == send) {
return flags | IS_NUMBER_TRAILING;
@@ -668,11 +667,53 @@ Perl_grok_infnan(const char** sp, const char* send)
return flags | IS_NUMBER_TRAILING;
}
if (*t == ')') {
- int nantype =
- grok_number_flags(s, t - s, &nanval,
- PERL_SCAN_TRAILING |
- PERL_SCAN_ALLOW_UNDERSCORES);
- /* nanval result currently unused */
+ int nantype;
+ UV nanval;
+ if (s[0] == '0' && s + 2 < t &&
+ isALPHA_FOLD_EQ(s[1], 'x') &&
+ isXDIGIT(s[2])) {
+ STRLEN len = t - s;
+ I32 flags = PERL_SCAN_ALLOW_UNDERSCORES;
+ nanval = grok_hex(s, &len, &flags, NULL);
+ if ((flags & PERL_SCAN_GREATER_THAN_UV_MAX)) {
+ nantype = 0;
+ } else {
+ nantype = IS_NUMBER_IN_UV;
+ }
+ s += len;
+ } else if (s[0] == '0' && s + 2 < t &&
+ isALPHA_FOLD_EQ(s[1], 'b') &&
+ (s[2] == '0' || s[2] == '1')) {
+ STRLEN len = t - s;
+ I32 flags = PERL_SCAN_ALLOW_UNDERSCORES;
+ nanval = grok_bin(s, &len, &flags, NULL);
+ if ((flags & PERL_SCAN_GREATER_THAN_UV_MAX)) {
+ nantype = 0;
+ } else {
+ nantype = IS_NUMBER_IN_UV;
+ }
+ s += len;
+ } else {
+ const char *u;
+ nantype =
+ grok_number_flags(s, t - s, &nanval,
+ PERL_SCAN_TRAILING |
+ PERL_SCAN_ALLOW_UNDERSCORES);
+ /* Unfortunately grok_number_flags() doesn't
+ * tell how far we got and the ')' will always
+ * be "trailing", so we need to double-check
+ * whether we had something dubious. */
+ for (u = s; u < t; u++) {
+ if (!isDIGIT(*u)) {
+ flags |= IS_NUMBER_TRAILING;
+ break;
+ }
+ }
+ s = u;
+ }
+
+ /* "What about octal?" Really? */
+
if ((nantype & IS_NUMBER_NOT_INT) ||
!(nantype && IS_NUMBER_IN_UV)) {
/* Certain configuration combinations where
@@ -694,30 +735,6 @@ Perl_grok_infnan(const char** sp, const char* send)
* (rightmost) bits of the payload. */
return 0;
}
- /* Unfortunately the grok_ interfaces don't tell
- * the count of the consumed bytes, so we cannot
- * figure out where the scanning left off.
- * So we need to duplicate the basics of
- * the scan ourselves. */
- if (s[0] == '0' && s < t &&
- isALPHA_FOLD_EQ(s[1], 'x')) {
- const char *u = s + 2;
- if (isXDIGIT(*u)) {
- while (u < t &&
- (isXDIGIT(*u) || *u == '_')) {
- u++;
- }
- }
- s = u;
- } else if (isDIGIT(*s) && s < t) {
- const char *u = s + 2;
- while (u < t &&
- (isDIGIT(*u) || *u == '_')) {
- u++;
- }
- s = u;
- }
- /* XXX 0b... maybe, octal (really?) */
if (s < t) {
flags |= IS_NUMBER_TRAILING;
}