[libc-commits] [libc] [libc] implement fgetwc (PR #196159)

Muhammad Bassiouni via libc-commits libc-commits at lists.llvm.org
Thu May 7 06:15:44 PDT 2026


================
@@ -0,0 +1,145 @@
+//===-- Unittests for fgetwc ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/wchar_macros.h" // For WEOF
+#include "src/stdio/fclose.h"
+#include "src/stdio/feof.h"
+#include "src/stdio/ferror.h"
+#include "src/stdio/fopen.h"
+#include "src/stdio/fwrite.h"
+#include "src/wchar/fgetwc.h"
+#include "src/wchar/fwide.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcFgetwcTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcFgetwcTest, ReadASCII) {
+  auto FILENAME =
+      libc_make_test_file_path(APPEND_LIBC_TEST("fgetwc_ascii.test"));
+  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+
+  // Write "abc"
+  constexpr char CONTENT[] = "abc";
+  ASSERT_EQ(LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT) - 1, file),
+            sizeof(CONTENT) - 1);
+  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
+
+  // Open for reading
+  file = LIBC_NAMESPACE::fopen(FILENAME, "r");
+  ASSERT_FALSE(file == nullptr);
+
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'a'));
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'b'));
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'c'));
+
+  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
+}
+
+TEST_F(LlvmLibcFgetwcTest, ReadUtf8) {
+  auto FILENAME =
+      libc_make_test_file_path(APPEND_LIBC_TEST("fgetwc_utf8.test"));
+  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+
+  // Write "a¢€𐍈"
+  // a   -> 0x61 (1-byte)
+  // ¢   -> 0xC2 0xA2 (2-byte)
+  // €   -> 0xE2 0x82 0xAC (3-byte)
+  // 𐍈   -> 0xF0 0x90 0x8D 0x88 (4-byte)
+  constexpr unsigned char CONTENT[] = {0x61, 0xC2, 0xA2, 0xE2, 0x82,
+                                       0xAC, 0xF0, 0x90, 0x8D, 0x88};
+  ASSERT_EQ(LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), file),
+            sizeof(CONTENT));
+  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
+
+  // Open for reading
+  file = LIBC_NAMESPACE::fopen(FILENAME, "r");
+  ASSERT_FALSE(file == nullptr);
+
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'a'));
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'¢'));
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'€'));
+  EXPECT_EQ(LIBC_NAMESPACE::fgetwc(file), static_cast<wint_t>(L'𐍈'));
----------------
bassiounix wrote:

4 byte `wchar`s would be problematic on windows because `wint_t` is only 2 bytes there.
We should add a guard here with any code that deals with any kind of size regression on any platform.

I think it didn't fail here is because there's no cmake entries yet.

https://github.com/llvm/llvm-project/pull/196159


More information about the libc-commits mailing list