root/maint/gnulib/tests/test-localename.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_locale_name
  2. test_locale_name_thread
  3. test_locale_name_posix
  4. test_locale_name_environ
  5. test_locale_name_default
  6. main

   1 /* Test of gl_locale_name function and its variants.
   2    Copyright (C) 2007-2021 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 test_locale_name (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 ()
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */