1 /* Test of duplicating a locale object.
2 Copyright (C) 2009-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>, 2007. */
23 #if HAVE_WORKING_DUPLOCALE
25 #include "signature.h"
26 SIGNATURE_CHECK (duplocale
, locale_t
, (locale_t
));
30 # include <monetary.h>
37 struct locale_dependent_values
47 get_locale_dependent_values (struct locale_dependent_values
*result
)
50 strfmon (result
->monetary
, sizeof (result
->monetary
),
52 /* result->monetary is usually "$123.75" */
54 snprintf (result
->numeric
, sizeof (result
->numeric
),
56 /* result->numeric is usually "3,5" */
57 strncpy (result
->time
, nl_langinfo (MON_1
), sizeof result
->time
- 1);
58 result
->time
[sizeof result
->time
- 1] = '\0';
59 /* result->time is usually "janvier" */
62 #if HAVE_WORKING_USELOCALE
65 test_with_uselocale (void)
67 struct locale_dependent_values expected_results
;
72 /* Set up a locale which is a mix between different system locales. */
73 setlocale (LC_ALL
, "en_US.UTF-8");
74 setlocale (LC_NUMERIC
, "de_DE.UTF-8");
75 setlocale (LC_TIME
, "fr_FR.UTF-8");
76 get_locale_dependent_values (&expected_results
);
78 /* Save the locale in a locale_t object. */
79 mixed1
= duplocale (LC_GLOBAL_LOCALE
);
80 ASSERT (mixed1
!= NULL
);
82 /* Use a per-thread locale. */
83 perthread
= newlocale (LC_ALL_MASK
, "es_ES.UTF-8", NULL
);
84 if (perthread
== NULL
)
86 uselocale (perthread
);
88 /* Save the locale in a locale_t object again. */
89 mixed2
= duplocale (LC_GLOBAL_LOCALE
);
90 ASSERT (mixed2
!= NULL
);
92 /* Set up a default locale. */
93 setlocale (LC_ALL
, "C");
94 uselocale (LC_GLOBAL_LOCALE
);
96 struct locale_dependent_values c_results
;
97 get_locale_dependent_values (&c_results
);
100 /* Now use the saved locale mixed1 again. */
101 setlocale (LC_ALL
, "C");
102 uselocale (LC_GLOBAL_LOCALE
);
105 struct locale_dependent_values results
;
106 get_locale_dependent_values (&results
);
108 ASSERT (strcmp (results
.monetary
, expected_results
.monetary
) == 0);
110 ASSERT (strcmp (results
.numeric
, expected_results
.numeric
) == 0);
111 ASSERT (strcmp (results
.time
, expected_results
.time
) == 0);
114 /* Now use the saved locale mixed2 again. */
115 setlocale (LC_ALL
, "C");
116 uselocale (LC_GLOBAL_LOCALE
);
119 struct locale_dependent_values results
;
120 get_locale_dependent_values (&results
);
122 ASSERT (strcmp (results
.monetary
, expected_results
.monetary
) == 0);
124 ASSERT (strcmp (results
.numeric
, expected_results
.numeric
) == 0);
125 ASSERT (strcmp (results
.time
, expected_results
.time
) == 0);
128 setlocale (LC_ALL
, "C");
129 uselocale (LC_GLOBAL_LOCALE
);
132 freelocale (perthread
);
138 #if HAVE_STRFMON_L || HAVE_SNPRINTF_L || (HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE)
141 get_locale_dependent_values_from (struct locale_dependent_values
*result
, locale_t locale
)
144 strfmon_l (result
->monetary
, sizeof (result
->monetary
), locale
,
146 /* result->monetary is usually "$123.75" */
149 snprintf_l (result
->numeric
, sizeof (result
->numeric
), locale
,
151 /* result->numeric is usually "3,5" */
153 #if HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE
154 strcpy (result
->time
, nl_langinfo_l (MON_1
, locale
));
155 /* result->time is usually "janvier" */
160 test_with_locale_parameter (void)
162 struct locale_dependent_values expected_results
;
166 /* Set up a locale which is a mix between different system locales. */
167 setlocale (LC_ALL
, "en_US.UTF-8");
168 setlocale (LC_NUMERIC
, "de_DE.UTF-8");
169 setlocale (LC_TIME
, "fr_FR.UTF-8");
170 get_locale_dependent_values (&expected_results
);
172 /* Save the locale in a locale_t object. */
173 mixed1
= duplocale (LC_GLOBAL_LOCALE
);
174 ASSERT (mixed1
!= NULL
);
176 /* Create another locale_t object. */
177 mixed2
= newlocale (LC_ALL_MASK
, "es_ES.UTF-8", NULL
);
181 /* Set up a default locale. */
182 setlocale (LC_ALL
, "C");
184 struct locale_dependent_values c_results
;
185 get_locale_dependent_values (&c_results
);
188 /* Now use the saved locale mixed2. */
190 struct locale_dependent_values results
;
191 get_locale_dependent_values_from (&results
, mixed2
);
194 /* Now use the saved locale mixed1 again. */
196 struct locale_dependent_values results
;
197 get_locale_dependent_values_from (&results
, mixed1
);
199 ASSERT (strcmp (results
.monetary
, expected_results
.monetary
) == 0);
202 ASSERT (strcmp (results
.numeric
, expected_results
.numeric
) == 0);
204 #if HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE
205 ASSERT (strcmp (results
.time
, expected_results
.time
) == 0);
220 #if HAVE_WORKING_USELOCALE
221 skipped
|= test_with_uselocale ();
223 #if HAVE_STRFMON_L || HAVE_SNPRINTF_L || (HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE)
224 skipped
|= test_with_locale_parameter ();
229 if (test_exit_status
!= EXIT_SUCCESS
)
230 return test_exit_status
;
231 fprintf (stderr
, "Skipping test: Spanish Unicode locale is not installed\n");
235 return test_exit_status
;
245 fprintf (stderr
, "Skipping test: function duplocale not available\n");