{-# LANGUAGE CPP #-} -- | This module provides access to the Quipper preprocessor, in a -- format that can be used in custom Setup scripts to teach Cabal to -- compile Quipper programs. module Quipper.Distribution.Preprocessor where import Distribution.Simple.PreProcess import Distribution.Simple.Utils import System.Environment import System.Exit import System.IO import System.IO.Error import System.Process -- To prevent CPP from expanding a macro in a Haskell comment. #define literal(x) x -- | The Quipper preprocessor, in the format required by Cabal. This -- can be used in the @Setup.hs@ file of Cabal packages, for example -- like this: -- -- > {-# LANGUAGE CPP #-} -- > -- > import Distribution.Simple -- > import Quipper.Distribution.Preprocessor -- > -- > -- The following is needed because of an incompatible change in Cabal 2. -- > #if literal(MIN_VERSION)_Cabal(2,0,0) -- > wrap x = \_ _ _ -> x -- > #else -- > wrap x = \_ _ -> x -- > #endif -- > -- > main = defaultMainWithHooks simpleUserHooks { -- > hookedPreProcessors = [("hs", wrap ppQuipper)] -- > } ppQuipper :: PreProcessor ppQuipper = PreProcessor { platformIndependent = True, runPreProcessor = mkSimplePreProcessor f } where f inFile outFile verbosity = catchIOError body handler where body = do info verbosity ("Preprocessing " ++ inFile ++ " to " ++ outFile) (exitcode, out, err) <- readProcessWithExitCode "quipper-pp" [inFile, inFile, outFile] "" case exitcode of ExitSuccess -> return () ExitFailure n -> quipper_pp_error err handler e = do name <- getProgName hPutStrLn stdout "" hPutStrLn stdout $ name ++ ": unable to run the Quipper preprocessor. Please make sure that quipper-pp is installed and on your PATH. Note that quipper-pp can be found in the package quipper-language." hPutStrLn stdout "" exitFailure quipper_pp_error err = do hPutStrLn stdout "" hPutStrLn stdout err exitFailure