|
Packit |
2cbdf3 |
#!/usr/bin/runhaskell
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
\begin{code}
|
|
Packit |
2cbdf3 |
module Main where
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
import Distribution.Verbosity
|
|
Packit |
2cbdf3 |
import Distribution.PackageDescription (PackageDescription(..))
|
|
Packit |
2cbdf3 |
import Distribution.Simple.Setup ( BuildFlags(..), buildVerbosity, fromFlagOrDefault )
|
|
Packit |
2cbdf3 |
import Distribution.Simple ( defaultMainWithHooks, simpleUserHooks, UserHooks(..) )
|
|
Packit |
2cbdf3 |
import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(..) )
|
|
Packit |
2cbdf3 |
import Distribution.Simple.Program
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
import System.FilePath (())
|
|
Packit |
2cbdf3 |
import Control.Exception ( IOException, try )
|
|
Packit |
2cbdf3 |
import System.Directory (removeFile)
|
|
Packit |
2cbdf3 |
import Data.Char
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
main :: IO ()
|
|
Packit |
2cbdf3 |
main = defaultMainWithHooks simpleUserHooks{ postBuild = myPostBuild,
|
|
Packit |
2cbdf3 |
postClean = myPostClean,
|
|
Packit |
2cbdf3 |
copyHook = myCopy,
|
|
Packit |
2cbdf3 |
instHook = myInstall }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
-- hack to turn cpp-style '# 27 "GenericTemplate.hs"' into
|
|
Packit |
2cbdf3 |
-- '{-# LINE 27 "GenericTemplate.hs" #-}'.
|
|
Packit |
2cbdf3 |
mungeLinePragma line = case symbols line of
|
|
Packit |
2cbdf3 |
syms | Just prag <- getLinePrag syms -> prag
|
|
Packit |
2cbdf3 |
-- Also convert old-style CVS lines, no idea why we do this...
|
|
Packit |
2cbdf3 |
("--":"$":"Id":":":_) -> filter (/='$') line
|
|
Packit |
2cbdf3 |
( "$":"Id":":":_) -> filter (/='$') line
|
|
Packit |
2cbdf3 |
_ -> line
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
getLinePrag :: [String] -> Maybe String
|
|
Packit |
2cbdf3 |
getLinePrag ("#" : n : string : rest)
|
|
Packit |
2cbdf3 |
| length rest <= 1 -- clang puts an extra field
|
|
Packit |
2cbdf3 |
, length string >= 2 && head string == '"' && last string == '"'
|
|
Packit |
2cbdf3 |
, all isDigit n
|
|
Packit |
2cbdf3 |
= Just $ "{-# LINE " ++ n ++ " " ++ string ++ " #-}"
|
|
Packit |
2cbdf3 |
getLinePrag other = Nothing
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
symbols :: String -> [String]
|
|
Packit |
2cbdf3 |
symbols cs = case lex cs of
|
|
Packit |
2cbdf3 |
(sym, cs'):_ | not (null sym) -> sym : symbols cs'
|
|
Packit |
2cbdf3 |
_ -> []
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
myPostBuild _ flags _ lbi = do
|
|
Packit |
2cbdf3 |
let verbosity = fromFlagOrDefault normal (buildVerbosity flags)
|
|
Packit |
2cbdf3 |
runProgram p = rawSystemProgramConf verbosity p (withPrograms lbi)
|
|
Packit |
2cbdf3 |
cpp_template src dst opts = do
|
|
Packit |
2cbdf3 |
let tmp = dst ++ ".tmp"
|
|
Packit |
2cbdf3 |
runProgram ghcProgram (["-o", tmp, "-E", "-cpp", "templates" src] ++ opts)
|
|
Packit |
2cbdf3 |
writeFile dst . unlines . map mungeLinePragma . lines =<< readFile tmp
|
|
Packit |
2cbdf3 |
removeFile tmp
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
sequence_ ([ cpp_template "GenericTemplate.hs" dst opts | (dst,opts) <- templates ] ++
|
|
Packit |
2cbdf3 |
[ cpp_template "wrappers.hs" dst opts | (dst,opts) <- wrappers ])
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
myPostClean _ _ _ _ = let try' = try :: IO a -> IO (Either IOException a)
|
|
Packit |
2cbdf3 |
in mapM_ (try' . removeFile) all_template_files
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
myInstall pkg_descr lbi hooks flags =
|
|
Packit |
2cbdf3 |
instHook simpleUserHooks pkg_descr' lbi hooks flags
|
|
Packit |
2cbdf3 |
where pkg_descr' = pkg_descr {
|
|
Packit |
2cbdf3 |
dataFiles = dataFiles pkg_descr ++ all_template_files
|
|
Packit |
2cbdf3 |
}
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
myCopy pkg_descr lbi hooks copy_flags =
|
|
Packit |
2cbdf3 |
copyHook simpleUserHooks pkg_descr' lbi hooks copy_flags
|
|
Packit |
2cbdf3 |
where pkg_descr' = pkg_descr {
|
|
Packit |
2cbdf3 |
dataFiles = dataFiles pkg_descr ++ all_template_files
|
|
Packit |
2cbdf3 |
}
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
all_template_files :: [FilePath]
|
|
Packit |
2cbdf3 |
all_template_files = map fst (templates ++ wrappers)
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
templates :: [(FilePath,[String])]
|
|
Packit |
2cbdf3 |
templates = [
|
|
Packit |
2cbdf3 |
("AlexTemplate", []),
|
|
Packit |
2cbdf3 |
("AlexTemplate-ghc", ["-DALEX_GHC"]),
|
|
Packit |
2cbdf3 |
("AlexTemplate-ghc-nopred",["-DALEX_GHC", "-DALEX_NOPRED"]),
|
|
Packit |
2cbdf3 |
("AlexTemplate-ghc-debug", ["-DALEX_GHC","-DALEX_DEBUG"]),
|
|
Packit |
2cbdf3 |
("AlexTemplate-debug", ["-DALEX_DEBUG"])
|
|
Packit |
2cbdf3 |
]
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
wrappers :: [(FilePath,[String])]
|
|
Packit |
2cbdf3 |
wrappers = [
|
|
Packit |
2cbdf3 |
("AlexWrapper-basic", ["-DALEX_BASIC"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-basic-bytestring", ["-DALEX_BASIC_BYTESTRING"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-strict-bytestring", ["-DALEX_STRICT_BYTESTRING"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-posn", ["-DALEX_POSN"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-posn-bytestring", ["-DALEX_POSN_BYTESTRING"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-monad", ["-DALEX_MONAD"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-monad-bytestring", ["-DALEX_MONAD_BYTESTRING"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-monadUserState", ["-DALEX_MONAD", "-DALEX_MONAD_USER_STATE"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-monadUserState-bytestring", ["-DALEX_MONAD_BYTESTRING", "-DALEX_MONAD_USER_STATE"]),
|
|
Packit |
2cbdf3 |
("AlexWrapper-gscan", ["-DALEX_GSCAN"])
|
|
Packit |
2cbdf3 |
]
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
\end{code}
|