{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.Program.ResponseFile (withResponseFile) where
import Prelude ()
import System.IO (TextEncoding, hSetEncoding, hPutStr, hClose)
import Distribution.Compat.Prelude
import Distribution.Simple.Utils (TempFileOptions, withTempFileEx, debug)
import Distribution.Verbosity
withResponseFile
:: Verbosity
-> TempFileOptions
-> FilePath
-> FilePath
-> Maybe TextEncoding
-> [String]
-> (FilePath -> IO a)
-> IO a
withResponseFile verbosity tmpFileOpts workDir fileNameTemplate encoding arguments f =
withTempFileEx tmpFileOpts workDir fileNameTemplate $ \responseFileName hf -> do
traverse_ (hSetEncoding hf) encoding
let responseContents = unlines $ map escapeResponseFileArg arguments
hPutStr hf responseContents
hClose hf
debug verbosity $ responseFileName ++ " contents: <<<"
debug verbosity responseContents
debug verbosity $ ">>> " ++ responseFileName
f responseFileName
escapeResponseFileArg :: String -> String
escapeResponseFileArg = reverse . foldl' escape []
where
escape :: String -> Char -> String
escape cs c =
case c of
'\\' -> c:'\\':cs
'\'' -> c:'\\':cs
'"' -> c:'\\':cs
_ | isSpace c -> c:'\\':cs
| otherwise -> c:cs