1 {-# OPTIONS -#include "Linker.h" -#include "SchedAPI.h" #-}
2 -----------------------------------------------------------------------------
3 -- $Id: InteractiveUI.hs,v 1.109 2002/01/23 16:50:49 simonmar Exp $
5 -- GHC Interactive User Interface
7 -- (c) The GHC Team 2000
9 -----------------------------------------------------------------------------
10 module InteractiveUI ( interactiveUI, ghciWelcomeMsg ) where
12 #include "../includes/config.h"
13 #include "HsVersions.h"
18 import CmTypes ( Linkable, isObjectLinkable, ModSummary(..) )
19 import CmLink ( findModuleLinkable_maybe )
21 import HscTypes ( TyThing(..), showModMsg, InteractiveContext(..) )
22 import MkIface ( ifaceTyThing )
25 import DriverUtil ( handle, remove_spaces )
27 import Finder ( flushPackageCache )
29 import Id ( isRecordSelector, recordSelectorFieldLabel,
30 isDataConWrapId, idName )
31 import Class ( className )
32 import TyCon ( tyConName, tyConClass_maybe, isPrimTyCon )
33 import FieldLabel ( fieldLabelTyCon )
34 import SrcLoc ( isGoodSrcLoc )
35 import Module ( moduleName )
36 import NameEnv ( nameEnvElts )
37 import Name ( Name, isHomePackageName, nameSrcLoc, nameOccName,
39 import OccName ( isSymOcc )
40 import BasicTypes ( defaultFixity )
42 import CmdLineOpts ( DynFlag(..), getDynFlags, saveDynFlags,
43 restoreDynFlags, dopt_unset )
44 import Panic ( GhcException(..), showGhcException )
47 #ifndef mingw32_TARGET_OS
53 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
69 import PrelGHC ( unsafeCoerce# )
70 import Foreign ( nullPtr )
71 import CString ( peekCString )
73 -----------------------------------------------------------------------------
77 \ / _ \\ /\\ /\\/ __(_)\n\
78 \ / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n\
79 \/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n\
80 \\\____/\\/ /_/\\____/|_| Type :? for help.\n"
82 GLOBAL_VAR(commands, builtin_commands, [(String, String -> GHCi Bool)])
84 builtin_commands :: [(String, String -> GHCi Bool)]
86 ("add", keepGoing addModule),
87 ("cd", keepGoing changeDirectory),
88 ("def", keepGoing defineMacro),
89 ("help", keepGoing help),
90 ("?", keepGoing help),
91 ("info", keepGoing info),
92 ("load", keepGoing loadModule),
93 ("module", keepGoing setContext),
94 ("reload", keepGoing reloadModule),
95 ("set", keepGoing setCmd),
96 ("show", keepGoing showCmd),
97 ("type", keepGoing typeOfExpr),
98 ("unset", keepGoing unsetOptions),
99 ("undef", keepGoing undefineMacro),
103 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
104 keepGoing a str = a str >> return False
106 shortHelpText = "use :? for help.\n"
109 \ Commands available from the prompt:\n\
111 \ <stmt> evaluate/run <stmt>\n\
112 \ :add <filename> ... add module(s) to the current target set\n\
113 \ :cd <dir> change directory to <dir>\n\
114 \ :def <cmd> <expr> define a command :<cmd>\n\
115 \ :help, :? display this list of commands\n\
116 \ :info [<name> ...] display information about the given names\n\
117 \ :load <filename> ... load module(s) and their dependents\n\
118 \ :module <mod> set the context for expression evaluation to <mod>\n\
119 \ :reload reload the current module set\n\
121 \ :set <option> ... set options\n\
122 \ :set args <arg> ... set the arguments returned by System.getArgs\n\
123 \ :set prog <progname> set the value returned by System.getProgName\n\
125 \ :show modules show the currently loaded modules\n\
126 \ :show bindings show the current bindings made at the prompt\n\
128 \ :type <expr> show the type of <expr>\n\
129 \ :undef <cmd> undefine user-defined command :<cmd>\n\
130 \ :unset <option> ... unset options\n\
132 \ :!<command> run the shell command <command>\n\
134 \ Options for `:set' and `:unset':\n\
136 \ +r revert top-level expressions after each evaluation\n\
137 \ +s print timing/memory stats after each evaluation\n\
138 \ +t print type after evaluation\n\
139 \ -<flags> most GHC command line flags can also be set here\n\
140 \ (eg. -v2, -fglasgow-exts, etc.)\n\
143 interactiveUI :: CmState -> [FilePath] -> [LibrarySpec] -> IO ()
144 interactiveUI cmstate paths cmdline_libs = do
146 hSetBuffering stdout NoBuffering
148 -- link in the available packages
149 pkgs <- getPackageInfo
151 linkPackages cmdline_libs pkgs
153 dflags <- getDynFlags
155 (cmstate, maybe_hval)
156 <- cmCompileExpr cmstate dflags "IO.hSetBuffering IO.stdout IO.NoBuffering Prelude.>> IO.hSetBuffering IO.stderr IO.NoBuffering"
158 Just hval -> unsafeCoerce# hval :: IO ()
159 _ -> panic "interactiveUI:buffering"
161 (cmstate, maybe_hval)
162 <- cmCompileExpr cmstate dflags "IO.hFlush PrelHandle.stderr"
164 Just hval -> writeIORef flush_stderr (unsafeCoerce# hval :: IO ())
165 _ -> panic "interactiveUI:stderr"
167 (cmstate, maybe_hval)
168 <- cmCompileExpr cmstate dflags "IO.hFlush PrelHandle.stdout"
170 Just hval -> writeIORef flush_stdout (unsafeCoerce# hval :: IO ())
171 _ -> panic "interactiveUI:stdout"
173 -- initial context is just the Prelude
174 cmstate <- cmSetContext cmstate dflags [] ["Prelude"]
176 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
180 startGHCi (runGHCi paths)
181 GHCiState{ progname = "<interactive>",
187 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
188 Readline.resetTerminal Nothing
194 runGHCi :: [FilePath] -> GHCi ()
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
236 io $ do putStrLn "Leaving GHCi."
240 -- ignore ^C exceptions caught here
241 ghciHandleDyn (\e -> case e of Interrupted -> ghciUnblock interactiveLoop
242 _other -> return ()) $ do
244 -- read commands from stdin
245 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
252 -- NOTE: We only read .ghci files if they are owned by the current user,
253 -- and aren't world writable. Otherwise, we could be accidentally
254 -- running code planted by a malicious third party.
256 -- Furthermore, We only read ./.ghci if . is owned by the current user
257 -- and isn't writable by anyone else. I think this is sufficient: we
258 -- don't need to check .. and ../.. etc. because "." always refers to
259 -- the same directory while a process is running.
261 checkPerms :: String -> IO Bool
263 handle (\_ -> return False) $ do
264 #ifdef mingw32_TARGET_OS
267 st <- getFileStatus name
269 if fileOwner st /= me then do
270 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
273 let mode = fileMode st
274 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
275 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
277 putStrLn $ "*** WARNING: " ++ name ++
278 " is writable by someone else, IGNORING!"
283 fileLoop :: Handle -> Bool -> GHCi ()
284 fileLoop hdl prompt = do
285 cmstate <- getCmState
286 (mod,imports) <- io (cmGetContext cmstate)
287 when prompt (io (putStr (mkPrompt mod imports)))
288 l <- io (IO.try (hGetLine hdl))
290 Left e | isEOFError e -> return ()
291 | otherwise -> throw e
293 case remove_spaces l of
294 "" -> fileLoop hdl prompt
295 l -> do quit <- runCommand l
296 if quit then return () else fileLoop hdl prompt
298 stringLoop :: [String] -> GHCi ()
299 stringLoop [] = return ()
300 stringLoop (s:ss) = do
301 case remove_spaces s of
303 l -> do quit <- runCommand l
304 if quit then return () else stringLoop ss
306 mkPrompt toplevs exports
307 = concat (intersperse " " (toplevs ++ map ('*':) exports)) ++ "> "
309 #if HAVE_READLINE_HEADERS && HAVE_READLINE_LIBS
310 readlineLoop :: GHCi ()
312 cmstate <- getCmState
313 (mod,imports) <- io (cmGetContext cmstate)
315 l <- io (readline (mkPrompt mod imports))
319 case remove_spaces l of
324 if quit then return () else readlineLoop
327 -- Top level exception handler, just prints out the exception
329 runCommand :: String -> GHCi Bool
331 ghciHandle ( \exception -> do
333 showException exception
338 showException (DynException dyn) =
339 case fromDynamic dyn of
340 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
341 Just Interrupted -> io (putStrLn "Interrupted.")
342 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
343 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
344 Just other_ghc_ex -> io (print other_ghc_ex)
346 showException other_exception
347 = io (putStrLn ("*** Exception: " ++ show other_exception))
349 doCommand (':' : command) = specialCommand command
351 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
354 runStmt :: String -> GHCi [Name]
356 | null (filter (not.isSpace) stmt) = return []
358 = do st <- getGHCiState
359 dflags <- io getDynFlags
360 let dflags' = dopt_unset dflags Opt_WarnUnusedBinds
361 (new_cmstate, result) <-
362 io $ withProgName (progname st) $ withArgs (args st) $
363 cmRunStmt (cmstate st) dflags' stmt
364 setGHCiState st{cmstate = new_cmstate}
366 CmRunFailed -> return []
367 CmRunException e -> showException e >> return []
368 CmRunOk names -> return names
370 -- possibly print the type and revert CAFs after evaluating an expression
372 = do b <- isOptionSet ShowType
373 cmstate <- getCmState
374 when b (mapM_ (showTypeOfName cmstate) names)
376 b <- isOptionSet RevertCAFs
377 io (when b revertCAFs)
381 showTypeOfName :: CmState -> Name -> GHCi ()
382 showTypeOfName cmstate n
383 = do maybe_str <- io (cmTypeOfName cmstate n)
386 Just str -> io (putStrLn (showSDoc (ppr n) ++ " :: " ++ str))
388 flushEverything :: GHCi ()
390 = io $ do Monad.join (readIORef flush_stdout)
391 Monad.join (readIORef flush_stderr)
394 specialCommand :: String -> GHCi Bool
395 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
396 specialCommand str = do
397 let (cmd,rest) = break isSpace str
398 cmds <- io (readIORef commands)
399 case [ (s,f) | (s,f) <- cmds, prefixMatch cmd s ] of
400 [] -> io (hPutStr stdout ("unknown command `:" ++ cmd ++ "'\n"
401 ++ shortHelpText) >> return False)
402 [(_,f)] -> f (dropWhile isSpace rest)
403 cs -> io (hPutStrLn stdout ("prefix " ++ cmd ++
404 " matches multiple commands (" ++
405 foldr1 (\a b -> a ++ ',':b) (map fst cs)
406 ++ ")") >> return False)
408 noArgs c = throwDyn (CmdLineError ("command `" ++ c ++ "' takes no arguments"))
410 -----------------------------------------------------------------------------
413 help :: String -> GHCi ()
414 help _ = io (putStr helpText)
416 info :: String -> GHCi ()
417 info "" = throwDyn (CmdLineError "syntax: `:i <thing-you-want-info-about>'")
420 init_cms <- getCmState
421 dflags <- io getDynFlags
423 infoThings cms [] = return cms
424 infoThings cms (name:names) = do
425 (cms, stuff) <- io (cmInfoThing cms dflags name)
426 io (putStrLn (showSDocForUser unqual (
427 vcat (intersperse (text "") (map showThing stuff))))
431 unqual = cmGetPrintUnqual init_cms
433 showThing (ty_thing, fixity)
434 = vcat [ text "-- " <> showTyThing ty_thing,
435 showFixity fixity (getName ty_thing),
436 ppr (ifaceTyThing ty_thing) ]
439 | fix == defaultFixity = empty
440 | otherwise = ppr fix <+>
441 (if isSymOcc (nameOccName name)
443 else char '`' <> ppr name <> char '`')
445 showTyThing (AClass cl)
446 = hcat [ppr cl, text " is a class", showSrcLoc (className cl)]
447 showTyThing (ATyCon ty)
449 = hcat [ppr ty, text " is a primitive type constructor"]
451 = hcat [ppr ty, text " is a type constructor", showSrcLoc (tyConName ty)]
452 showTyThing (AnId id)
453 = hcat [ppr id, text " is a ", idDescr id, showSrcLoc (idName id)]
456 | isRecordSelector id =
457 case tyConClass_maybe (fieldLabelTyCon (
458 recordSelectorFieldLabel id)) of
459 Nothing -> text "record selector"
460 Just c -> text "method in class " <> ppr c
461 | isDataConWrapId id = text "data constructor"
462 | otherwise = text "variable"
464 -- also print out the source location for home things
466 | isHomePackageName name && isGoodSrcLoc loc
467 = hsep [ text ", defined at", ppr loc ]
470 where loc = nameSrcLoc name
472 cms <- infoThings init_cms names
476 addModule :: String -> GHCi ()
478 let files = words str
479 state <- getGHCiState
480 dflags <- io (getDynFlags)
481 io (revertCAFs) -- always revert CAFs on load/add.
482 let new_targets = files ++ targets state
483 graph <- io (cmDepAnal (cmstate state) dflags new_targets)
484 (cmstate1, ok, mods) <- io (cmLoadModules (cmstate state) dflags graph)
485 setGHCiState state{ cmstate = cmstate1, targets = new_targets }
486 setContextAfterLoad mods
487 modulesLoadedMsg ok mods
489 changeDirectory :: String -> GHCi ()
490 changeDirectory ('~':d) = do
491 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
492 io (setCurrentDirectory (tilde ++ '/':d))
493 changeDirectory d = io (setCurrentDirectory d)
495 defineMacro :: String -> GHCi ()
497 let (macro_name, definition) = break isSpace s
498 cmds <- io (readIORef commands)
500 then throwDyn (CmdLineError "invalid macro name")
502 if (macro_name `elem` map fst cmds)
503 then throwDyn (CmdLineError
504 ("command `" ++ macro_name ++ "' is already defined"))
507 -- give the expression a type signature, so we can be sure we're getting
508 -- something of the right type.
509 let new_expr = '(' : definition ++ ") :: String -> IO String"
511 -- compile the expression
513 dflags <- io getDynFlags
514 (new_cmstate, maybe_hv) <- io (cmCompileExpr cms dflags new_expr)
515 setCmState new_cmstate
518 Just hv -> io (writeIORef commands --
519 ((macro_name, keepGoing (runMacro hv)) : cmds))
521 runMacro :: HValue{-String -> IO String-} -> String -> GHCi ()
523 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
524 stringLoop (lines str)
526 undefineMacro :: String -> GHCi ()
527 undefineMacro macro_name = do
528 cmds <- io (readIORef commands)
529 if (macro_name `elem` map fst builtin_commands)
530 then throwDyn (CmdLineError
531 ("command `" ++ macro_name ++ "' cannot be undefined"))
533 if (macro_name `notElem` map fst cmds)
534 then throwDyn (CmdLineError
535 ("command `" ++ macro_name ++ "' not defined"))
537 io (writeIORef commands (filter ((/= macro_name) . fst) cmds))
540 loadModule :: String -> GHCi ()
541 loadModule str = timeIt (loadModule' str)
544 let files = words str
545 state <- getGHCiState
546 dflags <- io getDynFlags
548 -- do the dependency anal first, so that if it fails we don't throw
549 -- away the current set of modules.
550 graph <- io (cmDepAnal (cmstate state) dflags files)
552 -- Dependency anal ok, now unload everything
553 cmstate1 <- io (cmUnload (cmstate state) dflags)
554 setGHCiState state{ cmstate = cmstate1, targets = [] }
556 io (revertCAFs) -- always revert CAFs on load.
557 (cmstate2, ok, mods) <- io (cmLoadModules cmstate1 dflags graph)
558 setGHCiState state{ cmstate = cmstate2, targets = files }
560 setContextAfterLoad mods
561 modulesLoadedMsg ok mods
564 reloadModule :: String -> GHCi ()
566 state <- getGHCiState
567 dflags <- io getDynFlags
568 case targets state of
569 [] -> io (putStr "no current target\n")
571 -- do the dependency anal first, so that if it fails we don't throw
572 -- away the current set of modules.
573 graph <- io (cmDepAnal (cmstate state) dflags paths)
575 io (revertCAFs) -- always revert CAFs on reload.
577 <- io (cmLoadModules (cmstate state) dflags graph)
578 setGHCiState state{ cmstate=cmstate1 }
579 setContextAfterLoad mods
580 modulesLoadedMsg ok mods
582 reloadModule _ = noArgs ":reload"
584 setContextAfterLoad [] = setContext prel
585 setContextAfterLoad (m:_) = do
586 cmstate <- getCmState
587 b <- io (cmModuleIsInterpreted cmstate m)
588 if b then setContext m else setContext ('*':m)
590 modulesLoadedMsg ok mods = do
592 | null mods = text "none."
594 punctuate comma (map text mods)) <> text "."
597 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
599 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
602 typeOfExpr :: String -> GHCi ()
604 = do cms <- getCmState
605 dflags <- io getDynFlags
606 (new_cmstate, maybe_tystr) <- io (cmTypeOfExpr cms dflags str)
607 setCmState new_cmstate
610 Just tystr -> io (putStrLn tystr)
612 quit :: String -> GHCi Bool
615 shellEscape :: String -> GHCi Bool
616 shellEscape str = io (system str >> return False)
618 -----------------------------------------------------------------------------
619 -- Setting the module context
622 | all sensible mods = fn mods
623 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
625 (fn, mods) = case str of
626 '+':stuff -> (addToContext, words stuff)
627 '-':stuff -> (removeFromContext, words stuff)
628 stuff -> (newContext, words stuff)
630 sensible ('*':c:cs) = isUpper c && all isAlphaNumEx cs
631 sensible (c:cs) = isUpper c && all isAlphaNumEx cs
632 isAlphaNumEx c = isAlphaNum c || c == '_'
636 dflags <- io getDynFlags
637 (as,bs) <- separate cms mods [] []
638 let bs' = if null as && prel `notElem` bs then prel:bs else bs
639 cms' <- io (cmSetContext cms dflags as bs')
642 separate cmstate [] as bs = return (as,bs)
643 separate cmstate (('*':m):ms) as bs = separate cmstate ms as (m:bs)
644 separate cmstate (m:ms) as bs = do
645 b <- io (cmModuleIsInterpreted cmstate m)
646 if b then separate cmstate ms (m:as) bs
647 else throwDyn (CmdLineError ("module `" ++ m ++ "' is not interpreted"))
652 addToContext mods = do
654 dflags <- io getDynFlags
655 (as,bs) <- io (cmGetContext cms)
657 (as',bs') <- separate cms mods [] []
659 let as_to_add = as' \\ (as ++ bs)
660 bs_to_add = bs' \\ (as ++ bs)
662 cms' <- io (cmSetContext cms dflags
663 (as ++ as_to_add) (bs ++ bs_to_add))
667 removeFromContext mods = do
669 dflags <- io getDynFlags
670 (as,bs) <- io (cmGetContext cms)
672 (as_to_remove,bs_to_remove) <- separate cms mods [] []
674 let as' = as \\ (as_to_remove ++ bs_to_remove)
675 bs' = bs \\ (as_to_remove ++ bs_to_remove)
677 cms' <- io (cmSetContext cms dflags as' bs')
680 ----------------------------------------------------------------------------
683 -- set options in the interpreter. Syntax is exactly the same as the
684 -- ghc command line, except that certain options aren't available (-C,
687 -- This is pretty fragile: most options won't work as expected. ToDo:
688 -- figure out which ones & disallow them.
690 setCmd :: String -> GHCi ()
692 = do st <- getGHCiState
693 let opts = options st
694 io $ putStrLn (showSDoc (
695 text "options currently set: " <>
698 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
702 ("args":args) -> setArgs args
703 ("prog":prog) -> setProg prog
704 wds -> setOptions wds
708 setGHCiState st{ args = args }
712 setGHCiState st{ progname = prog }
714 io (hPutStrLn stderr "syntax: :set prog <progname>")
717 do -- first, deal with the GHCi opts (+s, +t, etc.)
718 let (plus_opts, minus_opts) = partition isPlus wds
719 mapM setOpt plus_opts
721 -- now, the GHC flags
722 pkgs_before <- io (readIORef v_Packages)
723 leftovers <- io (processArgs static_flags minus_opts [])
724 pkgs_after <- io (readIORef v_Packages)
726 -- update things if the users wants more packages
727 when (pkgs_before /= pkgs_after) $
728 newPackages (pkgs_after \\ pkgs_before)
730 -- then, dynamic flags
733 leftovers <- processArgs dynamic_flags leftovers []
736 if (not (null leftovers))
737 then throwDyn (CmdLineError ("unrecognised flags: " ++
742 unsetOptions :: String -> GHCi ()
744 = do -- first, deal with the GHCi opts (+s, +t, etc.)
746 (minus_opts, rest1) = partition isMinus opts
747 (plus_opts, rest2) = partition isPlus rest1
749 if (not (null rest2))
750 then io (putStrLn ("unknown option: `" ++ head rest2 ++ "'"))
753 mapM unsetOpt plus_opts
755 -- can't do GHC flags for now
756 if (not (null minus_opts))
757 then throwDyn (CmdLineError "can't unset GHC command-line flags")
760 isMinus ('-':s) = True
763 isPlus ('+':s) = True
767 = case strToGHCiOpt str of
768 Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
769 Just o -> setOption o
772 = case strToGHCiOpt str of
773 Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
774 Just o -> unsetOption o
776 strToGHCiOpt :: String -> (Maybe GHCiOption)
777 strToGHCiOpt "s" = Just ShowTiming
778 strToGHCiOpt "t" = Just ShowType
779 strToGHCiOpt "r" = Just RevertCAFs
780 strToGHCiOpt _ = Nothing
782 optToStr :: GHCiOption -> String
783 optToStr ShowTiming = "s"
784 optToStr ShowType = "t"
785 optToStr RevertCAFs = "r"
787 newPackages new_pkgs = do
788 state <- getGHCiState
789 dflags <- io getDynFlags
790 cmstate1 <- io (cmUnload (cmstate state) dflags)
791 setGHCiState state{ cmstate = cmstate1, targets = [] }
794 pkgs <- getPackageInfo
795 flushPackageCache pkgs
797 new_pkg_info <- getPackageDetails new_pkgs
798 mapM_ linkPackage (reverse new_pkg_info)
800 -----------------------------------------------------------------------------
805 ["modules" ] -> showModules
806 ["bindings"] -> showBindings
807 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
811 let mg = cmGetModuleGraph cms
812 ls = cmGetLinkables cms
813 maybe_linkables = map (findModuleLinkable_maybe ls)
814 (map (moduleName.ms_mod) mg)
815 zipWithM showModule mg maybe_linkables
818 showModule :: ModSummary -> Maybe Linkable -> GHCi ()
819 showModule m (Just l) = do
820 io (putStrLn (showModMsg (isObjectLinkable l) (ms_mod m) (ms_location m)))
821 showModule _ Nothing = panic "missing linkable"
826 unqual = cmGetPrintUnqual cms
827 showBinding b = putStrLn (showSDocForUser unqual (ppr (ifaceTyThing b)))
829 io (mapM showBinding (cmGetBindings cms))
832 -----------------------------------------------------------------------------
835 data GHCiState = GHCiState
839 targets :: [FilePath],
841 options :: [GHCiOption]
845 = ShowTiming -- show time/allocs after evaluation
846 | ShowType -- show the type of expressions
847 | RevertCAFs -- revert CAFs after every evaluation
850 GLOBAL_VAR(flush_stdout, error "no flush_stdout", IO ())
851 GLOBAL_VAR(flush_stderr, error "no flush_stdout", IO ())
853 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
855 startGHCi :: GHCi a -> GHCiState -> IO a
856 startGHCi g state = do ref <- newIORef state; unGHCi g ref
858 instance Monad GHCi where
859 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
860 return a = GHCi $ \s -> return a
862 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
863 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
864 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
866 getGHCiState = GHCi $ \r -> readIORef r
867 setGHCiState s = GHCi $ \r -> writeIORef r s
869 -- for convenience...
870 getCmState = getGHCiState >>= return . cmstate
871 setCmState cms = do s <- getGHCiState; setGHCiState s{cmstate=cms}
873 isOptionSet :: GHCiOption -> GHCi Bool
875 = do st <- getGHCiState
876 return (opt `elem` options st)
878 setOption :: GHCiOption -> GHCi ()
880 = do st <- getGHCiState
881 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
883 unsetOption :: GHCiOption -> GHCi ()
885 = do st <- getGHCiState
886 setGHCiState (st{ options = filter (/= opt) (options st) })
889 io m = GHCi { unGHCi = \s -> m >>= return }
891 -----------------------------------------------------------------------------
892 -- recursive exception handlers
894 -- Don't forget to unblock async exceptions in the handler, or if we're
895 -- in an exception loop (eg. let a = error a in a) the ^C exception
896 -- may never be delivered. Thanks to Marcin for pointing out the bug.
898 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
899 ghciHandle h (GHCi m) = GHCi $ \s ->
900 Exception.catch (m s)
901 (\e -> unGHCi (ghciHandle h (ghciUnblock (h e))) s)
903 ghciUnblock :: GHCi a -> GHCi a
904 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
906 -----------------------------------------------------------------------------
909 -- Left: full path name of a .o file, including trailing .o
910 -- Right: "unadorned" name of a .DLL/.so
911 -- e.g. On unix "qt" denotes "libqt.so"
912 -- On WinDoze "burble" denotes "burble.DLL"
913 -- addDLL is platform-specific and adds the lib/.so/.DLL
914 -- suffixes platform-dependently; we don't do that here.
916 -- For dynamic objects only, try to find the object file in all the
917 -- directories specified in v_Library_Paths before giving up.
920 = Either FilePath String
922 showLS (Left nm) = "(static) " ++ nm
923 showLS (Right nm) = "(dynamic) " ++ nm
925 linkPackages :: [LibrarySpec] -> [PackageConfig] -> IO ()
926 linkPackages cmdline_lib_specs pkgs
927 = do mapM_ linkPackage (reverse pkgs)
928 lib_paths <- readIORef v_Library_paths
929 mapM_ (preloadLib lib_paths) cmdline_lib_specs
930 if (null cmdline_lib_specs)
932 else do putStr "final link ... "
934 if ok then putStrLn "done."
935 else throwDyn (InstallationError
936 "linking extra libraries/objects failed")
938 preloadLib :: [String] -> LibrarySpec -> IO ()
939 preloadLib lib_paths lib_spec
940 = do putStr ("Loading object " ++ showLS lib_spec ++ " ... ")
943 -> do b <- preload_static lib_paths static_ish
944 putStrLn (if b then "done." else "not found")
946 -> -- We add "" to the set of paths to try, so that
947 -- if none of the real paths match, we force addDLL
948 -- to look in the default dynamic-link search paths.
949 do maybe_errstr <- preload_dynamic (lib_paths++[""])
953 Just mm -> preloadFailed mm lib_paths lib_spec
956 preloadFailed :: String -> [String] -> LibrarySpec -> IO ()
957 preloadFailed sys_errmsg paths spec
958 = do putStr ("failed.\nDynamic linker error message was:\n "
959 ++ sys_errmsg ++ "\nWhilst trying to load: "
960 ++ showLS spec ++ "\nDirectories to search are:\n"
961 ++ unlines (map (" "++) paths) )
964 -- not interested in the paths in the static case.
965 preload_static paths name
966 = do b <- doesFileExist name
967 if not b then return False
968 else loadObj name >> return True
970 -- return Nothing == success, else Just error message from addDLL
971 preload_dynamic [] name
973 preload_dynamic (path:paths) rootname
974 = do -- addDLL returns NULL on success
975 maybe_errmsg <- addDLL path rootname
976 if maybe_errmsg == nullPtr
977 then preload_dynamic paths rootname
978 else do str <- peekCString maybe_errmsg
982 = (throwDyn . CmdLineError)
983 "user specified .o/.so/.DLL could not be loaded."
985 -- Packages that don't need loading, because the compiler shares them with
986 -- the interpreted program.
987 dont_load_these = [ "gmp", "rts" ]
989 -- Packages that are already linked into GHCi. For mingw32, we only
990 -- skip gmp and rts, since std and after need to load the msvcrt.dll
991 -- library which std depends on.
993 # ifndef mingw32_TARGET_OS
994 = [ "std", "concurrent", "posix", "text", "util" ]
999 linkPackage :: PackageConfig -> IO ()
1001 | name pkg `elem` dont_load_these = return ()
1004 -- For each obj, try obj.o and if that fails, obj.so.
1005 -- Complication: all the .so's must be loaded before any of the .o's.
1006 let dirs = library_dirs pkg
1007 let objs = hs_libraries pkg ++ extra_libraries pkg
1008 classifieds <- mapM (locateOneObj dirs) objs
1010 -- Don't load the .so libs if this is a package GHCi is already
1011 -- linked against, because we'll already have the .so linked in.
1012 let (so_libs, obj_libs) = partition isRight classifieds
1013 let sos_first | name pkg `elem` loaded_in_ghci = obj_libs
1014 | otherwise = so_libs ++ obj_libs
1016 putStr ("Loading package " ++ name pkg ++ " ... ")
1017 mapM loadClassified sos_first
1018 putStr "linking ... "
1020 if ok then putStrLn "done."
1021 else panic ("can't load package `" ++ name pkg ++ "'")
1023 isRight (Right _) = True
1024 isRight (Left _) = False
1026 loadClassified :: LibrarySpec -> IO ()
1027 loadClassified (Left obj_absolute_filename)
1028 = do loadObj obj_absolute_filename
1029 loadClassified (Right dll_unadorned)
1030 = do maybe_errmsg <- addDLL "" dll_unadorned -- doesn't seem right to me
1031 if maybe_errmsg == nullPtr
1033 else do str <- peekCString maybe_errmsg
1034 throwDyn (CmdLineError ("can't load .so/.DLL for: "
1035 ++ dll_unadorned ++ " (" ++ str ++ ")" ))
1037 locateOneObj :: [FilePath] -> String -> IO LibrarySpec
1039 = return (Right obj) -- we assume
1040 locateOneObj (d:ds) obj
1041 = do let path = d ++ '/':obj ++ ".o"
1042 b <- doesFileExist path
1043 if b then return (Left path) else locateOneObj ds obj
1045 -----------------------------------------------------------------------------
1046 -- timing & statistics
1048 timeIt :: GHCi a -> GHCi a
1050 = do b <- isOptionSet ShowTiming
1053 else do allocs1 <- io $ getAllocations
1054 time1 <- io $ getCPUTime
1056 allocs2 <- io $ getAllocations
1057 time2 <- io $ getCPUTime
1058 io $ printTimes (allocs2 - allocs1) (time2 - time1)
1061 foreign import "getAllocations" getAllocations :: IO Int
1063 printTimes :: Int -> Integer -> IO ()
1064 printTimes allocs psecs
1065 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1066 secs_str = showFFloat (Just 2) secs
1067 putStrLn (showSDoc (
1068 parens (text (secs_str "") <+> text "secs" <> comma <+>
1069 int allocs <+> text "bytes")))
1071 -----------------------------------------------------------------------------
1074 foreign import revertCAFs :: IO () -- make it "safe", just in case