diff options
-rw-r--r-- | intrpvar.h | 4 | ||||
-rw-r--r-- | perl.c | 1 | ||||
-rw-r--r-- | perl.h | 4 | ||||
-rw-r--r-- | sv.c | 15 | ||||
-rw-r--r-- | util.c | 17 |
5 files changed, 28 insertions, 13 deletions
diff --git a/intrpvar.h b/intrpvar.h index 8b2aa29321..8ecd10ffed 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -362,8 +362,8 @@ PERLVARI(Inumeric_standard, bool, TRUE) /* Assume simple numerics */ PERLVARI(Inumeric_local, bool, TRUE) /* Assume local numerics */ -PERLVAR(Inumeric_radix, char) - /* The radix character if not '.' */ +PERLVAR(Inumeric_radix, SV *) + /* The radix separator if not '.' */ #endif /* !USE_LOCALE_NUMERIC */ @@ -562,6 +562,7 @@ perl_destruct(pTHXx) #ifdef USE_LOCALE_NUMERIC Safefree(PL_numeric_name); PL_numeric_name = Nullch; + SvREFCNT_dec(PL_numeric_radix); #endif /* clear utf8 character classes */ @@ -3217,9 +3217,9 @@ typedef struct am_table_short AMTS; #define SET_NUMERIC_LOCAL() \ set_numeric_local(); -#define IS_NUMERIC_RADIX(c) \ +#define IS_NUMERIC_RADIX(s) \ ((PL_hints & HINT_LOCALE) && \ - PL_numeric_radix && (c) == PL_numeric_radix) + PL_numeric_radix && memEQ(s, SvPVX(PL_numeric_radix), SvCUR(PL_numeric_radix))) #define STORE_NUMERIC_LOCAL_SET_STANDARD() \ bool was_local = (PL_hints & HINT_LOCALE) && PL_numeric_local; \ @@ -2448,6 +2448,7 @@ Perl_looks_like_number(pTHX_ SV *sv) I32 numtype = 0; I32 sawinf = 0; STRLEN len; + bool specialradix = FALSE; if (SvPOK(sv)) { sbegin = SvPVX(sv); @@ -2514,10 +2515,13 @@ Perl_looks_like_number(pTHX_ SV *sv) if (*s == '.' #ifdef USE_LOCALE_NUMERIC - || IS_NUMERIC_RADIX(*s) + || (specialradix = IS_NUMERIC_RADIX(s)) #endif ) { - s++; + if (specialradix) + s += SvCUR(PL_numeric_radix); + else + s++; numtype |= IS_NUMBER_NOT_INT; while (isDIGIT(*s)) /* optional digits after the radix */ s++; @@ -2525,10 +2529,13 @@ Perl_looks_like_number(pTHX_ SV *sv) } else if (*s == '.' #ifdef USE_LOCALE_NUMERIC - || IS_NUMERIC_RADIX(*s) + || (specialradix = IS_NUMERIC_RADIX(s)) #endif ) { - s++; + if (specialradix) + s += SvCUR(PL_numeric_radix); + else + s++; numtype |= IS_NUMBER_TO_INT_BY_ATOL | IS_NUMBER_NOT_INT; /* no digits before the radix means we need digits after it */ if (isDIGIT(*s)) { @@ -575,11 +575,18 @@ Perl_set_numeric_radix(pTHX) struct lconv* lc; lc = localeconv(); - if (lc && lc->decimal_point) - /* We assume that decimal separator aka the radix - * character is always a single character. If it - * ever is a string, this needs to be rethunk. */ - PL_numeric_radix = *lc->decimal_point; + if (lc && lc->decimal_point) { + if (lc->decimal_point[0] == '.' && lc->decimal_point[1] == 0) { + SvREFCNT_dec(PL_numeric_radix); + PL_numeric_radix = 0; + } + else { + if (PL_numeric_radix) + sv_setpv(PL_numeric_radix, lc->decimal_point); + else + PL_numeric_radix = newSVpv(lc->decimal_point, 0); + } + } else PL_numeric_radix = 0; # endif /* HAS_LOCALECONV */ |