summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2001-06-09 23:37:36 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2001-06-10 03:00:17 +0000
commit906f284febf43a7190682e42c5aef12275cef5ce (patch)
treee6ea1208fb92005aca81064eb92cc4f14efdbc4f /sv.c
parentb00ec89b8b3e208d96fee2dc79a984083fc0a295 (diff)
downloadperl-906f284febf43a7190682e42c5aef12275cef5ce.tar.gz
Try to grok numbers both with the locale specific separator
and with the usual "." (if different from the lss); add a test to locale.t to do also a little bit of math in addition to just equalness testing; remove extraneous logic as suggested in Subject: Re: pragma/locale.t #107 Message-ID: <20010609223735.Y76396@plum.flirble.org> p4raw-id: //depot/perl@10494
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c86
1 files changed, 52 insertions, 34 deletions
diff --git a/sv.c b/sv.c
index aeb471d1ae..2a843e6a5c 100644
--- a/sv.c
+++ b/sv.c
@@ -1505,7 +1505,7 @@ S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep)
int sawinf = 0;
char* radix = ".";
STRLEN radixlen = 1;
-
+ bool radixfound;
while (isSPACE(*s))
s++;
@@ -1589,44 +1589,64 @@ S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep)
*valuep = value;
skip_value:
- if (s + radixlen <= send && memEQ(s, radix, radixlen)) {
+ 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;
numtype |= IS_NUMBER_NOT_INT;
while (isDIGIT(*s)) /* optional digits after the radix */
s++;
}
}
- else if (s + radixlen <= send && memEQ(s, radix, radixlen)) {
- 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
- return 0;
- }
- 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') {
+ 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;
+ }
+#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
+ return 0;
+ }
+ else 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++;
+ 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;
}
- sawinf = 1;
+ else /* Add test for NaN here. */
+ return 0;
}
- else /* Add test for NaN here. */
- return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
@@ -2423,7 +2443,7 @@ Perl_sv_2nv(pTHX_ register SV *sv)
sv_upgrade(sv, SVt_PVNV);
else
sv_upgrade(sv, SVt_NV);
-#if defined(USE_LONG_DOUBLE)
+#ifdef USE_LONG_DOUBLE
DEBUG_c({
STORE_NUMERIC_LOCAL_SET_STANDARD();
PerlIO_printf(Perl_debug_log,
@@ -2445,9 +2465,7 @@ Perl_sv_2nv(pTHX_ register SV *sv)
if (SvNOKp(sv) && !(SvIOK(sv) || SvPOK(sv))) {
SvNOK_on(sv);
}
- else if (SvIOKp(sv) &&
- (!SvPOKp(sv) || !grok_number(SvPVX(sv), SvCUR(sv),NULL)))
- {
+ else if (SvIOKp(sv)) {
SvNVX(sv) = SvIsUV(sv) ? (NV)SvUVX(sv) : (NV)SvIVX(sv);
#ifdef NV_PRESERVES_UV
SvNOK_on(sv);