bug-coreutils
[Top][All Lists]
Advanced

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

Re: [OT] Is od broken?


From: Eric Blake
Subject: Re: [OT] Is od broken?
Date: Wed, 11 Jun 2008 18:22:18 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> 
> Gary noticed an issue with the indentation of multi-specifier od:
> 
> $ od -t cx1  abc.txt
> ~   0000000   T   h   i   s       i   s       a   b   c       f   i   l   e
> ~           54 68 69 73 20 69 73 20 61 62 63 20 66 69 6c 65
> ~   0000020  \n
> ~           0a
> ~   0000021
> 
> |> | That looks horrible!
> |>
> |> Not a compliance bug, but you are certainly welcome to report it upstream
> |> as an QoI enhancement request.
> 
> I gave this more thought.  Since od enforces that each output line consume
> a multiple of the lcm of input bytes per field, and it already knows how
> many bytes are output per field, then it should be possible to compute the
> amount of padding per field necessary to make all fields right-justified.
> ~ I'm working on a patch for this.
> 
> In looking at the code, there are also some simplifications when we heed
> autoconf's advice that HAVE_LONG_DOUBLE is an obsolete construct (ie. all
> reasonable porting targets support compilation of long double, and we use
> gnulib's printf to make up for libc deficiencies in printing long double,
> so that code does not need to be conditionally compiled).  I'll include a
> patch for that in my series.
> 
> --
> Don't work too hard, make some time for fun as well!
> 
> Eric Blake             ebb9 <at> byu.net
> 

Here's my attempt at a series to address this:

Eric Blake (3):
  od defaults to -toS, not -td2.
  Align multiple od -t specs.
  Simplify long double support.

 NEWS                     |    1 +
 THANKS                   |    1 +
 m4/jm-macros.m4          |    1 -
 src/od.c                 |  150 ++++++++++++++++++++++++++++------------------
 tests/Makefile.am        |    1 +
 tests/misc/od-multiple-t |   47 ++++++++++++++
 6 files changed, 142 insertions(+), 59 deletions(-)
 create mode 100755 tests/misc/od-multiple-t


I chose to use fixed-width padding for every field, rather than trying to be 
even more complicated by using variable-width padding to minimize the overall 
resulting line length.  The result thus has a lot of consecutive spaces for 
certain combinations of -t, but at least things are consistently aligned:

$  src/od -An -N48 configure -tx8 -tfL
        2f6e69622f202123        65754720230a6873        65756c6176207373
          0.000000000000000000e+9999          0.000000000000000000e+9999
        797320726f662073        7065642d6d657473        7620746e65646e65
          0.000000000000000000e+9999          0.000000000000000000e+9999

$  src/od -An -N48 configure -tx8                
 2f6e69622f202123 65754720230a6873
 65756c6176207373 797320726f662073
 7065642d6d657473 7620746e65646e65

$  src/od -An -N48 configure -tfL
 0.000000000000000000e+9999
 0.000000000000000000e+9999
 0.000000000000000000e+9999
 0.000000000000000000e+9999

I'm not sure why cygwin is printing such a weird value for (invalid) long 
doubles, but this patch didn't change the situation.  It seems like a NaN might 
be better than 0.0...e+9999 if the random 12-byte sequence can't be converted 
to a valid 10-byte register long double on x86.  Perhaps this is a bug in 
gnulib's printf replacement?


In case gmane botches this patch with line wraps, you could try the original 
file from here:
http://home.comcast.net/~ericblake/coreutils.patch7

From: Eric Blake <address@hidden>
Date: Wed, 11 Jun 2008 08:01:31 -0600
Subject: [PATCH] od defaults to -toS, not -td2.

* src/od.c (usage): Correct description of default.

Signed-off-by: Eric Blake <address@hidden>
---
 src/od.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/od.c b/src/od.c
index 4df8e7d..97e43ea 100644
--- a/src/od.c
+++ b/src/od.c
@@ -382,7 +382,7 @@ output line.  \
 "), stdout);
       fputs (_("\
 --string without a number implies 3.  --width without a number\n\
-implies 32.  By default, od uses -A o -t d2 -w16.\n\
+implies 32.  By default, od uses -A o -t oS -w16.\n\
 "), stdout);
       emit_bug_reporting_address ();
     }
