hinstaller-2007.4.23: src/System/Installer/TH.hs
{-
System.Installer : Installer wrapper for Haskell applications
Copyright (C) 2007 Matthew Sackman
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
-}
{-# LANGUAGE TemplateHaskell #-}
module System.Installer.TH
(makeInstallFuncCase,
makeDataDecls,
makeInstallFunc,
makeImportDecl
)
where
import System.FilePath
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import System.Installer.Foreign
makeInstallFuncCase :: String -> (String, FilePath) -> Q Clause
makeInstallFuncCase funcName (clauseName, filepath)
= result
where
result = clause [conP dataName []]
(normalB [| writeFileData $ptr $len filename |]) []
filename = takeFileName filepath
dataName = mkName $ "Installer_" ++ fullName
fullName = funcName ++ "_" ++ clauseName
ptr = varE $ mkName ("installer_" ++ fullName)
len = varE $ mkName ("installer_" ++ fullName ++ "_length")
makeInstallFunc :: String -> [Q Clause] -> Q Dec
makeInstallFunc funcName clauses
= funD (mkName funcName) clauses
makeDataDecls :: String -> [(String, FilePath)] -> Q [Dec]
makeDataDecls base names
= do { dataDecl' <- dataDecl
; instanceDecl' <- instanceDecl
; return [dataDecl', instanceDecl']
}
where
dataDecl = dataD (cxt []) dataDeclName []
constructors $ map mkName ["Eq", "Ord", "Enum"]
instanceDecl = instanceD (cxt []) (appT (conT (mkName "Show"))
(conT dataDeclName))
[showFuncs]
showFuncs = funD (mkName "show") $ map makeShowFunc names
dataDeclName = mkName $ "Installer_" ++ base
constructors = map makeDataCons names
makeDataCons :: (String, FilePath) -> Q Con
makeDataCons (name, _)
= normalC (mkName $ "Installer_" ++ base ++ "_" ++ name) []
makeShowFunc :: (String, FilePath) -> Q Clause
makeShowFunc (name, _)
= clause [conP dataName []] (normalB . litE . stringL $ name) []
where
dataName = mkName $ "Installer_" ++ base ++ "_" ++ name
makeImportDecl :: String -> (String, FilePath, FilePath) -> Q [Dec]
makeImportDecl funcName (clauseName, _, tmpPathCHeader)
= makeImportDecl' ("installer_" ++ funcName ++ "_" ++ clauseName)
tmpPathCHeader
makeImportDecl' :: String -> FilePath -> Q [Dec]
makeImportDecl' prefix headerFile
= return [fileDataImport, fileLengthImport]
where
fileLengthImport = ForeignD
(ImportF CCall Safe
("static " ++ headerFile ++ " " ++ prefix ++ "_length")
(mkName $ prefix ++ "_length")
(ConT (mkName "CInt"))
)
fileDataImport = ForeignD
(ImportF CCall Safe
("static " ++ headerFile ++ " " ++ prefix)
(mkName $ prefix)
(AppT (ConT (mkName "Ptr"))
(ConT (mkName "CUChar"))
)
)