Based on the portable 'locale_t' type, it is possible to write a portable newlocale() function.
2025-02-14 Bruno Haible <br...@clisp.org> newlocale: Add tests. * tests/test-newlocale.c: New file. * modules/newlocale-tests: New file. newlocale: New module. * lib/locale.in.h (newlocale): Consider GNULIB_NEWLOCALE. Declare if not declared. Don't define HAVE_WORKING_NEWLOCALE. * lib/newlocale.c: New file. * m4/newlocale.m4: New file. * m4/locale_h.m4 (gl_LOCALE_H_REQUIRE_DEFAULTS): Initialize GNULIB_NEWLOCALE. * modules/locale-h (Makefile.am): Substitute GNULIB_NEWLOCALE. * modules/newlocale: New file. * tests/test-locale-h-c++.cc: Check declaration of newlocale. * tests/test-localename.c: Ignore HAVE_WORKING_NEWLOCALE. * doc/posix-functions/newlocale.texi: Mention the new module. 2025-02-14 Bruno Haible <br...@clisp.org> localename-environ: New module. * lib/localename-environ.c: New file, extracted from lib/localename-unsafe.c. * lib/localename-unsafe.c (gl_locale_name_environ): Remove function. * m4/localename.m4 (gl_LOCALENAME_ENVIRON): New macro. * modules/localename-environ: New file. * modules/localename-unsafe (Depends-on): Add localename-environ. * modules/setlocale (Depends-on): Likewise.
>From d3afa7cfedb4a621bcf4d4d48db3be76b9712c14 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 14 Feb 2025 02:02:58 +0100 Subject: [PATCH 1/5] localename-environ: New module. * lib/localename-environ.c: New file, extracted from lib/localename-unsafe.c. * lib/localename-unsafe.c (gl_locale_name_environ): Remove function. * m4/localename.m4 (gl_LOCALENAME_ENVIRON): New macro. * modules/localename-environ: New file. * modules/localename-unsafe (Depends-on): Add localename-environ. * modules/setlocale (Depends-on): Likewise. --- ChangeLog | 11 ++++++++ lib/localename-environ.c | 58 ++++++++++++++++++++++++++++++++++++++ lib/localename-unsafe.c | 33 ---------------------- m4/localename.m4 | 7 ++++- modules/localename-environ | 26 +++++++++++++++++ modules/localename-unsafe | 1 + modules/setlocale | 5 ++-- 7 files changed, 105 insertions(+), 36 deletions(-) create mode 100644 lib/localename-environ.c create mode 100644 modules/localename-environ diff --git a/ChangeLog b/ChangeLog index dd083951c5..6c4200a35f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2025-02-14 Bruno Haible <br...@clisp.org> + + localename-environ: New module. + * lib/localename-environ.c: New file, extracted from + lib/localename-unsafe.c. + * lib/localename-unsafe.c (gl_locale_name_environ): Remove function. + * m4/localename.m4 (gl_LOCALENAME_ENVIRON): New macro. + * modules/localename-environ: New file. + * modules/localename-unsafe (Depends-on): Add localename-environ. + * modules/setlocale (Depends-on): Likewise. + 2025-02-13 Bruno Haible <br...@clisp.org> locale-h: Ensure locale_t type. diff --git a/lib/localename-environ.c b/lib/localename-environ.c new file mode 100644 index 0000000000..fea88fa88e --- /dev/null +++ b/lib/localename-environ.c @@ -0,0 +1,58 @@ +/* Determine name of the currently selected locale. + Copyright (C) 1995-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 Ulrich Drepper <drep...@gnu.org>, 1995. */ + +#include <config.h> + +/* Specification. */ +#include "localename.h" + +#include <stdlib.h> +#include <string.h> + +const char * +gl_locale_name_environ (_GL_UNUSED int category, const char *categoryname) +{ + const char *retval; + + /* Setting of LC_ALL overrides all other. */ + retval = getenv ("LC_ALL"); + if (retval != NULL && retval[0] != '\0') + return retval; + /* Next comes the name of the desired category. */ + retval = getenv (categoryname); + if (retval != NULL && retval[0] != '\0') + return retval; + /* Last possibility is the LANG environment variable. */ + retval = getenv ("LANG"); + if (retval != NULL && retval[0] != '\0') + { +#if HAVE_CFPREFERENCESCOPYAPPVALUE + /* Mac OS X 10.2 or newer. + Ignore invalid LANG value set by the Terminal application. */ + if (strcmp (retval, "UTF-8") != 0) +#endif +#if defined __CYGWIN__ + /* Cygwin. + Ignore dummy LANG value set by ~/.profile. */ + if (strcmp (retval, "C.UTF-8") != 0) +#endif + return retval; + } + + return NULL; +} diff --git a/lib/localename-unsafe.c b/lib/localename-unsafe.c index b3160b5015..ebdf2e9491 100644 --- a/lib/localename-unsafe.c +++ b/lib/localename-unsafe.c @@ -3310,39 +3310,6 @@ gl_locale_name_posix_unsafe (int category, _GL_UNUSED const char *categoryname) } } -const char * -gl_locale_name_environ (_GL_UNUSED int category, const char *categoryname) -{ - const char *retval; - - /* Setting of LC_ALL overrides all other. */ - retval = getenv ("LC_ALL"); - if (retval != NULL && retval[0] != '\0') - return retval; - /* Next comes the name of the desired category. */ - retval = getenv (categoryname); - if (retval != NULL && retval[0] != '\0') - return retval; - /* Last possibility is the LANG environment variable. */ - retval = getenv ("LANG"); - if (retval != NULL && retval[0] != '\0') - { -#if HAVE_CFPREFERENCESCOPYAPPVALUE - /* Mac OS X 10.2 or newer. - Ignore invalid LANG value set by the Terminal application. */ - if (strcmp (retval, "UTF-8") != 0) -#endif -#if defined __CYGWIN__ - /* Cygwin. - Ignore dummy LANG value set by ~/.profile. */ - if (strcmp (retval, "C.UTF-8") != 0) -#endif - return retval; - } - - return NULL; -} - const char * gl_locale_name_default (void) { diff --git a/m4/localename.m4 b/m4/localename.m4 index ee614fd943..af94411b23 100644 --- a/m4/localename.m4 +++ b/m4/localename.m4 @@ -1,5 +1,5 @@ # localename.m4 -# serial 12 +# serial 13 dnl Copyright (C) 2007, 2009-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, @@ -61,3 +61,8 @@ AC_DEFUN([gl_LOCALENAME_UNSAFE_LIMITED] AC_REQUIRE([gt_LC_MESSAGES]) AC_REQUIRE([gt_INTL_THREAD_LOCALE_NAME]) ]) + +AC_DEFUN([gl_LOCALENAME_ENVIRON], +[ + AC_REQUIRE([gt_INTL_MACOSX]) +]) diff --git a/modules/localename-environ b/modules/localename-environ new file mode 100644 index 0000000000..dcfc47e468 --- /dev/null +++ b/modules/localename-environ @@ -0,0 +1,26 @@ +Description: +Return current locale's name, as specified by environment variables. + +Files: +lib/localename.h +lib/localename-environ.c +m4/localename.m4 +m4/intlmacosx.m4 + +Depends-on: + +configure.ac: +gl_LOCALENAME_ENVIRON +gl_LOCALE_MODULE_INDICATOR([localename-environ]) + +Makefile.am: +lib_SOURCES += localename-environ.c + +Include: +"localename.h" + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/localename-unsafe b/modules/localename-unsafe index b0aea3409d..18fa5433bd 100644 --- a/modules/localename-unsafe +++ b/modules/localename-unsafe @@ -16,6 +16,7 @@ m4/musl.m4 Depends-on: localename-unsafe-limited +localename-environ extensions bool locale-h diff --git a/modules/setlocale b/modules/setlocale index c59ca1f41e..a7c52cdeef 100644 --- a/modules/setlocale +++ b/modules/setlocale @@ -7,8 +7,9 @@ m4/setlocale.m4 Depends-on: locale-h -localename [test $NEED_SETLOCALE_IMPROVED = 1] -setlocale-null [test $NEED_SETLOCALE_MTSAFE = 1] +localename [test $NEED_SETLOCALE_IMPROVED = 1] +localename-environ [test $NEED_SETLOCALE_IMPROVED = 1] +setlocale-null [test $NEED_SETLOCALE_MTSAFE = 1] configure.ac: gl_FUNC_SETLOCALE -- 2.43.0
>From f6af6db65754a7556c90672fd3abc1e20fc53e34 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 13 Feb 2025 23:01:52 +0100 Subject: [PATCH 2/5] newlocale: New module. * lib/locale.in.h (newlocale): Consider GNULIB_NEWLOCALE. Declare if not declared. Don't define HAVE_WORKING_NEWLOCALE. * lib/newlocale.c: New file. * m4/newlocale.m4: New file. * m4/locale_h.m4 (gl_LOCALE_H_REQUIRE_DEFAULTS): Initialize GNULIB_NEWLOCALE. * modules/locale-h (Makefile.am): Substitute GNULIB_NEWLOCALE. * modules/newlocale: New file. * tests/test-locale-h-c++.cc: Check declaration of newlocale. * tests/test-localename.c: Ignore HAVE_WORKING_NEWLOCALE. * doc/posix-functions/newlocale.texi: Mention the new module. --- ChangeLog | 15 +++ doc/posix-functions/newlocale.texi | 13 +- lib/locale.in.h | 16 +-- lib/newlocale.c | 204 +++++++++++++++++++++++++++++ m4/locale_h.m4 | 3 +- m4/newlocale.m4 | 22 ++++ modules/locale-h | 1 + modules/newlocale | 32 +++++ tests/test-locale-h-c++.cc | 2 +- tests/test-localename.c | 2 +- 10 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 lib/newlocale.c create mode 100644 m4/newlocale.m4 create mode 100644 modules/newlocale diff --git a/ChangeLog b/ChangeLog index 6c4200a35f..0e53a6e531 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2025-02-14 Bruno Haible <br...@clisp.org> + + newlocale: New module. + * lib/locale.in.h (newlocale): Consider GNULIB_NEWLOCALE. Declare if + not declared. Don't define HAVE_WORKING_NEWLOCALE. + * lib/newlocale.c: New file. + * m4/newlocale.m4: New file. + * m4/locale_h.m4 (gl_LOCALE_H_REQUIRE_DEFAULTS): Initialize + GNULIB_NEWLOCALE. + * modules/locale-h (Makefile.am): Substitute GNULIB_NEWLOCALE. + * modules/newlocale: New file. + * tests/test-locale-h-c++.cc: Check declaration of newlocale. + * tests/test-localename.c: Ignore HAVE_WORKING_NEWLOCALE. + * doc/posix-functions/newlocale.texi: Mention the new module. + 2025-02-14 Bruno Haible <br...@clisp.org> localename-environ: New module. diff --git a/doc/posix-functions/newlocale.texi b/doc/posix-functions/newlocale.texi index 762cf8c45e..a305c3821b 100644 --- a/doc/posix-functions/newlocale.texi +++ b/doc/posix-functions/newlocale.texi @@ -4,21 +4,22 @@ POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/newlocale.html} -Gnulib module: --- +Gnulib module: newlocale +@mindex newlocale Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item This function is missing on many platforms: -FreeBSD 9.0, NetBSD 5.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, Solaris 11.3, Cygwin 2.5.x, mingw, MSVC 14, Android 4.4. +FreeBSD 9.0, NetBSD 6.1, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, Solaris 11.3, Cygwin 2.5.x, mingw, MSVC 14, Android 4.4. @item This function is useless because the @code{locale_t} type is not defined on some platforms: z/OS. +@end itemize + +Portability problems not fixed by Gnulib: +@itemize @item This function is useless because the @code{locale_t} type contains basically no information on some platforms: diff --git a/lib/locale.in.h b/lib/locale.in.h index 389ff26124..7fa426859f 100644 --- a/lib/locale.in.h +++ b/lib/locale.in.h @@ -300,7 +300,7 @@ _GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " # include "setlocale_null.h" #endif -#if /*@GNULIB_NEWLOCALE@ ||*/ (@GNULIB_LOCALENAME_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_NEWLOCALE@) +#if @GNULIB_NEWLOCALE@ || (@GNULIB_LOCALENAME_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_NEWLOCALE@) # if @REPLACE_NEWLOCALE@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef newlocale @@ -313,19 +313,17 @@ _GL_FUNCDECL_RPL (newlocale, locale_t, _GL_CXXALIAS_RPL (newlocale, locale_t, (int category_mask, const char *name, locale_t base)); # else -# if @HAVE_NEWLOCALE@ +# if !@HAVE_NEWLOCALE@ +_GL_FUNCDECL_SYS (newlocale, locale_t, + (int category_mask, const char *name, locale_t base), + _GL_ARG_NONNULL ((2))); +# endif _GL_CXXALIAS_SYS (newlocale, locale_t, (int category_mask, const char *name, locale_t base)); -# endif # endif -# if __GLIBC__ >= 2 && @HAVE_NEWLOCALE@ +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (newlocale); # endif -# if @HAVE_NEWLOCALE@ || @REPLACE_NEWLOCALE@ -# ifndef HAVE_WORKING_NEWLOCALE -# define HAVE_WORKING_NEWLOCALE 1 -# endif -# endif #elif defined GNULIB_POSIXCHECK # undef newlocale # if HAVE_RAW_DECL_NEWLOCALE diff --git a/lib/newlocale.c b/lib/newlocale.c new file mode 100644 index 0000000000..01bc2f3953 --- /dev/null +++ b/lib/newlocale.c @@ -0,0 +1,204 @@ +/* Create a locale object. + 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. */ + +#include <config.h> + +/* Specification. */ +#include <locale.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include "localename.h" + +locale_t +newlocale (int category_mask, const char *name, locale_t base) +{ + if ((category_mask & ~LC_ALL_MASK) != 0) + { + errno = EINVAL; + return NULL; + } + + struct gl_locale_t tmp; + struct gl_locale_t *result; + if (base != NULL) + { + /* Work on tmp, so as not to destroy BASE until we're successful. */ + result = &tmp; + } + else + { + result = (struct gl_locale_t *) malloc (sizeof (struct gl_locale_t)); + if (result == NULL) + { + errno = ENOMEM; + return NULL; + } + } + + /* Canonicalize the name. */ + if (strcmp (name, "POSIX") == 0) + name = "C"; + +#if !HAVE_WINDOWS_LOCALE_T + /* In this case, the only NAMEs that we support are "C" and (equivalently) + "POSIX". */ + if (category_mask != 0 && strcmp (name, "C") != 0) + { + errno = ENOENT; + return NULL; + } +#endif + + int i; + int err; + for (i = 0; i < 6; i++) + { + int log2_lcmask = gl_index_to_log2_lcmask (i); + + if ((category_mask & (1 << log2_lcmask)) != 0) + { + const char *lcname; + if (name[0] == '\0') + { + /* name == "" means to look at the environment variables. */ + static struct { int cat; char cat_name[11 + 1]; } const categories[6] = + { + [gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_COLLATE))] = + { LC_COLLATE, "LC_COLLATE" }, + [gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_CTYPE))] = + { LC_CTYPE, "LC_CTYPE" }, + [gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_MESSAGES))] = + { LC_MESSAGES, "LC_MESSAGES" }, + [gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_MONETARY))] = + { LC_MONETARY, "LC_MONETARY" }, + [gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_NUMERIC))] = + { LC_NUMERIC, "LC_NUMERIC" }, + [gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_TIME))] = + { LC_TIME, "LC_TIME" } + }; + lcname = gl_locale_name_environ (categories[i].cat, + categories[i].cat_name); + if (lcname == NULL) + lcname = "C"; + } + else + lcname = name; + + result->category[i].name = strdup (lcname); + if (result->category[i].name == NULL) + { + err = ENOMEM; + goto fail_with_err; + } + if (strcmp (lcname, "C") == 0) + { + result->category[i].is_c_locale = true; +#if HAVE_WINDOWS_LOCALE_T + /* Just to initialize it. */ + result->category[i].system_locale = NULL; +#endif + } + else + { + result->category[i].is_c_locale = false; +#if HAVE_WINDOWS_LOCALE_T + if (log2_lcmask == gl_log2_lc_mask (LC_MESSAGES)) + result->category[i].system_locale = NULL; + else + { + int cat = log2_lcmask; + (void) cat; + /* Documentation: + <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/create-locale-wcreate-locale> */ + result->category[i].system_locale = + _create_locale (LC_ALL /* or cat */, lcname); + if (result->category[i].system_locale == NULL) + { + free (result->category[i].name); + err = ENOENT; + goto fail_with_err; + } + } +#endif + } + } + else + { + if (base == NULL) + { + result->category[i].name = strdup ("C"); + if (result->category[i].name == NULL) + { + err = ENOMEM; + goto fail_with_err; + } + result->category[i].is_c_locale = true; +#if HAVE_WINDOWS_LOCALE_T + /* Just to initialize it. */ + result->category[i].system_locale = NULL; +#endif + } + } + } + + /* Success. */ + if (base != NULL) + { + /* Copy the modified entries from RESULT to BASE. */ + for (i = 0; i < 6; i++) + { + int log2_lcmask = gl_index_to_log2_lcmask (i); + if ((category_mask & (1 << log2_lcmask)) != 0) + { +#if HAVE_WINDOWS_LOCALE_T + if (!(i == gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_MESSAGES)) + || base->category[i].is_c_locale)) + /* Documentation: + <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/free-locale> */ + _free_locale (base->category[i].system_locale); +#endif + free (base->category[i].name); + + base->category[i] = result->category[i]; + } + } + return base; + } + else + return result; + + fail_with_err: + while (--i >= 0) + { +#if HAVE_WINDOWS_LOCALE_T + if (!(i == gl_log2_lcmask_to_index (gl_log2_lc_mask (LC_MESSAGES)) + || result->category[i].is_c_locale)) + /* Documentation: + <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/free-locale> */ + _free_locale (result->category[i].system_locale); +#endif + free (result->category[i].name); + } + if (base == NULL) + free (result); + errno = err; + return NULL; +} diff --git a/m4/locale_h.m4 b/m4/locale_h.m4 index 9300062194..0635a4c3bb 100644 --- a/m4/locale_h.m4 +++ b/m4/locale_h.m4 @@ -1,5 +1,5 @@ # locale_h.m4 -# serial 32 +# serial 33 dnl Copyright (C) 2007, 2009-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, @@ -176,6 +176,7 @@ AC_DEFUN([gl_LOCALE_H_REQUIRE_DEFAULTS] gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALECONV]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE_NULL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NEWLOCALE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUPLOCALE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALENAME_UNSAFE]) ]) diff --git a/m4/newlocale.m4 b/m4/newlocale.m4 new file mode 100644 index 0000000000..b2475eb16f --- /dev/null +++ b/m4/newlocale.m4 @@ -0,0 +1,22 @@ +# newlocale.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. + +AC_DEFUN([gl_FUNC_NEWLOCALE], +[ + AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) + gl_CHECK_FUNCS_ANDROID([newlocale], [[#include <locale.h>]]) + if test $ac_cv_func_newlocale = no; then + HAVE_NEWLOCALE=0 + fi +]) + +# Prerequisites of lib/newlocale.c. +AC_DEFUN([gl_PREREQ_NEWLOCALE], +[ + : +]) diff --git a/modules/locale-h b/modules/locale-h index 5dab6ab42a..a5317cf9c9 100644 --- a/modules/locale-h +++ b/modules/locale-h @@ -38,6 +38,7 @@ locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_LOCALECONV''@/$(GNULIB_LOCALECONV)/g' \ -e 's/@''GNULIB_SETLOCALE''@/$(GNULIB_SETLOCALE)/g' \ -e 's/@''GNULIB_SETLOCALE_NULL''@/$(GNULIB_SETLOCALE_NULL)/g' \ + -e 's/@''GNULIB_NEWLOCALE''@/$(GNULIB_NEWLOCALE)/g' \ -e 's/@''GNULIB_DUPLOCALE''@/$(GNULIB_DUPLOCALE)/g' \ -e 's/@''GNULIB_LOCALENAME_UNSAFE''@/$(GNULIB_LOCALENAME_UNSAFE)/g' \ -e 's|@''HAVE_NEWLOCALE''@|$(HAVE_NEWLOCALE)|g' \ diff --git a/modules/newlocale b/modules/newlocale new file mode 100644 index 0000000000..78a10436fa --- /dev/null +++ b/modules/newlocale @@ -0,0 +1,32 @@ +Description: +newlocale() function: create a locale object. + +Files: +lib/newlocale.c +m4/newlocale.m4 + +Depends-on: +locale-h +localename-environ + +configure.ac: +gl_FUNC_NEWLOCALE +gl_CONDITIONAL([GL_COND_OBJ_NEWLOCALE], [test $HAVE_LOCALE_T = 0]) +AM_COND_IF([GL_COND_OBJ_NEWLOCALE], [ + gl_PREREQ_NEWLOCALE +]) +gl_LOCALE_MODULE_INDICATOR([newlocale]) + +Makefile.am: +if GL_COND_OBJ_NEWLOCALE +lib_SOURCES += newlocale.c +endif + +Include: +<locale.h> + +License: +LGPLv2+ + +Maintainer: +all diff --git a/tests/test-locale-h-c++.cc b/tests/test-locale-h-c++.cc index 1a68f2f28a..ad66ae4871 100644 --- a/tests/test-locale-h-c++.cc +++ b/tests/test-locale-h-c++.cc @@ -32,7 +32,7 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::localeconv, struct lconv *, (void)); SIGNATURE_CHECK (GNULIB_NAMESPACE::setlocale, char *, (int, const char *)); #endif -#if 0 +#if GNULIB_TEST_NEWLOCALE SIGNATURE_CHECK (GNULIB_NAMESPACE::newlocale, locale_t, (int, const char *, locale_t)); #endif diff --git a/tests/test-localename.c b/tests/test-localename.c index 3089b56c62..0bbc2c76d9 100644 --- a/tests/test-localename.c +++ b/tests/test-localename.c @@ -26,7 +26,7 @@ #include "macros.h" -#if HAVE_WORKING_NEWLOCALE && HAVE_WORKING_USELOCALE && !HAVE_FAKE_LOCALES +#if HAVE_WORKING_USELOCALE && !HAVE_FAKE_LOCALES # define HAVE_GOOD_USELOCALE 1 #endif -- 2.43.0
>From d08fa12b6eea6d3a8643d07501018cd93d45fa6b Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 14 Feb 2025 02:52:01 +0100 Subject: [PATCH 3/5] newlocale: Add tests. * tests/test-newlocale.c: New file. * modules/newlocale-tests: New file. --- ChangeLog | 4 +++ modules/newlocale-tests | 12 +++++++++ tests/test-newlocale.c | 56 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 modules/newlocale-tests create mode 100644 tests/test-newlocale.c diff --git a/ChangeLog b/ChangeLog index 0e53a6e531..1a73e832db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-02-14 Bruno Haible <br...@clisp.org> + newlocale: Add tests. + * tests/test-newlocale.c: New file. + * modules/newlocale-tests: New file. + newlocale: New module. * lib/locale.in.h (newlocale): Consider GNULIB_NEWLOCALE. Declare if not declared. Don't define HAVE_WORKING_NEWLOCALE. diff --git a/modules/newlocale-tests b/modules/newlocale-tests new file mode 100644 index 0000000000..706003b4f2 --- /dev/null +++ b/modules/newlocale-tests @@ -0,0 +1,12 @@ +Files: +tests/test-newlocale.c +tests/signature.h +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-newlocale +check_PROGRAMS += test-newlocale diff --git a/tests/test-newlocale.c b/tests/test-newlocale.c new file mode 100644 index 0000000000..fa21f8b697 --- /dev/null +++ b/tests/test-newlocale.c @@ -0,0 +1,56 @@ +/* Test of creating a locale object. + 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/>. */ + +/* Written by Bruno Haible <br...@clisp.org>, 2025. */ + +#include <config.h> + +#include <locale.h> + +#include "signature.h" +SIGNATURE_CHECK (newlocale, locale_t, (int, const char *, locale_t)); + +#include "macros.h" + +#if defined _WIN32 && !defined __CYGWIN__ + +# define ENGLISH "English_United States" +# define FRENCH "French_France" +# define GERMAN "German_Germany" +# define ENCODING ".1252" + +# define LOCALE1 ENGLISH ENCODING +# define LOCALE2 FRENCH ENCODING +# define LOCALE3 GERMAN ENCODING + +#else + +# define LOCALE1 "en_US.UTF-8" +# define LOCALE2 "fr_FR.UTF-8" +# define LOCALE3 "de_DE.UTF-8" + +#endif + +int +main () +{ + locale_t l1 = newlocale (LC_TIME_MASK, LOCALE1, NULL); + locale_t l2 = newlocale (LC_MESSAGES_MASK, LOCALE2, l1); + locale_t l3 = newlocale (LC_TIME_MASK, LOCALE3, l2); + (void) l3; + + return test_exit_status; +} -- 2.43.0