From: Jarkko Hietaniemi Date: Sat, 9 Jun 2001 15:23:52 +0000 (+0000) Subject: Numeric conversion tweaks suggested by Hugo and Nicholas. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5ca37ce9a896d8d8db4aa0d3ecf10ef4edb561a0;p=p5sagit%2Fp5-mst-13.2.git Numeric conversion tweaks suggested by Hugo and Nicholas. p4raw-id: //depot/perl@10485 --- diff --git a/embed.h b/embed.h index 2e67e36..36f2728 100644 --- a/embed.h +++ b/embed.h @@ -1108,7 +1108,6 @@ #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 @@ -2603,7 +2602,6 @@ #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) @@ -5074,8 +5072,6 @@ #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 diff --git a/embed.pl b/embed.pl index 7831f7e..67e142a 100755 --- 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 --- 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 --- 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 --- 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 --- 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) {