* stdlib/strtod_l.c (____STRTOF_INTERNAL): Properly handle -0.
authorUlrich Drepper <drepper@redhat.com>
Fri, 3 Aug 2007 16:45:47 +0000 (16:45 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 3 Aug 2007 16:45:47 +0000 (16:45 +0000)
* stdlib/Makefile (tests): Add tst-strtod5.
(tst-strtod5-ENV): New.
* stdlib/tst-strtod5.c: New file.

ChangeLog
nptl/ChangeLog
stdlib/Makefile
stdlib/strtod_l.c
stdlib/tst-strtod5.c [new file with mode: 0644]

index 1354272..1327ad6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2007-08-03  Jakub Jelinek  <jakub@redhat.com>
 
+       * stdlib/strtod_l.c (____STRTOF_INTERNAL): Properly handle -0.
+       * stdlib/Makefile (tests): Add tst-strtod5.
+       (tst-strtod5-ENV): New.
+       * stdlib/tst-strtod5.c: New file.
+
        * intl/dcigettext.c (_nl_find_msg): Free encoding if __gconv_open
        failed.
        * intl/finddomain.c (_nl_find_domain): Free normalized_codeset
index df334b2..6bbd304 100644 (file)
@@ -1,3 +1,121 @@
+2007-08-01  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Remove
+       definitions for private futexes.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Include
+       kernel-features.h and lowlevellock.h.  Use private futexes if
+       they are available.
+       (__lll_lock_wait_private, __lll_unlock_wake_private): New.
+       (__lll_mutex_lock_wait): Rename to
+       (__lll_lock_wait): ... this.  Don't compile in for libc.so.
+       (__lll_mutex_timedlock_wait): Rename to ...
+       (__lll_timedlock_wait): ... this.  Use __NR_gettimeofday.
+       Don't compile in for libc.so.
+       (__lll_mutex_unlock_wake): Rename to ...
+       (__lll_unlock_wake): ... this.  Don't compile in for libc.so.
+       (__lll_timedwait_tid): Use __NR_gettimeofday.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Allow including
+       the header from assembler.  Renamed all lll_mutex_* resp.
+       lll_robust_mutex_* macros to lll_* resp. lll_robust_*.
+       Renamed all LLL_MUTEX_LOCK_* macros to LLL_LOCK_*.
+       (FUTEX_CMP_REQUEUE, FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE):
+       Define.
+       (__lll_lock_wait_private): Add prototype.
+       (__lll_lock_wait, __lll_timedlock_wait, __lll_robust_lock_wait,
+       __lll_robust_timedlock_wait, __lll_unlock_wake_private,
+       __lll_unlock_wake): Likewise.
+       (lll_lock): Add private argument.  Call __lll_lock_wait_private
+       if private is constant LLL_PRIVATE.
+       (lll_robust_lock, lll_cond_lock, lll_robust_cond_lock,
+       lll_timedlock, lll_robust_timedlock): Add private argument.
+       (lll_unlock): Add private argument.  Call __lll_unlock_wake_private
+       if private is constant LLL_PRIVATE.
+       (lll_robust_unlock, lll_robust_dead): Add private argument.
+       (lll_lock_t): Remove.
+       (__lll_cond_wait, __lll_cond_timedwait, __lll_cond_wake,
+       __lll_cond_broadcast, lll_cond_wait, lll_cond_timedwait,
+       lll_cond_wake, lll_cond_broadcast): Remove.
+       * sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: Include
+       kernel-features.h and lowlevellock.h.
+       (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove.
+       (LOAD_FUTEX_WAIT): Define.
+       (__lll_robust_mutex_lock_wait): Rename to ...
+       (__lll_robust_lock_wait): ... this.  Add private argument.
+       Use LOAD_FUTEX_WAIT macro.
+       (__lll_robust_mutex_timedlock_wait): Rename to ...
+       (__lll_robust_timedlock_wait): ... this.    Add private argument.
+       Use __NR_gettimeofday.  Use LOAD_FUTEX_WAIT macro.
+       * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Include
+       lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove.
+       (pthread_barrier_wait): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Include
+       lowlevellock.h and pthread-errnos.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE,
+       FUTEX_CMP_REQUEUE, EINVAL): Remove.
+       (__pthread_cond_broadcast): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Include
+       lowlevellock.h and pthread-errnos.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, EINVAL): Remove.
+       (__pthread_cond_signal): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Include
+       lowlevellock.h.
+       (SYS_futex, SYS_gettimeofday, FUTEX_WAIT, FUTEX_WAKE): Remove.
+       (__pthread_cond_timedwait): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.  Use __NR_gettimeofday.
+       (__condvar_tw_cleanup): Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Include
+       lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove.
+       (__pthread_cond_wait): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       ( __condvar_w_cleanup): Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_once.S: Include lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Include
+       lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+       (__pthread_rwlock_rdlock): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Include
+       lowlevellock.h.
+       (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE,
+       FUTEX_PRIVATE_FLAG): Remove.
+       (pthread_rwlock_timedrdlock): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.  Use __NR_gettimeofday.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Include
+       lowlevellock.h.
+       (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE,
+       FUTEX_PRIVATE_FLAG): Remove.
+       (pthread_rwlock_timedwrlock): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.  Use __NR_gettimeofday.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Include
+       lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+       (__pthread_rwlock_unlock): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Include
+       lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+       (__pthread_rwlock_wrlock): Use __lll_{lock,unlock}_* instead of
+       __lll_mutex_{lock,unlock}_*.
+       * sysdeps/unix/sysv/linux/sh/sem_post.S: Include lowlevellock.h.
+       (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+       (__new_sem_post): Use standard initial exec code sequences.
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Include
+       lowlevellock.h.
+       (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE,
+       FUTEX_PRIVATE_FLAG): Remove.
+       (sem_timedwait): Use __NR_gettimeofday.  Use standard initial
+       exec code sequences.
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S: Include lowlevellock.h.
+       (__new_sem_trywait): Use standard initial exec code sequences.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: Include lowlevellock.h.
+       (__new_sem_wait): Use standard initial exec code sequences.
+
 2007-07-31  Anton Blanchard  <anton@samba.org>
 
        * sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post):
