1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
4 -- GHC Interactive User Interface
6 -- (c) The GHC Team 2005-2006
8 -----------------------------------------------------------------------------
14 #include "HsVersions.h"
20 import GHC ( Session, LoadHowMuch(..), Target(..), TargetId(..),
21 Type, Module, ModuleName, TyThing(..), Phase )
34 -- Other random utilities
36 import BasicTypes hiding (isTopLevel)
37 import Panic hiding (showException)
45 import Debugger hiding ( addModule )
48 import Var ( globaliseId )
56 #ifndef mingw32_HOST_OS
58 #if __GLASGOW_HASKELL__ > 504
62 import GHC.ConsoleHandler ( flushConsole )
63 import System.Win32 ( setConsoleCP, setConsoleOutputCP )
64 import qualified System.Win32
68 import Control.Concurrent ( yield ) -- Used in readline loop
69 import System.Console.Readline as Readline
74 import Control.Exception as Exception
75 -- import Control.Concurrent
79 import Data.Int ( Int64 )
80 import Data.Maybe ( isJust, isNothing, fromMaybe, catMaybes )
82 import System.Environment
83 import System.Exit ( exitWith, ExitCode(..) )
84 import System.Directory
86 import System.IO.Error as IO
89 import Control.Monad as Monad
90 import Foreign.StablePtr ( newStablePtr )
92 import GHC.Exts ( unsafeCoerce# )
93 import GHC.IOBase ( IOErrorType(InvalidArgument) )
95 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
97 import System.Posix.Internals ( setNonBlockingFD )
99 -----------------------------------------------------------------------------
103 " / _ \\ /\\ /\\/ __(_)\n"++
104 " / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n"++
105 "/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n"++
106 "\\____/\\/ /_/\\____/|_| Type :? for help.\n"
108 type Command = (String, String -> GHCi Bool, Bool, String -> IO [String])
109 cmdName (n,_,_,_) = n
111 GLOBAL_VAR(commands, builtin_commands, [Command])
113 builtin_commands :: [Command]
115 ("add", tlC$ keepGoingPaths addModule, False, completeFilename),
116 ("browse", keepGoing browseCmd, False, completeModule),
117 ("cd", keepGoing changeDirectory, False, completeFilename),
118 ("def", keepGoing defineMacro, False, completeIdentifier),
119 ("e", keepGoing editFile, False, completeFilename),
120 -- Hugs users are accustomed to :e, so make sure it doesn't overlap
121 ("edit", keepGoing editFile, False, completeFilename),
122 ("help", keepGoing help, False, completeNone),
123 ("?", keepGoing help, False, completeNone),
124 ("info", keepGoing info, False, completeIdentifier),
125 ("load", tlC$ keepGoingPaths loadModule_,False, completeHomeModuleOrFile),
126 ("module", keepGoing setContext, False, completeModule),
127 ("main", tlC$ keepGoing runMain, False, completeIdentifier),
128 ("reload", tlC$ keepGoing reloadModule, False, completeNone),
129 ("check", keepGoing checkModule, False, completeHomeModule),
130 ("set", keepGoing setCmd, True, completeSetOptions),
131 ("show", keepGoing showCmd, False, completeNone),
132 ("etags", keepGoing createETagsFileCmd, False, completeFilename),
133 ("ctags", keepGoing createCTagsFileCmd, False, completeFilename),
134 ("type", keepGoing typeOfExpr, False, completeIdentifier),
135 #if defined(DEBUGGER)
136 ("print", keepGoing (pprintClosureCommand True False), False, completeIdentifier),
137 ("sprint", keepGoing (pprintClosureCommand False False),False, completeIdentifier),
138 ("force", keepGoing (pprintClosureCommand False True), False, completeIdentifier),
139 ("breakpoint",keepGoing bkptOptions, False, completeBkpt),
141 ("kind", keepGoing kindOfType, False, completeIdentifier),
142 ("unset", keepGoing unsetOptions, True, completeSetOptions),
143 ("undef", keepGoing undefineMacro, False, completeMacro),
144 ("quit", quit, False, completeNone)
147 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
148 keepGoing a str = a str >> return False
150 -- tlC: Top Level Command
151 tlC :: (String -> GHCi Bool) -> (String -> GHCi Bool)
153 top_level <- isTopLevel
155 then throwDyn (CmdLineError "Command only allowed at Top Level")
158 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
159 keepGoingPaths a str = a (toArgs str) >> return False
161 shortHelpText = "use :? for help.\n"
163 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
165 " Commands available from the prompt:\n" ++
167 " <stmt> evaluate/run <stmt>\n" ++
168 " :add <filename> ... add module(s) to the current target set\n" ++
169 " :breakpoint <option> commands for the GHCi debugger\n" ++
170 " :browse [*]<module> display the names defined by <module>\n" ++
171 " :cd <dir> change directory to <dir>\n" ++
172 " :def <cmd> <expr> define a command :<cmd>\n" ++
173 " :edit <file> edit file\n" ++
174 " :edit edit last module\n" ++
175 " :help, :? display this list of commands\n" ++
176 " :info [<name> ...] display information about the given names\n" ++
177 " :print [<name> ...] prints a value without forcing its computation\n" ++
178 " :sprint [<name> ...] prints a value without forcing its computation(simpler)\n" ++
179 " :load <filename> ... load module(s) and their dependents\n" ++
180 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
181 " :main [<arguments> ...] run the main function with the given arguments\n" ++
182 " :reload reload the current module set\n" ++
184 " :set <option> ... set options\n" ++
185 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
186 " :set prog <progname> set the value returned by System.getProgName\n" ++
187 " :set prompt <prompt> set the prompt used in GHCi\n" ++
188 " :set editor <cmd> set the command used for :edit\n" ++
190 " :show modules show the currently loaded modules\n" ++
191 " :show bindings show the current bindings made at the prompt\n" ++
193 " :ctags [<file>] create tags file for Vi (default: \"tags\")\n" ++
194 " :etags [<file>] create tags file for Emacs (default: \"TAGS\")\n" ++
195 " :type <expr> show the type of <expr>\n" ++
196 " :kind <type> show the kind of <type>\n" ++
197 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
198 " :unset <option> ... unset options\n" ++
199 " :quit exit GHCi\n" ++
200 " :!<command> run the shell command <command>\n" ++
202 " Options for ':set' and ':unset':\n" ++
204 " +r revert top-level expressions after each evaluation\n" ++
205 " +s print timing/memory stats after each evaluation\n" ++
206 " +t print type after evaluation\n" ++
207 " -<flags> most GHC command line flags can also be set here\n" ++
208 " (eg. -v2, -fglasgow-exts, etc.)\n" ++
210 " Options for ':breakpoint':\n" ++
211 " list list the current breakpoints\n" ++
212 " add Module line [col] add a new breakpoint\n" ++
213 " del (breakpoint# | Module line [col]) delete a breakpoint\n" ++
214 " stop Stop a computation and return to the top level\n" ++
215 " step [count] Step by step execution (DISABLED)\n"
221 win <- System.Win32.getWindowsDirectory
222 return (win `joinFileName` "notepad.exe")
227 interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
228 interactiveUI session srcs maybe_expr = do
229 -- HACK! If we happen to get into an infinite loop (eg the user
230 -- types 'let x=x in x' at the prompt), then the thread will block
231 -- on a blackhole, and become unreachable during GC. The GC will
232 -- detect that it is unreachable and send it the NonTermination
233 -- exception. However, since the thread is unreachable, everything
234 -- it refers to might be finalized, including the standard Handles.
235 -- This sounds like a bug, but we don't have a good solution right
241 -- Initialise buffering for the *interpreted* I/O system
242 initInterpBuffering session
244 when (isNothing maybe_expr) $ do
245 -- Only for GHCi (not runghc and ghc -e):
246 -- Turn buffering off for the compiled program's stdout/stderr
248 -- Turn buffering off for GHCi's stdout
250 hSetBuffering stdout NoBuffering
251 -- We don't want the cmd line to buffer any input that might be
252 -- intended for the program, so unbuffer stdin.
253 hSetBuffering stdin NoBuffering
255 -- initial context is just the Prelude
256 prel_mod <- GHC.findModule session prel_name Nothing
257 GHC.setContext session [] [prel_mod]
261 Readline.setAttemptedCompletionFunction (Just completeWord)
262 --Readline.parseAndBind "set show-all-if-ambiguous 1"
264 let symbols = "!#$%&*+/<=>?@\\^|-~"
265 specials = "(),;[]`{}"
267 word_break_chars = spaces ++ specials ++ symbols
269 Readline.setBasicWordBreakCharacters word_break_chars
270 Readline.setCompleterWordBreakCharacters word_break_chars
273 bkptTable <- newIORef emptyBkptTable
274 GHC.setBreakpointHandler session (instrumentationBkptHandler bkptTable)
275 default_editor <- findEditor
277 startGHCi (runGHCi srcs maybe_expr)
278 GHCiState{ progname = "<interactive>",
281 editor = default_editor,
285 bkptTable = bkptTable,
290 Readline.resetTerminal Nothing
295 prel_name = GHC.mkModuleName "Prelude"
297 runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi ()
298 runGHCi paths maybe_expr = do
299 let read_dot_files = not opt_IgnoreDotGhci
301 when (read_dot_files) $ do
304 exists <- io (doesFileExist file)
306 dir_ok <- io (checkPerms ".")
307 file_ok <- io (checkPerms file)
308 when (dir_ok && file_ok) $ do
309 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
312 Right hdl -> fileLoop hdl False
314 when (read_dot_files) $ do
315 -- Read in $HOME/.ghci
316 either_dir <- io (IO.try (getEnv "HOME"))
320 cwd <- io (getCurrentDirectory)
321 when (dir /= cwd) $ do
322 let file = dir ++ "/.ghci"
323 ok <- io (checkPerms file)
325 either_hdl <- io (IO.try (openFile file ReadMode))
328 Right hdl -> fileLoop hdl False
330 -- Perform a :load for files given on the GHCi command line
331 -- When in -e mode, if the load fails then we want to stop
332 -- immediately rather than going on to evaluate the expression.
333 when (not (null paths)) $ do
334 ok <- ghciHandle (\e -> do showException e; return Failed) $
336 when (isJust maybe_expr && failed ok) $
337 io (exitWith (ExitFailure 1))
339 -- if verbosity is greater than 0, or we are connected to a
340 -- terminal, display the prompt in the interactive loop.
341 is_tty <- io (hIsTerminalDevice stdin)
342 dflags <- getDynFlags
343 let show_prompt = verbosity dflags > 0 || is_tty
348 #if defined(mingw32_HOST_OS)
349 -- The win32 Console API mutates the first character of
350 -- type-ahead when reading from it in a non-buffered manner. Work
351 -- around this by flushing the input buffer of type-ahead characters,
352 -- but only if stdin is available.
353 flushed <- io (IO.try (GHC.ConsoleHandler.flushConsole stdin))
355 Left err | isDoesNotExistError err -> return ()
356 | otherwise -> io (ioError err)
357 Right () -> return ()
359 -- initialise the console if necessary
362 -- enter the interactive loop
363 interactiveLoop is_tty show_prompt
365 -- just evaluate the expression we were given
370 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
373 interactiveLoop is_tty show_prompt =
374 -- Ignore ^C exceptions caught here
375 ghciHandleDyn (\e -> case e of
377 #if defined(mingw32_HOST_OS)
380 interactiveLoop is_tty show_prompt
381 _other -> return ()) $
383 ghciUnblock $ do -- unblock necessary if we recursed from the
384 -- exception handler above.
386 -- read commands from stdin
390 else fileLoop stdin show_prompt
392 fileLoop stdin show_prompt
396 -- NOTE: We only read .ghci files if they are owned by the current user,
397 -- and aren't world writable. Otherwise, we could be accidentally
398 -- running code planted by a malicious third party.
400 -- Furthermore, We only read ./.ghci if . is owned by the current user
401 -- and isn't writable by anyone else. I think this is sufficient: we
402 -- don't need to check .. and ../.. etc. because "." always refers to
403 -- the same directory while a process is running.
405 checkPerms :: String -> IO Bool
407 #ifdef mingw32_HOST_OS
410 Util.handle (\_ -> return False) $ do
411 st <- getFileStatus name
413 if fileOwner st /= me then do
414 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
417 let mode = fileMode st
418 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
419 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
421 putStrLn $ "*** WARNING: " ++ name ++
422 " is writable by someone else, IGNORING!"
427 fileLoop :: Handle -> Bool -> GHCi ()
428 fileLoop hdl show_prompt = do
429 session <- getSession
430 (mod,imports) <- io (GHC.getContext session)
432 when show_prompt (io (putStr (mkPrompt mod imports (prompt st))))
433 l <- io (IO.try (hGetLine hdl))
435 Left e | isEOFError e -> return ()
436 | InvalidArgument <- etype -> return ()
437 | otherwise -> io (ioError e)
438 where etype = ioeGetErrorType e
439 -- treat InvalidArgument in the same way as EOF:
440 -- this can happen if the user closed stdin, or
441 -- perhaps did getContents which closes stdin at
444 case removeSpaces l of
445 "" -> fileLoop hdl show_prompt
446 l -> do quit <- runCommand l
447 if quit then return () else fileLoop hdl show_prompt
449 stringLoop :: [String] -> GHCi Bool{-True: we quit-}
450 stringLoop [] = return False
451 stringLoop (s:ss) = do
452 case removeSpaces s of
454 l -> do quit <- runCommand l
455 if quit then return True else stringLoop ss
457 mkPrompt toplevs exports prompt
458 = showSDoc $ f prompt
460 f ('%':'s':xs) = perc_s <> f xs
461 f ('%':'%':xs) = char '%' <> f xs
462 f (x:xs) = char x <> f xs
465 perc_s = hsep (map (\m -> char '*' <> ppr (GHC.moduleName m)) toplevs) <+>
466 hsep (map (ppr . GHC.moduleName) exports)
470 readlineLoop :: GHCi ()
472 session <- getSession
473 (mod,imports) <- io (GHC.getContext session)
475 saveSession -- for use by completion
477 l <- io (readline (mkPrompt mod imports (prompt st))
478 `finally` setNonBlockingFD 0)
479 -- readline sometimes puts stdin into blocking mode,
480 -- so we need to put it back for the IO library
485 case removeSpaces l of
490 if quit then return () else readlineLoop
493 runCommand :: String -> GHCi Bool
494 runCommand c = ghciHandle handler (doCommand c)
496 doCommand (':' : command) = specialCommand command
498 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
501 -- This version is for the GHC command-line option -e. The only difference
502 -- from runCommand is that it catches the ExitException exception and
503 -- exits, rather than printing out the exception.
504 runCommandEval c = ghciHandle handleEval (doCommand c)
506 handleEval (ExitException code) = io (exitWith code)
507 handleEval e = do handler e
508 io (exitWith (ExitFailure 1))
510 doCommand (':' : command) = specialCommand command
512 = do nms <- runStmt stmt
514 Nothing -> io (exitWith (ExitFailure 1))
515 -- failure to run the command causes exit(1) for ghc -e.
516 _ -> finishEvalExpr nms
518 runStmt :: String -> GHCi (Maybe [Name])
520 | null (filter (not.isSpace) stmt) = return (Just [])
522 = do st <- getGHCiState
523 session <- getSession
524 result <- io $ withProgName (progname st) $ withArgs (args st) $
525 GHC.runStmt session stmt
527 GHC.RunFailed -> return Nothing
528 GHC.RunException e -> throw e -- this is caught by runCommand(Eval)
529 GHC.RunOk names -> return (Just names)
531 -- possibly print the type and revert CAFs after evaluating an expression
532 finishEvalExpr mb_names
533 = do b <- isOptionSet ShowType
534 session <- getSession
537 Just names -> when b (mapM_ (showTypeOfName session) names)
540 io installSignalHandlers
541 b <- isOptionSet RevertCAFs
542 io (when b revertCAFs)
545 showTypeOfName :: Session -> Name -> GHCi ()
546 showTypeOfName session n
547 = do maybe_tything <- io (GHC.lookupName session n)
548 case maybe_tything of
550 Just thing -> showTyThing thing
552 specialCommand :: String -> GHCi Bool
553 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
554 specialCommand str = do
555 let (cmd,rest) = break isSpace str
556 maybe_cmd <- io (lookupCommand cmd)
558 Nothing -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
559 ++ shortHelpText) >> return False)
560 Just (_,f,_,_) -> f (dropWhile isSpace rest)
562 lookupCommand :: String -> IO (Maybe Command)
563 lookupCommand str = do
564 cmds <- readIORef commands
565 -- look for exact match first, then the first prefix match
566 case [ c | c <- cmds, str == cmdName c ] of
567 c:_ -> return (Just c)
568 [] -> case [ c | c@(s,_,_,_) <- cmds, prefixMatch str s ] of
570 c:_ -> return (Just c)
572 -----------------------------------------------------------------------------
575 help :: String -> GHCi ()
576 help _ = io (putStr helpText)
578 info :: String -> GHCi ()
579 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
580 info s = do { let names = words s
581 ; session <- getSession
582 ; dflags <- getDynFlags
583 ; let exts = dopt Opt_GlasgowExts dflags
584 ; mapM_ (infoThing exts session) names }
586 infoThing exts session str = io $ do
587 names <- GHC.parseName session str
588 let filtered = filterOutChildren names
589 mb_stuffs <- mapM (GHC.getInfo session) filtered
590 unqual <- GHC.getPrintUnqual session
591 putStrLn (showSDocForUser unqual $
592 vcat (intersperse (text "") $
593 [ pprInfo exts stuff | Just stuff <- mb_stuffs ]))
595 -- Filter out names whose parent is also there Good
596 -- example is '[]', which is both a type and data
597 -- constructor in the same type
598 filterOutChildren :: [Name] -> [Name]
599 filterOutChildren names = filter (not . parent_is_there) names
600 where parent_is_there n
601 -- | Just p <- GHC.nameParent_maybe n = p `elem` names
605 pprInfo exts (thing, fixity, insts)
606 = pprTyThingInContextLoc exts thing
607 $$ show_fixity fixity
608 $$ vcat (map GHC.pprInstance insts)
611 | fix == GHC.defaultFixity = empty
612 | otherwise = ppr fix <+> ppr (GHC.getName thing)
614 -----------------------------------------------------------------------------
617 runMain :: String -> GHCi ()
619 let ss = concat $ intersperse "," (map (\ s -> ('"':s)++"\"") (toArgs args))
620 runCommand $ '[': ss ++ "] `System.Environment.withArgs` main"
623 addModule :: [FilePath] -> GHCi ()
625 io (revertCAFs) -- always revert CAFs on load/add.
626 files <- mapM expandPath files
627 targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
628 session <- getSession
629 io (mapM_ (GHC.addTarget session) targets)
630 ok <- io (GHC.load session LoadAllTargets)
633 changeDirectory :: String -> GHCi ()
634 changeDirectory dir = do
635 session <- getSession
636 graph <- io (GHC.getModuleGraph session)
637 when (not (null graph)) $
638 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
639 io (GHC.setTargets session [])
640 io (GHC.load session LoadAllTargets)
641 setContextAfterLoad session []
642 io (GHC.workingDirectoryChanged session)
643 dir <- expandPath dir
644 io (setCurrentDirectory dir)
646 editFile :: String -> GHCi ()
649 -- find the name of the "topmost" file loaded
650 session <- getSession
651 graph0 <- io (GHC.getModuleGraph session)
652 graph1 <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph0
653 let graph2 = flattenSCCs (GHC.topSortModuleGraph True graph1 Nothing)
654 case GHC.ml_hs_file (GHC.ms_location (last graph2)) of
655 Just file -> do_edit file
656 Nothing -> throwDyn (CmdLineError "unknown file name")
657 | otherwise = do_edit str
663 throwDyn (CmdLineError "editor not set, use :set editor")
664 io $ system (cmd ++ ' ':file)
667 defineMacro :: String -> GHCi ()
669 let (macro_name, definition) = break isSpace s
670 cmds <- io (readIORef commands)
672 then throwDyn (CmdLineError "invalid macro name")
674 if (macro_name `elem` map cmdName cmds)
675 then throwDyn (CmdLineError
676 ("command '" ++ macro_name ++ "' is already defined"))
679 -- give the expression a type signature, so we can be sure we're getting
680 -- something of the right type.
681 let new_expr = '(' : definition ++ ") :: String -> IO String"
683 -- compile the expression
685 maybe_hv <- io (GHC.compileExpr cms new_expr)
688 Just hv -> io (writeIORef commands --
689 (cmds ++ [(macro_name, runMacro hv, False, completeNone)]))
691 runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi Bool
693 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
694 stringLoop (lines str)
696 undefineMacro :: String -> GHCi ()
697 undefineMacro macro_name = do
698 cmds <- io (readIORef commands)
699 if (macro_name `elem` map cmdName builtin_commands)
700 then throwDyn (CmdLineError
701 ("command '" ++ macro_name ++ "' cannot be undefined"))
703 if (macro_name `notElem` map cmdName cmds)
704 then throwDyn (CmdLineError
705 ("command '" ++ macro_name ++ "' not defined"))
707 io (writeIORef commands (filter ((/= macro_name) . cmdName) cmds))
710 loadModule :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
711 loadModule fs = timeIt (loadModule' fs)
713 loadModule_ :: [FilePath] -> GHCi ()
714 loadModule_ fs = do loadModule (zip fs (repeat Nothing)); return ()
716 loadModule' :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
717 loadModule' files = do
718 session <- getSession
721 io (GHC.setTargets session [])
722 io (GHC.load session LoadAllTargets)
725 let (filenames, phases) = unzip files
726 exp_filenames <- mapM expandPath filenames
727 let files' = zip exp_filenames phases
728 targets <- io (mapM (uncurry GHC.guessTarget) files')
730 -- NOTE: we used to do the dependency anal first, so that if it
731 -- fails we didn't throw away the current set of modules. This would
732 -- require some re-working of the GHC interface, so we'll leave it
733 -- as a ToDo for now.
735 io (GHC.setTargets session targets)
736 ok <- io (GHC.load session LoadAllTargets)
740 checkModule :: String -> GHCi ()
742 let modl = GHC.mkModuleName m
743 session <- getSession
744 result <- io (GHC.checkModule session modl)
746 Nothing -> io $ putStrLn "Nothing"
747 Just r -> io $ putStrLn (showSDoc (
748 case GHC.checkedModuleInfo r of
749 Just cm | Just scope <- GHC.modInfoTopLevelScope cm ->
751 (local,global) = partition ((== modl) . GHC.moduleName . GHC.nameModule) scope
753 (text "global names: " <+> ppr global) $$
754 (text "local names: " <+> ppr local)
756 afterLoad (successIf (isJust result)) session
758 reloadModule :: String -> GHCi ()
760 io (revertCAFs) -- always revert CAFs on reload.
761 session <- getSession
762 ok <- io (GHC.load session LoadAllTargets)
765 io (revertCAFs) -- always revert CAFs on reload.
766 session <- getSession
767 ok <- io (GHC.load session (LoadUpTo (GHC.mkModuleName m)))
770 afterLoad ok session = do
771 io (revertCAFs) -- always revert CAFs on load.
772 graph <- io (GHC.getModuleGraph session)
773 graph' <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph
774 setContextAfterLoad session graph'
775 refreshBkptTable graph'
776 modulesLoadedMsg ok (map GHC.ms_mod_name graph')
778 setContextAfterLoad session [] = do
779 prel_mod <- getPrelude
780 io (GHC.setContext session [] [prel_mod])
781 setContextAfterLoad session ms = do
782 -- load a target if one is available, otherwise load the topmost module.
783 targets <- io (GHC.getTargets session)
784 case [ m | Just m <- map (findTarget ms) targets ] of
786 let graph' = flattenSCCs (GHC.topSortModuleGraph True ms Nothing) in
787 load_this (last graph')
792 = case filter (`matches` t) ms of
796 summary `matches` Target (TargetModule m) _
797 = GHC.ms_mod_name summary == m
798 summary `matches` Target (TargetFile f _) _
799 | Just f' <- GHC.ml_hs_file (GHC.ms_location summary) = f == f'
800 summary `matches` target
803 load_this summary | m <- GHC.ms_mod summary = do
804 b <- io (GHC.moduleIsInterpreted session m)
805 if b then io (GHC.setContext session [m] [])
807 prel_mod <- getPrelude
808 io (GHC.setContext session [] [prel_mod,m])
811 modulesLoadedMsg :: SuccessFlag -> [ModuleName] -> GHCi ()
812 modulesLoadedMsg ok mods = do
813 dflags <- getDynFlags
814 when (verbosity dflags > 0) $ do
816 | null mods = text "none."
818 punctuate comma (map ppr mods)) <> text "."
821 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
823 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
826 typeOfExpr :: String -> GHCi ()
828 = do cms <- getSession
829 maybe_ty <- io (GHC.exprType cms str)
832 Just ty -> do ty' <- cleanType ty
833 tystr <- showForUser (ppr ty')
834 io (putStrLn (str ++ " :: " ++ tystr))
836 kindOfType :: String -> GHCi ()
838 = do cms <- getSession
839 maybe_ty <- io (GHC.typeKind cms str)
842 Just ty -> do tystr <- showForUser (ppr ty)
843 io (putStrLn (str ++ " :: " ++ tystr))
845 quit :: String -> GHCi Bool
848 shellEscape :: String -> GHCi Bool
849 shellEscape str = io (system str >> return False)
851 -----------------------------------------------------------------------------
852 -- create tags file for currently loaded modules.
854 createETagsFileCmd, createCTagsFileCmd :: String -> GHCi ()
856 createCTagsFileCmd "" = ghciCreateTagsFile CTags "tags"
857 createCTagsFileCmd file = ghciCreateTagsFile CTags file
859 createETagsFileCmd "" = ghciCreateTagsFile ETags "TAGS"
860 createETagsFileCmd file = ghciCreateTagsFile ETags file
862 data TagsKind = ETags | CTags
864 ghciCreateTagsFile :: TagsKind -> FilePath -> GHCi ()
865 ghciCreateTagsFile kind file = do
866 session <- getSession
867 io $ createTagsFile session kind file
870 -- - remove restriction that all modules must be interpreted
871 -- (problem: we don't know source locations for entities unless
872 -- we compiled the module.
874 -- - extract createTagsFile so it can be used from the command-line
875 -- (probably need to fix first problem before this is useful).
877 createTagsFile :: Session -> TagsKind -> FilePath -> IO ()
878 createTagsFile session tagskind tagFile = do
879 graph <- GHC.getModuleGraph session
880 let ms = map GHC.ms_mod graph
882 is_interpreted <- GHC.moduleIsInterpreted session m
883 -- should we just skip these?
884 when (not is_interpreted) $
885 throwDyn (CmdLineError ("module '"
886 ++ GHC.moduleNameString (GHC.moduleName m)
887 ++ "' is not interpreted"))
888 mbModInfo <- GHC.getModuleInfo session m
890 | Just modinfo <- mbModInfo,
891 Just unqual <- GHC.modInfoPrintUnqualified modinfo = unqual
892 | otherwise = GHC.alwaysQualify
895 Just modInfo -> return $! listTags unqual modInfo
898 mtags <- mapM tagModule ms
899 either_res <- collateAndWriteTags tagskind tagFile $ concat mtags
901 Left e -> hPutStrLn stderr $ ioeGetErrorString e
904 listTags :: PrintUnqualified -> GHC.ModuleInfo -> [TagInfo]
905 listTags unqual modInfo =
906 [ tagInfo unqual name loc
907 | name <- GHC.modInfoExports modInfo
908 , let loc = nameSrcLoc name
912 type TagInfo = (String -- tag name
915 ,Int -- column number
918 -- get tag info, for later translation into Vim or Emacs style
919 tagInfo :: PrintUnqualified -> Name -> SrcLoc -> TagInfo
920 tagInfo unqual name loc
921 = ( showSDocForUser unqual $ pprOccName (nameOccName name)
922 , showSDocForUser unqual $ ftext (srcLocFile loc)
927 collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
928 collateAndWriteTags CTags file tagInfos = do -- ctags style, Vim et al
929 let tags = unlines $ sortLe (<=) $ nub $ map showTag tagInfos
930 IO.try (writeFile file tags)
931 collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
932 let byFile op (_,f1,_,_) (_,f2,_,_) = f1 `op` f2
933 groups = groupBy (byFile (==)) $ sortLe (byFile (<=)) tagInfos
934 tagGroups <- mapM tagFileGroup groups
935 IO.try (writeFile file $ concat tagGroups)
937 tagFileGroup group@[] = throwDyn (CmdLineError "empty tag file group??")
938 tagFileGroup group@((_,fileName,_,_):_) = do
939 file <- readFile fileName -- need to get additional info from sources..
940 let byLine (_,_,l1,_) (_,_,l2,_) = l1 <= l2
941 sortedGroup = sortLe byLine group
942 tags = unlines $ perFile sortedGroup 1 0 $ lines file
943 return $ "\x0c\n" ++ fileName ++ "," ++ show (length tags) ++ "\n" ++ tags
944 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos (line:lines) | lNo>count =
945 perFile (tagInfo:tags) (count+1) (pos+length line) lines
946 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos lines@(line:_) | lNo==count =
947 showETag tagInfo line pos : perFile tags count pos lines
948 perFile tags count pos lines = []
950 -- simple ctags format, for Vim et al
951 showTag :: TagInfo -> String
952 showTag (tag,file,lineNo,colNo)
953 = tag ++ "\t" ++ file ++ "\t" ++ show lineNo
955 -- etags format, for Emacs/XEmacs
956 showETag :: TagInfo -> String -> Int -> String
957 showETag (tag,file,lineNo,colNo) line charPos
958 = take colNo line ++ tag
960 ++ "\x01" ++ show lineNo
961 ++ "," ++ show charPos
963 -----------------------------------------------------------------------------
964 -- Browsing a module's contents
966 browseCmd :: String -> GHCi ()
969 ['*':m] | looksLikeModuleName m -> browseModule m False
970 [m] | looksLikeModuleName m -> browseModule m True
971 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
973 browseModule m exports_only = do
975 modl <- io $ GHC.findModule s (GHC.mkModuleName m) Nothing
976 is_interpreted <- io (GHC.moduleIsInterpreted s modl)
977 when (not is_interpreted && not exports_only) $
978 throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
980 -- Temporarily set the context to the module we're interested in,
981 -- just so we can get an appropriate PrintUnqualified
982 (as,bs) <- io (GHC.getContext s)
983 prel_mod <- getPrelude
984 io (if exports_only then GHC.setContext s [] [prel_mod,modl]
985 else GHC.setContext s [modl] [])
986 unqual <- io (GHC.getPrintUnqual s)
987 io (GHC.setContext s as bs)
989 mb_mod_info <- io $ GHC.getModuleInfo s modl
991 Nothing -> throwDyn (CmdLineError ("unknown module: " ++ m))
994 | exports_only = GHC.modInfoExports mod_info
995 | otherwise = fromMaybe [] (GHC.modInfoTopLevelScope mod_info)
997 filtered = filterOutChildren names
999 things <- io $ mapM (GHC.lookupName s) filtered
1001 dflags <- getDynFlags
1002 let exts = dopt Opt_GlasgowExts dflags
1003 io (putStrLn (showSDocForUser unqual (
1004 vcat (map (pprTyThingInContext exts) (catMaybes things))
1006 -- ToDo: modInfoInstances currently throws an exception for
1007 -- package modules. When it works, we can do this:
1008 -- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
1010 -----------------------------------------------------------------------------
1011 -- Setting the module context
1014 | all sensible mods = fn mods
1015 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
1017 (fn, mods) = case str of
1018 '+':stuff -> (addToContext, words stuff)
1019 '-':stuff -> (removeFromContext, words stuff)
1020 stuff -> (newContext, words stuff)
1022 sensible ('*':m) = looksLikeModuleName m
1023 sensible m = looksLikeModuleName m
1025 separate :: Session -> [String] -> [Module] -> [Module]
1026 -> GHCi ([Module],[Module])
1027 separate session [] as bs = return (as,bs)
1028 separate session (('*':str):ms) as bs = do
1029 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1030 b <- io $ GHC.moduleIsInterpreted session m
1031 if b then separate session ms (m:as) bs
1032 else throwDyn (CmdLineError ("module '"
1033 ++ GHC.moduleNameString (GHC.moduleName m)
1034 ++ "' is not interpreted"))
1035 separate session (str:ms) as bs = do
1036 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1037 separate session ms as (m:bs)
1039 newContext :: [String] -> GHCi ()
1040 newContext strs = do
1042 (as,bs) <- separate s strs [] []
1043 prel_mod <- getPrelude
1044 let bs' = if null as && prel_mod `notElem` bs then prel_mod:bs else bs
1045 io $ GHC.setContext s as bs'
1048 addToContext :: [String] -> GHCi ()
1049 addToContext strs = do
1051 (as,bs) <- io $ GHC.getContext s
1053 (new_as,new_bs) <- separate s strs [] []
1055 let as_to_add = new_as \\ (as ++ bs)
1056 bs_to_add = new_bs \\ (as ++ bs)
1058 io $ GHC.setContext s (as ++ as_to_add) (bs ++ bs_to_add)
1061 removeFromContext :: [String] -> GHCi ()
1062 removeFromContext strs = do
1064 (as,bs) <- io $ GHC.getContext s
1066 (as_to_remove,bs_to_remove) <- separate s strs [] []
1068 let as' = as \\ (as_to_remove ++ bs_to_remove)
1069 bs' = bs \\ (as_to_remove ++ bs_to_remove)
1071 io $ GHC.setContext s as' bs'
1073 ----------------------------------------------------------------------------
1076 -- set options in the interpreter. Syntax is exactly the same as the
1077 -- ghc command line, except that certain options aren't available (-C,
1080 -- This is pretty fragile: most options won't work as expected. ToDo:
1081 -- figure out which ones & disallow them.
1083 setCmd :: String -> GHCi ()
1085 = do st <- getGHCiState
1086 let opts = options st
1087 io $ putStrLn (showSDoc (
1088 text "options currently set: " <>
1091 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
1094 = case toArgs str of
1095 ("args":args) -> setArgs args
1096 ("prog":prog) -> setProg prog
1097 ("prompt":prompt) -> setPrompt (after 6)
1098 ("editor":cmd) -> setEditor (after 6)
1099 wds -> setOptions wds
1100 where after n = dropWhile isSpace $ drop n $ dropWhile isSpace str
1104 setGHCiState st{ args = args }
1108 setGHCiState st{ progname = prog }
1110 io (hPutStrLn stderr "syntax: :set prog <progname>")
1114 setGHCiState st{ editor = cmd }
1116 setPrompt value = do
1119 then io $ hPutStrLn stderr $ "syntax: :set prompt <prompt>, currently \"" ++ prompt st ++ "\""
1120 else setGHCiState st{ prompt = remQuotes value }
1122 remQuotes ('\"':xs) | not (null xs) && last xs == '\"' = init xs
1126 do -- first, deal with the GHCi opts (+s, +t, etc.)
1127 let (plus_opts, minus_opts) = partition isPlus wds
1128 mapM_ setOpt plus_opts
1130 -- then, dynamic flags
1131 dflags <- getDynFlags
1132 let pkg_flags = packageFlags dflags
1133 (dflags',leftovers) <- io $ GHC.parseDynamicFlags dflags minus_opts
1135 if (not (null leftovers))
1136 then throwDyn (CmdLineError ("unrecognised flags: " ++
1140 new_pkgs <- setDynFlags dflags'
1142 -- if the package flags changed, we should reset the context
1143 -- and link the new packages.
1144 dflags <- getDynFlags
1145 when (packageFlags dflags /= pkg_flags) $ do
1146 io $ hPutStrLn stderr "package flags have changed, ressetting and loading new packages..."
1147 session <- getSession
1148 io (GHC.setTargets session [])
1149 io (GHC.load session LoadAllTargets)
1150 io (linkPackages dflags new_pkgs)
1151 setContextAfterLoad session []
1155 unsetOptions :: String -> GHCi ()
1157 = do -- first, deal with the GHCi opts (+s, +t, etc.)
1158 let opts = words str
1159 (minus_opts, rest1) = partition isMinus opts
1160 (plus_opts, rest2) = partition isPlus rest1
1162 if (not (null rest2))
1163 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
1166 mapM_ unsetOpt plus_opts
1168 -- can't do GHC flags for now
1169 if (not (null minus_opts))
1170 then throwDyn (CmdLineError "can't unset GHC command-line flags")
1173 isMinus ('-':s) = True
1176 isPlus ('+':s) = True
1180 = case strToGHCiOpt str of
1181 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1182 Just o -> setOption o
1185 = case strToGHCiOpt str of
1186 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1187 Just o -> unsetOption o
1189 strToGHCiOpt :: String -> (Maybe GHCiOption)
1190 strToGHCiOpt "s" = Just ShowTiming
1191 strToGHCiOpt "t" = Just ShowType
1192 strToGHCiOpt "r" = Just RevertCAFs
1193 strToGHCiOpt _ = Nothing
1195 optToStr :: GHCiOption -> String
1196 optToStr ShowTiming = "s"
1197 optToStr ShowType = "t"
1198 optToStr RevertCAFs = "r"
1200 -- ---------------------------------------------------------------------------
1205 ["modules" ] -> showModules
1206 ["bindings"] -> showBindings
1207 ["linker"] -> io showLinkerState
1208 ["breakpoints"] -> showBkptTable
1209 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
1212 session <- getSession
1213 let show_one ms = do m <- io (GHC.showModule session ms)
1215 graph <- io (GHC.getModuleGraph session)
1216 mapM_ show_one graph
1220 unqual <- io (GHC.getPrintUnqual s)
1221 bindings <- io (GHC.getBindings s)
1222 mapM_ showTyThing bindings
1225 showTyThing (AnId id) = do
1226 ty' <- cleanType (GHC.idType id)
1227 str <- showForUser (ppr id <> text " :: " <> ppr ty')
1229 showTyThing _ = return ()
1231 -- if -fglasgow-exts is on we show the foralls, otherwise we don't.
1232 cleanType :: Type -> GHCi Type
1234 dflags <- getDynFlags
1235 if dopt Opt_GlasgowExts dflags
1237 else return $! GHC.dropForAlls ty
1239 showBkptTable :: GHCi ()
1242 msg <- showForUser . vcat $
1243 [ ppr mod <> colon <+> fcat
1244 [ parens(int row <> comma <> int col) | (row,col) <- sites]
1245 | (mod, sites) <- sitesList bt ]
1247 -- -----------------------------------------------------------------------------
1250 completeNone :: String -> IO [String]
1251 completeNone w = return []
1254 completeWord :: String -> Int -> Int -> IO (Maybe (String, [String]))
1255 completeWord w start end = do
1256 line <- Readline.getLineBuffer
1258 ':':_ | all isSpace (take (start-1) line) -> wrapCompleter completeCmd w
1260 | Just c <- is_cmd line -> do
1261 maybe_cmd <- lookupCommand c
1262 let (n,w') = selectWord (words' 0 line)
1264 Nothing -> return Nothing
1265 Just (_,_,False,complete) -> wrapCompleter complete w
1266 Just (_,_,True,complete) -> let complete' w = do rets <- complete w
1267 return (map (drop n) rets)
1268 in wrapCompleter complete' w'
1270 --printf "complete %s, start = %d, end = %d\n" w start end
1271 wrapCompleter completeIdentifier w
1272 where words' _ [] = []
1273 words' n str = let (w,r) = break isSpace str
1274 (s,r') = span isSpace r
1275 in (n,w):words' (n+length w+length s) r'
1276 -- In a Haskell expression we want to parse 'a-b' as three words
1277 -- where a compiler flag (ie. -fno-monomorphism-restriction) should
1278 -- only be a single word.
1279 selectWord [] = (0,w)
1280 selectWord ((offset,x):xs)
1281 | offset+length x >= start = (start-offset,take (end-offset) x)
1282 | otherwise = selectWord xs
1285 | ((':':w) : _) <- words (dropWhile isSpace line) = Just w
1286 | otherwise = Nothing
1289 cmds <- readIORef commands
1290 return (filter (w `isPrefixOf`) (map (':':) (map cmdName cmds)))
1292 completeMacro w = do
1293 cmds <- readIORef commands
1294 let cmds' = [ cmd | cmd <- map cmdName cmds, cmd `elem` map cmdName builtin_commands ]
1295 return (filter (w `isPrefixOf`) cmds')
1297 completeIdentifier w = do
1299 rdrs <- GHC.getRdrNamesInScope s
1300 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
1302 completeModule w = do
1304 dflags <- GHC.getSessionDynFlags s
1305 let pkg_mods = allExposedModules dflags
1306 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) pkg_mods))
1308 completeHomeModule w = do
1310 g <- GHC.getModuleGraph s
1311 let home_mods = map GHC.ms_mod_name g
1312 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) home_mods))
1314 completeSetOptions w = do
1315 return (filter (w `isPrefixOf`) options)
1316 where options = "args":"prog":allFlags
1318 completeBkpt = unionComplete completeModule completeBkptCmds
1320 completeBkptCmds w = do
1321 return (filter (w `isPrefixOf`) options)
1322 where options = ["add","del","list","stop"]
1324 completeFilename = Readline.filenameCompletionFunction
1326 completeHomeModuleOrFile = unionComplete completeHomeModule completeFilename
1328 unionComplete :: (String -> IO [String]) -> (String -> IO [String]) -> String -> IO [String]
1329 unionComplete f1 f2 w = do
1334 wrapCompleter :: (String -> IO [String]) -> String -> IO (Maybe (String,[String]))
1335 wrapCompleter fun w = do
1338 [] -> return Nothing
1339 [x] -> return (Just (x,[]))
1340 xs -> case getCommonPrefix xs of
1341 "" -> return (Just ("",xs))
1342 pref -> return (Just (pref,xs))
1344 getCommonPrefix :: [String] -> String
1345 getCommonPrefix [] = ""
1346 getCommonPrefix (s:ss) = foldl common s ss
1347 where common s "" = s
1349 common (c:cs) (d:ds)
1350 | c == d = c : common cs ds
1353 allExposedModules :: DynFlags -> [ModuleName]
1354 allExposedModules dflags
1355 = map GHC.mkModuleName (concat (map exposedModules (filter exposed (eltsUFM pkg_db))))
1357 pkg_db = pkgIdMap (pkgState dflags)
1359 completeCmd = completeNone
1360 completeMacro = completeNone
1361 completeIdentifier = completeNone
1362 completeModule = completeNone
1363 completeHomeModule = completeNone
1364 completeSetOptions = completeNone
1365 completeFilename = completeNone
1366 completeHomeModuleOrFile=completeNone
1367 completeBkpt = completeNone
1370 -- ---------------------------------------------------------------------------
1371 -- User code exception handling
1373 -- This is the exception handler for exceptions generated by the
1374 -- user's code and exceptions coming from children sessions;
1375 -- it normally just prints out the exception. The
1376 -- handler must be recursive, in case showing the exception causes
1377 -- more exceptions to be raised.
1379 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
1380 -- raising another exception. We therefore don't put the recursive
1381 -- handler arond the flushing operation, so if stderr is closed
1382 -- GHCi will just die gracefully rather than going into an infinite loop.
1383 handler :: Exception -> GHCi Bool
1384 handler (DynException dyn)
1385 | Just StopChildSession <- fromDynamic dyn
1386 -- propagate to the parent session
1387 = ASSERTM (liftM not isTopLevel) >> throwDyn StopChildSession
1389 | Just (ChildSessionStopped msg) <- fromDynamic dyn
1390 -- Reload modules and display some message
1391 = ASSERTM (isTopLevel) >> io(putStrLn msg) >> return False
1393 handler exception = do
1395 io installSignalHandlers
1396 ghciHandle handler (showException exception >> return False)
1398 showException (DynException dyn) =
1399 case fromDynamic dyn of
1400 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
1401 Just Interrupted -> io (putStrLn "Interrupted.")
1402 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
1403 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
1404 Just other_ghc_ex -> io (print other_ghc_ex)
1406 showException other_exception
1407 = io (putStrLn ("*** Exception: " ++ show other_exception))
1409 -----------------------------------------------------------------------------
1410 -- recursive exception handlers
1412 -- Don't forget to unblock async exceptions in the handler, or if we're
1413 -- in an exception loop (eg. let a = error a in a) the ^C exception
1414 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1416 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1417 ghciHandle h (GHCi m) = GHCi $ \s ->
1418 Exception.catch (m s)
1419 (\e -> unGHCi (ghciUnblock (h e)) s)
1421 ghciUnblock :: GHCi a -> GHCi a
1422 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1425 -- ----------------------------------------------------------------------------
1428 expandPath :: String -> GHCi String
1430 case dropWhile isSpace path of
1432 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1433 return (tilde ++ '/':d)
1437 -- ----------------------------------------------------------------------------
1438 -- Windows console setup
1440 setUpConsole :: IO ()
1442 #ifdef mingw32_HOST_OS
1443 -- On Windows we need to set a known code page, otherwise the characters
1444 -- we read from the console will be be in some strange encoding, and
1445 -- similarly for characters we write to the console.
1447 -- At the moment, GHCi pretends all input is Latin-1. In the
1448 -- future we should support UTF-8, but for now we set the code pages
1451 -- It seems you have to set the font in the console window to
1452 -- a Unicode font in order for output to work properly,
1453 -- otherwise non-ASCII characters are mapped wrongly. sigh.
1454 -- (see MSDN for SetConsoleOutputCP()).
1456 setConsoleCP 28591 -- ISO Latin-1
1457 setConsoleOutputCP 28591 -- ISO Latin-1
1462 instrumentationBkptHandler :: IORef (BkptTable Module) -> BkptHandler Module
1463 instrumentationBkptHandler ref_bkptTable = BkptHandler {
1464 isAutoBkptEnabled = \sess bkptLoc -> do
1465 bktpTable <- readIORef ref_bkptTable
1466 return$ isBkptEnabled bktpTable bkptLoc
1468 , handleBreakpoint = doBreakpoint ref_bkptTable
1471 doBreakpoint :: IORef (BkptTable Module)-> Session -> [(Id,HValue)] -> BkptLocation Module -> String -> b -> IO b
1472 doBreakpoint ref_bkptTable s@(Session ref) values _ locMsg b = do
1473 let (ids, hValues) = unzip values
1474 names = map idName ids
1475 ASSERT (length names == length hValues) return ()
1476 let global_ids = map globaliseAndTidy ids
1477 printScopeMsg locMsg global_ids
1478 typed_ids <- mapM instantiateIdType global_ids
1479 hsc_env <- readIORef ref
1480 let ictxt = hsc_IC hsc_env
1481 rn_env = ic_rn_local_env ictxt
1482 type_env = ic_type_env ictxt
1483 bound_names = map idName typed_ids
1484 new_rn_env = extendLocalRdrEnv rn_env bound_names
1485 -- Remove any shadowed bindings from the type_env;
1486 -- they are inaccessible but might, I suppose, cause
1487 -- a space leak if we leave them there
1488 shadowed = [ n | name <- bound_names,
1489 let rdr_name = mkRdrUnqual (nameOccName name),
1490 Just n <- [lookupLocalRdrEnv rn_env rdr_name] ]
1491 filtered_type_env = delListFromNameEnv type_env shadowed
1492 new_type_env = extendTypeEnvWithIds filtered_type_env (typed_ids)
1493 new_ic = ictxt { ic_rn_local_env = new_rn_env,
1494 ic_type_env = new_type_env }
1495 writeIORef ref (hsc_env { hsc_IC = new_ic })
1496 is_tty <- hIsTerminalDevice stdin
1497 prel_mod <- GHC.findModule s prel_name Nothing
1498 withExtendedLinkEnv (zip names hValues) $
1499 startGHCi (interactiveLoop is_tty True) GHCiState{
1500 progname = "<interactive>",
1502 prompt = locMsg ++ "> ",
1505 bkptTable= ref_bkptTable,
1509 \StopChildSession -> evaluate$
1510 throwDyn (ChildSessionStopped "")
1512 writeIORef ref hsc_env
1513 putStrLn $ "Returning to normal execution..."
1516 printScopeMsg :: String -> [Id] -> IO ()
1517 printScopeMsg location ids = do
1518 unqual <- GHC.getPrintUnqual s
1519 printForUser stdout unqual $
1520 text "Local bindings in scope:" $$
1521 nest 2 (pprWithCommas showId ids)
1524 ppr (idName id) <+> dcolon <+> ppr (idType id)
1526 -- | Give the Id a Global Name, and tidy its type
1527 globaliseAndTidy :: Id -> Id
1529 = let tidied_type = tidyTopType$ idType id
1530 in setIdType (globaliseId VanillaGlobal id) tidied_type
1532 -- | Instantiate the tyVars with GHC.Base.Unknown
1533 instantiateIdType :: Id -> IO Id
1534 instantiateIdType id = do
1535 instantiatedType <- instantiateTyVarsToUnknown s (idType id)
1536 return$ setIdType id instantiatedType