Boost logo

Boost :

Subject: Re: [boost] [filesystem] Request for comments on proposed relative() function
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2014-05-15 20:53:37


On 16/05/2014 00:44, quoth Yakov Galka:
> One problem with boost filesystem is the lack of theoretical foundation.

There kind of is one if you look at the Definitions section at
http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html.
  I'm not completely convinced that the implemented methods actually
obey this though, nor that they are necessarily wrong in not doing so. :)

> Operations (examples are for Windows, because it is less trivial than
> Unix):
> * concatenation -- already defined:
> * "a" / "b" = "a/b"
> * "c:" / "d" = "c:d"
> * "/a/b" / "c:" = "c:"
> * "a" / "../b" = "a/../b"
> * "d:/a" / "/b" = "d:/b"
> * is_absolute(x) iff there exists f such that for all g, g / x = f.
> * is_absolute("d:/xyz") = true
> * is_absolute("/abc") = false
> * is_absolute("c:") = true or false, depending on whether we
> include the environment states into the filesystem node quantification.
> * relative(x, y) = z s.t. y / z is equivalent to x. (not always exists)
> * relative("a/b", "a") = "b"
> * relative("c:/a/b", "c:") = "/a/b"
> * relative("c:/a/b", "c:/") = "c:/"
> * relative("c:a/b", "c:/") = NaP
> * relative(x, "") = x

Agree with most of those, except:
   relative("c:/a/b", "c:/") = "a/b"
   relative("c:a/b", "d:/") = "c:a/b"
   relative("c:a/b", "c:/") = "a/b"
(Case 2 because that's still a valid relative path from d:/ base; case 3
because it's implied that c:/ is the cwd of c:, and given that the path
is equivalent to case 1. Though I accept that this third case may be
borderline; alternatively it should return the same as case 2.)

Also I'm dubious whether allowing the base-path of relative() to be
itself relative is useful in any way. In particular the case
relative(absolute-path, relative-path) seems nonsensical; at best it
should probably return the unmodified absolute-path.

Though I suppose for consistency with absolute/canonical, relative()
could use absolute(base) as its base internally, which would produce
reasonable results (albeit somewhat dependent on filesystem state -- but
that's not unexpected when dealing with relative paths).

> Note that on Windows, AFAIK but I may be mistaken, eval-equivalence and
> equivalence are the same, because ".." are resolved syntactically by
> Win32 API before any reparse points etc. kick-in. One can think of
> eval-parent ".." meaning 'go back' whereas the Unix parent ".." behave
> as a regular subdirectory. One may still wish to distinguish between
> equivalence and eval-equivalence on Windows.

I'm not sure how the Linux filesystem in general behaves, but the shell
typically appears to do the same thing -- cd into a symlinked folder
followed by "cd .." gets you back to your original folder, not the
parent of the symlink target.

> absolute(p,base) illogical
> --------------------------
>
> The case when p.has_root_name() && !p.has_root_directory() makes no
> sense. I remember that it was once left unspecified. Don't know why it
> got defined now.

absolute("c:foo", "c:/bar") == "c:/bar/foo"

This requires that case.

> * canonical() -- a better name would be resolve(), cause what it
> ultimately does is resolving symlinks? Naming it realpath() is also an
> option.

It also appears to currently be the only function that resolves ".."
path fragments. I would prefer if there were a function that does this
lexically, without hitting the filesystem or requiring that the path
actually exist.

(Perhaps system_complete()? Hard to tell from the docs, as it defines
its behaviour in terms of a function that does not exist.)

> Rationale: by the definitions section, paths are abstract entities
> detached from the filesystem. Asking for relative(x,y) or x/y are
> legitimate questions on their own, even if the paths do not exist at the
> specific point in time and space. Even when x and y are relative to a
> yet-unknown base. Making them depend on the current filesystem state is
> error prone.

I don't think anyone ever suggested relative() should require that the
path exist. But I don't think that it's unreasonable for it to react to
the current directory of each drive -- that's the purpose of relative
paths. (And if you want it to be relative to some other folder, you
should specify which one explicitly as an absolute path, and then there
is no dependency on the filesystem.)

> RFC and thanks for your attention,
> Yakov Galka

I think most of the points you brought up here aren't really on-topic in
this particular thread, and would have been better made in a separate
thread (or by writing your own alternative implementation). I doubt
it's likely that grand sweeping changes to an existing accepted library
would get anywhere. But that doesn't mean you couldn't submit an
alternative intended to supersede it; that's happened in the past.

But hey, I'm not a maintainer, so what do I know. :)


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk