Transliterate unknown characters at output
authorMichael Snoyman <michael@snoyman.com>
Tue, 18 Aug 2015 15:58:02 +0000 (17:58 +0200)
committerBen Gamari <bgamari.foss@gmail.com>
Tue, 18 Aug 2015 16:32:28 +0000 (12:32 -0400)
This avoids the compiler from crashing when, for example, a warning
contains a non-Latin identifier and the LANG variable is set to C.
Fixes #6037.

Test Plan:
Create a Haskell source file containing an identifier with non-Latin
characters and no type signature. Compile with `LANG=C ghc -Wall
foo.hs`, and it should fail. With this patch, it will succeed.

Reviewers: austin, rwbarton, bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1153

GHC Trac Issues: #6037, #10762

compiler/utils/Util.hs
ghc/Main.hs
testsuite/tests/driver/all.T

index 96cd752..96e911e 100644 (file)
@@ -83,6 +83,7 @@ module Util (
         doesDirNameExist,
         getModificationUTCTime,
         modificationTimeIfExists,
+        hSetTranslit,
 
         global, consIORef, globalM,
 
@@ -122,6 +123,8 @@ import Control.Applicative (Applicative)
 #endif
 import Control.Applicative ( liftA2 )
 import Control.Monad    ( liftM )
+import GHC.IO.Encoding (mkTextEncoding, textEncodingName)
+import System.IO (Handle, hGetEncoding, hSetEncoding)
 import System.IO.Error as IO ( isDoesNotExistError )
 import System.Directory ( doesDirectoryExist, getModificationTime )
 import System.FilePath
@@ -978,6 +981,19 @@ modificationTimeIfExists f = do
                         then return Nothing
                         else ioError e
 
+-- --------------------------------------------------------------
+-- Change the character encoding of the given Handle to transliterate
+-- on unsupported characters instead of throwing an exception
+
+hSetTranslit :: Handle -> IO ()
+hSetTranslit h = do
+    menc <- hGetEncoding h
+    case fmap textEncodingName menc of
+        Just name | '/' `notElem` name -> do
+            enc' <- mkTextEncoding $ name ++ "//TRANSLIT"
+            hSetEncoding h enc'
+        _ -> return ()
+
 -- split a string at the last character where 'pred' is True,
 -- returning a pair of strings. The first component holds the string
 -- up (but not including) the last character for which 'pred' returned
index 201ee5d..ed2ac67 100644 (file)
@@ -80,6 +80,9 @@ main = do
    initGCStatistics -- See Note [-Bsymbolic and hooks]
    hSetBuffering stdout LineBuffering
    hSetBuffering stderr LineBuffering
+   hSetTranslit stdout
+   hSetTranslit stderr
+
    GHC.defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
     -- 1. extract the -B flag from the args
     argv0 <- getArgs
index b79f166..a11c0f1 100644 (file)
@@ -382,7 +382,7 @@ test('T7060',
 test('T7130', normal, compile_fail, ['-fflul-laziness'])
 test('T7563', when(unregisterised(), skip), run_command,
      ['$MAKE -s --no-print-directory T7563'])
-test('T6037', expect_broken(6037), run_command,
+test('T6037', normal, run_command,
      ['$MAKE -s --no-print-directory T6037'])
 test('T2507',
      # The testsuite doesn't know how to set a non-Unicode locale on Windows or Mac OS X