"Fossies" - the Fresh Open Source Software Archive

Member "gnuastro-0.8/bootstrapped/tests/test-localename.c" (28 Dec 2018, 24617 Bytes) of package /linux/privat/gnuastro-0.8.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test-localename.c": 0.7_vs_0.8.

    1 /* Test of gl_locale_name function and its variants.
    2    Copyright (C) 2007-2018 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_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 test_locale_name (void)
   69 {
   70   const char *ret;
   71   const char *name;
   72 
   73   /* Check that gl_locale_name returns non-NULL.  */
   74   ASSERT (gl_locale_name (LC_MESSAGES, "LC_MESSAGES") != NULL);
   75 
   76   /* Get into a defined state,  */
   77   setlocale (LC_ALL, "en_US.UTF-8");
   78 #if HAVE_GOOD_USELOCALE
   79   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   unsetenv ("LC_ALL");
   85   unsetenv ("LC_CTYPE");
   86   unsetenv ("LC_MESSAGES");
   87   unsetenv ("LC_NUMERIC");
   88   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   unsetenv ("LC_COLLATE");
   94   unsetenv ("LC_MONETARY");
   95   unsetenv ("LC_TIME");
   96   unsetenv ("LC_ADDRESS");
   97   unsetenv ("LC_IDENTIFICATION");
   98   unsetenv ("LC_MEASUREMENT");
   99   unsetenv ("LC_NAME");
  100   unsetenv ("LC_PAPER");
  101   unsetenv ("LC_TELEPHONE");
  102   ret = setlocale (LC_ALL, "");
  103   ASSERT (ret != NULL);
  104   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
  105                   gl_locale_name_default ()) == 0);
  106   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   setenv ("LC_ALL", "", 1);
  113   unsetenv ("LC_CTYPE");
  114   unsetenv ("LC_MESSAGES");
  115   unsetenv ("LANG");
  116   setlocale (LC_ALL, "");
  117   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
  118                   gl_locale_name_default ()) == 0);
  119 
  120   unsetenv ("LC_ALL");
  121   setenv ("LC_CTYPE", "", 1);
  122   unsetenv ("LC_MESSAGES");
  123   unsetenv ("LANG");
  124   setlocale (LC_ALL, "");
  125   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
  126                   gl_locale_name_default ()) == 0);
  127 
  128   unsetenv ("LC_ALL");
  129   unsetenv ("LC_CTYPE");
  130   setenv ("LC_MESSAGES", "", 1);
  131   unsetenv ("LANG");
  132   setlocale (LC_ALL, "");
  133   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
  134                   gl_locale_name_default ()) == 0);
  135 
  136   unsetenv ("LC_ALL");
  137   unsetenv ("LC_CTYPE");
  138   unsetenv ("LC_MESSAGES");
  139   setenv ("LANG", "", 1);
  140   setlocale (LC_ALL, "");
  141   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   setenv ("LC_ALL", "C", 1);
  148   unsetenv ("LC_CTYPE");
  149   unsetenv ("LC_MESSAGES");
  150   unsetenv ("LANG");
  151   setlocale (LC_ALL, "");
  152   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
  153 
  154   unsetenv ("LC_ALL");
  155   setenv ("LC_CTYPE", "C", 1);
  156   setenv ("LC_MESSAGES", "C", 1);
  157   unsetenv ("LANG");
  158   setlocale (LC_ALL, "");
  159   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
  160 
  161   unsetenv ("LC_ALL");
  162   unsetenv ("LC_CTYPE");
  163   unsetenv ("LC_MESSAGES");
  164   setenv ("LANG", "C", 1);
  165   setlocale (LC_ALL, "");
  166   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
  167 
  168   /* Check mixed situations.  */
  169 
  170   unsetenv ("LC_ALL");
  171   unsetenv ("LC_CTYPE");
  172   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
  173   setenv ("LANG", "de_DE.UTF-8", 1);
  174   if (setlocale (LC_ALL, "") != NULL)
  175     {
  176       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       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
  186 #endif
  187       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
  188       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  189     }
  190 
  191   unsetenv ("LC_ALL");
  192   unsetenv ("LC_CTYPE");
  193   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
  194   unsetenv ("LANG");
  195   if (setlocale (LC_ALL, "") != NULL)
  196     {
  197       name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
  198       ASSERT (strcmp (name, gl_locale_name_default ()) == 0);
  199       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
  200       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     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  207     if (locale != NULL)
  208       {
  209         uselocale (locale);
  210         name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
  211         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  212         name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
  213         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  214         uselocale (LC_GLOBAL_LOCALE);
  215         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     for (i = 0; i < SIZEOF (categories); i++)
  225       {
  226         int category_mask = categories[i].mask;
  227         locale_t loc = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  228         if (loc != NULL)
  229           {
  230             locale_t locale = newlocale (category_mask, "de_DE.UTF-8", loc);
  231             if (locale == NULL)
  232               freelocale (loc);
  233             else
  234               {
  235                 unsigned int j;
  236 
  237                 uselocale (locale);
  238                 for (j = 0; j < SIZEOF (categories); j++)
  239                   {
  240                     const char *name_j =
  241                       gl_locale_name (categories[j].cat, categories[j].string);
  242                     if (j == i)
  243                       ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
  244                     else
  245                       ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
  246                   }
  247                 uselocale (LC_GLOBAL_LOCALE);
  248                 freelocale (locale);
  249               }
  250           }
  251       }
  252   }
  253 #endif
  254 }
  255 
  256 /* Test the gl_locale_name_thread() function.  */
  257 static void
  258 test_locale_name_thread (void)
  259 {
  260   /* Get into a defined state,  */
  261   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   uselocale (LC_GLOBAL_LOCALE);
  267   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
  268   ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
  269 
  270   /* Check that gl_locale_name_thread considers the thread locale.  */
  271   {
  272     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  273     if (locale != NULL)
  274       {
  275         const char *name;
  276 
  277         uselocale (locale);
  278         name = gl_locale_name_thread (LC_CTYPE, "LC_CTYPE");
  279         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  280         name = gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES");
  281         ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  282         uselocale (LC_GLOBAL_LOCALE);
  283         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     for (i = 0; i < SIZEOF (categories); i++)
  293       {
  294         int category_mask = categories[i].mask;
  295         locale_t loc = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  296         if (loc != NULL)
  297           {
  298             locale_t locale = newlocale (category_mask, "de_DE.UTF-8", loc);
  299             if (locale == NULL)
  300               freelocale (loc);
  301             else
  302               {
  303                 unsigned int j;
  304 
  305                 uselocale (locale);
  306                 for (j = 0; j < SIZEOF (categories); j++)
  307                   {
  308                     const char *name_j =
  309                       gl_locale_name_thread (categories[j].cat,
  310                                              categories[j].string);
  311                     if (j == i)
  312                       ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
  313                     else
  314                       ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
  315                   }
  316                 uselocale (LC_GLOBAL_LOCALE);
  317                 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     for (j = 0; j < SIZEOF (choices); j++)
  443       {
  444         locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
  445         available[j] = (locale != NULL);
  446         if (locale != NULL)
  447           {
  448             unsigned int i;
  449 
  450             uselocale (locale);
  451             for (i = 0; i < SIZEOF (categories); i++)
  452               {
  453                 unsaved_names[j][i] = gl_locale_name_thread (categories[i].cat, categories[i].string);
  454                 saved_names[j][i] = strdup (unsaved_names[j][i]);
  455               }
  456             uselocale (LC_GLOBAL_LOCALE);
  457             freelocale (locale);
  458           }
  459       }
  460     /* Verify the unsaved_names are still valid.  */
  461     for (j = 0; j < SIZEOF (choices); j++)
  462       if (available[j])
  463         {
  464           unsigned int i;
  465 
  466           for (i = 0; i < SIZEOF (categories); i++)
  467             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     for (j = SIZEOF (choices); j > 0; )
  472       {
  473         j--;
  474         if (available[j])
  475           {
  476             locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
  477             unsigned int i;
  478 
  479             ASSERT (locale != NULL);
  480             uselocale (locale);
  481             for (i = 0; i < SIZEOF (categories); i++)
  482               {
  483                 const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string);
  484                 ASSERT (strcmp (unsaved_names[j][i], name) == 0);
  485               }
  486             uselocale (LC_GLOBAL_LOCALE);
  487             freelocale (locale);
  488           }
  489       }
  490     /* Verify the unsaved_names are still valid.  */
  491     for (j = 0; j < SIZEOF (choices); j++)
  492       if (available[j])
  493         {
  494           unsigned int i;
  495 
  496           for (i = 0; i < SIZEOF (categories); i++)
  497             {
  498               ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
  499               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 }
  509 
  510 /* Test the gl_locale_name_posix() function.  */
  511 static void
  512 test_locale_name_posix (void)
  513 {
  514   const char *ret;
  515   const char *name;
  516 
  517   /* Get into a defined state,  */
  518   setlocale (LC_ALL, "en_US.UTF-8");
  519 #if HAVE_GOOD_USELOCALE
  520   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   unsetenv ("LC_ALL");
  526   unsetenv ("LC_CTYPE");
  527   unsetenv ("LC_MESSAGES");
  528   unsetenv ("LC_NUMERIC");
  529   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   unsetenv ("LC_COLLATE");
  535   unsetenv ("LC_MONETARY");
  536   unsetenv ("LC_TIME");
  537   unsetenv ("LC_ADDRESS");
  538   unsetenv ("LC_IDENTIFICATION");
  539   unsetenv ("LC_MEASUREMENT");
  540   unsetenv ("LC_NAME");
  541   unsetenv ("LC_PAPER");
  542   unsetenv ("LC_TELEPHONE");
  543   ret = setlocale (LC_ALL, "");
  544   ASSERT (ret != NULL);
  545   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  546   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
  547   name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
  548   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   setenv ("LC_ALL", "", 1);
  554   unsetenv ("LC_CTYPE");
  555   unsetenv ("LC_MESSAGES");
  556   unsetenv ("LANG");
  557   setlocale (LC_ALL, "");
  558   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  559   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
  560 
  561   unsetenv ("LC_ALL");
  562   setenv ("LC_CTYPE", "", 1);
  563   unsetenv ("LC_MESSAGES");
  564   unsetenv ("LANG");
  565   setlocale (LC_ALL, "");
  566   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  567   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
  568 
  569   unsetenv ("LC_ALL");
  570   unsetenv ("LC_CTYPE");
  571   setenv ("LC_MESSAGES", "", 1);
  572   unsetenv ("LANG");
  573   setlocale (LC_ALL, "");
  574   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  575   ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
  576 
  577   unsetenv ("LC_ALL");
  578   unsetenv ("LC_CTYPE");
  579   unsetenv ("LC_MESSAGES");
  580   setenv ("LANG", "", 1);
  581   setlocale (LC_ALL, "");
  582   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  583   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   setenv ("LC_ALL", "C", 1);
  589   unsetenv ("LC_CTYPE");
  590   unsetenv ("LC_MESSAGES");
  591   unsetenv ("LANG");
  592   setlocale (LC_ALL, "");
  593   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  594   ASSERT (strcmp (name, "C") == 0);
  595 
  596   unsetenv ("LC_ALL");
  597   setenv ("LC_CTYPE", "C", 1);
  598   setenv ("LC_MESSAGES", "C", 1);
  599   unsetenv ("LANG");
  600   setlocale (LC_ALL, "");
  601   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  602   ASSERT (strcmp (name, "C") == 0);
  603 
  604   unsetenv ("LC_ALL");
  605   unsetenv ("LC_CTYPE");
  606   unsetenv ("LC_MESSAGES");
  607   setenv ("LANG", "C", 1);
  608   setlocale (LC_ALL, "");
  609   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  610   ASSERT (strcmp (name, "C") == 0);
  611 
  612   /* Check mixed situations.  */
  613 
  614   unsetenv ("LC_ALL");
  615   unsetenv ("LC_CTYPE");
  616   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
  617   setenv ("LANG", "de_DE.UTF-8", 1);
  618   if (setlocale (LC_ALL, "") != NULL)
  619     {
  620       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       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
  625 #endif
  626       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  627       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  628     }
  629 
  630   unsetenv ("LC_ALL");
  631   unsetenv ("LC_CTYPE");
  632   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
  633   unsetenv ("LANG");
  634   if (setlocale (LC_ALL, "") != NULL)
  635     {
  636       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
  637       ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
  638       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  639       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     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  646     if (locale != NULL)
  647       {
  648         unsetenv ("LC_ALL");
  649         unsetenv ("LC_CTYPE");
  650         unsetenv ("LC_MESSAGES");
  651         setenv ("LANG", "C", 1);
  652         setlocale (LC_ALL, "");
  653         uselocale (locale);
  654         name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
  655         ASSERT (strcmp (name, "C") == 0);
  656         uselocale (LC_GLOBAL_LOCALE);
  657         freelocale (locale);
  658       }
  659   }
  660 #endif
  661 }
  662 
  663 /* Test the gl_locale_name_environ() function.  */
  664 static void
  665 test_locale_name_environ (void)
  666 {
  667   const char *name;
  668 
  669   /* Get into a defined state,  */
  670   setlocale (LC_ALL, "en_US.UTF-8");
  671 #if HAVE_GOOD_USELOCALE
  672   uselocale (LC_GLOBAL_LOCALE);
  673 #endif
  674 
  675   /* Check that when all environment variables are unset,
  676      gl_locale_name_environ returns NULL.  */
  677   unsetenv ("LC_ALL");
  678   unsetenv ("LC_CTYPE");
  679   unsetenv ("LC_MESSAGES");
  680   unsetenv ("LC_NUMERIC");
  681   unsetenv ("LANG");
  682   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
  683   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   setenv ("LC_ALL", "", 1);
  689   unsetenv ("LC_CTYPE");
  690   unsetenv ("LC_MESSAGES");
  691   unsetenv ("LANG");
  692   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
  693 
  694   unsetenv ("LC_ALL");
  695   setenv ("LC_CTYPE", "", 1);
  696   unsetenv ("LC_MESSAGES");
  697   unsetenv ("LANG");
  698   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
  699 
  700   unsetenv ("LC_ALL");
  701   unsetenv ("LC_CTYPE");
  702   setenv ("LC_MESSAGES", "", 1);
  703   unsetenv ("LANG");
  704   ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
  705 
  706   unsetenv ("LC_ALL");
  707   unsetenv ("LC_CTYPE");
  708   unsetenv ("LC_MESSAGES");
  709   setenv ("LANG", "", 1);
  710   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   setenv ("LC_ALL", "C", 1);
  716   unsetenv ("LC_CTYPE");
  717   unsetenv ("LC_MESSAGES");
  718   unsetenv ("LANG");
  719   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
  720   ASSERT (strcmp (name, "C") == 0);
  721 
  722   unsetenv ("LC_ALL");
  723   setenv ("LC_CTYPE", "C", 1);
  724   setenv ("LC_MESSAGES", "C", 1);
  725   unsetenv ("LANG");
  726   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
  727   ASSERT (strcmp (name, "C") == 0);
  728 
  729   unsetenv ("LC_ALL");
  730   unsetenv ("LC_CTYPE");
  731   unsetenv ("LC_MESSAGES");
  732   setenv ("LANG", "C", 1);
  733   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
  734   ASSERT (strcmp (name, "C") == 0);
  735 
  736   /* Check mixed situations.  */
  737 
  738   unsetenv ("LC_ALL");
  739   unsetenv ("LC_CTYPE");
  740   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
  741   setenv ("LANG", "de_DE.UTF-8", 1);
  742   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
  743   ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
  744   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
  745   ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
  746 
  747   unsetenv ("LC_ALL");
  748   unsetenv ("LC_CTYPE");
  749   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
  750   unsetenv ("LANG");
  751   name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
  752   ASSERT (name == NULL);
  753   name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
  754   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     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  760     if (locale != NULL)
  761       {
  762         unsetenv ("LC_ALL");
  763         unsetenv ("LC_CTYPE");
  764         unsetenv ("LC_MESSAGES");
  765         setenv ("LANG", "C", 1);
  766         setlocale (LC_ALL, "");
  767         uselocale (locale);
  768         name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
  769         ASSERT (strcmp (name, "C") == 0);
  770         uselocale (LC_GLOBAL_LOCALE);
  771         freelocale (locale);
  772       }
  773   }
  774 #endif
  775 }
  776 
  777 /* Test the gl_locale_name_default() function.  */
  778 static void
  779 test_locale_name_default (void)
  780 {
  781   const char *name = gl_locale_name_default ();
  782 
  783   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   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     locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
  795     if (locale != NULL)
  796       {
  797         uselocale (locale);
  798         ASSERT (strcmp (gl_locale_name_default (), name) == 0);
  799         uselocale (LC_GLOBAL_LOCALE);
  800         freelocale (locale);
  801       }
  802   }
  803 #endif
  804 }
  805 
  806 int
  807 main ()
  808 {
  809   test_locale_name ();
  810   test_locale_name_thread ();
  811   test_locale_name_posix ();
  812   test_locale_name_environ ();
  813   test_locale_name_default ();
  814 
  815   return 0;
  816 }