These 3 patches are small improvements. The first two are for robustness and maintainability.
The third one is to speed up the gl_locale_name function of thread-local locales on AIX ≥ 7.2. The AIX maintainers have apparently noticed that it's hard to write a gettext() function if the locale_t object does not contain the locale name of the LC_MESSAGES category. So they added that in AIX 7.2. What they did not notice is that there is also a dcgettext() function, that is supposed to work for other locale categories, such as LC_TIME, and that the same problem remains for LC_TIME etc. that they so intelligently fixed for LC_MESSAGES. 2024-02-15 Bruno Haible <br...@clisp.org> localename: Speed up lookup of the LC_MESSAGES name on AIX ≥ 7.2. * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): On AIX, test for the 'locale_name' member. * lib/localename.c (get_locale_t_name): For the LC_MESSAGES category, use the 'locale_name' member if available. 2024-02-15 Bruno Haible <br...@clisp.org> localename: Add more comments. * m4/intl-thread-locale.m4: Document expected configuration results. * doc/posix-functions/uselocale.texi: Update platforms list. * lib/localename.c: Likewise. 2024-02-15 Bruno Haible <br...@clisp.org> localename: Add parameter validation. * lib/localename.c (get_locale_t_name, gl_locale_name_thread_unsafe, gl_locale_name_thread, gl_locale_name_posix, gl_locale_name): Verify that the category argument is not LC_ALL.
>From 14e0811e01ceba4ef5fa9162ab5baa73957fa1ee Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 15 Feb 2024 10:48:50 +0100 Subject: [PATCH 01/12] localename: Add parameter validation. * lib/localename.c (get_locale_t_name, gl_locale_name_thread_unsafe, gl_locale_name_thread, gl_locale_name_posix, gl_locale_name): Verify that the category argument is not LC_ALL. --- ChangeLog | 7 +++++++ lib/localename.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index 023c1d4d50..531d5ffa57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-02-15 Bruno Haible <br...@clisp.org> + + localename: Add parameter validation. + * lib/localename.c (get_locale_t_name, gl_locale_name_thread_unsafe, + gl_locale_name_thread, gl_locale_name_posix, gl_locale_name): Verify + that the category argument is not LC_ALL. + 2024-02-14 Bruno Haible <br...@clisp.org> localename: Notice setlocale() invocations on more platforms. diff --git a/lib/localename.c b/lib/localename.c index 3bfcdabf4f..72f773bbed 100644 --- a/lib/localename.c +++ b/lib/localename.c @@ -2730,6 +2730,9 @@ struniq (const char *string) static const char * get_locale_t_name (int category, locale_t locale) { + if (category == LC_ALL) + /* Invalid argument. */ + abort (); if (locale == LC_GLOBAL_LOCALE) { /* Query the global locale. */ @@ -3105,6 +3108,9 @@ static const char * gl_locale_name_thread_unsafe (int category, _GL_UNUSED const char *categoryname) { + if (category == LC_ALL) + /* Invalid argument. */ + abort (); # if HAVE_GOOD_USELOCALE { locale_t thread_locale = uselocale (NULL); @@ -3282,6 +3288,9 @@ gl_locale_name_thread_unsafe (int category, _GL_UNUSED const char *categoryname) const char * gl_locale_name_thread (int category, _GL_UNUSED const char *categoryname) { + if (category == LC_ALL) + /* Invalid argument. */ + abort (); #if HAVE_GOOD_USELOCALE const char *name = gl_locale_name_thread_unsafe (category, categoryname); if (name != NULL) @@ -3328,6 +3337,9 @@ gl_locale_name_thread (int category, _GL_UNUSED const char *categoryname) const char * gl_locale_name_posix (int category, _GL_UNUSED const char *categoryname) { + if (category == LC_ALL) + /* Invalid argument. */ + abort (); #if defined WINDOWS_NATIVE if (LC_MIN <= category && category <= LC_MAX) { @@ -3531,6 +3543,10 @@ gl_locale_name (int category, const char *categoryname) { const char *retval; + if (category == LC_ALL) + /* Invalid argument. */ + abort (); + retval = gl_locale_name_thread (category, categoryname); if (retval != NULL) return retval; -- 2.34.1
From 08529be2425599726e0f4e77a4e0c998c9706e6b Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 15 Feb 2024 14:35:53 +0100 Subject: [PATCH 02/12] localename: Add more comments. * m4/intl-thread-locale.m4: Document expected configuration results. * doc/posix-functions/uselocale.texi: Update platforms list. * lib/localename.c: Likewise. --- ChangeLog | 7 +++++++ doc/posix-functions/uselocale.texi | 5 +++-- lib/localename.c | 6 ++++-- m4/intl-thread-locale.m4 | 13 ++++++++++++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 531d5ffa57..365a8d07e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-02-15 Bruno Haible <br...@clisp.org> + + localename: Add more comments. + * m4/intl-thread-locale.m4: Document expected configuration results. + * doc/posix-functions/uselocale.texi: Update platforms list. + * lib/localename.c: Likewise. + 2024-02-15 Bruno Haible <br...@clisp.org> localename: Add parameter validation. diff --git a/doc/posix-functions/uselocale.texi b/doc/posix-functions/uselocale.texi index e6ded0caf4..600d4c1e28 100644 --- a/doc/posix-functions/uselocale.texi +++ b/doc/posix-functions/uselocale.texi @@ -14,7 +14,8 @@ @itemize @item This function is missing on many platforms: -FreeBSD 9.0, NetBSD 9.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, IRIX 6.5, Solaris 11.3, Cygwin 2.5.x, mingw, MSVC 14, Android 4.4. +@c For NetBSD, see https://mail-index.netbsd.org/tech-userlevel/2015/12/29/msg009556.html +FreeBSD 9.0, NetBSD 10.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, IRIX 6.5, Solaris 11.3, Cygwin 2.5.x, mingw, MSVC 14, Android API level 20. @item This function is not documented and leads to crashes in subsequent @code{setlocale} invocations on some platforms: @@ -26,5 +27,5 @@ @item This function is useless because the @code{locale_t} type contains basically no information on some platforms: -OpenBSD 6.3. +OpenBSD 7.4. @end itemize diff --git a/lib/localename.c b/lib/localename.c index 72f773bbed..1bdc73f1cb 100644 --- a/lib/localename.c +++ b/lib/localename.c @@ -2630,8 +2630,10 @@ get_lcid (const char *locale_name) #endif -#if HAVE_GOOD_USELOCALE /* glibc, Mac OS X, FreeBSD >= 9.1, Cygwin >= 2.6, - Solaris 11 OpenIndiana, or Solaris >= 11.4 */ +#if HAVE_GOOD_USELOCALE /* glibc, musl libc, macOS, FreeBSD >= 9.1, AIX 7.1, + AIX >= 7.3, Solaris >= 11.4, Solaris 11 OpenIndiana, + Solaris 11 OmniOS, Cygwin >= 2.6, + Android API level >= 21 */ /* Simple hash set of strings. We don't want to drag in lots of hash table code here. */ diff --git a/m4/intl-thread-locale.m4 b/m4/intl-thread-locale.m4 index 74a2654b65..9710cb6d84 100644 --- a/m4/intl-thread-locale.m4 +++ b/m4/intl-thread-locale.m4 @@ -1,4 +1,4 @@ -# intl-thread-locale.m4 serial 10 +# intl-thread-locale.m4 serial 11 dnl Copyright (C) 2015-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -38,6 +38,7 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl they did not think about the programs. dnl In this situation, even the HAVE_NAMELESS_LOCALES support does not work. dnl So, define HAVE_FAKE_LOCALES and disable all locale_t support. + dnl Expected result: HAVE_FAKE_LOCALES is defined on OpenBSD ≥ 6.2. case "$gt_cv_func_uselocale_works" in *yes) AC_CHECK_HEADERS_ONCE([xlocale.h]) @@ -81,6 +82,7 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] ;; esac + dnl Expected result: HAVE_SOLARIS114_LOCALES is defined on Solaris ≥ 11.4. case "$gt_cv_func_uselocale_works" in *yes) AC_CACHE_CHECK([for Solaris 11.4 locale system], @@ -128,6 +130,7 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl requires the gnulib overrides of 'newlocale', 'duplocale', 'freelocale', dnl which is a problem for GNU libunistring. Therefore try hard to avoid dnl enabling this code! + dnl Expected result: HAVE_NAMELESS_LOCALES is defined on AIX. gt_nameless_locales=no case "$host_os" in dnl It's needed on AIX 7.2. @@ -141,6 +144,9 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl We cannot support uselocale() on platforms where the locale_t type is dnl fake. So, set dnl gt_good_uselocale = gt_working_uselocale && !gt_fake_locales. + dnl Expected result: HAVE_GOOD_USELOCALE is defined on all platforms except + dnl FreeBSD < 9.1, NetBSD, OpenBSD, Minix, AIX < 7, AIX 7.2, HP-UX, IRIX, + dnl Solaris < 11.4, Cygwin < 2.6, mingw, MSVC 14, Android API level < 21. if test $gt_working_uselocale = yes && test $gt_fake_locales = no; then gt_good_uselocale=yes AC_DEFINE([HAVE_GOOD_USELOCALE], [1], @@ -152,6 +158,8 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl Set gt_localename_enhances_locale_funcs to indicate whether localename.c dnl overrides newlocale(), duplocale(), freelocale() to keep track of locale dnl names. + dnl Expected result: LOCALENAME_ENHANCE_LOCALE_FUNCS is defined on + dnl AIX 7.1, AIX ≥ 7.3. if test $gt_good_uselocale = yes && test $gt_nameless_locales = yes; then gt_localename_enhances_locale_funcs=yes LOCALENAME_ENHANCE_LOCALE_FUNCS=1 @@ -164,6 +172,9 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl Tests whether uselocale() exists and is usable. dnl Sets gt_working_uselocale and defines HAVE_WORKING_USELOCALE. +dnl Expected result: HAVE_WORKING_USELOCALE is defined on all platforms except +dnl FreeBSD < 9.1, NetBSD, OpenBSD < 6.2, Minix, AIX < 7, AIX 7.2, HP-UX, IRIX, +dnl Solaris < 11.4, Cygwin < 2.6, mingw, MSVC 14, Android API level < 21. AC_DEFUN([gt_FUNC_USELOCALE], [ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles -- 2.34.1
From 276f74abae91dc777e279888634d272089f0562f Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 15 Feb 2024 16:00:59 +0100 Subject: [PATCH 03/12] =?UTF-8?q?localename:=20Speed=20up=20lookup=20of=20?= =?UTF-8?q?the=20LC=5FMESSAGES=20name=20on=20AIX=20=E2=89=A5=207.2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): On AIX, test for the 'locale_name' member. * lib/localename.c (get_locale_t_name): For the LC_MESSAGES category, use the 'locale_name' member if available. --- ChangeLog | 8 ++++++++ lib/localename.c | 18 +++++++++++++----- m4/intl-thread-locale.m4 | 26 +++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 365a8d07e0..4007567028 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2024-02-15 Bruno Haible <br...@clisp.org> + + localename: Speed up lookup of the LC_MESSAGES name on AIX ≥ 7.2. + * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): On AIX, test + for the 'locale_name' member. + * lib/localename.c (get_locale_t_name): For the LC_MESSAGES category, + use the 'locale_name' member if available. + 2024-02-15 Bruno Haible <br...@clisp.org> localename: Add more comments. diff --git a/lib/localename.c b/lib/localename.c index 1bdc73f1cb..f6879ac330 100644 --- a/lib/localename.c +++ b/lib/localename.c @@ -1,12 +1,12 @@ /* Determine name of the currently selected locale. Copyright (C) 1995-2024 Free Software Foundation, Inc. - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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 Lesser General Public License for more details. @@ -2747,6 +2747,14 @@ get_locale_t_name (int category, locale_t locale) } else { +# if HAVE_AIX72_LOCALES + if (category == LC_MESSAGES) + { + const char *name = ((__locale_t) locale)->locale_name; + if (name != NULL) + return struniq (name); + } +# endif /* Look up the names in the hash table. */ size_t hashcode = locale_hash_function (locale); size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; diff --git a/m4/intl-thread-locale.m4 b/m4/intl-thread-locale.m4 index 9710cb6d84..63efc44fbc 100644 --- a/m4/intl-thread-locale.m4 +++ b/m4/intl-thread-locale.m4 @@ -1,4 +1,4 @@ -# intl-thread-locale.m4 serial 11 +# intl-thread-locale.m4 serial 12 dnl Copyright (C) 2015-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -130,7 +130,8 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl requires the gnulib overrides of 'newlocale', 'duplocale', 'freelocale', dnl which is a problem for GNU libunistring. Therefore try hard to avoid dnl enabling this code! - dnl Expected result: HAVE_NAMELESS_LOCALES is defined on AIX. + dnl Expected result: HAVE_NAMELESS_LOCALES is defined on AIX, + dnl and HAVE_AIX72_LOCALES is defined on AIX ≥ 7.2. gt_nameless_locales=no case "$host_os" in dnl It's needed on AIX 7.2. @@ -138,6 +139,25 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] gt_nameless_locales=yes AC_DEFINE([HAVE_NAMELESS_LOCALES], [1], [Define if the locale_t type does not contain the name of each locale category.]) + dnl In AIX ≥ 7.2, a locale contains at least the name of the LC_MESSSAGES + dnl category (fix of defect 823926). + AC_CACHE_CHECK([for AIX locales with LC_MESSAGES name], + [gt_cv_locale_aix72], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include <locale.h> + /* Include <sys/localedef.h>, which defines __locale_t. */ + #include <stdlib.h> + locale_t x; + ]], + [[return ((__locale_t) x)->locale_name[0];]])], + [gt_cv_locale_aix72=yes], + [gt_cv_locale_aix72=no]) + ]) + if test $gt_cv_locale_aix72 = yes; then + AC_DEFINE([HAVE_AIX72_LOCALES], [1], + [Define if the __locale_t type contains the name of the LC_MESSAGES category.]) + fi ;; esac @@ -150,7 +170,7 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] if test $gt_working_uselocale = yes && test $gt_fake_locales = no; then gt_good_uselocale=yes AC_DEFINE([HAVE_GOOD_USELOCALE], [1], - [Define if the uselocale exists, may be safely called, and returns sufficient information.]) + [Define if the uselocale function exists, may be safely called, and returns sufficient information.]) else gt_good_uselocale=no fi -- 2.34.1