Skip to content

Commit 42cfcf1

Browse files
committed
Fix prefixing issues after by-chunk logic
1 parent 7deb492 commit 42cfcf1

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

par.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ executable par
2828
, interpolatedstring-perl6
2929
, optparse-applicative
3030
, process
31+
, safe
3132
, semigroups
3233
, stm
3334
, string-class

src/Main.hs

+24-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
{-# LANGUAGE OverloadedStrings #-}
2-
{-# LANGUAGE QuasiQuotes #-}
1+
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE QuasiQuotes #-}
3+
{-# LANGUAGE ScopedTypeVariables #-}
34

45
module Main where
56

@@ -9,15 +10,16 @@ import Control.Concurrent.MVar
910
import Control.Concurrent.STM
1011
import Control.Exception (finally)
1112
import Control.Exception.Enclosed (handleAny)
12-
import Control.Monad (MonadPlus (..))
1313
import Data.ByteString (ByteString)
1414
import qualified Data.ByteString as B
15+
import qualified Data.ByteString.Char8 as BSC8
1516
import Data.Foldable
1617
import qualified Data.List as L
1718
import qualified Data.List.NonEmpty as NL
1819
import Data.String.Class (toStrictByteString)
1920
import Options.Applicative
2021
import Prelude hiding (mapM, mapM_)
22+
import Safe
2123
import SlaveThread (fork)
2224
import System.Exit
2325
import System.IO
@@ -69,8 +71,8 @@ runSingle outQ errQ cmdBig = do
6971
(_, Just hout, Just herr, ph) <-
7072
createProcess (shell cmd){ std_out = CreatePipe
7173
, std_err = CreatePipe }
72-
(_, w1) <- forkW (forwardHandler hout outQ (\s -> [toBs cmdPrefix <> s]))
73-
(_, w2) <- forkW (forwardHandler herr errQ (\s -> [toBs cmdPrefix <> s]))
74+
(_, w1) <- forkW (forwardHandler hout outQ prefixer)
75+
(_, w2) <- forkW (forwardHandler herr errQ prefixer)
7476
res <- waitForProcess ph
7577
waitSignal w1 >> waitSignal w2
7678
return res
@@ -82,18 +84,28 @@ runSingle outQ errQ cmdBig = do
8284
else (cmdBig, "")
8385
parprefix = "PARPREFIX="
8486
toBs = toStrictByteString
87+
prefixer chunk isNewline = if isNewline
88+
then [toBs cmdPrefix <> chunk]
89+
else [chunk]
8590

86-
forwardHandler :: (MonadPlus mp, Foldable mp)
87-
=> Handle -> TBQueue (Maybe ByteString) -> (ByteString -> mp ByteString) -> IO ()
88-
forwardHandler from to f = fin (hndl go)
91+
forwardHandler :: Handle
92+
-> TBQueue (Maybe ByteString)
93+
-> (ByteString -> Bool -> [ByteString])
94+
-> IO ()
95+
forwardHandler from to f = fin (hndl (go True))
8996
where
90-
go = do
97+
go endedNewline = do
9198
eof <- hIsEOF from
9299
if eof then return ()
93100
else do
94-
l <- B.hGetSome from (1024 * 1024)
95-
mapM_ (\s -> atomically (writeTBQueue to (Just s))) (f l)
96-
go
101+
chunk <- B.hGetSome from (1024 * 1024)
102+
let ls = BSC8.split '\n' chunk
103+
let fl = f (headDef "" ls) endedNewline
104+
rest = msum (map (\l -> f l True) (tailDef [] ls))
105+
lastEmpty = last ls == ""
106+
rest' = if lastEmpty then init rest else rest
107+
mapM_ (\l -> atomically (writeTBQueue to (Just (l <> "\n")))) (fl <> rest')
108+
go lastEmpty
97109
hndl = handleAny (const (return ()))
98110
fin f' = finally f' (atomically (writeTBQueue to Nothing))
99111

0 commit comments

Comments
 (0)