[libc-commits] [libc] [libc] Add bindtextdomain and bind_textdomain_codeset stubs (PR #232711)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Fri Oct 16 05:12:24 PDT 2026
https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/232711
Added stateless stubs for bindtextdomain and bind_textdomain_codeset behind LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS. Both functions return nullptr without modifying errno when given a null or empty domain name, and return "/usr/share/locale" (for bindtextdomain) or nullptr (for bind_textdomain_codeset) when queried with a null setting argument.
Assisted-by: Automated tooling, human reviewed.
>From 50ac145d5b94f23104b3da4183a30121d1037258 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 15 Oct 2026 15:12:05 +0100
Subject: [PATCH] [libc] Add bindtextdomain and bind_textdomain_codeset stubs
Added stateless stubs for bindtextdomain and bind_textdomain_codeset
behind LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS. Both functions return
nullptr without modifying errno when given a null or empty domain name,
and return "/usr/share/locale" (for bindtextdomain) or nullptr (for
bind_textdomain_codeset) when queried with a null setting argument.
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 | 14 ++++++++
libc/src/libintl/CMakeLists.txt | 16 ++++++++++
libc/src/libintl/bind_textdomain_codeset.cpp | 30 +++++++++++++++++
libc/src/libintl/bind_textdomain_codeset.h | 25 +++++++++++++++
libc/src/libintl/bindtextdomain.cpp | 32 +++++++++++++++++++
libc/src/libintl/bindtextdomain.h | 25 +++++++++++++++
libc/test/src/libintl/CMakeLists.txt | 2 ++
libc/test/src/libintl/libintl_test.cpp | 28 ++++++++++++++++
16 files changed, 188 insertions(+)
create mode 100644 libc/src/libintl/bind_textdomain_codeset.cpp
create mode 100644 libc/src/libintl/bind_textdomain_codeset.h
create mode 100644 libc/src/libintl/bindtextdomain.cpp
create mode 100644 libc/src/libintl/bindtextdomain.h
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index a85fa19a92fcc..061b923d1ffbf 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -969,6 +969,8 @@ endif()
if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
libc.src.libintl.textdomain
# regex.h entrypoints
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 87fdcd0465230..7d1d061b1f2d7 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -1004,6 +1004,8 @@ endif()
if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
libc.src.libintl.textdomain
# regex.h entrypoints
diff --git a/libc/config/baremetal/hexagon/entrypoints.txt b/libc/config/baremetal/hexagon/entrypoints.txt
index cfee5f8240e60..3290e646c177f 100644
--- a/libc/config/baremetal/hexagon/entrypoints.txt
+++ b/libc/config/baremetal/hexagon/entrypoints.txt
@@ -985,6 +985,8 @@ endif()
if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
libc.src.libintl.textdomain
# regex.h entrypoints
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 19397087f3e92..de4602de33a5d 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -996,6 +996,8 @@ endif()
if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
libc.src.libintl.textdomain
# regex.h entrypoints
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b2c8d62a65f4e..761b4e1055705 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1497,6 +1497,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.glob.globfree
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
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 023d298170c24..8166470d222f5 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)
if(LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
libc.src.libintl.textdomain
# regex.h entrypoints
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 3bdc686c0e4ce..ce89db9476606 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1709,6 +1709,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.glob.globfree
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
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 23a588f65d743..88659ca320d31 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1735,6 +1735,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.glob.globfree
# libintl.h entrypoints
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
libc.src.libintl.textdomain
# net/if.h entrypoints
diff --git a/libc/include/libintl.yaml b/libc/include/libintl.yaml
index 7e429f3a6b7b2..3ef6e02eb77a7 100644
--- a/libc/include/libintl.yaml
+++ b/libc/include/libintl.yaml
@@ -7,6 +7,20 @@ types:
enums: []
objects: []
functions:
+ - name: bind_textdomain_codeset
+ standards:
+ - posix
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: bindtextdomain
+ standards:
+ - posix
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: const char *
- name: textdomain
standards:
- posix
diff --git a/libc/src/libintl/CMakeLists.txt b/libc/src/libintl/CMakeLists.txt
index 063f12227a4b7..9b506e2b99e0e 100644
--- a/libc/src/libintl/CMakeLists.txt
+++ b/libc/src/libintl/CMakeLists.txt
@@ -1,3 +1,19 @@
+add_entrypoint_object(
+ bind_textdomain_codeset
+ SRCS
+ bind_textdomain_codeset.cpp
+ HDRS
+ bind_textdomain_codeset.h
+)
+
+add_entrypoint_object(
+ bindtextdomain
+ SRCS
+ bindtextdomain.cpp
+ HDRS
+ bindtextdomain.h
+)
+
add_entrypoint_object(
textdomain
SRCS
diff --git a/libc/src/libintl/bind_textdomain_codeset.cpp b/libc/src/libintl/bind_textdomain_codeset.cpp
new file mode 100644
index 0000000000000..83b7b56c1dae5
--- /dev/null
+++ b/libc/src/libintl/bind_textdomain_codeset.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 bind_textdomain_codeset (stub).
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/libintl/bind_textdomain_codeset.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(char *, bind_textdomain_codeset,
+ (const char *domainname, const char *codeset)) {
+ // TODO: Implement message catalogs. For now, validate domainname and return
+ // the requested codeset (or nullptr when querying).
+ if (domainname == nullptr || domainname[0] == '\0' || codeset == nullptr)
+ return nullptr;
+ return const_cast<char *>(codeset);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/libintl/bind_textdomain_codeset.h b/libc/src/libintl/bind_textdomain_codeset.h
new file mode 100644
index 0000000000000..fa70742637185
--- /dev/null
+++ b/libc/src/libintl/bind_textdomain_codeset.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 bind_textdomain_codeset.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_LIBINTL_BIND_TEXTDOMAIN_CODESET_H
+#define LLVM_LIBC_SRC_LIBINTL_BIND_TEXTDOMAIN_CODESET_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *bind_textdomain_codeset(const char *domainname, const char *codeset);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_LIBINTL_BIND_TEXTDOMAIN_CODESET_H
diff --git a/libc/src/libintl/bindtextdomain.cpp b/libc/src/libintl/bindtextdomain.cpp
new file mode 100644
index 0000000000000..a6b6e0ce3fd50
--- /dev/null
+++ b/libc/src/libintl/bindtextdomain.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 bindtextdomain (stub).
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/libintl/bindtextdomain.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(char *, bindtextdomain,
+ (const char *domainname, const char *dirname)) {
+ // TODO: Implement message catalogs. For now, validate domainname and return
+ // the default locale directory when querying or dirname when setting.
+ if (domainname == nullptr || domainname[0] == '\0')
+ return nullptr;
+ if (dirname == nullptr)
+ return const_cast<char *>("/usr/share/locale");
+ return const_cast<char *>(dirname);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/libintl/bindtextdomain.h b/libc/src/libintl/bindtextdomain.h
new file mode 100644
index 0000000000000..dfa99bfe163e3
--- /dev/null
+++ b/libc/src/libintl/bindtextdomain.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 bindtextdomain.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_LIBINTL_BINDTEXTDOMAIN_H
+#define LLVM_LIBC_SRC_LIBINTL_BINDTEXTDOMAIN_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *bindtextdomain(const char *domainname, const char *dirname);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_LIBINTL_BINDTEXTDOMAIN_H
diff --git a/libc/test/src/libintl/CMakeLists.txt b/libc/test/src/libintl/CMakeLists.txt
index 955c5214b53eb..ecc2e0901c19d 100644
--- a/libc/test/src/libintl/CMakeLists.txt
+++ b/libc/test/src/libintl/CMakeLists.txt
@@ -8,6 +8,8 @@ if(LLVM_LIBC_FULL_BUILD AND LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
SRCS
libintl_test.cpp
DEPENDS
+ libc.src.libintl.bind_textdomain_codeset
+ libc.src.libintl.bindtextdomain
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 9f31d16b87bcb..2ce3ec41dbfab 100644
--- a/libc/test/src/libintl/libintl_test.cpp
+++ b/libc/test/src/libintl/libintl_test.cpp
@@ -11,6 +11,8 @@
///
//===----------------------------------------------------------------------===//
+#include "src/libintl/bind_textdomain_codeset.h"
+#include "src/libintl/bindtextdomain.h"
#include "src/libintl/textdomain.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
@@ -27,3 +29,29 @@ TEST_F(LlvmLibcLibintlTest, Textdomain) {
EXPECT_THAT(LIBC_NAMESPACE::textdomain(DOMAIN_NAME),
Succeeds(const_cast<char *>(DOMAIN_NAME)));
}
+
+TEST_F(LlvmLibcLibintlTest, Bindtextdomain) {
+ EXPECT_THAT(LIBC_NAMESPACE::bindtextdomain(nullptr, "/custom/dir"),
+ Succeeds<char *>(nullptr));
+ EXPECT_THAT(LIBC_NAMESPACE::bindtextdomain("", "/custom/dir"),
+ Succeeds<char *>(nullptr));
+ EXPECT_STREQ(LIBC_NAMESPACE::bindtextdomain("my_app", nullptr),
+ "/usr/share/locale");
+
+ constexpr const char *DIR_NAME = "/custom/dir";
+ EXPECT_THAT(LIBC_NAMESPACE::bindtextdomain("my_app", DIR_NAME),
+ Succeeds(const_cast<char *>(DIR_NAME)));
+}
+
+TEST_F(LlvmLibcLibintlTest, BindTextdomainCodeset) {
+ EXPECT_THAT(LIBC_NAMESPACE::bind_textdomain_codeset(nullptr, "UTF-8"),
+ Succeeds<char *>(nullptr));
+ EXPECT_THAT(LIBC_NAMESPACE::bind_textdomain_codeset("", "UTF-8"),
+ Succeeds<char *>(nullptr));
+ EXPECT_THAT(LIBC_NAMESPACE::bind_textdomain_codeset("my_app", nullptr),
+ Succeeds<char *>(nullptr));
+
+ constexpr const char *CODESET = "UTF-8";
+ EXPECT_THAT(LIBC_NAMESPACE::bind_textdomain_codeset("my_app", CODESET),
+ Succeeds(const_cast<char *>(CODESET)));
+}
More information about the libc-commits
mailing list