From 4dff93434fcb770cb490a738d10d9cbb4a35d5be Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 8 Feb 2023 23:43:03 +0100 Subject: [PATCH] nl_langinfo tests: Add another test. * tests/test-nl_langinfo2.c: New file. * tests/test-nl_langinfo2.sh: New file. * modules/nl_langinfo-tests (Files): Add them. Add intl-thread-locale.m4. (Depends-on): Add c-strcasestr, stdbool. (configure.ac): Invoke gt_FUNC_USELOCALE. (Makefile.am): Arrange to compile test-nl_langinfo2 and test it through test-nl_langinfo2.sh. --- ChangeLog | 10 +++ modules/nl_langinfo-tests | 11 ++- tests/test-nl_langinfo2.c | 136 +++++++++++++++++++++++++++++++++++++ tests/test-nl_langinfo2.sh | 12 ++++ 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 tests/test-nl_langinfo2.c create mode 100755 tests/test-nl_langinfo2.sh diff --git a/ChangeLog b/ChangeLog index fcced364ff..a6b0d2eef7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2023-02-08 Bruno Haible + nl_langinfo tests: Add another test. + * tests/test-nl_langinfo2.c: New file. + * tests/test-nl_langinfo2.sh: New file. + * modules/nl_langinfo-tests (Files): Add them. Add + intl-thread-locale.m4. + (Depends-on): Add c-strcasestr, stdbool. + (configure.ac): Invoke gt_FUNC_USELOCALE. + (Makefile.am): Arrange to compile test-nl_langinfo2 and test it through + test-nl_langinfo2.sh. + nl_langinfo tests: Prepare for adding more tests. * tests/test-nl_langinfo1.c: Renamed from tests/test-nl_langinfo.c. * tests/test-nl_langinfo1.sh: Renamed from tests/test-nl_langinfo.sh. diff --git a/modules/nl_langinfo-tests b/modules/nl_langinfo-tests index e4456e3789..c48597acca 100644 --- a/modules/nl_langinfo-tests +++ b/modules/nl_langinfo-tests @@ -1,24 +1,31 @@ Files: tests/test-nl_langinfo1.sh +tests/test-nl_langinfo2.sh tests/test-nl_langinfo1.c +tests/test-nl_langinfo2.c tests/test-nl_langinfo-mt.c tests/signature.h tests/macros.h m4/locale-fr.m4 +m4/intl-thread-locale.m4 Depends-on: c-strcase +c-strcasestr setlocale thread nanosleep +stdbool configure.ac: gt_LOCALE_FR gt_LOCALE_FR_UTF8 +gt_FUNC_USELOCALE Makefile.am: -TESTS += test-nl_langinfo1.sh test-nl_langinfo-mt +TESTS += test-nl_langinfo1.sh test-nl_langinfo2.sh test-nl_langinfo-mt TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' -check_PROGRAMS += test-nl_langinfo1 test-nl_langinfo-mt +check_PROGRAMS += test-nl_langinfo1 test-nl_langinfo2 test-nl_langinfo-mt test_nl_langinfo1_LDADD = $(LDADD) $(SETLOCALE_LIB) +test_nl_langinfo2_LDADD = $(LDADD) $(SETLOCALE_LIB) test_nl_langinfo_mt_LDADD = $(LDADD) $(SETLOCALE_LIB) $(LIBMULTITHREAD) $(NANOSLEEP_LIB) diff --git a/tests/test-nl_langinfo2.c b/tests/test-nl_langinfo2.c new file mode 100644 index 0000000000..4625a8a0f8 --- /dev/null +++ b/tests/test-nl_langinfo2.c @@ -0,0 +1,136 @@ +/* Test of nl_langinfo replacement. + Copyright (C) 2023 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 . */ + +/* Written by Bruno Haible , 2023. */ + +#include + +#include + +#include +#include +#include + +#include "c-strcase.h" +#include "c-strcasestr.h" +#include "macros.h" + +int +main (int argc, char *argv[]) +{ +#if HAVE_WORKING_USELOCALE + /* Check that nl_langinfo() uses the per-thread locale. */ + int pass; + bool skipped_all = true; + + /* Extract a few items from the C locale. */ + /* nl_langinfo items of the LC_CTYPE category */ + const char *c_CODESET = nl_langinfo (CODESET); + /* nl_langinfo items of the LC_NUMERIC category */ + const char *c_RADIXCHAR = nl_langinfo (RADIXCHAR); + /* nl_langinfo items of the LC_TIME category */ + const char *c_T_FMT_AMPM = nl_langinfo (T_FMT_AMPM); + const char *c_AM_STR = nl_langinfo (AM_STR); + const char *c_PM_STR = nl_langinfo (PM_STR); + /* nl_langinfo items of the LC_MONETARY category */ + const char *c_CRNCYSTR = nl_langinfo (CRNCYSTR); + /* nl_langinfo items of the LC_MESSAGES category */ + const char *c_YESEXPR = nl_langinfo (YESEXPR); + + /* Sanity checks. */ + (void) c_CODESET; + ASSERT (strcmp (c_RADIXCHAR, ".") == 0); + ASSERT (strlen (c_T_FMT_AMPM) > 0); + ASSERT (strlen (c_AM_STR) > 0); + ASSERT (strlen (c_PM_STR) > 0); + ASSERT (strlen (c_CRNCYSTR) <= 1); /* "-", "+", ".", or "" */ + ASSERT (c_strcasestr (c_YESEXPR, "y" /* from "yes" */) != NULL); + + for (pass = 1; pass <= 2; pass++) + { + /* pass locale + 1 traditional French locale + 2 French UTF-8 locale + */ + const char *fr_locale_name = + getenv (pass == 1 ? "LOCALE_FR" : "LOCALE_FR_UTF8"); + if (strcmp (fr_locale_name, "none") != 0) + { + /* Use a per-thread locale. */ + locale_t fr_locale = newlocale (LC_ALL_MASK, fr_locale_name, NULL); + if (fr_locale != NULL) + { + uselocale (fr_locale); + + /* Extract a few items from the current locale, and check the + values. */ + + /* nl_langinfo items of the LC_CTYPE category */ + const char *fr_CODESET = nl_langinfo (CODESET); + if (pass == 1) + ASSERT (strstr (fr_CODESET, "8859") != NULL); + else if (pass == 2) + ASSERT (c_strcasecmp (fr_CODESET, "UTF-8") == 0 + || c_strcasecmp (fr_CODESET, "UTF8") == 0); + + /* nl_langinfo items of the LC_NUMERIC category */ + const char *fr_RADIXCHAR = nl_langinfo (RADIXCHAR); + ASSERT (strcmp (fr_RADIXCHAR, ",") == 0); + + /* nl_langinfo items of the LC_TIME category */ + /* macOS doesn't get the LC_TIME values right. + Poor. */ + #if !(defined __APPLE__ && defined __MACH__) + const char *fr_T_FMT_AMPM = nl_langinfo (T_FMT_AMPM); + const char *fr_AM_STR = nl_langinfo (AM_STR); + const char *fr_PM_STR = nl_langinfo (PM_STR); + ASSERT (strlen (fr_T_FMT_AMPM) == 0 + || strcmp (fr_T_FMT_AMPM, "%I:%M:%S") == 0); + ASSERT (strlen (fr_AM_STR) == 0); + ASSERT (strlen (fr_PM_STR) == 0); + #endif + + /* nl_langinfo items of the LC_MONETARY category */ + /* macOS doesn't get the EUR currency symbol or abbreviation + right. Very poor. */ + #if !(defined __APPLE__ && defined __MACH__) + const char *fr_CRNCYSTR = nl_langinfo (CRNCYSTR); + if (pass == 2) + ASSERT (strlen (fr_CRNCYSTR) >= 1 + && strcmp (fr_CRNCYSTR + 1, "€") == 0); + #endif + + /* nl_langinfo items of the LC_MESSAGES category */ + const char *fr_YESEXPR = nl_langinfo (YESEXPR); + ASSERT (c_strcasestr (fr_YESEXPR, "o" /* from "oui" */) != NULL); + + skipped_all = false; + } + } + } + + if (skipped_all) + { + fputs ("Skipping test: French locale is not installed\n", stderr); + return 77; + } + + return 0; +#else + fputs ("Skipping test: uselocale() not available\n", stderr); + return 77; +#endif +} diff --git a/tests/test-nl_langinfo2.sh b/tests/test-nl_langinfo2.sh new file mode 100755 index 0000000000..6333c9006d --- /dev/null +++ b/tests/test-nl_langinfo2.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# The name of a specific traditional locale. +: "${LOCALE_FR=fr_FR}" + +# The name of a specific UTF-8 locale. +: "${LOCALE_FR_UTF8=fr_FR.UTF-8}" + +# Make them accessible as environment variables. +export LOCALE_FR LOCALE_FR_UTF8 + +${CHECKER} ./test-nl_langinfo2${EXEEXT} -- 2.39.5