maint.mk: Update system header list for #include syntax checks.
[gnulib.git] / tests / test-localename.c
blob0e64ce6a949180feebebd05a975054eaf76dde7a
1 /* Test of gl_locale_name function and its variants.
2 Copyright (C) 2007-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. */
19 #include <config.h>
21 #include "localename.h"
23 #include <locale.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #include "macros.h"
29 #if HAVE_WORKING_NEWLOCALE && HAVE_WORKING_USELOCALE && !HAVE_FAKE_LOCALES
30 # define HAVE_GOOD_USELOCALE 1
31 #endif
33 #ifdef __HAIKU__
34 /* Work around Haiku bug <https://dev.haiku-os.org/ticket/18344>. */
35 # define freelocale(loc) ((void) (loc))
36 #endif
38 /* Suppress GCC false positive. */
39 #if __GNUC__ >= 12
40 # pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
41 #endif
43 /* The name that setlocale(,NULL) returns for the "C" locale. */
44 #ifdef __HAIKU__
45 # define C_CANONICALIZED "POSIX"
46 #else
47 # define C_CANONICALIZED "C"
48 #endif
50 static int
51 is_default (const char *name)
53 return strcmp (name, gl_locale_name_default ()) == 0
54 || (strcmp (name, C_CANONICALIZED) == 0
55 && strcmp (gl_locale_name_default (), "C") == 0)
56 #if MUSL_LIBC
57 || (strcmp (name, "C.UTF-8") == 0
58 && strcmp (gl_locale_name_default (), "C") == 0)
59 #endif
63 #if HAVE_GOOD_USELOCALE
65 static struct { int cat; int mask; const char *string; } const categories[] =
67 { LC_CTYPE, LC_CTYPE_MASK, "LC_CTYPE" },
68 { LC_NUMERIC, LC_NUMERIC_MASK, "LC_NUMERIC" },
69 { LC_TIME, LC_TIME_MASK, "LC_TIME" },
70 { LC_COLLATE, LC_COLLATE_MASK, "LC_COLLATE" },
71 { LC_MONETARY, LC_MONETARY_MASK, "LC_MONETARY" },
72 { LC_MESSAGES, LC_MESSAGES_MASK, "LC_MESSAGES" }
73 # ifdef LC_PAPER
74 , { LC_PAPER, LC_PAPER_MASK, "LC_PAPER" }
75 # endif
76 # ifdef LC_NAME
77 , { LC_NAME, LC_NAME_MASK, "LC_NAME" }
78 # endif
79 # ifdef LC_ADDRESS
80 , { LC_ADDRESS, LC_ADDRESS_MASK, "LC_ADDRESS" }
81 # endif
82 # ifdef LC_TELEPHONE
83 , { LC_TELEPHONE, LC_TELEPHONE_MASK, "LC_TELEPHONE" }
84 # endif
85 # ifdef LC_MEASUREMENT
86 , { LC_MEASUREMENT, LC_MEASUREMENT_MASK, "LC_MEASUREMENT" }
87 # endif
88 # ifdef LC_IDENTIFICATION
89 , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK, "LC_IDENTIFICATION" }
90 # endif
93 #endif
95 /* Test the gl_locale_name() function. */
96 static void
97 test_locale_name (void)
99 const char *ret;
100 const char *name;
102 /* Check that gl_locale_name returns non-NULL. */
103 ASSERT (gl_locale_name (LC_MESSAGES, "LC_MESSAGES") != NULL);
105 /* Get into a defined state, */
106 setlocale (LC_ALL, "en_US.UTF-8");
107 #if HAVE_GOOD_USELOCALE
108 uselocale (LC_GLOBAL_LOCALE);
109 #endif
111 /* Check that when all environment variables are unset,
112 gl_locale_name returns the default locale. */
113 unsetenv ("LC_ALL");
114 unsetenv ("LC_CTYPE");
115 unsetenv ("LC_MESSAGES");
116 unsetenv ("LC_NUMERIC");
117 unsetenv ("LANG");
118 /* Need also to unset all environment variables that specify standard or
119 non-standard locale categories. Otherwise, on glibc systems, when some
120 of these variables are set and reference a nonexistent locale, the
121 setlocale (LC_ALL, "") call below would fail. */
122 unsetenv ("LC_COLLATE");
123 unsetenv ("LC_MONETARY");
124 unsetenv ("LC_TIME");
125 unsetenv ("LC_ADDRESS");
126 unsetenv ("LC_IDENTIFICATION");
127 unsetenv ("LC_MEASUREMENT");
128 unsetenv ("LC_NAME");
129 unsetenv ("LC_PAPER");
130 unsetenv ("LC_TELEPHONE");
131 ret = setlocale (LC_ALL, "");
132 ASSERT (ret != NULL);
133 ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
134 ASSERT (is_default (gl_locale_name (LC_NUMERIC, "LC_NUMERIC")));
136 /* Check that an empty environment variable is treated like an unset
137 environment variable. */
139 setenv ("LC_ALL", "", 1);
140 unsetenv ("LC_CTYPE");
141 unsetenv ("LC_MESSAGES");
142 unsetenv ("LANG");
143 setlocale (LC_ALL, "");
144 ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
146 unsetenv ("LC_ALL");
147 setenv ("LC_CTYPE", "", 1);
148 unsetenv ("LC_MESSAGES");
149 unsetenv ("LANG");
150 setlocale (LC_ALL, "");
151 ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
153 unsetenv ("LC_ALL");
154 unsetenv ("LC_CTYPE");
155 setenv ("LC_MESSAGES", "", 1);
156 unsetenv ("LANG");
157 setlocale (LC_ALL, "");
158 ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
160 unsetenv ("LC_ALL");
161 unsetenv ("LC_CTYPE");
162 unsetenv ("LC_MESSAGES");
163 setenv ("LANG", "", 1);
164 setlocale (LC_ALL, "");
165 ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
167 /* Check that LC_ALL overrides the others, and LANG is overridden by the
168 others. */
170 setenv ("LC_ALL", "C", 1);
171 unsetenv ("LC_CTYPE");
172 unsetenv ("LC_MESSAGES");
173 unsetenv ("LANG");
174 setlocale (LC_ALL, "");
175 ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
176 C_CANONICALIZED) == 0);
178 unsetenv ("LC_ALL");
179 setenv ("LC_CTYPE", "C", 1);
180 setenv ("LC_MESSAGES", "C", 1);
181 unsetenv ("LANG");
182 setlocale (LC_ALL, "");
183 ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
184 C_CANONICALIZED) == 0);
186 unsetenv ("LC_ALL");
187 unsetenv ("LC_CTYPE");
188 unsetenv ("LC_MESSAGES");
189 setenv ("LANG", "C", 1);
190 setlocale (LC_ALL, "");
191 ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
192 C_CANONICALIZED) == 0);
194 /* Check mixed situations. */
196 unsetenv ("LC_ALL");
197 unsetenv ("LC_CTYPE");
198 setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
199 setenv ("LANG", "de_DE.UTF-8", 1);
200 if (setlocale (LC_ALL, "") != NULL)
202 name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
203 #if defined _WIN32 && !defined __CYGWIN__
204 /* On native Windows, here,
205 gl_locale_name_thread (LC_CTYPE, "LC_CTYPE")
206 returns NULL and
207 gl_locale_name_posix (LC_CTYPE, "LC_CTYPE")
208 returns either "de_DE" or "de_DE.UTF-8". */
209 ASSERT (strcmp (name, "de_DE") == 0 || strcmp (name, "de_DE.UTF-8") == 0);
210 #else
211 ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
212 #endif
213 name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
214 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
217 unsetenv ("LC_ALL");
218 unsetenv ("LC_CTYPE");
219 setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
220 unsetenv ("LANG");
221 if (setlocale (LC_ALL, "") != NULL)
223 name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
224 ASSERT (is_default (name));
225 name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
226 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
229 #if HAVE_GOOD_USELOCALE
230 /* Check that gl_locale_name considers the thread locale. */
232 locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
233 if (locale != NULL)
235 uselocale (locale);
236 name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
237 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
238 name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
239 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
240 uselocale (LC_GLOBAL_LOCALE);
241 freelocale (locale);
245 /* Check that gl_locale_name distinguishes different categories of the
246 thread locale, and that the name is the right one for each. */
248 unsigned int i;
250 for (i = 0; i < SIZEOF (categories); i++)
252 int category_mask = categories[i].mask;
253 locale_t loc = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
254 if (loc != NULL)
256 locale_t locale = newlocale (category_mask, "de_DE.UTF-8", loc);
257 if (locale == NULL)
258 freelocale (loc);
259 else
261 unsigned int j;
263 uselocale (locale);
264 for (j = 0; j < SIZEOF (categories); j++)
266 const char *name_j =
267 gl_locale_name (categories[j].cat, categories[j].string);
268 if (j == i)
269 ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
270 else
271 ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
273 uselocale (LC_GLOBAL_LOCALE);
274 freelocale (locale);
279 #endif
282 /* Test the gl_locale_name_thread() function. */
283 static void
284 test_locale_name_thread (void)
286 /* Get into a defined state, */
287 setlocale (LC_ALL, "en_US.UTF-8");
289 #if HAVE_GOOD_USELOCALE
290 /* Check that gl_locale_name_thread returns NULL when no thread locale is
291 set. */
292 uselocale (LC_GLOBAL_LOCALE);
293 ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
294 ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
296 /* Check that gl_locale_name_thread considers the thread locale. */
298 locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
299 if (locale != NULL)
301 const char *name;
303 uselocale (locale);
304 name = gl_locale_name_thread (LC_CTYPE, "LC_CTYPE");
305 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
306 name = gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES");
307 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
308 uselocale (LC_GLOBAL_LOCALE);
309 freelocale (locale);
313 /* Check that gl_locale_name_thread distinguishes different categories of the
314 thread locale, and that the name is the right one for each. */
316 unsigned int i;
318 for (i = 0; i < SIZEOF (categories); i++)
320 int category_mask = categories[i].mask;
321 locale_t loc = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
322 if (loc != NULL)
324 locale_t locale = newlocale (category_mask, "de_DE.UTF-8", loc);
325 if (locale == NULL)
326 freelocale (loc);
327 else
329 unsigned int j;
331 uselocale (locale);
332 for (j = 0; j < SIZEOF (categories); j++)
334 const char *name_j =
335 gl_locale_name_thread (categories[j].cat,
336 categories[j].string);
337 if (j == i)
338 ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
339 else
340 ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
342 uselocale (LC_GLOBAL_LOCALE);
343 freelocale (locale);
349 /* Check that gl_locale_name_thread returns a string that is allocated with
350 indefinite extent. */
352 /* Try many locale names in turn, in order to defeat possible caches. */
353 static const char * const choices[] =
355 "C",
356 "POSIX",
357 "af_ZA",
358 "af_ZA.UTF-8",
359 "am_ET",
360 "am_ET.UTF-8",
361 "be_BY",
362 "be_BY.UTF-8",
363 "bg_BG",
364 "bg_BG.UTF-8",
365 "ca_ES",
366 "ca_ES.UTF-8",
367 "cs_CZ",
368 "cs_CZ.UTF-8",
369 "da_DK",
370 "da_DK.UTF-8",
371 "de_AT",
372 "de_AT.UTF-8",
373 "de_CH",
374 "de_CH.UTF-8",
375 "de_DE",
376 "de_DE.UTF-8",
377 "el_GR",
378 "el_GR.UTF-8",
379 "en_AU",
380 "en_AU.UTF-8",
381 "en_CA",
382 "en_CA.UTF-8",
383 "en_GB",
384 "en_GB.UTF-8",
385 "en_IE",
386 "en_IE.UTF-8",
387 "en_NZ",
388 "en_NZ.UTF-8",
389 "en_US",
390 "en_US.UTF-8",
391 "es_ES",
392 "es_ES.UTF-8",
393 "et_EE",
394 "et_EE.UTF-8",
395 "eu_ES",
396 "eu_ES.UTF-8",
397 "fi_FI",
398 "fi_FI.UTF-8",
399 "fr_BE",
400 "fr_BE.UTF-8",
401 "fr_CA",
402 "fr_CA.UTF-8",
403 "fr_CH",
404 "fr_CH.UTF-8",
405 "fr_FR",
406 "fr_FR.UTF-8",
407 "he_IL",
408 "he_IL.UTF-8",
409 "hr_HR",
410 "hr_HR.UTF-8",
411 "hu_HU",
412 "hu_HU.UTF-8",
413 "hy_AM",
414 "is_IS",
415 "is_IS.UTF-8",
416 "it_CH",
417 "it_CH.UTF-8",
418 "it_IT",
419 "it_IT.UTF-8",
420 "ja_JP.UTF-8",
421 "kk_KZ",
422 "kk_KZ.UTF-8",
423 "ko_KR.UTF-8",
424 "lt_LT",
425 "lt_LT.UTF-8",
426 "nl_BE",
427 "nl_BE.UTF-8",
428 "nl_NL",
429 "nl_NL.UTF-8",
430 "no_NO",
431 "no_NO.UTF-8",
432 "pl_PL",
433 "pl_PL.UTF-8",
434 "pt_BR",
435 "pt_BR.UTF-8",
436 "pt_PT",
437 "pt_PT.UTF-8",
438 "ro_RO",
439 "ro_RO.UTF-8",
440 "ru_RU",
441 "ru_RU.UTF-8",
442 "sk_SK",
443 "sk_SK.UTF-8",
444 "sl_SI",
445 "sl_SI.UTF-8",
446 "sv_SE",
447 "sv_SE.UTF-8",
448 "tr_TR",
449 "tr_TR.UTF-8",
450 "uk_UA",
451 "uk_UA.UTF-8",
452 "zh_CN",
453 "zh_CN.UTF-8",
454 "zh_HK",
455 "zh_HK.UTF-8",
456 "zh_TW",
457 "zh_TW.UTF-8"
459 /* Remember which locales are available. */
460 unsigned char /* bool */ available[SIZEOF (choices)];
461 /* Array of remembered results of gl_locale_name_thread. */
462 const char *unsaved_names[SIZEOF (choices)][SIZEOF (categories)];
463 /* Array of remembered results of gl_locale_name_thread, stored in safe
464 memory. */
465 char *saved_names[SIZEOF (choices)][SIZEOF (categories)];
466 unsigned int j;
468 for (j = 0; j < SIZEOF (choices); j++)
470 locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
471 available[j] = (locale != NULL);
472 if (locale != NULL)
474 unsigned int i;
476 uselocale (locale);
477 for (i = 0; i < SIZEOF (categories); i++)
479 unsaved_names[j][i] = gl_locale_name_thread (categories[i].cat, categories[i].string);
480 saved_names[j][i] = strdup (unsaved_names[j][i]);
482 uselocale (LC_GLOBAL_LOCALE);
483 freelocale (locale);
486 /* Verify the unsaved_names are still valid. */
487 for (j = 0; j < SIZEOF (choices); j++)
488 if (available[j])
490 unsigned int i;
492 for (i = 0; i < SIZEOF (categories); i++)
493 ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
495 /* Allocate many locales, without freeing them. This is an attempt at
496 overwriting as much of the previously allocated memory as possible. */
497 for (j = SIZEOF (choices); j > 0; )
499 j--;
500 if (available[j])
502 locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
503 unsigned int i;
505 ASSERT (locale != NULL);
506 uselocale (locale);
507 for (i = 0; i < SIZEOF (categories); i++)
509 const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string);
510 ASSERT (strcmp (unsaved_names[j][i], name) == 0);
512 uselocale (LC_GLOBAL_LOCALE);
513 freelocale (locale);
516 /* Verify the unsaved_names are still valid. */
517 for (j = 0; j < SIZEOF (choices); j++)
518 if (available[j])
520 unsigned int i;
522 for (i = 0; i < SIZEOF (categories); i++)
524 ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
525 free (saved_names[j][i]);
529 #else
530 /* Check that gl_locale_name_thread always returns NULL. */
531 ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
532 ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
533 #endif
536 /* Test the gl_locale_name_posix() function. */
537 static void
538 test_locale_name_posix (void)
540 const char *ret;
541 const char *name;
543 /* Get into a defined state, */
544 setlocale (LC_ALL, "en_US.UTF-8");
545 #if HAVE_GOOD_USELOCALE
546 uselocale (LC_GLOBAL_LOCALE);
547 #endif
549 /* Check that when all environment variables are unset,
550 gl_locale_name_posix returns either NULL or the default locale. */
551 unsetenv ("LC_ALL");
552 unsetenv ("LC_CTYPE");
553 unsetenv ("LC_MESSAGES");
554 unsetenv ("LC_NUMERIC");
555 unsetenv ("LANG");
556 /* Need also to unset all environment variables that specify standard or
557 non-standard locale categories. Otherwise, on glibc systems, when some
558 of these variables are set and reference a nonexistent locale, the
559 setlocale (LC_ALL, "") call below would fail. */
560 unsetenv ("LC_COLLATE");
561 unsetenv ("LC_MONETARY");
562 unsetenv ("LC_TIME");
563 unsetenv ("LC_ADDRESS");
564 unsetenv ("LC_IDENTIFICATION");
565 unsetenv ("LC_MEASUREMENT");
566 unsetenv ("LC_NAME");
567 unsetenv ("LC_PAPER");
568 unsetenv ("LC_TELEPHONE");
569 ret = setlocale (LC_ALL, "");
570 ASSERT (ret != NULL);
571 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
572 ASSERT (name == NULL || is_default (name));
573 name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
574 ASSERT (name == NULL || is_default (name));
576 /* Check that an empty environment variable is treated like an unset
577 environment variable. */
579 setenv ("LC_ALL", "", 1);
580 unsetenv ("LC_CTYPE");
581 unsetenv ("LC_MESSAGES");
582 unsetenv ("LANG");
583 setlocale (LC_ALL, "");
584 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
585 ASSERT (name == NULL || is_default (name));
587 unsetenv ("LC_ALL");
588 setenv ("LC_CTYPE", "", 1);
589 unsetenv ("LC_MESSAGES");
590 unsetenv ("LANG");
591 setlocale (LC_ALL, "");
592 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
593 ASSERT (name == NULL || is_default (name));
595 unsetenv ("LC_ALL");
596 unsetenv ("LC_CTYPE");
597 setenv ("LC_MESSAGES", "", 1);
598 unsetenv ("LANG");
599 setlocale (LC_ALL, "");
600 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
601 ASSERT (name == NULL || is_default (name));
603 unsetenv ("LC_ALL");
604 unsetenv ("LC_CTYPE");
605 unsetenv ("LC_MESSAGES");
606 setenv ("LANG", "", 1);
607 setlocale (LC_ALL, "");
608 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
609 ASSERT (name == NULL || is_default (name));
611 /* Check that LC_ALL overrides the others, and LANG is overridden by the
612 others. */
614 setenv ("LC_ALL", "C", 1);
615 unsetenv ("LC_CTYPE");
616 unsetenv ("LC_MESSAGES");
617 unsetenv ("LANG");
618 setlocale (LC_ALL, "");
619 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
620 ASSERT (strcmp (name, C_CANONICALIZED) == 0);
622 unsetenv ("LC_ALL");
623 setenv ("LC_CTYPE", "C", 1);
624 setenv ("LC_MESSAGES", "C", 1);
625 unsetenv ("LANG");
626 setlocale (LC_ALL, "");
627 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
628 ASSERT (strcmp (name, C_CANONICALIZED) == 0);
630 unsetenv ("LC_ALL");
631 unsetenv ("LC_CTYPE");
632 unsetenv ("LC_MESSAGES");
633 setenv ("LANG", "C", 1);
634 setlocale (LC_ALL, "");
635 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
636 ASSERT (strcmp (name, C_CANONICALIZED) == 0);
638 /* Check mixed situations. */
640 unsetenv ("LC_ALL");
641 unsetenv ("LC_CTYPE");
642 setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
643 setenv ("LANG", "de_DE.UTF-8", 1);
644 if (setlocale (LC_ALL, "") != NULL)
646 name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
647 #if defined _WIN32 && !defined __CYGWIN__
648 ASSERT (strcmp (name, "de_DE") == 0 || strcmp (name, "de_DE.UTF-8") == 0);
649 #else
650 ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
651 #endif
652 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
653 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
656 unsetenv ("LC_ALL");
657 unsetenv ("LC_CTYPE");
658 setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
659 unsetenv ("LANG");
660 if (setlocale (LC_ALL, "") != NULL)
662 name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
663 ASSERT (name == NULL || is_default (name));
664 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
665 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
668 #if HAVE_GOOD_USELOCALE
669 /* Check that gl_locale_name_posix ignores the thread locale. */
671 locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
672 if (locale != NULL)
674 unsetenv ("LC_ALL");
675 unsetenv ("LC_CTYPE");
676 unsetenv ("LC_MESSAGES");
677 setenv ("LANG", "C", 1);
678 setlocale (LC_ALL, "");
679 uselocale (locale);
680 name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
681 ASSERT (strcmp (name, C_CANONICALIZED) == 0);
682 uselocale (LC_GLOBAL_LOCALE);
683 freelocale (locale);
686 #endif
689 /* Test the gl_locale_name_environ() function. */
690 static void
691 test_locale_name_environ (void)
693 const char *name;
695 /* Get into a defined state, */
696 setlocale (LC_ALL, "en_US.UTF-8");
697 #if HAVE_GOOD_USELOCALE
698 uselocale (LC_GLOBAL_LOCALE);
699 #endif
701 /* Check that when all environment variables are unset,
702 gl_locale_name_environ returns NULL. */
703 unsetenv ("LC_ALL");
704 unsetenv ("LC_CTYPE");
705 unsetenv ("LC_MESSAGES");
706 unsetenv ("LC_NUMERIC");
707 unsetenv ("LANG");
708 ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
709 ASSERT (gl_locale_name_environ (LC_NUMERIC, "LC_NUMERIC") == NULL);
711 /* Check that an empty environment variable is treated like an unset
712 environment variable. */
714 setenv ("LC_ALL", "", 1);
715 unsetenv ("LC_CTYPE");
716 unsetenv ("LC_MESSAGES");
717 unsetenv ("LANG");
718 ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
720 unsetenv ("LC_ALL");
721 setenv ("LC_CTYPE", "", 1);
722 unsetenv ("LC_MESSAGES");
723 unsetenv ("LANG");
724 ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
726 unsetenv ("LC_ALL");
727 unsetenv ("LC_CTYPE");
728 setenv ("LC_MESSAGES", "", 1);
729 unsetenv ("LANG");
730 ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
732 unsetenv ("LC_ALL");
733 unsetenv ("LC_CTYPE");
734 unsetenv ("LC_MESSAGES");
735 setenv ("LANG", "", 1);
736 ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
738 /* Check that LC_ALL overrides the others, and LANG is overridden by the
739 others. */
741 setenv ("LC_ALL", "C", 1);
742 unsetenv ("LC_CTYPE");
743 unsetenv ("LC_MESSAGES");
744 unsetenv ("LANG");
745 name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
746 ASSERT (strcmp (name, "C") == 0);
748 unsetenv ("LC_ALL");
749 setenv ("LC_CTYPE", "C", 1);
750 setenv ("LC_MESSAGES", "C", 1);
751 unsetenv ("LANG");
752 name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
753 ASSERT (strcmp (name, "C") == 0);
755 unsetenv ("LC_ALL");
756 unsetenv ("LC_CTYPE");
757 unsetenv ("LC_MESSAGES");
758 setenv ("LANG", "C", 1);
759 name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
760 ASSERT (strcmp (name, "C") == 0);
762 /* Check mixed situations. */
764 unsetenv ("LC_ALL");
765 unsetenv ("LC_CTYPE");
766 setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
767 setenv ("LANG", "de_DE.UTF-8", 1);
768 name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
769 ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
770 name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
771 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
773 unsetenv ("LC_ALL");
774 unsetenv ("LC_CTYPE");
775 setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
776 unsetenv ("LANG");
777 name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
778 ASSERT (name == NULL);
779 name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
780 ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
782 #if HAVE_GOOD_USELOCALE
783 /* Check that gl_locale_name_environ ignores the thread locale. */
785 locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
786 if (locale != NULL)
788 unsetenv ("LC_ALL");
789 unsetenv ("LC_CTYPE");
790 unsetenv ("LC_MESSAGES");
791 setenv ("LANG", "C", 1);
792 setlocale (LC_ALL, "");
793 uselocale (locale);
794 name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
795 ASSERT (strcmp (name, "C") == 0);
796 uselocale (LC_GLOBAL_LOCALE);
797 freelocale (locale);
800 #endif
803 /* Test the gl_locale_name_default() function. */
804 static void
805 test_locale_name_default (void)
807 const char *name = gl_locale_name_default ();
809 ASSERT (name != NULL);
811 /* Only Mac OS X and Windows have a facility for the user to set the default
812 locale. */
813 #if !((defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __CYGWIN__))
814 ASSERT (strcmp (name, "C") == 0);
815 #endif
817 #if HAVE_GOOD_USELOCALE
818 /* Check that gl_locale_name_default ignores the thread locale. */
820 locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
821 if (locale != NULL)
823 uselocale (locale);
824 ASSERT (strcmp (gl_locale_name_default (), name) == 0);
825 uselocale (LC_GLOBAL_LOCALE);
826 freelocale (locale);
829 #endif
833 main ()
835 test_locale_name ();
836 test_locale_name_thread ();
837 test_locale_name_posix ();
838 test_locale_name_environ ();
839 test_locale_name_default ();
841 return test_exit_status;