@@ -290,13 +290,24 @@ getSearchPath = fmap splitSearchPath (getEnv "PATH")
290290-- > splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
291291-- > splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
292292-- > splitExtension "file/path.txt/" == ("file/path.txt/","")
293+
294+ -- A naive implementation would be to use @splitFileName_@ first,
295+ -- then break filename into basename and extension, then recombine dir and basename.
296+ -- This is way too expensive, see @splitFileName_@ comment for discussion.
297+ --
298+ -- Instead we speculatively split on the extension separator first, then check
299+ -- whether results are well-formed.
293300splitExtension :: FILEPATH -> (STRING , STRING )
294- splitExtension x = if null nameDot
295- then (x, mempty )
296- else (dir <> init nameDot, extSeparator `cons` ext)
297- where
298- (dir,file) = splitFileName_ x
299- (nameDot,ext) = breakEnd isExtSeparator file
301+ splitExtension x
302+ -- Imagine x = "no-dots", then nameDot = ""
303+ | null nameDot = (x, mempty )
304+ -- Imagine x = "\\shared.with.dots\no-dots"
305+ | isWindows && null (dropDrive nameDot) = (x, mempty )
306+ -- Imagine x = "dir.with.dots/no-dots"
307+ | any isPathSeparator ext = (x, mempty )
308+ | otherwise = (init nameDot, extSeparator `cons` ext)
309+ where
310+ (nameDot, ext) = breakEnd isExtSeparator x
300311
301312-- | Get the extension of a file, returns @\"\"@ for no extension, @.ext@ otherwise.
302313--
0 commit comments