LCOV - code coverage report
Current view: top level - lib/gltests - test-localename.c (source / functions) Hit Total Coverage
Test: GNU Libidn Lines: 289 365 79.2 %
Date: 2020-07-22 17:53:13 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13