X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=utils%2Frunghc%2Frunghc.hs;h=e2cea312317001411e1efe272ccb19b93cf1bb84;hp=a55fdca07d784de1f28a4e57b426b5c7ff6e5d21;hb=0843c0bdc66008008d38eff07c90437ed56d9ca1;hpb=b0616f49e428debba01e7262e582eb7c16306585 diff --git a/utils/runghc/runghc.hs b/utils/runghc/runghc.hs index a55fdca..e2cea31 100644 --- a/utils/runghc/runghc.hs +++ b/utils/runghc/runghc.hs @@ -27,54 +27,68 @@ import System.IO import Data.List import System.Exit import Data.Char - -#ifdef USING_COMPAT -import Compat.RawSystem ( rawSystem ) -import Compat.Directory ( findExecutable ) -#else +import System.Directory ( removeFile ) +import Control.Exception ( bracket ) +import System.Directory ( findExecutable, getTemporaryDirectory ) import System.Cmd ( rawSystem ) -import System.Directory ( findExecutable ) -#endif main :: IO () main = do args <- getArgs - case args of - "-f" : ghc : args' -> doIt ghc args' - ('-' : 'f' : ghc) : args' -> doIt (dropWhile isSpace ghc) args' - _ -> do + case getGhcLoc args of + (Just ghc, args') -> doIt ghc args' + (Nothing, args') -> do mb_ghc <- findExecutable "ghc" case mb_ghc of Nothing -> dieProg ("cannot find ghc") - Just ghc -> doIt ghc args + Just ghc -> doIt ghc args' + +getGhcLoc :: [String] -> (Maybe FilePath, [String]) +getGhcLoc ("-f" : ghc : args) = (Just ghc, args) +getGhcLoc (('-' : 'f' : ghc) : args) = (Just ghc, args) +-- If you need the first GHC flag to be a -f flag then you can pass -- +-- first +getGhcLoc ("--" : args) = (Nothing, args) +getGhcLoc args = (Nothing, args) doIt :: String -> [String] -> IO () doIt ghc args = do - let (ghc_args, rest) = break notArg args + let (ghc_args, rest) = getGhcArgs args case rest of - [] -> dieProg "syntax: runghc [-f GHCPATH] [GHC-ARGS] FILE ARG..." + [] -> do + -- behave like typical perl, python, ruby interpreters: + -- read from stdin + tmpdir <- getTemporaryDirectory + bracket + (openTempFile tmpdir "runghcXXXX.hs") + (\(filename,_) -> removeFile filename) + $ \(filename,h) -> do + getContents >>= hPutStr h + hClose h + doIt ghc (ghc_args ++ [filename]) filename : prog_args -> do - let expr = "System.Environment.withProgName " ++ show filename ++ - " (System.Environment.withArgs " ++ show prog_args ++ - " (GHC.TopHandler.runIOFastExit" ++ - " (Main.main Prelude.>> Prelude.return ())))" + let c1 = ":set prog " ++ show filename + c2 = ":main " ++ show prog_args res <- rawSystem ghc (["-ignore-dot-ghci"] ++ ghc_args ++ - [ "-e", expr, filename]) - -- runIOFastExit: makes exceptions raised by Main.main - -- behave in the same way as for a compiled program. - -- 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. - -- - -- Why (main >> return ()) rather than just main? Because - -- otherwise GHCi by default tries to evaluate the result - -- of the IO in order to show it (see #1200). + [ "-e", c1, "-e", c2, filename]) exitWith res -notArg :: String -> Bool -notArg ('-':_) = False -notArg _ = True +getGhcArgs :: [String] -> ([String], [String]) +getGhcArgs args + = let (ghcArgs, otherArgs) = case break pastArgs args of + (xs, "--":ys) -> (xs, ys) + (xs, ys) -> (xs, ys) + in (map unescape ghcArgs, otherArgs) + where unescape ('-':'-':'g':'h':'c':'-':'a':'r':'g':'=':arg) = arg + unescape arg = arg + +pastArgs :: String -> Bool +-- You can use -- to mark the end of the flags, in case you need to use +-- a file called -foo.hs for some reason. You almost certainly shouldn't, +-- though. +pastArgs "--" = True +pastArgs ('-':_) = False +pastArgs _ = True dieProg :: String -> IO a dieProg msg = do @@ -82,3 +96,6 @@ dieProg msg = do hPutStrLn stderr (p ++ ": " ++ msg) exitWith (ExitFailure 1) +-- usage :: String +-- usage = "syntax: runghc [-f GHC-PATH | --] [GHC-ARGS] [--] FILE ARG..." +