(root)/
glibc-2.38/
stdlib/
tst-strfmon_l.c
       1  /* Test locale dependence of strfmon_l.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdbool.h>
      20  #include <stdio.h>
      21  #include <monetary.h>
      22  #include <string.h>
      23  #include <stdlib.h>
      24  #include <locale.h>
      25  
      26  static const char *const en_us_name = "en_US.ISO-8859-1";
      27  
      28  /* Locale value to be used by tests.  */
      29  static locale_t loc;
      30  static const char *loc_name;
      31  
      32  /* Set the global locale to GLOBAL_NAME, and the locale referenced by
      33     the loc variable above to LOCAL_NAME.  */
      34  static void
      35  init_loc (const char *global_name, const char *local_name)
      36  {
      37    loc = newlocale (LC_ALL_MASK, local_name, 0);
      38    if (loc == 0)
      39      {
      40        printf ("error: newlocale (%s): %m\n", local_name);
      41        abort ();
      42      }
      43    loc_name = local_name;
      44  
      45    if (setlocale (LC_ALL, global_name) == NULL)
      46      {
      47        printf ("error: setlocale (%s): %m\n", global_name);
      48        abort ();
      49      }
      50  }
      51  
      52  /* Expected strings for a positive or negative value.  */
      53  struct testcase
      54  {
      55    const char *i;                /* %i */
      56    const char *n;                /* %n */
      57    const char *i_ungrouped;      /* %^i */
      58    const char *n_ungrouped;      /* %^n */
      59  };
      60  
      61  /* Collected expected strings for both positive and negative
      62     values.  */
      63  struct testcase_pair
      64  {
      65    struct testcase positive;     /* 1234567.89 */
      66    struct testcase negative;     /* -1234567.89 */
      67  };
      68  
      69  static bool errors;
      70  
      71  /* Test one value using the locale loc.  */
      72  static void
      73  test_one (const char *format, double value, const char *ldformat,
      74  	  long double ldvalue, const char *expected)
      75  {
      76    static char actual[64], actualld[64];
      77    int result = strfmon_l (actual, sizeof (actual), loc, format, value);
      78    int res_ld = strfmon_l (actualld, sizeof (actualld), loc, ldformat, ldvalue);
      79    if (result < 0)
      80      {
      81        printf ("error: locale %s, format \"%s\", value %g: strfmon_l: %m\n",
      82                loc_name, format, value);
      83        errors = true;
      84      }
      85    else if (res_ld < 0)
      86      {
      87        printf ("error: locale %s, format \"%s\", value %Lg: strfmon_l: %m\n",
      88  	      loc_name, ldformat, ldvalue);
      89        errors = true;
      90      }
      91    else if (strcmp (actual, expected) != 0)
      92      {
      93        printf ("error: locale %s, format \"%s\", value %g: mismatch\n",
      94                loc_name, format, value);
      95        printf ("error:   expected: \"%s\"\n", expected);
      96        printf ("error:   actual:   \"%s\"\n", actual);
      97        errors = true;
      98      }
      99    else if (strcmp (actualld, expected) != 0)
     100      {
     101        printf ("error: locale %s, format \"%s\", value %Lg: mismatch\n",
     102  	      loc_name, ldformat, ldvalue);
     103        printf ("error:   expected: \"%s\"\n", expected);
     104        printf ("error:   actual:   \"%s\"\n", actualld);
     105        errors = true;
     106      }
     107  }
     108  
     109  static void
     110  test_pair (const struct testcase_pair *pair)
     111  {
     112    double positive = 1234567.89;
     113    long double pos = 1234567.89L;
     114    test_one ("%i", positive, "%Li", pos, pair->positive.i);
     115    test_one ("%n", positive, "%Ln", pos, pair->positive.n);
     116    test_one ("%^i", positive, "%^Li", pos, pair->positive.i_ungrouped);
     117    test_one ("%^n", positive, "%^Ln", pos, pair->positive.n_ungrouped);
     118    double negative = -1234567.89;
     119    long double neg = -1234567.89L;
     120    test_one ("%i", negative, "%Li", neg, pair->negative.i);
     121    test_one ("%n", negative, "%Ln", neg, pair->negative.n);
     122    test_one ("%^i", negative, "%^Li", neg, pair->negative.i_ungrouped);
     123    test_one ("%^n", negative, "%^Ln", neg, pair->negative.n_ungrouped);
     124  }
     125  
     126  static const struct testcase_pair en_us =
     127    {
     128      {
     129        "USD 1,234,567.89", "$1,234,567.89",
     130        "USD 1234567.89", "$1234567.89"
     131      },
     132      {
     133        "-USD 1,234,567.89", "-$1,234,567.89",
     134        "-USD 1234567.89", "-$1234567.89"
     135      }
     136    };
     137  
     138  static void
     139  test_en_us (const char *other_name)
     140  {
     141    init_loc (other_name, en_us_name);
     142    test_pair (&en_us);
     143    freelocale (loc);
     144  }
     145  
     146  struct locale_pair
     147  {
     148    const char *locale_name;
     149    struct testcase_pair pair;
     150  };
     151  
     152  static const struct locale_pair tests[] =
     153    {
     154      {
     155        "de_DE.UTF-8",
     156        {
     157          {
     158           "1.234.567,89 EUR", "1.234.567,89 \u20ac",
     159           "1234567,89 EUR", "1234567,89 \u20ac"
     160          },
     161          {
     162           "-1.234.567,89 EUR", "-1.234.567,89 \u20ac",
     163           "-1234567,89 EUR", "-1234567,89 \u20ac"
     164          }
     165        },
     166      },
     167      {
     168        "tg_TJ.UTF-8",
     169        {
     170          {
     171            "1\u202f234\u202f567.89 TJS", "1\u202f234\u202f567.89 \u0440\u0443\u0431",
     172            "1234567.89 TJS", "1234567.89 \u0440\u0443\u0431"
     173          },
     174          {
     175            "-1\u202f234\u202f567.89 TJS", "-1\u202f234\u202f567.89 \u0440\u0443\u0431",
     176            "-1234567.89 TJS", "-1234567.89 \u0440\u0443\u0431"
     177          }
     178        }
     179      },
     180      {
     181        "hr_HR.UTF-8",
     182        {
     183          {
     184            "HRK 1.234.567,89", "1.234.567,89 kn",
     185            "HRK 1234567,89", "1234567,89 kn"
     186          },
     187          {
     188            "-HRK 1.234.567,89", "-1.234.567,89 kn",
     189            "-HRK 1234567,89", "-1234567,89 kn"
     190          }
     191        }
     192      },
     193      {
     194        "hi_IN.UTF-8",
     195        {
     196          {
     197            "INR12,34,567.89", "\u20b912,34,567.89",
     198            "INR1234567.89", "\u20b91234567.89"
     199          },
     200          {
     201            "-INR12,34,567.89", "-\u20b912,34,567.89",
     202            "-INR1234567.89", "-\u20b91234567.89"
     203          }
     204        }
     205      },
     206      {
     207        "el_GR.UTF-8",
     208        {
     209          {
     210            "1.234.567,89EUR", "1.234.567,89\u20ac",
     211            "1234567,89EUR", "1234567,89\u20ac"
     212          },
     213          {
     214            "-1.234.567,89EUR", "-1.234.567,89\u20ac",
     215            "-1234567,89EUR", "-1234567,89\u20ac",
     216          }
     217        }
     218      },
     219      {}
     220    };
     221  
     222  static int
     223  do_test (void)
     224  {
     225    for (const struct locale_pair *test = tests;
     226         test->locale_name != NULL; ++test)
     227      {
     228        init_loc (en_us_name, test->locale_name);
     229        test_pair (&test->pair);
     230        freelocale (loc);
     231        test_en_us (test->locale_name);
     232      }
     233  
     234    return errors;
     235  }
     236  
     237  #define TEST_FUNCTION do_test ()
     238  #include "../test-skeleton.c"