fix: fix unfinished u8 fopen.

- finish unfinished utf8 version fopen.
- add testbench for it.
This commit is contained in:
2025-08-13 08:49:18 +08:00
parent e23a1346eb
commit 8fcfa180b4
3 changed files with 50 additions and 22 deletions

View File

@ -1,35 +1,38 @@
#include "fopen.hpp" #include "fopen.hpp"
#include "../macro/os_detector.hpp" #include "../macro/os_detector.hpp"
#include "../string/reinterpret.hpp"
#if defined(YYCC_OS_WINDOWS) #if defined(YYCC_OS_WINDOWS)
#include "../windows/import_guard_head.hpp" // Include header file including MSVCRT specific function.
#include <Windows.h> #include <wchar.h>
#include "../windows/import_guard_tail.hpp" // Include encoding convertion header
#endif #include "../encoding/windows.hpp"
// Define namespace macro
#define ENC ::yycc::encoding::windows
#else
// Include reinterpret header and define namespace macro
#include "../string/reinterpret.hpp"
#define REINTERPRET ::yycc::string::reinterpret #define REINTERPRET ::yycc::string::reinterpret
#endif
namespace yycc::patch::fopen { namespace yycc::patch::fopen {
std::FILE* fopen(const char8_t* u8_filepath, const char8_t* u8_mode) { std::FILE* fopen(const char8_t* u8_filepath, const char8_t* u8_mode) {
// TODO: Fix this after finish Windows encoding #if defined(YYCC_OS_WINDOWS)
// #if defined(YYCC_OS_WINDOWS) // convert mode and file path to wchar
auto wmode = ENC::to_wchar(u8_mode);
auto wpath = ENC::to_wchar(u8_filepath);
// // convert mode and file path to wchar // check convertion success
// std::wstring wmode, wpath; if (wmode.has_value() && wpath.has_value()) {
// if (!YYCC::EncodingHelper::UTF8ToWchar(u8_mode, wmode)) // call microsoft specified fopen which support wchar as argument.
// return nullptr; return _wfopen(wpath.value().c_str(), wmode.value().c_str());
// if (!YYCC::EncodingHelper::UTF8ToWchar(u8_filepath, wpath)) } else {
// return nullptr; // fail to convert encoding
return nullptr;
// // call microsoft specified fopen which support wchar as argument. }
// return _wfopen(wpath.c_str(), wmode.c_str()); #else
// #else
// return std::fopen(REINTERPRET::as_ordinary(u8_filepath), REINTERPRET::as_ordinary(u8_mode));
// #endif
return std::fopen(REINTERPRET::as_ordinary(u8_filepath), REINTERPRET::as_ordinary(u8_mode)); return std::fopen(REINTERPRET::as_ordinary(u8_filepath), REINTERPRET::as_ordinary(u8_mode));
#endif
} }
} } // namespace yycc::patch::fopen

View File

@ -11,6 +11,7 @@ PRIVATE
yycc/constraint.cpp yycc/constraint.cpp
yycc/constraint/builder.cpp yycc/constraint/builder.cpp
yycc/patch/ptr_pad.cpp yycc/patch/ptr_pad.cpp
yycc/patch/fopen.cpp
yycc/string/op.cpp yycc/string/op.cpp
yycc/string/reinterpret.cpp yycc/string/reinterpret.cpp
yycc/num/parse.cpp yycc/num/parse.cpp

View File

@ -0,0 +1,24 @@
#include <gtest/gtest.h>
#include <yycc.hpp>
#include <yycc/patch/fopen.hpp>
#define FOPEN ::yycc::patch::fopen
namespace yycctest::patch::fopen {
TEST(PatchFopen, Normal) {
FILE* handle;
#if defined(YYCC_OS_WINDOWS)
// In Windows, we can always visit NUL device.
handle = FOPEN::fopen(u8"NUL", u8"wb");
#else
// In other system following UNIX design, we can visit /dev/null device.
handle = FOPEN::fopen(u8"/dev/null", u8"wb");
#endif
ASSERT_TRUE(handle != nullptr);
std::fclose(handle);
}
} // namespace yycctest::patch::fopen