(root)/
gcc-13.2.0/
libquadmath/
printf/
_i18n_number.h
       1  /* Copyright (C) 2000, 2004, 2008 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3     Contributed by Ulrich Drepper <drepper@gnu.org>, 2000.
       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, write to the Free
      17     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
      18     02111-1307 USA.  */
      19  
      20  /* Look up the value of the next multibyte character and return its numerical
      21     value if it is one of the digits known in the locale.  If *DECIDED is
      22     -1 this means it is not yet decided which form it is and we have to
      23     search through all available digits.  Otherwise we know which script
      24     the digits are from.  */
      25  static inline char *
      26  outdigit_value (char *s, int n)
      27  {
      28    const char *outdigit;
      29    size_t dlen;
      30  
      31    assert (0 <= n && n <= 9);
      32    outdigit = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB + n);
      33    dlen = strlen (outdigit);
      34  
      35    s -= dlen;
      36    while (dlen-- > 0)
      37      s[dlen] = outdigit[dlen];
      38  
      39    return s;
      40  }
      41  
      42  /* Look up the value of the next multibyte character and return its numerical
      43     value if it is one of the digits known in the locale.  If *DECIDED is
      44     -1 this means it is not yet decided which form it is and we have to
      45     search through all available digits.  Otherwise we know which script
      46     the digits are from.  */
      47  static inline wchar_t
      48  outdigitwc_value (int n)
      49  {
      50    assert (0 <= n && n <= 9);
      51  
      52    return nl_langinfo_wc (_NL_CTYPE_OUTDIGIT0_WC + n);
      53  }
      54  
      55  static char *
      56  _i18n_number_rewrite (char *w, char *rear_ptr, char *end)
      57  {
      58    char decimal[MB_LEN_MAX + 1];
      59    char thousands[MB_LEN_MAX + 1];
      60  
      61    /* "to_outpunct" is a map from ASCII decimal point and thousands-sep
      62       to their equivalent in locale. This is defined for locales which
      63       use extra decimal point and thousands-sep.  */
      64    wctrans_t map = wctrans ("to_outpunct");
      65    wint_t wdecimal = towctrans (L_('.'), map);
      66    wint_t wthousands = towctrans (L_(','), map);
      67  
      68    if (__builtin_expect (map != NULL, 0))
      69      {
      70        mbstate_t state;
      71        memset (&state, '\0', sizeof (state));
      72  
      73        size_t n = wcrtomb (decimal, wdecimal, &state);
      74        if (n == (size_t) -1)
      75  	memcpy (decimal, ".", 2);
      76        else
      77  	decimal[n] = '\0';
      78  
      79        memset (&state, '\0', sizeof (state));
      80  
      81        n = wcrtomb (thousands, wthousands, &state);
      82        if (n == (size_t) -1)
      83  	memcpy (thousands, ",", 2);
      84        else
      85  	thousands[n] = '\0';
      86      }
      87  
      88    /* Copy existing string so that nothing gets overwritten.  */
      89    char *src;
      90    int use_alloca = (rear_ptr - w) < 4096;
      91    if (__builtin_expect (use_alloca, 1))
      92      src = (char *) alloca (rear_ptr - w);
      93    else
      94      {
      95        src = (char *) malloc (rear_ptr - w);
      96        if (src == NULL)
      97  	/* If we cannot allocate the memory don't rewrite the string.
      98  	   It is better than nothing.  */
      99  	return w;
     100      }
     101  
     102    memcpy (src, w, rear_ptr - w);
     103    char *s = src + (rear_ptr - w);
     104  
     105    w = end;
     106  
     107    /* Process all characters in the string.  */
     108    while (--s >= src)
     109      {
     110        if (*s >= '0' && *s <= '9')
     111  	{
     112  	  if (sizeof (char) == 1)
     113  	    w = (char *) outdigit_value ((char *) w, *s - '0');
     114  	  else
     115  	    *--w = (char) outdigitwc_value (*s - '0');
     116  	}
     117        else if (__builtin_expect (map == NULL, 1) || (*s != '.' && *s != ','))
     118  	*--w = *s;
     119        else
     120  	{
     121  	  if (sizeof (char) == 1)
     122  	    {
     123  	      const char *outpunct = *s == '.' ? decimal : thousands;
     124  	      size_t dlen = strlen (outpunct);
     125  
     126  	      w -= dlen;
     127  	      while (dlen-- > 0)
     128  		w[dlen] = outpunct[dlen];
     129  	    }
     130  	  else
     131  	    *--w = *s == '.' ? (char) wdecimal : (char) wthousands;
     132  	}
     133      }
     134  
     135    if (! use_alloca)
     136      free (src);
     137  
     138    return w;
     139  }