1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
3 -- $Id: InteractiveUI.hs,v 1.190 2005/02/23 15:38:52 simonmar Exp $
5 -- GHC Interactive User Interface
7 -- (c) The GHC Team 2004
9 -----------------------------------------------------------------------------
10 module InteractiveUI (
11 interactiveUI, -- :: CmState -> [FilePath] -> IO ()
15 #include "HsVersions.h"
18 import HscTypes ( GhciMode(..) )
19 import IfaceSyn ( IfaceDecl(..), IfaceClassOp(..), IfaceConDecls(..),
20 IfaceConDecl(..), IfaceType,
21 IfaceInst(..), pprIfaceDeclHead, pprParendIfaceType,
22 pprIfaceForAllPart, pprIfaceType )
23 import FunDeps ( pprFundeps )
26 import DriverUtil ( remove_spaces )
27 import Linker ( showLinkerState, linkPackages )
29 import Name ( Name, NamedThing(..) )
30 import OccName ( OccName, isSymOcc, occNameUserString )
31 import BasicTypes ( StrictnessMark(..), defaultFixity, SuccessFlag(..) )
33 import CmdLineOpts ( DynFlags(..), DynFlag(..), dopt )
34 import Panic hiding ( showException )
36 import SrcLoc ( SrcLoc, isGoodSrcLoc )
38 #ifndef mingw32_HOST_OS
39 import DriverUtil( handle )
41 #if __GLASGOW_HASKELL__ > 504
47 import Control.Concurrent ( yield ) -- Used in readline loop
48 import System.Console.Readline as Readline
53 import Control.Exception as Exception
55 -- import Control.Concurrent
59 import Data.Int ( Int64 )
62 import System.Environment
63 import System.Exit ( exitWith, ExitCode(..) )
64 import System.Directory
66 import System.IO.Error as IO
68 import Control.Monad as Monad
69 import Foreign.StablePtr ( newStablePtr )
71 import GHC.Exts ( unsafeCoerce# )
72 import GHC.IOBase ( IOErrorType(InvalidArgument) )
74 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
76 import System.Posix.Internals ( 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", keepGoingPaths 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", keepGoingPaths loadModule),
99 ("module", keepGoing setContext),
100 ("reload", keepGoing reloadModule),
101 ("set", keepGoing setCmd),
102 ("show", keepGoing showCmd),
103 ("type", keepGoing typeOfExpr),
104 ("kind", keepGoing kindOfType),
105 ("unset", keepGoing unsetOptions),
106 ("undef", keepGoing undefineMacro),
110 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
111 keepGoing a str = a str >> return False
113 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
114 keepGoingPaths a str = a (toArgs str) >> return False
116 shortHelpText = "use :? for help.\n"
118 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
120 " Commands available from the prompt:\n" ++
122 " <stmt> evaluate/run <stmt>\n" ++
123 " :add <filename> ... add module(s) to the current target set\n" ++
124 " :browse [*]<module> display the names defined by <module>\n" ++
125 " :cd <dir> change directory to <dir>\n" ++
126 " :def <cmd> <expr> define a command :<cmd>\n" ++
127 " :help, :? display this list of commands\n" ++
128 " :info [<name> ...] display information about the given names\n" ++
129 " :load <filename> ... load module(s) and their dependents\n" ++
130 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
131 " :reload reload the current module set\n" ++
133 " :set <option> ... set options\n" ++
134 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
135 " :set prog <progname> set the value returned by System.getProgName\n" ++
137 " :show modules show the currently loaded modules\n" ++
138 " :show bindings show the current bindings made at the prompt\n" ++
140 " :type <expr> show the type of <expr>\n" ++
141 " :kind <type> show the kind of <type>\n" ++
142 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
143 " :unset <option> ... unset options\n" ++
144 " :quit exit GHCi\n" ++
145 " :!<command> run the shell command <command>\n" ++
147 " Options for ':set' and ':unset':\n" ++
149 " +r revert top-level expressions after each evaluation\n" ++
150 " +s print timing/memory stats after each evaluation\n" ++
151 " +t print type after evaluation\n" ++
152 " -<flags> most GHC command line flags can also be set here\n" ++
153 " (eg. -v2, -fglasgow-exts, etc.)\n"
156 interactiveUI :: DynFlags -> [FilePath] -> Maybe String -> IO ()
157 interactiveUI dflags srcs maybe_expr = do
159 cmstate <- cmInit Interactive dflags;
161 -- HACK! If we happen to get into an infinite loop (eg the user
162 -- types 'let x=x in x' at the prompt), then the thread will block
163 -- on a blackhole, and become unreachable during GC. The GC will
164 -- detect that it is unreachable and send it the NonTermination
165 -- exception. However, since the thread is unreachable, everything
166 -- it refers to might be finalized, including the standard Handles.
167 -- This sounds like a bug, but we don't have a good solution right
174 hSetBuffering stdout NoBuffering
176 -- Initialise buffering for the *interpreted* I/O system
177 initInterpBuffering cmstate
179 -- We don't want the cmd line to buffer any input that might be
180 -- intended for the program, so unbuffer stdin.
181 hSetBuffering stdin NoBuffering
183 -- initial context is just the Prelude
184 cmstate <- cmSetContext cmstate [] ["Prelude"]
190 startGHCi (runGHCi srcs dflags maybe_expr)
191 GHCiState{ progname = "<interactive>",
198 Readline.resetTerminal Nothing
203 runGHCi :: [FilePath] -> DynFlags -> Maybe String -> GHCi ()
204 runGHCi paths dflags maybe_expr = do
205 read_dot_files <- io (readIORef v_Read_DotGHCi)
207 when (read_dot_files) $ do
210 exists <- io (doesFileExist file)
212 dir_ok <- io (checkPerms ".")
213 file_ok <- io (checkPerms file)
214 when (dir_ok && file_ok) $ do
215 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
218 Right hdl -> fileLoop hdl False
220 when (read_dot_files) $ do
221 -- Read in $HOME/.ghci
222 either_dir <- io (IO.try (getEnv "HOME"))
226 cwd <- io (getCurrentDirectory)
227 when (dir /= cwd) $ do
228 let file = dir ++ "/.ghci"
229 ok <- io (checkPerms file)
231 either_hdl <- io (IO.try (openFile file ReadMode))
234 Right hdl -> fileLoop hdl False
236 -- Perform a :load for files given on the GHCi command line
237 when (not (null paths)) $
238 ghciHandle showException $
241 -- if verbosity is greater than 0, or we are connected to a
242 -- terminal, display the prompt in the interactive loop.
243 is_tty <- io (hIsTerminalDevice stdin)
244 let show_prompt = verbosity dflags > 0 || is_tty
248 -- enter the interactive loop
249 interactiveLoop is_tty show_prompt
251 -- just evaluate the expression we were given
256 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
259 interactiveLoop is_tty show_prompt = do
260 -- Ignore ^C exceptions caught here
261 ghciHandleDyn (\e -> case e of
262 Interrupted -> ghciUnblock (interactiveLoop is_tty show_prompt)
263 _other -> return ()) $ do
265 -- read commands from stdin
269 else fileLoop stdin show_prompt
271 fileLoop stdin show_prompt
275 -- NOTE: We only read .ghci files if they are owned by the current user,
276 -- and aren't world writable. Otherwise, we could be accidentally
277 -- running code planted by a malicious third party.
279 -- Furthermore, We only read ./.ghci if . is owned by the current user
280 -- and isn't writable by anyone else. I think this is sufficient: we
281 -- don't need to check .. and ../.. etc. because "." always refers to
282 -- the same directory while a process is running.
284 checkPerms :: String -> IO Bool
286 #ifdef mingw32_HOST_OS
289 DriverUtil.handle (\_ -> return False) $ do
290 st <- getFileStatus name
292 if fileOwner st /= me then do
293 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
296 let mode = fileMode st
297 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
298 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
300 putStrLn $ "*** WARNING: " ++ name ++
301 " is writable by someone else, IGNORING!"
306 fileLoop :: Handle -> Bool -> GHCi ()
307 fileLoop hdl prompt = do
308 cmstate <- getCmState
309 (mod,imports) <- io (cmGetContext cmstate)
310 when prompt (io (putStr (mkPrompt mod imports)))
311 l <- io (IO.try (hGetLine hdl))
313 Left e | isEOFError e -> return ()
314 | InvalidArgument <- etype -> return ()
315 | otherwise -> io (ioError e)
316 where etype = ioeGetErrorType e
317 -- treat InvalidArgument in the same way as EOF:
318 -- this can happen if the user closed stdin, or
319 -- perhaps did getContents which closes stdin at
322 case remove_spaces l of
323 "" -> fileLoop hdl prompt
324 l -> do quit <- runCommand l
325 if quit then return () else fileLoop hdl prompt
327 stringLoop :: [String] -> GHCi ()
328 stringLoop [] = return ()
329 stringLoop (s:ss) = do
330 case remove_spaces s of
332 l -> do quit <- runCommand l
333 if quit then return () else stringLoop ss
335 mkPrompt toplevs exports
336 = concat (intersperse " " (map ('*':) toplevs ++ exports)) ++ "> "
339 readlineLoop :: GHCi ()
341 cmstate <- getCmState
342 (mod,imports) <- io (cmGetContext cmstate)
344 l <- io (readline (mkPrompt mod imports)
345 `finally` setNonBlockingFD 0)
346 -- readline sometimes puts stdin into blocking mode,
347 -- so we need to put it back for the IO library
351 case remove_spaces l of
356 if quit then return () else readlineLoop
359 runCommand :: String -> GHCi Bool
360 runCommand c = ghciHandle handler (doCommand c)
362 -- This version is for the GHC command-line option -e. The only difference
363 -- from runCommand is that it catches the ExitException exception and
364 -- exits, rather than printing out the exception.
365 runCommandEval c = ghciHandle handleEval (doCommand c)
367 handleEval (ExitException code) = io (exitWith code)
368 handleEval e = do showException e
369 io (exitWith (ExitFailure 1))
371 -- This is the exception handler for exceptions generated by the
372 -- user's code; it normally just prints out the exception. The
373 -- handler must be recursive, in case showing the exception causes
374 -- more exceptions to be raised.
376 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
377 -- raising another exception. We therefore don't put the recursive
378 -- handler arond the flushing operation, so if stderr is closed
379 -- GHCi will just die gracefully rather than going into an infinite loop.
380 handler :: Exception -> GHCi Bool
381 handler exception = do
383 io installSignalHandlers
384 ghciHandle handler (showException exception >> return False)
386 showException (DynException dyn) =
387 case fromDynamic dyn of
388 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
389 Just Interrupted -> io (putStrLn "Interrupted.")
390 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
391 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
392 Just other_ghc_ex -> io (print other_ghc_ex)
394 showException other_exception
395 = io (putStrLn ("*** Exception: " ++ show other_exception))
397 doCommand (':' : command) = specialCommand command
399 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
402 runStmt :: String -> GHCi [Name]
404 | null (filter (not.isSpace) stmt) = return []
406 = do st <- getGHCiState
407 cmstate <- getCmState
408 (new_cmstate, result) <-
409 io $ withProgName (progname st) $ withArgs (args st) $
410 cmRunStmt cmstate stmt
411 setGHCiState st{cmstate = new_cmstate}
413 CmRunFailed -> return []
414 CmRunException e -> throw e -- this is caught by runCommand(Eval)
415 CmRunOk names -> return names
417 -- possibly print the type and revert CAFs after evaluating an expression
419 = do b <- isOptionSet ShowType
420 cmstate <- getCmState
421 when b (mapM_ (showTypeOfName cmstate) names)
424 io installSignalHandlers
425 b <- isOptionSet RevertCAFs
426 io (when b revertCAFs)
429 showTypeOfName :: CmState -> Name -> GHCi ()
430 showTypeOfName cmstate n
431 = do maybe_str <- io (cmTypeOfName cmstate n)
434 Just str -> io (putStrLn (showSDoc (ppr n) ++ " :: " ++ str))
436 specialCommand :: String -> GHCi Bool
437 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
438 specialCommand str = do
439 let (cmd,rest) = break isSpace str
440 cmds <- io (readIORef commands)
441 case [ (s,f) | (s,f) <- cmds, prefixMatch cmd s ] of
442 [] -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
443 ++ shortHelpText) >> return False)
444 [(_,f)] -> f (dropWhile isSpace rest)
445 cs -> io (hPutStrLn stdout ("prefix " ++ cmd ++
446 " matches multiple commands (" ++
447 foldr1 (\a b -> a ++ ',':b) (map fst cs)
448 ++ ")") >> return False)
450 noArgs c = throwDyn (CmdLineError ("command '" ++ c ++ "' takes no arguments"))
453 -----------------------------------------------------------------------------
454 -- To flush buffers for the *interpreted* computation we need
455 -- to refer to *its* stdout/stderr handles
457 GLOBAL_VAR(flush_interp, error "no flush_interp", IO ())
458 GLOBAL_VAR(turn_off_buffering, error "no flush_stdout", IO ())
460 no_buf_cmd = "System.IO.hSetBuffering System.IO.stdout System.IO.NoBuffering" ++
461 " Prelude.>> System.IO.hSetBuffering System.IO.stderr System.IO.NoBuffering"
462 flush_cmd = "System.IO.hFlush System.IO.stdout Prelude.>> System.IO.hFlush IO.stderr"
464 initInterpBuffering :: CmState -> IO ()
465 initInterpBuffering cmstate
466 = do maybe_hval <- cmCompileExpr cmstate no_buf_cmd
469 Just hval -> writeIORef turn_off_buffering (unsafeCoerce# hval :: IO ())
470 other -> panic "interactiveUI:setBuffering"
472 maybe_hval <- cmCompileExpr cmstate flush_cmd
474 Just hval -> writeIORef flush_interp (unsafeCoerce# hval :: IO ())
475 _ -> panic "interactiveUI:flush"
477 turnOffBuffering -- Turn it off right now
482 flushInterpBuffers :: GHCi ()
484 = io $ do Monad.join (readIORef flush_interp)
487 turnOffBuffering :: IO ()
489 = do Monad.join (readIORef turn_off_buffering)
492 -----------------------------------------------------------------------------
495 help :: String -> GHCi ()
496 help _ = io (putStr helpText)
498 info :: String -> GHCi ()
499 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
500 info s = do { let names = words s
501 ; init_cms <- getCmState
502 ; dflags <- getDynFlags
503 ; let exts = dopt Opt_GlasgowExts dflags
504 ; mapM_ (infoThing exts init_cms) names }
506 infoThing exts cms name
507 = do { stuff <- io (cmGetInfo cms name)
508 ; io (putStrLn (showSDocForUser (cmGetPrintUnqual cms) $
509 vcat (intersperse (text "") (map (showThing exts) stuff)))) }
511 showThing :: Bool -> GetInfoResult -> SDoc
512 showThing exts (wanted_str, (thing, fixity, src_loc, insts))
513 = vcat [ showWithLoc src_loc (showDecl exts want_name thing),
515 vcat (map show_inst insts)]
517 want_name occ = wanted_str == occNameUserString occ
520 | fix == defaultFixity = empty
521 | otherwise = ppr fix <+> text wanted_str
523 show_inst (iface_inst, loc)
524 = showWithLoc loc (ptext SLIT("instance") <+> ppr (ifInstHead iface_inst))
526 showWithLoc :: SrcLoc -> SDoc -> SDoc
528 = hang doc 2 (char '\t' <> show_loc loc)
529 -- The tab tries to make them line up a bit
531 show_loc loc -- The ppr function for SrcLocs is a bit wonky
532 | isGoodSrcLoc loc = comment <+> ptext SLIT("Defined at") <+> ppr loc
533 | otherwise = comment <+> ppr loc
534 comment = ptext SLIT("--")
537 -- Now there is rather a lot of goop just to print declarations in a
538 -- civilised way with "..." for the parts we are less interested in.
540 showDecl :: Bool -> (OccName -> Bool) -> IfaceDecl -> SDoc
541 showDecl exts want_name (IfaceForeign {ifName = tc})
542 = ppr tc <+> ptext SLIT("is a foreign type")
544 showDecl exts want_name (IfaceId {ifName = var, ifType = ty})
545 = ppr var <+> dcolon <+> showType exts ty
547 showDecl exts want_name (IfaceSyn {ifName = tycon, ifTyVars = tyvars, ifSynRhs = mono_ty})
548 = hang (ptext SLIT("type") <+> pprIfaceDeclHead [] tycon tyvars)
549 2 (equals <+> ppr mono_ty)
551 showDecl exts want_name (IfaceData {ifName = tycon,
552 ifTyVars = tyvars, ifCons = condecls})
553 = hang (pp_nd <+> pprIfaceDeclHead context tycon tyvars)
554 2 (add_bars (ppr_trim show_con cs))
556 show_con (IfVanillaCon { ifConOcc = con_name, ifConInfix = is_infix, ifConArgTys = tys,
557 ifConStricts = strs, ifConFields = flds})
558 | want_name tycon || want_name con_name || any want_name flds
559 = Just (show_guts con_name is_infix tys_w_strs flds)
560 | otherwise = Nothing
562 tys_w_strs = tys `zip` (strs ++ repeat NotMarkedStrict)
563 show_con (IfGadtCon { ifConOcc = con_name, ifConTyVars = tvs, ifConCtxt = theta,
564 ifConArgTys = arg_tys, ifConResTys = res_tys, ifConStricts = strs })
565 | want_name tycon || want_name con_name
566 = Just (ppr_bndr con_name <+> colon <+> pprIfaceForAllPart tvs theta pp_tau)
567 | otherwise = Nothing
569 tys_w_strs = arg_tys `zip` (strs ++ repeat NotMarkedStrict)
570 pp_tau = foldr add pp_res_ty tys_w_strs
571 pp_res_ty = ppr_bndr tycon <+> hsep (map pprParendIfaceType res_tys)
572 add bty pp_ty = ppr_bangty bty <+> arrow <+> pp_ty
574 show_guts con True [ty1, ty2] flds = sep [ppr_bangty ty1, ppr con, ppr_bangty ty2]
575 show_guts con _ tys [] = ppr_bndr con <+> sep (map ppr_bangty tys)
576 show_guts con _ tys flds
577 = ppr_bndr con <+> braces (sep (punctuate comma (ppr_trim show_fld (tys `zip` flds))))
579 show_fld (bty, fld) | want_name tycon || want_name con || want_name fld
580 = Just (ppr_bndr fld <+> dcolon <+> ppr_bangty bty)
581 | otherwise = Nothing
583 (pp_nd, context, cs) = case condecls of
584 IfAbstractTyCon -> (ptext SLIT("data"), [], [])
585 IfDataTyCon (Just cxt) cs -> (ptext SLIT("data"), cxt, cs)
586 IfDataTyCon Nothing cs -> (ptext SLIT("data"), [], cs)
587 IfNewTyCon c -> (ptext SLIT("newtype"), [], [c])
590 add_bars [c] = equals <+> c
591 add_bars (c:cs) = equals <+> sep (c : map (char '|' <+>) cs)
593 ppr_bangty (ty, str) = ppr_str str <> pprParendIfaceType ty
594 ppr_str MarkedStrict = char '!'
595 ppr_str MarkedUnboxed = ptext SLIT("!!")
596 ppr_str NotMarkedStrict = empty
598 showDecl exts want_name (IfaceClass {ifCtxt = context, ifName = clas, ifTyVars = tyvars,
599 ifFDs = fds, ifSigs = sigs})
600 = hang (ptext SLIT("class") <+> pprIfaceDeclHead context clas tyvars
601 <+> pprFundeps fds <+> ptext SLIT("where"))
602 2 (vcat (ppr_trim show_op sigs))
604 show_op (IfaceClassOp op dm ty)
605 | want_name clas || want_name op
606 = Just (ppr_bndr op <+> dcolon <+> showType exts ty)
610 showType :: Bool -> IfaceType -> SDoc
611 showType True ty = pprIfaceType ty -- -fglasgow-exts: print with the foralls
612 showType False ty = ppr ty -- otherwise, print without the foralls
614 ppr_trim :: (a -> Maybe SDoc) -> [a] -> [SDoc]
616 = snd (foldr go (False, []) xs)
618 go x (eliding, so_far)
619 | Just doc <- show x = (False, doc : so_far)
620 | otherwise = if eliding then (True, so_far)
621 else (True, ptext SLIT("...") : so_far)
623 ppr_bndr :: OccName -> SDoc
624 -- Wrap operators in ()
625 ppr_bndr occ | isSymOcc occ = parens (ppr occ)
626 | otherwise = ppr occ
629 -----------------------------------------------------------------------------
632 addModule :: [FilePath] -> GHCi ()
634 state <- getGHCiState
635 io (revertCAFs) -- always revert CAFs on load/add.
636 files <- mapM expandPath files
637 let new_targets = files ++ targets state
638 graph <- io (cmDepAnal (cmstate state) new_targets)
639 (cmstate1, ok, mods) <- io (cmLoadModules (cmstate state) graph)
640 setGHCiState state{ cmstate = cmstate1, targets = new_targets }
641 setContextAfterLoad mods
642 dflags <- getDynFlags
643 modulesLoadedMsg ok mods dflags
645 changeDirectory :: String -> GHCi ()
646 changeDirectory dir = do
647 state <- getGHCiState
648 when (targets state /= []) $
649 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
650 cmstate1 <- io (cmUnload (cmstate state))
651 setGHCiState state{ cmstate = cmstate1, targets = [] }
652 setContextAfterLoad []
653 dir <- expandPath dir
654 io (setCurrentDirectory dir)
656 defineMacro :: String -> GHCi ()
658 let (macro_name, definition) = break isSpace s
659 cmds <- io (readIORef commands)
661 then throwDyn (CmdLineError "invalid macro name")
663 if (macro_name `elem` map fst cmds)
664 then throwDyn (CmdLineError
665 ("command '" ++ macro_name ++ "' is already defined"))
668 -- give the expression a type signature, so we can be sure we're getting
669 -- something of the right type.
670 let new_expr = '(' : definition ++ ") :: String -> IO String"
672 -- compile the expression
674 maybe_hv <- io (cmCompileExpr cms new_expr)
677 Just hv -> io (writeIORef commands --
678 ((macro_name, keepGoing (runMacro hv)) : cmds))
680 runMacro :: HValue{-String -> IO String-} -> String -> GHCi ()
682 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
683 stringLoop (lines str)
685 undefineMacro :: String -> GHCi ()
686 undefineMacro macro_name = do
687 cmds <- io (readIORef commands)
688 if (macro_name `elem` map fst builtin_commands)
689 then throwDyn (CmdLineError
690 ("command '" ++ macro_name ++ "' cannot be undefined"))
692 if (macro_name `notElem` map fst cmds)
693 then throwDyn (CmdLineError
694 ("command '" ++ macro_name ++ "' not defined"))
696 io (writeIORef commands (filter ((/= macro_name) . fst) cmds))
699 loadModule :: [FilePath] -> GHCi ()
700 loadModule fs = timeIt (loadModule' fs)
702 loadModule' :: [FilePath] -> GHCi ()
703 loadModule' files = do
704 state <- getGHCiState
707 files <- mapM expandPath files
709 -- do the dependency anal first, so that if it fails we don't throw
710 -- away the current set of modules.
711 graph <- io (cmDepAnal (cmstate state) files)
713 -- Dependency anal ok, now unload everything
714 cmstate1 <- io (cmUnload (cmstate state))
715 setGHCiState state{ cmstate = cmstate1, targets = [] }
717 io (revertCAFs) -- always revert CAFs on load.
718 (cmstate2, ok, mods) <- io (cmLoadModules cmstate1 graph)
719 setGHCiState state{ cmstate = cmstate2, targets = files }
721 setContextAfterLoad mods
722 dflags <- getDynFlags
723 modulesLoadedMsg ok mods dflags
726 reloadModule :: String -> GHCi ()
728 state <- getGHCiState
729 case targets state of
730 [] -> io (putStr "no current target\n")
732 -- do the dependency anal first, so that if it fails we don't throw
733 -- away the current set of modules.
734 graph <- io (cmDepAnal (cmstate state) paths)
736 io (revertCAFs) -- always revert CAFs on reload.
738 <- io (cmLoadModules (cmstate state) graph)
739 setGHCiState state{ cmstate=cmstate1 }
740 setContextAfterLoad mods
741 dflags <- getDynFlags
742 modulesLoadedMsg ok mods dflags
744 reloadModule _ = noArgs ":reload"
746 setContextAfterLoad [] = setContext prel
747 setContextAfterLoad (m:_) = do
748 cmstate <- getCmState
749 b <- io (cmModuleIsInterpreted cmstate m)
750 if b then setContext ('*':m) else setContext m
752 modulesLoadedMsg ok mods dflags =
753 when (verbosity dflags > 0) $ do
755 | null mods = text "none."
757 punctuate comma (map text mods)) <> text "."
760 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
762 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
765 typeOfExpr :: String -> GHCi ()
767 = do cms <- getCmState
768 maybe_tystr <- io (cmTypeOfExpr cms str)
771 Just tystr -> io (putStrLn tystr)
773 kindOfType :: String -> GHCi ()
775 = do cms <- getCmState
776 maybe_tystr <- io (cmKindOfType cms str)
779 Just tystr -> io (putStrLn tystr)
781 quit :: String -> GHCi Bool
784 shellEscape :: String -> GHCi Bool
785 shellEscape str = io (system str >> return False)
787 -----------------------------------------------------------------------------
788 -- Browsing a module's contents
790 browseCmd :: String -> GHCi ()
793 ['*':m] | looksLikeModuleName m -> browseModule m False
794 [m] | looksLikeModuleName m -> browseModule m True
795 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
797 browseModule m exports_only = do
800 is_interpreted <- io (cmModuleIsInterpreted cms m)
801 when (not is_interpreted && not exports_only) $
802 throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
804 -- Temporarily set the context to the module we're interested in,
805 -- just so we can get an appropriate PrintUnqualified
806 (as,bs) <- io (cmGetContext cms)
807 cms1 <- io (if exports_only then cmSetContext cms [] [prel,m]
808 else cmSetContext cms [m] [])
809 cms2 <- io (cmSetContext cms1 as bs)
811 things <- io (cmBrowseModule cms2 m exports_only)
813 let unqual = cmGetPrintUnqual cms1 -- NOTE: cms1 with the new context
815 dflags <- getDynFlags
816 let exts = dopt Opt_GlasgowExts dflags
817 io (putStrLn (showSDocForUser unqual (
818 vcat (map (showDecl exts (const True)) things)
821 -----------------------------------------------------------------------------
822 -- Setting the module context
825 | all sensible mods = fn mods
826 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
828 (fn, mods) = case str of
829 '+':stuff -> (addToContext, words stuff)
830 '-':stuff -> (removeFromContext, words stuff)
831 stuff -> (newContext, words stuff)
833 sensible ('*':m) = looksLikeModuleName m
834 sensible m = looksLikeModuleName m
838 (as,bs) <- separate cms mods [] []
839 let bs' = if null as && prel `notElem` bs then prel:bs else bs
840 cms' <- io (cmSetContext cms as bs')
843 separate cmstate [] as bs = return (as,bs)
844 separate cmstate (('*':m):ms) as bs = do
845 b <- io (cmModuleIsInterpreted cmstate m)
846 if b then separate cmstate ms (m:as) bs
847 else throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
848 separate cmstate (m:ms) as bs = separate cmstate ms as (m:bs)
853 addToContext mods = do
855 (as,bs) <- io (cmGetContext cms)
857 (as',bs') <- separate cms mods [] []
859 let as_to_add = as' \\ (as ++ bs)
860 bs_to_add = bs' \\ (as ++ bs)
862 cms' <- io (cmSetContext cms
863 (as ++ as_to_add) (bs ++ bs_to_add))
867 removeFromContext mods = do
869 (as,bs) <- io (cmGetContext cms)
871 (as_to_remove,bs_to_remove) <- separate cms mods [] []
873 let as' = as \\ (as_to_remove ++ bs_to_remove)
874 bs' = bs \\ (as_to_remove ++ bs_to_remove)
876 cms' <- io (cmSetContext cms as' bs')
879 ----------------------------------------------------------------------------
882 -- set options in the interpreter. Syntax is exactly the same as the
883 -- ghc command line, except that certain options aren't available (-C,
886 -- This is pretty fragile: most options won't work as expected. ToDo:
887 -- figure out which ones & disallow them.
889 setCmd :: String -> GHCi ()
891 = do st <- getGHCiState
892 let opts = options st
893 io $ putStrLn (showSDoc (
894 text "options currently set: " <>
897 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
901 ("args":args) -> setArgs args
902 ("prog":prog) -> setProg prog
903 wds -> setOptions wds
907 setGHCiState st{ args = args }
911 setGHCiState st{ progname = prog }
913 io (hPutStrLn stderr "syntax: :set prog <progname>")
916 do -- first, deal with the GHCi opts (+s, +t, etc.)
917 let (plus_opts, minus_opts) = partition isPlus wds
918 mapM_ setOpt plus_opts
920 -- now, the GHC flags
921 leftovers <- io $ processStaticFlags minus_opts
923 -- then, dynamic flags
924 dflags <- getDynFlags
925 (dflags',leftovers) <- io $ processDynamicFlags leftovers dflags
928 -- update things if the users wants more packages
930 let new_packages = pkgs_after \\ pkgs_before
931 when (not (null new_packages)) $
932 newPackages new_packages
935 if (not (null leftovers))
936 then throwDyn (CmdLineError ("unrecognised flags: " ++
941 unsetOptions :: String -> GHCi ()
943 = do -- first, deal with the GHCi opts (+s, +t, etc.)
945 (minus_opts, rest1) = partition isMinus opts
946 (plus_opts, rest2) = partition isPlus rest1
948 if (not (null rest2))
949 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
952 mapM_ unsetOpt plus_opts
954 -- can't do GHC flags for now
955 if (not (null minus_opts))
956 then throwDyn (CmdLineError "can't unset GHC command-line flags")
959 isMinus ('-':s) = True
962 isPlus ('+':s) = True
966 = case strToGHCiOpt str of
967 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
968 Just o -> setOption o
971 = case strToGHCiOpt str of
972 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
973 Just o -> unsetOption o
975 strToGHCiOpt :: String -> (Maybe GHCiOption)
976 strToGHCiOpt "s" = Just ShowTiming
977 strToGHCiOpt "t" = Just ShowType
978 strToGHCiOpt "r" = Just RevertCAFs
979 strToGHCiOpt _ = Nothing
981 optToStr :: GHCiOption -> String
982 optToStr ShowTiming = "s"
983 optToStr ShowType = "t"
984 optToStr RevertCAFs = "r"
986 newPackages new_pkgs = do -- The new packages are already in v_Packages
987 state <- getGHCiState
988 cmstate1 <- io (cmUnload (cmstate state))
989 setGHCiState state{ cmstate = cmstate1, targets = [] }
990 dflags <- getDynFlags
991 io (linkPackages dflags new_pkgs)
992 setContextAfterLoad []
994 -- ---------------------------------------------------------------------------
999 ["modules" ] -> showModules
1000 ["bindings"] -> showBindings
1001 ["linker"] -> io showLinkerState
1002 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
1005 = do { cms <- getCmState
1006 ; let show_one ms = io (putStrLn (cmShowModule cms ms))
1007 ; mapM_ show_one (cmGetModuleGraph cms) }
1012 unqual = cmGetPrintUnqual cms
1013 -- showBinding b = putStrLn (showSDocForUser unqual (ppr (ifaceTyThing b)))
1014 showBinding b = putStrLn (showSDocForUser unqual (ppr (getName b)))
1016 io (mapM_ showBinding (cmGetBindings cms))
1020 -----------------------------------------------------------------------------
1023 data GHCiState = GHCiState
1027 targets :: [FilePath],
1029 options :: [GHCiOption]
1033 = ShowTiming -- show time/allocs after evaluation
1034 | ShowType -- show the type of expressions
1035 | RevertCAFs -- revert CAFs after every evaluation
1038 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
1040 startGHCi :: GHCi a -> GHCiState -> IO a
1041 startGHCi g state = do ref <- newIORef state; unGHCi g ref
1043 instance Monad GHCi where
1044 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
1045 return a = GHCi $ \s -> return a
1047 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
1048 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
1049 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
1051 getGHCiState = GHCi $ \r -> readIORef r
1052 setGHCiState s = GHCi $ \r -> writeIORef r s
1054 -- for convenience...
1055 getCmState = getGHCiState >>= return . cmstate
1056 setCmState cms = do s <- getGHCiState; setGHCiState s{cmstate=cms}
1058 getDynFlags = getCmState >>= return . cmGetDFlags
1060 setDynFlags dflags = do s <- getCmState; setCmState (cmSetDFlags s dflags)
1062 isOptionSet :: GHCiOption -> GHCi Bool
1064 = do st <- getGHCiState
1065 return (opt `elem` options st)
1067 setOption :: GHCiOption -> GHCi ()
1069 = do st <- getGHCiState
1070 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
1072 unsetOption :: GHCiOption -> GHCi ()
1074 = do st <- getGHCiState
1075 setGHCiState (st{ options = filter (/= opt) (options st) })
1077 io :: IO a -> GHCi a
1078 io m = GHCi { unGHCi = \s -> m >>= return }
1080 -----------------------------------------------------------------------------
1081 -- recursive exception handlers
1083 -- Don't forget to unblock async exceptions in the handler, or if we're
1084 -- in an exception loop (eg. let a = error a in a) the ^C exception
1085 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1087 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1088 ghciHandle h (GHCi m) = GHCi $ \s ->
1089 Exception.catch (m s)
1090 (\e -> unGHCi (ghciUnblock (h e)) s)
1092 ghciUnblock :: GHCi a -> GHCi a
1093 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1095 -----------------------------------------------------------------------------
1096 -- timing & statistics
1098 timeIt :: GHCi a -> GHCi a
1100 = do b <- isOptionSet ShowTiming
1103 else do allocs1 <- io $ getAllocations
1104 time1 <- io $ getCPUTime
1106 allocs2 <- io $ getAllocations
1107 time2 <- io $ getCPUTime
1108 io $ printTimes (fromIntegral (allocs2 - allocs1))
1112 foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64
1113 -- defined in ghc/rts/Stats.c
1115 printTimes :: Integer -> Integer -> IO ()
1116 printTimes allocs psecs
1117 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1118 secs_str = showFFloat (Just 2) secs
1119 putStrLn (showSDoc (
1120 parens (text (secs_str "") <+> text "secs" <> comma <+>
1121 text (show allocs) <+> text "bytes")))
1123 -----------------------------------------------------------------------------
1130 -- Have to turn off buffering again, because we just
1131 -- reverted stdout, stderr & stdin to their defaults.
1133 foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
1134 -- Make it "safe", just in case
1136 -- -----------------------------------------------------------------------------
1139 expandPath :: String -> GHCi String
1141 case dropWhile isSpace path of
1143 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1144 return (tilde ++ '/':d)