diff options
author | Hugo van der Sanden <hv@crypt.org> | 2001-06-10 12:23:30 +0100 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-10 10:55:34 +0000 |
commit | f20cc2f4b57d0af6ae56e81a5194c331ceb01e3b (patch) | |
tree | ee8a22d9bdb44e073630ea0358bc42b5f93e96fd /sv.c | |
parent | 906f284febf43a7190682e42c5aef12275cef5ce (diff) | |
download | perl-f20cc2f4b57d0af6ae56e81a5194c331ceb01e3b.tar.gz |
Re: pragma/locale.t #107
Message-Id: <200106101023.LAA32085@crypt.compulink.co.uk>
Encapsulate the scan of the decimal radix separator.
p4raw-id: //depot/perl@10495
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 106 |
1 files changed, 50 insertions, 56 deletions
@@ -1494,6 +1494,30 @@ S_not_a_number(pTHX_ SV *sv) #define IS_NUMBER_NEG 0x08 /* leading minus sign */ #define IS_NUMBER_INFINITY 0x10 /* this is big */ +static bool +S_grok_numeric_radix(pTHX_ const char **sp, const char *send) +{ +#ifdef USE_LOCALE_NUMERIC + if (PL_numeric_radix_sv && IN_LOCALE) { + STRLEN len; + char* radix = SvPV(PL_numeric_radix_sv, len); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } + /* always try "." if numeric radix didn't match because + * we may have data from different locales mixed */ +#endif + if (*sp < send && **sp == '.') { + ++*sp; + return TRUE; + } + return FALSE; +} + +#define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send) + static int S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep) { @@ -1503,9 +1527,6 @@ S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep) const char max_mod_10 = UV_MAX % 10 + '0'; int numtype = 0; int sawinf = 0; - char* radix = "."; - STRLEN radixlen = 1; - bool radixfound; while (isSPACE(*s)) s++; @@ -1516,11 +1537,6 @@ S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep) else if (*s == '+') s++; -#ifdef USE_LOCALE_NUMERIC - if (PL_numeric_radix_sv && IN_LOCALE) - radix = SvPV(PL_numeric_radix_sv, radixlen); -#endif - /* next must be digit or the radix separator or beginning of infinity */ if (isDIGIT(*s)) { /* UVs are at least 32 bits, so the first 9 decimal digits cannot @@ -1589,64 +1605,42 @@ S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep) *valuep = value; skip_value: - if (s + radixlen <= send && memEQ(s, radix, radixlen)) - radixfound = TRUE; -#ifdef USE_LOCALE_NUMERIC - /* if we did change the radix and the radix is not the "." - * retry with the "." (in case of mixed data) */ - else if (IN_LOCALE && !(*radix == '.' && radixlen == 1) && *s == '.') { - radixlen = 1; - radixfound = TRUE; - } -#endif - if (radixfound) { - s += radixlen; + if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT; while (isDIGIT(*s)) /* optional digits after the radix */ s++; } } - else { - if (s + radixlen <= send && memEQ(s, radix, radixlen)) - radixfound = TRUE; -#ifdef USE_LOCALE_NUMERIC - else if (IN_LOCALE && !(*radix == '.' && radixlen == 1) && *s == '.') { - radixlen = 1; - radixfound = TRUE; + else if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT; + /* no digits before the radix means we need digits after it */ + if (isDIGIT(*s)) { + do { + s++; + } while (isDIGIT(*s)); + numtype |= IS_NUMBER_IN_UV; + if (valuep) { + /* integer approximation is valid - it's 0. */ + *valuep = 0; + } } -#endif - if (radixfound) { - s += radixlen; - numtype |= IS_NUMBER_NOT_INT; - /* no digits before the radix means we need digits after it */ - if (isDIGIT(*s)) { - do { - s++; - } while (isDIGIT(*s)); - numtype |= IS_NUMBER_IN_UV; - if (valuep) { - /* integer approximation is valid - it's 0. */ - *valuep = 0; - } - } - else + else return 0; - } - else if (*s == 'I' || *s == 'i') { + } + else if (*s == 'I' || *s == 'i') { + s++; if (*s != 'N' && *s != 'n') return 0; + s++; if (*s != 'F' && *s != 'f') return 0; + s++; if (*s == 'I' || *s == 'i') { s++; if (*s != 'N' && *s != 'n') return 0; - s++; if (*s != 'F' && *s != 'f') return 0; - s++; if (*s == 'I' || *s == 'i') { - s++; if (*s != 'N' && *s != 'n') return 0; - s++; if (*s != 'I' && *s != 'i') return 0; - s++; if (*s != 'T' && *s != 't') return 0; - s++; if (*s != 'Y' && *s != 'y') return 0; - s++; - } - sawinf = 1; + s++; if (*s != 'I' && *s != 'i') return 0; + s++; if (*s != 'T' && *s != 't') return 0; + s++; if (*s != 'Y' && *s != 'y') return 0; + s++; } - else /* Add test for NaN here. */ - return 0; + sawinf = 1; } + else /* Add test for NaN here. */ + return 0; if (sawinf) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ |