X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fghci%2FInteractiveUI.hs;h=afd970214b5f1be4c5c9ac23e396158a0d8d97a1;hb=00fc612dc1e776ef34bd09b4f4ef4f6650d418b0;hp=73b1e47684d6261159940b08e71b27f921040ed7;hpb=c24bd1bbbdc4e20ea5c31b8779a70a5421f44962;p=ghc-hetmet.git diff --git a/compiler/ghci/InteractiveUI.hs b/compiler/ghci/InteractiveUI.hs index 73b1e47..afd9702 100644 --- a/compiler/ghci/InteractiveUI.hs +++ b/compiler/ghci/InteractiveUI.hs @@ -82,9 +82,10 @@ import Data.Array import Control.Monad as Monad import Text.Printf import Foreign -import Foreign.C ( withCStringLen ) +import Foreign.C import GHC.Exts ( unsafeCoerce# ) import GHC.IOBase ( IOErrorType(InvalidArgument) ) +import GHC.TopHandler import Data.IORef ( IORef, readIORef, writeIORef ) @@ -280,8 +281,9 @@ findEditor = do return "" #endif -interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO () -interactiveUI session srcs maybe_expr = do +interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe [String] + -> IO () +interactiveUI session srcs maybe_exprs = do -- HACK! If we happen to get into an infinite loop (eg the user -- types 'let x=x in x' at the prompt), then the thread will block -- on a blackhole, and become unreachable during GC. The GC will @@ -297,7 +299,7 @@ interactiveUI session srcs maybe_expr = do -- Initialise buffering for the *interpreted* I/O system initInterpBuffering session - when (isNothing maybe_expr) $ do + when (isNothing maybe_exprs) $ do -- Only for GHCi (not runghc and ghc -e): -- Turn buffering off for the compiled program's stdout/stderr @@ -328,7 +330,7 @@ interactiveUI session srcs maybe_expr = do default_editor <- findEditor - startGHCi (runGHCi srcs maybe_expr) + startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = "", args = [], prompt = "%s> ", @@ -351,8 +353,8 @@ interactiveUI session srcs maybe_expr = do return () -runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi () -runGHCi paths maybe_expr = do +runGHCi :: [(FilePath, Maybe Phase)] -> Maybe [String] -> GHCi () +runGHCi paths maybe_exprs = do let read_dot_files = not opt_IgnoreDotGhci when (read_dot_files) $ do @@ -390,7 +392,7 @@ runGHCi paths maybe_expr = do when (not (null paths)) $ do ok <- ghciHandle (\e -> do showException e; return Failed) $ loadModule paths - when (isJust maybe_expr && failed ok) $ + when (isJust maybe_exprs && failed ok) $ io (exitWith (ExitFailure 1)) -- if verbosity is greater than 0, or we are connected to a @@ -399,7 +401,7 @@ runGHCi paths maybe_expr = do dflags <- getDynFlags let show_prompt = verbosity dflags > 0 || is_tty - case maybe_expr of + case maybe_exprs of Nothing -> do #if defined(mingw32_HOST_OS) @@ -415,15 +417,25 @@ runGHCi paths maybe_expr = do #endif -- enter the interactive loop interactiveLoop is_tty show_prompt - Just expr -> do + Just exprs -> do -- just evaluate the expression we were given - runCommandEval expr - return () + enqueueCommands exprs + let handle e = do st <- getGHCiState + -- Jump through some hoops to get the + -- current progname in the exception text: + -- : + io $ withProgName (progname st) + -- The "fast exit" part just calls exit() + -- directly instead of doing an orderly + -- runtime shutdown, otherwise the main + -- GHCi thread will complain about being + -- interrupted. + $ topHandlerFastExit e + runCommands' handle (return Nothing) -- and finally, exit io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi." - interactiveLoop :: Bool -> Bool -> GHCi () interactiveLoop is_tty show_prompt = -- Ignore ^C exceptions caught here @@ -594,14 +606,18 @@ queryQueue = do return (Just c) runCommands :: GHCi (Maybe String) -> GHCi () -runCommands getCmd = do +runCommands = runCommands' handler + +runCommands' :: (Exception -> GHCi Bool) -- Exception handler + -> GHCi (Maybe String) -> GHCi () +runCommands' eh getCmd = do mb_cmd <- noSpace queryQueue mb_cmd <- maybe (noSpace getCmd) (return . Just) mb_cmd case mb_cmd of Nothing -> return () Just c -> do - b <- ghciHandle handler (doCommand c) - if b then return () else runCommands getCmd + b <- ghciHandle eh (doCommand c) + if b then return () else runCommands' eh getCmd where noSpace q = q >>= maybe (return Nothing) (\c->case removeSpaces c of @@ -642,24 +658,6 @@ enqueueCommands cmds = do setGHCiState st{ cmdqueue = cmds ++ cmdqueue st } --- This version is for the GHC command-line option -e. The only difference --- from runCommand is that it catches the ExitException exception and --- exits, rather than printing out the exception. -runCommandEval :: String -> GHCi Bool -runCommandEval c = ghciHandle handleEval (doCommand c) - where - handleEval (ExitException code) = io (exitWith code) - handleEval e = do handler e - io (exitWith (ExitFailure 1)) - - doCommand (':' : command) = specialCommand command - doCommand stmt - = do r <- runStmt stmt GHC.RunToCompletion - case r of - False -> io (exitWith (ExitFailure 1)) - -- failure to run the command causes exit(1) for ghc -e. - _ -> return True - runStmt :: String -> SingleStep -> GHCi Bool runStmt stmt step | null (filter (not.isSpace) stmt) = return False