std.path review: update

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Wed Jul 20 12:30:04 PDT 2011


On Wed, 20 Jul 2011 17:36:51 +0000, Lars T. Kyllingstad wrote:

> On Mon, 18 Jul 2011 14:51:06 -0400, Steven Schveighoffer wrote:
> 
>> On Mon, 18 Jul 2011 14:25:57 -0400, Lars T. Kyllingstad
>> <public at kyllingen.nospamnet> wrote:
>> 
>>> On Mon, 18 Jul 2011 13:16:29 -0400, Steven Schveighoffer wrote:
>> 
>>>> In driveName:
>>>>
>>>> Should std.path handle uunc paths?  i.e. \\servername\share\path  (I
>>>> think if it does, it should specify \\servername\share as the drive)
>>>
>>> Yes, std.path is supposed to support UNC paths.  For instance, the
>>> following works now:
>>>
>>>   assert (equal(pathSplitter(`\\foo\bar\baz`), [`\\foo`, "bar",
>>>   "baz"]));
>>>
>>> I guess you would rather have that
>>>
>>>   assert (equal(pathSplitter(`\\foo\bar\baz`), [`\\foo\bar`, "baz"]));
>>>
>>> then?  I am not very familiar with Windows network shares; is \\foo
>>> never a valid path on its own?
>> 
>> It is and it isn't.
> 
> Well, that certainly cleared things up. ;)
> 
> 
>> It's *not* a normal directory, because only shares can be in that
>> directory.  In other words, the point at which a UNC path turns into
>> normal directory structure is after the share name.
>> 
>> An easy way to compare is, you can only map drive letters to shares,
>> not to servers.
> 
> Then driveName() should probably return the full share path.  But, of
> the following asserts, which should pass?
> 
>     assert (pathSplitter(`\\foo\bar\baz`).front == `\\foo\bar`); assert
>     (pathSplitter(`\\foo\bar\baz`).front == `\\foo`);
> 
>     assert (baseName(`\\foo\bar`) == `\\foo\bar`); assert
>     (baseName(`\\foo\bar`) == "bar");
> 
>     assert (dirName(`\\foo\bar`) == `\\foo\bar`); assert
>     (dirName(`\\foo\bar`) == `\\foo`);
> 
> Note that if you replace `\\foo\bar` with `c:\` in the above, the first
> assert in each pair will pass.  Same with "/" on POSIX.  Basically, that
> choice corresponds to treating `\\foo\bar` as a filesystem root.
> 
> 
>>> As I understand it, some POSIX systems also mount network drives using
>>> similar paths.  Does anyone know whether "//foo" is a valid path on
>>> these systems, or does it have to bee "//foo/bar"?
>> 
>> Typically, linux uses URL's, i.e. smb://server/share   URL parsing is
>> probably not in std.path's charter.
>> 
>> However, I have used a command like:
>> 
>> mount -t cifs //server/share /mnt/serverfiles
>> 
>> But this is only in very special contexts.  In general I don't think
>> //foo should be considered a server path on Posix systems.
> 
> I actually got a request on the Phobos list that std.path should support
> such paths.  Furthermore, the POSIX stardard explicitly mentions "//"
> paths (though it basically says it is implementation-defined whether to
> bother dealing with them).
> 
> 
>>>> joinPath:
>>>>
>>>> Does this normalize the paths?  For example:
>>>>
>>>> joinPath("/home/steves", "../lars") => /home/steves/../lars or
>>>> /home/lars ?
>>>>
>>>> If so, the docs should reflect that.  If not, maybe it should :)  If
>>>> it doesn't, at least the docs should state that it doesn't.
>>>
>>> No, it doesn't, and I don't think it should.  It is better to let the
>>> user choose whether they want the overhead of normalization by calling
>>> normalize() explicitly.  I will specify this in the docs.
>> 
>> In fact, if you do not normalize during the join, it's *more* overhead
>> to normalize afterwards.  If normalization is done while joining, then
>> you only build one string.  There's no need to build a non-normalized
>> string, then build a normalized string based on that.
>> 
>> Plus the data is only iterated once.
>> 
>> I think it's at least worth an option, but I'm not going to hold back
>> my vote based on this :)
> 
> If it doesn't turn out to be a huge undertaking, I think I'll replace
> joinPath() with a function buildPath() that takes an input range of path
> segments and joins them together, with optional normalization.  Then,
> normalize(path) can be implemented as:
> 
>     buildPath(pathSplitter(path));
> 
> Does that sound sensible?

Actually, I realise now, it doesn't. :)  Since joinPath/buildPath needs 
to support path segments containing multiple directories, normalize would 
just be

  buildPath(path)

-Lars


More information about the Digitalmars-d mailing list