FileManipCompat 0.16 → 0.17
raw patch · 2 files changed
+32/−33 lines, 2 files
Files
- FileManipCompat.cabal +1/−1
- System/FilePath/FindCompat.hs +31/−32
FileManipCompat.cabal view
@@ -1,5 +1,5 @@ Name: FileManipCompat-Version: 0.16+Version: 0.17 License: BSD3 License-File: LICENSE Author: Bryan O'Sullivan <bos@serpentine.com>
System/FilePath/FindCompat.hs view
@@ -110,10 +110,8 @@ , (||?) ) where -import Control.Monad (foldM, forM, liftM, liftM2) import Control.Monad import Control.Monad.State-import Control.Monad.Identity import Data.Bits (Bits, (.&.)) import Data.List (sort) import System.Directory (getDirectoryContents)@@ -212,29 +210,30 @@ -- 'RecursionPredicate'. Lazily return a sorted list of all files -- matching the given 'FilterPredicate'. Any errors that occur are -- dealt with by the given handler.+ findWithHandler ::- (FilePath -> E.Exception -> IO [FilePath]) -- ^ error handler+ (FilePath -> E.SomeException -> IO [FilePath]) -- ^ error handler -> RecursionPredicate -- ^ control recursion into subdirectories -> FilterPredicate -- ^ decide whether a file appears in the result -> FilePath -- ^ directory to start searching -> IO [FilePath] -- ^ files that matched the 'FilterPredicate' -findWithHandler errHandler recurse filter path =+findWithHandler errHandler recurse thisfilter path = E.handle (errHandler path) $ F.getSymbolicLinkStatus path >>= visit path 0- where visit path depth st =- if F.isDirectory st && evalFI recurse path depth st- then unsafeInterleaveIO (traverse path (succ depth) st)- else filterPath path depth st []- traverse dir depth dirSt = do+ where visit thispath thisdepth st =+ if F.isDirectory st && evalFI recurse thispath thisdepth st+ then unsafeInterleaveIO (traverse thispath (succ thisdepth) st)+ else filterPath thispath thisdepth st []+ traverse dir thisdepth dirSt = do names <- E.catch (getDirContents dir) (errHandler dir) filteredPaths <- forM names $ \name -> do- let path = dir </> name- unsafeInterleaveIO $ E.handle (errHandler path)- (F.getSymbolicLinkStatus path >>= visit path depth)- filterPath dir depth dirSt (concat filteredPaths)- filterPath path depth st result =- return $ if evalFI filter path depth st- then path:result+ let thispath = dir </> name+ unsafeInterleaveIO $ E.handle (errHandler thispath)+ (F.getSymbolicLinkStatus thispath >>= visit thispath thisdepth)+ filterPath dir thisdepth dirSt (concat filteredPaths)+ filterPath thispath thisdepth st result =+ return $ if evalFI thisfilter thispath thisdepth st+ then thispath:result else result -- | Search a directory recursively, with recursion controlled by a@@ -257,29 +256,29 @@ -- strict in its left argument to avoid space leaks. If you need a -- right-to-left fold, use 'foldr' on the result of 'findWithHandler' -- instead.+ foldWithHandler- :: (FilePath -> a -> E.Exception -> IO a) -- ^ error handler+ :: (FilePath -> a -> E.SomeException -> IO a) -- ^ error handler -> RecursionPredicate -- ^ control recursion into subdirectories -> (a -> FileInfo -> a) -- ^ function to fold with -> a -- ^ seed value for fold -> FilePath -- ^ directory to start searching -> IO a -- ^ final value after folding--foldWithHandler errHandler recurse f state path =- E.handle (errHandler path state) $- F.getSymbolicLinkStatus path >>= visit state path 0- where visit state path depth st =- if F.isDirectory st && evalFI recurse path depth st- then traverse state path (succ depth) st- else let state' = f state (mkFI path depth st)+foldWithHandler errHandler recurse f mystate mypath =+ E.handle (errHandler mypath mystate) $+ F.getSymbolicLinkStatus mypath >>= visit mystate mypath 0+ where visit thisstate path thisdepth st =+ if F.isDirectory st && evalFI recurse path thisdepth st+ then traverse thisstate path (succ thisdepth) st+ else let state' = f thisstate (mkFI path thisdepth st) in state' `seq` return state'- traverse state dir depth dirSt = E.handle (errHandler dir state) $+ traverse thisstate dir thisdepth dirSt = E.handle (errHandler dir thisstate) $ getDirContents dir >>=- let state' = f state (mkFI dir depth dirSt)- in state' `seq` flip foldM state' (\state name ->- E.handle (errHandler dir state) $+ let state' = f thisstate (mkFI dir thisdepth dirSt)+ in state' `seq` flip foldM state' (\stateHere name ->+ E.handle (errHandler dir stateHere) $ let path = dir </> name- in F.getSymbolicLinkStatus path >>= visit state path depth)+ in F.getSymbolicLinkStatus path >>= visit thisstate path thisdepth) -- | Search a directory recursively, with recursion controlled by a -- 'RecursionPredicate'. Fold over all files found. Any errors that@@ -354,7 +353,7 @@ path <- filePath st <- fileStatus return $ if F.isSymbolicLink st- then unsafePerformIO $ E.handle (const (return Nothing)) $+ then unsafePerformIO $ E.handle (const (return Nothing) :: E.SomeException -> IO (Maybe a) ) $ Just `liftM` f path else Nothing @@ -478,7 +477,7 @@ contains p = do d <- filePath return $ unsafePerformIO $- E.handle (const (return False)) $+ E.handle (const (return False) :: E.SomeException -> IO Bool) $ F.getFileStatus (d </> p) >> return True -- | Lift a binary operator into the 'FindClause' monad, so that it