packages feed

hat-2.9.0.0: tools/HatMake.hs

-- Simple 'make' for tracing
-- only works with ghc
-- authors: Neil Mitchel, Olaf Chitil
module Main where

import System.Environment (getArgs)
import System.Process (system)
import System.Exit (ExitCode(..), exitFailure)
import Data.List (nub, partition, isPrefixOf, intersperse, concat)
import Data.Char (isSpace)
import System.Directory (doesFileExist, findExecutable)
import Control.Monad (when)


main = do x <- getArgs
          Just hatPath <- findExecutable "hat-make"
          let hatFolder = dropFilename hatPath
          when (null x) (error "Please give the name of the file to hat-make on the command line")
          let opts = init x
          let optStr = concat (intersperse " " opts)
          let y = last x
          systemTry $ "ghc -M -dep-makefile .depend -dep-suffix \"\" " 
                      ++ y ++ " " ++ optStr
          mak <- readFile ".depend"
          let (files,depends) = parseMakefile mak
          translate hatFolder files depends
          compileAll hatFolder optStr y

dropFilename x = reverse $ dropWhile (\x -> not $ x `elem` "\\/") $ reverse x


parseMakefile :: String -> ([String], [(String, String)])
parseMakefile src =
        (
            nub $ concat [[a,b] | (a,b) <- res]
            ,
            nub $ [(a,b) | (a,b) <- res, a /= b]
        )
    where
        res = concatMap f $ lines src
    
        f :: String -> [(String, String)]
        f ('#':_) = []
        f x = [(filename a, filename b)]
            where (a,_:b) = break (== ':') x

filename x = reverse $ tail $ dropWhile (/= '.') $ reverse $ filter (not . isSpace) x


translate :: String -> [String] -> [(String, String)] -> IO ()
translate hatFolder files deps =
        if null files then return ()
        else if null yes then error "Circular dependancies"
        else mapM_ (translateFile hatFolder) yes >> translate hatFolder no newdeps
    where
        newdeps = [(a,b) | (a,b) <- deps, not (b `elem` yes)]
        (yes,no) = partition isDoable files
        isDoable x = not $ any ((==) x . fst) deps


translateFile :: String -> FilePath -> IO ()
translateFile hatFolder file = do
    fil <- pickFile file
    putStrLn $ "Converting with Hat, " ++ fil
    systemTry $ "hat-trans " ++ fil


pickFile :: FilePath -> IO FilePath
pickFile x = do hs  <- doesFileExist (x++".hs")
                lhs <- doesFileExist (x++".lhs")
                return $ if lhs then x ++ ".lhs" else x ++ ".hs"

compileAll :: String -> String -> String -> IO ()
compileAll hatFolder optStr file = do
    putStrLn "Compiling with GHC..."
    systemTry $ "ghc --make Hat/" ++ file ++ " " ++ optStr
                    -- " -ffi -fglasgow-exts -cpp -i.;" ++
                    -- hatFolder ++ "/hs " ++
                    -- hatFolder ++ "/c/hat-c.o " ++
                    -- hatFolder ++ "/c/ntohl.o"

systemTry :: String -> IO ()
systemTry x = do putStrLn x
                 y <- system x
                 when (y /= ExitSuccess) exitFailure


prettyFile :: FilePath -> FilePath
prettyFile x = x  -- for Unix
-- prettyFile x = map g (if "./" `isPrefixOf` x then drop 2 x else x)
--     where
--        g '/' = '\\'
--        g x = x