Numeric conversion tweaks suggested by Hugo and Nicholas.
Jarkko Hietaniemi [Sat, 9 Jun 2001 15:23:52 +0000 (15:23 +0000)]
p4raw-id: //depot/perl@10485

embed.h
embed.pl
perl.h
proto.h
sv.c
util.c

diff --git a/embed.h b/embed.h
index 2e67e36..36f2728 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define del_sv                 S_del_sv
 #  endif
 #  if !defined(NV_PRESERVES_UV)
-#define sv_2inuv_non_preserve  S_sv_2inuv_non_preserve
 #define sv_2iuv_non_preserve   S_sv_2iuv_non_preserve
 #  endif
 #define expect_number          S_expect_number
 #define del_sv(a)              S_del_sv(aTHX_ a)
 #  endif
 #  if !defined(NV_PRESERVES_UV)
-#define sv_2inuv_non_preserve(a,b)     S_sv_2inuv_non_preserve(aTHX_ a,b)
 #define sv_2iuv_non_preserve(a,b)      S_sv_2iuv_non_preserve(aTHX_ a,b)
 #  endif
 #define expect_number(a)       S_expect_number(aTHX_ a)
 #define del_sv                 S_del_sv
 #  endif
 #  if !defined(NV_PRESERVES_UV)
-#define S_sv_2inuv_non_preserve        CPerlObj::S_sv_2inuv_non_preserve
-#define sv_2inuv_non_preserve  S_sv_2inuv_non_preserve
 #define S_sv_2iuv_non_preserve CPerlObj::S_sv_2iuv_non_preserve
 #define sv_2iuv_non_preserve   S_sv_2iuv_non_preserve
 #  endif
index 7831f7e..67e142a 100755 (executable)
--- a/embed.pl
+++ b/embed.pl
@@ -2514,7 +2514,6 @@ s |void   |sv_del_backref |SV *sv
 s      |void   |del_sv |SV *p
 #  endif
 #  if !defined(NV_PRESERVES_UV)
-s      |int    |sv_2inuv_non_preserve  |SV *sv|I32 numtype
 s      |int    |sv_2iuv_non_preserve   |SV *sv|I32 numtype
 #  endif
 s      |I32    |expect_number  |char** pattern
diff --git a/perl.h b/perl.h
index 08f00f1..4ceefc4 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -3450,12 +3450,6 @@ typedef struct am_table_short AMTS;
 #define IN_LOCALE \
        (PL_curcop == &PL_compiling ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME)
 
-#define IS_NUMERIC_RADIX(s, send)      \
-       (PL_numeric_radix_sv \
-        && IN_LOCALE \
-        && SvCUR(PL_numeric_radix_sv) <= ((send)-(s)) \
-        && memEQ(s, SvPVX(PL_numeric_radix_sv), SvCUR(PL_numeric_radix_sv)))
-
 #define STORE_NUMERIC_LOCAL_SET_STANDARD() \
        bool was_local = PL_numeric_local && IN_LOCALE; \
        if (was_local) SET_NUMERIC_STANDARD();
diff --git a/proto.h b/proto.h
index dc4be43..5005708 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -1238,7 +1238,6 @@ STATIC void       S_sv_del_backref(pTHX_ SV *sv);
 STATIC void    S_del_sv(pTHX_ SV *p);
 #  endif
 #  if !defined(NV_PRESERVES_UV)
-STATIC int     S_sv_2inuv_non_preserve(pTHX_ SV *sv, I32 numtype);
 STATIC int     S_sv_2iuv_non_preserve(pTHX_ SV *sv, I32 numtype);
 #  endif
 STATIC I32     S_expect_number(pTHX_ char** pattern);
diff --git a/sv.c b/sv.c
index fe6d11e..f39f305 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1503,9 +1503,9 @@ 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;
-#ifdef USE_LOCALE_NUMERIC
-    bool specialradix = FALSE;
-#endif
+    char* radix = ".";
+    STRLEN radixlen = 1;
+         
 
     while (isSPACE(*s))
        s++;
@@ -1516,6 +1516,11 @@ 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
@@ -1584,48 +1589,29 @@ S_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep)
            *valuep = value;
 
       skip_value:
-        if (
-#ifdef USE_LOCALE_NUMERIC
-            (specialradix = IS_NUMERIC_RADIX(s, send)) ||
-#endif
-           *s == '.') {
-#ifdef USE_LOCALE_NUMERIC
-            if (specialradix)
-                s += SvCUR(PL_numeric_radix_sv);
-            else
-#endif
-                s++;
+       if (s + radixlen <= send && memEQ(s, radix, radixlen)) {
+           s += radixlen;
            numtype |= IS_NUMBER_NOT_INT;
-            while (isDIGIT(*s))  /* optional digits after the radix */
-                s++;
-        }
-    }
-    else if (
-#ifdef USE_LOCALE_NUMERIC
-        (specialradix = IS_NUMERIC_RADIX(s, send)) ||
-#endif
-        *s == '.'
-        ) {
-#ifdef USE_LOCALE_NUMERIC
-       if (specialradix)
-           s += SvCUR(PL_numeric_radix_sv);
-       else
-#endif
-            s++;
-       numtype |= IS_NUMBER_NOT_INT;
-        /* no digits before the radix means we need digits after it */
-        if (isDIGIT(*s)) {
-           do {
+           while (isDIGIT(*s))  /* optional digits after the radix */
                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 + 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;
@@ -2459,9 +2445,8 @@ Perl_sv_2nv(pTHX_ register SV *sv)
     if (SvNOKp(sv) && !(SvIOK(sv) || SvPOK(sv))) {
        SvNOK_on(sv);
     }
-    else     if (SvIOKp(sv) &&
-           (!SvPOKp(sv) || !strchr(SvPVX(sv),'.') || /* XXX check this logic */
-            !grok_number(SvPVX(sv), SvCUR(sv),NULL)))
+    else if (SvIOKp(sv) &&
+            (!SvPOKp(sv) || !grok_number(SvPVX(sv), SvCUR(sv),NULL)))
     {
        SvNVX(sv) = SvIsUV(sv) ? (NV)SvUVX(sv) : (NV)SvIVX(sv);
 #ifdef NV_PRESERVES_UV
diff --git a/util.c b/util.c
index e034c33..9cf667f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -4082,8 +4082,10 @@ Perl_my_atof2(pTHX_ const char* orig, NV* value)
     I32 ipart = 0;     /* index into part[] */
     I32 offcount;      /* number of digits in least significant part */
 
+#ifdef USE_LOCALE_NUMERIC
     if (PL_numeric_radix_sv)
        point = SvPV(PL_numeric_radix_sv, pointlen);
+#endif
 
     /* sign */
     switch (*s) {