Bump to 1.14.1
[platform/upstream/augeas.git] / tests / test-localename.c
1 /* Test of gl_locale_name function and its variants.
2    Copyright (C) 2007-2016 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         uselocale (LC_GLOBAL_LOCALE);
187         freelocale (locale);
188       }
189   }
190
191   /* Check that gl_locale_name distinguishes different categories of the
192      thread locale, and that the name is the right one for each.  */
193   {
194     unsigned int i;
195
196     for (i = 0; i < SIZEOF (categories); i++)
197       {
198         int category_mask = categories[i].mask;
199         locale_t loc = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
200         if (loc != NULL)
201           {
202             locale_t locale = newlocale (category_mask, "de_DE.UTF-8", loc);
203             if (locale == NULL)
204               freelocale (loc);
205             else
206               {
207                 unsigned int j;
208
209                 uselocale (locale);
210                 for (j = 0; j < SIZEOF (categories); j++)
211                   {
212                     const char *name_j =
213                       gl_locale_name (categories[j].cat, categories[j].string);
214                     if (j == i)
215                       ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
216                     else
217                       ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
218                   }
219                 uselocale (LC_GLOBAL_LOCALE);
220                 freelocale (locale);
221               }
222           }
223       }
224   }
225 #endif
226 }
227
228 /* Test the gl_locale_name_thread() function.  */
229 static void
230 test_locale_name_thread (void)
231 {
232   /* Get into a defined state,  */
233   setlocale (LC_ALL, "en_US.UTF-8");
234
235 #if HAVE_NEWLOCALE
236   /* Check that gl_locale_name_thread returns NULL when no thread locale is
237      set.  */
238   uselocale (LC_GLOBAL_LOCALE);
239   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
240   ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
241
242   /* Check that gl_locale_name_thread considers the thread locale.  */
243   {
244     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
245     if (locale != NULL)
246       {
247         const char *name;
248
249         uselocale (locale);
250         name = gl_locale_name_thread (LC_CTYPE, "LC_CTYPE");
251         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
252         name = gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES");
253         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
254         uselocale (LC_GLOBAL_LOCALE);
255         freelocale (locale);
256       }
257   }
258
259   /* Check that gl_locale_name_thread distinguishes different categories of the
260      thread locale, and that the name is the right one for each.  */
261   {
262     unsigned int i;
263
264     for (i = 0; i < SIZEOF (categories); i++)
265       {
266         int category_mask = categories[i].mask;
267         locale_t loc = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
268         if (loc != NULL)
269           {
270             locale_t locale = newlocale (category_mask, "de_DE.UTF-8", loc);
271             if (locale == NULL)
272               freelocale (loc);
273             else
274               {
275                 unsigned int j;
276
277                 uselocale (locale);
278                 for (j = 0; j < SIZEOF (categories); j++)
279                   {
280                     const char *name_j =
281                       gl_locale_name_thread (categories[j].cat,
282                                              categories[j].string);
283                     if (j == i)
284                       ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
285                     else
286                       ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
287                   }
288                 uselocale (LC_GLOBAL_LOCALE);
289                 freelocale (locale);
290               }
291           }
292       }
293   }
294
295   /* Check that gl_locale_name_thread returns a string that is allocated with
296      indefinite extent.  */
297   {
298     /* Try many locale names in turn, in order to defeat possible caches.  */
299     static const char * const choices[] =
300       {
301         "C",
302         "POSIX",
303         "af_ZA",
304         "af_ZA.UTF-8",
305         "am_ET",
306         "am_ET.UTF-8",
307         "be_BY",
308         "be_BY.UTF-8",
309         "bg_BG",
310         "bg_BG.UTF-8",
311         "ca_ES",
312         "ca_ES.UTF-8",
313         "cs_CZ",
314         "cs_CZ.UTF-8",
315         "da_DK",
316         "da_DK.UTF-8",
317         "de_AT",
318         "de_AT.UTF-8",
319         "de_CH",
320         "de_CH.UTF-8",
321         "de_DE",
322         "de_DE.UTF-8",
323         "el_GR",
324         "el_GR.UTF-8",
325         "en_AU",
326         "en_AU.UTF-8",
327         "en_CA",
328         "en_CA.UTF-8",
329         "en_GB",
330         "en_GB.UTF-8",
331         "en_IE",
332         "en_IE.UTF-8",
333         "en_NZ",
334         "en_NZ.UTF-8",
335         "en_US",
336         "en_US.UTF-8",
337         "es_ES",
338         "es_ES.UTF-8",
339         "et_EE",
340         "et_EE.UTF-8",
341         "eu_ES",
342         "eu_ES.UTF-8",
343         "fi_FI",
344         "fi_FI.UTF-8",
345         "fr_BE",
346         "fr_BE.UTF-8",
347         "fr_CA",
348         "fr_CA.UTF-8",
349         "fr_CH",
350         "fr_CH.UTF-8",
351         "fr_FR",
352         "fr_FR.UTF-8",
353         "he_IL",
354         "he_IL.UTF-8",
355         "hr_HR",
356         "hr_HR.UTF-8",
357         "hu_HU",
358         "hu_HU.UTF-8",
359         "hy_AM",
360         "is_IS",
361         "is_IS.UTF-8",
362         "it_CH",
363         "it_CH.UTF-8",
364         "it_IT",
365         "it_IT.UTF-8",
366         "ja_JP.UTF-8",
367         "kk_KZ",
368         "kk_KZ.UTF-8",
369         "ko_KR.UTF-8",
370         "lt_LT",
371         "lt_LT.UTF-8",
372         "nl_BE",
373         "nl_BE.UTF-8",
374         "nl_NL",
375         "nl_NL.UTF-8",
376         "no_NO",
377         "no_NO.UTF-8",
378         "pl_PL",
379         "pl_PL.UTF-8",
380         "pt_BR",
381         "pt_BR.UTF-8",
382         "pt_PT",
383         "pt_PT.UTF-8",
384         "ro_RO",
385         "ro_RO.UTF-8",
386         "ru_RU",
387         "ru_RU.UTF-8",
388         "sk_SK",
389         "sk_SK.UTF-8",
390         "sl_SI",
391         "sl_SI.UTF-8",
392         "sv_SE",
393         "sv_SE.UTF-8",
394         "tr_TR",
395         "tr_TR.UTF-8",
396         "uk_UA",
397         "uk_UA.UTF-8",
398         "zh_CN",
399         "zh_CN.UTF-8",
400         "zh_HK",
401         "zh_HK.UTF-8",
402         "zh_TW",
403         "zh_TW.UTF-8"
404       };
405     /* Remember which locales are available.  */
406     unsigned char /* bool */ available[SIZEOF (choices)];
407     /* Array of remembered results of gl_locale_name_thread.  */
408     const char *unsaved_names[SIZEOF (choices)][SIZEOF (categories)];
409     /* Array of remembered results of gl_locale_name_thread, stored in safe
410        memory.  */
411     char *saved_names[SIZEOF (choices)][SIZEOF (categories)];
412     unsigned int j;
413
414     for (j = 0; j < SIZEOF (choices); j++)
415       {
416         locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
417         available[j] = (locale != NULL);
418         if (locale != NULL)
419           {
420             unsigned int i;
421
422             uselocale (locale);
423             for (i = 0; i < SIZEOF (categories); i++)
424               {
425                 unsaved_names[j][i] = gl_locale_name_thread (categories[i].cat, categories[i].string);
426                 saved_names[j][i] = strdup (unsaved_names[j][i]);
427               }
428             uselocale (LC_GLOBAL_LOCALE);
429             freelocale (locale);
430           }
431       }
432     /* Verify the unsaved_names are still valid.  */
433     for (j = 0; j < SIZEOF (choices); j++)
434       if (available[j])
435         {
436           unsigned int i;
437
438           for (i = 0; i < SIZEOF (categories); i++)
439             ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
440         }
441     /* Allocate many locales, without freeing them.  This is an attempt at
442        overwriting as much of the previously allocated memory as possible.  */
443     for (j = SIZEOF (choices); j > 0; )
444       {
445         j--;
446         if (available[j])
447           {
448             locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
449             unsigned int i;
450
451             ASSERT (locale != NULL);
452             uselocale (locale);
453             for (i = 0; i < SIZEOF (categories); i++)
454               {
455                 const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string);
456                 ASSERT (strcmp (unsaved_names[j][i], name) == 0);
457               }
458             uselocale (LC_GLOBAL_LOCALE);
459             freelocale (locale);
460           }
461       }
462     /* Verify the unsaved_names are still valid.  */
463     for (j = 0; j < SIZEOF (choices); j++)
464       if (available[j])
465         {
466           unsigned int i;
467
468           for (i = 0; i < SIZEOF (categories); i++)
469             {
470               ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
471               free (saved_names[j][i]);
472             }
473         }
474   }
475 #else
476   /* Check that gl_locale_name_thread always returns NULL.  */
477   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
478   ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
479 #endif
480 }
481
482 /* Test the gl_locale_name_posix() function.  */
483 static void
484 test_locale_name_posix (void)
485 {
486   const char *name;
487
488   /* Get into a defined state,  */
489   setlocale (LC_ALL, "en_US.UTF-8");
490 #if HAVE_NEWLOCALE
491   uselocale (LC_GLOBAL_LOCALE);
492 #endif
493
494   /* Check that when all environment variables are unset,
495      gl_locale_name_posix returns either NULL or the default locale.  */
496   unsetenv ("LC_ALL");
497   unsetenv ("LC_CTYPE");
498   unsetenv ("LC_MESSAGES");
499   unsetenv ("LC_NUMERIC");
500   unsetenv ("LANG");
501   setlocale (LC_ALL, "");
502   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
503   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
504   name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
505   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
506
507   /* Check that an empty environment variable is treated like an unset
508      environment variable.  */
509
510   setenv ("LC_ALL", "", 1);
511   unsetenv ("LC_CTYPE");
512   unsetenv ("LC_MESSAGES");
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   setenv ("LC_CTYPE", "", 1);
520   unsetenv ("LC_MESSAGES");
521   unsetenv ("LANG");
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   unsetenv ("LC_ALL");
527   unsetenv ("LC_CTYPE");
528   setenv ("LC_MESSAGES", "", 1);
529   unsetenv ("LANG");
530   setlocale (LC_ALL, "");
531   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
532   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
533
534   unsetenv ("LC_ALL");
535   unsetenv ("LC_CTYPE");
536   unsetenv ("LC_MESSAGES");
537   setenv ("LANG", "", 1);
538   setlocale (LC_ALL, "");
539   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
540   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
541
542   /* Check that LC_ALL overrides the others, and LANG is overridden by the
543      others.  */
544
545   setenv ("LC_ALL", "C", 1);
546   unsetenv ("LC_CTYPE");
547   unsetenv ("LC_MESSAGES");
548   unsetenv ("LANG");
549   setlocale (LC_ALL, "");
550   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
551   ASSERT (strcmp (name, "C") == 0);
552
553   unsetenv ("LC_ALL");
554   setenv ("LC_CTYPE", "C", 1);
555   setenv ("LC_MESSAGES", "C", 1);
556   unsetenv ("LANG");
557   setlocale (LC_ALL, "");
558   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
559   ASSERT (strcmp (name, "C") == 0);
560
561   unsetenv ("LC_ALL");
562   unsetenv ("LC_CTYPE");
563   unsetenv ("LC_MESSAGES");
564   setenv ("LANG", "C", 1);
565   setlocale (LC_ALL, "");
566   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
567   ASSERT (strcmp (name, "C") == 0);
568
569   /* Check mixed situations.  */
570
571   unsetenv ("LC_ALL");
572   unsetenv ("LC_CTYPE");
573   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
574   setenv ("LANG", "de_DE.UTF-8", 1);
575   if (setlocale (LC_ALL, "") != NULL)
576     {
577       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
578       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
579       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
580       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
581     }
582
583   unsetenv ("LC_ALL");
584   unsetenv ("LC_CTYPE");
585   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
586   unsetenv ("LANG");
587   if (setlocale (LC_ALL, "") != NULL)
588     {
589       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
590       ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
591       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
592       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
593     }
594
595 #if HAVE_NEWLOCALE
596   /* Check that gl_locale_name_posix ignores the thread locale.  */
597   {
598     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
599     if (locale != NULL)
600       {
601         unsetenv ("LC_ALL");
602         unsetenv ("LC_CTYPE");
603         unsetenv ("LC_MESSAGES");
604         setenv ("LANG", "C", 1);
605         setlocale (LC_ALL, "");
606         uselocale (locale);
607         name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
608         ASSERT (strcmp (name, "C") == 0);
609         uselocale (LC_GLOBAL_LOCALE);
610         freelocale (locale);
611       }
612   }
613 #endif
614 }
615
616 /* Test the gl_locale_name_environ() function.  */
617 static void
618 test_locale_name_environ (void)
619 {
620   const char *name;
621
622   /* Get into a defined state,  */
623   setlocale (LC_ALL, "en_US.UTF-8");
624 #if HAVE_NEWLOCALE
625   uselocale (LC_GLOBAL_LOCALE);
626 #endif
627
628   /* Check that when all environment variables are unset,
629      gl_locale_name_environ returns NULL.  */
630   unsetenv ("LC_ALL");
631   unsetenv ("LC_CTYPE");
632   unsetenv ("LC_MESSAGES");
633   unsetenv ("LC_NUMERIC");
634   unsetenv ("LANG");
635   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
636   ASSERT (gl_locale_name_environ (LC_NUMERIC, "LC_NUMERIC") == NULL);
637
638   /* Check that an empty environment variable is treated like an unset
639      environment variable.  */
640
641   setenv ("LC_ALL", "", 1);
642   unsetenv ("LC_CTYPE");
643   unsetenv ("LC_MESSAGES");
644   unsetenv ("LANG");
645   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
646
647   unsetenv ("LC_ALL");
648   setenv ("LC_CTYPE", "", 1);
649   unsetenv ("LC_MESSAGES");
650   unsetenv ("LANG");
651   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
652
653   unsetenv ("LC_ALL");
654   unsetenv ("LC_CTYPE");
655   setenv ("LC_MESSAGES", "", 1);
656   unsetenv ("LANG");
657   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
658
659   unsetenv ("LC_ALL");
660   unsetenv ("LC_CTYPE");
661   unsetenv ("LC_MESSAGES");
662   setenv ("LANG", "", 1);
663   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
664
665   /* Check that LC_ALL overrides the others, and LANG is overridden by the
666      others.  */
667
668   setenv ("LC_ALL", "C", 1);
669   unsetenv ("LC_CTYPE");
670   unsetenv ("LC_MESSAGES");
671   unsetenv ("LANG");
672   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
673   ASSERT (strcmp (name, "C") == 0);
674
675   unsetenv ("LC_ALL");
676   setenv ("LC_CTYPE", "C", 1);
677   setenv ("LC_MESSAGES", "C", 1);
678   unsetenv ("LANG");
679   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
680   ASSERT (strcmp (name, "C") == 0);
681
682   unsetenv ("LC_ALL");
683   unsetenv ("LC_CTYPE");
684   unsetenv ("LC_MESSAGES");
685   setenv ("LANG", "C", 1);
686   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
687   ASSERT (strcmp (name, "C") == 0);
688
689   /* Check mixed situations.  */
690
691   unsetenv ("LC_ALL");
692   unsetenv ("LC_CTYPE");
693   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
694   setenv ("LANG", "de_DE.UTF-8", 1);
695   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
696   ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
697   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
698   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
699
700   unsetenv ("LC_ALL");
701   unsetenv ("LC_CTYPE");
702   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
703   unsetenv ("LANG");
704   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
705   ASSERT (name == NULL);
706   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
707   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
708
709 #if HAVE_NEWLOCALE
710   /* Check that gl_locale_name_environ ignores the thread locale.  */
711   {
712     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
713     if (locale != NULL)
714       {
715         unsetenv ("LC_ALL");
716         unsetenv ("LC_CTYPE");
717         unsetenv ("LC_MESSAGES");
718         setenv ("LANG", "C", 1);
719         setlocale (LC_ALL, "");
720         uselocale (locale);
721         name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
722         ASSERT (strcmp (name, "C") == 0);
723         uselocale (LC_GLOBAL_LOCALE);
724         freelocale (locale);
725       }
726   }
727 #endif
728 }
729
730 /* Test the gl_locale_name_default() function.  */
731 static void
732 test_locale_name_default (void)
733 {
734   const char *name = gl_locale_name_default ();
735
736   ASSERT (name != NULL);
737
738   /* Only Mac OS X and Windows have a facility for the user to set the default
739      locale.  */
740 #if !((defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __WIN32__ || defined __CYGWIN__))
741   ASSERT (strcmp (name, "C") == 0);
742 #endif
743
744 #if HAVE_NEWLOCALE
745   /* Check that gl_locale_name_default ignores the thread locale.  */
746   {
747     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
748     if (locale != NULL)
749       {
750         uselocale (locale);
751         ASSERT (strcmp (gl_locale_name_default (), name) == 0);
752         uselocale (LC_GLOBAL_LOCALE);
753         freelocale (locale);
754       }
755   }
756 #endif
757 }
758
759 int
760 main ()
761 {
762   test_locale_name ();
763   test_locale_name_thread ();
764   test_locale_name_posix ();
765   test_locale_name_environ ();
766   test_locale_name_default ();
767
768   return 0;
769 }