module Main (main) where import Char (isSpace) import Maybe (catMaybes, isJust) import List (isPrefixOf, intersperse) import System (getArgs) import Text.Regex main = do [filterFileName] <- getArgs filterFile <- readFile filterFileName let match = matcher (parseFilterFile filterFile) interact (unlines . filter match . lines) data FilterSpec = Exclude String | NotExclude String -- override Exclude but not AlwaysExclude | AlwaysExclude String parseFilterFile :: String -> [FilterSpec] parseFilterFile = catMaybes . map parseLine . lines where parseLine [] = Nothing parseLine ('#':_) = Nothing parseLine line | "exclude " `isPrefixOf` line = Just $ Exclude $ trim $ drop 8 line | "do not exclude " `isPrefixOf` line = Just $ NotExclude $ trim $ drop 15 line | "always exclude " `isPrefixOf` line = Just $ AlwaysExclude $ trim $ drop 15 line parseLine line = error $ "cannot parse line: " ++ line trim = takeWhile (not . isSpace) . dropWhile isSpace matcher :: [FilterSpec] -> (String -> Bool) matcher spec = match where excludeRegex = mkRegex $ concat $ intersperse "|" [ regex | Exclude regex <- spec ] noExcludeRegex = mkRegex $ concat $ intersperse "|" [ regex | NotExclude regex <- spec ] alwaysExcludeRegex = mkRegex $ concat $ intersperse "|" [ regex | AlwaysExclude regex <- spec ] match line = not $ ((isJust $ matchRegex excludeRegex line) && (not $ isJust $ matchRegex noExcludeRegex line)) || (isJust $ matchRegex alwaysExcludeRegex line)