This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
locale.c: Avoid rescanning a string
authorKarl Williamson <khw@cpan.org>
Tue, 2 Jan 2018 02:07:19 +0000 (19:07 -0700)
committerKarl Williamson <khw@cpan.org>
Wed, 31 Jan 2018 05:27:25 +0000 (22:27 -0700)
We can use a parameter to find out where in the string the portion of
interest starts.  Do that to avoid starting again from scratch.

locale.c

index c0d9463..4279929 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -310,9 +310,10 @@ S_set_numeric_radix(pTHX_ const bool use_locale)
     if (use_locale) {
         const char * radix = my_nl_langinfo(PERL_RADIXCHAR, FALSE);
                                           /* FALSE => already in dest locale */
-
         /* ... and the character being used isn't a dot */
         if (strNE(radix, ".")) {
+            const U8 * first_variant;
+
             if (PL_numeric_radix_sv) {
                 sv_setpv(PL_numeric_radix_sv, radix);
             }
@@ -320,10 +321,17 @@ S_set_numeric_radix(pTHX_ const bool use_locale)
                 PL_numeric_radix_sv = newSVpv(radix, 0);
             }
 
-            if ( !  is_utf8_invariant_string(
-                     (U8 *) SvPVX(PL_numeric_radix_sv), SvCUR(PL_numeric_radix_sv))
-                &&  is_utf8_string(
-                     (U8 *) SvPVX(PL_numeric_radix_sv), SvCUR(PL_numeric_radix_sv))
+            /* If there is a byte variant under UTF-8, and if the remainder of
+             * the string starting there is valid UTF-8, and we are in a UTF-8
+             * locale, then mark the radix as being in UTF-8 */
+            if ( !  is_utf8_invariant_string_loc(
+                                            (U8 *) SvPVX(PL_numeric_radix_sv),
+                                            SvCUR(PL_numeric_radix_sv),
+                                            &first_variant)
+                &&  is_utf8_string(first_variant,
+                                   SvCUR(PL_numeric_radix_sv)
+                                 - ((char *) first_variant
+                                 - SvPVX(PL_numeric_radix_sv)))
                 && _is_cur_LC_category_utf8(LC_NUMERIC))
             {
                 SvUTF8_on(PL_numeric_radix_sv);