]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Thu, 29 Jun 2000 08:44:37 +0000 (08:44 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 29 Jun 2000 08:44:37 +0000 (08:44 +0000)
2000-06-29  Ulrich Drepper  <drepper@redhat.com>

* stdlib/grouping.h: Correctly handle multibyte thousands
separator and decimal point.
* stdlib/stdtod.c: Likewise.
* sysdeps/generic/strtol.c: Likewise.

* locale/categories.def: Add entries for wide character decimal point
and thousands separator in numeric and monetary category.

2000-06-28  Ulrich Drepper  <drepper@redhat.com>

* stdio-common/printf_fp.c (__printf_fp): Remove unnecessary
second definition and initialization of decimal.

* libio/libio.h (struct _IO_cookie_file): Move struct type defintion
out.
* libio/libioP.h (struct _IO_cookie_file): Move struct type defintion
in.
(_IO_JUMPS): Don't cast THIS--expect arg to be a
(struct _IO_FILE_plus *).
(_IO_iter_next, _IO_iter_file): _IO_ITER is now
(struct _IO_FILE_plus *).
(_IO_check_libio): Set user-visible handles to
(struct _IO_FILE_plus *).

ChangeLog
stdlib/grouping.h
stdlib/strtod.c
sysdeps/generic/strtol.c

index f953e8e42b3a5373c3ba0e91c0ae8d9cce6875c7..01e9fea1b58f63b383f679bd634622044017d9a5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,27 @@
+2000-06-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * stdlib/grouping.h: Correctly handle multibyte thousands
+       separator and decimal point.
+       * stdlib/stdtod.c: Likewise.
+       * sysdeps/generic/strtol.c: Likewise.
+
+       * locale/categories.def: Add entries for wide character decimal point
+       and thousands separator in numeric and monetary category.
+
+2000-06-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * stdio-common/printf_fp.c (__printf_fp): Remove unnecessary
+       second definition and initialization of decimal.
+
 2000-06-28  Greg McGary  <greg@mcgary.org>
 
-       * libio/libio.h (struct _IO_cookie_file): Move struct type defintion out.
+       * libio/libio.h (struct _IO_cookie_file): Move struct type defintion
+       out.
        (_IO_FILE): Declare chain as (struct _IO_FILE_plus *).
-       * libio/libioP.h (struct _IO_cookie_file): Move struct type defintion in.
-       (_IO_JUMPS): Don't cast THIS--expect arg to be a (struct _IO_FILE_plus *).
+       * libio/libioP.h (struct _IO_cookie_file): Move struct type defintion
+       in.
+       (_IO_JUMPS): Don't cast THIS--expect arg to be a
+       (struct _IO_FILE_plus *).
        (_IO_JUMPS_FUNC): Express in terms of _IO_JUMPS, and add cast to
        THIS, since _IO_JUMPS no longer does it implicitly.
        (_IO_file_init, _IO_old_file_init, _IO_new_file_init): Declare
        * libio/genops.c (_IO_link_in, _IO_un_link): Likewise.
        (_IO_flush_all, _IO_flush_all_linebuffered, _IO_unbuffer_write):
        Declare iteration pointer as (struct _IO_FILE_plus *).
-       (_IO_iter_next, _IO_iter_file): _IO_ITER is now (struct _IO_FILE_plus *).
+       (_IO_iter_next, _IO_iter_file): _IO_ITER is now
+               (struct _IO_FILE_plus *).
        * libio/stdfiles.c (_IO_list_all): Declare as (struct _IO_FILE_plus *).
        * libio/oldstdfiles.c (_IO_list_all): Likewise.
-       (_IO_check_libio): Set user-visible handles to (struct _IO_FILE_plus *).
+       (_IO_check_libio): Set user-visible handles to
+       (struct _IO_FILE_plus *).
        * libio/stdio.c (stdin, stdout, stderr): Set user-visible handles
        to (struct _IO_FILE_plus *).
 
index 71b89f9133d39e89155040032af8b5a50da5f7b2..ca760c7978f3af32267ede7076cabe6ddf863f61 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal header for proving correct grouping in strings of numbers.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    The GNU C Library is free software; you can redistribute it and/or
 
 static inline const STRING_TYPE *
 correctly_grouped_prefix (const STRING_TYPE *begin, const STRING_TYPE *end,
-                         wchar_t thousands, const char *grouping)
+#ifdef USE_WIDE_CHAR
+                         wchar_t thousands,
+#else
+                         const char *thousands,
+#endif
+                         const char *grouping)
 {
+#ifndef USE_WIDE_CHAR
+  size_t thousands_len;
+  int cnt;
+#endif
+
   if (grouping == NULL)
     return end;
 
-  if (*grouping == '\0')
-    {
-      /* No grouping allowed.  Accept all characters up to the first
-        thousands separator.  */
-      while (begin < end && *begin != thousands)
-       ++begin;
-      return begin;
-    }
+#ifndef USE_WIDE_CHAR
+  thousands_len = strlen (thousands);
+#endif
 
   while (end > begin)
     {
@@ -50,8 +55,23 @@ correctly_grouped_prefix (const STRING_TYPE *begin, const STRING_TYPE *end,
       const char *gp = grouping;
 
       /* Check first group.  */
-      while (cp >= begin && (wchar_t) *cp != thousands)
-       --cp;
+      while (cp >= begin)
+       {
+#ifdef USE_WIDE_CHAR
+         if (*cp == thousands)
+           break;
+#else
+         if (cp[thousands_len - 1] == *thousands)
+           {
+             for (cnt = 1; thousands[cnt] != '\0'; ++cnt)
+               if (thousands[cnt] != cp[thousands_len - 1 - cnt])
+                 break;
+             if (thousands[cnt] == '\0')
+               break;
+           }
+#endif
+         --cp;
+       }
 
       /* We allow the representation to contain no grouping at all even if
         the locale specifies we can have grouping.  */
@@ -93,8 +113,20 @@ correctly_grouped_prefix (const STRING_TYPE *begin, const STRING_TYPE *end,
                  )
                {
                  /* No more thousands separators are allowed to follow.  */
-                 while (cp >= begin && (wchar_t) *cp != thousands)
-                   --cp;
+                 while (cp >= begin)
+                   {
+#ifdef USE_WIDE_CHAR
+                     if (*cp == thousands)
+                       break;
+#else
+                     for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+                       if (thousands[cnt] != cp[thousands_len - cnt - 1])
+                         break;
+                     if (thousands[cnt] == '\0')
+                       break;
+#endif
+                     --cp;
+                   }
 
                  if (cp < begin)
                    /* OK, only digits followed.  */
@@ -105,8 +137,20 @@ correctly_grouped_prefix (const STRING_TYPE *begin, const STRING_TYPE *end,
                  /* Check the next group.  */
                  const STRING_TYPE *group_end = cp;
 
-                 while (cp >= begin && (wchar_t) *cp != thousands)
-                   --cp;
+                 while (cp >= begin)
+                   {
+#ifdef USE_WIDE_CHAR
+                     if (*cp == thousands)
+                       break;
+#else
+                     for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+                       if (thousands[cnt] != cp[thousands_len - cnt - 1])
+                         break;
+                     if (thousands[cnt] == '\0')
+                       break;
+#endif
+                     --cp;
+                   }
 
                  if (cp < begin && group_end - cp <= (int) *gp)
                    /* Final group is correct.  */
index f2ff79f6df4963906d2e6f7a9368b6b2b202ca9c..d15237125e98cc2661caa3c93a3d68e207599e94 100644 (file)
@@ -1,6 +1,6 @@
 /* Read decimal floating point numbers.
    This file is part of the GNU C Library.
-   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -301,7 +301,12 @@ round_and_return (mp_limb_t *retval, int exponent, int negative,
    factor for the resulting number (see code) multiply by it.  */
 static inline const STRING_TYPE *
 str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
-           int *exponent)
+           int *exponent
+#ifndef USE_WIDE_CHAR
+           , const char *decimal, size_t decimal_len, const char *thousands
+#endif
+
+           )
 {
   /* Number of digits for actual limb.  */
   int cnt = 0;
@@ -338,8 +343,22 @@ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
         the string.  But these all can be ignored because we know the
         format of the number is correct and we have an exact number
         of characters to read.  */
-      while (*str < L_('0') || *str > L_('9'))
+#ifdef USE_WIDE_CHAR
+      if (*str < L'0' || *str > L'9')
        ++str;
+#else
+      if (*str < '0' || *str > '9')
+       {
+         if (thousands != NULL && *str == *thousands
+             && ({ for (cnt == 1; thousands[cnt] != '\0'; ++cnt)
+                     if (thousands[cnt] != str[cnt])
+                       break;
+                   thousands[cnt] == '\0'; }))
+           str += cnt;
+         else
+           str += decimal_len;
+       }
+#endif
       low = low * 10 + *str++ - L_('0');
       ++cnt;
     }
@@ -451,12 +470,23 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
   typedef unsigned int wint_t;
 #endif
   /* The radix character of the current locale.  */
+#ifdef USE_WIDE_CHAR
   wchar_t decimal;
+#else
+  const char *decimal;
+  size_t decimal_len;
+#endif
   /* The thousands character of the current locale.  */
+#ifdef USE_WIDE_CHAR
   wchar_t thousands = L'\0';
+#else
+  const char *thousands = NULL;
+#endif
   /* The numeric grouping specification of the current locale,
      in the format described in <locale.h>.  */
   const char *grouping;
+  /* Used in several places.  */
+  int cnt;
 
 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
   struct locale_data *current = loc->__locales[LC_NUMERIC];
@@ -470,21 +500,34 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
       else
        {
          /* Figure out the thousands separator character.  */
-         thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP));
-         if (thousands == WEOF)
-           thousands = L'\0';
+#ifdef USE_WIDE_CHAR
+         thousands = _NL_CURRENT_WORD (LC_NUMERIC,
+                                       _NL_NUMERIC_THOUSANDS_SEP_WC);
          if (thousands == L'\0')
            grouping = NULL;
+#else
+         thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+         if (*thousands == '\0')
+           {
+             thousands = NULL;
+             grouping = NULL;
+           }
+#endif
        }
     }
   else
     grouping = NULL;
 
   /* Find the locale's decimal point character.  */
