
Hello, Guys The System.FilePath might not be perfect and might not handle some unusual cases very well. Most of functions in this module are collected from Cabal/Alex/Happy/Haddock. Some of these tools already use their own functions for file path handling. Special care was taken to make them more portable but probably there is still enough room for optimizations.
What about splitFileExt "foo.bar."? ("foo", "bar.") or ("foo.bar.", "")?
The latter makes more sense to me, as an extension of the first case you give and splitting "foo.tar.gz" to ("foo.tar", "gz").
I will take a look at this. I also don't know which case is more natural.
(Win32)
splitFileName "\\\\server\\share" ==> ("\\\\server","share") (should probably be ("\\\\server\\share",""))
Why? "\\\\server" is the server name and "share" is the directory name on this server.
splitFileName "foo:xyz" ==> ("foo:.","xyz") (should be (".","foo:xyz") -- this refers to the named stream xyz of foo)
System.FilePath currently doesn't support NTFS streams. I don't care much about them because they are rarely used but the things can be improved. The trouble here is that in some cases the drive letter cann't be easily distinguished. What does "c:foo" mean, file "foo" on drive "c" or stream "foo" of file "c"?
joinPaths "c:\\" "\\foo" ==> "\\foo" (should be "c:\\foo". I realize that "cd c:\\" on Windows doesn't actually make "c:\\" the current directory, but ";" doesn't separate shell commands either.)
On Windows there is current drive and current directory on each drive. "\\foo" means top level directory "foo" on the current drive. If the current drive is "c" then I can agree that the joined path is "c:\\foo" but if the current drive is "a" then this is wrong. In both cases "\\foo" is the right answer. If you want something like "c:\\foo" you can use System.Directory.canonicalizePath. canonicalizePath "\\foo" returns either "c:\\foo" or "a:\\foo".
(Posix)
splitFileName "/foo" ==> ("/","foo"), splitFileName "/foo/" ==> ("/foo","") (arguably makes sense, but why isn't it documented?)
OK
splitFileName "/foo/bar" ==> ("/foo","bar") splitFileName "/foo//bar" ==> ("/foo/","bar") (definitely a bug)
Is "/foo//bar" valid file path and what does "//" mean?
pathParents "/foo///bar" ==> ["/","/foo","/foo","/foo","/foo/bar"]
Again what does "///" mean?
pathParents "foo/../bar" ==> [".","foo/../bar"] (what if foo doesn't exist and we wanted to create it?)
If "foo" doesn't exist then you can create it or raise an error Cheers, Krasimir

On Tue, Jan 25, 2005 at 01:32:29PM +0200, Krasimir Angelov wrote:
splitFileName "/foo/bar" ==> ("/foo","bar") splitFileName "/foo//bar" ==> ("/foo/","bar") (definitely a bug)
Is "/foo//bar" valid file path and what does "//" mean?
"//" means the same thing as "/". In unix you can use as many directory separators as you like. Or alternatively, you could think of it as meaning the same thing as "/./", which might make more sense. I suppose you could think of the directory "" as being equivalent to ".", which would explain why "./foo" and "foo" are the same thing, as is "././foo" or ".//foo", and "foo/" and "foo/." are also the same. The exception of course is that "/foo" and "./foo" are not the same thing. -- David Roundy http://www.darcs.net

On 25 Jan 2005, at 11:32, Krasimir Angelov wrote:
splitFileName "/foo/bar" ==> ("/foo","bar") splitFileName "/foo//bar" ==> ("/foo/","bar") (definitely a bug)
Is "/foo//bar" valid file path and what does "//" mean?
pathParents "/foo///bar" ==> ["/","/foo","/foo","/foo","/foo/bar"]
Again what does "///" mean?
Under implementations of unix that I have played with, extra // are ignored. So "/foo//bar" == "/foo/bar" == "/foo///bar". I have no idea if this is in some standard. My guess is that it is made so that programs which concatenate paths clumsily can cope OK, so you can do "/foo" ++ "/" ++ "bar" or "/foo/" ++ "/" ++ "bar" and get the same results: i.e. it is an extension of the notion that "/foo/" and "/foo" refer to the same directory. (Except, apparently, in the presence of symbolic links... or so I have some vague memory) Jules

Jules Bean wrote:
[...] it is an extension of the notion that "/foo/" and "/foo" refer to the same directory. (Except, apparently, in the presence of symbolic links... or so I have some vague memory)
Yes, "/foo/" is equivalent to "/foo/.", which is not always the same as "/foo". If "/foo" is a symlink, then lstat("/foo/", ...) will stat the directory at the other end, not the symlink. -- Ben

On Tue, 25 Jan 2005 13:32:29 +0200, Krasimir Angelov
What about splitFileExt "foo.bar."? ("foo", "bar.") or ("foo.bar.", "")?
The latter makes more sense to me, as an extension of the first case you give and splitting "foo.tar.gz" to ("foo.tar", "gz").
I will take a look at this. I also don't know which case is more natural.
("foo.bar.", "") is more natural for me because it eleminates the special case for "." and "..". The original definition of splitFileExt is: splitFileExt :: FilePath -> (String, String) splitFileExt p = case pre of [] -> (p, []) (_:pre) -> (reverse (pre++path), reverse suf) where (fname,path) = break isPathSeparator (reverse p) (suf,pre) | fname == "." || fname == ".." = (fname,"") | otherwise = break (== '.') fname The definition can be changed to: splitFileExt :: FilePath -> (String, String) splitFileExt p = case break (== '.') fname of (suf@(_:_),_:pre) -> (reverse (pre++path), reverse suf) _ -> (p, []) where (fname,path) = break isPathSeparator (reverse p) The letter is simplier, it doesn't treat "." and ".." as special cases and for it splitFileExt "foo.bar." == ("foo.bar.", "") Cheers, Krasimir
participants (4)
-
Ben Rudiak-Gould
-
David Roundy
-
Jules Bean
-
Krasimir Angelov