summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-11-15 19:58:15 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-11-15 19:58:15 +0000
commit01eb211bade92275e39254cc5a0dc21834dbcac4 (patch)
tree5bc1f1bc46184968c816940f078b28e0f8840525 /libstdc++-v3/src
parent838fd641a6ffb7e4734321de14385bece3e4506b (diff)
libstdc++: Implement LWG 3070 in path::lexically_relative
* src/c++17/fs_path.cc [_GLIBCXX_FILESYSTEM_IS_WINDOWS] (is_disk_designator): New helper function. (path::_Parser::root_path()): Use is_disk_designator. (path::lexically_relative(const path&)): Implement resolution of LWG 3070. * testsuite/27_io/filesystem/path/generation/relative.cc: Check with path components that look like a root-name. From-SVN: r278313
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/c++17/fs_path.cc22
1 files changed, 21 insertions, 1 deletions
diff --git a/libstdc++-v3/src/c++17/fs_path.cc b/libstdc++-v3/src/c++17/fs_path.cc
index 14842452354..5fba971fef6 100644
--- a/libstdc++-v3/src/c++17/fs_path.cc
+++ b/libstdc++-v3/src/c++17/fs_path.cc
@@ -47,6 +47,13 @@ static inline bool is_dir_sep(path::value_type ch)
#endif
}
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+static inline bool is_disk_designator(std::wstring_view s)
+{
+ return s.length() == 2 && s[1] == L':';
+}
+#endif
+
struct path::_Parser
{
using string_view_type = std::basic_string_view<value_type>;
@@ -117,7 +124,7 @@ struct path::_Parser
++pos;
}
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
- else if (len > 1 && input[1] == L':')
+ else if (is_disk_designator(input.substr(0, 2)))
{
// got disk designator
root.first.str = input.substr(0, 2);
@@ -1747,6 +1754,19 @@ path::lexically_relative(const path& base) const
if (!has_root_directory() && base.has_root_directory())
return ret;
auto [a, b] = std::mismatch(begin(), end(), base.begin(), base.end());
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3070. path::lexically_relative causes surprising results if a filename
+ // can also be a root-name
+ if (!empty())
+ for (auto& p : _M_cmpts)
+ if (p._M_type() == _Type::_Filename && is_disk_designator(p.native()))
+ return ret;
+ if (!base.empty())
+ for (auto i = b, end = base.end(); i != end; ++i)
+ if (i->_M_type() == _Type::_Filename && is_disk_designator(i->native()))
+ return ret;
+#endif
if (a == end() && b == base.end())
ret = ".";
else