{-# LANGUAGE TupleSections #-} module Jukebox.Utils where import Data.List import qualified Jukebox.Seq as Seq import qualified Data.HashSet as Set import Data.Hashable import System.Process import qualified Data.ByteString.Char8 as BS import System.IO import System.Exit import Control.Applicative import Control.Concurrent usort :: Ord a => [a] -> [a] usort = map head . group . sort merge :: Ord a => [a] -> [a] -> [a] merge [] ys = ys merge xs [] = xs merge (x:xs) (y:ys) = case x `compare` y of LT -> x:merge xs (y:ys) EQ -> x:merge xs ys GT -> y:merge (x:xs) ys nub :: (Seq.List f, Ord a, Hashable a) => f a -> [a] nub = Set.toList . Set.fromList . Seq.toList popen :: FilePath -> [String] -> BS.ByteString -> IO (ExitCode, BS.ByteString) popen prog args inp = do (stdin, stdout, stderr_, pid) <- runInteractiveProcess prog args Nothing Nothing forkIO $ hGetContents stderr_ >>= hPutStr stderr BS.hPutStr stdin inp hFlush stdin hClose stdin code <- waitForProcess pid fmap (code,) (BS.hGetContents stdout) <* hClose stdout