refs #125, fix broken windows long path test and broken create_directories with prefixed long paths

This commit is contained in:
Steffen Schümann 2021-06-10 01:21:07 +02:00
parent 4e21ab3057
commit 15e814e820
2 changed files with 37 additions and 33 deletions

View File

@ -595,6 +595,7 @@ private:
friend void swap(path& lhs, path& rhs) noexcept; friend void swap(path& lhs, path& rhs) noexcept;
friend size_t hash_value(const path& p) noexcept; friend size_t hash_value(const path& p) noexcept;
friend path canonical(const path& p, std::error_code& ec); friend path canonical(const path& p, std::error_code& ec);
friend bool create_directories(const path& p, std::error_code& ec) noexcept;
string_type::size_type root_name_length() const noexcept; string_type::size_type root_name_length() const noexcept;
void postprocess_path_with_format(format fmt); void postprocess_path_with_format(format fmt);
void check_long_path(); void check_long_path();
@ -3900,35 +3901,36 @@ GHC_INLINE bool create_directories(const path& p, std::error_code& ec) noexcept
path current; path current;
ec.clear(); ec.clear();
bool didCreate = false; bool didCreate = false;
for (path::string_type part : p) { auto rootPathLen = p._prefixLength + p.root_name_length() + (p.has_root_directory() ? 1 : 0);
current = p.native().substr(0, rootPathLen);
path folders(p._path.substr(rootPathLen));
for (path::string_type part : folders) {
current /= part; current /= part;
if (current != p.root_name() && current != p.root_path()) { std::error_code tec;
std::error_code tec; auto fs = status(current, tec);
auto fs = status(current, tec); if (tec && fs.type() != file_type::not_found) {
if (tec && fs.type() != file_type::not_found) { ec = tec;
ec = tec; return false;
return false;
}
if (!exists(fs)) {
create_directory(current, ec);
if (ec) {
std::error_code tmp_ec;
if (is_directory(current, tmp_ec)) {
ec.clear();
}
else {
return false;
}
}
didCreate = true;
}
#ifndef LWG_2935_BEHAVIOUR
else if (!is_directory(fs)) {
ec = detail::make_error_code(detail::portable_error::exists);
return false;
}
#endif
} }
if (!exists(fs)) {
create_directory(current, ec);
if (ec) {
std::error_code tmp_ec;
if (is_directory(current, tmp_ec)) {
ec.clear();
}
else {
return false;
}
}
didCreate = true;
}
#ifndef LWG_2935_BEHAVIOUR
else if (!is_directory(fs)) {
ec = detail::make_error_code(detail::portable_error::exists);
return false;
}
#endif
} }
return didCreate; return didCreate;
} }

View File

@ -2854,13 +2854,15 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long
CHECK_NOTHROW(fs::create_directory(dir)); CHECK_NOTHROW(fs::create_directory(dir));
CHECK(fs::exists(dir)); CHECK(fs::exists(dir));
generateFile(dir / "f0"); generateFile(dir / "f0");
CHECK(fs::exists(dir / "f0")); REQUIRE(fs::exists(dir / "f0"));
auto native = dir.u8string();
if (native.substr(0, 4) == u8"\\\\?\\") {
break;
}
} }
CHECK(c <= 'Z'); CHECK(c > 'Z');
fs::remove_all(fs::current_path() / std::string(16, 'A'));
CHECK(!fs::exists(fs::current_path() / std::string(16, 'A')));
CHECK_NOTHROW(fs::create_directories(dir));
CHECK(fs::exists(dir));
generateFile(dir / "f0");
CHECK(fs::exists(dir / "f0"));
#else #else
WARN("Windows specific tests are empty on non-Windows systems."); WARN("Windows specific tests are empty on non-Windows systems.");
#endif #endif