[project @ 2000-12-20 10:33:25 by simonmar]
[ghc-hetmet.git] / ghc / compiler / main / DriverUtil.hs
index 08d02c6..e1311fe 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: DriverUtil.hs,v 1.9 2000/11/19 19:40:08 simonmar Exp $
+-- $Id: DriverUtil.hs,v 1.15 2000/12/12 14:35:08 simonmar Exp $
 --
 -- Utils for the driver
 --
@@ -9,10 +9,11 @@
 
 module DriverUtil where
 
+#include "../includes/config.h"
 #include "HsVersions.h"
 
-import Config
 import Util
+import Panic
 
 import IOExts
 import Exception
@@ -21,6 +22,7 @@ import RegexString
 
 import IO
 import System
+import Directory ( removeFile )
 import List
 import Char
 import Monad
@@ -28,8 +30,6 @@ import Monad
 -----------------------------------------------------------------------------
 -- Errors
 
-short_usage = "Usage: For basic information, try the `--help' option."
-   
 GLOBAL_VAR(v_Path_usage,  "",  String)
 
 long_usage = do
@@ -39,38 +39,9 @@ long_usage = do
   exitWith ExitSuccess
   where
      dump "" = return ()
-     dump ('$':'$':s) = hPutStr stderr prog_name >> dump s
+     dump ('$':'$':s) = hPutStr stderr progName >> dump s
      dump (c:s) = hPutChar stderr c >> dump s
 
-data BarfKind
-  = PhaseFailed String ExitCode
-  | Interrupted
-  | UsageError String                  -- prints the short usage msg after the error
-  | OtherError String                  -- just prints the error message
-  deriving Eq
-
-prog_name = unsafePerformIO (getProgName)
-{-# NOINLINE prog_name #-}
-
-instance Show BarfKind where
-  showsPrec _ e = showString prog_name . showString ": " . showBarf e
-
-showBarf (UsageError str)
-   = showString str . showChar '\n' . showString short_usage
-showBarf (OtherError str)
-   = showString str
-showBarf (PhaseFailed phase code)
-   = showString phase . showString " failed, code = " . shows code
-showBarf (Interrupted)
-   = showString "interrupted"
-
-unknownFlagErr f = throwDyn (UsageError ("unrecognised flag: " ++ f))
-
-barfKindTc = mkTyCon "BarfKind"
-{-# NOINLINE barfKindTc #-}
-instance Typeable BarfKind where
-  typeOf _ = mkAppTy barfKindTc []
-
 -----------------------------------------------------------------------------
 -- Reading OPTIONS pragmas
 
@@ -97,6 +68,9 @@ optionRegex = mkRegex "\\{-#[ \t]+OPTIONS[ \t]+(.*)#-\\}"   -- -}
 -----------------------------------------------------------------------------
 -- Utils
 
+unknownFlagErr :: String -> a
+unknownFlagErr f = throwDyn (UsageError ("unrecognised flag: " ++ f))
+
 my_partition :: (a -> Maybe b) -> [a] -> ([(a,b)],[a])
 my_partition _ [] = ([],[])
 my_partition p (a:as)
@@ -117,6 +91,9 @@ later = flip finally
 handleDyn :: Typeable ex => (ex -> IO a) -> IO a -> IO a
 handleDyn = flip catchDyn
 
+handle :: (Exception -> IO a) -> IO a -> IO a
+handle = flip Exception.catchAllIO
+
 split :: Char -> String -> [String]
 split c s = case rest of
                []     -> [chunk] 
@@ -134,17 +111,16 @@ addNoDups var x = do
   unless (x `elem` xs) $ writeIORef var (x:xs)
 
 splitFilename :: String -> (String,String)
-splitFilename f = (reverse (stripDot rev_basename), reverse rev_ext)
-  where (rev_ext, rev_basename) = span ('.' /=) (reverse f)
-        stripDot ('.':xs) = xs
-        stripDot xs       = xs
+splitFilename f = split_longest_prefix f '.'
 
 -- "foo/bar/xyzzy.ext" -> ("foo/bar", "xyzzy", ".ext")
 splitFilename3 :: String -> (String,String,String)
 splitFilename3 str
-   = let dir = getdir str
-         (name, ext) = splitFilename (drop (length dir) str)
-     in  (dir, name, ext)
+   = let (dir, rest) = split_longest_prefix str '/'
+        (name, ext) = splitFilename rest
+        real_dir | null dir  = "."
+                 | otherwise = dir
+     in  (real_dir, name, ext)
 
 remove_suffix :: Char -> String -> String
 remove_suffix c s
@@ -160,6 +136,16 @@ take_longest_prefix :: String -> Char -> String
 take_longest_prefix s c = reverse pre
   where (_suf,pre) = break (==c) (reverse s)
 
+-- split a string at the last occurence of 'c', returning the two
+-- parts of the string with the 'c' removed.  If the string contains
+-- no 'c's, the entire string is returned in the second component.
+split_longest_prefix :: String -> Char -> (String,String)
+split_longest_prefix s c
+  = case pre of
+       []      -> ([], reverse suf)
+       (_:pre) -> (reverse pre, reverse suf)
+  where (suf,pre) = break (==c) (reverse s)
+
 newsuf :: String -> String -> String
 newsuf suf s = remove_suffix '.' s ++ suf
 
@@ -173,3 +159,24 @@ newdir dir s = dir ++ '/':drop_longest_prefix s '/'
 
 remove_spaces :: String -> String
 remove_spaces = reverse . dropWhile isSpace . reverse . dropWhile isSpace
+
+
+-- system that works feasibly under Windows (i.e. passes the command line to sh,
+-- because system() under Windows doesn't look at SHELL, and always uses CMD.EXE)
+kludgedSystem cmd phase_name
+ = do
+#ifndef mingw32_TARGET_OS
+   exit_code <- system cmd `catchAllIO` 
+                  (\_ -> throwDyn (PhaseFailed phase_name (ExitFailure 1)))
+#else
+   pid <- myGetProcessID
+   let tmp = "/tmp/sh" ++ show pid
+   h <- openFile tmp WriteMode
+   hPutStrLn h cmd
+   hClose h
+   exit_code <- system ("sh - " ++ tmp) `catchAllIO` 
+                  (\_ -> removeFile tmp >>
+                          throwDyn (PhaseFailed phase_name (ExitFailure 1)))
+   removeFile tmp
+#endif
+   return exit_code