]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
D support: Add the runtime library.
authorBruno Haible <bruno@clisp.org>
Tue, 1 Apr 2025 00:18:40 +0000 (02:18 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 1 Apr 2025 00:38:25 +0000 (02:38 +0200)
* gnulib-local/m4/d.m4: New file.
* gnulib-local/modules/d: New file.
* gnulib-local/Makefile.am (EXTRA_DIST): Add d.m4 and the 'd' module.
* autogen.sh (GNULIB_MODULES_RUNTIME_OTHER): Add d, dcomp-script.
* gettext-runtime/intl-d/Makefile.am: New file.
* gettext-runtime/intl-d/gnu/libintl/package.d: New file.
* gettext-runtime/intl-d/gnu/libintl/libintl.d: New file.
* gettext-runtime/intl-d/gnu/libintl/internal/low.d: New file.
* gettext-runtime/configure.ac: Invoke gt_D_CHOICE, gt_DCOMP. Set the variable
BUILDD and the Automake conditional BUILD_D.
* gettext-runtime/Makefile.am (SUBDIRS): Add intl-d.
* NEWS: Mention libintl_d.a.
* gettext-runtime/NEWS: Likewise.
* PACKAGING: Add the sources and binary for the libintl_d library.
* DEPENDENCIES: Mention the D compiler and runtime.

15 files changed:
.gitignore
DEPENDENCIES
NEWS
PACKAGING
autogen.sh
gettext-runtime/Makefile.am
gettext-runtime/NEWS
gettext-runtime/configure.ac
gettext-runtime/intl-d/Makefile.am [new file with mode: 0644]
gettext-runtime/intl-d/gnu/libintl/internal/low.d [new file with mode: 0644]
gettext-runtime/intl-d/gnu/libintl/libintl.d [new file with mode: 0644]
gettext-runtime/intl-d/gnu/libintl/package.d [new file with mode: 0644]
gnulib-local/Makefile.am
gnulib-local/m4/d.m4 [new file with mode: 0644]
gnulib-local/modules/d [new file with mode: 0644]

index 728d7d6bd732ca1854769380a613a83c4643411d..f509eea6f5144169a3eedfe9eba8bf90547f03af 100644 (file)
@@ -29,6 +29,7 @@
 /build-aux/config.rpath
 /build-aux/csharpcomp.sh.in
 /build-aux/csharpexec.sh.in
+/build-aux/dcomp.sh.in
 /build-aux/git-version-gen
 /build-aux/gitlog-to-changelog
 /build-aux/gocomp.sh.in
 /gettext-runtime/intl/Makefile.in
 /gettext-runtime/intl-csharp/Makefile.in
 /gettext-runtime/intl-java/Makefile.in
+/gettext-runtime/intl-d/Makefile.in
 /gettext-runtime/libasprintf/aclocal.m4
 /gettext-runtime/libasprintf/configure
 /gettext-runtime/libasprintf/config.h.in
@@ -623,6 +625,7 @@ autom4te.cache/
 /gettext-runtime/Makefile
 /gettext-runtime/config.h
 /gettext-runtime/csharpcomp.sh
+/gettext-runtime/dcomp.sh
 /gettext-runtime/javacomp.sh
 /gettext-runtime/libtool
 /gettext-runtime/stamp-h1
@@ -634,6 +637,7 @@ autom4te.cache/
 /gettext-runtime/intl/stamp-h1
 /gettext-runtime/intl-csharp/Makefile
 /gettext-runtime/intl-java/Makefile
+/gettext-runtime/intl-d/Makefile
 /gettext-runtime/libasprintf/Makefile
 /gettext-runtime/libasprintf/config.h
 /gettext-runtime/libasprintf/libtool
@@ -711,6 +715,7 @@ autom4te.cache/
 /gettext-runtime/intl-csharp/GNU.Gettext.pdb
 /gettext-runtime/intl-java/**/*.class
 /gettext-runtime/intl-java/libintl.jar
+/gettext-runtime/intl-d/libintl_d.a
 /gettext-runtime/libasprintf/libasprintf.la
 /gettext-runtime/man/gettext.1
 /gettext-runtime/man/gettext.1.html
index 45e63169cf1bfb9cf445325fa647860095bcf834..e0382ab4388e7f706308637de08c3883e788a6a7 100644 (file)
@@ -121,6 +121,38 @@ The following packages should be installed before GNU gettext is installed
   + If more than one C# is installed, pass the option --enable-csharp=IMPL
     to 'configure', to disambiguate.
 
+* A D compiler and runtime (e.g. gdc, ldc2, or dmd).
+  + Recommended.
+    Needed for building libintl_d.a.
+  o gdc:
+    + Homepage:
+      https://wiki.dlang.org/GDC
+      https://gcc.gnu.org/
+    + Pre-built package name:
+      - On Debian and Debian-based systems: gdc,
+      - On Red Hat distributions: gcc-gdc.
+      - Other: --
+  o ldc2:
+    + Homepage:
+      https://wiki.dlang.org/LDC
+    + Download:
+      https://github.com/ldc-developers/ldc/tags
+    + Pre-built package name:
+      - On Debian and Debian-based systems: ldc,
+      - On Red Hat distributions: ldc.
+      - Other: https://repology.org/project/ldc/versions
+  o dmd:
+    + Homepage:
+      https://wiki.dlang.org/DMD
+    + Download:
+      https://dlang.org/download.html
+    + Pre-built package name:
+      - On Debian and Debian-based systems: --,
+      - On Red Hat distributions: --.
+      - Other: https://repology.org/project/dmd/versions
+  + If more than one D compiler is installed, set the environment variable
+    DC, to disambiguate.
+
 * git 1.6 or newer
   + Recommended.
     Needed by the 'autopoint' program, if not configured with --without-git
diff --git a/NEWS b/NEWS
index 8e55d85e94890520d0119918fca4da981c0c7d8d..8464209280d605429892d62628e3f49c9cda37d4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Version 0.25 - March 2025
+Version 0.25 - April 2025
 
 # Programming languages support:
   * Go:
@@ -9,6 +9,9 @@ Version 0.25 - March 2025
   * TypeScript:
     - xgettext now supports TypeScript and TSX (= TypeScript with JSX
       extensions).
+  * D:
+    - A new library libintl_d.a contains the runtime for using GNU gettext
+      message catalogs in the D programming language.
 
 Version 0.24 - February 2025
 
index 8a8666ed6b7bcf2733bf318a6de7bee5b79a88e5..b336015028ee41d5ac74e2d6b627a5283e4d132b 100644 (file)
--- a/PACKAGING
+++ b/PACKAGING
@@ -85,6 +85,11 @@ is according to the following file list.
       $prefix/lib/gettext/GNU.Gettext.dll
       $prefix/share/doc/gettext/csharpdoc/*
 
+      $prefix/lib/libintl_d.a
+      $prefix/include/d/gnu/libintl/package.d
+      $prefix/include/d/gnu/libintl/libintl.d
+      $prefix/include/d/gnu/libintl/internal/low.d
+
       $prefix/lib/libasprintf.*
       $prefix/include/autosprintf.h
       $prefix/share/doc/libasprintf/autosprintf*.html
index d670dad0caf29ad91a5d8b34017ba13927968e7b..3a3c3a1f012ae2c90c1683bd3ad3ede009599089 100755 (executable)
@@ -123,6 +123,8 @@ if ! $skip_gnulib; then
     gettext-runtime-misc
     ansi-c++-opt
     csharpcomp-script
+    d
+    dcomp-script
     java
     javacomp-script
     manywarnings
index 24925e95c191ab0f2bd4cebd0076e34304a95901..057df11455d8fa1e353439a2b2a8b4f41d227daa 100644 (file)
@@ -1,5 +1,5 @@
 ## Makefile for the gettext-runtime directory of GNU gettext
-## Copyright (C) 1995-2024 Free Software Foundation, Inc.
+## Copyright (C) 1995-2025 Free Software Foundation, Inc.
 ##
 ## This program is free software: you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ SUBDIR_libasprintf = libasprintf
 else
 SUBDIR_libasprintf =
 endif
-SUBDIRS = doc intl intl-java intl-csharp gnulib-lib $(SUBDIR_libasprintf) src po man m4 tests
+SUBDIRS = doc intl intl-java intl-csharp intl-d gnulib-lib $(SUBDIR_libasprintf) src po man m4 tests
 
 EXTRA_DIST = BUGS
 
index 7457f5d01584a17222c31547bcd2b7285cc4adc5..dfd2b6936df1411a8bbf37ba6d2586c45e4983b3 100644 (file)
@@ -1,3 +1,8 @@
+Version 0.25 - April 2025
+
+* New library: libintl_d.a contains the runtime for using GNU gettext
+  message catalogs in the D programming language.
+
 Version 0.23 - December 2023
 
 * In the C.UTF-8 locale, like in the C locale, the *gettext() functions
index 2de5cc9809d39b7b42e47ac5be54efa3290546fc..9bbf6250454924cb40a7e62d0e35b7db8bb26724 100644 (file)
@@ -60,6 +60,21 @@ else
 fi
 AC_SUBST([BUILDCSHARP])
 
+gt_D_CHOICE
+gt_DCOMP
+if test "$D_CHOICE" != no; then
+  AC_CHECK_TOOL([DC], [gdc ldc2 dmd])
+  if test -n "$DC"; then
+    BUILDD=yes
+  else
+    BUILDD=no
+  fi
+else
+  BUILDD=no
+fi
+AC_SUBST([BUILDD])
+AM_CONDITIONAL([BUILD_D], [test $BUILDD = yes])
+
 dnl Check for host type.
 AC_CANONICAL_HOST
 
@@ -211,6 +226,8 @@ AC_CONFIG_FILES([intl-java/Makefile])
 
 AC_CONFIG_FILES([intl-csharp/Makefile])
 
+AC_CONFIG_FILES([intl-d/Makefile])
+
 AC_CONFIG_FILES([gnulib-lib/Makefile])
 
 AC_CONFIG_FILES([src/Makefile])
diff --git a/gettext-runtime/intl-d/Makefile.am b/gettext-runtime/intl-d/Makefile.am
new file mode 100644 (file)
index 0000000..e721400
--- /dev/null
@@ -0,0 +1,66 @@
+## Makefile for the gettext-runtime/intl-d subdirectory of GNU gettext
+## Copyright (C) 2025 Free Software Foundation, Inc.
+##
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.10 gnu
+
+RM = rm -f
+
+dincludedir = $(includedir)/d
+
+if BUILD_D
+lib_LIBRARIES = libintl_d.a
+endif
+libintl_d_a_SOURCES = \
+  gnu/libintl/package.d \
+  gnu/libintl/libintl.d \
+  gnu/libintl/internal/low.d
+if BUILD_D
+libintl_d_a_LIBADD = package.o libintl.o low.o
+libintl_d_a_DEPENDENCIES = package.o libintl.o low.o
+
+# Rules for compiling a .d file, that work even without a VPATH variable.
+package.o: $(srcdir)/gnu/libintl/package.d
+       $(SHELL) ../dcomp.sh -I$(srcdir) -c $(srcdir)/gnu/libintl/package.d
+libintl.o: $(srcdir)/gnu/libintl/libintl.d
+       $(SHELL) ../dcomp.sh -I$(srcdir) -c $(srcdir)/gnu/libintl/libintl.d
+low.o: $(srcdir)/gnu/libintl/internal/low.d
+       $(SHELL) ../dcomp.sh -I$(srcdir) -c $(srcdir)/gnu/libintl/internal/low.d
+
+install-data-local: install-d-sources
+installdirs-local: installdirs-d-sources
+uninstall-local: uninstall-d-sources
+
+install-d-sources:
+       $(MKDIR_P) $(DESTDIR)$(dincludedir)
+       $(MKDIR_P) $(DESTDIR)$(dincludedir)/gnu/libintl/internal
+       @for f in $(libintl_d_a_SOURCES); do \
+         echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(dincludedir)/$$f"; \
+         $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(dincludedir)/$$f; \
+       done
+
+installdirs-d-sources:
+       $(MKDIR_P) $(DESTDIR)$(dincludedir)
+       $(MKDIR_P) $(DESTDIR)$(dincludedir)/gnu/libintl/internal
+
+uninstall-d-sources:
+       @for f in $(libintl_d_a_SOURCES); do \
+         echo "$(RM) $(DESTDIR)$(dincludedir)/$$f"; \
+         $(RM) $(DESTDIR)$(dincludedir)/$$f; \
+       done
+
+endif
diff --git a/gettext-runtime/intl-d/gnu/libintl/internal/low.d b/gettext-runtime/intl-d/gnu/libintl/internal/low.d
new file mode 100644 (file)
index 0000000..e93e0cd
--- /dev/null
@@ -0,0 +1,96 @@
+/+ D bindings to the GNU gettext runtime library.
+   Copyright © 2025 Free Software Foundation, Inc.
+
+   Boost Software License - Version 1.0 - August 17th, 2003
+
+   Permission is hereby granted, free of charge, to any person or organization
+   obtaining a copy of the software and accompanying documentation covered by
+   this license (the "Software") to use, reproduce, display, distribute,
+   execute, and transmit the Software, and to prepare derivative works of the
+   Software, and to permit third-parties to whom the Software is furnished to
+   do so, all subject to the following:
+
+   The copyright notices in the Software and this entire statement, including
+   the above license grant, this restriction and the following disclaimer,
+   must be included in all copies of the Software, in whole or in part, and
+   all derivative works of the Software, unless such copies or derivative
+   works are solely in the form of machine-executable object code generated by
+   a source language processor.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+   SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+   FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+ +/
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2025.  */
+
+module gnu.libintl.internal.low;
+
+/* <libintl.h> API  */
+
+// On some platforms (glibc, musl libc, NetBSD), the symbols have no prefix at
+// the linker level. On other platforms, the symbols exist both prefixed with
+// 'libintl_' at the linker level and without prefix (see intl-compat.c).
+// We can therefore use the symbols without prefix unconditionally.
+  private extern (C) const(char) * gettext (const(char) *msgid);
+  private extern (C) const(char) * dgettext (const(char) *domainname, const(char) *msgid);
+  private extern (C) const(char) * dcgettext (const(char) *domainname, const(char) *msgid, int category);
+  private extern (C) const(char) * ngettext (const(char) *msgid, const(char) *msgid_plural, ulong n);
+  private extern (C) const(char) * dngettext (const(char) *domainname, const(char) *msgid, const(char) *msgid_plural, ulong n);
+  private extern (C) const(char) * dcngettext (const(char) *domainname, const(char) *msgid, const(char) *msgid_plural, ulong n, int category);
+  private extern (C) const(char) * textdomain (const(char) *domainname);
+  private extern (C) const(char) * bindtextdomain (const(char) *domainname, const(char) *dirname);
+  private extern (C) const(char) * bind_textdomain_codeset (const(char) *domainname, const(char) *codeset);
+  alias unsafe_gettext                 = gettext;
+  alias unsafe_dgettext                = dgettext;
+  alias unsafe_dcgettext               = dcgettext;
+  alias unsafe_ngettext                = ngettext;
+  alias unsafe_dngettext               = dngettext;
+  alias unsafe_dcngettext              = dcngettext;
+  alias unsafe_textdomain              = textdomain;
+  alias unsafe_bindtextdomain          = bindtextdomain;
+  alias unsafe_bind_textdomain_codeset = bind_textdomain_codeset;
+/+
+  // The symbols are prefixed with 'libintl_' at the linker level.
+  private extern (C) const(char) * libintl_gettext (const(char) *msgid);
+  private extern (C) const(char) * libintl_dgettext (const(char) *domainname, const(char) *msgid);
+  private extern (C) const(char) * libintl_dcgettext (const(char) *domainname, const(char) *msgid, int category);
+  private extern (C) const(char) * libintl_ngettext (const(char) *msgid, const(char) *msgid_plural, ulong n);
+  private extern (C) const(char) * libintl_dngettext (const(char) *domainname, const(char) *msgid, const(char) *msgid_plural, ulong n);
+  private extern (C) const(char) * libintl_dcngettext (const(char) *domainname, const(char) *msgid, const(char) *msgid_plural, ulong n, int category);
+  private extern (C) const(char) * libintl_textdomain (const(char) *domainname);
+  private extern (C) const(char) * libintl_bindtextdomain (const(char) *domainname, const(char) *dirname);
+  private extern (C) const(char) * libintl_bind_textdomain_codeset (const(char) *domainname, const(char) *codeset);
+  alias unsafe_gettext                 = libintl_gettext;
+  alias unsafe_dgettext                = libintl_dgettext;
+  alias unsafe_dcgettext               = libintl_dcgettext;
+  alias unsafe_ngettext                = libintl_ngettext;
+  alias unsafe_dngettext               = libintl_dngettext;
+  alias unsafe_dcngettext              = libintl_dcngettext;
+  alias unsafe_textdomain              = libintl_textdomain;
+  alias unsafe_bindtextdomain          = libintl_bindtextdomain;
+  alias unsafe_bind_textdomain_codeset = libintl_bind_textdomain_codeset;
++/
+
+/* <locale.h> / <libintl.h> API  */
+
+version (OSX)
+  version = OverriddenSetlocale;
+else version (Windows)
+  version = OverriddenSetlocale;
+else version (Cygwin)
+  version = OverriddenSetlocale;
+
+version (OverriddenSetlocale) {
+  /* Support for the locale chosen by the user.  */
+  private extern (C) char * libintl_setlocale (int category, const(char) * locale);
+  alias unsafe_setlocale = libintl_setlocale;
+} else {
+  /* <https://dlang.org/library/core/stdc/locale/setlocale.html>.  */
+  import core.stdc.locale : setlocale;
+  alias unsafe_setlocale = setlocale;
+}
diff --git a/gettext-runtime/intl-d/gnu/libintl/libintl.d b/gettext-runtime/intl-d/gnu/libintl/libintl.d
new file mode 100644 (file)
index 0000000..f073d84
--- /dev/null
@@ -0,0 +1,157 @@
+/+ D bindings to the GNU gettext runtime library.
+   Copyright © 2025 Free Software Foundation, Inc.
+
+   Boost Software License - Version 1.0 - August 17th, 2003
+
+   Permission is hereby granted, free of charge, to any person or organization
+   obtaining a copy of the software and accompanying documentation covered by
+   this license (the "Software") to use, reproduce, display, distribute,
+   execute, and transmit the Software, and to prepare derivative works of the
+   Software, and to permit third-parties to whom the Software is furnished to
+   do so, all subject to the following:
+
+   The copyright notices in the Software and this entire statement, including
+   the above license grant, this restriction and the following disclaimer,
+   must be included in all copies of the Software, in whole or in part, and
+   all derivative works of the Software, unless such copies or derivative
+   works are solely in the form of machine-executable object code generated by
+   a source language processor.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+   SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+   FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+ +/
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2025.  */
+
+module gnu.libintl.libintl;
+
+import gnu.libintl.internal.low;
+
+import std.conv;
+import std.string;
+
+/* Argument conversion: While string *literals* in D are NUL-terminated, strings
+   in general are not. Therefore we need to call toStringz, to ensure the C
+   function receives a NUL-terminated 'const char *'.  */
+/* Result conversion: When a 'const char *' is passed to a function such as
+   writeln(), it prints it like a pointer. But we want to print it as a string.
+   We therefore need to convert the result to 'string'.
+   For this purpose, to!string works, whereas fromStringz does not.  */
+
+public string gettext (string msgid)
+{
+  return to!string(unsafe_gettext(toStringz(msgid)));
+}
+
+public string dgettext (string domainname, string msgid)
+{
+  return to!string(unsafe_dgettext(toStringz(domainname), toStringz(msgid)));
+}
+
+public string dcgettext (string domainname, string msgid, int category)
+{
+  return to!string(unsafe_dcgettext(toStringz(domainname), toStringz(msgid), category));
+}
+
+public string ngettext (string msgid, string msgid_plural, ulong n)
+{
+  return to!string(unsafe_ngettext(toStringz(msgid), toStringz(msgid_plural), n));
+}
+
+public string dngettext (string domainname, string msgid, string msgid_plural, ulong n)
+{
+  return to!string(unsafe_dngettext(toStringz(domainname), toStringz(msgid), toStringz(msgid_plural), n));
+}
+
+public string dcngettext (string domainname, string msgid, string msgid_plural, ulong n, int category)
+{
+  return to!string(unsafe_dcngettext(toStringz(domainname), toStringz(msgid), toStringz(msgid_plural), n, category));
+}
+
+public string pgettext (string msgctxt, string msgid)
+{
+  const(char) * msg_ctxt_id = toStringz(msgctxt ~ "\x04" ~ msgid);
+  const(char) * translation = unsafe_gettext (msg_ctxt_id);
+  if (translation == msg_ctxt_id)
+    return msgid;
+  else
+    return to!string(translation);
+}
+
+public string dpgettext (string domainname, string msgctxt, string msgid)
+{
+  const(char) * msg_ctxt_id = toStringz(msgctxt ~ "\x04" ~ msgid);
+  const(char) * translation = unsafe_dgettext (toStringz(domainname), msg_ctxt_id);
+  if (translation == msg_ctxt_id)
+    return msgid;
+  else
+    return to!string(translation);
+}
+
+public string dcpgettext (string domainname, string msgctxt, string msgid, int category)
+{
+  const(char) * msg_ctxt_id = toStringz(msgctxt ~ "\x04" ~ msgid);
+  const(char) * translation = unsafe_dcgettext (toStringz(domainname), msg_ctxt_id, category);
+  if (translation == msg_ctxt_id)
+    return msgid;
+  else
+    return to!string(translation);
+}
+
+public string npgettext (string msgctxt, string msgid, string msgid_plural, ulong n)
+{
+  const(char) * msg_ctxt_id = toStringz(msgctxt ~ "\x04" ~ msgid);
+  const(char) * translation = unsafe_ngettext (msg_ctxt_id, toStringz(msgid_plural), n);
+  if (translation == msg_ctxt_id)
+    return (n == 1 ? msgid : msgid_plural);
+  else
+    return to!string(translation);
+}
+
+public string dnpgettext (string domainname, string msgctxt, string msgid, string msgid_plural, ulong n)
+{
+  const(char) * msg_ctxt_id = toStringz(msgctxt ~ "\x04" ~ msgid);
+  const(char) * translation = unsafe_dngettext (toStringz(domainname), msg_ctxt_id, toStringz(msgid_plural), n);
+  if (translation == msg_ctxt_id)
+    return (n == 1 ? msgid : msgid_plural);
+  else
+    return to!string(translation);
+}
+
+public string dcnpgettext (string domainname, string msgctxt, string msgid, string msgid_plural, ulong n, int category)
+{
+  const(char) * msg_ctxt_id = toStringz(msgctxt ~ "\x04" ~ msgid);
+  const(char) * translation = unsafe_dcngettext (toStringz(domainname), msg_ctxt_id, toStringz(msgid_plural), n, category);
+  if (translation == msg_ctxt_id)
+    return (n == 1 ? msgid : msgid_plural);
+  else
+    return to!string(translation);
+}
+
+public string textdomain (string domainname)
+{
+  return to!string(unsafe_textdomain(toStringz(domainname)));
+}
+
+public string bindtextdomain (string domainname, string dirname)
+{
+  // D uses UTF-8 for its string representation.
+  unsafe_bindtextdomain(toStringz(domainname), "UTF-8");
+  return to!string(unsafe_bindtextdomain(toStringz(domainname), toStringz(dirname)));
+}
+
+public const(char) * setlocale (int category, const(char) * locale)
+{
+  return unsafe_setlocale (category, locale);
+}
+
+unittest
+{
+  import std.stdio;
+  writeln(gettext("Hello world!"));
+}
diff --git a/gettext-runtime/intl-d/gnu/libintl/package.d b/gettext-runtime/intl-d/gnu/libintl/package.d
new file mode 100644 (file)
index 0000000..57fcf5e
--- /dev/null
@@ -0,0 +1,33 @@
+/+ D bindings to the GNU gettext runtime library.
+   Copyright © 2025 Free Software Foundation, Inc.
+
+   Boost Software License - Version 1.0 - August 17th, 2003
+
+   Permission is hereby granted, free of charge, to any person or organization
+   obtaining a copy of the software and accompanying documentation covered by
+   this license (the "Software") to use, reproduce, display, distribute,
+   execute, and transmit the Software, and to prepare derivative works of the
+   Software, and to permit third-parties to whom the Software is furnished to
+   do so, all subject to the following:
+
+   The copyright notices in the Software and this entire statement, including
+   the above license grant, this restriction and the following disclaimer,
+   must be included in all copies of the Software, in whole or in part, and
+   all derivative works of the Software, unless such copies or derivative
+   works are solely in the form of machine-executable object code generated by
+   a source language processor.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+   SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+   FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+ +/
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2025.  */
+
+module gnu.libintl;
+
+public import gnu.libintl.libintl;
index 89cfc7787e44a80f71a38f7f6e6b6ffb6163ea62..9122ddf9f3ca820621667202b993b2602cca6db2 100644 (file)
@@ -1,5 +1,5 @@
 ## Makefile for the gnulib-local directory of GNU gettext
-## Copyright (C) 2006-2024 Free Software Foundation, Inc.
+## Copyright (C) 2006-2025 Free Software Foundation, Inc.
 ##
 ## This program is free software: you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -147,10 +147,12 @@ lib/unistd.in.h.diff \
 lib/xerror.c \
 lib/xerror.h \
 m4/backupfile.m4 \
+m4/d.m4 \
 m4/java.m4 \
 m4/libxml.m4 \
 modules/backupfile \
 modules/closeout \
+modules/d \
 modules/error-progname \
 modules/gettext-runtime-intl-misc \
 modules/gettext-runtime-misc \
diff --git a/gnulib-local/m4/d.m4 b/gnulib-local/m4/d.m4
new file mode 100644 (file)
index 0000000..2c25fbd
--- /dev/null
@@ -0,0 +1,19 @@
+# d.m4
+# serial 1
+dnl Copyright (C) 2025 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl This file is offered as-is, without any warranty.
+
+# Sets D_CHOICE to 'yes' or 'no', depending on the preferred use of D.
+AC_DEFUN([gt_D_CHOICE],
+[
+  AC_MSG_CHECKING([whether to use D])
+  AC_ARG_ENABLE(d,
+    [  --disable-d             do not build D sources],
+    [D_CHOICE="$enableval"],
+    [D_CHOICE=yes])
+  AC_MSG_RESULT([$D_CHOICE])
+  AC_SUBST([D_CHOICE])
+])
diff --git a/gnulib-local/modules/d b/gnulib-local/modules/d
new file mode 100644 (file)
index 0000000..2bef24a
--- /dev/null
@@ -0,0 +1,20 @@
+Description:
+Find user preferences regarding the use of D.
+
+Files:
+m4/d.m4
+
+Depends-on:
+
+configure.ac:
+gt_D_CHOICE
+
+Makefile.am:
+
+Include:
+
+License:
+GPL
+
+Maintainer:
+Bruno Haible