Merge b99c2aebd5ddd6fb2f190731ba80b949fc3842b5 into 9fda7b0afbd0640f482f4aea8720a8c0afd18740

This commit is contained in:
Riccardo 2025-01-23 21:08:14 +01:00 committed by GitHub
commit 15c216a553
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 141 additions and 4 deletions

View File

@ -74,6 +74,9 @@ macro(AddTestExecutableWithStdCpp cppStd)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(filesystem_test_cpp${cppStd} PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(filesystem_test_cpp${cppStd} PRIVATE _CRT_SECURE_NO_WARNINGS)
endif() endif()
if(MINGW)
target_compile_options(filesystem_test_cpp${cppStd} PUBLIC "-Wa,-mbig-obj")
endif()
if(EMSCRIPTEN) if(EMSCRIPTEN)
set_target_properties(filesystem_test_cpp${cppStd} PROPERTIES LINK_FLAGS "-g4 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1") set_target_properties(filesystem_test_cpp${cppStd} PROPERTIES LINK_FLAGS "-g4 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1")
endif() endif()

View File

@ -300,6 +300,21 @@
#error "Can't raise unicode errors with exception support disabled" #error "Can't raise unicode errors with exception support disabled"
#endif #endif
#if defined(GHC_OS_WINDOWS)
#if !defined(__GLIBCXX__) || (defined(_GLIBCXX_HAVE__WFOPEN) && defined(_GLIBCXX_USE_WCHAR_T))
#define GHC_HAS_FSTREAM_OPEN_WITH_WCHAR
#elif defined(__GLIBCXX__) && defined(_WIO_DEFINED)
#define GHC_HAS_WIO_DEFINED
#include <ext/stdio_filebuf.h>
#include <fcntl.h>
#include <share.h>
#ifndef _S_IREAD
// Some tests disable the previous inclusion of sys/stat.h; however, we need it when using old versions of MinGW.
#include <sys/stat.h>
#endif
#endif
#endif
namespace ghc { namespace ghc {
namespace filesystem { namespace filesystem {
@ -1142,8 +1157,66 @@ GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link, std:
GHC_FS_API uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept; GHC_FS_API uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept;
#endif #endif
#if defined(GHC_OS_WINDOWS) && (!defined(__GLIBCXX__) || (defined(_GLIBCXX_HAVE__WFOPEN) && defined(_GLIBCXX_USE_WCHAR_T))) #ifdef GHC_HAS_WIO_DEFINED
#define GHC_HAS_FSTREAM_OPEN_WITH_WCHAR namespace detail {
inline int open_flags(std::ios::openmode mode)
{
const bool out = (mode & std::ios::out) != 0;
const bool in = (mode & std::ios::in) != 0;
int flags = 0;
if (in && out) {
flags |= _O_RDWR | _O_CREAT;
}
else if (out) {
flags |= _O_WRONLY | _O_CREAT;
}
else {
flags |= _O_RDONLY;
}
if ((mode & std::ios::app) != 0) {
flags |= _O_APPEND;
}
if ((mode & std::ios::trunc) != 0) {
flags |= _O_TRUNC;
}
flags |= (mode & std::ios::binary) != 0 ? _O_BINARY : _O_TEXT;
return flags;
}
inline int permission_flags(std::ios::openmode mode) {
int flags = 0;
if ((mode & std::ios::in) != 0) {
flags |= _S_IREAD;
}
if ((mode & std::ios::out) != 0) {
flags |= _S_IWRITE;
}
return flags;
}
template< class charT, class traits = std::char_traits< charT>>
__gnu_cxx::stdio_filebuf<charT, traits> open_filebuf_from_unicode_path(const path& file_path, std::ios::openmode mode) {
// Opening a file handle/descriptor from the native (wide) string path.
int file_handle = 0;
_wsopen_s(&file_handle, GHC_NATIVEWP(file_path), open_flags(mode), _SH_DENYNO, permission_flags(mode));
// Creating a GLIBCXX stdio_filebuf object from the file handle (it will check if the handle is actually opened).
__gnu_cxx::stdio_filebuf<charT, traits> result{file_handle, mode};
// If mode has the flag std::ios::ate, we need to seek at the end of the filebuf.
if (result.is_open() && (mode & std::ios::ate) != 0){
const auto seek_result = result.pubseekoff(0, std::ios::end, mode);
const auto end_pos = typename traits::pos_type(typename traits::off_type(-1));
if (seek_result == end_pos) {
// If the seeking fails, we need to close the filebuf (as per the standard).
result.close();
}
}
// Returning the filebuf in any case, whether we successfully opened it or not (the caller will check it).
return result;
}
} // namespace detail
#endif #endif
// Non-C++17 add-on std::fstream wrappers with path // Non-C++17 add-on std::fstream wrappers with path
@ -1159,6 +1232,16 @@ public:
{ {
#ifdef GHC_HAS_FSTREAM_OPEN_WITH_WCHAR #ifdef GHC_HAS_FSTREAM_OPEN_WITH_WCHAR
return std::basic_filebuf<charT, traits>::open(p.wstring().c_str(), mode) ? this : 0; return std::basic_filebuf<charT, traits>::open(p.wstring().c_str(), mode) ? this : 0;
#elif defined(GHC_HAS_WIO_DEFINED)
if (this->is_open()) {
return nullptr;
}
auto filebuf = detail::open_filebuf_from_unicode_path<charT, traits>(p, mode);
if (!filebuf.is_open()) {
return nullptr;
}
this->swap(filebuf);
return this;
#else #else
return std::basic_filebuf<charT, traits>::open(p.string().c_str(), mode) ? this : 0; return std::basic_filebuf<charT, traits>::open(p.string().c_str(), mode) ? this : 0;
#endif #endif
@ -1176,6 +1259,20 @@ public:
{ {
} }
void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream<charT, traits>::open(p.wstring().c_str(), mode); } void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream<charT, traits>::open(p.wstring().c_str(), mode); }
#elif defined(GHC_HAS_WIO_DEFINED)
explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in)
{
open(p, mode);
}
void open(const path& p, std::ios_base::openmode mode = std::ios_base::in)
{
*this->rdbuf() = detail::open_filebuf_from_unicode_path<charT, traits>(p, mode | std::ios_base::in);
if (!this->is_open()) {
this->setstate(std::ios_base::failbit);
} else {
this->clear();
}
}
#else #else
explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in)
: std::basic_ifstream<charT, traits>(p.string().c_str(), mode) : std::basic_ifstream<charT, traits>(p.string().c_str(), mode)
@ -1199,6 +1296,20 @@ public:
{ {
} }
void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream<charT, traits>::open(p.wstring().c_str(), mode); } void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream<charT, traits>::open(p.wstring().c_str(), mode); }
#elif defined(GHC_HAS_WIO_DEFINED)
explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out)
{
open(p, mode);
}
void open(const path& p, std::ios_base::openmode mode = std::ios_base::out)
{
*this->rdbuf() = detail::open_filebuf_from_unicode_path<charT, traits>(p, mode | std::ios_base::out);
if (!this->is_open()) {
this->setstate(std::ios_base::failbit);
} else {
this->clear();
}
}
#else #else
explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out)
: std::basic_ofstream<charT, traits>(p.string().c_str(), mode) : std::basic_ofstream<charT, traits>(p.string().c_str(), mode)
@ -1222,6 +1333,20 @@ public:
{ {
} }
void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream<charT, traits>::open(p.wstring().c_str(), mode); } void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream<charT, traits>::open(p.wstring().c_str(), mode); }
#elif defined(GHC_HAS_WIO_DEFINED)
explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
open(p, mode);
}
void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
*this->rdbuf() = detail::open_filebuf_from_unicode_path<charT, traits>(p, mode | std::ios_base::in | std::ios_base::out);
if (!this->is_open()) {
this->setstate(std::ios_base::failbit);
} else {
this->clear();
}
}
#else #else
explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::basic_fstream<charT, traits>(p.string().c_str(), mode) : std::basic_fstream<charT, traits>(p.string().c_str(), mode)

