1 /* Test of nl_langinfo replacement.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2023. */
27 #include "c-strcase.h"
28 #include "c-strcasestr.h"
32 main (int argc
, char *argv
[])
34 #if HAVE_WORKING_USELOCALE
35 /* Check that nl_langinfo() uses the per-thread locale. */
37 bool skipped_all
= true;
39 /* Extract a few items from the C locale. */
40 /* nl_langinfo items of the LC_CTYPE category */
41 const char *c_CODESET
= nl_langinfo (CODESET
);
42 /* nl_langinfo items of the LC_NUMERIC category */
43 const char *c_RADIXCHAR
= nl_langinfo (RADIXCHAR
);
44 /* nl_langinfo items of the LC_TIME category */
45 const char *c_T_FMT_AMPM
= nl_langinfo (T_FMT_AMPM
);
46 const char *c_AM_STR
= nl_langinfo (AM_STR
);
47 const char *c_PM_STR
= nl_langinfo (PM_STR
);
48 /* nl_langinfo items of the LC_MONETARY category */
49 const char *c_CRNCYSTR
= nl_langinfo (CRNCYSTR
);
50 /* nl_langinfo items of the LC_MESSAGES category */
51 const char *c_YESEXPR
= nl_langinfo (YESEXPR
);
55 ASSERT (strcmp (c_RADIXCHAR
, ".") == 0);
56 ASSERT (strlen (c_T_FMT_AMPM
) > 0);
57 ASSERT (strlen (c_AM_STR
) > 0);
58 ASSERT (strlen (c_PM_STR
) > 0);
59 ASSERT (strlen (c_CRNCYSTR
) <= 1); /* "-", "+", ".", or "" */
60 ASSERT (c_strcasestr (c_YESEXPR
, "y" /* from "yes" */) != NULL
);
62 for (pass
= 1; pass
<= 2; pass
++)
65 1 traditional French locale
68 const char *fr_locale_name
=
69 getenv (pass
== 1 ? "LOCALE_FR" : "LOCALE_FR_UTF8");
70 if (strcmp (fr_locale_name
, "none") != 0)
72 /* Use a per-thread locale. */
73 locale_t fr_locale
= newlocale (LC_ALL_MASK
, fr_locale_name
, NULL
);
74 if (fr_locale
!= NULL
)
76 uselocale (fr_locale
);
78 /* Extract a few items from the current locale, and check the
81 /* nl_langinfo items of the LC_CTYPE category */
82 const char *fr_CODESET
= nl_langinfo (CODESET
);
84 ASSERT (strstr (fr_CODESET
, "8859") != NULL
);
86 ASSERT (c_strcasecmp (fr_CODESET
, "UTF-8") == 0
87 || c_strcasecmp (fr_CODESET
, "UTF8") == 0);
89 /* In musl libc, locales differ at most in the LC_MESSAGES
91 #if !defined MUSL_LIBC
93 /* nl_langinfo items of the LC_NUMERIC category */
94 const char *fr_RADIXCHAR
= nl_langinfo (RADIXCHAR
);
95 ASSERT (strcmp (fr_RADIXCHAR
, ",") == 0);
97 /* nl_langinfo items of the LC_TIME category */
98 /* macOS and Solaris 11 don't get the LC_TIME values right.
100 #if !((defined __APPLE__ && defined __MACH__) || defined __sun)
101 const char *fr_T_FMT_AMPM
= nl_langinfo (T_FMT_AMPM
);
102 const char *fr_AM_STR
= nl_langinfo (AM_STR
);
103 const char *fr_PM_STR
= nl_langinfo (PM_STR
);
104 ASSERT (strlen (fr_T_FMT_AMPM
) == 0
105 || strcmp (fr_T_FMT_AMPM
, "%I:%M:%S") == 0);
106 ASSERT (strlen (fr_AM_STR
) == 0);
107 ASSERT (strlen (fr_PM_STR
) == 0);
110 /* nl_langinfo items of the LC_MONETARY category */
111 /* macOS doesn't get the EUR currency symbol or abbreviation
113 #if !(defined __APPLE__ && defined __MACH__)
114 const char *fr_CRNCYSTR
= nl_langinfo (CRNCYSTR
);
116 ASSERT (strlen (fr_CRNCYSTR
) >= 1
117 && strcmp (fr_CRNCYSTR
+ 1, "€") == 0);
122 /* nl_langinfo items of the LC_MESSAGES category */
123 /* In musl libc, this works only if the package 'musl-locales' is
125 #if !defined MUSL_LIBC
126 const char *fr_YESEXPR
= nl_langinfo (YESEXPR
);
127 ASSERT (c_strcasestr (fr_YESEXPR
, "o" /* from "oui" */) != NULL
);
137 if (test_exit_status
!= EXIT_SUCCESS
)
138 return test_exit_status
;
139 fputs ("Skipping test: French locale is not installed\n", stderr
);
143 return test_exit_status
;
145 fputs ("Skipping test: uselocale() not available\n", stderr
);