diff options
author | Karl Williamson <public@khwilliamson.com> | 2013-12-31 22:41:39 -0700 |
---|---|---|
committer | Karl Williamson <public@khwilliamson.com> | 2014-01-01 13:49:24 -0700 |
commit | 626ef08910b91efb9ac7ecd5f41e991c2a4ce5dd (patch) | |
tree | 243c359e9d115d0661755f0a66a0cd2ddc78aff9 /numeric.c | |
parent | cb27eebd32af3dfebf46f5eb3778fe29175004b5 (diff) | |
download | perl-626ef08910b91efb9ac7ecd5f41e991c2a4ce5dd.tar.gz |
numeric.c: Use macros instead of strchr()
This replaces uses of strchr() (and hence its loop) with a simple array
lookup, mask, and test. This causes an extra test to be needed later in
the hex decoding case to get the hex value, instead of a subtract
previously. However these two tests are fewer than the average number
in strchr().
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 35 |
1 files changed, 15 insertions, 20 deletions
@@ -291,15 +291,14 @@ Perl_grok_hex(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) } for (; len-- && *s; s++) { - const char *hexdigit = strchr(PL_hexdigit, *s); - if (hexdigit) { + if (isXDIGIT(*s)) { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. With gcc seems to be much straighter code than old scan_hex. */ redo: if (!overflowed) { if (value <= max_div_16) { - value = (value << 4) | ((hexdigit - PL_hexdigit) & 15); + value = (value << 4) | XDIGIT_VALUE(*s); continue; } /* Bah. We're just overflowed. */ @@ -316,11 +315,11 @@ Perl_grok_hex(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount of 16-tuples. */ - value_nv += (NV)((hexdigit - PL_hexdigit) & 15); + value_nv += (NV) XDIGIT_VALUE(*s); continue; } if (*s == '_' && len && allow_underscores && s[1] - && (hexdigit = strchr(PL_hexdigit, s[1]))) + && isXDIGIT(s[1])) { --len; ++s; @@ -395,17 +394,14 @@ Perl_grok_oct(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) PERL_ARGS_ASSERT_GROK_OCT; for (; len-- && *s; s++) { - /* gcc 2.95 optimiser not smart enough to figure that this subtraction - out front allows slicker code. */ - int digit = *s - '0'; - if (digit >= 0 && digit <= 7) { + if (isOCTAL(*s)) { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. */ redo: if (!overflowed) { if (value <= max_div_8) { - value = (value << 3) | digit; + value = (value << 3) | OCTAL_VALUE(*s); continue; } /* Bah. We're just overflowed. */ @@ -422,20 +418,19 @@ Perl_grok_oct(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount of 8-tuples. */ - value_nv += (NV)digit; + value_nv += (NV) OCTAL_VALUE(*s); continue; } - if (digit == ('_' - '0') && len && allow_underscores - && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) - { - --len; - ++s; - goto redo; - } + if (*s == '_' && len && allow_underscores && isOCTAL(s[1])) { + --len; + ++s; + goto redo; + } /* Allow \octal to work the DWIM way (that is, stop scanning * as soon as non-octal characters are seen, complain only if - * someone seems to want to use the digits eight and nine). */ - if (digit == 8 || digit == 9) { + * someone seems to want to use the digits eight and nine. Since we + * know it is not octal, then if isDIGIT, must be an 8 or 9). */ + if (isDIGIT(*s)) { if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) Perl_ck_warner(aTHX_ packWARN(WARN_DIGIT), "Illegal octal digit '%c' ignored", *s); |