Ar.hs 1.53 KB
Newer Older
1
module Settings.Builders.Ar (arArgs, arCmd) where
2

Ben Gamari's avatar
Ben Gamari committed
3
import Base
4
import Expression
5
import Oracles
6
import Predicates (builder)
7 8

arArgs :: Args
9 10 11
arArgs = builder Ar ? mconcat [ arg "q"
                              , arg =<< getOutput
                              , append =<< getInputs ]
12 13 14

-- This count includes arg "q" and arg file parameters in arArgs (see above).
-- Update this value appropriately when changing arArgs.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
arFlagsCount :: Int
arFlagsCount = 2

-- Ar needs to be invoked in a special way: we pass the list of files to be
-- archived via a temporary file as otherwise Ar (or rather Windows command
-- line) chokes up. Alternatively, we split argument list into chunks and call
-- ar multiple times (when passing files via a separate file is not supported).
arCmd :: FilePath -> [String] -> Action ()
arCmd path argList = do
    arSupportsAtFile <- flag ArSupportsAtFile
    let flagArgs = take arFlagsCount argList
        fileArgs = drop arFlagsCount argList
    if arSupportsAtFile
    then useAtFile path flagArgs fileArgs
    else useSuccessiveInvokations path flagArgs fileArgs

useAtFile :: FilePath -> [String] -> [String] -> Action ()
useAtFile path flagArgs fileArgs = withTempFile $ \tmp -> do
    writeFile' tmp $ unwords fileArgs
    cmd [path] flagArgs ('@' : tmp)

useSuccessiveInvokations :: FilePath -> [String] -> [String] -> Action ()
useSuccessiveInvokations path flagArgs fileArgs = do
    maxChunk <- cmdLineLengthLimit
    forM_ (chunksOfSize maxChunk fileArgs) $ \argsChunk ->
        unit . cmd [path] $ flagArgs ++ argsChunk