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
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
29
    else useSuccessiveInvocations path flagArgs fileArgs
30 31 32 33 34 35

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

36 37
useSuccessiveInvocations :: FilePath -> [String] -> [String] -> Action ()
useSuccessiveInvocations path flagArgs fileArgs = do
38 39 40
    maxChunk <- cmdLineLengthLimit
    forM_ (chunksOfSize maxChunk fileArgs) $ \argsChunk ->
        unit . cmd [path] $ flagArgs ++ argsChunk