iterIO-0.1: Examples/fgrep.hs
module Main where
import qualified Data.ByteString.Lazy.Char8 as L8
import qualified Data.ByteString.Lazy as L
import Control.Monad
import Control.Monad.Trans
import System.Environment
import System.Exit
import System.IO
-- import System.IO.Error
import Data.IterIO
filterLines :: (Monad m) =>
String
-> Inum L.ByteString [L.ByteString] m a
filterLines s = mkInum loop
where
loop = do line <- lineI
if match line then return [line] else loop
ls = L8.pack s
match l | L.null l = False
| otherwise = L.isPrefixOf ls l || match (L.tail l)
printLines :: (MonadIO m) => Iter [L.ByteString] m ()
printLines = do
line <- safeHeadI
case line of
Just l -> do liftIO $ L.putStrLn l
printLines
Nothing -> return ()
enumFileCatchError :: (MonadIO m) => FilePath -> Onum L.ByteString m a
enumFileCatchError file = enumFile file `inumCatch` enumCatchIO
where
enumCatchIO :: (ChunkData t, MonadIO m) =>
IOError
-> IterR () m (IterR t m a)
-> Iter () m (IterR t m a)
enumCatchIO _ = verboseResumeI
-- or to avoid the need for a type signature, you could say:
-- enumCatchIO e = flip const (e :: IOError) verboseResumeI
main :: IO ()
main = do
prog <- getProgName
av <- getArgs
unless (length av >= 1) $ do
hPutStrLn stderr $ "usage: " ++ prog ++ " string [file ...]"
exitFailure
hSetBuffering stdout NoBuffering
let pat = head av
enum = if length av == 1
then enumHandle stdin
else foldr1 cat $ map enumFileCatchError $ tail av
enum |. filterLines pat |$ printLines
exitSuccess