Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++20 status.

3096.path::lexically_relative is confused by trailing slashes

Section: 31.12.6.5.11[fs.path.gen]Status:C++20Submitter: Jonathan WakelyOpened: 2018-04-04Last modified: 2021-02-25

Priority:2

View all otherissues in [fs.path.gen].

View all issues withC++20 status.

Discussion:

filesystem::proximate("/dir", "/dir/") returns"." when"/dir" exists, and".." otherwise. It should always be"." because whether it exists shouldn't matter.

The problem is infilesystem::path::lexically_relative, as shown by:

path("/dir").lexically_relative("/dir/.");// yields ""path("/dir").lexically_relative("/dir/");// yields ".."

The two calls should yield the same result, and when iteration of apath with a trailing slash gave "." as the final element they did yield the same result. In the final C++17 spec the trailing slash produces an empty filename in the iteration sequence, andlexically_relative doesn't handle that correctly.

[2018-04-10, Jonathan comments]

There are more inconsistencies with paths that are "obviously" equivalent to the human reader:

path("a/b/c").lexically_relative("a/b/c")// yields "."path("a/b/c").lexically_relative("a/b/c/")// yields ".."path("a/b/c").lexically_relative("a/b/c/.")// yields ""path("a/b/c/").lexically_relative("a/b/c")// yields ""path("a/b/c/.").lexically_relative("a/b/c")// yields "."path("a/b/c/.").lexically_relative("a/b/c/")// yields "../."

I think the right solution is:

  1. when counting[b, base.end()) in bullet (4.2) handle empty filename elements (which can only occur as the last element, due to a trailing slash) equivalently to dot elements; and

  2. add a new condition for the case wheren == 0 and[a, end()) contains no non-empty elements, i.e. the paths are equivalent except for final dots or a final slash, which don't introduce any relative difference between the paths.

[2018-06-18 after reflector discussion]

Priority set to 2

[2018-08-23 Batavia Issues processing]

Status to Tentatively Ready

[2018-11, Adopted in San Diego]

Proposed resolution:

This wording is relative toN4727.

  1. Edit 31.12.6.5.11[fs.path.gen] as indicated:

    path lexically_relative(const path& base) const;

    -3-Returns:*this made relative tobase. Does not resolve (31.12.6[fs.class.path]) symlinks. Does not first normalize (31.12.6.2[fs.path.generic])*this orbase.

    -4-Effects: Ifroot_name() != base.root_name() istrue oris_absolute() != base.is_absolute()istrue or!has_root_directory() && base.has_root_directory() istrue, returnspath(). Determines the first mismatched element of*this andbase as if by:

    auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());

    Then,

    1. (4.1) — ifa == end() andb == base.end(), returnspath("."); otherwise

    2. (4.2) — letn be the number offilename elements in[b, base.end()) that are not dot or dot-dotor empty, minus the number that are dot-dot. Ifn<0, returnspath(); otherwise

    3. (4.?) — ifn == 0 and(a == end() || a->empty()), returnspath("."); otherwise

    4. (4.3) — returns an object of classpath that is default-constructed, followed by […]


[8]ページ先頭

©2009-2026 Movatter.jp