Remove unnecessary casts of alloca, since now it's guaranteed to be (void *).
[platform/upstream/coreutils.git] / src / od.c
index 2e3f7f9..d362e66 100644 (file)
--- a/src/od.c
+++ b/src/od.c
@@ -1,5 +1,5 @@
 /* od -- dump files in octal and other formats
-   Copyright (C) 92, 1995-2002 Free Software Foundation, Inc.
+   Copyright (C) 92, 1995-2003 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
@@ -24,7 +24,6 @@
 #include <getopt.h>
 #include <sys/types.h>
 #include "system.h"
-#include "closeout.h"
 #include "error.h"
 #include "posixver.h"
 #include "xstrtol.h"
@@ -32,7 +31,7 @@
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "od"
 
-#define AUTHORS "Jim Meyering"
+#define WRITTEN_BY _("Written by Jim Meyering.")
 
 #if defined(__GNUC__) || defined(STDC_HEADERS)
 # include <float.h>
@@ -44,10 +43,6 @@ typedef long double LONG_DOUBLE;
 typedef double LONG_DOUBLE;
 #endif
 
-#if HAVE_VALUES_H
-# include <values.h>
-#endif
-
 /* The default number of input bytes per output line.  */
 #define DEFAULT_BYTES_PER_BLOCK 16
 
@@ -106,7 +101,7 @@ struct tspec
   {
     enum output_format fmt;
     enum size_spec size;
-    void (*print_function) PARAMS ((size_t, const char *, const char *));
+    void (*print_function) (size_t, const char *, const char *);
     char *fmt_string;
     int hexl_mode_trailer;
     int field_width;
@@ -197,7 +192,7 @@ static uintmax_t pseudo_offset;
 
 /* Function that accepts an address and an optional following char,
    and prints the address and char to stdout.  */
-static void (*format_address) PARAMS ((uintmax_t, char));
+static void (*format_address) (uintmax_t, char);
 
 /* The number of input bytes to skip before formatting and writing.  */
 static uintmax_t n_bytes_to_skip = 0;
@@ -371,7 +366,7 @@ of output.  \
 --string without a number implies 3.  --width without a number\n\
 implies 32.  By default, od uses -A o -t d2 -w 16.\n\
 "), stdout);
-      puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
+      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     }
   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
@@ -680,7 +675,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
   enum output_format fmt;
   const char *pre_fmt_string;
   char *fmt_string;
-  void (*print_function) PARAMS ((size_t, const char *, const char *));
+  void (*print_function) (size_t, const char *, const char *);
   const char *p;
   unsigned int c;
   unsigned int field_width = 0;
@@ -742,6 +737,11 @@ this system doesn't provide a %lu-byte integral type"), s_orig, size);
          break;
        }
 
+#define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format)     \
+  ((Spec) == LONG_LONG ? (Max_format)                                  \
+   : ((Spec) == LONG ? (Long_format)                                   \
+      : (Min_format)))                                                 \
+
 #define FMT_BYTES_ALLOCATED 9
       fmt_string = xmalloc (FMT_BYTES_ALLOCATED);
 
