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

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

DEFINITIONS

This source file includes following definitions.
  1. get_locale_dependent_values
  2. test_with_uselocale
  3. get_locale_dependent_values_from
  4. test_with_locale_parameter
  5. main
  6. main

   1 /* Test of duplicating a locale object.
   2    Copyright (C) 2009-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 <locale.h>
  22 
  23 #if HAVE_WORKING_DUPLOCALE
  24 
  25 #include "signature.h"
  26 SIGNATURE_CHECK (duplocale, locale_t, (locale_t));
  27 
  28 #include <langinfo.h>
  29 #if HAVE_MONETARY_H
  30 # include <monetary.h>
  31 #endif
  32 #include <stdio.h>
  33 #include <string.h>
  34 
  35 #include "macros.h"
  36 
  37 struct locale_dependent_values
  38 {
  39 #if HAVE_MONETARY_H
  40   char monetary[100];
  41 #endif
  42   char numeric[100];
  43   char time[100];
  44 };
  45 
  46 static void
  47 get_locale_dependent_values (struct locale_dependent_values *result)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49 #if HAVE_MONETARY_H
  50   strfmon (result->monetary, sizeof (result->monetary),
  51            "%n", 123.75);
  52   /* result->monetary is usually "$123.75" */
  53 #endif
  54   snprintf (result->numeric, sizeof (result->numeric),
  55             "%g", 3.5);
  56   /* result->numeric is usually "3,5" */
  57   strncpy (result->time, nl_langinfo (MON_1), sizeof result->time - 1);
  58   result->time[sizeof result->time - 1] = '\0';
  59   /* result->time is usually "janvier" */
  60 }
  61 
  62 #if HAVE_WORKING_USELOCALE
  63 
  64 static int
  65 test_with_uselocale (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67   struct locale_dependent_values expected_results;
  68   locale_t mixed1;
  69   locale_t mixed2;
  70   locale_t perthread;
  71 
  72   /* Set up a locale which is a mix between different system locales.  */
  73   setlocale (LC_ALL, "en_US.UTF-8");
  74   setlocale (LC_NUMERIC, "de_DE.UTF-8");
  75   setlocale (LC_TIME, "fr_FR.UTF-8");
  76   get_locale_dependent_values (&expected_results);
  77 
  78   /* Save the locale in a locale_t object.  */
  79   mixed1 = duplocale (LC_GLOBAL_LOCALE);
  80   ASSERT (mixed1 != NULL);
  81 
  82   /* Use a per-thread locale.  */
  83   perthread = newlocale (LC_ALL_MASK, "es_ES.UTF-8", NULL);
  84   if (perthread == NULL)
  85     return 1;
  86   uselocale (perthread);
  87 
  88   /* Save the locale in a locale_t object again.  */
  89   mixed2 = duplocale (LC_GLOBAL_LOCALE);
  90   ASSERT (mixed2 != NULL);
  91 
  92   /* Set up a default locale.  */
  93   setlocale (LC_ALL, "C");
  94   uselocale (LC_GLOBAL_LOCALE);
  95   {
  96     struct locale_dependent_values c_results;
  97     get_locale_dependent_values (&c_results);
  98   }
  99 
 100   /* Now use the saved locale mixed1 again.  */
 101   setlocale (LC_ALL, "C");
 102   uselocale (LC_GLOBAL_LOCALE);
 103   uselocale (mixed1);
 104   {
 105     struct locale_dependent_values results;
 106     get_locale_dependent_values (&results);
 107 # if HAVE_MONETARY_H
 108     ASSERT (strcmp (results.monetary, expected_results.monetary) == 0);
 109 # endif
 110     ASSERT (strcmp (results.numeric, expected_results.numeric) == 0);
 111     ASSERT (strcmp (results.time, expected_results.time) == 0);
 112   }
 113 
 114   /* Now use the saved locale mixed2 again.  */
 115   setlocale (LC_ALL, "C");
 116   uselocale (LC_GLOBAL_LOCALE);
 117   uselocale (mixed2);
 118   {
 119     struct locale_dependent_values results;
 120     get_locale_dependent_values (&results);
 121 # if HAVE_MONETARY_H
 122     ASSERT (strcmp (results.monetary, expected_results.monetary) == 0);
 123 # endif
 124     ASSERT (strcmp (results.numeric, expected_results.numeric) == 0);
 125     ASSERT (strcmp (results.time, expected_results.time) == 0);
 126   }
 127 
 128   setlocale (LC_ALL, "C");
 129   uselocale (LC_GLOBAL_LOCALE);
 130   freelocale (mixed1);
 131   freelocale (mixed2);
 132   freelocale (perthread);
 133   return 0;
 134 }
 135 
 136 #endif
 137 
 138 #if HAVE_STRFMON_L || HAVE_SNPRINTF_L || (HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE)
 139 
 140 static void
 141 get_locale_dependent_values_from (struct locale_dependent_values *result, locale_t locale)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143 #if HAVE_STRFMON_L
 144   strfmon_l (result->monetary, sizeof (result->monetary), locale,
 145              "%n", 123.75);
 146   /* result->monetary is usually "$123.75" */
 147 #endif
 148 #if HAVE_SNPRINTF_L
 149   snprintf_l (result->numeric, sizeof (result->numeric), locale,
 150               "%g", 3.5);
 151   /* result->numeric is usually "3,5" */
 152 #endif
 153 #if HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE
 154   strcpy (result->time, nl_langinfo_l (MON_1, locale));
 155   /* result->time is usually "janvier" */
 156 #endif
 157 }
 158 
 159 static int
 160 test_with_locale_parameter (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162   struct locale_dependent_values expected_results;
 163   locale_t mixed1;
 164   locale_t mixed2;
 165 
 166   /* Set up a locale which is a mix between different system locales.  */
 167   setlocale (LC_ALL, "en_US.UTF-8");
 168   setlocale (LC_NUMERIC, "de_DE.UTF-8");
 169   setlocale (LC_TIME, "fr_FR.UTF-8");
 170   get_locale_dependent_values (&expected_results);
 171 
 172   /* Save the locale in a locale_t object.  */
 173   mixed1 = duplocale (LC_GLOBAL_LOCALE);
 174   ASSERT (mixed1 != NULL);
 175 
 176   /* Create another locale_t object.  */
 177   mixed2 = newlocale (LC_ALL_MASK, "es_ES.UTF-8", NULL);
 178   if (mixed2 == NULL)
 179     return 1;
 180 
 181   /* Set up a default locale.  */
 182   setlocale (LC_ALL, "C");
 183   {
 184     struct locale_dependent_values c_results;
 185     get_locale_dependent_values (&c_results);
 186   }
 187 
 188   /* Now use the saved locale mixed2.  */
 189   {
 190     struct locale_dependent_values results;
 191     get_locale_dependent_values_from (&results, mixed2);
 192   }
 193 
 194   /* Now use the saved locale mixed1 again.  */
 195   {
 196     struct locale_dependent_values results;
 197     get_locale_dependent_values_from (&results, mixed1);
 198 #if HAVE_STRFMON_L
 199     ASSERT (strcmp (results.monetary, expected_results.monetary) == 0);
 200 #endif
 201 #if HAVE_SNPRINTF_L
 202     ASSERT (strcmp (results.numeric, expected_results.numeric) == 0);
 203 #endif
 204 #if HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE
 205     ASSERT (strcmp (results.time, expected_results.time) == 0);
 206 #endif
 207   }
 208 
 209   freelocale (mixed1);
 210   freelocale (mixed2);
 211   return 0;
 212 }
 213 
 214 #endif
 215 
 216 int
 217 main ()
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219   int skipped = 0;
 220 #if HAVE_WORKING_USELOCALE
 221   skipped |= test_with_uselocale ();
 222 #endif
 223 #if HAVE_STRFMON_L || HAVE_SNPRINTF_L || (HAVE_NL_LANGINFO_L && HAVE_WORKING_USELOCALE)
 224   skipped |= test_with_locale_parameter ();
 225 #endif
 226 
 227   if (skipped)
 228     {
 229       fprintf (stderr, "Skipping test: Spanish Unicode locale is not installed\n");
 230       return 77;
 231     }
 232 
 233   return 0;
 234 }
 235 
 236 #else
 237 
 238 #include <stdio.h>
 239 
 240 int
 241 main ()
     /* [previous][next][first][last][top][bottom][index][help] */
 242 {
 243   fprintf (stderr, "Skipping test: function duplocale not available\n");
 244   return 77;
 245 }
 246 
 247 #endif

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