gulrak / filesystem

An implementation of C++17 std::filesystem for C++11 /C++14/C++17/C++20 on Windows, macOS, Linux and FreeBSD.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Case-Sensitivity For Windows Drive Letters

jnhyatt opened this issue · comments

Windows case-sensitivity for drive letters is not always interpreted correctly.

To Reproduce:

fs::path path = fs::relative("c:\\dev\\working\\directory\\file.txt");

Assuming the current working directory is C:\dev\working\directory, one would expect path to be file.txt. However, because the second (optional) argument to relative is evaluated as C:\dev\working\directory (capital 'C'), lexically_relative will exit early on its first check and simply return a default-constructed path.

A fix for this specific issue could be to force drive letters to be capital, say, in weakly_canonical. Now, even Windows can't guarantee case-insensitivity for all file names, but I do believe that drive letters are case-insensitive -- for example, I don't think you can have a d: and D: drive mounted simultaneously. Additionally, under MSVC, it appears that path equality checks are completely case-insensitive when using the standard template library's file system implementation. This does not seem to be the case when compiling under any other compiler.

Good catch, I'll look into it.

It took me some time to decide how to tackle this. In the end, my take is to make the comparison for the root name on Windows (drive letter) case insensitive. As this is in part correlating with the different fs::path::compare() rules from LWG 2936, I started implementing an option to enable that one as well, but the drive letter case insensitivity is not part of that option, so should be active starting from v1.3.6 if there are no objections with that solution.

I plan to keep LWG_2936_BEHAVIOUR disabled by default in v1.3.6, but I either enable it by default on v1.4.0 or at least when C++20 is found.