maint: update copyright
[gnulib.git] / tests / test-localename.c
1 /* Test of gl_locale_name function and its variants.
2    Copyright (C) 2007-2014 Free Software Foundation, Inc.
3
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.
8
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.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18
19 #include <config.h>
20
21 #include "localename.h"
22
23 #include <locale.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "macros.h"
28
29
30 #if HAVE_NEWLOCALE
31
32 static struct { int cat; int mask; const char *string; } const categories[] =
33   {
34       { LC_CTYPE,          LC_CTYPE_MASK,          "LC_CTYPE" },
35       { LC_NUMERIC,        LC_NUMERIC_MASK,        "LC_NUMERIC" },
36       { LC_TIME,           LC_TIME_MASK,           "LC_TIME" },
37       { LC_COLLATE,        LC_COLLATE_MASK,        "LC_COLLATE" },
38       { LC_MONETARY,       LC_MONETARY_MASK,       "LC_MONETARY" },
39       { LC_MESSAGES,       LC_MESSAGES_MASK,       "LC_MESSAGES" }
40 # ifdef LC_PAPER
41     , { LC_PAPER,          LC_PAPER_MASK,          "LC_PAPER" }
42 # endif
43 # ifdef LC_NAME
44     , { LC_NAME,           LC_NAME_MASK,           "LC_NAME" }
45 # endif
46 # ifdef LC_ADDRESS
47     , { LC_ADDRESS,        LC_ADDRESS_MASK,        "LC_ADDRESS" }
48 # endif
49 # ifdef LC_TELEPHONE
50     , { LC_TELEPHONE,      LC_TELEPHONE_MASK,      "LC_TELEPHONE" }
51 # endif
52 # ifdef LC_MEASUREMENT
53     , { LC_MEASUREMENT,    LC_MEASUREMENT_MASK,    "LC_MEASUREMENT" }
54 # endif
55 # ifdef LC_IDENTIFICATION
56     , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK, "LC_IDENTIFICATION" }
57 # endif
58   };
59
60 #endif
61
62 /* Test the gl_locale_name() function.  */
63 static void
64 test_locale_name (void)
65 {
66   const char *name;
67
68   /* Check that gl_locale_name returns non-NULL.  */
69   ASSERT (gl_locale_name (LC_MESSAGES, "LC_MESSAGES") != NULL);
70
71   /* Get into a defined state,  */
72   setlocale (LC_ALL, "en_US.UTF-8");
73 #if HAVE_NEWLOCALE
74   uselocale (LC_GLOBAL_LOCALE);
75 #endif
76
77   /* Check that when all environment variables are unset,
78      gl_locale_name returns the default locale.  */
79   unsetenv ("LC_ALL");
80   unsetenv ("LC_CTYPE");
81   unsetenv ("LC_MESSAGES");
82   unsetenv ("LC_NUMERIC");
83   unsetenv ("LANG");
84   setlocale (LC_ALL, "");
85   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
86                   gl_locale_name_default ()) == 0);
87   ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
88                   gl_locale_name_default ()) == 0);
89
90   /* Check that an empty environment variable is treated like an unset
91      environment variable.  */
92
93   setenv ("LC_ALL", "", 1);
94   unsetenv ("LC_CTYPE");
95   unsetenv ("LC_MESSAGES");
96   unsetenv ("LANG");
97   setlocale (LC_ALL, "");
98   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
99                   gl_locale_name_default ()) == 0);
100
101   unsetenv ("LC_ALL");
102   setenv ("LC_CTYPE", "", 1);
103   unsetenv ("LC_MESSAGES");
104   unsetenv ("LANG");
105   setlocale (LC_ALL, "");
106   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
107                   gl_locale_name_default ()) == 0);
108
109   unsetenv ("LC_ALL");
110   unsetenv ("LC_CTYPE");
111   setenv ("LC_MESSAGES", "", 1);
112   unsetenv ("LANG");
113   setlocale (LC_ALL, "");
114   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
115                   gl_locale_name_default ()) == 0);
116
117   unsetenv ("LC_ALL");
118   unsetenv ("LC_CTYPE");
119   unsetenv ("LC_MESSAGES");
120   setenv ("LANG", "", 1);
121   setlocale (LC_ALL, "");
122   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
123                   gl_locale_name_default ()) == 0);
124
125   /* Check that LC_ALL overrides the others, and LANG is overridden by the
126      others.  */
127
128   setenv ("LC_ALL", "C", 1);
129   unsetenv ("LC_CTYPE");
130   unsetenv ("LC_MESSAGES");
131   unsetenv ("LANG");
132   setlocale (LC_ALL, "");
133   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
134
135   unsetenv ("LC_ALL");
136   setenv ("LC_CTYPE", "C", 1);
137   setenv ("LC_MESSAGES", "C", 1);
138   unsetenv ("LANG");
139   setlocale (LC_ALL, "");
140   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
141
142   unsetenv ("LC_ALL");
143   unsetenv ("LC_CTYPE");
144   unsetenv ("LC_MESSAGES");
145   setenv ("LANG", "C", 1);
146   setlocale (LC_ALL, "");
147   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
148
149   /* Check mixed situations.  */
150
151   unsetenv ("LC_ALL");
152   unsetenv ("LC_CTYPE");
153   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
154   setenv ("LANG", "de_DE.UTF-8", 1);
155   if (setlocale (LC_ALL, "") != NULL)
156     {
157       name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
158       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
159       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
160       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
161     }
162
163   unsetenv ("LC_ALL");
164   unsetenv ("LC_CTYPE");
165   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
166   unsetenv ("LANG");
167   if (setlocale (LC_ALL, "") != NULL)
168     {
169       name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
170       ASSERT (strcmp (name, gl_locale_name_default ()) == 0);
171       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
172       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
173     }
174
175 #if HAVE_NEWLOCALE
176   /* Check that gl_locale_name considers the thread locale.  */
177   {
178     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
179     if (locale != NULL)
180       {
181         uselocale (locale);
182         name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
183         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
184         name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
185         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
186       }
187   }
188
189   /* Check that gl_locale_name distinguishes different categories of the
190      thread locale, and that the name is the right one for each.  */
191   {
192     unsigned int i;
193
194     for (i = 0; i < SIZEOF (categories); i++)
195       {
196         int category_mask = categories[i].mask;
197         locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
198         if (locale != NULL)
199           {
200             locale = newlocale (category_mask, "de_DE.UTF-8", locale);
201             if (locale != NULL)
202               {
203                 unsigned int j;
204
205                 uselocale (locale);
206                 for (j = 0; j < SIZEOF (categories); j++)
207                   {
208                     const char *name_j =
209                       gl_locale_name (categories[j].cat, categories[j].string);
210                     if (j == i)
211                       ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
212                     else
213                       ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
214                   }
215               }
216           }
217       }
218   }
219 #endif
220 }
221
222 /* Test the gl_locale_name_thread() function.  */
223 static void
224 test_locale_name_thread (void)
225 {
226   /* Get into a defined state,  */
227   setlocale (LC_ALL, "en_US.UTF-8");
228
229 #if HAVE_NEWLOCALE
230   /* Check that gl_locale_name_thread returns NULL when no thread locale is
231      set.  */
232   uselocale (LC_GLOBAL_LOCALE);
233   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
234   ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
235
236   /* Check that gl_locale_name_thread considers the thread locale.  */
237   {
238     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
239     if (locale != NULL)
240       {
241         const char *name;
242
243         uselocale (locale);
244         name = gl_locale_name_thread (LC_CTYPE, "LC_CTYPE");
245         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
246         name = gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES");
247         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
248       }
249   }
250
251   /* Check that gl_locale_name_thread distinguishes different categories of the
252      thread locale, and that the name is the right one for each.  */
253   {
254     unsigned int i;
255
256     for (i = 0; i < SIZEOF (categories); i++)
257       {
258         int category_mask = categories[i].mask;
259         locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
260         if (locale != NULL)
261           {
262             locale = newlocale (category_mask, "de_DE.UTF-8", locale);
263             if (locale != NULL)
264               {
265                 unsigned int j;
266
267                 uselocale (locale);
268                 for (j = 0; j < SIZEOF (categories); j++)
269                   {
270                     const char *name_j =
271                       gl_locale_name_thread (categories[j].cat,
272                                              categories[j].string);
273                     if (j == i)
274                       ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
275                     else
276                       ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
277                   }
278               }
279           }
280       }
281   }
282
283   /* Check that gl_locale_name_thread returns a string that is allocated with
284      indefinite extent.  */
285   {
286     /* Try many locale names in turn, in order to defeat possible caches.  */
287     static const char * const choices[] =
288       {
289         "C",
290         "POSIX",
291         "af_ZA",
292         "af_ZA.UTF-8",
293         "am_ET",
294         "am_ET.UTF-8",
295         "be_BY",
296         "be_BY.UTF-8",
297         "bg_BG",
298         "bg_BG.UTF-8",
299         "ca_ES",
300         "ca_ES.UTF-8",
301         "cs_CZ",
302         "cs_CZ.UTF-8",
303         "da_DK",
304         "da_DK.UTF-8",
305         "de_AT",
306         "de_AT.UTF-8",
307         "de_CH",
308         "de_CH.UTF-8",
309         "de_DE",
310         "de_DE.UTF-8",
311         "el_GR",
312         "el_GR.UTF-8",
313         "en_AU",
314         "en_AU.UTF-8",
315         "en_CA",
316         "en_CA.UTF-8",
317         "en_GB",
318         "en_GB.UTF-8",
319         "en_IE",
320         "en_IE.UTF-8",
321         "en_NZ",
322         "en_NZ.UTF-8",
323         "en_US",
324         "en_US.UTF-8",
325         "es_ES",
326         "es_ES.UTF-8",
327         "et_EE",
328         "et_EE.UTF-8",
329         "eu_ES",
330         "eu_ES.UTF-8",
331         "fi_FI",
332         "fi_FI.UTF-8",
333         "fr_BE",
334         "fr_BE.UTF-8",
335         "fr_CA",
336         "fr_CA.UTF-8",
337         "fr_CH",
338         "fr_CH.UTF-8",
339         "fr_FR",
340         "fr_FR.UTF-8",
341         "he_IL",
342         "he_IL.UTF-8",
343         "hr_HR",
344         "hr_HR.UTF-8",
345         "hu_HU",
346         "hu_HU.UTF-8",
347         "hy_AM",
348         "is_IS",
349         "is_IS.UTF-8",
350         "it_CH",
351         "it_CH.UTF-8",
352         "it_IT",
353         "it_IT.UTF-8",
354         "ja_JP.UTF-8",
355         "kk_KZ",
356         "kk_KZ.UTF-8",
357         "ko_KR.UTF-8",
358         "lt_LT",
359         "lt_LT.UTF-8",
360         "nl_BE",
361         "nl_BE.UTF-8",
362         "nl_NL",
363         "nl_NL.UTF-8",
364         "no_NO",
365         "no_NO.UTF-8",
366         "pl_PL",
367         "pl_PL.UTF-8",
368         "pt_BR",
369         "pt_BR.UTF-8",
370         "pt_PT",
371         "pt_PT.UTF-8",
372         "ro_RO",
373         "ro_RO.UTF-8",
374         "ru_RU",
375         "ru_RU.UTF-8",
376         "sk_SK",
377         "sk_SK.UTF-8",
378         "sl_SI",
379         "sl_SI.UTF-8",
380         "sv_SE",
381         "sv_SE.UTF-8",
382         "tr_TR",
383         "tr_TR.UTF-8",
384         "uk_UA",
385         "uk_UA.UTF-8",
386         "zh_CN",
387         "zh_CN.UTF-8",
388         "zh_HK",
389         "zh_HK.UTF-8",
390         "zh_TW",
391         "zh_TW.UTF-8"
392       };
393     /* Remember which locales are available.  */
394     unsigned char /* bool */ available[SIZEOF (choices)];
395     /* Array of remembered results of gl_locale_name_thread.  */
396     const char *unsaved_names[SIZEOF (choices)][SIZEOF (categories)];
397     /* Array of remembered results of gl_locale_name_thread, stored in safe
398        memory.  */
399     char *saved_names[SIZEOF (choices)][SIZEOF (categories)];
400     unsigned int j;
401
402     for (j = 0; j < SIZEOF (choices); j++)
403       {
404         locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
405         available[j] = (locale != NULL);
406         if (locale != NULL)
407           {
408             unsigned int i;
409
410             uselocale (locale);
411             for (i = 0; i < SIZEOF (categories); i++)
412               {
413                 unsaved_names[j][i] = gl_locale_name_thread (categories[i].cat, categories[i].string);
414                 saved_names[j][i] = strdup (unsaved_names[j][i]);
415               }
416             uselocale (LC_GLOBAL_LOCALE);
417             freelocale (locale);
418           }
419       }
420     /* Verify the unsaved_names are still valid.  */
421     for (j = 0; j < SIZEOF (choices); j++)
422       if (available[j])
423         {
424           unsigned int i;
425
426           for (i = 0; i < SIZEOF (categories); i++)
427             ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
428         }
429     /* Allocate many locales, without freeing them.  This is an attempt at
430        overwriting as much of the previously allocated memory as possible.  */
431     for (j = SIZEOF (choices); j > 0; )
432       {
433         j--;
434         if (available[j])
435           {
436             locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
437             unsigned int i;
438
439             ASSERT (locale != NULL);
440             uselocale (locale);
441             for (i = 0; i < SIZEOF (categories); i++)
442               {
443                 const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string);
444                 ASSERT (strcmp (unsaved_names[j][i], name) == 0);
445               }
446             uselocale (LC_GLOBAL_LOCALE);
447           }
448       }
449     /* Verify the unsaved_names are still valid.  */
450     for (j = 0; j < SIZEOF (choices); j++)
451       if (available[j])
452         {
453           unsigned int i;
454
455           for (i = 0; i < SIZEOF (categories); i++)
456             ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
457         }
458   }
459 #else
460   /* Check that gl_locale_name_thread always returns NULL.  */
461   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
462   ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
463 #endif
464 }
465
466 /* Test the gl_locale_name_posix() function.  */
467 static void
468 test_locale_name_posix (void)
469 {
470   const char *name;
471
472   /* Get into a defined state,  */
473   setlocale (LC_ALL, "en_US.UTF-8");
474 #if HAVE_NEWLOCALE
475   uselocale (LC_GLOBAL_LOCALE);
476 #endif
477
478   /* Check that when all environment variables are unset,
479      gl_locale_name_posix returns either NULL or the default locale.  */
480   unsetenv ("LC_ALL");
481   unsetenv ("LC_CTYPE");
482   unsetenv ("LC_MESSAGES");
483   unsetenv ("LC_NUMERIC");
484   unsetenv ("LANG");
485   setlocale (LC_ALL, "");
486   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
487   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
488   name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
489   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
490
491   /* Check that an empty environment variable is treated like an unset
492      environment variable.  */
493
494   setenv ("LC_ALL", "", 1);
495   unsetenv ("LC_CTYPE");
496   unsetenv ("LC_MESSAGES");
497   unsetenv ("LANG");
498   setlocale (LC_ALL, "");
499   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
500   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
501
502   unsetenv ("LC_ALL");
503   setenv ("LC_CTYPE", "", 1);
504   unsetenv ("LC_MESSAGES");
505   unsetenv ("LANG");
506   setlocale (LC_ALL, "");
507   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
508   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
509
510   unsetenv ("LC_ALL");
511   unsetenv ("LC_CTYPE");
512   setenv ("LC_MESSAGES", "", 1);
513   unsetenv ("LANG");
514   setlocale (LC_ALL, "");
515   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
516   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
517
518   unsetenv ("LC_ALL");
519   unsetenv ("LC_CTYPE");
520   unsetenv ("LC_MESSAGES");
521   setenv ("LANG", "", 1);
522   setlocale (LC_ALL, "");
523   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
524   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
525
526   /* Check that LC_ALL overrides the others, and LANG is overridden by the
527      others.  */
528
529   setenv ("LC_ALL", "C", 1);
530   unsetenv ("LC_CTYPE");
531   unsetenv ("LC_MESSAGES");
532   unsetenv ("LANG");
533   setlocale (LC_ALL, "");
534   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
535   ASSERT (strcmp (name, "C") == 0);
536
537   unsetenv ("LC_ALL");
538   setenv ("LC_CTYPE", "C", 1);
539   setenv ("LC_MESSAGES", "C", 1);
540   unsetenv ("LANG");
541   setlocale (LC_ALL, "");
542   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
543   ASSERT (strcmp (name, "C") == 0);
544
545   unsetenv ("LC_ALL");
546   unsetenv ("LC_CTYPE");
547   unsetenv ("LC_MESSAGES");
548   setenv ("LANG", "C", 1);
549   setlocale (LC_ALL, "");
550   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
551   ASSERT (strcmp (name, "C") == 0);
552
553   /* Check mixed situations.  */
554
555   unsetenv ("LC_ALL");
556   unsetenv ("LC_CTYPE");
557   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
558   setenv ("LANG", "de_DE.UTF-8", 1);
559   if (setlocale (LC_ALL, "") != NULL)
560     {
561       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
562       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
563       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
564       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
565     }
566
567   unsetenv ("LC_ALL");
568   unsetenv ("LC_CTYPE");
569   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
570   unsetenv ("LANG");
571   if (setlocale (LC_ALL, "") != NULL)
572     {
573       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
574       ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
575       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
576       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
577     }
578
579 #if HAVE_NEWLOCALE
580   /* Check that gl_locale_name_posix ignores the thread locale.  */
581   {
582     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
583     if (locale != NULL)
584       {
585         unsetenv ("LC_ALL");
586         unsetenv ("LC_CTYPE");
587         unsetenv ("LC_MESSAGES");
588         setenv ("LANG", "C", 1);
589         setlocale (LC_ALL, "");
590         uselocale (locale);
591         name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
592         ASSERT (strcmp (name, "C") == 0);
593       }
594   }
595 #endif
596 }
597
598 /* Test the gl_locale_name_environ() function.  */
599 static void
600 test_locale_name_environ (void)
601 {
602   const char *name;
603
604   /* Get into a defined state,  */
605   setlocale (LC_ALL, "en_US.UTF-8");
606 #if HAVE_NEWLOCALE
607   uselocale (LC_GLOBAL_LOCALE);
608 #endif
609
610   /* Check that when all environment variables are unset,
611      gl_locale_name_environ returns NULL.  */
612   unsetenv ("LC_ALL");
613   unsetenv ("LC_CTYPE");
614   unsetenv ("LC_MESSAGES");
615   unsetenv ("LC_NUMERIC");
616   unsetenv ("LANG");
617   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
618   ASSERT (gl_locale_name_environ (LC_NUMERIC, "LC_NUMERIC") == NULL);
619
620   /* Check that an empty environment variable is treated like an unset
621      environment variable.  */
622
623   setenv ("LC_ALL", "", 1);
624   unsetenv ("LC_CTYPE");
625   unsetenv ("LC_MESSAGES");
626   unsetenv ("LANG");
627   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
628
629   unsetenv ("LC_ALL");
630   setenv ("LC_CTYPE", "", 1);
631   unsetenv ("LC_MESSAGES");
632   unsetenv ("LANG");
633   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
634
635   unsetenv ("LC_ALL");
636   unsetenv ("LC_CTYPE");
637   setenv ("LC_MESSAGES", "", 1);
638   unsetenv ("LANG");
639   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
640
641   unsetenv ("LC_ALL");
642   unsetenv ("LC_CTYPE");
643   unsetenv ("LC_MESSAGES");
644   setenv ("LANG", "", 1);
645   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
646
647   /* Check that LC_ALL overrides the others, and LANG is overridden by the
648      others.  */
649
650   setenv ("LC_ALL", "C", 1);
651   unsetenv ("LC_CTYPE");
652   unsetenv ("LC_MESSAGES");
653   unsetenv ("LANG");
654   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
655   ASSERT (strcmp (name, "C") == 0);
656
657   unsetenv ("LC_ALL");
658   setenv ("LC_CTYPE", "C", 1);
659   setenv ("LC_MESSAGES", "C", 1);
660   unsetenv ("LANG");
661   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
662   ASSERT (strcmp (name, "C") == 0);
663
664   unsetenv ("LC_ALL");
665   unsetenv ("LC_CTYPE");
666   unsetenv ("LC_MESSAGES");
667   setenv ("LANG", "C", 1);
668   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
669   ASSERT (strcmp (name, "C") == 0);
670
671   /* Check mixed situations.  */
672
673   unsetenv ("LC_ALL");
674   unsetenv ("LC_CTYPE");
675   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
676   setenv ("LANG", "de_DE.UTF-8", 1);
677   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
678   ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
679   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
680   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
681
682   unsetenv ("LC_ALL");
683   unsetenv ("LC_CTYPE");
684   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
685   unsetenv ("LANG");
686   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
687   ASSERT (name == NULL);
688   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
689   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
690
691 #if HAVE_NEWLOCALE
692   /* Check that gl_locale_name_environ ignores the thread locale.  */
693   {
694     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
695     if (locale != NULL)
696       {
697         unsetenv ("LC_ALL");
698         unsetenv ("LC_CTYPE");
699         unsetenv ("LC_MESSAGES");
700         setenv ("LANG", "C", 1);
701         setlocale (LC_ALL, "");
702         uselocale (locale);
703         name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
704         ASSERT (strcmp (name, "C") == 0);
705       }
706   }
707 #endif
708 }
709
710 /* Test the gl_locale_name_default() function.  */
711 static void
712 test_locale_name_default (void)
713 {
714   const char *name = gl_locale_name_default ();
715
716   ASSERT (name != NULL);
717
718   /* Only Mac OS X and Windows have a facility for the user to set the default
719      locale.  */
720 #if !((defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __WIN32__ || defined __CYGWIN__))
721   ASSERT (strcmp (name, "C") == 0);
722 #endif
723
724 #if HAVE_NEWLOCALE
725   /* Check that gl_locale_name_default ignores the thread locale.  */
726   {
727     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
728     if (locale != NULL)
729       {
730         uselocale (locale);
731         ASSERT (strcmp (gl_locale_name_default (), name) == 0);
732       }
733   }
734 #endif
735 }
736
737 int
738 main ()
739 {
740   test_locale_name ();
741   test_locale_name_thread ();
742   test_locale_name_posix ();
743   test_locale_name_environ ();
744   test_locale_name_default ();
745
746   return 0;
747 }