bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

printf fix to match Bash behavior


From: Paul Eggert
Subject: printf fix to match Bash behavior
Date: Fri, 09 Jul 2004 00:34:06 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Bash printf uses long double to print floating-point numbers.  Here's
a patch to coreutils printf to be consistent.  With this patch, the
coreutils command "printf '%.17g\n' 0.1" prints 0.1 on an x86 host,
just as Bash does.  (Unfortunately this test case isn't portable.)

Index: lib/ChangeLog
===================================================================
RCS file: /home/meyering/coreutils/cu/lib/ChangeLog,v
retrieving revision 1.789
diff -p -u -r1.789 ChangeLog
--- lib/ChangeLog       7 Jul 2004 15:54:54 -0000       1.789
+++ lib/ChangeLog       9 Jul 2004 07:26:32 -0000
@@ -1,3 +1,12 @@
+2004-07-09  Paul Eggert  <address@hidden>
+
+       * Makefile.am (libfetish_a_SOURCES): Add c-strtold.c.
+       * c-strtold.c: New file.
+       * c-strtod.c: Include <config.h> first.
+       (C_STRTOD, DOUBLE, STRTOD): New macros.
+       (c_strtod): Use them.
+       * c-strtod.h (c_strtold): New decl.
+
 2004-07-07  Jim Meyering  <address@hidden>
 
        Don't infloop when MAXSYMLINKS is not defined.
Index: lib/Makefile.am
===================================================================
RCS file: /home/meyering/coreutils/cu/lib/Makefile.am,v
retrieving revision 1.188
diff -p -u -r1.188 Makefile.am
--- lib/Makefile.am     6 Jul 2004 16:56:21 -0000       1.188
+++ lib/Makefile.am     9 Jul 2004 06:13:12 -0000
@@ -42,7 +42,7 @@ libfetish_a_SOURCES = \
   argmatch.c argmatch.h \
   backupfile.c backupfile.h \
   basename.c \
-  c-strtod.c c-strtod.h \
+  c-strtod.c c-strtod.h c-strtold.c \
   canon-host.c \
   canonicalize.c canonicalize.h \
   cloexec.c cloexec.h \
--- /dev/null   2003-03-18 21:55:57 +0000
+++ lib/c-strtold.c     2004-07-09 06:44:25 +0000
@@ -0,0 +1,2 @@
+#define LONG 1
+#include "c-strtod.c"
Index: lib/c-strtod.c
===================================================================
RCS file: /home/meyering/coreutils/cu/lib/c-strtod.c,v
retrieving revision 1.3
diff -p -u -r1.3 c-strtod.c
--- lib/c-strtod.c      29 Nov 2003 12:01:51 -0000      1.3
+++ lib/c-strtod.c      9 Jul 2004 06:43:49 -0000
@@ -1,6 +1,6 @@
 /* Convert string to double, using the C locale.
 
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -18,6 +18,10 @@
 
 /* Written by Paul Eggert.  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include "c-strtod.h"
 
 #include <locale.h>
@@ -25,10 +29,25 @@
 
 #include "xalloc.h"
 
-double
-c_strtod (char const *nptr, char **endptr)
+#if LONG
+# define C_STRTOD c_strtold
+# define DOUBLE long double
+#else
+# define C_STRTOD c_strtod
+# define DOUBLE double
+#endif
+
+/* c_strtold falls back on strtod if strtold isn't declared.  */
+#if LONG && HAVE_DECL_STRTOLD
+# define STRTOD strtold
+#else
+# define STRTOD strtod
+#endif
+
+DOUBLE
+C_STRTOD (char const *nptr, char **endptr)
 {
-  double r;
+  DOUBLE r;
   char *saved_locale = setlocale (LC_NUMERIC, NULL);
 
   if (saved_locale)
@@ -37,7 +56,7 @@ c_strtod (char const *nptr, char **endpt
       setlocale (LC_NUMERIC, "C");
     }
 
-  r = strtod (nptr, endptr);
+  r = STRTOD (nptr, endptr);
 
   if (saved_locale)
     {
Index: lib/c-strtod.h
===================================================================
RCS file: /home/meyering/coreutils/cu/lib/c-strtod.h,v
retrieving revision 1.1
diff -p -u -r1.1 c-strtod.h
--- lib/c-strtod.h      27 Nov 2003 07:46:01 -0000      1.1
+++ lib/c-strtod.h      7 Jul 2004 18:13:17 -0000
@@ -1 +1,2 @@
 double c_strtod (char const *, char **);
+long double c_strtold (char const *, char **);
Index: m4/ChangeLog
===================================================================
RCS file: /home/meyering/coreutils/cu/m4/ChangeLog,v
retrieving revision 1.590
diff -p -u -r1.590 ChangeLog
--- m4/ChangeLog        6 Jul 2004 16:17:25 -0000       1.590
+++ m4/ChangeLog        9 Jul 2004 07:11:32 -0000
@@ -1,3 +1,8 @@
+2004-07-09  Paul Eggert  <address@hidden>
+
+       * c-strtod.m4: New file.
+       * prereq.m4 (gl_PREREQ): Add gl_C_STRTOLD.
+
 2004-04-03  Dmitry V. Levin  <address@hidden>
 
        * m4/canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME):
--- /dev/null   2003-03-18 21:55:57 +0000
+++ m4/c-strtod.m4      2004-07-09 07:16:55 +0000
@@ -0,0 +1,32 @@
+# c-strtod.m4 serial 1
+
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+# Written by Paul Eggert.
+
+AC_DEFUN([gl_C_STRTOD],
+[
+  dnl Prerequisites of lib/c-strtod.c.
+  :
+])
+
+AC_DEFUN([gl_C_STRTOLD],
+[
+  dnl Prerequisites of lib/c-strtold.c.
+  AC_REQUIRE([gl_C_STRTOD])
+  AC_CHECK_DECLS_ONCE([strtold])
+])
Index: m4/prereq.m4
===================================================================
RCS file: /home/meyering/coreutils/cu/m4/prereq.m4,v
retrieving revision 1.90
diff -p -u -r1.90 prereq.m4
--- m4/prereq.m4        20 Apr 2004 09:19:27 -0000      1.90
+++ m4/prereq.m4        9 Jul 2004 06:18:55 -0000
@@ -1,4 +1,4 @@
-#serial 40
+#serial 41
 
 dnl We use gl_ for non Autoconf macros.
 m4_pattern_forbid([^gl_[ABCDEFGHIJKLMNOPQRSTUVXYZ]])dnl
@@ -17,6 +17,7 @@ AC_DEFUN([gl_PREREQ],
   AC_REQUIRE([gl_FUNC_MKSTEMP])
   AC_REQUIRE([gl_ALLOCSA])
   AC_REQUIRE([gl_BACKUPFILE])
+  AC_REQUIRE([gl_C_STRTOLD])
   AC_REQUIRE([gl_CANON_HOST])
   AC_REQUIRE([gl_CLOEXEC])
   AC_REQUIRE([gl_CLOSEOUT])
Index: ChangeLog
===================================================================
RCS file: /home/meyering/coreutils/cu/ChangeLog,v
retrieving revision 1.980
diff -p -u -r1.980 ChangeLog
--- ChangeLog   8 Jul 2004 14:01:59 -0000       1.980
+++ ChangeLog   9 Jul 2004 07:30:13 -0000
@@ -1,3 +1,10 @@
+2004-07-09  Paul Eggert  <address@hidden>
+
+       * src/printf.c (vstrtold): Renamed from vstrtod.
+       Now returns long double.  All uses changed.
+       (print_direc): Use "L" length modifier when printing floating point
+       numbers, since we're now printing long double.
+       
 2004-07-06  Paul Eggert  <address@hidden>
 
        * Version 5.3.0.
Index: src/printf.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/printf.c,v
retrieving revision 1.91
diff -p -u -r1.91 printf.c
--- src/printf.c        8 Jul 2004 14:01:49 -0000       1.91
+++ src/printf.c        9 Jul 2004 07:14:18 -0000
@@ -183,9 +183,9 @@ FUNC_NAME (char const *s)                                   
         \
   return val;                                                           \
 }                                                                       \
 
-STRTOX (intmax_t,  vstrtoimax, (strtoimax (s, &end, 0)))
-STRTOX (uintmax_t, vstrtoumax, (strtoumax (s, &end, 0)))
-STRTOX (double,    vstrtod,    (c_strtod (s, &end)))
+STRTOX (intmax_t,    vstrtoimax, (strtoimax (s, &end, 0)))
+STRTOX (uintmax_t,   vstrtoumax, (strtoumax (s, &end, 0)))
+STRTOX (long double, vstrtold,   (c_strtold (s, &end)))
 
 /* Output a single-character \ escape.  */
 
@@ -334,22 +334,31 @@ print_direc (const char *start, size_t l
      integer length modifier.  */
   {
     char *q;
+    char const *length_modifier;
     size_t length_modifier_len;
 
     switch (conversion)
       {
       case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
+       length_modifier = PRIdMAX;
        length_modifier_len = sizeof PRIdMAX - 2;
        break;
 
+      case 'a': case 'e': case 'f': case 'g':
+      case 'A': case 'E': case 'F': case 'G':
+       length_modifier = "L";
+       length_modifier_len = 1;
+       break;
+
       default:
+       length_modifier = start;  /* Any valid pointer will do.  */
        length_modifier_len = 0;
        break;
       }
 
     p = xmalloc (length + length_modifier_len + 2);
     q = mempcpy (p, start, length);
-    q = mempcpy (q, PRIdMAX, length_modifier_len);
+    q = mempcpy (q, length_modifier, length_modifier_len);
     *q++ = conversion;
     *q = '\0';
   }
@@ -409,7 +418,7 @@ print_direc (const char *start, size_t l
     case 'g':
     case 'G':
       {
-       double arg = vstrtod (argument);
+       long double arg = vstrtold (argument);
        if (!have_field_width)
          {
            if (!have_precision)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]