@@ -751,32 +751,30 @@ this system doesn't provide a %lu-byte integral type"), s_orig, size);
        {
        case 'd':
          fmt = SIGNED_DECIMAL;
-         sprintf (fmt_string, " %%%u%sd",
+         sprintf (fmt_string, " %%%u%s",
                   (field_width = bytes_to_signed_dec_digits[size]),
-                  (size_spec == LONG ? "l"
-                   : (size_spec == LONG_LONG ? "ll"
-                      : "")));
+                  ISPEC_TO_FORMAT (size_spec, "d", "ld", PRIdMAX));
          break;
 
        case 'o':
          fmt = OCTAL;
-         sprintf (fmt_string, " %%0%u%so",
+         sprintf (fmt_string, " %%0%u%s",
                   (field_width = bytes_to_oct_digits[size]),
-                  (size_spec == LONG ? "l" : ""));
+                  ISPEC_TO_FORMAT (size_spec, "o", "lo", PRIoMAX));
          break;
 
        case 'u':
          fmt = UNSIGNED_DECIMAL;
-         sprintf (fmt_string, " %%%u%su",
+         sprintf (fmt_string, " %%%u%s",
                   (field_width = bytes_to_unsigned_dec_digits[size]),
-                  (size_spec == LONG ? "l" : ""));
+                  ISPEC_TO_FORMAT (size_spec, "u", "lu", PRIuMAX));
          break;
 
        case 'x':
          fmt = HEXADECIMAL;
-         sprintf (fmt_string, " %%0%u%sx",
+         sprintf (fmt_string, " %%0%u%s",
                   (field_width = bytes_to_hex_digits[size]),
-                  (size_spec == LONG ? "l" : ""));
+                  ISPEC_TO_FORMAT (size_spec, "x", "lx", PRIxMAX));
          break;
 
        default:
@@ -984,10 +982,11 @@ open_next_file (void)
    it is not standard input.  Return nonzero if there has been an error
    on in_stream or stdout; return zero otherwise.  This function will
    report more than one error only if both a read and a write error
-   have occurred.  */
+   have occurred.  IN_ERRNO, if nonzero, is the error number
+   corresponding to the most recent action for IN_STREAM.  */
 
 static int
-check_and_close (void)
+check_and_close (int in_errno)
 {
   int err = 0;
 
@@ -995,7 +994,7 @@ check_and_close (void)
     {
       if (ferror (in_stream))
        {
-         error (0, errno, "%s", input_filename);
+         error (0, in_errno, _("%s: read error"), input_filename);
          if (in_stream != stdin)
            fclose (in_stream);
          err = 1;
@@ -1011,7 +1010,7 @@ check_and_close (void)
 
   if (ferror (stdout))
     {
-      error (0, errno, _("standard output"));
+      error (0, 0, _("write error"));
       err = 1;
     }
 
@@ -1042,9 +1041,7 @@ decode_format_string (const char *s)
       if (n_specs >= n_specs_allocated)
        {
          n_specs_allocated = 1 + (3 * n_specs_allocated) / 2;
-         spec = (struct tspec *) xrealloc ((char *) spec,
-                                           (n_specs_allocated
-                                            * sizeof (struct tspec)));
+         spec = xrealloc (spec, (n_specs_allocated * sizeof (struct tspec)));
        }
 
       memcpy ((char *) &spec[n_specs], (char *) &tspec,
@@ -1066,6 +1063,7 @@ static int
 skip (uintmax_t n_skip)
 {
   int err = 0;
+  int in_errno = 0;
 
   if (n_skip == 0)
     return 0;
@@ -1094,13 +1092,13 @@ skip (uintmax_t n_skip)
 
          if (S_ISREG (file_stats.st_mode) && 0 <= file_stats.st_size)
            {
-             if (file_stats.st_size <= n_skip)
+             if ((uintmax_t) file_stats.st_size <= n_skip)
                n_skip -= file_stats.st_size;
              else
                {
                  if (fseeko (in_stream, n_skip, SEEK_CUR) != 0)
                    {
-                     error (0, errno, "%s", input_filename);
+                     in_errno = errno;
                      err = 1;
                    }
                  n_skip = 0;
@@ -1122,7 +1120,12 @@ skip (uintmax_t n_skip)
                  n_bytes_read = fread (buf, 1, n_bytes_to_read, in_stream);
                  n_skip -= n_bytes_read;
                  if (n_bytes_read != n_bytes_to_read)
-                   break;
+                   {
+                     in_errno = errno;
+                     err = 1;
+                     n_skip = 0;
+                     break;
+                   }
                }
            }
 
@@ -1136,7 +1139,7 @@ skip (uintmax_t n_skip)
          err = 1;
        }
 
-      err |= check_and_close ();
+      err |= check_and_close (in_errno);
 
       err |= open_next_file ();
     }
@@ -1294,7 +1297,7 @@ read_char (int *c)
       if (*c != EOF)
        break;
 
-      err |= check_and_close ();
+      err |= check_and_close (errno);
 
       err |= open_next_file ();
     }
@@ -1341,7 +1344,7 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
       if (n_read == n_needed)
        break;
 
-      err |= check_and_close ();
+      err |= check_and_close (errno);
 
       err |= open_next_file ();
     }
@@ -1422,8 +1425,8 @@ dump (void)
   int err;
   size_t n_bytes_read;
 
-  block[0] = (char *) alloca (bytes_per_block);
-  block[1] = (char *) alloca (bytes_per_block);
+  block[0] = alloca (bytes_per_block);
+  block[1] = alloca (bytes_per_block);
 
   current_offset = n_bytes_to_skip;
 
@@ -1486,7 +1489,7 @@ dump (void)
   format_address (current_offset, '\n');
 
   if (limit_bytes_to_format && current_offset >= end_offset)
-    err |= check_and_close ();
+    err |= check_and_close (0);
 
   return err;
 }
@@ -1606,7 +1609,7 @@ dump_strings (void)
 
   free (buf);
 
-  err |= check_and_close ();
+  err |= check_and_close (0);
   return err;
 }
 