-- 
1.5.5.1


>From 5700d58ce428655c7560c83249e971c90971ee28 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 11 Jun 2008 09:14:26 -0600
Subject: [PATCH] Align multiple od -t specs.

* src/od.c (struct tspec): Add pad_width field, and adjust
print_function prototype.
(decode_one_format): Default to pad width of 1, and rewrite all
fmt_string to account for pad width.
(FMT_BYTES_ALLOCATED): Adjust to new format style.
(main): Compute pad width per spec.
(write_block): Account for pad width.
(print_s_char, print_char, print_s_short, print_short, print_int)
(print_long, print_long_long, print_float, print_double)
(print_long_double, print_named_ascii, print_ascii): All print
functions adjusted to use pad width.
* tests/Makefile.am (TESTS): Add test.
* tests/misc/od-multiple-t: New file.
* THANKS: Update.
* NEWS: Mention the improvement.
Reported by Gary Johnson.

Signed-off-by: Eric Blake <address@hidden>
---
 NEWS                     |    1 +
 THANKS                   |    1 +
 src/od.c                 |  124 +++++++++++++++++++++++++++++++---------------
 tests/Makefile.am        |    1 +
 tests/misc/od-multiple-t |   47 +++++++++++++++++
 5 files changed, 134 insertions(+), 40 deletions(-)
 create mode 100755 tests/misc/od-multiple-t

diff --git a/NEWS b/NEWS
index 97f3162..cfaa3e6 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,7 @@ GNU coreutils NEWS
   HP-UX 11, Tru64, AIX, IRIX 6.5, and Cygwin, "ls -l" now displays the presence
   of an ACL on a file via a '+' sign after the mode, and "cp -p" copies ACLs.
 
+  od now aligns fields across lines when printing multiple -t specifiers.
 
 * Noteworthy changes in release 6.12 (2008-05-31) [stable]
 
diff --git a/THANKS b/THANKS
index cb9b098..a9bb12f 100644
--- a/THANKS
+++ b/THANKS
@@ -182,6 +182,7 @@ Gabor Z. Papp                       address@hidden
 Gaël Quéri                          address@hidden
 Galen Hazelwood                     address@hidden
 Gary Anderson                       address@hidden
+Gary Johnson                        address@hidden
 Gary V. Vaughan                     address@hidden
 Gaute Hvoslef Kvalnes               address@hidden
 Geoff Collyer                       geoff at collyer.net
