[libc-commits] [libc] [libc] Add gettext and gettext_l stubs (PR #233603)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Mon Oct 19 14:59:40 PDT 2026


https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/233603

Added stateless stubs for gettext and gettext_l behind LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS.  In the "C" locale, POSIX requires the gettext family to return the input msgid pointer unchanged without modifying errno.

Assisted-by: Automated tooling, human reviewed.

>From 086d16e86e766ef409458c31c108dfd9a26a3094 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 15 Oct 2026 15:12:07 +0100
Subject: [PATCH] [libc] Add gettext and gettext_l stubs

Added stateless stubs for gettext and gettext_l behind
LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS.  In the "C" locale, POSIX
requires the gettext family to return the input msgid pointer unchanged
without modifying errno.

Assisted-by: Automated tooling, human reviewed.
---
 libc/config/baremetal/aarch64/entrypoints.txt |  2 ++
 libc/config/baremetal/arm/entrypoints.txt     |  2 ++
 libc/config/baremetal/hexagon/entrypoints.txt |  2 ++
 libc/config/baremetal/riscv/entrypoints.txt   |  2 ++
 libc/config/linux/aarch64/entrypoints.txt     |  2 ++
 libc/config/linux/arm/entrypoints.txt         |  2 ++
 libc/config/linux/riscv/entrypoints.txt       |  2 ++
 libc/config/linux/x86_64/entrypoints.txt      |  2 ++
 libc/include/libintl.yaml                     | 13 +++++++++
 libc/src/libintl/CMakeLists.txt               | 18 ++++++++++++
 libc/src/libintl/gettext.cpp                  | 26 +++++++++++++++++
 libc/src/libintl/gettext.h                    | 25 +++++++++++++++++
 libc/src/libintl/gettext_l.cpp                | 28 +++++++++++++++++++
 libc/src/libintl/gettext_l.h                  | 26 +++++++++++++++++
 libc/test/src/libintl/CMakeLists.txt          |  3 ++
 libc/test/src/libintl/libintl_test.cpp        | 12 ++++++++
 16 files changed, 167 insertions(+)
 create mode 100644 libc/src/libintl/gettext.cpp
 create mode 100644 libc/src/libintl/gettext.h
 create mode 100644 libc/src/libintl/gettext_l.cpp
 create mode 100644 libc/src/libintl/gettext_l.h

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 061b923d1ffbf3..9a1b060d801075 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -971,6 +971,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
     # libintl.h entrypoints
     libc.src.libintl.bind_textdomain_codeset
     libc.src.libintl.bindtextdomain
+    libc.src.libintl.gettext
+    libc.src.libintl.gettext_l
     libc.src.libintl.textdomain
 
     # regex.h entrypoints
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 7d1d061b1f2d79..358b8bb14d5d63 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -1006,6 +1006,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
     # libintl.h entrypoints
     libc.src.libintl.bind_textdomain_codeset
     libc.src.libintl.bindtextdomain
+    libc.src.libintl.gettext
+    libc.src.libintl.gettext_l
     libc.src.libintl.textdomain
 
     # regex.h entrypoints
diff --git a/libc/config/baremetal/hexagon/entrypoints.txt b/libc/config/baremetal/hexagon/entrypoints.txt
index 3290e646c177f9..3ea1f49a08f0a6 100644
--- a/libc/config/baremetal/hexagon/entrypoints.txt
+++ b/libc/config/baremetal/hexagon/entrypoints.txt
@@ -987,6 +987,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
     # libintl.h entrypoints
     libc.src.libintl.bind_textdomain_codeset
     libc.src.libintl.bindtextdomain
+    libc.src.libintl.gettext
+    libc.src.libintl.gettext_l
     libc.src.libintl.textdomain
 
     # regex.h entrypoints
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index de4602de33a5d9..c9d54b255ce1e8 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -998,6 +998,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
     # libintl.h entrypoints
     libc.src.libintl.bind_textdomain_codeset
     libc.src.libintl.bindtextdomain
+    libc.src.libintl.gettext
+    libc.src.libintl.gettext_l
     libc.src.libintl.textdomain
 
     # regex.h entrypoints
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f19427f507b037..8c20907ee11fd8 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1498,6 +1498,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
       # libintl.h entrypoints
       libc.src.libintl.bind_textdomain_codeset
       libc.src.libintl.bindtextdomain
+      libc.src.libintl.gettext
+      libc.src.libintl.gettext_l
       libc.src.libintl.textdomain
 
       # net/if.h entrypoints
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index c3cf0fb5cc97ff..4796a06545d12a 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -725,6 +725,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
       # libintl.h entrypoints
       libc.src.libintl.bind_textdomain_codeset
       libc.src.libintl.bindtextdomain
+      libc.src.libintl.gettext
+      libc.src.libintl.gettext_l
       libc.src.libintl.textdomain
 
       # regex.h entrypoints
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index f9156b9fd6e4ad..8c87c1e5471fed 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1710,6 +1710,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
       # libintl.h entrypoints
       libc.src.libintl.bind_textdomain_codeset
       libc.src.libintl.bindtextdomain
+      libc.src.libintl.gettext
+      libc.src.libintl.gettext_l
       libc.src.libintl.textdomain
 
       # net/if.h entrypoints
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 7125b2248a8752..2bc0209210a56b 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1736,6 +1736,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
       # libintl.h entrypoints
       libc.src.libintl.bind_textdomain_codeset
       libc.src.libintl.bindtextdomain
+      libc.src.libintl.gettext
+      libc.src.libintl.gettext_l
       libc.src.libintl.textdomain
 
       # net/if.h entrypoints
diff --git a/libc/include/libintl.yaml b/libc/include/libintl.yaml
index 3ef6e02eb77a7c..ee8b4eaf64c947 100644
--- a/libc/include/libintl.yaml
+++ b/libc/include/libintl.yaml
@@ -21,6 +21,19 @@ functions:
     arguments:
       - type: const char *
       - type: const char *
+  - name: gettext
+    standards:
+      - posix
+    return_type: char *
+    arguments:
+      - type: const char *
+  - name: gettext_l
+    standards:
+      - posix
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: locale_t
   - name: textdomain
     standards:
       - posix
diff --git a/libc/src/libintl/CMakeLists.txt b/libc/src/libintl/CMakeLists.txt
index 9b506e2b99e0e5..99ab7f25c6da24 100644
--- a/libc/src/libintl/CMakeLists.txt
+++ b/libc/src/libintl/CMakeLists.txt
@@ -14,6 +14,24 @@ add_entrypoint_object(
     bindtextdomain.h
 )
 
+add_entrypoint_object(
+  gettext
+  SRCS
+    gettext.cpp
+  HDRS
+    gettext.h
+)
+
+add_entrypoint_object(
+  gettext_l
+  SRCS
+    gettext_l.cpp
+  HDRS
+    gettext_l.h
+  DEPENDS
+    libc.hdr.types.locale_t
+)
+
 add_entrypoint_object(
   textdomain
   SRCS
diff --git a/libc/src/libintl/gettext.cpp b/libc/src/libintl/gettext.cpp
new file mode 100644
index 00000000000000..72b669cd56a9ed
--- /dev/null
+++ b/libc/src/libintl/gettext.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of gettext (stub).
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/libintl/gettext.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(char *, gettext, (const char *msgid)) {
+  // TODO: Implement message catalogs. For now, return msgid unchanged.
+  return const_cast<char *>(msgid);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/libintl/gettext.h b/libc/src/libintl/gettext.h
new file mode 100644
index 00000000000000..c981e5d4464f95
--- /dev/null
+++ b/libc/src/libintl/gettext.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for gettext.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_LIBINTL_GETTEXT_H
+#define LLVM_LIBC_SRC_LIBINTL_GETTEXT_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *gettext(const char *msgid);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_LIBINTL_GETTEXT_H
diff --git a/libc/src/libintl/gettext_l.cpp b/libc/src/libintl/gettext_l.cpp
new file mode 100644
index 00000000000000..8e45fe78cd931d
--- /dev/null
+++ b/libc/src/libintl/gettext_l.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of gettext_l (stub).
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/libintl/gettext_l.h"
+
+#include "hdr/types/locale_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(char *, gettext_l,
+                   (const char *msgid, [[maybe_unused]] locale_t locale)) {
+  // TODO: Implement message catalogs. For now, return msgid unchanged.
+  return const_cast<char *>(msgid);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/libintl/gettext_l.h b/libc/src/libintl/gettext_l.h
new file mode 100644
index 00000000000000..e8477d39485a08
--- /dev/null
+++ b/libc/src/libintl/gettext_l.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for gettext_l.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_LIBINTL_GETTEXT_L_H
+#define LLVM_LIBC_SRC_LIBINTL_GETTEXT_L_H
+
+#include "hdr/types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *gettext_l(const char *msgid, locale_t locale);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_LIBINTL_GETTEXT_L_H
diff --git a/libc/test/src/libintl/CMakeLists.txt b/libc/test/src/libintl/CMakeLists.txt
index ecc2e0901c19dc..08a412e9640d2d 100644
--- a/libc/test/src/libintl/CMakeLists.txt
+++ b/libc/test/src/libintl/CMakeLists.txt
@@ -8,8 +8,11 @@ if(LLVM_LIBC_FULL_BUILD AND LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
     SRCS
       libintl_test.cpp
     DEPENDS
+      libc.hdr.types.locale_t
       libc.src.libintl.bind_textdomain_codeset
       libc.src.libintl.bindtextdomain
+      libc.src.libintl.gettext
+      libc.src.libintl.gettext_l
       libc.src.libintl.textdomain
       libc.test.UnitTest.ErrnoCheckingTest
       libc.test.UnitTest.ErrnoSetterMatcher
diff --git a/libc/test/src/libintl/libintl_test.cpp b/libc/test/src/libintl/libintl_test.cpp
index 2ce3ec41dbfab5..07249d840892bd 100644
--- a/libc/test/src/libintl/libintl_test.cpp
+++ b/libc/test/src/libintl/libintl_test.cpp
@@ -11,8 +11,11 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "hdr/types/locale_t.h"
 #include "src/libintl/bind_textdomain_codeset.h"
 #include "src/libintl/bindtextdomain.h"
+#include "src/libintl/gettext.h"
+#include "src/libintl/gettext_l.h"
 #include "src/libintl/textdomain.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
@@ -55,3 +58,12 @@ TEST_F(LlvmLibcLibintlTest, BindTextdomainCodeset) {
   EXPECT_THAT(LIBC_NAMESPACE::bind_textdomain_codeset("my_app", CODESET),
               Succeeds(const_cast<char *>(CODESET)));
 }
+
+TEST_F(LlvmLibcLibintlTest, Gettext) {
+  constexpr const char *MSG = "hello world";
+  locale_t loc = nullptr;
+
+  EXPECT_THAT(LIBC_NAMESPACE::gettext(MSG), Succeeds(const_cast<char *>(MSG)));
+  EXPECT_THAT(LIBC_NAMESPACE::gettext_l(MSG, loc),
+              Succeeds(const_cast<char *>(MSG)));
+}



More information about the libc-commits mailing list