index b4518b2..7390647 100644 (file)
@@ -68,7 +68,7 @@ tests         := tst-strtol tst-strtod testmb testrand testsort testdiv   \
                   tst-limits tst-rand48 bug-strtod tst-setcontext          \
                   test-a64l tst-qsort tst-system testmb2 bug-strtod2       \
                   tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
-                  tst-makecontext tst-strtod4
+                  tst-makecontext tst-strtod4 tst-strtod5
 
 include ../Makeconfig
 
@@ -115,6 +115,7 @@ test-canon-ARGS = --test-dir=${common-objpfx}stdlib
 tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata
 tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata
 tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata
+tst-strtod5-ENV = LOCPATH=$(common-objpfx)localedata
 testmb2-ENV = LOCPATH=$(common-objpfx)localedata
 
 # Run a test on the header files we use.
index 4033e3b..939440f 100644 (file)
@@ -700,7 +700,8 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
 #endif
       /* If TP is at the start of the digits, there was no correctly
         grouped prefix of the string; so no number found.  */
-      RETURN (0.0, tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp);
+      RETURN (negative ? -0.0 : 0.0,
+             tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp);
     }
 
   /* Remember first significant digit and read following characters until the
@@ -759,7 +760,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
          if (tp < startp)
            /* The number is validly grouped, but consists
               only of zeroes.  The whole value is zero.  */
-           RETURN (0.0, tp);
+           RETURN (negative ? -0.0 : 0.0, tp);
 
          /* Recompute DIG_NO so we won't read more digits than
             are properly grouped.  */
@@ -862,7 +863,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
                    {
                      /* Overflow or underflow.  */
                      __set_errno (ERANGE);
-                     result = (exp_negative ? 0.0 :
+                     result = (exp_negative ? (negative ? -0.0 : 0.0) :
                                negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL);
                    }
 
diff --git a/stdlib/tst-strtod5.c b/stdlib/tst-strtod5.c
new file mode 100644 (file)
index 0000000..337c746
--- /dev/null
@@ -0,0 +1,88 @@
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define NBSP "\xc2\xa0"
+
+static const struct
+{
+  const char *in;
+  int group;
+  double expected;
+} tests[] =
+  {
+    { "0", 0, 0.0 },
+    { "000", 0, 0.0 },
+    { "-0", 0, -0.0 },
+    { "-000", 0, -0.0 },
+    { "0,", 0, 0.0 },
+    { "-0,", 0, -0.0 },
+    { "0,0", 0, 0.0 },
+    { "-0,0", 0, -0.0 },
+    { "0e-10", 0, 0.0 },
+    { "-0e-10", 0, -0.0 },
+    { "0,e-10", 0, 0.0 },
+    { "-0,e-10", 0, -0.0 },
+    { "0,0e-10", 0, 0.0 },
+    { "-0,0e-10", 0, -0.0 },
+    { "0e-1000000", 0, 0.0 },
+    { "-0e-1000000", 0, -0.0 },
+    { "0,0e-1000000", 0, 0.0 },
+    { "-0,0e-1000000", 0, -0.0 },
+    { "0", 1, 0.0 },
+    { "000", 1, 0.0 },
+    { "-0", 1, -0.0 },
+    { "-000", 1, -0.0 },
+    { "0e-10", 1, 0.0 },
+    { "-0e-10", 1, -0.0 },
+    { "0e-1000000", 1, 0.0 },
+    { "-0e-1000000", 1, -0.0 },
+    { "000"NBSP"000"NBSP"000", 1, 0.0 },
+    { "-000"NBSP"000"NBSP"000", 1, -0.0 }
+  };
+#define NTESTS (sizeof (tests) / sizeof (tests[0]))
+
+
+static int
+do_test (void)
+{
+  if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL)
+    {
+      puts ("could not set locale");
+      return 1;
+    }
+
+  int status = 0;
+
+  for (int i = 0; i < NTESTS; ++i)
+    {
+      char *ep;
+      double r;
+
+      if (tests[i].group)
+       r = __strtod_internal (tests[i].in, &ep, 1);
+      else
+       r = strtod (tests[i].in, &ep);
+
+      if (*ep != '\0')
+       {
+         printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep);
+         status = 1;
+       }
+
+      if (r != tests[i].expected
+         || copysign (10.0, r) != copysign (10.0, tests[i].expected))
+       {
+         printf ("%d: got wrong results %g, expected %g\n",
+                 i, r, tests[i].expected);
+         status = 1;
+       }
+    }
+
+  return status;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"