This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
my_atof(): Lock dot radix
authorKarl Williamson <khw@cpan.org>
Thu, 18 Jan 2018 00:01:00 +0000 (17:01 -0700)
committerKarl Williamson <khw@cpan.org>
Wed, 31 Jan 2018 05:12:46 +0000 (22:12 -0700)
This commit shows some redundant checks.  It examines the text and if it
finds a dot in the middle of the number, and the locale is expecting
something else, it toggles LC_NUMERIC to be the C locale so that the dot
is understood.  However, during further parsing, grok_numeric_radix()
gets called and sees that the locale shouldn't be C, and toggles it
back.  That ordinarily would cause the dot to not be recognized, but
this function always recognizes a dot no matter what the locale.  So
none of our tests fail.  I'm not sure if this is always the case, and I
don't understand this area of the code all that well, but there is a
simple way to cause grok_numeric_radix to not change the locale back,
and that is to call the macro LOCK_LC_NUMERIC_STANDARD() when changing
it the first time in my_atof().  The purpose of this macro is precisely
this situation, so that recursed calls don't try to override the
decisions of the outer calls

numeric.c

index 7065486..50c85a4 100644 (file)
--- a/numeric.c
+++ b/numeric.c
@@ -1242,13 +1242,17 @@ Perl_my_atof(pTHX_ const char* s)
             const bool use_standard_radix
                     = standard_pos && (!local_pos || standard_pos < local_pos);
 
-            if (use_standard_radix)
+            if (use_standard_radix) {
                 SET_NUMERIC_STANDARD();
+                LOCK_LC_NUMERIC_STANDARD();
+            }
 
             Perl_atof2(s, x);
 
-            if (use_standard_radix)
+            if (use_standard_radix) {
+                UNLOCK_LC_NUMERIC_STANDARD();
                 SET_NUMERIC_UNDERLYING();
+            }
         }
         else
             Perl_atof2(s, x);