import Data.Version import Control.Exception import System.Cmd import System.IO import System.Exit import System.Directory import Distribution.Setup import Distribution.Simple import Distribution.Simple.Utils import Distribution.Simple.LocalBuildInfo import Distribution.PackageDescription main = do descFile <- defaultPackageDesc desc <- readPackageDescription descFile let ver = (pkgVersion (package desc)) defaultMainWithHooks (mkHooks desc ver) mkHooks :: PackageDescription -> Version -> UserHooks mkHooks desc ver = defaultUserHooks { readDesc = return (Just desc) , postConf = doPostConf ver , postBuild = createTemplates , postClean = cleanDerivedFiles } templateFiles :: [String] templateFiles = [ "HappyTemplate" , "HappyTemplate-ghc" , "HappyTemplate-coerce" , "HappyTemplate-arrays" , "HappyTemplate-arrays-ghc" , "HappyTemplate-arrays-coerce" , "HappyTemplate-arrays-debug" , "HappyTemplate-arrays-ghc-debug" , "HappyTemplate-arrays-coerce-debug" , "GLR_Base" , "GLR_Lib" , "GLR_Lib-ghc" , "GLR_Lib-ghc-debug" ] cleanDerivedFiles :: Args -> Int -> LocalBuildInfo -> IO ExitCode cleanDerivedFiles args _ buildInfo = do sequence_ $ map (delFile . (\x -> "templates/"++x++".hspp")) $ templateFiles sequence_ $ map (delFile . (\x -> "templates/"++x)) $ templateFiles removeFile "src/Version.hs" return ExitSuccess where delFile path = try (removeFile path) >> return () doPostConf :: Version -> Args -> ConfigFlags -> LocalBuildInfo -> IO ExitCode doPostConf version args flags buildInfo = do case (compilerFlavor (compiler buildInfo)) of GHC -> do createVersionModule version return ExitSuccess _ -> do putStrLn "Currently only GHC is supported as a build platform for Happy" return (ExitFailure 1) createVersionModule :: Version -> IO () createVersionModule version = do h <- openFile "src/Version.hs" WriteMode hPutStr h "module Version where\n" hPutStr h ("version = \""++(showVersion version)++"\"") hClose h createTemplates :: Args -> Int -> LocalBuildInfo -> IO ExitCode createTemplates args _ buildInfo = do putStrLn "building parser templates..." pwd <- getCurrentDirectory setCurrentDirectory (pwd++"/templates") defaultTemplate "HappyTemplate" [] defaultTemplate "HappyTemplate-ghc" [ghcOpt] defaultTemplate "HappyTemplate-coerce" [ghcOpt,coerceOpt] defaultTemplate "HappyTemplate-arrays" [arrayOpt] defaultTemplate "HappyTemplate-arrays-ghc" [ghcOpt,arrayOpt] defaultTemplate "HappyTemplate-arrays-coerce" [ghcOpt,arrayOpt,coerceOpt] defaultTemplate "HappyTemplate-arrays-debug" [arrayOpt,debugOpt] defaultTemplate "HappyTemplate-arrays-ghc-debug" [arrayOpt,ghcOpt,debugOpt] defaultTemplate "HappyTemplate-arrays-coerce-debug" [ghcOpt,arrayOpt,coerceOpt,debugOpt] runCpp "GLR_Base" [] "GLR_Base.lhs" glrTemplate "GLR_Lib" [] glrTemplate "GLR_Lib-ghc" [ghcOpt] glrTemplate "GLR_Lib-ghc-debug" [ghcOpt,debugOpt] setCurrentDirectory pwd return ExitSuccess where ghc = compilerPath (compiler buildInfo) ghcOpt = "-DHAPPY_GHC" coerceOpt = "-DHAPPY_COERCE" arrayOpt = "-DHAPPY_ARRAY" debugOpt = "-DHAPPY_DEBUG" cppArgs = if (compilerVersion (compiler buildInfo)) >= Version{ versionBranch = [4,11,4], versionTags = [] } then ["-E","-cpp","-o"] else ["-E","-cpp",">"] perlRE = "s/^#\\s+(\\d+)\\s+(\\\"[^\\\"]*\\\")/{-# LINE \\1 \\2 #-}/g;s/\\$$(Id:.*)\\$$/\\1/g" runCpp file args template = do rawSystem ghc (concat [cppArgs,[file],args,[template]]) rawSystem "perl" ["-pi.hspp","-e",perlRE,file] defaultTemplate file args = runCpp file args "GenericTemplate.hs" glrTemplate file args = runCpp file args "GLR_Lib.lhs"