import qualified Id ( setIdType )
import IdInfo ( GlobalIdDetails(..) )
import Linker ( HValue, extendLinkEnv, withExtendedLinkEnv,initDynLinker )
-import PrelNames ( breakpointJumpName )
+import PrelNames ( breakpointJumpName, breakpointCondJumpName )
#endif
-- The GHC interface
#endif
#else
import GHC.ConsoleHandler ( flushConsole )
+import System.Win32 ( setConsoleCP, setConsoleOutputCP )
#endif
#ifdef USE_READLINE
nest 2 (pprWithCommas showId ids)
where showId id = ppr (idName id) <+> dcolon <+> ppr (idType id)
+jumpCondFunction :: Session -> Int -> [HValue] -> String -> Bool -> b -> b
+jumpCondFunction session ptr hValues location True b = b
+jumpCondFunction session ptr hValues location False b
+ = jumpFunction session ptr hValues location b
+
jumpFunction :: Session -> Int -> [HValue] -> String -> b -> b
jumpFunction session@(Session ref) (I# idsPtr) hValues location b
= unsafePerformIO $
new_ic = ictxt { ic_rn_local_env = new_rn_env,
ic_type_env = new_type_env }
writeIORef ref (hsc_env { hsc_IC = new_ic })
+ is_tty <- hIsTerminalDevice stdin
withExtendedLinkEnv (zip names hValues) $
- startGHCi (runGHCi [] Nothing)
+ startGHCi (interactiveLoop is_tty True)
GHCiState{ progname = "<interactive>",
args = [],
prompt = location++"> ",
interactiveUI session srcs maybe_expr = do
#if defined(GHCI) && defined(BREAKPOINT)
initDynLinker =<< GHC.getSessionDynFlags session
- extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))]
+ extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))
+ ,(breakpointCondJumpName,unsafeCoerce# (jumpCondFunction session))]
#endif
-- HACK! If we happen to get into an infinite loop (eg the user
-- types 'let x=x in x' at the prompt), then the thread will block
case maybe_expr of
Nothing ->
-#if defined(mingw32_HOST_OS)
do
+#if defined(mingw32_HOST_OS)
-- The win32 Console API mutates the first character of
-- type-ahead when reading from it in a non-buffered manner. Work
-- around this by flushing the input buffer of type-ahead characters,
| otherwise -> io (ioError err)
Right () -> return ()
#endif
+ -- initialise the console if necessary
+ io setUpConsole
+
-- enter the interactive loop
interactiveLoop is_tty show_prompt
Just expr -> do
l -> do quit <- runCommand l
if quit then return () else fileLoop hdl show_prompt
-stringLoop :: [String] -> GHCi ()
-stringLoop [] = return ()
+stringLoop :: [String] -> GHCi Bool{-True: we quit-}
+stringLoop [] = return False
stringLoop (s:ss) = do
case removeSpaces s of
"" -> stringLoop ss
l -> do quit <- runCommand l
- if quit then return () else stringLoop ss
+ if quit then return True else stringLoop ss
mkPrompt toplevs exports prompt
= showSDoc $ f prompt
runCommandEval c = ghciHandle handleEval (doCommand c)
where
handleEval (ExitException code) = io (exitWith code)
- handleEval e = do showException e
+ handleEval e = do handler e
io (exitWith (ExitFailure 1))
doCommand (':' : command) = specialCommand command
case maybe_hv of
Nothing -> return ()
Just hv -> io (writeIORef commands --
- (cmds ++ [(macro_name, keepGoing (runMacro hv), False, completeNone)]))
+ (cmds ++ [(macro_name, runMacro hv, False, completeNone)]))
-runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi ()
+runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi Bool
runMacro fun s = do
str <- io ((unsafeCoerce# fun :: String -> IO String) s)
stringLoop (lines str)
setContextAfterLoad session graph'
modulesLoadedMsg ok (map GHC.ms_mod graph')
#if defined(GHCI) && defined(BREAKPOINT)
- io (extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))])
+ io (extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))
+ ,(breakpointCondJumpName,unsafeCoerce# (jumpCondFunction session))])
#endif
setContextAfterLoad session [] = do
foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
-- Make it "safe", just in case
--- -----------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------
-- Utils
expandPath :: String -> GHCi String
return (tilde ++ '/':d)
other ->
return other
+
+-- ----------------------------------------------------------------------------
+-- Windows console setup
+
+setUpConsole :: IO ()
+setUpConsole = do
+#ifdef mingw32_HOST_OS
+ -- On Windows we need to set a known code page, otherwise the characters
+ -- we read from the console will be be in some strange encoding, and
+ -- similarly for characters we write to the console.
+ --
+ -- At the moment, GHCi pretends all input is Latin-1. In the
+ -- future we should support UTF-8, but for now we set the code pages
+ -- to Latin-1.
+ --
+ -- It seems you have to set the font in the console window to
+ -- a Unicode font in order for output to work properly,
+ -- otherwise non-ASCII characters are mapped wrongly. sigh.
+ -- (see MSDN for SetConsoleOutputCP()).
+ --
+ setConsoleCP 28591 -- ISO Latin-1
+ setConsoleOutputCP 28591 -- ISO Latin-1
+#endif
+ return ()