This fixes linking against a DLL of libc++ while using the common headers (generated from the static version of the library, but which work for both shared and static versions) when calling e.g. std::filesystem::u8path.
175 lines
6.3 KiB
Diff
175 lines
6.3 KiB
Diff
From bd884f520faaa41618d6e901e1631ff02fab3044 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
|
|
Date: Wed, 4 Nov 2020 15:59:56 +0200
|
|
Subject: [PATCH 14/25] [libcxx] Implement append and operator/ properly for
|
|
windows
|
|
|
|
The root_path function has to be changed to return the parsed bit
|
|
as-is; otherwise a path like "//net" gets a root path of "//net/", as
|
|
the root name, "//net", gets the root directory (an empty string) appended,
|
|
forming "//net/". (The same doesn't happen for the root dir "c:" though.)
|
|
|
|
Differential Revision: https://reviews.llvm.org/D91178
|
|
|
|
(cherry picked from commit 78d693faecf98718dadfa6e39f291e5999f380c7)
|
|
---
|
|
libcxx/include/filesystem | 52 ++++++++++++++++---
|
|
.../path.member/path.append.pass.cpp | 48 +++++++++++++++++
|
|
2 files changed, 92 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem
|
|
index eecf416e851c..201cecc0e8b2 100644
|
|
--- a/libcxx/include/filesystem
|
|
+++ b/libcxx/include/filesystem
|
|
@@ -1006,14 +1006,44 @@ public:
|
|
return *this;
|
|
}
|
|
|
|
-private:
|
|
- template <class _ECharT>
|
|
- static bool __source_is_absolute(_ECharT __first_or_null) {
|
|
- return __is_separator(__first_or_null);
|
|
- }
|
|
-
|
|
public:
|
|
// appends
|
|
+#if defined(_LIBCPP_WIN32API)
|
|
+ path& operator/=(const path& __p) {
|
|
+ auto __p_root_name = __p.__root_name();
|
|
+ auto __p_root_name_size = __p_root_name.size();
|
|
+ if (__p.is_absolute() ||
|
|
+ (!__p_root_name.empty() && __p_root_name != root_name())) {
|
|
+ __pn_ = __p.__pn_;
|
|
+ return *this;
|
|
+ }
|
|
+ if (__p.has_root_directory()) {
|
|
+ path __root_name_str = root_name();
|
|
+ __pn_ = __root_name_str.native();
|
|
+ __pn_ += __p.__pn_.substr(__p_root_name_size);
|
|
+ return *this;
|
|
+ }
|
|
+ if (has_filename() || (!has_root_directory() && is_absolute()))
|
|
+ __pn_ += preferred_separator;
|
|
+ __pn_ += __p.__pn_.substr(__p_root_name_size);
|
|
+ return *this;
|
|
+ }
|
|
+ template <class _Source>
|
|
+ _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
|
|
+ operator/=(const _Source& __src) {
|
|
+ return operator/=(path(__src));
|
|
+ }
|
|
+
|
|
+ template <class _Source>
|
|
+ _EnableIfPathable<_Source> append(const _Source& __src) {
|
|
+ return operator/=(path(__src));
|
|
+ }
|
|
+
|
|
+ template <class _InputIt>
|
|
+ path& append(_InputIt __first, _InputIt __last) {
|
|
+ return operator/=(path(__first, __last));
|
|
+ }
|
|
+#else
|
|
path& operator/=(const path& __p) {
|
|
if (__p.is_absolute()) {
|
|
__pn_ = __p.__pn_;
|
|
@@ -1038,7 +1068,8 @@ public:
|
|
_EnableIfPathable<_Source> append(const _Source& __src) {
|
|
using _Traits = __is_pathable<_Source>;
|
|
using _CVT = _PathCVT<_SourceChar<_Source> >;
|
|
- if (__source_is_absolute(_Traits::__first_or_null(__src)))
|
|
+ bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src));
|
|
+ if (__source_is_absolute)
|
|
__pn_.clear();
|
|
else if (has_filename())
|
|
__pn_ += preferred_separator;
|
|
@@ -1051,13 +1082,14 @@ public:
|
|
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
|
|
static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
|
|
using _CVT = _PathCVT<_ItVal>;
|
|
- if (__first != __last && __source_is_absolute(*__first))
|
|
+ if (__first != __last && __is_separator(*__first))
|
|
__pn_.clear();
|
|
else if (has_filename())
|
|
__pn_ += preferred_separator;
|
|
_CVT::__append_range(__pn_, __first, __last);
|
|
return *this;
|
|
}
|
|
+#endif
|
|
|
|
// concatenation
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
@@ -1295,7 +1327,11 @@ public:
|
|
return string_type(__root_directory());
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY path root_path() const {
|
|
+#if defined(_LIBCPP_WIN32API)
|
|
+ return string_type(__root_path_raw());
|
|
+#else
|
|
return root_name().append(string_type(__root_directory()));
|
|
+#endif
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY path relative_path() const {
|
|
return string_type(__relative_path());
|
|
diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
|
|
index eabd6f92da3c..ad9d06eb9849 100644
|
|
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
|
|
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
|
|
@@ -63,6 +63,54 @@ const AppendOperatorTestcase Cases[] =
|
|
, {S("/p1"), S("/p2/"), S("/p2/")}
|
|
, {S("p1"), S(""), S("p1/")}
|
|
, {S("p1/"), S(""), S("p1/")}
|
|
+
|
|
+ , {S("//host"), S("foo"), S("//host/foo")}
|
|
+ , {S("//host/"), S("foo"), S("//host/foo")}
|
|
+ , {S("//host"), S(""), S("//host/")}
|
|
+
|
|
+#ifdef _WIN32
|
|
+ , {S("foo"), S("C:/bar"), S("C:/bar")}
|
|
+ , {S("foo"), S("C:"), S("C:")}
|
|
+
|
|
+ , {S("C:"), S(""), S("C:")}
|
|
+ , {S("C:foo"), S("/bar"), S("C:/bar")}
|
|
+ , {S("C:foo"), S("bar"), S("C:foo/bar")}
|
|
+ , {S("C:/foo"), S("bar"), S("C:/foo/bar")}
|
|
+ , {S("C:/foo"), S("/bar"), S("C:/bar")}
|
|
+
|
|
+ , {S("C:foo"), S("C:/bar"), S("C:/bar")}
|
|
+ , {S("C:foo"), S("C:bar"), S("C:foo/bar")}
|
|
+ , {S("C:/foo"), S("C:/bar"), S("C:/bar")}
|
|
+ , {S("C:/foo"), S("C:bar"), S("C:/foo/bar")}
|
|
+
|
|
+ , {S("C:foo"), S("c:/bar"), S("c:/bar")}
|
|
+ , {S("C:foo"), S("c:bar"), S("c:bar")}
|
|
+ , {S("C:/foo"), S("c:/bar"), S("c:/bar")}
|
|
+ , {S("C:/foo"), S("c:bar"), S("c:bar")}
|
|
+
|
|
+ , {S("C:/foo"), S("D:bar"), S("D:bar")}
|
|
+#else
|
|
+ , {S("foo"), S("C:/bar"), S("foo/C:/bar")}
|
|
+ , {S("foo"), S("C:"), S("foo/C:")}
|
|
+
|
|
+ , {S("C:"), S(""), S("C:/")}
|
|
+ , {S("C:foo"), S("/bar"), S("/bar")}
|
|
+ , {S("C:foo"), S("bar"), S("C:foo/bar")}
|
|
+ , {S("C:/foo"), S("bar"), S("C:/foo/bar")}
|
|
+ , {S("C:/foo"), S("/bar"), S("/bar")}
|
|
+
|
|
+ , {S("C:foo"), S("C:/bar"), S("C:foo/C:/bar")}
|
|
+ , {S("C:foo"), S("C:bar"), S("C:foo/C:bar")}
|
|
+ , {S("C:/foo"), S("C:/bar"), S("C:/foo/C:/bar")}
|
|
+ , {S("C:/foo"), S("C:bar"), S("C:/foo/C:bar")}
|
|
+
|
|
+ , {S("C:foo"), S("c:/bar"), S("C:foo/c:/bar")}
|
|
+ , {S("C:foo"), S("c:bar"), S("C:foo/c:bar")}
|
|
+ , {S("C:/foo"), S("c:/bar"), S("C:/foo/c:/bar")}
|
|
+ , {S("C:/foo"), S("c:bar"), S("C:/foo/c:bar")}
|
|
+
|
|
+ , {S("C:/foo"), S("D:bar"), S("C:/foo/D:bar")}
|
|
+#endif
|
|
};
|
|
|
|
|
|
--
|
|
2.25.1
|
|
|