This goes with the patch for #1839, #1463
[ghc-hetmet.git] / utils / runghc / runghc.hs
index 9346390..244c98f 100644 (file)
@@ -39,44 +39,50 @@ import System.Directory ( findExecutable )
 main :: IO ()
 main = do
     args <- getArgs
-    case args of
-        ("-f" : ghc : args) -> do
-            doIt ghc args
-        ('-' : 'f' : ghc) : args -> do
-            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..."
+        [] -> 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 ())))"
+            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
@@ -84,3 +90,6 @@ dieProg msg = do
     hPutStrLn stderr (p ++ ": " ++ msg)
     exitWith (ExitFailure 1)
 
+usage :: String
+usage = "syntax: runghc [-f GHC-PATH | --] [GHC-ARGS] [--] FILE ARG..."
+