filepath-bytestring 1.4.2.1.1 → 1.4.2.1.2
raw patch · 5 files changed
+202/−179 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG +6/−0
- System/FilePath/Internal.hs +188/−174
- filepath-bytestring.cabal +3/−3
- tests/TestGen.hs +2/−1
- tests/TestUtil.hs +3/−1
CHANGELOG view
@@ -1,3 +1,9 @@+filepath-bytestring (1.4.2.1.2) unstable; urgency=medium++ * Fix build with ghc 8.0 (pre-Semigroup Monoid transition)++ -- Joey Hess <id@joeyh.name> Mon, 30 Dec 2019 12:18:15 -0400+ filepath-bytestring (1.4.2.1.1) unstable; urgency=medium * When running on Windows, RawFilePath is assumed to be encoded with
System/FilePath/Internal.hs view
@@ -146,6 +146,8 @@ import qualified GHC.IO.Encoding as Encoding import System.IO.Unsafe (unsafePerformIO) #endif+import Data.Semigroup+import Prelude #ifndef mingw32_HOST_OS -- Import from unix, rather than redefining, so users who import both@@ -176,8 +178,8 @@ {-# NOINLINE encodeFilePath' #-} encodeFilePath' :: FilePath -> String encodeFilePath' f = unsafePerformIO $ do- enc <- Encoding.getFileSystemEncoding- GHC.withCString enc f (GHC.peekCString Encoding.char8)+ enc <- Encoding.getFileSystemEncoding+ GHC.withCString enc f (GHC.peekCString Encoding.char8) #endif -- | Convert from RawFilePath to FilePath@@ -195,8 +197,8 @@ {-# NOINLINE decodeFilePath' #-} decodeFilePath' :: String -> FilePath decodeFilePath' s = unsafePerformIO $ do- enc <- Encoding.getFileSystemEncoding- GHC.withCString Encoding.char8 s (GHC.peekCString enc)+ enc <- Encoding.getFileSystemEncoding+ GHC.withCString Encoding.char8 s (GHC.peekCString enc) #endif @@ -287,14 +289,14 @@ -- > untested Windows: splitSearchPath "File1;\"File2\";File3" == ["File1","File2","File3"] splitSearchPath :: String -> [FilePath] splitSearchPath = f- where- f xs = case break isSearchPathSeparator xs of- (pre, [] ) -> g pre- (pre, _:post) -> g pre ++ f post+ where+ f xs = case break isSearchPathSeparator xs of+ (pre, [] ) -> g pre+ (pre, _:post) -> g pre ++ f post - g "" = ["." | isPosix]- g ('\"':x@(_:_)) | isWindows && last x == '\"' = [init x]- g x = [x]+ g "" = ["." | isPosix]+ g ('\"':x@(_:_)) | isWindows && last x == '\"' = [init x]+ g x = [x] -- | Get a list of 'FilePath's in the $PATH variable.@@ -320,11 +322,11 @@ -- > splitExtension "file/path.txt/" == ("file/path.txt/","") splitExtension :: RawFilePath -> (ByteString, ByteString) splitExtension x = if B.null nameDot- then (x,mempty)- else (dir <> B.init nameDot, extSeparator `B.cons` ext)- where- (dir,file) = splitFileName_ x- (nameDot,ext) = B.breakEnd isExtSeparator file+ then (x,mempty)+ else (dir <> B.init nameDot, extSeparator `B.cons` ext)+ where+ (dir,file) = splitFileName_ x+ (nameDot,ext) = B.breakEnd isExtSeparator file -- | Get the extension of a file, returns @\"\"@ for no extension, @.ext@ otherwise. --@@ -382,12 +384,13 @@ -- > Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt" addExtension :: RawFilePath -> ByteString -> RawFilePath addExtension file ext = case B.uncons ext of- Nothing -> file- Just (x,_xs) -> joinDrive a $- if isExtSeparator x then b <> ext- else b <> (extSeparator `B.cons` ext)- where- (a,b) = splitDrive file+ Nothing -> file+ Just (x,_xs) -> joinDrive a $+ if isExtSeparator x+ then b <> ext+ else b <> (extSeparator `B.cons` ext)+ where+ (a,b) = splitDrive file -- | Does the given filename have an extension? --@@ -409,9 +412,9 @@ isExtensionOf :: ByteString -> RawFilePath -> Bool isExtensionOf ext = B.isSuffixOf ext' . takeExtensions where- ext' = case B.uncons ext of- Just (h, _) | isExtSeparator h -> ext- _ -> extSeparator `B.cons` ext+ ext' = case B.uncons ext of+ Just (h, _) | isExtSeparator h -> ext+ _ -> extSeparator `B.cons` ext -- | Drop the given extension from a FilePath, and the @\".\"@ preceding it. -- Returns 'Nothing' if the FilePath does not have the given extension, or@@ -431,12 +434,12 @@ -- > stripExtension "" x == Just x stripExtension :: ByteString -> RawFilePath -> Maybe RawFilePath stripExtension ext path = case B.uncons ext of- Nothing -> Just path- Just (x, _) -> - let dotExt = if isExtSeparator x- then ext- else extSeparator `B.cons` ext- in B.stripSuffix dotExt path+ Nothing -> Just path+ Just (x, _) -> + let dotExt = if isExtSeparator x+ then ext+ else extSeparator `B.cons` ext+ in B.stripSuffix dotExt path -- | Split on all extensions.@@ -448,9 +451,9 @@ -- > splitExtensions "file.tar.gz" == ("file",".tar.gz") splitExtensions :: RawFilePath -> (RawFilePath, ByteString) splitExtensions x = (a <> c, d)- where- (a,b) = splitFileName_ x- (c,d) = B.break isExtSeparator b+ where+ (a,b) = splitFileName_ x+ (c,d) = B.break isExtSeparator b -- | Drop all extensions. --@@ -516,64 +519,67 @@ addSlash :: RawFilePath -> RawFilePath -> (RawFilePath, RawFilePath) addSlash a xs = (a <> c,d)- where (c,d) = B.span isPathSeparator xs+ where+ (c,d) = B.span isPathSeparator xs -- See [1]. -- "\\?\D:\<path>" or "\\?\UNC\<server>\<share>" readDriveUNC :: RawFilePath -> Maybe (RawFilePath, RawFilePath) readDriveUNC p = do- (s1, p') <- B.uncons p- (s2, p'') <- B.uncons p'- (q, p''') <- B.uncons p''- (s3, rest) <- B.uncons p'''- if q == fromIntegral (ord '?') && all isPathSeparator [s1,s2,s3]- then case breakunc rest of- Just (unc,r) -> - let (a,b) = readDriveShareName r- in Just (B.pack [s1,s2,q,s3] <> unc <> a, b)- Nothing -> case readDriveLetter rest of- -- Extended-length path.- Just (a,b) -> Just (B.pack [s1,s2,q,s3] <> a, b)- Nothing -> Nothing- else Nothing+ (s1, p') <- B.uncons p+ (s2, p'') <- B.uncons p'+ (q, p''') <- B.uncons p''+ (s3, rest) <- B.uncons p'''+ if q == fromIntegral (ord '?') && all isPathSeparator [s1,s2,s3]+ then case breakunc rest of+ Just (unc,r) -> + let (a,b) = readDriveShareName r+ in Just (B.pack [s1,s2,q,s3] <> unc <> a, b)+ Nothing -> case readDriveLetter rest of+ -- Extended-length path.+ Just (a,b) -> Just (B.pack [s1,s2,q,s3] <> a, b)+ Nothing -> Nothing+ else Nothing where- breakunc b = do- (u, b') <- B.uncons b- (n, b'') <- B.uncons b'- (c, b''') <- B.uncons b''- (s, rest) <- B.uncons b'''- let isup v ch = toUpper (chr (fromIntegral v)) == ch- if isPathSeparator s && isup u 'U' && isup n 'N' && isup c 'C'- then Just (B.take 4 b, rest)- else Nothing+ breakunc b = do+ (u, b') <- B.uncons b+ (n, b'') <- B.uncons b'+ (c, b''') <- B.uncons b''+ (s, rest) <- B.uncons b'''+ let isup v ch = toUpper (chr (fromIntegral v)) == ch+ if isPathSeparator s && isup u 'U' && isup n 'N' && isup c 'C'+ then Just (B.take 4 b, rest)+ else Nothing {- c:\ -} readDriveLetter :: RawFilePath -> Maybe (RawFilePath, RawFilePath) readDriveLetter p = case B.uncons p of- Just (x, t) | isLetter x -> case B.uncons t of- Just (c, t') | c == colon -> case B.uncons t' of- Just (y, _) | isPathSeparator y ->- Just $ addSlash (B.pack [x, colon]) t'- _ -> Just (B.pack [x, colon], t')- _ -> Nothing- _ -> Nothing- where colon = fromIntegral (ord ':')+ Just (x, t) | isLetter x -> case B.uncons t of+ Just (c, t') | c == colon -> case B.uncons t' of+ Just (y, _) | isPathSeparator y ->+ Just $ addSlash (B.pack [x, colon]) t'+ _ -> Just (B.pack [x, colon], t')+ _ -> Nothing+ _ -> Nothing+ where+ colon = fromIntegral (ord ':') {- \\sharename\ -} readDriveShare :: ByteString -> Maybe (RawFilePath, RawFilePath) readDriveShare p = do- (s1, p') <- B.uncons p- (s2, p'') <- B.uncons p'- let (a,b) = readDriveShareName p''- if isPathSeparator s1 && isPathSeparator s2- then Just (s1 `B.cons` s2 `B.cons` a,b)- else Nothing+ (s1, p') <- B.uncons p+ (s2, p'') <- B.uncons p'+ let (a,b) = readDriveShareName p''+ if isPathSeparator s1 && isPathSeparator s2+ then Just (s1 `B.cons` s2 `B.cons` a,b)+ else Nothing {- assume you have already seen \\ -} {- share\bob -> "share\", "bob" -} readDriveShareName :: ByteString -> (RawFilePath, RawFilePath) readDriveShareName name = addSlash a b- where (a,b) = B.break isPathSeparator name+ where+ (a,b) = B.break isPathSeparator name -- | Join a drive and the rest of the path.@@ -635,8 +641,8 @@ -- > Windows: splitFileName "c:" == ("c:","") splitFileName :: RawFilePath -> (ByteString, ByteString) splitFileName x = (if B.null dir then "./" else dir, name)- where- (dir, name) = splitFileName_ x+ where+ (dir, name) = splitFileName_ x -- version of splitFileName where, if the FilePath has no directory -- component, the returned directory is "" rather than "./". This@@ -646,9 +652,9 @@ -- e.g. replaceFileName. splitFileName_ :: RawFilePath -> (ByteString, ByteString) splitFileName_ x = (drv <> dir, file)- where- (drv,pth) = splitDrive x- (dir,file) = B.breakEnd isPathSeparator pth+ where+ (drv,pth) = splitDrive x+ (dir,file) = B.breakEnd isPathSeparator pth -- | Set the filename. --@@ -698,9 +704,9 @@ -- > Valid x => replaceBaseName x (takeBaseName x) == x replaceBaseName :: RawFilePath -> ByteString -> RawFilePath replaceBaseName pth nam = combineAlways a (nam <.> ext)- where- (a,b) = splitFileName_ pth- ext = takeExtension b+ where+ (a,b) = splitFileName_ pth+ ext = takeExtension b -- | Is an item either a directory or the last character a path separator? --@@ -708,14 +714,14 @@ -- > hasTrailingPathSeparator "test/" == True hasTrailingPathSeparator :: RawFilePath -> Bool hasTrailingPathSeparator x = case B.unsnoc x of- Nothing -> False- Just (_i, l) -> isPathSeparator l+ Nothing -> False+ Just (_i, l) -> isPathSeparator l hasLeadingPathSeparator :: RawFilePath -> Bool hasLeadingPathSeparator x = case B.uncons x of- Nothing -> False- Just (h,_t) -> isPathSeparator h+ Nothing -> False+ Just (h,_t) -> isPathSeparator h -- | Add a trailing file path separator if one is not already present. --@@ -724,8 +730,8 @@ -- > Posix: addTrailingPathSeparator "test/rest" == "test/rest/" addTrailingPathSeparator :: RawFilePath -> RawFilePath addTrailingPathSeparator x- | hasTrailingPathSeparator x = x- | otherwise = B.snoc x pathSeparator+ | hasTrailingPathSeparator x = x+ | otherwise = B.snoc x pathSeparator -- | Remove any trailing path separators@@ -735,12 +741,11 @@ -- > Windows: dropTrailingPathSeparator "\\" == "\\" -- > Posix: not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x dropTrailingPathSeparator :: RawFilePath -> RawFilePath-dropTrailingPathSeparator x =- if hasTrailingPathSeparator x && not (isDrive x)- then let x' = dropWhileEnd isPathSeparator x- in if B.null x' then B.singleton (B.last x) else x'- else x-+dropTrailingPathSeparator x+ | hasTrailingPathSeparator x && not (isDrive x) = + let x' = dropWhileEnd isPathSeparator x+ in if B.null x' then B.singleton (B.last x) else x'+ | otherwise = x -- | Get the directory name, move up one level. --@@ -768,18 +773,20 @@ {-# INLINE combine #-} -- | An alias for '</>'. combine :: RawFilePath -> RawFilePath -> RawFilePath-combine a b | hasLeadingPathSeparator b || (not isPosix && hasDrive b) = b- | otherwise = combineAlways a b+combine a b+ | hasLeadingPathSeparator b || (not isPosix && hasDrive b) = b+ | otherwise = combineAlways a b -- | Combine two paths, assuming rhs is NOT absolute. combineAlways :: RawFilePath -> RawFilePath -> RawFilePath-combineAlways a b | B.null a = b- | B.null b = a- | hasTrailingPathSeparator a = a <> b- | isWindows && B.length a == 2- && B.last a == fromIntegral (ord ':')- && isLetter (B.head a) = a <> b- | otherwise = a <> B.singleton pathSeparator <> b+combineAlways a b+ | B.null a = b+ | B.null b = a+ | hasTrailingPathSeparator a = a <> b+ | isWindows && B.length a == 2+ && B.last a == fromIntegral (ord ':')+ && isLetter (B.head a) = a <> b+ | otherwise = a <> B.singleton pathSeparator <> b -- | Combine two paths with a path separator. -- If the second path starts with a path separator or a drive letter, then it returns the second.@@ -836,15 +843,15 @@ -- > Posix: splitPath "/file/test" == ["/","file/","test"] splitPath :: RawFilePath -> [RawFilePath] splitPath x = [drive | not (B.null drive)] ++ f path- where- (drive,path) = splitDrive x+ where+ (drive,path) = splitDrive x - f y- | B.null y = []- | otherwise = (a<>c) : f d- where- (a,b) = B.break isPathSeparator y- (c,d) = B.span isPathSeparator b+ f y+ | B.null y = []+ | otherwise = (a<>c) : f d+ where+ (a,b) = B.break isPathSeparator y+ (c,d) = B.span isPathSeparator b -- | Just as 'splitPath', but don't add the trailing slashes to each element. --@@ -889,11 +896,11 @@ -- > untested Windows: not (equalFilePath "C:" "C:/") equalFilePath :: RawFilePath -> RawFilePath -> Bool equalFilePath a b = f a == f b- where+ where -- FIXME: B8.map will not lower-case non-ascii characters.- f x | isWindows = dropTrailingPathSeparator $ B8.map toLower $ normalise x- | otherwise = dropTrailingPathSeparator $ normalise x-+ f x+ | isWindows = dropTrailingPathSeparator $ B8.map toLower $ normalise x+ | otherwise = dropTrailingPathSeparator $ normalise x -} {-@@ -924,24 +931,26 @@ -- > untested Posix: makeRelative "some/path" "some/path/a/b/c" == "a/b/c" makeRelative :: FilePath -> FilePath -> FilePath makeRelative root path- | equalFilePath root path = "."- | takeAbs root /= takeAbs path = path- | otherwise = f (dropAbs root) (dropAbs path)- where- f "" y = dropWhile isPathSeparator y- f x y = let (x1,x2) = g x- (y1,y2) = g y- in if equalFilePath x1 y1 then f x2 y2 else path+ | equalFilePath root path = "."+ | takeAbs root /= takeAbs path = path+ | otherwise = f (dropAbs root) (dropAbs path)+ where+ f "" y = dropWhile isPathSeparator y+ f x y =+ let (x1,x2) = g x+ (y1,y2) = g y+ in if equalFilePath x1 y1 then f x2 y2 else path - g x = (dropWhile isPathSeparator a, dropWhile isPathSeparator b)- where (a,b) = break isPathSeparator $ dropWhile isPathSeparator x+ g x = (dropWhile isPathSeparator a, dropWhile isPathSeparator b)+ where+ (a,b) = break isPathSeparator $ dropWhile isPathSeparator x - -- on windows, need to drop '/' which is kind of absolute, but not a drive- dropAbs x | hasLeadingPathSeparator x && not (hasDrive x) = tail x- dropAbs x = dropDrive x+ -- on windows, need to drop '/' which is kind of absolute, but not a drive+ dropAbs x | hasLeadingPathSeparator x && not (hasDrive x) = tail x+ dropAbs x = dropDrive x - takeAbs x | hasLeadingPathSeparator x && not (hasDrive x) = [pathSeparator]- takeAbs x = map (\y -> if isPathSeparator y then pathSeparator else toLower y) $ takeDrive x+ takeAbs x | hasLeadingPathSeparator x && not (hasDrive x) = [pathSeparator]+ takeAbs x = map (\y -> if isPathSeparator y then pathSeparator else toLower y) $ takeDrive x -} @@ -976,59 +985,62 @@ -- > Posix: normalise "//home" == "/home" normalise :: RawFilePath -> RawFilePath normalise path- | addPathSeparator = result <> B.singleton pathSeparator- | otherwise = result+ | addPathSeparator = result <> B.singleton pathSeparator+ | otherwise = result where- (drv,pth) = splitDrive path- result = joinDrive' (normaliseDrive drv) (f pth)+ (drv,pth) = splitDrive path+ result = joinDrive' (normaliseDrive drv) (f pth) - joinDrive' "" "" = "."- joinDrive' d p = joinDrive d p+ joinDrive' "" "" = "."+ joinDrive' d p = joinDrive d p - addPathSeparator = isDirPath pth- && not (hasTrailingPathSeparator result)- && not (isRelativeDrive drv)+ addPathSeparator = isDirPath pth+ && not (hasTrailingPathSeparator result)+ && not (isRelativeDrive drv) - isDirPath xs = hasTrailingPathSeparator xs- || not (B.null xs) && B.last xs == extSeparator && hasTrailingPathSeparator (B.init xs)+ isDirPath xs = hasTrailingPathSeparator xs+ || not (B.null xs) && B.last xs == extSeparator+ && hasTrailingPathSeparator (B.init xs) - f :: RawFilePath -> RawFilePath- f = joinPath . dropDots . propSep . splitDirectories+ f :: RawFilePath -> RawFilePath+ f = joinPath . dropDots . propSep . splitDirectories - propSep :: [RawFilePath] -> [RawFilePath]- propSep (x:xs) | B.all isPathSeparator x = B.singleton pathSeparator : xs- | otherwise = x : xs- propSep [] = []+ propSep :: [RawFilePath] -> [RawFilePath]+ propSep (x:xs)+ | B.all isPathSeparator x = B.singleton pathSeparator : xs+ | otherwise = x : xs+ propSep [] = [] - dropDots :: [RawFilePath] -> [RawFilePath]- dropDots = filter ("." /=)+ dropDots :: [RawFilePath] -> [RawFilePath]+ dropDots = filter ("." /=) normaliseDrive :: RawFilePath -> RawFilePath normaliseDrive "" = "" normaliseDrive _ | isPosix = B.singleton pathSeparator-normaliseDrive drive = if isJust $ readDriveLetter x2- then upcasedriveletter x2- else x2- where- x2 = B.map repSlash drive+normaliseDrive drive+ | isJust (readDriveLetter x2) = upcasedriveletter x2+ | otherwise = x2+ where+ x2 = B.map repSlash drive - repSlash x = if isPathSeparator x then pathSeparator else x+ repSlash x = if isPathSeparator x then pathSeparator else x - -- A Windows drive letter is an ascii character, so it's safe to- -- operate on the ByteString containing it using B8.- upcasedriveletter = B8.map toUpper+ -- A Windows drive letter is an ascii character, so it's safe to+ -- operate on the ByteString containing it using B8.+ upcasedriveletter = B8.map toUpper -- Information for validity functions on Windows. See [1]. isBadCharacter :: Word8 -> Bool isBadCharacter x = x >= 0 && x <= 31 || x `elem` l where- l = map (fromIntegral . ord) ":*?><|\""+ l = map (fromIntegral . ord) ":*?><|\"" badElements :: [FilePath] badElements =- ["CON","PRN","AUX","NUL","CLOCK$"- ,"COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9"- ,"LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"]+ ["CON","PRN","AUX","NUL","CLOCK$"+ ,"COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9"+ ,"LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"+ ] -- | Is a RawFilePath valid, i.e. could you create a file like it? This function checks for invalid names, -- and invalid characters, but does not check if length limits are exceeded, as these are typically@@ -1052,17 +1064,17 @@ -- > Windows: isValid " nul.txt" == True isValid :: RawFilePath -> Bool isValid path- | B.null path = False- | B.elem 0 path = False- | isPosix = True- | otherwise = - not (B.any isBadCharacter x2) &&- not (any f $ splitDirectories x2) &&- not (isJust (readDriveShare x1) && B.all isPathSeparator x1) &&- not (isJust (readDriveUNC x1) && not (hasTrailingPathSeparator x1))- where- (x1,x2) = splitDrive path- f x = map toUpper (B8.unpack $ dropWhileEnd (== 32) $ dropExtensions x) `elem` badElements+ | B.null path = False+ | B.elem 0 path = False+ | isPosix = True+ | otherwise = + not (B.any isBadCharacter x2) &&+ not (any f $ splitDirectories x2) &&+ not (isJust (readDriveShare x1) && B.all isPathSeparator x1) &&+ not (isJust (readDriveUNC x1) && not (hasTrailingPathSeparator x1))+ where+ (x1,x2) = splitDrive path+ f x = map toUpper (B8.unpack $ dropWhileEnd (== 32) $ dropExtensions x) `elem` badElements {- @@ -1128,7 +1140,8 @@ -- * "You cannot use the "\\?\" prefix with a relative path." isRelative :: RawFilePath -> Bool isRelative x = B.null drive || isRelativeDrive drive- where drive = takeDrive x+ where+ drive = takeDrive x {- c:foo -}@@ -1137,7 +1150,8 @@ -- current directory on the drive with the specified letter." isRelativeDrive :: RawFilePath -> Bool isRelativeDrive x =- maybe False (not . hasTrailingPathSeparator . fst) (readDriveLetter x)+ maybe False (not . hasTrailingPathSeparator . fst)+ (readDriveLetter x) -- | @not . 'isRelative'@ --
filepath-bytestring.cabal view
@@ -1,6 +1,6 @@ cabal-version: >= 1.18 name: filepath-bytestring-version: 1.4.2.1.1+version: 1.4.2.1.2 -- NOTE: Don't forget to update CHANGELOG and the filepath version below license: BSD3 license-file: LICENSE@@ -56,13 +56,13 @@ else build-depends: unix - ghc-options: -O2 -Wall+ ghc-options: -O2 -Wall -fno-warn-tabs test-suite filepath-tests type: exitcode-stdio-1.0 default-language: Haskell2010 main-is: Test.hs- ghc-options: -main-is Test+ ghc-options: -main-is Test -Wall -fno-warn-tabs hs-source-dirs: tests other-modules: TestEquiv
tests/TestGen.hs view
@@ -3,10 +3,11 @@ module TestGen(tests) where import TestUtil import Data.Char+import Data.Semigroup import qualified System.FilePath.Windows.ByteString as W import qualified System.FilePath.Posix.ByteString as P import Data.ByteString (isPrefixOf, isSuffixOf, null, any)-import Prelude hiding (isPrefixOf, isSuffixOf, null, any)+import Prelude hiding (null, any) tests :: [(String, Property)] tests = [("W.pathSeparator == fromIntegral (ord '\\\\')", property $ W.pathSeparator == fromIntegral (ord '\\'))
tests/TestUtil.hs view
@@ -9,7 +9,6 @@ ) where import Test.QuickCheck hiding ((==>))-import Data.List import Data.Maybe import Data.Word import Data.Char@@ -19,6 +18,8 @@ import System.FilePath.ByteString (RawFilePath, encodeFilePath) infixr 0 ==>++(==>) :: Bool -> Bool -> Bool a ==> b = not a || b class ToRawFilePath t where@@ -82,6 +83,7 @@ instance (EquivResult a b) => EquivResult (Maybe a) (Maybe b) where equivresult Nothing Nothing = True equivresult (Just a) (Just b) = equivresult a b+ equivresult _ _ = False instance (EquivResult a b) => EquivResult [a] [b] where equivresult a b = and (map (uncurry equivresult) (zip a b))