[project @ 2002-01-17 08:37:57 by sof]
[ghc-hetmet.git] / ghc / utils / hsc2hs / Main.hs
index b888f33..92aad1f 100644 (file)
@@ -1,5 +1,5 @@
 ------------------------------------------------------------------------
--- $Id: Main.hs,v 1.29 2001/03/29 17:56:18 qrczak Exp $
+-- $Id: Main.hs,v 1.35 2002/01/17 08:37:57 sof Exp $
 --
 -- Program for converting .hsc files to .hs files, by converting the
 -- file into a C program which is run to generate the Haskell source.
 -- See the documentation in the Users' Guide for more details.
 
 import GetOpt
-import System        (getProgName, getArgs, ExitCode(..), exitWith, exitFailure)
-import KludgedSystem (system, defaultCompiler)
+import Config
+import System        (getProgName, getArgs, ExitCode(..), exitWith, exitFailure, system)
 import Directory     (removeFile)
 import Monad         (MonadPlus(..), liftM, liftM2, when, unless)
 import Char          (isAlpha, isAlphaNum, isSpace, isDigit, toUpper, intToDigit, ord)
 import List          (intersperse)
 
+#include "../../includes/config.h"
+
+#ifdef mingw32_TARGET_OS
+import Win32DLL
+#endif
+
 version :: String
 version = "hsc2hs-0.65"
 
@@ -52,19 +58,27 @@ options = [
     Option "I" []             (ReqArg (CompFlag . ("-I"++))
                                                  "DIR")  "passed to the C compiler",
     Option "L" ["lflag"]      (ReqArg LinkFlag   "FLAG") "flag to pass to the linker",
-    Option ""  ["no-compile"] (NoArg  NoCompile)         "stop after writing *_hsc_make.c",
     Option "i" ["include"]    (ReqArg include    "FILE") "as if placed in the source",
     Option "D" ["define"]     (ReqArg define "NAME[=VALUE]") "as if placed in the source",
     Option "o" ["output"]     (ReqArg Output     "FILE") "name of main output file",
     Option ""  ["help"]       (NoArg  Help)              "display this help and exit",
-    Option ""  ["version"]    (NoArg  Version)           "output version information and exit"]
+    Option ""  ["version"]    (NoArg  Version)           "output version information and exit",
+    Option ""  ["no-compile"] (NoArg  NoCompile)         "stop after writing *_hsc_make.c"]
 
 main :: IO ()
 main = do
     prog <- getProgName
     let header = "Usage: "++prog++" [OPTIONS] INPUT.hsc [...]"
     args <- getArgs
-    case getOpt Permute options args of
+    let opts@(flags, files, errs) = getOpt Permute options args
+#ifdef mingw32_TARGET_OS
+    h <- getModuleHandle Nothing
+    n <- getModuleFileName h
+    let tempName = reverse (drop (length "\\bin\\hsc2hs.exe") (reverse n)) ++ "\\template-hsc.h"
+    let fflags = if [t | Template t <- flags] /= [] then flags else (Template tempName) : flags
+    let opts = (fflags, files, errs)
+#endif
+    case opts of
         (flags, _, _)
             | any isHelp    flags -> putStrLn (usageInfo header options)
             | any isVersion flags -> putStrLn version
@@ -430,12 +444,12 @@ output flags name toks = do
     
     let cProgName    = outDir++outBase++"_hsc_make.c"
         oProgName    = outDir++outBase++"_hsc_make.o"
-        progName     = outDir++outBase++"_hsc_make"
+        progName     = outDir++outBase++"_hsc_make" ++ progNameSuffix
         outHName     = outDir++outBase++"_hsc.h"
         outCName     = outDir++outBase++"_hsc.c"
-    
+
     let execProgName
-            | null outDir = "./"++progName
+            | null outDir = '.':pathSep:progName
             | otherwise   = progName
     
     let specials = [(pos, key, arg) | Special pos key arg <- toks]
@@ -454,7 +468,7 @@ output flags name toks = do
         _   -> onlyOne "compiler"
     
     linker <- case [l | Linker l <- flags] of
-        []  -> return defaultCompiler
+        []  -> return cGCC
         [l] -> return l
         _   -> onlyOne "linker"
     
@@ -494,15 +508,16 @@ output flags name toks = do
     removeFile progName
     
     when needsH $ writeFile outHName $