-  decimal = __btowc (*_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT));
-  if (decimal == WEOF)
-    decimal = L'.';
+#ifdef USE_WIDE_CHAR
+  decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
   assert (decimal != L'\0');
+# define decimal_len 1
+#else
+  decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+  decimal_len = strlen (decimal);
+  assert (decimal_len > 0);
+#endif
 
   /* Prepare number representation.  */
   exponent = 0;
@@ -510,8 +553,23 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
 
   /* Return 0.0 if no legal string is found.
      No character is used even if a sign was found.  */
-  if ((c < L_('0') || c > L_('9'))
-      && ((wchar_t) c != decimal || cp[1] < L_('0') || cp[1] > L_('9')))
+#ifdef USE_WIDE_CHAR
+  if (c == decimal && cp[1] >= L'0' && cp[1] <= L'9')
+    {
+      /* We accept it.  This funny construct is here only to indent
+        the code directly.  */
+    }
+#else
+  for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+    if (cp[cnt] != decimal[cnt])
+      break;
+  if (decimal[cnt] == '\0' && cp[1] >= '0' && cp[1] <= '9')
+    {
+      /* We accept it.  This funny construct is here only to indent
+        the code directly.  */
+    }
+#endif
+  else if (c < L_('0') || c > L_('9'))
     {
       int matched = 0;
       /* Check for `INF' or `INFINITY'.  */
@@ -588,16 +646,45 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
   start_of_digits = startp = cp;
 
   /* Ignore leading zeroes.  This helps us to avoid useless computations.  */
-  while (c == L_('0') || (thousands != L'\0' && (wchar_t) c == thousands))
+#ifdef USE_WIDE_CHAR
+  while (c == L'0' || (thousands != L'\0' && c == thousands))
     c = *++cp;
+#else
+  if (thousands == NULL)
+    while (c == '0')
+      c = *++cp;
+  else
+    {
+      /* We also have the multibyte thousands string.  */
+      while (1)
+       {
+         if (c != '0')
+           {
+             for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+               if (c != thousands[cnt])
+                 break;
+             if (thousands[cnt] != '\0')
+               break;
+           }
+         c = *++cp;
+       }
+    }
+#endif
 
   /* If no other digit but a '0' is found the result is 0.0.
      Return current read pointer.  */
-  if ((c < L_('0') || c > L_('9')) &&
-      (base == 16 && (c < TOLOWER (L_('a')) || c > TOLOWER (L_('f')))) &&
-      (wchar_t) c != decimal &&
-      (base == 16 && (cp == start_of_digits || TOLOWER (c) != L_('p'))) &&
-      (base != 16 && TOLOWER (c) != L_('e')))
+  if ((c < L_('0') || c > L_('9'))
+      && (base == 16 && (c < TOLOWER (L_('a')) || c > TOLOWER (L_('f'))))
+#ifdef USE_WIDE_CHAR
+      && c != decimal
+#else
+      && ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+             if (decimal[cnt] != cp[cnt])
+               break;
+           decimal[cnt] != '\0'; })
+#endif
+      && (base == 16 && (cp == start_of_digits || TOLOWER (c) != L_('p')))
+      && (base != 16 && TOLOWER (c) != L_('e')))
     {
       tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
       /* If TP is at the start of the digits, there was no correctly
@@ -617,9 +704,25 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
       if ((c >= L_('0') && c <= L_('9'))
          || (base == 16 && TOLOWER (c) >= L_('a') && TOLOWER (c) <= L_('f')))
        ++dig_no;
-      else if (thousands == L'\0' || (wchar_t) c != thousands)
-       /* Not a digit or separator: end of the integer part.  */
-       break;
+      else
+       {
+#ifdef USE_WIDE_CHAR
+         if (thousands == L'\0' || c != thousands)
+           /* Not a digit or separator: end of the integer part.  */
+           break;
+#else
+         if (thousands == NULL)
+           break;
+         else
+           {
+             for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+               if (thousands[cnt] != cp[cnt])
+                 break;
+             if (thousands[cnt] != '\0')
+               break;
+           }
+#endif
+       }
       c = *++cp;
     }
 
