{-# LANGUAGE TemplateHaskell
, OverloadedStrings
, RecordWildCards
, PatternGuards #-}
module System.Posix.ARX.TMPXTools where
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as Bytes
import Data.Char
import Data.List
import Data.Maybe
import Data.Monoid
import Numeric
import qualified Blaze.ByteString.Builder as Blaze
import Data.FileEmbed
import Data.Hashable
data Template = Template { rm0 :: Bool,
rm1 :: Bool,
shared :: Bool,
tmpdir :: ByteString,
env :: Blaze.Builder,
run :: Blaze.Builder,
dat :: Blaze.Builder }
instance Show Template where
show Template{..} =
"Template { tmpdir=" ++ Bytes.unpack tmpdir
++ " rm0=" ++ tf rm0 ++ " rm1=" ++ tf rm1 ++
" shared=" ++ tf shared ++ " ... }"
where
tf True = "true"
tf False = "false"
render :: Template -> Blaze.Builder
render Template{..} = mconcat [ blaze a,
flags,
blaze b,
env,
blaze c,
run,
blaze d,
dat,
blaze e ]
where
flags = mconcat [ "rm0=", tf rm0, " ; ",
"rm1=", tf rm1, " ; ",
"shared=", tf shared, " ; ",
"hash=", (hexStr . hash) dat, " ; ",
"tmpdir=", blaze tmpdir, "\n" ]
hash = abs . Data.Hashable.hash . Blaze.toByteString
hexStr = blaze . Bytes.pack . hex
hex i = Numeric.showIntAtBase 16 Data.Char.intToDigit i ""
blaze = Blaze.fromByteString
tf True = "true"
tf False = "false"
a : b : c : d : e : [] = findChunks $(embedFile "./model-scripts/tmpx.sh")
findChunks :: ByteString -> [ByteString]
findChunks = coalesce . markHoles
coalesce :: [Maybe ByteString] -> [ByteString]
coalesce = reverse . catMaybes . foldl' f []
where
f [ ] item = [item]
f (Just a : t) (Just b) = Just (Bytes.append a b) : t
f (Nothing : t) (Just b) = Just b : Nothing : t
f (Just a : t) (Nothing) = Nothing : Just a : t
f (Nothing : t) (Nothing) = Nothing : t
markHoles :: ByteString -> [Maybe ByteString]
markHoles = map f . Bytes.lines
where
f l | isHole l = Nothing
| otherwise = Just (l `Bytes.snoc` '\n')
isHole :: ByteString -> Bool
isHole line = "# To be set by tool." `Bytes.isSuffixOf` line