@@ -1629,6 +1632,7 @@ main (int argc, char **argv)
      after any true address.  */
   uintmax_t pseudo_start IF_LINT (= 0);
 
+  initialize_main (&argc, &argv);
   program_name = argv[0];
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
@@ -1646,6 +1650,8 @@ main (int argc, char **argv)
   integral_type_size[sizeof (int)] = INT;
   integral_type_size[sizeof (long int)] = LONG;
 #if HAVE_UNSIGNED_LONG_LONG
+  /* If `long' and `long long' have the same size, it's fine
+     to overwrite the entry for `long' with this one.  */
   integral_type_size[sizeof (ulonglong_t)] = LONG_LONG;
 #endif
 
@@ -1661,7 +1667,7 @@ main (int argc, char **argv)
 
   n_specs = 0;
   n_specs_allocated = 5;
-  spec = (struct tspec *) xmalloc (n_specs_allocated * sizeof (struct tspec));
+  spec = xmalloc (n_specs_allocated * sizeof (struct tspec));
 
   format_address = format_address_std;
   address_base = 8;
@@ -1809,10 +1815,10 @@ it must be one character from [doxn]"),
 
        case_GETOPT_HELP_CHAR;
 
-       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, WRITTEN_BY);
 
        default:
-         usage (1);
+         usage (EXIT_FAILURE);
          break;
        }
     }
@@ -1872,7 +1878,7 @@ it must be one character from [doxn]"),
              error (0, 0,
                     _("invalid second operand in compatibility mode `%s'"),
                     argv[optind + 1]);
-             usage (1);
+             usage (EXIT_FAILURE);
            }
        }
       else if (n_files == 3)
@@ -1892,14 +1898,14 @@ it must be one character from [doxn]"),
            {
              error (0, 0,
            _("in compatibility mode, the last two arguments must be offsets"));
-             usage (1);
+             usage (EXIT_FAILURE);
            }
        }
       else if (n_files > 3)
        {
          error (0, 0,
                 _("compatibility mode supports at most three arguments"));
-         usage (1);
+         usage (EXIT_FAILURE);
        }
 
       if (flag_pseudo_start)
@@ -1919,7 +1925,7 @@ it must be one character from [doxn]"),
     {
       end_offset = n_bytes_to_skip + max_bytes_to_format;
       if (end_offset < n_bytes_to_skip)
-       error (EXIT_FAILURE, 0, "skip-bytes + read-bytes is too large");
+       error (EXIT_FAILURE, 0, _("skip-bytes + read-bytes is too large"));
     }
 
   if (n_specs == 0)