1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
3 -- $Id: InteractiveUI.hs,v 1.158 2003/08/27 12:29:21 simonmar Exp $
5 -- GHC Interactive User Interface
7 -- (c) The GHC Team 2000
9 -----------------------------------------------------------------------------
10 module InteractiveUI (
11 interactiveUI, -- :: CmState -> [FilePath] -> IO ()
15 #include "../includes/config.h"
16 #include "HsVersions.h"
19 import HscTypes ( TyThing(..), HomeModInfo(hm_linkable), HomePackageTable,
20 isObjectLinkable, GhciMode(..) )
21 import HsSyn ( TyClDecl(..), ConDecl(..), Sig(..) )
22 import MkIface ( ifaceTyThing )
25 import DriverUtil ( remove_spaces )
26 import Linker ( showLinkerState, linkPackages )
28 import IdInfo ( GlobalIdDetails(..) )
29 import Id ( isImplicitId, idName, globalIdDetails )
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 hiding ( showException )
47 #ifndef mingw32_HOST_OS
48 import DriverUtil( handle )
50 #if __GLASGOW_HASKELL__ > 504
55 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
56 import Control.Concurrent ( yield ) -- Used in readline loop
57 import System.Console.Readline as Readline
62 import Control.Exception as Exception
64 import Control.Concurrent
70 import System.Environment
71 import System.Directory
72 import System.IO as IO
74 import Control.Monad as Monad
76 import GHC.Exts ( unsafeCoerce# )
78 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
80 import System.Posix.Internals ( setNonBlockingFD )
82 -----------------------------------------------------------------------------
86 \ / _ \\ /\\ /\\/ __(_)\n\
87 \ / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n\
88 \/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n\
89 \\\____/\\/ /_/\\____/|_| Type :? for help.\n"
91 GLOBAL_VAR(commands, builtin_commands, [(String, String -> GHCi Bool)])
93 builtin_commands :: [(String, String -> GHCi Bool)]
95 ("add", keepGoingPaths addModule),
96 ("browse", keepGoing browseCmd),
97 ("cd", keepGoing changeDirectory),
98 ("def", keepGoing defineMacro),
99 ("help", keepGoing help),
100 ("?", keepGoing help),
101 ("info", keepGoing info),
102 ("load", keepGoingPaths loadModule),
103 ("module", keepGoing setContext),
104 ("reload", keepGoing reloadModule),
105 ("set", keepGoing setCmd),
106 ("show", keepGoing showCmd),
107 ("type", keepGoing typeOfExpr),
108 ("unset", keepGoing unsetOptions),
109 ("undef", keepGoing undefineMacro),
113 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
114 keepGoing a str = a str >> return False
116 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
117 keepGoingPaths a str = a (toArgs str) >> return False
119 shortHelpText = "use :? for help.\n"
121 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
123 \ Commands available from the prompt:\n\
125 \ <stmt> evaluate/run <stmt>\n\
126 \ :add <filename> ... add module(s) to the current target set\n\
127 \ :browse [*]<module> display the names defined by <module>\n\
128 \ :cd <dir> change directory to <dir>\n\
129 \ :def <cmd> <expr> define a command :<cmd>\n\
130 \ :help, :? display this list of commands\n\
131 \ :info [<name> ...] display information about the given names\n\
132 \ :load <filename> ... load module(s) and their dependents\n\
133 \ :module [+/-] [*]<mod> ... set the context for expression evaluation\n\
134 \ :reload reload the current module set\n\
136 \ :set <option> ... set options\n\
137 \ :set args <arg> ... set the arguments returned by System.getArgs\n\
138 \ :set prog <progname> set the value returned by System.getProgName\n\
140 \ :show modules show the currently loaded modules\n\
141 \ :show bindings show the current bindings made at the prompt\n\
143 \ :type <expr> show the type of <expr>\n\
144 \ :undef <cmd> undefine user-defined command :<cmd>\n\
145 \ :unset <option> ... unset options\n\
147 \ :!<command> run the shell command <command>\n\
149 \ Options for `:set' and `:unset':\n\
151 \ +r revert top-level expressions after each evaluation\n\
152 \ +s print timing/memory stats after each evaluation\n\
153 \ +t print type after evaluation\n\
154 \ -<flags> most GHC command line flags can also be set here\n\
155 \ (eg. -v2, -fglasgow-exts, etc.)\n\
158 interactiveUI :: [FilePath] -> IO ()
159 interactiveUI srcs = do
160 dflags <- getDynFlags
162 cmstate <- cmInit Interactive;
165 hSetBuffering stdout NoBuffering
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 srcs 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 $
232 -- if verbosity is greater than 0, or we are connected to a
233 -- terminal, display the prompt in the interactive loop.
234 is_tty <- io (hIsTerminalDevice stdin)
235 let show_prompt = verbosity dflags > 0 || is_tty
237 -- enter the interactive loop
238 interactiveLoop is_tty show_prompt
241 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
244 interactiveLoop is_tty show_prompt = do
245 -- Ignore ^C exceptions caught here
246 ghciHandleDyn (\e -> case e of
247 Interrupted -> ghciUnblock (interactiveLoop is_tty show_prompt)
248 _other -> return ()) $ do
250 -- read commands from stdin
251 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
254 else fileLoop stdin show_prompt
256 fileLoop stdin show_prompt
260 -- NOTE: We only read .ghci files if they are owned by the current user,
261 -- and aren't world writable. Otherwise, we could be accidentally
262 -- running code planted by a malicious third party.
264 -- Furthermore, We only read ./.ghci if . is owned by the current user
265 -- and isn't writable by anyone else. I think this is sufficient: we
266 -- don't need to check .. and ../.. etc. because "." always refers to
267 -- the same directory while a process is running.
269 checkPerms :: String -> IO Bool
271 #ifdef mingw32_HOST_OS
274 DriverUtil.handle (\_ -> return False) $ do
275 st <- getFileStatus name
277 if fileOwner st /= me then do
278 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
281 let mode = fileMode st
282 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
283 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
285 putStrLn $ "*** WARNING: " ++ name ++
286 " is writable by someone else, IGNORING!"
291 fileLoop :: Handle -> Bool -> GHCi ()
292 fileLoop hdl prompt = do
293 cmstate <- getCmState
294 (mod,imports) <- io (cmGetContext cmstate)
295 when prompt (io (putStr (mkPrompt mod imports)))
296 l <- io (IO.try (hGetLine hdl))
298 Left e | isEOFError e -> return ()
299 | otherwise -> io (ioError e)
301 case remove_spaces l of
302 "" -> fileLoop hdl prompt
303 l -> do quit <- runCommand l
304 if quit then return () else fileLoop hdl prompt
306 stringLoop :: [String] -> GHCi ()
307 stringLoop [] = return ()
308 stringLoop (s:ss) = do
309 case remove_spaces s of
311 l -> do quit <- runCommand l
312 if quit then return () else stringLoop ss
314 mkPrompt toplevs exports
315 = concat (intersperse " " (map ('*':) toplevs ++ exports)) ++ "> "
317 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
318 readlineLoop :: GHCi ()
320 cmstate <- getCmState
321 (mod,imports) <- io (cmGetContext cmstate)
323 l <- io (readline (mkPrompt mod imports)
324 `finally` setNonBlockingFD 0)
325 -- readline sometimes puts stdin into blocking mode,
326 -- so we need to put it back for the IO library
330 case remove_spaces l of
335 if quit then return () else readlineLoop
338 runCommand :: String -> GHCi Bool
339 runCommand c = ghciHandle handler (doCommand c)
341 -- This is the exception handler for exceptions generated by the
342 -- user's code; it normally just prints out the exception. The
343 -- handler must be recursive, in case showing the exception causes
344 -- more exceptions to be raised.
346 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
347 -- raising another exception. We therefore don't put the recursive
348 -- handler arond the flushing operation, so if stderr is closed
349 -- GHCi will just die gracefully rather than going into an infinite loop.
350 handler :: Exception -> GHCi Bool
351 handler exception = do
353 io installSignalHandlers
354 ghciHandle handler (showException exception >> return False)
356 showException (DynException dyn) =
357 case fromDynamic dyn of
358 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
359 Just Interrupted -> io (putStrLn "Interrupted.")
360 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
361 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
362 Just other_ghc_ex -> io (print other_ghc_ex)
364 showException other_exception
365 = io (putStrLn ("*** Exception: " ++ show other_exception))
367 doCommand (':' : command) = specialCommand command
369 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
372 runStmt :: String -> GHCi [Name]
374 | null (filter (not.isSpace) stmt) = return []
376 = do st <- getGHCiState
377 dflags <- io getDynFlags
378 let dflags' = dopt_unset dflags Opt_WarnUnusedBinds
379 (new_cmstate, result) <-
380 io $ withProgName (progname st) $ withArgs (args st) $
381 cmRunStmt (cmstate st) dflags' stmt
382 setGHCiState st{cmstate = new_cmstate}
384 CmRunFailed -> return []
385 CmRunException e -> showException e >> return []
386 CmRunOk names -> return names
388 -- possibly print the type and revert CAFs after evaluating an expression
390 = do b <- isOptionSet ShowType
391 cmstate <- getCmState
392 when b (mapM_ (showTypeOfName cmstate) names)
395 io installSignalHandlers
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 = case globalIdDetails id of
512 RecordSelId lbl -> text "record selector for type" <+> ppr (fieldLabelTyCon lbl)
513 ClassOpId cls -> text "method in class" <+> ppr cls
514 otherwise -> text "variable"
516 -- also print out the source location for home things
518 | isHomePackageName name && isGoodSrcLoc loc
519 = hsep [ text ", defined at", ppr loc ]
522 where loc = nameSrcLoc name
524 cms <- infoThings init_cms names
528 addModule :: [FilePath] -> GHCi ()
530 state <- getGHCiState
531 dflags <- io (getDynFlags)
532 io (revertCAFs) -- always revert CAFs on load/add.
533 files <- mapM expandPath files
534 let new_targets = files ++ targets state
535 graph <- io (cmDepAnal (cmstate state) dflags new_targets)
536 (cmstate1, ok, mods) <- io (cmLoadModules (cmstate state) dflags graph)
537 setGHCiState state{ cmstate = cmstate1, targets = new_targets }
538 setContextAfterLoad mods
539 modulesLoadedMsg ok mods dflags
541 changeDirectory :: String -> GHCi ()
542 changeDirectory dir = do
543 state <- getGHCiState
544 when (targets state /= []) $
545 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded, \n\
546 \because the search path has changed.\n"
547 dflags <- io getDynFlags
548 cmstate1 <- io (cmUnload (cmstate state) dflags)
549 setGHCiState state{ cmstate = cmstate1, targets = [] }
550 setContextAfterLoad []
551 dir <- expandPath dir
552 io (setCurrentDirectory dir)
554 defineMacro :: String -> GHCi ()
556 let (macro_name, definition) = break isSpace s
557 cmds <- io (readIORef commands)
559 then throwDyn (CmdLineError "invalid macro name")
561 if (macro_name `elem` map fst cmds)
562 then throwDyn (CmdLineError
563 ("command `" ++ macro_name ++ "' is already defined"))
566 -- give the expression a type signature, so we can be sure we're getting
567 -- something of the right type.
568 let new_expr = '(' : definition ++ ") :: String -> IO String"
570 -- compile the expression
572 dflags <- io getDynFlags
573 (new_cmstate, maybe_hv) <- io (cmCompileExpr cms dflags new_expr)
574 setCmState new_cmstate
577 Just hv -> io (writeIORef commands --
578 ((macro_name, keepGoing (runMacro hv)) : cmds))
580 runMacro :: HValue{-String -> IO String-} -> String -> GHCi ()
582 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
583 stringLoop (lines str)
585 undefineMacro :: String -> GHCi ()
586 undefineMacro macro_name = do
587 cmds <- io (readIORef commands)
588 if (macro_name `elem` map fst builtin_commands)
589 then throwDyn (CmdLineError
590 ("command `" ++ macro_name ++ "' cannot be undefined"))
592 if (macro_name `notElem` map fst cmds)
593 then throwDyn (CmdLineError
594 ("command `" ++ macro_name ++ "' not defined"))
596 io (writeIORef commands (filter ((/= macro_name) . fst) cmds))
599 loadModule :: [FilePath] -> GHCi ()
600 loadModule fs = timeIt (loadModule' fs)
602 loadModule' :: [FilePath] -> GHCi ()
603 loadModule' files = do
604 state <- getGHCiState
605 dflags <- io getDynFlags
608 files <- mapM expandPath files
610 -- do the dependency anal first, so that if it fails we don't throw
611 -- away the current set of modules.
612 graph <- io (cmDepAnal (cmstate state) dflags files)
614 -- Dependency anal ok, now unload everything
615 cmstate1 <- io (cmUnload (cmstate state) dflags)
616 setGHCiState state{ cmstate = cmstate1, targets = [] }
618 io (revertCAFs) -- always revert CAFs on load.
619 (cmstate2, ok, mods) <- io (cmLoadModules cmstate1 dflags graph)
620 setGHCiState state{ cmstate = cmstate2, targets = files }
622 setContextAfterLoad mods
623 modulesLoadedMsg ok mods dflags
626 reloadModule :: String -> GHCi ()
628 state <- getGHCiState
629 dflags <- io getDynFlags
630 case targets state of
631 [] -> io (putStr "no current target\n")
633 -- do the dependency anal first, so that if it fails we don't throw
634 -- away the current set of modules.
635 graph <- io (cmDepAnal (cmstate state) dflags paths)
637 io (revertCAFs) -- always revert CAFs on reload.
639 <- io (cmLoadModules (cmstate state) dflags graph)
640 setGHCiState state{ cmstate=cmstate1 }
641 setContextAfterLoad mods
642 modulesLoadedMsg ok mods dflags
644 reloadModule _ = noArgs ":reload"
646 setContextAfterLoad [] = setContext prel
647 setContextAfterLoad (m:_) = do
648 cmstate <- getCmState
649 b <- io (cmModuleIsInterpreted cmstate m)
650 if b then setContext ('*':m) else setContext m
652 modulesLoadedMsg ok mods dflags =
653 when (verbosity dflags > 0) $ do
655 | null mods = text "none."
657 punctuate comma (map text mods)) <> text "."
660 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
662 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
665 typeOfExpr :: String -> GHCi ()
667 = do cms <- getCmState
668 dflags <- io getDynFlags
669 (new_cmstate, maybe_tystr) <- io (cmTypeOfExpr cms dflags str)
670 setCmState new_cmstate
673 Just tystr -> io (putStrLn tystr)
675 quit :: String -> GHCi Bool
678 shellEscape :: String -> GHCi Bool
679 shellEscape str = io (system str >> return False)
681 -----------------------------------------------------------------------------
682 -- Browing a module's contents
684 browseCmd :: String -> GHCi ()
687 ['*':m] | looksLikeModuleName m -> browseModule m False
688 [m] | looksLikeModuleName m -> browseModule m True
689 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
691 browseModule m exports_only = do
693 dflags <- io getDynFlags
695 is_interpreted <- io (cmModuleIsInterpreted cms m)
696 when (not is_interpreted && not exports_only) $
697 throwDyn (CmdLineError ("module `" ++ m ++ "' is not interpreted"))
699 -- temporarily set the context to the module we're interested in,
700 -- just so we can get an appropriate PrintUnqualified
701 (as,bs) <- io (cmGetContext cms)
702 cms1 <- io (if exports_only then cmSetContext cms dflags [] [prel,m]
703 else cmSetContext cms dflags [m] [])
704 cms2 <- io (cmSetContext cms1 dflags as bs)
706 (cms3, things) <- io (cmBrowseModule cms2 dflags m exports_only)
710 let unqual = cmGetPrintUnqual cms1 -- NOTE: cms1 with the new context
712 things' = filter wantToSee things
714 wantToSee (AnId id) = not (isImplicitId id)
715 wantToSee (ADataCon _) = False -- They'll come via their TyCon
718 thing_names = map getName things
720 thingDecl thing@(AnId id) = ifaceTyThing thing
722 thingDecl thing@(AClass c) =
723 let rn_decl = ifaceTyThing thing in
725 ClassDecl { tcdSigs = cons } ->
726 rn_decl{ tcdSigs = filter methodIsVisible cons }
729 methodIsVisible (ClassOpSig n _ _ _) = n `elem` thing_names
731 thingDecl thing@(ATyCon t) =
732 let rn_decl = ifaceTyThing thing in
734 TyData { tcdCons = DataCons cons } ->
735 rn_decl{ tcdCons = DataCons (filter conIsVisible cons) }
738 conIsVisible (ConDecl n _ _ _ _) = n `elem` thing_names
740 io (putStrLn (showSDocForUser unqual (
741 vcat (map (ppr . thingDecl) things')))
746 -----------------------------------------------------------------------------
747 -- Setting the module context
750 | all sensible mods = fn mods
751 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
753 (fn, mods) = case str of
754 '+':stuff -> (addToContext, words stuff)
755 '-':stuff -> (removeFromContext, words stuff)
756 stuff -> (newContext, words stuff)
758 sensible ('*':m) = looksLikeModuleName m
759 sensible m = looksLikeModuleName m
763 dflags <- io getDynFlags
764 (as,bs) <- separate cms mods [] []
765 let bs' = if null as && prel `notElem` bs then prel:bs else bs
766 cms' <- io (cmSetContext cms dflags as bs')
769 separate cmstate [] as bs = return (as,bs)
770 separate cmstate (('*':m):ms) as bs = do
771 b <- io (cmModuleIsInterpreted cmstate m)
772 if b then separate cmstate ms (m:as) bs
773 else throwDyn (CmdLineError ("module `" ++ m ++ "' is not interpreted"))
774 separate cmstate (m:ms) as bs = separate cmstate ms as (m:bs)
779 addToContext mods = do
781 dflags <- io getDynFlags
782 (as,bs) <- io (cmGetContext cms)
784 (as',bs') <- separate cms mods [] []
786 let as_to_add = as' \\ (as ++ bs)
787 bs_to_add = bs' \\ (as ++ bs)
789 cms' <- io (cmSetContext cms dflags
790 (as ++ as_to_add) (bs ++ bs_to_add))
794 removeFromContext mods = do
796 dflags <- io getDynFlags
797 (as,bs) <- io (cmGetContext cms)
799 (as_to_remove,bs_to_remove) <- separate cms mods [] []
801 let as' = as \\ (as_to_remove ++ bs_to_remove)
802 bs' = bs \\ (as_to_remove ++ bs_to_remove)
804 cms' <- io (cmSetContext cms dflags as' bs')
807 ----------------------------------------------------------------------------
810 -- set options in the interpreter. Syntax is exactly the same as the
811 -- ghc command line, except that certain options aren't available (-C,
814 -- This is pretty fragile: most options won't work as expected. ToDo:
815 -- figure out which ones & disallow them.
817 setCmd :: String -> GHCi ()
819 = do st <- getGHCiState
820 let opts = options st
821 io $ putStrLn (showSDoc (
822 text "options currently set: " <>
825 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
829 ("args":args) -> setArgs args
830 ("prog":prog) -> setProg prog
831 wds -> setOptions wds
835 setGHCiState st{ args = args }
839 setGHCiState st{ progname = prog }
841 io (hPutStrLn stderr "syntax: :set prog <progname>")
844 do -- first, deal with the GHCi opts (+s, +t, etc.)
845 let (plus_opts, minus_opts) = partition isPlus wds
846 mapM_ setOpt plus_opts
848 -- now, the GHC flags
849 pkgs_before <- io (readIORef v_ExplicitPackages)
850 leftovers <- io (processArgs static_flags minus_opts [])
851 pkgs_after <- io (readIORef v_ExplicitPackages)
853 -- update things if the users wants more packages
854 let new_packages = pkgs_after \\ pkgs_before
855 when (not (null new_packages)) $
856 newPackages new_packages
858 -- don't forget about the extra command-line flags from the
859 -- extra_ghc_opts fields in the new packages
860 new_package_details <- io (getPackageDetails new_packages)
861 let pkg_extra_opts = concatMap extra_ghc_opts new_package_details
862 pkg_extra_dyn <- io (processArgs static_flags pkg_extra_opts [])
864 -- then, dynamic flags
867 leftovers <- processArgs dynamic_flags (leftovers ++ pkg_extra_dyn) []
870 if (not (null leftovers))
871 then throwDyn (CmdLineError ("unrecognised flags: " ++
876 unsetOptions :: String -> GHCi ()
878 = do -- first, deal with the GHCi opts (+s, +t, etc.)
880 (minus_opts, rest1) = partition isMinus opts
881 (plus_opts, rest2) = partition isPlus rest1
883 if (not (null rest2))
884 then io (putStrLn ("unknown option: `" ++ head rest2 ++ "'"))
887 mapM_ unsetOpt plus_opts
889 -- can't do GHC flags for now
890 if (not (null minus_opts))
891 then throwDyn (CmdLineError "can't unset GHC command-line flags")
894 isMinus ('-':s) = True
897 isPlus ('+':s) = True
901 = case strToGHCiOpt str of
902 Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
903 Just o -> setOption o
906 = case strToGHCiOpt str of
907 Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
908 Just o -> unsetOption o
910 strToGHCiOpt :: String -> (Maybe GHCiOption)
911 strToGHCiOpt "s" = Just ShowTiming
912 strToGHCiOpt "t" = Just ShowType
913 strToGHCiOpt "r" = Just RevertCAFs
914 strToGHCiOpt _ = Nothing
916 optToStr :: GHCiOption -> String
917 optToStr ShowTiming = "s"
918 optToStr ShowType = "t"
919 optToStr RevertCAFs = "r"
921 newPackages new_pkgs = do -- The new packages are already in v_Packages
922 state <- getGHCiState
923 dflags <- io getDynFlags
924 cmstate1 <- io (cmUnload (cmstate state) dflags)
925 setGHCiState state{ cmstate = cmstate1, targets = [] }
926 io (linkPackages dflags new_pkgs)
927 setContextAfterLoad []
929 -- ---------------------------------------------------------------------------
934 ["modules" ] -> showModules
935 ["bindings"] -> showBindings
936 ["linker"] -> io showLinkerState
937 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
941 let (mg, hpt) = cmGetModInfo cms
942 mapM_ (showModule hpt) mg
945 showModule :: HomePackageTable -> ModSummary -> GHCi ()
946 showModule hpt mod_summary
947 = case lookupModuleEnv hpt mod of
948 Nothing -> panic "missing linkable"
949 Just mod_info -> io (putStrLn (showModMsg obj_linkable mod locn))
951 obj_linkable = isObjectLinkable (hm_linkable mod_info)
953 mod = ms_mod mod_summary
954 locn = ms_location mod_summary
959 unqual = cmGetPrintUnqual cms
960 showBinding b = putStrLn (showSDocForUser unqual (ppr (ifaceTyThing b)))
962 io (mapM_ showBinding (cmGetBindings cms))
966 -----------------------------------------------------------------------------
969 data GHCiState = GHCiState
973 targets :: [FilePath],
975 options :: [GHCiOption]
979 = ShowTiming -- show time/allocs after evaluation
980 | ShowType -- show the type of expressions
981 | RevertCAFs -- revert CAFs after every evaluation
984 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
986 startGHCi :: GHCi a -> GHCiState -> IO a
987 startGHCi g state = do ref <- newIORef state; unGHCi g ref
989 instance Monad GHCi where
990 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
991 return a = GHCi $ \s -> return a
993 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
994 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
995 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
997 getGHCiState = GHCi $ \r -> readIORef r
998 setGHCiState s = GHCi $ \r -> writeIORef r s
1000 -- for convenience...
1001 getCmState = getGHCiState >>= return . cmstate
1002 setCmState cms = do s <- getGHCiState; setGHCiState s{cmstate=cms}
1004 isOptionSet :: GHCiOption -> GHCi Bool
1006 = do st <- getGHCiState
1007 return (opt `elem` options st)
1009 setOption :: GHCiOption -> GHCi ()
1011 = do st <- getGHCiState
1012 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
1014 unsetOption :: GHCiOption -> GHCi ()
1016 = do st <- getGHCiState
1017 setGHCiState (st{ options = filter (/= opt) (options st) })
1019 io :: IO a -> GHCi a
1020 io m = GHCi { unGHCi = \s -> m >>= return }
1022 -----------------------------------------------------------------------------
1023 -- recursive exception handlers
1025 -- Don't forget to unblock async exceptions in the handler, or if we're
1026 -- in an exception loop (eg. let a = error a in a) the ^C exception
1027 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1029 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1030 ghciHandle h (GHCi m) = GHCi $ \s ->
1031 Exception.catch (m s)
1032 (\e -> unGHCi (ghciUnblock (h e)) s)
1034 ghciUnblock :: GHCi a -> GHCi a
1035 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1037 -----------------------------------------------------------------------------
1038 -- timing & statistics
1040 timeIt :: GHCi a -> GHCi a
1042 = do b <- isOptionSet ShowTiming
1045 else do allocs1 <- io $ getAllocations
1046 time1 <- io $ getCPUTime
1048 allocs2 <- io $ getAllocations
1049 time2 <- io $ getCPUTime
1050 io $ printTimes (allocs2 - allocs1) (time2 - time1)
1053 foreign import ccall "getAllocations" getAllocations :: IO Int
1055 printTimes :: Int -> Integer -> IO ()
1056 printTimes allocs psecs
1057 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1058 secs_str = showFFloat (Just 2) secs
1059 putStrLn (showSDoc (
1060 parens (text (secs_str "") <+> text "secs" <> comma <+>
1061 int allocs <+> text "bytes")))
1063 -----------------------------------------------------------------------------
1070 -- Have to turn off buffering again, because we just
1071 -- reverted stdout, stderr & stdin to their defaults.
1073 foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
1074 -- Make it "safe", just in case
1076 -- -----------------------------------------------------------------------------
1079 expandPath :: String -> GHCi String
1081 case dropWhile isSpace path of
1083 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1084 return (tilde ++ '/':d)