X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=utils%2Frunghc%2Frunghc.hs;h=707dc62be13d767986ba16f40c741fe5f481655b;hb=a6e4ca6e55cfc3f3fd3253df69e803c8a999729a;hp=83163bd401fd706ae162582950d5ca2f09f92ed7;hpb=373b03fe979abe898a387e02ca22007b768e343e;p=ghc-hetmet.git diff --git a/utils/runghc/runghc.hs b/utils/runghc/runghc.hs index 83163bd..707dc62 100644 --- a/utils/runghc/runghc.hs +++ b/utils/runghc/runghc.hs @@ -11,16 +11,16 @@ -- runghc program, for invoking from a #! line in a script. For example: -- -- script.lhs: --- #! /usr/bin/runghc --- > main = putStrLn "hello!" +-- #! /usr/bin/runghc +-- > main = putStrLn "hello!" -- -- runghc accepts one flag: -- --- -f specify the path +-- -f specify the path -- -- ----------------------------------------------------------------------------- -module Main where +module Main (main) where import System.Environment import System.IO @@ -36,42 +36,68 @@ import System.Cmd ( rawSystem ) import System.Directory ( findExecutable ) #endif -main = do - args <- getArgs - case args of - ('-':'f' : ghc) : args -> do - doIt (dropWhile isSpace ghc) args - args -> do - mb_ghc <- findExecutable "ghc" - case mb_ghc of - Nothing -> dieProg ("cannot find ghc") - Just ghc -> doIt ghc args +main :: IO () +main = do + args <- getArgs + 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' +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 - -- - case rest of - [] -> dieProg "syntax: runghc [-f GHCPATH] [GHC-ARGS] FILE ARG..." - filename : prog_args -> do - res <- rawSystem ghc ( - "-ignore-dot-ghci" : ghc_args ++ - [ "-e","System.Environment.withProgName "++show filename++" (System.Environment.withArgs [" - ++ concat (intersperse "," (map show prog_args)) - ++ "] (GHC.TopHandler.runIOFastExit Main.main))", filename]) + let (ghc_args, rest) = getGhcArgs args + case rest of + [] -> dieProg usage + 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 ())))" + 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. - exitWith res + -- + -- 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). + exitWith res + +getGhcArgs :: [String] -> ([String], [String]) +getGhcArgs args = case break pastArgs args of + (xs, "--":ys) -> (xs, ys) + (xs, ys) -> (xs, ys) -notArg ('-':_) = False -notArg _ = True +pastArgs :: String -> Bool +-- You can use -- to mark the end of the flags, in caes 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 - p <- getProgName - hPutStrLn stderr (p ++ ": " ++ msg) - exitWith (ExitFailure 1) + p <- getProgName + hPutStrLn stderr (p ++ ": " ++ msg) + exitWith (ExitFailure 1) + +usage :: String +usage = "syntax: runghc [-f GHC-PATH | --] [GHC-ARGS] [--] FILE ARG..." +