Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4fa8e0c

Browse files
committedAug 9, 2015
Merge pull request #739 from commercialhaskell/738-windows-code-page
Set code page to UTF-8 (65001) on Windows #738
2 parents 3fe10b9 + 21e517b commit 4fa8e0c

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed
 

‎src/Stack/Build/Execute.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,13 @@ withSingleContext ActionContext {..} ExecuteEnv {..} task@Task {..} msuffix inne
602602
cp = cp0
603603
{ cwd = Just $ toFilePath pkgDir
604604
, Process.env = envHelper menv
605-
, std_in = CreatePipe
605+
-- Ideally we'd create a new pipe here and then close it
606+
-- below to avoid the child process from taking from our
607+
-- stdin. However, if we do this, the child process won't
608+
-- be able to get the codepage on Windows that we want.
609+
-- See:
610+
-- https://github.com/commercialhaskell/stack/issues/738
611+
-- , std_in = CreatePipe
606612
, std_out =
607613
case mlogFile of
608614
Nothing -> CreatePipe
@@ -615,8 +621,7 @@ withSingleContext ActionContext {..} ExecuteEnv {..} task@Task {..} msuffix inne
615621
$logProcessRun (toFilePath exeName) fullArgs
616622

617623
-- Use createProcess_ to avoid the log file being closed afterwards
618-
(Just inH, moutH, merrH, ph) <- liftIO $ createProcess_ "singleBuild" cp
619-
liftIO $ hClose inH
624+
(Nothing, moutH, merrH, ph) <- liftIO $ createProcess_ "singleBuild" cp
620625

621626
let makeAbsolute = stripTHLoading -- If users want control, we should add a config option for this
622627

‎src/main/Main.hs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE CPP #-}
12
{-# LANGUAGE OverloadedStrings #-}
23
{-# LANGUAGE ScopedTypeVariables #-}
34
{-# LANGUAGE FlexibleContexts #-}
@@ -73,10 +74,61 @@ import System.FilePath (dropTrailingPathSeparator)
7374
import System.IO (hIsTerminalDevice, stderr, stdin, stdout, hSetBuffering, BufferMode(..))
7475
import System.Process.Read
7576

77+
#if WINDOWS
78+
import System.Win32.Console (setConsoleCP, setConsoleOutputCP, getConsoleCP, getConsoleOutputCP)
79+
import System.IO (hSetEncoding, utf8, hPutStrLn)
80+
#endif
81+
82+
-- | Set the code page for this process as necessary. Only applies to Windows.
83+
-- See: https://github.com/commercialhaskell/stack/issues/738
84+
fixCodePage :: IO a -> IO a
85+
#if WINDOWS
86+
fixCodePage inner = do
87+
origCPI <- getConsoleCP
88+
origCPO <- getConsoleOutputCP
89+
90+
let setInput = origCPI /= expected
91+
setOutput = origCPO /= expected
92+
fixInput
93+
| setInput = bracket_
94+
(do
95+
setConsoleCP expected
96+
hSetEncoding stdin utf8
97+
)
98+
(setConsoleCP origCPI)
99+
| otherwise = id
100+
fixOutput
101+
| setInput = bracket_
102+
(do
103+
setConsoleOutputCP expected
104+
hSetEncoding stdout utf8
105+
hSetEncoding stderr utf8
106+
)
107+
(setConsoleOutputCP origCPO)
108+
| otherwise = id
109+
110+
case (setInput, setOutput) of
111+
(False, False) -> return ()
112+
(True, True) -> warn ""
113+
(True, False) -> warn " input"
114+
(False, True) -> warn " output"
115+
116+
fixInput $ fixOutput inner
117+
where
118+
expected = 65001 -- UTF-8
119+
warn typ = hPutStrLn stderr $ concat
120+
[ "Setting"
121+
, typ
122+
, " codepage to UTF-8 (65001) to ensure correct output from GHC"
123+
]
124+
#else
125+
fixCodePage = id
126+
#endif
127+
76128
-- | Commandline dispatcher.
77129
main :: IO ()
78-
main = withInterpreterArgs stackProgName $ \args isInterpreter ->
79-
do -- Line buffer the output by default, particularly for non-terminal runs.
130+
main = withInterpreterArgs stackProgName $ \args isInterpreter -> fixCodePage $ do
131+
-- Line buffer the output by default, particularly for non-terminal runs.
80132
-- See https://github.com/commercialhaskell/stack/pull/360
81133
hSetBuffering stdout LineBuffering
82134
hSetBuffering stdin LineBuffering

‎stack.cabal

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ executable stack
208208
, transformers
209209
, http-client
210210
default-language: Haskell2010
211+
if os(windows)
212+
build-depends: Win32
213+
cpp-options: -DWINDOWS
211214

212215
test-suite stack-test
213216
type: exitcode-stdio-1.0

0 commit comments

Comments
 (0)
Please sign in to comment.