View File

@ -43,6 +43,9 @@ else()
message("Generating test runner for normal test...") message("Generating test runner for normal test...")
add_executable(filesystem_test filesystem_test.cpp catch.hpp) add_executable(filesystem_test filesystem_test.cpp catch.hpp)
target_link_libraries(filesystem_test ghc_filesystem) target_link_libraries(filesystem_test ghc_filesystem)
if(MINGW)
target_compile_options(filesystem_test PUBLIC "-Wa,-mbig-obj")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
target_link_libraries(filesystem_test xnet) target_link_libraries(filesystem_test xnet)
endif() endif()
@ -64,10 +67,13 @@ else()
add_executable(filesystem_test_char filesystem_test.cpp catch.hpp) add_executable(filesystem_test_char filesystem_test.cpp catch.hpp)
target_link_libraries(filesystem_test_char ghc_filesystem) target_link_libraries(filesystem_test_char ghc_filesystem)
SetTestCompileOptions(filesystem_test_char) SetTestCompileOptions(filesystem_test_char)
if(MINGW)
target_compile_options(filesystem_test_char PUBLIC "-Wa,-mbig-obj")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(filesystem_test_char PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) target_compile_definitions(filesystem_test_char PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE)
else() else()
target_compile_definitions(filesystem_test_char PRIVATE GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) target_compile_definitions(filesystem_test_char PRIVATE GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE)
endif() endif()
ParseAndAddCatchTests(filesystem_test_char) ParseAndAddCatchTests(filesystem_test_char)
endif() endif()
@ -95,6 +101,9 @@ SetTestCompileOptions(fwd_impl_test)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX) target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX)
endif() endif()
if(MINGW)
target_compile_options(fwd_impl_test PUBLIC "-Wa,-mbig-obj")
endif()
add_test(fwd_impl_test fwd_impl_test) add_test(fwd_impl_test fwd_impl_test)
add_executable(exception exception.cpp) add_executable(exception exception.cpp)