Fix compilation error on most platforms.
[gnulib.git] / tests / test-localename.c
1 /* Test of gl_locale_name function and its variants.
2    Copyright (C) 2007-2009 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       {
423         unsigned int i;
424
425         for (i = 0; i < SIZEOF (categories); i++)
426           ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
427       }
428     /* Allocate many locales, without freeing them.  This is an attempt at
429        overwriting as much of the previously allocated memory as possible.  */
430     for (j = SIZEOF (choices); j > 0; )
431       {
432         j--;
433         if (available[j])
434           {
435             locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
436             unsigned int i;
437
438             ASSERT (locale != NULL);
439             uselocale (locale);
440             for (i = 0; i < SIZEOF (categories); i++)
441               {
442                 const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string);
443                 ASSERT (strcmp (unsaved_names[j][i], name) == 0);
444               }
445             uselocale (LC_GLOBAL_LOCALE);
446           }
447       }
448     /* Verify the unsaved_names are still valid.  */
449     for (j = 0; j < SIZEOF (choices); j++)
450       {
451         unsigned int i;
452
453         for (i = 0; i < SIZEOF (categories); i++)
454           ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
455       }
456   }
457 #else
458   /* Check that gl_locale_name_thread always returns NULL.  */
459   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
460   ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
461 #endif
462 }
463
464 /* Test the gl_locale_name_posix() function.  */
465 static void
466 test_locale_name_posix (void)
467 {
468   const char *name;
469
470   /* Get into a defined state,  */
471   setlocale (LC_ALL, "en_US.UTF-8");
472 #if HAVE_NEWLOCALE
473   uselocale (LC_GLOBAL_LOCALE);
474 #endif
475
476   /* Check that when all environment variables are unset,
477      gl_locale_name_posix returns either NULL or the default locale.  */
478   unsetenv ("LC_ALL");
479   unsetenv ("LC_CTYPE");
480   unsetenv ("LC_MESSAGES");
481   unsetenv ("LC_NUMERIC");
482   unsetenv ("LANG");
483   setlocale (LC_ALL, "");
484   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
485   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
486   name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
487   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
488
489   /* Check that an empty environment variable is treated like an unset
490      environment variable.  */
491
492   setenv ("LC_ALL", "", 1);
493   unsetenv ("LC_CTYPE");
494   unsetenv ("LC_MESSAGES");
495   unsetenv ("LANG");
496   setlocale (LC_ALL, "");
497   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
498   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
499
500   unsetenv ("LC_ALL");
501   setenv ("LC_CTYPE", "", 1);
502   unsetenv ("LC_MESSAGES");
503   unsetenv ("LANG");
504   setlocale (LC_ALL, "");
505   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
506   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
507
508   unsetenv ("LC_ALL");
509   unsetenv ("LC_CTYPE");
510   setenv ("LC_MESSAGES", "", 1);
511   unsetenv ("LANG");
512   setlocale (LC_ALL, "");
513   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
514   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
515
516   unsetenv ("LC_ALL");
517   unsetenv ("LC_CTYPE");
518   unsetenv ("LC_MESSAGES");
519   setenv ("LANG", "", 1);
520   setlocale (LC_ALL, "");
521   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
522   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
523
524   /* Check that LC_ALL overrides the others, and LANG is overridden by the
525      others.  */
526
527   setenv ("LC_ALL", "C", 1);
528   unsetenv ("LC_CTYPE");
529   unsetenv ("LC_MESSAGES");
530   unsetenv ("LANG");
531   setlocale (LC_ALL, "");
532   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
533   ASSERT (strcmp (name, "C") == 0);
534
535   unsetenv ("LC_ALL");
536   setenv ("LC_CTYPE", "C", 1);
537   setenv ("LC_MESSAGES", "C", 1);
538   unsetenv ("LANG");
539   setlocale (LC_ALL, "");
540   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
541   ASSERT (strcmp (name, "C") == 0);
542
543   unsetenv ("LC_ALL");
544   unsetenv ("LC_CTYPE");
545   unsetenv ("LC_MESSAGES");
546   setenv ("LANG", "C", 1);
547   setlocale (LC_ALL, "");
548   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
549   ASSERT (strcmp (name, "C") == 0);
550
551   /* Check mixed situations.  */
552
553   unsetenv ("LC_ALL");
554   unsetenv ("LC_CTYPE");
555   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
556   setenv ("LANG", "de_DE.UTF-8", 1);
557   if (setlocale (LC_ALL, "") != NULL)
558     {
559       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
560       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
561       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
562       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
563     }
564
565   unsetenv ("LC_ALL");
566   unsetenv ("LC_CTYPE");
567   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
568   unsetenv ("LANG");
569   if (setlocale (LC_ALL, "") != NULL)
570     {
571       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
572       ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
573       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
574       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
575     }
576
577 #if HAVE_NEWLOCALE
578   /* Check that gl_locale_name_posix ignores the thread locale.  */
579   {
580     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
581     if (locale != NULL)
582       {
583         unsetenv ("LC_ALL");
584         unsetenv ("LC_CTYPE");
585         unsetenv ("LC_MESSAGES");
586         setenv ("LANG", "C", 1);
587         setlocale (LC_ALL, "");
588         uselocale (locale);
589         name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
590         ASSERT (strcmp (name, "C") == 0);
591       }
592   }
593 #endif
594 }
595
596 /* Test the gl_locale_name_environ() function.  */
597 static void
598 test_locale_name_environ (void)
599 {
600   const char *name;
601
602   /* Get into a defined state,  */
603   setlocale (LC_ALL, "en_US.UTF-8");
604 #if HAVE_NEWLOCALE
605   uselocale (LC_GLOBAL_LOCALE);
606 #endif
607
608   /* Check that when all environment variables are unset,
609      gl_locale_name_environ returns NULL.  */
610   unsetenv ("LC_ALL");
611   unsetenv ("LC_CTYPE");
612   unsetenv ("LC_MESSAGES");
613   unsetenv ("LC_NUMERIC");
614   unsetenv ("LANG");
615   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
616   ASSERT (gl_locale_name_environ (LC_NUMERIC, "LC_NUMERIC") == NULL);
617
618   /* Check that an empty environment variable is treated like an unset
619      environment variable.  */
620
621   setenv ("LC_ALL", "", 1);
622   unsetenv ("LC_CTYPE");
623   unsetenv ("LC_MESSAGES");
624   unsetenv ("LANG");
625   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
626
627   unsetenv ("LC_ALL");
628   setenv ("LC_CTYPE", "", 1);
629   unsetenv ("LC_MESSAGES");
630   unsetenv ("LANG");
631   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
632
633   unsetenv ("LC_ALL");
634   unsetenv ("LC_CTYPE");
635   setenv ("LC_MESSAGES", "", 1);
636   unsetenv ("LANG");
637   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
638
639   unsetenv ("LC_ALL");
640   unsetenv ("LC_CTYPE");
641   unsetenv ("LC_MESSAGES");
642   setenv ("LANG", "", 1);
643   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
644
645   /* Check that LC_ALL overrides the others, and LANG is overridden by the
646      others.  */
647
648   setenv ("LC_ALL", "C", 1);
649   unsetenv ("LC_CTYPE");
650   unsetenv ("LC_MESSAGES");
651   unsetenv ("LANG");
652   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
653   ASSERT (strcmp (name, "C") == 0);
654
655   unsetenv ("LC_ALL");
656   setenv ("LC_CTYPE", "C", 1);
657   setenv ("LC_MESSAGES", "C", 1);
658   unsetenv ("LANG");
659   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
660   ASSERT (strcmp (name, "C") == 0);
661
662   unsetenv ("LC_ALL");
663   unsetenv ("LC_CTYPE");
664   unsetenv ("LC_MESSAGES");
665   setenv ("LANG", "C", 1);
666   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
667   ASSERT (strcmp (name, "C") == 0);
668
669   /* Check mixed situations.  */
670
671   unsetenv ("LC_ALL");
672   unsetenv ("LC_CTYPE");
673   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
674   setenv ("LANG", "de_DE.UTF-8", 1);
675   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
676   ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
677   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
678   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
679
680   unsetenv ("LC_ALL");
681   unsetenv ("LC_CTYPE");
682   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
683   unsetenv ("LANG");
684   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
685   ASSERT (name == NULL);
686   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
687   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
688
689 #if HAVE_NEWLOCALE
690   /* Check that gl_locale_name_environ ignores the thread locale.  */
691   {
692     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
693     if (locale != NULL)
694       {
695         unsetenv ("LC_ALL");
696         unsetenv ("LC_CTYPE");
697         unsetenv ("LC_MESSAGES");
698         setenv ("LANG", "C", 1);
699         setlocale (LC_ALL, "");
700         uselocale (locale);
701         name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
702         ASSERT (strcmp (name, "C") == 0);
703       }
704   }
705 #endif
706 }
707
708 /* Test the gl_locale_name_default() function.  */
709 static void
710 test_locale_name_default (void)
711 {
712   const char *name = gl_locale_name_default ();
713
714   ASSERT (name != NULL);
715
716   /* Only MacOS X and Windows have a facility for the user to set the default
717      locale.  */
718 #if !((defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __WIN32__ || defined __CYGWIN__))
719   ASSERT (strcmp (name, "C") == 0);
720 #endif
721
722 #if HAVE_NEWLOCALE
723   /* Check that gl_locale_name_default ignores the thread locale.  */
724   {
725     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
726     if (locale != NULL)
727       {
728         uselocale (locale);
729         ASSERT (strcmp (gl_locale_name_default (), name) == 0);
730       }
731   }
732 #endif
733 }
734
735 int
736 main ()
737 {
738   test_locale_name ();
739   test_locale_name_thread ();
740   test_locale_name_posix ();
741   test_locale_name_environ ();
742   test_locale_name_default ();
743
744   return 0;
745 }