This patch extracts the base of the Windows LC_MESSAGES workaround into a separate module 'setlocale-messages', so that the module 'getlocalename_l' can depend on it without using the (large) 'setlocale' module.
2025-02-21 Bruno Haible <br...@clisp.org> setlocale-messages: New module. * lib/setlocale-messages.h: New file. * lib/setlocale-messages.c: New file, based on lib/setlocale.c. * modules/setlocale-messages: New file. * lib/setlocale.c: Include setlocale-messages.h. (lc_messages_name): Remove variable. (setlocale_single): Just invoke setlocale_messages. * modules/setlocale (Depends-on): Add setlocale-messages. diff --git a/lib/setlocale-messages.c b/lib/setlocale-messages.c new file mode 100644 index 0000000000..857236ee59 --- /dev/null +++ b/lib/setlocale-messages.c @@ -0,0 +1,45 @@ +/* Extension of the global locale with LC_MESSAGES. + Copyright (C) 2025 Free Software Foundation, Inc. + + 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 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. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "setlocale-messages.h" + +#include <stddef.h> +#include <string.h> + +/* The system does not store an LC_MESSAGES locale category. Do it here. */ +static char lc_messages_name[64] = "C"; + +const char * +setlocale_messages (const char *name) +{ + if (name != NULL) + { + lc_messages_name[sizeof (lc_messages_name) - 1] = '\0'; + strncpy (lc_messages_name, name, sizeof (lc_messages_name) - 1); + } + return lc_messages_name; +} + +const char * +setlocale_messages_null (void) +{ + /* This implementation is multithread-safe, assuming no other thread changes + the LC_MESSAGES locale category. */ + return lc_messages_name; +} diff --git a/lib/setlocale-messages.h b/lib/setlocale-messages.h new file mode 100644 index 0000000000..06c7a8dd41 --- /dev/null +++ b/lib/setlocale-messages.h @@ -0,0 +1,40 @@ +/* Extension of the global locale with LC_MESSAGES. + Copyright (C) 2025 Free Software Foundation, Inc. + + 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 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. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <br...@clisp.org>, 2025. */ + +#ifndef _SETLOCALE_MESSAGES_H +#define _SETLOCALE_MESSAGES_H + +/* This file is only relevant on platforms that lack LC_MESSAGES, namely + native Windows. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* setlocale_messages (NAME) is like setlocale (LC_MESSAGES, NAME). */ +extern const char *setlocale_messages (const char *name); + +/* setlocale_messages_null () is like setlocale (LC_MESSAGES, NULL), except that + it is guaranteed to be multithread-safe. */ +extern const char *setlocale_messages_null (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SETLOCALE_MESSAGES_H */ diff --git a/lib/setlocale.c b/lib/setlocale.c index b1c456c9da..5095eddb64 100644 --- a/lib/setlocale.c +++ b/lib/setlocale.c @@ -33,6 +33,7 @@ #include <stdlib.h> #include <string.h> +#include "setlocale-messages.h" #include "localename.h" #if HAVE_CFLOCALECOPYPREFERREDLANGUAGES || HAVE_CFPREFERENCESCOPYAPPVALUE @@ -905,22 +906,12 @@ setlocale_unixlike (int category, const char *locale) # if LC_MESSAGES == 1729 -/* The system does not store an LC_MESSAGES locale category. Do it here. */ -static char lc_messages_name[64] = "C"; - /* Like setlocale, but support also LC_MESSAGES. */ static char * setlocale_single (int category, const char *locale) { if (category == LC_MESSAGES) - { - if (locale != NULL) - { - lc_messages_name[sizeof (lc_messages_name) - 1] = '\0'; - strncpy (lc_messages_name, locale, sizeof (lc_messages_name) - 1); - } - return lc_messages_name; - } + return setlocale_messages (locale); else return setlocale_unixlike (category, locale); } diff --git a/modules/setlocale b/modules/setlocale index 1d1389b951..45c35ff808 100644 --- a/modules/setlocale +++ b/modules/setlocale @@ -7,6 +7,7 @@ m4/setlocale.m4 Depends-on: locale-h +setlocale-messages [test $NEED_SETLOCALE_IMPROVED = 1] localename [test $NEED_SETLOCALE_IMPROVED = 1] localename-environ [test $NEED_SETLOCALE_IMPROVED = 1] setlocale-null [test $NEED_SETLOCALE_MTSAFE = 1] diff --git a/modules/setlocale-messages b/modules/setlocale-messages new file mode 100644 index 0000000000..bd7c078cc8 --- /dev/null +++ b/modules/setlocale-messages @@ -0,0 +1,27 @@ +Description: +Extension of the global locale with LC_MESSAGES. + +Files: +lib/setlocale-messages.h +lib/setlocale-messages.c + +Depends-on: + +configure.ac: +AC_REQUIRE([AC_CANONICAL_HOST]) +gl_CONDITIONAL([GL_COND_OBJ_SETLOCALE_MESSAGES], + [case "$host_os" in mingw* | windows*) true;; *) false;; esac]) + +Makefile.am: +if GL_COND_OBJ_SETLOCALE_MESSAGES +lib_SOURCES += setlocale-messages.c +endif + +Include: +"setlocale-messages.h" + +License: +LGPLv2+ + +Maintainer: +all