@@ -667,9 +770,19 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
 
   /* Read the fractional digits.  A special case are the 'american style'
      numbers like `16.' i.e. with decimal but without trailing digits.  */
-  if ((wchar_t) c == decimal)
+  if (
+#ifdef USE_WIDE_CHAR
+      c == decimal
+#else
+      ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+          if (decimal[cnt] != cp[cnt])
+            break;
+        decimal[cnt] == '\0'; })
+#endif
+      )
     {
-      c = *++cp;
+      cp += decimal_len;
+      c = *cp;
       while ((c >= L_('0') && c <= L_('9')) ||
             (base == 16 && TOLOWER (c) >= L_('a') && TOLOWER (c) <= L_('f')))
        {
@@ -779,9 +892,24 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
   if (lead_zero)
     {
       /* Find the decimal point */
-      while ((wchar_t) *startp != decimal)
+#ifdef USE_WIDE_CHAR
+      while (*startp != decimal)
        ++startp;
-      startp += lead_zero + 1;
+#else
+      while (1)
+       {
+         if (*startp == decimal[0])
+           {
+             for (cnt = 1; decimal[cnt] != '\0'; ++cnt)
+               if (decimal[cnt] != startp[cnt])
+                 break;
+             if (decimal[cnt] == '\0')
+               break;
+           }
+         ++startp;
+       }
+#endif
+      startp += lead_zero + decimal_len;
       exponent -= base == 16 ? 4 * lead_zero : lead_zero;
       dig_no -= lead_zero;
     }
@@ -828,8 +956,8 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
 
       while (--dig_no > 0 && idx >= 0)
        {
-         while (!ISXDIGIT (*startp))
-           ++startp;
+         if (!ISXDIGIT (*startp))
+           startp += decimal_len;
          if (ISDIGIT (*startp))
            val = *startp++ - L_('0');
          else
@@ -885,7 +1013,11 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
   if (int_no > 0)
     {
       /* Read the integer part as a multi-precision number to NUM.  */
-      startp = str_to_mpn (startp, int_no, num, &numsize, &exponent);
+      startp = str_to_mpn (startp, int_no, num, &numsize, &exponent
+#ifndef USE_WIDE_CHAR
+                          , decimal, decimal_len, thousands
+#endif
+                          );
 
       if (exponent > 0)
        {
@@ -1031,7 +1163,6 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
        123e-6 gives 123 / 1000000.  */
 
     int expbit;
-    int cnt;
     int neg_exp;
     int more_bits;
     mp_limb_t cy;
@@ -1095,8 +1226,11 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
       memcpy (den, num, densize * sizeof (mp_limb_t));
 
     /* Read the fractional digits from the string.  */
-    (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent);
-
+    (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent
+#ifndef USE_WIDE_CHAR
+                      , decimal, decimal_len, thousands
+#endif
+                      );
 
     /* We now have to shift both numbers so that the highest bit in the
        denominator is set.  In the same process we copy the numerator to
index 42da792c44ccf55dfbead3af4e7acbcc9c3404f3..44e2104e18b206904ca046b360fc41aed89df854 100644 (file)
@@ -1,5 +1,5 @@
 /* Convert string representation of a number into an integer value.
-   Copyright (C) 1991,92,94,95,96,97,98,99 Free Software Foundation, Inc.
+   Copyright (C) 1991,92,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -243,13 +243,20 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
   register UCHAR_TYPE c;
   const STRING_TYPE *save, *end;
   int overflow;
+#ifndef USE_WIDE_CHAR
+  int cnt;
+#endif
 
 #ifdef USE_NUMBER_GROUPING
 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
   struct locale_data *current = loc->__locales[LC_NUMERIC];
 # endif
   /* The thousands character of the current locale.  */
+# ifdef USE_WIDE_CHAR
   wchar_t thousands = L'\0';
+# else
+  const char *thousands = NULL;
+# endif
   /* The numeric grouping specification of the current locale,
      in the format described in <locale.h>.  */
   const char *grouping;
@@ -262,13 +269,23 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
       else
        {
          /* Figure out the thousands separator character.  */
-# if defined _LIBC || defined _HAVE_BTOWC
-         thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP));
-         if (thousands == WEOF)
-           thousands = L'\0';
-# endif
+# ifdef USE_WIDE_CHAR
+#  ifdef _LIBC
+         thousands = _NL_CURRENT_WORD (LC_NUMERIC,
+                                       _NL_NUMERIC_THOUSANDS_SEP_WC);
+#  endif
          if (thousands == L'\0')
            grouping = NULL;
+# else
+#  ifdef _LIBC
+         thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+#  endif
+         if (*thousands == '\0')
+           {
+             thousands = NULL;
+             grouping = NULL;
+           }
+# endif
        }
     }
   else
@@ -325,15 +342,33 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
     {
       /* Find the end of the digit string and check its grouping.  */
       end = s;
-      for (c = *end; c != L_('\0'); c = *++end)
-       if ((wchar_t) c != thousands
-           && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
-           && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
-         break;
-      if (*s == thousands)
-       end = s;
-      else
-       end = correctly_grouped_prefix (s, end, thousands, grouping);
+      if (
+# ifdef USE_WIDE_CHAR
+         *s != thousands
+# else
+         ({ for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+              if (thousands[cnt] != end[cnt])
+                break;
+            thousands[cnt] != '\0'; })
+# endif
+         )
+       {
+         for (c = *end; c != L_('\0'); c = *++end)
+           if (((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
+# ifdef USE_WIDE_CHAR
+               && c != thousands
+# else
+               && ({ for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+                     if (thousands[cnt] != end[cnt])
+                       break;
+                     thousands[cnt] != '\0'; })
+# endif
+               && (!ISALPHA (c)
+                   || (int) (TOUPPER (c) - L_('A') + 10) >= base))
+             break;
+
+         end = correctly_grouped_prefix (s, end, thousands, grouping);
+       }
     }
   else
 #endif