diff --git a/System/FilePath/Internal.hs b/System/FilePath/Internal.hs index eeb11f35..0c92b3e0 100644 --- a/System/FilePath/Internal.hs +++ b/System/FilePath/Internal.hs @@ -122,7 +122,7 @@ import qualified Data.List as L #ifndef OS_PATH import Data.String (fromString) import System.Environment(getEnv) -import Prelude (String, map, FilePath, Eq, IO, id, reverse, dropWhile, null, break, take, all, elem, any, span) +import Prelude (String, map, FilePath, Eq, IO, id, last, init, reverse, dropWhile, null, break, take, all, elem, any, span) import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.List(stripPrefix, isSuffixOf, uncons, dropWhileEnd) #define CHAR Char @@ -299,15 +299,14 @@ getSearchPath = fmap splitSearchPath (getEnv "PATH") -- Instead we speculatively split on the extension separator first, then check -- whether results are well-formed. splitExtension :: FILEPATH -> (STRING, STRING) -splitExtension x = case unsnoc nameDot of +splitExtension x -- Imagine x = "no-dots", then nameDot = "" - Nothing -> (x, mempty) - Just (initNameDot, _) - -- Imagine x = "\\shared.with.dots\no-dots" - | isWindows && null (dropDrive nameDot) -> (x, mempty) - -- Imagine x = "dir.with.dots/no-dots" - | any isPathSeparator ext -> (x, mempty) - | otherwise -> (initNameDot, extSeparator `cons` ext) + | null nameDot = (x, mempty) + -- Imagine x = "\\shared.with.dots\no-dots" + | isWindows && null (dropDrive nameDot) = (x, mempty) + -- Imagine x = "dir.with.dots/no-dots" + | any isPathSeparator ext = (x, mempty) + | otherwise = (init nameDot, extSeparator `cons` ext) where (nameDot, ext) = breakEnd isExtSeparator x @@ -669,9 +668,9 @@ splitFileName_ fp where (dirSlash, file) = breakEnd isPathSeparator fp dropExcessTrailingPathSeparators x - | Just lastX <- getTrailingPathSeparator x + | hasTrailingPathSeparator x , let x' = dropWhileEnd isPathSeparator x - , otherwise = if | null x' -> singleton lastX + , otherwise = if | null x' -> singleton (last x) | otherwise -> addTrailingPathSeparator x' | otherwise = x @@ -743,13 +742,10 @@ replaceBaseName pth nam = combineAlways a (nam <.> ext) -- > hasTrailingPathSeparator "test" == False -- > hasTrailingPathSeparator "test/" == True hasTrailingPathSeparator :: FILEPATH -> Bool -hasTrailingPathSeparator = isJust . getTrailingPathSeparator +hasTrailingPathSeparator x + | null x = False + | otherwise = isPathSeparator $ last x -getTrailingPathSeparator :: FILEPATH -> Maybe CHAR -getTrailingPathSeparator x = case unsnoc x of - Just (_, lastX) - | isPathSeparator lastX -> Just lastX - _ -> Nothing hasLeadingPathSeparator :: FILEPATH -> Bool hasLeadingPathSeparator = maybe False (isPathSeparator . fst) . uncons @@ -771,12 +767,11 @@ addTrailingPathSeparator x = if hasTrailingPathSeparator x then x else x <> sing -- > Windows: dropTrailingPathSeparator "\\" == "\\" -- > Posix: not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x dropTrailingPathSeparator :: FILEPATH -> FILEPATH -dropTrailingPathSeparator x = case getTrailingPathSeparator x of - Just lastX - | not (isDrive x) - -> let x' = dropWhileEnd isPathSeparator x - in if null x' then singleton lastX else x' - _ -> x +dropTrailingPathSeparator x = + if hasTrailingPathSeparator x && not (isDrive x) + then let x' = dropWhileEnd isPathSeparator x + in if null x' then singleton (last x) else x' + else x -- | Get the directory name, move up one level. @@ -1049,9 +1044,9 @@ normalise filepath = && not (hasTrailingPathSeparator result) && not (isRelativeDrive drv) - isDirPath xs = hasTrailingPathSeparator xs || case unsnoc xs of - Nothing -> False - Just (initXs, lastXs) -> lastXs == _period && hasTrailingPathSeparator initXs + isDirPath xs = hasTrailingPathSeparator xs + || not (null xs) && last xs == _period + && hasTrailingPathSeparator (init xs) f = joinPath . dropDots . propSep . splitDirectories