summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorHugo van der Sanden <hv@crypt.org>2001-06-10 12:23:30 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2001-06-10 10:55:34 +0000
commitf20cc2f4b57d0af6ae56e81a5194c331ceb01e3b (patch)
treeee8a22d9bdb44e073630ea0358bc42b5f93e96fd /sv.c
parent906f284febf43a7190682e42c5aef12275cef5ce (diff)
downloadperl-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.c106
1 files changed, 50 insertions, 56 deletions
diff --git a/sv.c b/sv.c
index 2a843e6a5c..4b86aab5b8 100644
--- a/sv.c
+++ b/sv.c
@@ -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 */