#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
#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();
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++;
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
*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;
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