module Argon.Preprocess
(
CppOptions(..)
, defaultCppOptions
, getPreprocessedSrcDirect
) where
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>))
#endif
import qualified GHC
import qualified DynFlags as GHC
import qualified MonadUtils as GHC
import qualified DriverPhases as GHC
import qualified DriverPipeline as GHC
import qualified HscTypes as GHC
data CppOptions = CppOptions
{ cppDefine :: [String]
, cppInclude :: [FilePath]
, cppFile :: [FilePath]
}
defaultCppOptions :: CppOptions
defaultCppOptions = CppOptions [] [] []
getPreprocessedSrcDirect :: (GHC.GhcMonad m)
=> CppOptions
-> FilePath
-> m (String, GHC.DynFlags)
getPreprocessedSrcDirect cppOptions file = do
hscEnv <- GHC.getSession
let dfs = GHC.hsc_dflags hscEnv
newEnv = hscEnv { GHC.hsc_dflags = injectCppOptions cppOptions dfs }
(dflags', hspp_fn) <-
GHC.liftIO $ GHC.preprocess newEnv (file, Just (GHC.Cpp GHC.HsSrcFile))
txt <- GHC.liftIO $ readFile hspp_fn
return (txt, dflags')
injectCppOptions :: CppOptions -> GHC.DynFlags -> GHC.DynFlags
injectCppOptions CppOptions{..} dflags =
foldr addOptP dflags (map mkDefine cppDefine ++ map mkIncludeDir cppInclude
++ map mkInclude cppFile)
where
mkDefine = ("-D" ++)
mkIncludeDir = ("-I" ++)
mkInclude = ("-include" ++)
addOptP :: String -> GHC.DynFlags -> GHC.DynFlags
addOptP f = alterSettings (\s -> s { GHC.sOpt_P = f : GHC.sOpt_P s})
alterSettings :: (GHC.Settings -> GHC.Settings) -> GHC.DynFlags -> GHC.DynFlags
alterSettings f dflags = dflags { GHC.settings = f (GHC.settings dflags) }