我已经浏览了cabal Distribution.Simple*包,知道PreProcessor数据类型可用于定义自定义预处理器.但是提供的示例并不那么有用.我不知道如何调用预处理器.
目前,我只是在Setup.hs文件中定义自己的预处理器.
这个功能有完整的例子吗?
[已编辑]
检查我刚发现的这个邮件列表存档.但解决方案涉及从一种类型的文件(由该文件的扩展名标识)转换为另一种类型的文件.
我想要做的是将代码注入到.hs定义了自定义标记的现有文件中,例如
-- <inject point="foo">
-- extra Haskell code goes here
-- </inject>
Run Code Online (Sandbox Code Playgroud)
最重要的事情之一是将.Cabal文件中的BuildType设置为Custom.如果它停留在Simple Cabal将完全忽略Setup.hs文件.
Build-Type: Custom
Run Code Online (Sandbox Code Playgroud)
这是我的包中的示例自定义预处理器,它首先运行cpphs然后运行hsc2hs
#!/usr/bin/env runhaskell
> {-# LANGUAGE BangPatterns #-}
> import Distribution.Simple
> import Distribution.Simple.PreProcess
> import Distribution.Simple.Utils
> import Distribution.PackageDescription
> import Distribution.Simple.LocalBuildInfo
> import Data.Char
> import System.Exit
> import System.IO
> import System.Directory
> import System.FilePath.Windows
> main = let hooks = simpleUserHooks
> xpp = ("xpphs", ppXpp)
> in defaultMainWithHooks hooks { hookedPreProcessors = xpp:knownSuffixHandlers }
>
> ppXpp :: BuildInfo -> LocalBuildInfo -> PreProcessor
> ppXpp build local =
> PreProcessor {
> platformIndependent = True,
> runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity ->
> do info verbosity (inFile++" is being preprocessed to "++outFile)
> let hscFile = replaceExtension inFile "hsc"
> runSimplePreProcessor (ppCpp build local) inFile hscFile verbosity
> handle <- openFile hscFile ReadMode
> source <- sGetContents handle
> hClose handle
> let newsource = unlines $ process $ lines source
> writeFile hscFile newsource
> runSimplePreProcessor (ppHsc2hs build local) hscFile outFile verbosity
> removeFile hscFile
> return ()
> }
Run Code Online (Sandbox Code Playgroud)
当找到任何扩展名为.xpphs的文件时,Cabal会自动调用此预处理器.
在您的情况下,只需使用.hs扩展名注册预处理器.(我不确定Cabal是否允许这样做.但如果没有,你可以简单地将注入点的文件重命名为.xh或者其他东西.这实际上会更好,因为你不处理项目中的每个文件然后)