Any example of a custom PreProcessor in Haskell?

前端 未结 1 1716
情深已故
情深已故 2021-01-06 16:04

I\'ve walked through the cabal Distribution.Simple* packages to know that the PreProcessor data type can be used to defined custom pre-processors.

相关标签:
1条回答
  • 2021-01-06 16:45

    One of the most important things to do is setting your BuildType in your .Cabal file to Custom. If it stays at Simple Cabal will completely ignore the Setup.hs file.

    Build-Type:     Custom
    

    Here is an example Custom preprocessor from my package, It first runs cpphs and then runs 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 ()
    >      }
    

    This preprocessor will automatically be called by Cabal when any file with the extension .xpphs is found.

    In your case just register the preprocessor with a .hs extension. (I'm not sure if Cabal allows this. But if it doesn't you can simply rename the files with the injection point to a .xh or something. This would actually be better since you don't process every file in your project then)

    0 讨论(0)
提交回复
热议问题