@@ -122,7 +122,7 @@ import qualified Data.List as L
122122#ifndef OS_PATH
123123import Data.String (fromString )
124124import System.Environment (getEnv )
125- import Prelude (String , map , FilePath , Eq , IO , id , last , init , reverse , dropWhile , null , break , take , all , elem , any , span )
125+ import Prelude (String , map , FilePath , Eq , IO , id , reverse , dropWhile , null , break , take , all , elem , any , span )
126126import Data.Char (toLower , toUpper , isAsciiLower , isAsciiUpper )
127127import Data.List (stripPrefix , isSuffixOf , uncons , dropWhileEnd )
128128#define CHAR Char
@@ -299,14 +299,15 @@ getSearchPath = fmap splitSearchPath (getEnv "PATH")
299299-- Instead we speculatively split on the extension separator first, then check
300300-- whether results are well-formed.
301301splitExtension :: FILEPATH -> (STRING , STRING )
302- splitExtension x
302+ splitExtension x = case unsnoc nameDot of
303303 -- Imagine x = "no-dots", then nameDot = ""
304- | null nameDot = (x, mempty )
305- -- Imagine x = "\\shared.with.dots\no-dots"
306- | isWindows && null (dropDrive nameDot) = (x, mempty )
307- -- Imagine x = "dir.with.dots/no-dots"
308- | any isPathSeparator ext = (x, mempty )
309- | otherwise = (init nameDot, extSeparator `cons` ext)
304+ Nothing -> (x, mempty )
305+ Just (initNameDot, _)
306+ -- Imagine x = "\\shared.with.dots\no-dots"
307+ | isWindows && null (dropDrive nameDot) -> (x, mempty )
308+ -- Imagine x = "dir.with.dots/no-dots"
309+ | any isPathSeparator ext -> (x, mempty )
310+ | otherwise -> (initNameDot, extSeparator `cons` ext)
310311 where
311312 (nameDot, ext) = breakEnd isExtSeparator x
312313
@@ -668,9 +669,9 @@ splitFileName_ fp
668669 where
669670 (dirSlash, file) = breakEnd isPathSeparator fp
670671 dropExcessTrailingPathSeparators x
671- | hasTrailingPathSeparator x
672+ | Just lastX <- getTrailingPathSeparator x
672673 , let x' = dropWhileEnd isPathSeparator x
673- , otherwise = if | null x' -> singleton ( last x)
674+ , otherwise = if | null x' -> singleton lastX
674675 | otherwise -> addTrailingPathSeparator x'
675676 | otherwise = x
676677
@@ -742,10 +743,13 @@ replaceBaseName pth nam = combineAlways a (nam <.> ext)
742743-- > hasTrailingPathSeparator "test" == False
743744-- > hasTrailingPathSeparator "test/" == True
744745hasTrailingPathSeparator :: FILEPATH -> Bool
745- hasTrailingPathSeparator x
746- | null x = False
747- | otherwise = isPathSeparator $ last x
746+ hasTrailingPathSeparator = isJust . getTrailingPathSeparator
748747
748+ getTrailingPathSeparator :: FILEPATH -> Maybe CHAR
749+ getTrailingPathSeparator x = case unsnoc x of
750+ Just (_, lastX)
751+ | isPathSeparator lastX -> Just lastX
752+ _ -> Nothing
749753
750754hasLeadingPathSeparator :: FILEPATH -> Bool
751755hasLeadingPathSeparator = maybe False (isPathSeparator . fst ) . uncons
@@ -767,11 +771,12 @@ addTrailingPathSeparator x = if hasTrailingPathSeparator x then x else x <> sing
767771-- > Windows: dropTrailingPathSeparator "\\" == "\\"
768772-- > Posix: not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
769773dropTrailingPathSeparator :: FILEPATH -> FILEPATH
770- dropTrailingPathSeparator x =
771- if hasTrailingPathSeparator x && not (isDrive x)
772- then let x' = dropWhileEnd isPathSeparator x
773- in if null x' then singleton (last x) else x'
774- else x
774+ dropTrailingPathSeparator x = case getTrailingPathSeparator x of
775+ Just lastX
776+ | not (isDrive x)
777+ -> let x' = dropWhileEnd isPathSeparator x
778+ in if null x' then singleton lastX else x'
779+ _ -> x
775780
776781
777782-- | Get the directory name, move up one level.
@@ -1044,9 +1049,9 @@ normalise filepath =
10441049 && not (hasTrailingPathSeparator result)
10451050 && not (isRelativeDrive drv)
10461051
1047- isDirPath xs = hasTrailingPathSeparator xs
1048- || not ( null xs) && last xs == _period
1049- && hasTrailingPathSeparator ( init xs)
1052+ isDirPath xs = hasTrailingPathSeparator xs || case unsnoc xs of
1053+ Nothing -> False
1054+ Just (initXs, lastXs) -> lastXs == _period && hasTrailingPathSeparator initXs
10501055
10511056 f = joinPath . dropDots . propSep . splitDirectories
10521057
0 commit comments