diff --git a/src/yycc/patch/fopen.cpp b/src/yycc/patch/fopen.cpp index ede83e4..772e044 100644 --- a/src/yycc/patch/fopen.cpp +++ b/src/yycc/patch/fopen.cpp @@ -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 -#include "../windows/import_guard_tail.hpp" -#endif - +// Include header file including MSVCRT specific function. +#include +// 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 diff --git a/testbench/CMakeLists.txt b/testbench/CMakeLists.txt index 8ba0e64..4734267 100644 --- a/testbench/CMakeLists.txt +++ b/testbench/CMakeLists.txt @@ -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 diff --git a/testbench/yycc/patch/fopen.cpp b/testbench/yycc/patch/fopen.cpp new file mode 100644 index 0000000..c294857 --- /dev/null +++ b/testbench/yycc/patch/fopen.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#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