This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Revert "PATCH: [perl #119499] "$!" with UTF-8 flag"
authorKarl Williamson <khw@cpan.org>
Wed, 4 Jun 2014 00:39:40 +0000 (18:39 -0600)
committerKarl Williamson <khw@cpan.org>
Thu, 5 Jun 2014 18:23:02 +0000 (12:23 -0600)
This reverts commit b17e32ea3ba5ef7362d2a3d1a433661afb897786.

With this commit, the stringification of $! will have the UTF-8 flag set
when the text is actually non-ASCII UTF-8.  The reverted commit itself
reverted code that was to fix bugs with this discrepancy of the UTF-8
flag, but which caused backward-compatibility problems with existing
code.

Several things have happened in the interim which allows us to
experimentally resotre the previously reverted changes.  One is that
this is early in the 5.21 cycle, and we have plenty of time to see what
negative consequences this may cause.  Two is that the returned text
will only be in UTF-8 if the stringification happens within the scope of
'use locale'.  This means that the negative effects won't happen for
code, like ack, that is otherwise locale unaware.  Third, the 'locale'
pragma has been enhanced to allow the program to only have locale
awareness of LC_MESSAGES.

Code that needs to continue the 5.20 and earlier behavior can do the
stringification within the scopes of both 'use bytes' and 'use locale
":messages".  No other Perl operations will be affected by locale; only
$! and $^E stringification.  The 'bytes' pragma causes the UTF-8 flag to
not be set, just as in previous Perl releases.

lib/locale.t
mg.c
pod/perldelta.pod
pod/perlvar.pod

index f045735..38b0d09 100644 (file)
@@ -1783,8 +1783,8 @@ foreach my $Locale (@Locale) {
             $ok13 = $w == 0;
 
             # Look for non-ASCII error messages, and verify that the first
-            # such is NOT in UTF-8 (the others almost certainly will be like
-            # the first)  See [perl #119499].
+            # such is in UTF-8 (the others almost certainly will be like the
+            # first).
             $ok14 = 1;
             $ok14_5 = 1;
             foreach my $err (keys %!) {
@@ -1792,7 +1792,7 @@ foreach my $Locale (@Locale) {
                 $! = eval "&Errno::$err";   # Convert to strerror() output
                 my $strerror = "$!";
                 if ("$strerror" =~ /\P{ASCII}/) {
-                    $ok14 = utf8::is_utf8($strerror);
+                    $ok14 = utf8::is_utf8($strerror);
                     no locale;
                     $ok14_5 = "$!" !~ /\P{ASCII}/;
                     last;
@@ -1876,7 +1876,7 @@ foreach my $Locale (@Locale) {
     $problematical_tests{$locales_test_number} = 1;
 
     report_result($Locale, ++$locales_test_number, $ok14);
-    $test_names{$locales_test_number} = 'Verify that non-ASCII UTF-8 error messages are NOT in UTF-8';
+    $test_names{$locales_test_number} = 'Verify that non-ASCII UTF-8 error messages are in UTF-8';
 
     report_result($Locale, ++$locales_test_number, $ok14_5);
     $test_names{$locales_test_number} = '... and are ASCII outside "use locale"';
diff --git a/mg.c b/mg.c
index 80f5a7b..e62e9e6 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -753,24 +753,19 @@ S_fixup_errno_string(pTHX_ SV* sv)
     if(strEQ(SvPVX(sv), "")) {
        sv_catpv(sv, UNKNOWN_ERRNO_MSG);
     }
-#if 0
-    /* This is disabled to get v5.20 out the door.  It means that $! behaves as
-     * if in the scope of both 'use locale' and 'use bytes'.  This can cause
-     * mixed encodings and double utf8 upgrading,  See towards the end of the
-     * thread for [perl #119499] */
     else {
 
         /* In some locales the error string may come back as UTF-8, in which
          * case we should turn on that flag.  This didn't use to happen, and to
-         * avoid any possible backward compatibility issues, we don't turn on
-         * the flag unless we have to.  So the flag stays off for an entirely
-         * ASCII string.  We assume that if the string looks like UTF-8, it
-         * really is UTF-8:  "text in any other encoding that uses bytes with
-         * the high bit set is extremely unlikely to pass a UTF-8 validity
-         * test" (http://en.wikipedia.org/wiki/Charset_detection).  There is a
-         * potential that we will get it wrong however, especially on short
-         * error message text.  (If it turns out to be necessary, we could also
-         * keep track if the current LC_MESSAGES locale is UTF-8) */
+         * avoid as many possible backward compatibility issues as possible, we
+         * don't turn on the flag unless we have to.  So the flag stays off for
+         * an entirely ASCII string.  We assume that if the string looks like
+         * UTF-8, it really is UTF-8:  "text in any other encoding that uses
+         * bytes with the high bit set is extremely unlikely to pass a UTF-8
+         * validity test" (http://en.wikipedia.org/wiki/Charset_detection).
+         * There is a potential that we will get it wrong however, especially
+         * on short error message text.  (If it turns out to be necessary, we
+         * could also keep track if the current LC_MESSAGES locale is UTF-8) */
         if (! IN_BYTES  /* respect 'use bytes' */
             && ! is_ascii_string((U8*) SvPVX_const(sv), SvCUR(sv))
             && is_utf8_string((U8*) SvPVX_const(sv), SvCUR(sv)))
@@ -778,7 +773,6 @@ S_fixup_errno_string(pTHX_ SV* sv)
             SvUTF8_on(sv);
         }
     }
-#endif
 }
 
 #ifdef VMS
index 5da8218..d4278b3 100644 (file)
@@ -105,6 +105,18 @@ handle locale, this can cause garbage text to be displayed.  It's better
 to display text that is translatable via some tool than garbage text
 which is much harder to figure out.
 
+=head2 C<"$!"> text will be returned in UTF-8 when appropriate
+
+The stringification of C<$!> and C<$^E> will have the UTF-8 flag set
+when the text is actually non-ASCII UTF-8.  This will enable programs
+that are set up to be locale-aware to properly output messages in the
+user's native language.  Code that needs to continue the 5.20 and
+earlier behavior can do the stringification within the scopes of both
+'use bytes' and 'use locale ":messages".  No other Perl operations will
+be affected by locale; only C<$!> and C<$^E> stringification.  The
+'bytes' pragma causes the UTF-8 flag to not be set, just as in previous
+Perl releases.  This resolves [perl #112208].
+
 =head1 Deprecations
 
 XXX Any deprecated features, syntax, modules etc. should be listed here.
index 4b6bb74..cd917af 100644 (file)
@@ -1765,10 +1765,6 @@ It can be used immediately before invoking the C<die()> operator,
 to set the exit value, or to inspect the system error string
 corresponding to error I<n>, or to restore C<$!> to a meaningful state.
 
-Note that when stringified, the text is always returned as if both
-S<L<C<"use locale">|perllocale>> and S<L<C<"use bytes">|bytes>> are in
-effect.  This is likely to change in v5.22.
-
 Mnemonic: What just went bang?
 
 =item %OS_ERROR