1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
3 -- $Id: InteractiveUI.hs,v 1.143 2003/02/12 15:01:35 simonpj Exp $
5 -- GHC Interactive User Interface
7 -- (c) The GHC Team 2000
9 -----------------------------------------------------------------------------
10 module InteractiveUI (
11 interactiveUI, -- :: CmState -> [FilePath] -> [LibrarySpec] -> IO ()
15 #include "../includes/config.h"
16 #include "HsVersions.h"
19 import HscTypes ( TyThing(..), HomeModInfo(hm_linkable), HomePackageTable,
21 import HsSyn ( TyClDecl(..), ConDecl(..), Sig(..) )
22 import MkIface ( ifaceTyThing )
25 import DriverUtil ( remove_spaces, handle )
26 import Linker ( initLinker, showLinkerState, linkLibraries,
29 import Id ( isRecordSelector, isImplicitId, recordSelectorFieldLabel, idName )
30 import Class ( className )
31 import TyCon ( tyConName, tyConClass_maybe, isPrimTyCon, DataConDetails(..) )
32 import DataCon ( dataConName )
33 import FieldLabel ( fieldLabelTyCon )
34 import SrcLoc ( isGoodSrcLoc )
35 import Module ( showModMsg, lookupModuleEnv )
36 import Name ( Name, isHomePackageName, nameSrcLoc, nameOccName,
38 import OccName ( isSymOcc )
39 import BasicTypes ( defaultFixity, SuccessFlag(..) )
42 import CmdLineOpts ( DynFlag(..), DynFlags(..), getDynFlags, saveDynFlags,
43 restoreDynFlags, dopt_unset )
44 import Panic ( GhcException(..), showGhcException )
47 #ifndef mingw32_TARGET_OS
51 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
52 import Control.Concurrent ( yield ) -- Used in readline loop
53 import System.Console.Readline as Readline
58 import Control.Exception as Exception
60 import Control.Concurrent
66 import System.Environment
67 import System.Directory
68 import System.IO as IO
70 import Control.Monad as Monad
72 import GHC.Exts ( unsafeCoerce# )
74 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
76 import GHC.Posix ( setNonBlockingFD )
78 -----------------------------------------------------------------------------
82 \ / _ \\ /\\ /\\/ __(_)\n\
83 \ / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n\
84 \/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n\
85 \\\____/\\/ /_/\\____/|_| Type :? for help.\n"
87 GLOBAL_VAR(commands, builtin_commands, [(String, String -> GHCi Bool)])
89 builtin_commands :: [(String, String -> GHCi Bool)]
91 ("add", keepGoing addModule),
92 ("browse", keepGoing browseCmd),
93 ("cd", keepGoing changeDirectory),
94 ("def", keepGoing defineMacro),
95 ("help", keepGoing help),
96 ("?", keepGoing help),
97 ("info", keepGoing info),
98 ("load", keepGoing loadModule),
99 ("module", keepGoing setContext),
100 ("reload", keepGoing reloadModule),
101 ("set", keepGoing setCmd),
102 ("show", keepGoing showCmd),
103 ("type", keepGoing typeOfExpr),
104 ("unset", keepGoing unsetOptions),
105 ("undef", keepGoing undefineMacro),
109 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
110 keepGoing a str = a str >> return False
112 shortHelpText = "use :? for help.\n"
114 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
116 \ Commands available from the prompt:\n\
118 \ <stmt> evaluate/run <stmt>\n\
119 \ :add <filename> ... add module(s) to the current target set\n\
120 \ :browse [*]<module> display the names defined by <module>\n\
121 \ :cd <dir> change directory to <dir>\n\
122 \ :def <cmd> <expr> define a command :<cmd>\n\
123 \ :help, :? display this list of commands\n\
124 \ :info [<name> ...] display information about the given names\n\
125 \ :load <filename> ... load module(s) and their dependents\n\
126 \ :module [+/-] [*]<mod> ... set the context for expression evaluation\n\
127 \ :reload reload the current module set\n\
129 \ :set <option> ... set options\n\
130 \ :set args <arg> ... set the arguments returned by System.getArgs\n\
131 \ :set prog <progname> set the value returned by System.getProgName\n\
133 \ :show modules show the currently loaded modules\n\
134 \ :show bindings show the current bindings made at the prompt\n\
136 \ :type <expr> show the type of <expr>\n\
137 \ :undef <cmd> undefine user-defined command :<cmd>\n\
138 \ :unset <option> ... unset options\n\
140 \ :!<command> run the shell command <command>\n\
142 \ Options for `:set' and `:unset':\n\
144 \ +r revert top-level expressions after each evaluation\n\
145 \ +s print timing/memory stats after each evaluation\n\
146 \ +t print type after evaluation\n\
147 \ -<flags> most GHC command line flags can also be set here\n\
148 \ (eg. -v2, -fglasgow-exts, etc.)\n\
151 interactiveUI :: CmState -> [FilePath] -> [FilePath] -> IO ()
152 interactiveUI cmstate paths cmdline_objs = do
154 hSetBuffering stdout NoBuffering
156 dflags <- getDynFlags
160 -- link packages requested explicitly on the command-line
161 expl <- readIORef v_ExplicitPackages
162 linkPackages dflags expl
164 -- link libraries from the command-line
165 linkLibraries dflags cmdline_objs
167 -- Initialise buffering for the *interpreted* I/O system
168 cmstate <- initInterpBuffering cmstate dflags
170 -- We don't want the cmd line to buffer any input that might be
171 -- intended for the program, so unbuffer stdin.
172 hSetBuffering stdin NoBuffering
174 -- initial context is just the Prelude
175 cmstate <- cmSetContext cmstate dflags [] ["Prelude"]
177 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
181 startGHCi (runGHCi paths dflags)
182 GHCiState{ progname = "<interactive>",
188 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
189 Readline.resetTerminal Nothing
194 runGHCi :: [FilePath] -> DynFlags -> GHCi ()
195 runGHCi paths dflags = do
196 read_dot_files <- io (readIORef v_Read_DotGHCi)
198 when (read_dot_files) $ do
201 exists <- io (doesFileExist file)
203 dir_ok <- io (checkPerms ".")
204 file_ok <- io (checkPerms file)
205 when (dir_ok && file_ok) $ do
206 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
209 Right hdl -> fileLoop hdl False
211 when (read_dot_files) $ do
212 -- Read in $HOME/.ghci
213 either_dir <- io (IO.try (getEnv "HOME"))
217 cwd <- io (getCurrentDirectory)
218 when (dir /= cwd) $ do
219 let file = dir ++ "/.ghci"
220 ok <- io (checkPerms file)
222 either_hdl <- io (IO.try (openFile file ReadMode))
225 Right hdl -> fileLoop hdl False
227 -- perform a :load for files given on the GHCi command line
228 when (not (null paths)) $
229 ghciHandle showException $
230 loadModule (unwords paths)
232 -- enter the interactive loop
233 #if defined(mingw32_TARGET_OS)
234 -- always show prompt, since hIsTerminalDevice returns True for Consoles
235 -- only, which we may or may not be running under (cf. Emacs sub-shells.)
238 is_tty <- io (hIsTerminalDevice stdin)
239 interactiveLoop is_tty
243 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
246 interactiveLoop is_tty = do
247 -- ignore ^C exceptions caught here
248 ghciHandleDyn (\e -> case e of
249 Interrupted -> ghciUnblock (interactiveLoop is_tty)
250 _other -> return ()) $ do
252 -- read commands from stdin
253 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
256 else fileLoop stdin False -- turn off prompt for non-TTY input
258 fileLoop stdin is_tty
262 -- NOTE: We only read .ghci files if they are owned by the current user,
263 -- and aren't world writable. Otherwise, we could be accidentally
264 -- running code planted by a malicious third party.
266 -- Furthermore, We only read ./.ghci if . is owned by the current user
267 -- and isn't writable by anyone else. I think this is sufficient: we
268 -- don't need to check .. and ../.. etc. because "." always refers to
269 -- the same directory while a process is running.
271 checkPerms :: String -> IO Bool
273 #ifdef mingw32_TARGET_OS
276 DriverUtil.handle (\_ -> return False) $ do
277 st <- getFileStatus name
279 if fileOwner st /= me then do
280 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
283 let mode = fileMode st
284 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
285 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
287 putStrLn $ "*** WARNING: " ++ name ++
288 " is writable by someone else, IGNORING!"
293 fileLoop :: Handle -> Bool -> GHCi ()
294 fileLoop hdl prompt = do
295 cmstate <- getCmState
296 (mod,imports) <- io (cmGetContext cmstate)
297 when prompt (io (putStr (mkPrompt mod imports)))
298 l <- io (IO.try (hGetLine hdl))
300 Left e | isEOFError e -> return ()
301 | otherwise -> io (ioError e)
303 case remove_spaces l of
304 "" -> fileLoop hdl prompt
305 l -> do quit <- runCommand l
306 if quit then return () else fileLoop hdl prompt
308 stringLoop :: [String] -> GHCi ()
309 stringLoop [] = return ()
310 stringLoop (s:ss) = do
311 case remove_spaces s of
313 l -> do quit <- runCommand l
314 if quit then return () else stringLoop ss
316 mkPrompt toplevs exports
317 = concat (intersperse " " (map ('*':) toplevs ++ exports)) ++ "> "
319 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
320 readlineLoop :: GHCi ()
322 cmstate <- getCmState
323 (mod,imports) <- io (cmGetContext cmstate)
325 l <- io (readline (mkPrompt mod imports)
326 `finally` setNonBlockingFD 0)
327 -- readline sometimes puts stdin into blocking mode,
328 -- so we need to put it back for the IO library
332 case remove_spaces l of
337 if quit then return () else readlineLoop
340 runCommand :: String -> GHCi Bool
341 runCommand c = ghciHandle handler (doCommand c)
343 -- This is the exception handler for exceptions generated by the
344 -- user's code; it normally just prints out the exception. The
345 -- handler must be recursive, in case showing the exception causes
346 -- more exceptions to be raised.
348 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
349 -- raising another exception. We therefore don't put the recursive
350 -- handler arond the flushing operation, so if stderr is closed
351 -- GHCi will just die gracefully rather than going into an infinite loop.
352 handler :: Exception -> GHCi Bool
353 handler exception = do
355 ghciHandle handler (showException exception >> return False)
357 showException (DynException dyn) =
358 case fromDynamic dyn of
359 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
360 Just Interrupted -> io (putStrLn "Interrupted.")
361 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
362 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
363 Just other_ghc_ex -> io (print other_ghc_ex)
365 showException other_exception
366 = io (putStrLn ("*** Exception: " ++ show other_exception))
368 doCommand (':' : command) = specialCommand command
370 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
373 runStmt :: String -> GHCi [Name]
375 | null (filter (not.isSpace) stmt) = return []
377 = do st <- getGHCiState
378 dflags <- io getDynFlags
379 let dflags' = dopt_unset dflags Opt_WarnUnusedBinds
380 (new_cmstate, result) <-
381 io $ withProgName (progname st) $ withArgs (args st) $
382 cmRunStmt (cmstate st) dflags' stmt
383 setGHCiState st{cmstate = new_cmstate}
385 CmRunFailed -> return []
386 CmRunException e -> showException e >> return []
387 CmRunOk names -> return names
389 -- possibly print the type and revert CAFs after evaluating an expression
391 = do b <- isOptionSet ShowType
392 cmstate <- getCmState
393 when b (mapM_ (showTypeOfName cmstate) names)
396 b <- isOptionSet RevertCAFs
397 io (when b revertCAFs)
400 showTypeOfName :: CmState -> Name -> GHCi ()
401 showTypeOfName cmstate n
402 = do maybe_str <- io (cmTypeOfName cmstate n)
405 Just str -> io (putStrLn (showSDoc (ppr n) ++ " :: " ++ str))
407 specialCommand :: String -> GHCi Bool
408 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
409 specialCommand str = do
410 let (cmd,rest) = break isSpace str
411 cmds <- io (readIORef commands)
412 case [ (s,f) | (s,f) <- cmds, prefixMatch cmd s ] of
413 [] -> io (hPutStr stdout ("unknown command `:" ++ cmd ++ "'\n"
414 ++ shortHelpText) >> return False)
415 [(_,f)] -> f (dropWhile isSpace rest)
416 cs -> io (hPutStrLn stdout ("prefix " ++ cmd ++
417 " matches multiple commands (" ++
418 foldr1 (\a b -> a ++ ',':b) (map fst cs)
419 ++ ")") >> return False)
421 noArgs c = throwDyn (CmdLineError ("command `" ++ c ++ "' takes no arguments"))
424 -----------------------------------------------------------------------------
425 -- To flush buffers for the *interpreted* computation we need
426 -- to refer to *its* stdout/stderr handles
428 GLOBAL_VAR(flush_interp, error "no flush_interp", IO ())
429 GLOBAL_VAR(turn_off_buffering, error "no flush_stdout", IO ())
431 no_buf_cmd = "IO.hSetBuffering IO.stdout IO.NoBuffering" ++
432 " Prelude.>> IO.hSetBuffering IO.stderr IO.NoBuffering"
433 flush_cmd = "IO.hFlush IO.stdout Prelude.>> IO.hFlush IO.stderr"
435 initInterpBuffering :: CmState -> DynFlags -> IO CmState
436 initInterpBuffering cmstate dflags
437 = do (cmstate, maybe_hval) <- cmCompileExpr cmstate dflags no_buf_cmd
440 Just hval -> writeIORef turn_off_buffering (unsafeCoerce# hval :: IO ())
441 other -> panic "interactiveUI:setBuffering"
443 (cmstate, maybe_hval) <- cmCompileExpr cmstate dflags flush_cmd
445 Just hval -> writeIORef flush_interp (unsafeCoerce# hval :: IO ())
446 _ -> panic "interactiveUI:flush"
448 turnOffBuffering -- Turn it off right now
453 flushInterpBuffers :: GHCi ()
455 = io $ do Monad.join (readIORef flush_interp)
458 turnOffBuffering :: IO ()
460 = do Monad.join (readIORef turn_off_buffering)
463 -----------------------------------------------------------------------------
466 help :: String -> GHCi ()
467 help _ = io (putStr helpText)
469 info :: String -> GHCi ()
470 info "" = throwDyn (CmdLineError "syntax: `:i <thing-you-want-info-about>'")
473 init_cms <- getCmState
474 dflags <- io getDynFlags
476 infoThings cms [] = return cms
477 infoThings cms (name:names) = do
478 (cms, stuff) <- io (cmInfoThing cms dflags name)
479 io (putStrLn (showSDocForUser unqual (
480 vcat (intersperse (text "") (map showThing stuff))))
484 unqual = cmGetPrintUnqual init_cms
486 showThing (ty_thing, fixity)
487 = vcat [ text "-- " <> showTyThing ty_thing,
488 showFixity fixity (getName ty_thing),
489 ppr (ifaceTyThing ty_thing) ]
492 | fix == defaultFixity = empty
493 | otherwise = ppr fix <+>
494 (if isSymOcc (nameOccName name)
496 else char '`' <> ppr name <> char '`')
498 showTyThing (AClass cl)
499 = hcat [ppr cl, text " is a class", showSrcLoc (className cl)]
500 showTyThing (ADataCon dc)
501 = hcat [ppr dc, text " is a data constructor", showSrcLoc (dataConName dc)]
502 showTyThing (ATyCon ty)
504 = hcat [ppr ty, text " is a primitive type constructor"]
506 = hcat [ppr ty, text " is a type constructor", showSrcLoc (tyConName ty)]
507 showTyThing (AnId id)
508 = hcat [ppr id, text " is a ", idDescr id, showSrcLoc (idName id)]
511 | isRecordSelector id =
512 case tyConClass_maybe (fieldLabelTyCon (
513 recordSelectorFieldLabel id)) of
514 Nothing -> text "record selector"
515 Just c -> text "method in class " <> ppr c
516 | otherwise = text "variable"
518 -- also print out the source location for home things
520 | isHomePackageName name && isGoodSrcLoc loc
521 = hsep [ text ", defined at", ppr loc ]
524 where loc = nameSrcLoc name
526 cms <- infoThings init_cms names
530 addModule :: String -> GHCi ()
532 let files = words str
533 state <- getGHCiState
534 dflags <- io (getDynFlags)
535 io (revertCAFs) -- always revert CAFs on load/add.
536 let new_targets = files ++ targets state
537 graph <- io (cmDepAnal (cmstate state) dflags new_targets)
538 (cmstate1, ok, mods) <- io (cmLoadModules (cmstate state) dflags graph)
539 setGHCiState state{ cmstate = cmstate1, targets = new_targets }
540 setContextAfterLoad mods
541 modulesLoadedMsg ok mods dflags
543 changeDirectory :: String -> GHCi ()
544 changeDirectory ('~':d) = do
545 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
546 io (setCurrentDirectory (tilde ++ '/':d))
547 changeDirectory d = io (setCurrentDirectory d)
549 defineMacro :: String -> GHCi ()
551 let (macro_name, definition) = break isSpace s
552 cmds <- io (readIORef commands)
554 then throwDyn (CmdLineError "invalid macro name")
556 if (macro_name `elem` map fst cmds)
557 then throwDyn (CmdLineError
558 ("command `" ++ macro_name ++ "' is already defined"))
561 -- give the expression a type signature, so we can be sure we're getting
562 -- something of the right type.
563 let new_expr = '(' : definition ++ ") :: String -> IO String"
565 -- compile the expression
567 dflags <- io getDynFlags
568 (new_cmstate, maybe_hv) <- io (cmCompileExpr cms dflags new_expr)
569 setCmState new_cmstate
572 Just hv -> io (writeIORef commands --
573 ((macro_name, keepGoing (runMacro hv)) : cmds))
575 runMacro :: HValue{-String -> IO String-} -> String -> GHCi ()
577 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
578 stringLoop (lines str)
580 undefineMacro :: String -> GHCi ()
581 undefineMacro macro_name = do
582 cmds <- io (readIORef commands)
583 if (macro_name `elem` map fst builtin_commands)
584 then throwDyn (CmdLineError
585 ("command `" ++ macro_name ++ "' cannot be undefined"))
587 if (macro_name `notElem` map fst cmds)
588 then throwDyn (CmdLineError
589 ("command `" ++ macro_name ++ "' not defined"))
591 io (writeIORef commands (filter ((/= macro_name) . fst) cmds))
594 loadModule :: String -> GHCi ()
595 loadModule str = timeIt (loadModule' str)
598 let files = words str
599 state <- getGHCiState
600 dflags <- io getDynFlags
602 -- do the dependency anal first, so that if it fails we don't throw
603 -- away the current set of modules.
604 graph <- io (cmDepAnal (cmstate state) dflags files)
606 -- Dependency anal ok, now unload everything
607 cmstate1 <- io (cmUnload (cmstate state) dflags)
608 setGHCiState state{ cmstate = cmstate1, targets = [] }
610 io (revertCAFs) -- always revert CAFs on load.
611 (cmstate2, ok, mods) <- io (cmLoadModules cmstate1 dflags graph)
612 setGHCiState state{ cmstate = cmstate2, targets = files }
614 setContextAfterLoad mods
615 modulesLoadedMsg ok mods dflags
618 reloadModule :: String -> GHCi ()
620 state <- getGHCiState
621 dflags <- io getDynFlags
622 case targets state of
623 [] -> io (putStr "no current target\n")
625 -- do the dependency anal first, so that if it fails we don't throw
626 -- away the current set of modules.
627 graph <- io (cmDepAnal (cmstate state) dflags paths)
629 io (revertCAFs) -- always revert CAFs on reload.
631 <- io (cmLoadModules (cmstate state) dflags graph)
632 setGHCiState state{ cmstate=cmstate1 }
633 setContextAfterLoad mods
634 modulesLoadedMsg ok mods dflags
636 reloadModule _ = noArgs ":reload"
638 setContextAfterLoad [] = setContext prel
639 setContextAfterLoad (m:_) = do
640 cmstate <- getCmState
641 b <- io (cmModuleIsInterpreted cmstate m)
642 if b then setContext ('*':m) else setContext m
644 modulesLoadedMsg ok mods dflags =
645 when (verbosity dflags > 0) $ do
647 | null mods = text "none."
649 punctuate comma (map text mods)) <> text "."
652 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
654 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
657 typeOfExpr :: String -> GHCi ()
659 = do cms <- getCmState
660 dflags <- io getDynFlags
661 (new_cmstate, maybe_tystr) <- io (cmTypeOfExpr cms dflags str)
662 setCmState new_cmstate
665 Just tystr -> io (putStrLn tystr)
667 quit :: String -> GHCi Bool
670 shellEscape :: String -> GHCi Bool
671 shellEscape str = io (system str >> return False)
673 -----------------------------------------------------------------------------
674 -- Browing a module's contents
676 browseCmd :: String -> GHCi ()
679 ['*':m] | looksLikeModuleName m -> browseModule m False
680 [m] | looksLikeModuleName m -> browseModule m True
681 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
683 browseModule m exports_only = do
685 dflags <- io getDynFlags
687 is_interpreted <- io (cmModuleIsInterpreted cms m)
688 when (not is_interpreted && not exports_only) $
689 throwDyn (CmdLineError ("module `" ++ m ++ "' is not interpreted"))
691 -- temporarily set the context to the module we're interested in,
692 -- just so we can get an appropriate PrintUnqualified
693 (as,bs) <- io (cmGetContext cms)
694 cms1 <- io (if exports_only then cmSetContext cms dflags [] [prel,m]
695 else cmSetContext cms dflags [m] [])
696 cms2 <- io (cmSetContext cms1 dflags as bs)
698 (cms3, things) <- io (cmBrowseModule cms2 dflags m exports_only)
702 let unqual = cmGetPrintUnqual cms1 -- NOTE: cms1 with the new context
704 things' = filter wantToSee things
706 wantToSee (AnId id) = not (isImplicitId id)
707 wantToSee (ADataCon _) = False -- They'll come via their TyCon
710 thing_names = map getName things
712 thingDecl thing@(AnId id) = ifaceTyThing thing
714 thingDecl thing@(AClass c) =
715 let rn_decl = ifaceTyThing thing in
717 ClassDecl { tcdSigs = cons } ->
718 rn_decl{ tcdSigs = filter methodIsVisible cons }
721 methodIsVisible (ClassOpSig n _ _ _) = n `elem` thing_names
723 thingDecl thing@(ATyCon t) =
724 let rn_decl = ifaceTyThing thing in
726 TyData { tcdCons = DataCons cons } ->
727 rn_decl{ tcdCons = DataCons (filter conIsVisible cons) }
730 conIsVisible (ConDecl n _ _ _ _) = n `elem` thing_names
732 io (putStrLn (showSDocForUser unqual (
733 vcat (map (ppr . thingDecl) things')))
738 -----------------------------------------------------------------------------
739 -- Setting the module context
742 | all sensible mods = fn mods
743 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
745 (fn, mods) = case str of
746 '+':stuff -> (addToContext, words stuff)
747 '-':stuff -> (removeFromContext, words stuff)
748 stuff -> (newContext, words stuff)
750 sensible ('*':m) = looksLikeModuleName m
751 sensible m = looksLikeModuleName m
755 dflags <- io getDynFlags
756 (as,bs) <- separate cms mods [] []
757 let bs' = if null as && prel `notElem` bs then prel:bs else bs
758 cms' <- io (cmSetContext cms dflags as bs')
761 separate cmstate [] as bs = return (as,bs)
762 separate cmstate (('*':m):ms) as bs = do
763 b <- io (cmModuleIsInterpreted cmstate m)
764 if b then separate cmstate ms (m:as) bs
765 else throwDyn (CmdLineError ("module `" ++ m ++ "' is not interpreted"))
766 separate cmstate (m:ms) as bs = separate cmstate ms as (m:bs)
771 addToContext mods = do
773 dflags <- io getDynFlags
774 (as,bs) <- io (cmGetContext cms)
776 (as',bs') <- separate cms mods [] []
778 let as_to_add = as' \\ (as ++ bs)
779 bs_to_add = bs' \\ (as ++ bs)
781 cms' <- io (cmSetContext cms dflags
782 (as ++ as_to_add) (bs ++ bs_to_add))
786 removeFromContext mods = do
788 dflags <- io getDynFlags
789 (as,bs) <- io (cmGetContext cms)
791 (as_to_remove,bs_to_remove) <- separate cms mods [] []
793 let as' = as \\ (as_to_remove ++ bs_to_remove)
794 bs' = bs \\ (as_to_remove ++ bs_to_remove)
796 cms' <- io (cmSetContext cms dflags as' bs')
799 ----------------------------------------------------------------------------
802 -- set options in the interpreter. Syntax is exactly the same as the
803 -- ghc command line, except that certain options aren't available (-C,
806 -- This is pretty fragile: most options won't work as expected. ToDo:
807 -- figure out which ones & disallow them.
809 setCmd :: String -> GHCi ()
811 = do st <- getGHCiState
812 let opts = options st
813 io $ putStrLn (showSDoc (
814 text "options currently set: " <>
817 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
821 ("args":args) -> setArgs args
822 ("prog":prog) -> setProg prog
823 wds -> setOptions wds
827 setGHCiState st{ args = args }
831 setGHCiState st{ progname = prog }
833 io (hPutStrLn stderr "syntax: :set prog <progname>")
836 do -- first, deal with the GHCi opts (+s, +t, etc.)
837 let (plus_opts, minus_opts) = partition isPlus wds
838 mapM_ setOpt plus_opts
840 -- now, the GHC flags
841 pkgs_before <- io (readIORef v_ExplicitPackages)
842 leftovers <- io (processArgs static_flags minus_opts [])
843 pkgs_after <- io (readIORef v_ExplicitPackages)
845 -- update things if the users wants more packages
846 let new_packages = pkgs_after \\ pkgs_before
847 when (not (null new_packages)) $
848 newPackages new_packages
850 -- don't forget about the extra command-line flags from the
851 -- extra_ghc_opts fields in the new packages
852 new_package_details <- io (getPackageDetails new_packages)
853 let pkg_extra_opts = concatMap extra_ghc_opts new_package_details
854 pkg_extra_dyn <- io (processArgs static_flags pkg_extra_opts [])
856 -- then, dynamic flags
859 leftovers <- processArgs dynamic_flags (leftovers ++ pkg_extra_dyn) []
862 if (not (null leftovers))
863 then throwDyn (CmdLineError ("unrecognised flags: " ++
868 unsetOptions :: String -> GHCi ()
870 = do -- first, deal with the GHCi opts (+s, +t, etc.)
872 (minus_opts, rest1) = partition isMinus opts
873 (plus_opts, rest2) = partition isPlus rest1
875 if (not (null rest2))
876 then io (putStrLn ("unknown option: `" ++ head rest2 ++ "'"))
879 mapM_ unsetOpt plus_opts
881 -- can't do GHC flags for now
882 if (not (null minus_opts))
883 then throwDyn (CmdLineError "can't unset GHC command-line flags")
886 isMinus ('-':s) = True
889 isPlus ('+':s) = True
893 = case strToGHCiOpt str of
894 Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
895 Just o -> setOption o
898 = case strToGHCiOpt str of
899 Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
900 Just o -> unsetOption o
902 strToGHCiOpt :: String -> (Maybe GHCiOption)
903 strToGHCiOpt "s" = Just ShowTiming
904 strToGHCiOpt "t" = Just ShowType
905 strToGHCiOpt "r" = Just RevertCAFs
906 strToGHCiOpt _ = Nothing
908 optToStr :: GHCiOption -> String
909 optToStr ShowTiming = "s"
910 optToStr ShowType = "t"
911 optToStr RevertCAFs = "r"
913 newPackages new_pkgs = do -- The new packages are already in v_Packages
914 state <- getGHCiState
915 dflags <- io getDynFlags
916 cmstate1 <- io (cmUnload (cmstate state) dflags)
917 setGHCiState state{ cmstate = cmstate1, targets = [] }
918 io (linkPackages dflags new_pkgs)
919 setContextAfterLoad []
921 -- ---------------------------------------------------------------------------
926 ["modules" ] -> showModules
927 ["bindings"] -> showBindings
928 ["linker"] -> io showLinkerState
929 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
933 let (mg, hpt) = cmGetModInfo cms
934 mapM_ (showModule hpt) mg
937 showModule :: HomePackageTable -> ModSummary -> GHCi ()
938 showModule hpt mod_summary
939 = case lookupModuleEnv hpt mod of
940 Nothing -> panic "missing linkable"
941 Just mod_info -> io (putStrLn (showModMsg obj_linkable mod locn))
943 obj_linkable = isObjectLinkable (hm_linkable mod_info)
945 mod = ms_mod mod_summary
946 locn = ms_location mod_summary
951 unqual = cmGetPrintUnqual cms
952 showBinding b = putStrLn (showSDocForUser unqual (ppr (ifaceTyThing b)))
954 io (mapM_ showBinding (cmGetBindings cms))
958 -----------------------------------------------------------------------------
961 data GHCiState = GHCiState
965 targets :: [FilePath],
967 options :: [GHCiOption]
971 = ShowTiming -- show time/allocs after evaluation
972 | ShowType -- show the type of expressions
973 | RevertCAFs -- revert CAFs after every evaluation
976 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
978 startGHCi :: GHCi a -> GHCiState -> IO a
979 startGHCi g state = do ref <- newIORef state; unGHCi g ref
981 instance Monad GHCi where
982 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
983 return a = GHCi $ \s -> return a
985 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
986 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
987 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
989 getGHCiState = GHCi $ \r -> readIORef r
990 setGHCiState s = GHCi $ \r -> writeIORef r s
992 -- for convenience...
993 getCmState = getGHCiState >>= return . cmstate
994 setCmState cms = do s <- getGHCiState; setGHCiState s{cmstate=cms}
996 isOptionSet :: GHCiOption -> GHCi Bool
998 = do st <- getGHCiState
999 return (opt `elem` options st)
1001 setOption :: GHCiOption -> GHCi ()
1003 = do st <- getGHCiState
1004 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
1006 unsetOption :: GHCiOption -> GHCi ()
1008 = do st <- getGHCiState
1009 setGHCiState (st{ options = filter (/= opt) (options st) })
1011 io :: IO a -> GHCi a
1012 io m = GHCi { unGHCi = \s -> m >>= return }
1014 -----------------------------------------------------------------------------
1015 -- recursive exception handlers
1017 -- Don't forget to unblock async exceptions in the handler, or if we're
1018 -- in an exception loop (eg. let a = error a in a) the ^C exception
1019 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1021 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1022 ghciHandle h (GHCi m) = GHCi $ \s ->
1023 Exception.catch (m s)
1024 (\e -> unGHCi (ghciUnblock (h e)) s)
1026 ghciUnblock :: GHCi a -> GHCi a
1027 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1029 -----------------------------------------------------------------------------
1030 -- timing & statistics
1032 timeIt :: GHCi a -> GHCi a
1034 = do b <- isOptionSet ShowTiming
1037 else do allocs1 <- io $ getAllocations
1038 time1 <- io $ getCPUTime
1040 allocs2 <- io $ getAllocations
1041 time2 <- io $ getCPUTime
1042 io $ printTimes (allocs2 - allocs1) (time2 - time1)
1045 foreign import ccall "getAllocations" getAllocations :: IO Int
1047 printTimes :: Int -> Integer -> IO ()
1048 printTimes allocs psecs
1049 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1050 secs_str = showFFloat (Just 2) secs
1051 putStrLn (showSDoc (
1052 parens (text (secs_str "") <+> text "secs" <> comma <+>
1053 int allocs <+> text "bytes")))
1055 -----------------------------------------------------------------------------
1062 -- Have to turn off buffering again, because we just
1063 -- reverted stdout, stderr & stdin to their defaults.
1065 foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
1066 -- Make it "safe", just in case