-        "#ifndef "++includeGuard++"\n\
-        \#define "++includeGuard++"\n\
-        \#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 409\n\
-        \#include <Rts.h>\n\
-        \#endif\n\
-        \#include <HsFFI.h>\n\
-        \#if __NHC__\n\
-        \#undef HsChar\n\
-        \#define HsChar int\n\
+        "#ifndef "++includeGuard++"\n\ 
+        \#define "++includeGuard++"\n\ 
+        \#if " ++
+       "__GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 409\n\ 
+        \#include <Rts.h>\n\ 
+        \#endif\n\ 
+        \#include <HsFFI.h>\n\ 
+        \#if __NHC__\n\ 
+        \#undef HsChar\n\ 
+        \#define HsChar int\n\ 
         \#endif\n"++
         concatMap outFlagH flags++
         concatMap outTokenH specials++
@@ -539,7 +554,7 @@ outHeaderCProg (pos, key, arg) = case key of
         (header, _:body) -> case break isSpace header of
             (name, args) ->
                 outCLine pos++
-                "#define hsc_"++name++"("++dropWhile isSpace args++") \
+                "#define hsc_"++name++"("++dropWhile isSpace args++") \ 
                 \printf ("++joinLines body++");\n"
     _ -> ""
     where
@@ -547,9 +562,11 @@ outHeaderCProg (pos, key, arg) = case key of
 
 outHeaderHs :: [Flag] -> Maybe String -> [(SourcePos, String, String)] -> String
 outHeaderHs flags inH toks =
-    "#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 409\n\
-    \    printf (\"{-# OPTIONS -optc-D__GLASGOW_HASKELL__=%d #-}\\n\", \
-    \__GLASGOW_HASKELL__);\n\
+    "#if " ++
+    "__GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 409\n\ 
+    \    printf (\"{-# OPTIONS -optc-D" ++
+    "__GLASGOW_HASKELL__=%d #-}\\n\", \ 
+    \__GLASGOW_HASKELL__);\n\ 
     \#endif\n"++
     case inH of
         Nothing -> concatMap outFlag flags++concatMap outSpecial toks
@@ -608,11 +625,11 @@ outEnum arg =
                     (enum, rest) -> let
                         this = case break (== '=') $ dropWhile isSpace enum of
                             (name, []) ->
-                                "    hsc_enum ("++t++", "++f++", \
+                                "    hsc_enum ("++t++", "++f++", \ 
                                 \hsc_haskellize (\""++name++"\"), "++
                                 name++");\n"
                             (hsName, _:cName) ->
-                                "    hsc_enum ("++t++", "++f++", \
+                                "    hsc_enum ("++t++", "++f++", \ 
                                 \printf (\"%s\", \""++hsName++"\"), "++
                                 cName++");\n"
                         in this++enums rest
@@ -634,8 +651,8 @@ outTokenH (pos, key, arg) =
             's':'t':'r':'u':'c':'t':' ':_ -> arg++"\n"
             't':'y':'p':'e':'d':'e':'f':' ':_ -> arg++"\n"
             'i':'n':'l':'i':'n':'e':' ':_ ->
-                "#ifdef __GNUC__\n\
-                \extern\n\
+                "#ifdef __GNUC__\n\ 
+                \extern\n\ 
                 \#endif\n"++
                 arg++"\n"
             _ -> "extern "++header++";\n"
@@ -649,19 +666,20 @@ outTokenC (pos, key, arg) =
         "def" -> case arg of
             's':'t':'r':'u':'c':'t':' ':_ -> ""
             't':'y':'p':'e':'d':'e':'f':' ':_ -> ""
-            'i':'n':'l':'i':'n':'e':' ':_ ->
-                outCLine pos++
-                "#ifndef __GNUC__\n\
-                \extern\n\
-                \#endif\n"++
-                header++
-                "\n#ifndef __GNUC__\n\
-                \;\n\
-                \#else\n"++
-                body++
-                "\n#endif\n"
+            'i':'n':'l':'i':'n':'e':' ':arg' ->
+               case span (\c -> c /= '{' && c /= '=') arg' of
+               (header, body) ->
+                   outCLine pos++
+                   "#ifndef __GNUC__\n\ 
+                   \extern inline\n\ 
+                   \#endif\n"++
+                   header++
+                   "\n#ifndef __GNUC__\n\ 
+                   \;\n\ 
+                   \#else\n"++
+                   body++
+                   "\n#endif\n"
             _ -> outCLine pos++arg++"\n"
-            where (header, body) = span (\c -> c /= '{' && c /= '=') arg
         _ | conditional key -> outCLine pos++"#"++key++" "++arg++"\n"
         _ -> ""