@@ -290,13 +290,24 @@ getSearchPath = fmap splitSearchPath (getEnv "PATH")
290
290
-- > splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
291
291
-- > splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
292
292
-- > 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.
293
300
splitExtension :: 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
300
311
301
312
-- | Get the extension of a file, returns @\"\"@ for no extension, @.ext@ otherwise.
302
313
--
0 commit comments