[libc-commits] [libc] [libc] implement fwide (PR #196157)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Wed May 6 13:05:30 PDT 2026


https://github.com/michaelrj-google updated https://github.com/llvm/llvm-project/pull/196157

>From 0af6f39e1069674be47231fc12da2c8087bd8ad3 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Wed, 6 May 2026 18:26:55 +0000
Subject: [PATCH 1/2] [libc] implement fwide

Add fwide function and tests. Part 1/11. All build file changes are in
part 11.

Assisted by Gemini
---
 libc/src/wchar/fwide.cpp           | 38 +++++++++++++++++++++
 libc/src/wchar/fwide.h             | 21 ++++++++++++
 libc/test/src/wchar/fwide_test.cpp | 54 ++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 libc/src/wchar/fwide.cpp
 create mode 100644 libc/src/wchar/fwide.h
 create mode 100644 libc/test/src/wchar/fwide_test.cpp

diff --git a/libc/src/wchar/fwide.cpp b/libc/src/wchar/fwide.cpp
new file mode 100644
index 0000000000000..6965b4ea1ef82
--- /dev/null
+++ b/libc/src/wchar/fwide.cpp
@@ -0,0 +1,38 @@
+//===-- Implementation of fwide -------------------------------------------===//
+//
+// 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 "src/wchar/fwide.h"
+#include "hdr/types/FILE.h"
+#include "src/__support/File/file.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, fwide, (::FILE *stream, int mode)) {
+  LIBC_CRASH_ON_NULLPTR(stream);
+  auto *f = reinterpret_cast<File *>(stream);
+
+  File::Orientation orient;
+  if (mode > 0) {
+    orient = f->try_set_orientation(File::Orientation::WIDE);
+  } else if (mode < 0) {
+    orient = f->try_set_orientation(File::Orientation::BYTE);
+  } else {
+    orient = f->get_orientation();
+  }
+
+  if (orient == File::Orientation::WIDE)
+    return 1;
+  if (orient == File::Orientation::BYTE)
+    return -1;
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/fwide.h b/libc/src/wchar/fwide.h
new file mode 100644
index 0000000000000..bdb5a0534ca77
--- /dev/null
+++ b/libc/src/wchar/fwide.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fwide -----------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_FWIDE_H
+#define LLVM_LIBC_SRC_WCHAR_FWIDE_H
+
+#include "hdr/types/FILE.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int fwide(::FILE *stream, int mode);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_FWIDE_H
diff --git a/libc/test/src/wchar/fwide_test.cpp b/libc/test/src/wchar/fwide_test.cpp
new file mode 100644
index 0000000000000..6131310a13018
--- /dev/null
+++ b/libc/test/src/wchar/fwide_test.cpp
@@ -0,0 +1,54 @@
+//===-- Unittests for fwide -----------------------------------------------===//
+//
+// 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 "src/stdio/fclose.h"
+#include "src/stdio/fopen.h"
+#include "src/wchar/fwide.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcFwideTest, QueryInitial) {
+  auto FILENAME =
+      libc_make_test_file_path(APPEND_LIBC_TEST("fwide_query.test"));
+  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+
+  // Initial orientation should be unoriented (0)
+  EXPECT_EQ(LIBC_NAMESPACE::fwide(file, 0), 0);
+
+  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
+}
+
+TEST(LlvmLibcFwideTest, OrientWide) {
+  auto FILENAME = libc_make_test_file_path(APPEND_LIBC_TEST("fwide_wide.test"));
+  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+
+  // Setting mode > 0 should return > 0 (wide oriented)
+  EXPECT_GT(LIBC_NAMESPACE::fwide(file, 1), 0);
+
+  // Subsequent orientation queries/attempts should still return > 0
+  EXPECT_GT(LIBC_NAMESPACE::fwide(file, 0), 0);
+  EXPECT_GT(LIBC_NAMESPACE::fwide(file, -1), 0);
+
+  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
+}
+
+TEST(LlvmLibcFwideTest, OrientByte) {
+  auto FILENAME = libc_make_test_file_path(APPEND_LIBC_TEST("fwide_byte.test"));
+  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+
+  // Setting mode < 0 should return < 0 (byte oriented)
+  EXPECT_LT(LIBC_NAMESPACE::fwide(file, -1), 0);
+
+  // Subsequent orientation queries/attempts should still return < 0
+  EXPECT_LT(LIBC_NAMESPACE::fwide(file, 0), 0);
+  EXPECT_LT(LIBC_NAMESPACE::fwide(file, 1), 0);
+
+  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
+}

>From 8a9f5a568e6129128b5172e4af334402ed08ee0a Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Wed, 6 May 2026 20:04:51 +0000
Subject: [PATCH 2/2] format

---
 libc/src/wchar/fwide.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/wchar/fwide.cpp b/libc/src/wchar/fwide.cpp
index 6965b4ea1ef82..19af86e79de79 100644
--- a/libc/src/wchar/fwide.cpp
+++ b/libc/src/wchar/fwide.cpp
@@ -15,7 +15,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, fwide, (::FILE *stream, int mode)) {
+LLVM_LIBC_FUNCTION(int, fwide, (::FILE * stream, int mode)) {
   LIBC_CRASH_ON_NULLPTR(stream);
   auto *f = reinterpret_cast<File *>(stream);
 



More information about the libc-commits mailing list