diff --git a/src/od.c b/src/od.c
index 97e43ea..c0f06a7 100644
--- a/src/od.c
+++ b/src/od.c
@@ -92,13 +92,13 @@ enum output_format
 enum
   {
     FMT_BYTES_ALLOCATED =
-      MAX ((sizeof " %0" - 1 + INT_STRLEN_BOUND (int)
+      MAX ((sizeof "%*s%0" - 1 + INT_STRLEN_BOUND (int)
            + MAX (sizeof "ld",
                   MAX (sizeof PRIdMAX,
                        MAX (sizeof PRIoMAX,
                             MAX (sizeof PRIuMAX,
                                  sizeof PRIxMAX))))),
-          sizeof " %.Le" + 2 * INT_STRLEN_BOUND (int))
+          sizeof "%*s%.Le" + 2 * INT_STRLEN_BOUND (int))
   };
 
 /* Each output format specification (from `-t spec' or from
@@ -107,10 +107,11 @@ struct tspec
   {
     enum output_format fmt;
     enum size_spec size;
-    void (*print_function) (size_t, void const *, char const *);
+    void (*print_function) (size_t, void const *, char const *, int);
     char fmt_string[FMT_BYTES_ALLOCATED];
     bool hexl_mode_trailer;
     int field_width;
+    int pad_width;
   };
 
 /* Convert the number of 8-bit bytes of a binary representation to
@@ -392,94 +393,101 @@ implies 32.  By default, od uses
 /* Define the print functions.  */
 
 static void
-print_s_char (size_t n_bytes, void const *block, char const *fmt_string)
+print_s_char (size_t n_bytes, void const *block, char const *fmt_string,
+              int pad)
 {
   signed char const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_char (size_t n_bytes, void const *block, char const *fmt_string)
+print_char (size_t n_bytes, void const *block, char const *fmt_string,
+            int pad)
 {
   unsigned char const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_s_short (size_t n_bytes, void const *block, char const *fmt_string)
+print_s_short (size_t n_bytes, void const *block, char const *fmt_string,
+               int pad)
 {
   short int const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_short (size_t n_bytes, void const *block, char const *fmt_string)
+print_short (size_t n_bytes, void const *block, char const *fmt_string, int 
pad)
 {
   unsigned short int const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_int (size_t n_bytes, void const *block, char const *fmt_string)
+print_int (size_t n_bytes, void const *block, char const *fmt_string, int pad)
 {
   unsigned int const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_long (size_t n_bytes, void const *block, char const *fmt_string)
+print_long (size_t n_bytes, void const *block, char const *fmt_string, int pad)
 {
   unsigned long int const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_long_long (size_t n_bytes, void const *block, char const *fmt_string)
+print_long_long (size_t n_bytes, void const *block, char const *fmt_string,
+                 int pad)
 {
   unsigned_long_long_int const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_float (size_t n_bytes, void const *block, char const *fmt_string)
+print_float (size_t n_bytes, void const *block, char const *fmt_string,
+             int pad)
 {
   float const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 static void
-print_double (size_t n_bytes, void const *block, char const *fmt_string)
+print_double (size_t n_bytes, void const *block, char const *fmt_string,
+              int pad)
 {
   double const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 
 #ifdef HAVE_LONG_DOUBLE
 static void
-print_long_double (size_t n_bytes, void const *block, char const *fmt_string)
+print_long_double (size_t n_bytes, void const *block, char const *fmt_string,
+                   int pad)
 {
   long double const *p = block;
   size_t i;
   for (i = n_bytes / sizeof *p; i != 0; i--)
-    printf (fmt_string, *p++);
+    printf (fmt_string, pad, "", *p++);
 }
 #endif
 
@@ -499,7 +507,7 @@ dump_hexl_mode_trailer (size_t n_bytes,
 
 static void
 print_named_ascii (size_t n_bytes, void const *block,
-                  const char *unused_fmt_string ATTRIBUTE_UNUSED)
+                  const char *unused_fmt_string ATTRIBUTE_UNUSED, int pad)
 {
   unsigned char const *p = block;
   size_t i;
@@ -519,13 +527,13 @@ print_named_ascii (size_t n_bytes, void const *block,
          s = buf;
        }
 
-      printf (" %3s", s);
+      printf ("%*s%3s", pad, "", s);
     }
 }
 
 static void
 print_ascii (size_t n_bytes, void const *block,
-            const char *unused_fmt_string ATTRIBUTE_UNUSED)
+            const char *unused_fmt_string ATTRIBUTE_UNUSED, int pad)
 {
   unsigned char const *p = block;
   size_t i;
@@ -574,7 +582,7 @@ print_ascii (size_t n_bytes, void const *block,
          s = buf;
        }
 
-      printf (" %3s", s);
+      printf ("%*s%3s", pad, "", s);
     }
 }
 
@@ -614,7 +622,8 @@ simple_strtoul (const char *s, const char **p,
        fmt = SIGNED_DECIMAL;
        size = INT or LONG; (whichever integral_type_size[4] resolves to)
        print_function = print_int; (assuming size == INT)
-       fmt_string = "%011d%c";
+       fmt_string = "%*s%011d";
+       pad_width = 1; (but may be increased later)
       }
    S_ORIG is solely for reporting errors.  It should be the full format
    string argument.
@@ -628,7 +637,7 @@ decode_one_format (const char *s_orig, const
   unsigned long int size;
   enum output_format fmt;
   const char *pre_fmt_string;
-  void (*print_function) (size_t, void const *, char const *);
+  void (*print_function) (size_t, void const *, char const *, int);
   const char *p;
   char c;
   int field_width;
@@ -702,28 +711,28 @@ this system doesn't provide a %lu-byte
        {
        case 'd':
          fmt = SIGNED_DECIMAL;
-         sprintf (tspec->fmt_string, " %%%d%s",
+         sprintf (tspec->fmt_string, "%%*s%%%d%s",
                   (field_width = bytes_to_signed_dec_digits[size]),
                   ISPEC_TO_FORMAT (size_spec, "d", "ld", PRIdMAX));
          break;
 
        case 'o':
          fmt = OCTAL;
-         sprintf (tspec->fmt_string, " %%0%d%s",
+         sprintf (tspec->fmt_string, "%%*s%%0%d%s",
                   (field_width = bytes_to_oct_digits[size]),
                   ISPEC_TO_FORMAT (size_spec, "o", "lo", PRIoMAX));
          break;
 
        case 'u':
          fmt = UNSIGNED_DECIMAL;
-         sprintf (tspec->fmt_string, " %%%d%s",
+         sprintf (tspec->fmt_string, "%%*s%%%d%s",
                   (field_width = bytes_to_unsigned_dec_digits[size]),
                   ISPEC_TO_FORMAT (size_spec, "u", "lu", PRIuMAX));
          break;
 
        case 'x':
          fmt = HEXADECIMAL;
-         sprintf (tspec->fmt_string, " %%0%d%s",
+         sprintf (tspec->fmt_string, "%%*s%%0%d%s",
                   (field_width = bytes_to_hex_digits[size]),
                   ISPEC_TO_FORMAT (size_spec, "x", "lx", PRIxMAX));
          break;
@@ -817,20 +826,20 @@ this system doesn't provide a %lu-byte floating
        case FLOAT_SINGLE:
          print_function = print_float;
          /* Don't use %#e; not all systems support it.  */
-         pre_fmt_string = " %%%d.%de";
+         pre_fmt_string = "%%*s%%%d.%de";
          precision = FLT_DIG;
          break;
 
        case FLOAT_DOUBLE:
          print_function = print_double;
-         pre_fmt_string = " %%%d.%de";
+         pre_fmt_string = "%%*s%%%d.%de";
          precision = DBL_DIG;
          break;
 
 #ifdef HAVE_LONG_DOUBLE
        case FLOAT_LONG_DOUBLE:
          print_function = print_long_double;
-         pre_fmt_string = " %%%d.%dLe";
+         pre_fmt_string = "%%*s%%%d.%dLe";
          precision = LDBL_DIG;
          break;
 #endif
@@ -870,6 +879,7 @@ this system doesn't provide a %lu-byte floating
   tspec->print_function = print_function;
 
   tspec->field_width = field_width;
+  tspec->pad_width = 1;
   tspec->hexl_mode_trailer = (*s == 'z');
   if (tspec->hexl_mode_trailer)
     s++;
@@ -1198,13 +1208,14 @@ write_block (uintmax_t current_offset, size_t n_bytes,
            format_address (current_offset, '\0');
          else
            printf ("%*s", address_pad_len, "");
-         (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
+         (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string,
+                                     spec[i].pad_width);
          if (spec[i].hexl_mode_trailer)
            {
              /* space-pad out to full line width, then dump the trailer */
              int datum_width = width_bytes[spec[i].size];
              int blank_fields = (bytes_per_block - n_bytes) / datum_width;
-             int field_width = spec[i].field_width + 1;
+             int field_width = spec[i].field_width + spec[i].pad_width;
              printf ("%*s", blank_fields * field_width, "");
              dump_hexl_mode_trailer (n_bytes, curr_block);
            }
@@ -1555,6 +1566,7 @@ main (int argc, char **argv)
   bool modern = false;
   bool width_specified = false;
   bool ok = true;
+  size_t width_per_lcm = 0;
   static char const multipliers[] = "bEGKkMmPTYZ0";
 
   /* The old-style `pseudo starting address' to be printed in parentheses
@@ -1915,11 +1927,43 @@ it must be one character from [doxn]"),
        bytes_per_block = l_c_m;
     }
 
+  /* Compute padding necessary to align output block.  */
+  if (1 < n_specs)
+    {
+      for (i = 0; i < n_specs; i++)
+        {
+          int fields_per_lcm = l_c_m / width_bytes[spec[i].size];
+          int lcm_width = (spec[i].field_width + 1) * fields_per_lcm;
+          if (width_per_lcm < lcm_width)
+            {
+              width_per_lcm = lcm_width;
+              if (width_per_lcm % l_c_m)
+                width_per_lcm = ((width_per_lcm / l_c_m) + 1) * l_c_m;
+            }
+        }
+      for (i = 0; i < n_specs; i++)
+        {
+          int fields_per_block = bytes_per_block / width_bytes[spec[i].size];
+          int block_width = spec[i].field_width * fields_per_block;
+          spec[i].pad_width = ((width_per_lcm * (bytes_per_block / l_c_m)
+                                - block_width) / fields_per_block);
+        }
+    }
+
 #ifdef DEBUG
+  else
+    width_per_lcm = spec[0].field_width + 1;
+  printf (_("lcm=%d, width_per_lcm=%zu\n"), l_c_m, width_per_lcm);
   for (i = 0; i < n_specs; i++)
     {
-      printf (_("%d: fmt=\"%s\" width=%d\n"),
-             i, spec[i].fmt_string, width_bytes[spec[i].size]);
+      int fields_per_lcm = l_c_m / width_bytes[spec[i].size];
+      assert (bytes_per_block % width_bytes[spec[i].size] == 0);
+      assert (width_per_lcm == ((spec[i].field_width + spec[i].pad_width)
+                                * fields_per_lcm));
+      assert (spec[i].pad_width && spec[i].pad_width < width_per_lcm);
+      printf (_("%d: fmt=\"%s\" in_width=%d out_width=%d pad=%d\n"),
+             i, spec[i].fmt_string, width_bytes[spec[i].size],
+              spec[i].field_width, spec[i].pad_width);
     }
 #endif
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bc17299..d09e451 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -171,6 +171,7 @@ TESTS =                                             \
   misc/nl                                      \
   misc/nohup                                   \
   misc/od-N                                    \
+  misc/od-multiple-t                           \
   misc/od-x8                                   \
   misc/paste                                   \
   misc/pathchk1                                        \
diff --git a/tests/misc/od-multiple-t b/tests/misc/od-multiple-t
new file mode 100755
index 0000000..63fb7e4
--- /dev/null
+++ b/tests/misc/od-multiple-t
@@ -0,0 +1,47 @@
+#!/bin/sh
+# verify that multiple -t specifiers to od align well
+# This would fail before coreutils-6.13.
+
+# Copyright (C) 2008 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  od --version
+fi
+
+. $srcdir/test-lib.sh
+
+# Choose 48 bytes for the input, as that is lcm for 1, 2, 4, 8, 12, 16;
+# we don't anticipate any other native object size on modern hardware.
+seq 19 > in || framework_failure
+test `wc -c < in` -eq 48 || framework_failure
+
+fail=0
+
+list='a c dC dS dI dL oC oS oI oL uC uS uI uL xC xS xI xL fF fD fL'
+for format1 in $list; do
+  for format2 in $list; do
+    od -An -t${format1}z -t${format2}z in > out-raw || fail=1
+    linewidth=`head -n1 out-raw | wc -c`
+    linecount=`wc -l < out-raw`
+    echo $format1 $format2 `wc -c < out-raw` >> out
+    echo $format1 $format2 `expr $linewidth '*' $linecount` >> exp
+  done
+done
+
+compare out exp || fail=1
+
+(exit $fail); exit $fail
-- 
1.5.5.1


>From 79c3502e37ec5d898ceb1cc8bf13cac9fb9c9591 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 11 Jun 2008 11:45:16 -0600
Subject: [PATCH] Simplify long double support.

* m4/jm-macros.m4 (gl_CHECK_ALL_TYPES): Remove obsolete check for
AC_C_LONG_DOUBLE.
* src/od.c (LONG_DOUBLE): Delete.
(width_bytes, MAX_FP_TYPE_SIZE, decode_one_format, main): Just use
'long double' directly.
(print_long_double): No longer protect by HAVE_LONG_DOUBLE.

Signed-off-by: Eric Blake <address@hidden>
---
 m4/jm-macros.m4 |    1 -
 src/od.c        |   24 +++++++-----------------
 2 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4
index cf1f2f0..9680e95 100644
--- a/m4/jm-macros.m4
+++ b/m4/jm-macros.m4
@@ -140,7 +140,6 @@ AC_DEFUN([gl_CHECK_ALL_TYPES],
   AC_REQUIRE([AC_C_BIGENDIAN])
   AC_REQUIRE([AC_C_VOLATILE])
   AC_REQUIRE([AC_C_INLINE])
-  AC_REQUIRE([AC_C_LONG_DOUBLE])
   AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
 
   AC_REQUIRE([gl_CHECK_ALL_HEADERS])
diff --git a/src/od.c b/src/od.c
index c0f06a7..1d8b369 100644
--- a/src/od.c
+++ b/src/od.c
@@ -34,12 +34,6 @@
 
 #include <float.h>
 
-#ifdef HAVE_LONG_DOUBLE
-typedef long double LONG_DOUBLE;
-#else
-typedef double LONG_DOUBLE;
-#endif
-
 /* The default number of input bytes per output line.  */
 #define DEFAULT_BYTES_PER_BLOCK 16
 
@@ -160,7 +154,7 @@ static const int width_bytes[] =
   sizeof (unsigned_long_long_int),
   sizeof (float),
   sizeof (double),
-  sizeof (LONG_DOUBLE)
+  sizeof (long double)
 };
 
 /* Ensure that for each member of `enum size_spec' there is an
@@ -260,7 +254,7 @@ static bool have_read_stdin;
 /* Map the size in bytes to a type identifier.  */
 static enum size_spec integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1];
 
-#define MAX_FP_TYPE_SIZE sizeof (LONG_DOUBLE)
+#define MAX_FP_TYPE_SIZE sizeof (long double)
 static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1];
 
 static char const short_options[] = "A:aBbcDdeFfHhIij:LlN:OoS:st:vw::Xx";
@@ -479,7 +473,6 @@ print_double (size_t n_bytes, void const *block,
     printf (fmt_string, pad, "", *p++);
 }
 
-#ifdef HAVE_LONG_DOUBLE
 static void
 print_long_double (size_t n_bytes, void const *block, char const *fmt_string,
                    int pad)
@@ -489,7 +482,6 @@ print_long_double (size_t n_bytes, void const
   for (i = n_bytes / sizeof *p; i != 0; i--)
     printf (fmt_string, pad, "", *p++);
 }
-#endif
 
 static void
 dump_hexl_mode_trailer (size_t n_bytes, const char *block)
@@ -791,7 +783,7 @@ this system doesn't provide a %lu-byte
 
        case 'L':
          ++s;
-         size = sizeof (LONG_DOUBLE);
+         size = sizeof (long double);
          break;
 
        default:
@@ -836,13 +828,11 @@ this system doesn't provide a %lu-byte
          precision = DBL_DIG;
          break;
 
-#ifdef HAVE_LONG_DOUBLE
        case FLOAT_LONG_DOUBLE:
          print_function = print_long_double;
          pre_fmt_string = "%%*s%%%d.%dLe";
          precision = LDBL_DIG;
          break;
-#endif
 
        default:
          abort ();
@@ -1598,10 +1588,10 @@ main (int argc, char **argv)
     fp_type_size[i] = NO_SIZE;
 
   fp_type_size[sizeof (float)] = FLOAT_SINGLE;
-  /* The array entry for `double' is filled in after that for LONG_DOUBLE
-     so that if `long double' is the same type or if long double isn't
-     supported FLOAT_LONG_DOUBLE will never be used.  */
-  fp_type_size[sizeof (LONG_DOUBLE)] = FLOAT_LONG_DOUBLE;
+  /* The array entry for `double' is filled in after that for `long double'
+     so that if they are the same size, we avoid any overhead of
+     long double computation in libc.  */
+  fp_type_size[sizeof (long double)] = FLOAT_LONG_DOUBLE;
   fp_type_size[sizeof (double)] = FLOAT_DOUBLE;
 
   n_specs = 0;
-- 
1.5.5.1








reply via email to

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