X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2FInteractiveUI.hs;h=8eb94f1c57aec5f1f7cc9c60454bf82a9761333d;hb=4a343629ebe5be2c5b27e84c031e38abd81122fa;hp=323dc259c71339092b4ba7fdcf3757a4ffd25219;hpb=342b18fc5abca755d55a07449ea7183222782865;p=ghc-hetmet.git diff --git a/ghc/InteractiveUI.hs b/ghc/InteractiveUI.hs index 323dc25..8eb94f1 100644 --- a/ghc/InteractiveUI.hs +++ b/ghc/InteractiveUI.hs @@ -2,6 +2,7 @@ -- -fno-cse is needed for GLOBAL_VAR's to behave properly {-# OPTIONS -#include "Linker.h" #-} +{-# OPTIONS_GHC -fno-warn-name-shadowing #-} ----------------------------------------------------------------------------- -- -- GHC Interactive User Interface @@ -38,7 +39,6 @@ import Outputable hiding (printForUser, printForUserPartWay) import Module -- for ModuleEnv import Name import SrcLoc -import ObjLink -- Other random utilities import CmdLineParser @@ -53,6 +53,7 @@ import NameSet import Maybes ( orElse, expectJust ) import FastString import Encoding +import Foreign.C #ifndef mingw32_HOST_OS import System.Posix hiding (getEnv) @@ -87,7 +88,14 @@ import Control.Monad as Monad import Text.Printf import Foreign import GHC.Exts ( unsafeCoerce# ) + +#if __GLASGOW_HASKELL__ >= 611 +import GHC.IO.Exception ( IOErrorType(InvalidArgument) ) +import GHC.IO.Handle ( hFlushAll ) +#else import GHC.IOBase ( IOErrorType(InvalidArgument) ) +#endif + import GHC.TopHandler import Data.IORef ( IORef, readIORef, writeIORef ) @@ -283,14 +291,16 @@ findEditor = do return "" #endif +foreign import ccall unsafe "rts_isProfiled" isProfiled :: IO CInt + interactiveUI :: [(FilePath, Maybe Phase)] -> Maybe [String] -> Ghc () interactiveUI srcs maybe_exprs = do -- although GHCi compiles with -prof, it is not usable: the byte-code -- compiler and interpreter don't work with profiling. So we check for -- this up front and emit a helpful error message (#2197) - m <- liftIO $ lookupSymbol "PushCostCentre" - when (isJust m) $ + i <- liftIO $ isProfiled + when (i /= 0) $ ghcError (InstallationError "GHCi cannot be used when compiled with -prof") -- HACK! If we happen to get into an infinite loop (eg the user @@ -419,7 +429,7 @@ runGHCi paths maybe_exprs = do Nothing -> do -- enter the interactive loop - runGHCiInput $ runCommands $ haskelineLoop show_prompt + runGHCiInput $ runCommands $ nextInputLine show_prompt is_tty Just exprs -> do -- just evaluate the expression we were given enqueueCommands exprs @@ -447,13 +457,14 @@ runGHCiInput f = do setLogAction f --- TODO really bad name -haskelineLoop :: Bool -> InputT GHCi (Maybe String) -haskelineLoop show_prompt = do +nextInputLine :: Bool -> Bool -> InputT GHCi (Maybe String) +nextInputLine show_prompt is_tty + | is_tty = do prompt <- if show_prompt then lift mkPrompt else return "" - l <- getInputLine prompt - return l - + getInputLine prompt + | otherwise = do + when show_prompt $ lift mkPrompt >>= liftIO . putStr + fileLoop stdin -- NOTE: We only read .ghci files if they are owned by the current user, -- and aren't world writable. Otherwise, we could be accidentally @@ -489,7 +500,7 @@ checkPerms name = fileLoop :: MonadIO m => Handle -> InputT m (Maybe String) fileLoop hdl = do - l <- liftIO $ IO.try (BS.hGetLine hdl) + l <- liftIO $ IO.try $ hGetLine hdl case l of Left e | isEOFError e -> return Nothing | InvalidArgument <- etype -> return Nothing @@ -499,7 +510,7 @@ fileLoop hdl = do -- this can happen if the user closed stdin, or -- perhaps did getContents which closes stdin at -- EOF. - Right l -> fmap Just (Encoding.decode l) + Right l -> return (Just l) mkPrompt :: GHCi String mkPrompt = do @@ -623,7 +634,16 @@ runStmt stmt step | null (filter (not.isSpace) stmt) = return False | ["import", mod] <- words stmt = keepGoing' setContext ('+':mod) | otherwise - = do result <- GhciMonad.runStmt stmt step + = do +#if __GLASGOW_HASKELL__ >= 611 + -- In the new IO library, read handles buffer data even if the Handle + -- is set to NoBuffering. This causes problems for GHCi where there + -- are really two stdin Handles. So we flush any bufferred data in + -- GHCi's stdin Handle here (only relevant if stdin is attached to + -- a file, otherwise the read buffer can't be flushed). + liftIO $ IO.try $ hFlushAll stdin +#endif + result <- GhciMonad.runStmt stmt step afterRunStmt (const True) result --afterRunStmt :: GHC.RunResult -> GHCi Bool