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 "../macro/os_detector.hpp"
#include "../string/reinterpret.hpp"
#if defined(YYCC_OS_WINDOWS)
#include "../windows/import_guard_head.hpp"
#include <Windows.h>
#include "../windows/import_guard_tail.hpp"
#endif
// Include header file including MSVCRT specific function.
#include <wchar.h>
// Include encoding convertion header
#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
#endif
namespace yycc::patch::fopen {
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
// std::wstring wmode, wpath;
// if (!YYCC::EncodingHelper::UTF8ToWchar(u8_mode, wmode))
// return nullptr;
// if (!YYCC::EncodingHelper::UTF8ToWchar(u8_filepath, wpath))
// return nullptr;
// // call microsoft specified fopen which support wchar as argument.
// return _wfopen(wpath.c_str(), wmode.c_str());
// #else
// return std::fopen(REINTERPRET::as_ordinary(u8_filepath), REINTERPRET::as_ordinary(u8_mode));
// #endif
// check convertion success
if (wmode.has_value() && wpath.has_value()) {
// call microsoft specified fopen which support wchar as argument.
return _wfopen(wpath.value().c_str(), wmode.value().c_str());
} else {
// fail to convert encoding
return nullptr;
}
#else
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/builder.cpp
yycc/patch/ptr_pad.cpp
yycc/patch/fopen.cpp
yycc/string/op.cpp
yycc/string/reinterpret.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