]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Prefer C99 formats like %jd to doing it by hand
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 2 Aug 2024 02:31:50 +0000 (19:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 4 Aug 2024 08:41:43 +0000 (01:41 -0700)
It’s now safe to assume support for C99 formats like %jd, so remove
some of the longwinded formatting code put in only to be portable to
pre-C99 platforms.
* gnulib.modules: Add intprops.
* src/buffer.c (format_total_stats, try_new_volume)
(write_volume_label):
* src/checkpoint.c (format_checkpoint_string):
* src/compare.c (verify_volume):
* src/create.c (to_chars_subst, dump_regular_file):
* src/incremen.c (read_num):
* src/list.c (read_and, from_header, simple_print_header)
(print_for_mkdir):
* src/sparse.c (sparse_dump_region):
* src/system.c (dec_to_env, sys_exec_info_script)
(sys_exec_checkpoint_script):
* src/xheader.c (out_of_range_header):
Prefer C99 formats like %jd and %ju to STRINGIFY_BIGINT.
* src/common.h: Sort includes.
Include intprops.h, verify.h.  All other includes of verify.h
removed.
(intmax, uintmax): New functions and macros.
(STRINGIFY_BIGINT): Remove; no longer used.
(TIMESPEC_STRSIZE_BOUND): Make it 1 byte bigger, for negatives.
* src/create.c (MAX_VAL_WITH_DIGITS, to_base256):
Use *_WIDTH macros rather than assuming no padding bits.
Prefer UINTMAX_MAX to (uintmax_t) -1.
* src/list.c (tartime): Use strftime result rather
than running strlen later.
* src/misc.c (timetostr): New function.  Prefer it when
printing time_t values.

13 files changed:
gnulib.modules
src/buffer.c
src/checkpoint.c
src/common.h
src/compare.c
src/create.c
src/incremen.c
src/list.c
src/misc.c
src/sparse.c
src/system.c
src/tar.c
src/xheader.c

index 8c4e8e8e38ac100a230442e034e34639ca1a50b2..4dc35be48e3b57d561f18ace2b7073032f9a617b 100644 (file)
@@ -63,6 +63,7 @@ gitlog-to-changelog
 hash
 human
 idx
+intprops
 inttostr
 inttypes
 largefile
index b55a132c2775236ca5d42389f4b3f6d64e032e11..e76ee9b7fbce1fdd6617d0a398941884b065eb00 100644 (file)
@@ -28,7 +28,6 @@
 #include <fnmatch.h>
 #include <human.h>
 #include <quotearg.h>
-#include <verify.h>
 
 #include "common.h"
 #include <rmt.h>
@@ -543,7 +542,6 @@ format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
 
     case DELETE_SUBCOMMAND:
       {
-        char buf[UINTMAX_STRSIZE_BOUND];
         n = print_stats (fp, formats[TF_READ],
                         records_read * record_size);
 
@@ -553,15 +551,10 @@ format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
         n += print_stats (fp, formats[TF_WRITE],
                          prev_written + bytes_written);
 
-       fputc (eor, fp);
-       n++;
-
-       if (formats[TF_DELETED] && formats[TF_DELETED][0])
-         n += fprintf (fp, "%s: ", gettext (formats[TF_DELETED]));
-        n += fprintf (fp, "%s",
-                     STRINGIFY_BIGINT ((records_read - records_skipped)
-                                       * record_size
-                                       - (prev_written + bytes_written), buf));
+       intmax_t deleted = ((records_read - records_skipped) * record_size
+                           - (prev_written + bytes_written));
+       n += fprintf (fp, "%c%s: %jd", eor, gettext (formats[TF_DELETED]),
+                     deleted);
       }
       break;
 
@@ -1528,7 +1521,6 @@ try_new_volume (void)
 
   if (bufmap_head)
     {
-      uintmax_t s;
       if (!continued_file_name)
        {
          WARN ((0, 0, _("%s is not continued on this volume"),
@@ -1553,34 +1545,25 @@ try_new_volume (void)
             }
         }
 
-      s = continued_file_size + continued_file_offset;
-
-      if (bufmap_head->sizetotal != s || s < continued_file_offset)
+      uintmax_t s;
+      if (ckd_add (&s, continued_file_size, continued_file_offset)
+         || s != bufmap_head->sizetotal)
         {
-          char totsizebuf[UINTMAX_STRSIZE_BOUND];
-          char s1buf[UINTMAX_STRSIZE_BOUND];
-          char s2buf[UINTMAX_STRSIZE_BOUND];
-
-          WARN ((0, 0, _("%s is the wrong size (%s != %s + %s)"),
+         WARN ((0, 0, _("%s is the wrong size (%jd != %ju + %ju)"),
                  quote (continued_file_name),
-                 STRINGIFY_BIGINT (bufmap_head->sizetotal, totsizebuf),
-                 STRINGIFY_BIGINT (continued_file_size, s1buf),
-                 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
+                intmax (bufmap_head->sizetotal),
+                uintmax (continued_file_size),
+                uintmax (continued_file_offset)));
           return false;
         }
 
-      if (bufmap_head->sizetotal - bufmap_head->sizeleft !=
-         continued_file_offset)
+      if (bufmap_head->sizetotal - bufmap_head->sizeleft
+         != continued_file_offset)
         {
-          char totsizebuf[UINTMAX_STRSIZE_BOUND];
-          char s1buf[UINTMAX_STRSIZE_BOUND];
-          char s2buf[UINTMAX_STRSIZE_BOUND];
-
-          WARN ((0, 0, _("This volume is out of sequence (%s - %s != %s)"),
-                 STRINGIFY_BIGINT (bufmap_head->sizetotal, totsizebuf),
-                 STRINGIFY_BIGINT (bufmap_head->sizeleft, s1buf),
-                 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
-
+         WARN ((0, 0, _("This volume is out of sequence (%jd - %jd != %ju)"),
+                intmax (bufmap_head->sizetotal),
+                intmax (bufmap_head->sizeleft),
+                uintmax (continued_file_offset)));
           return false;
         }
     }
@@ -1700,11 +1683,9 @@ _write_volume_label (const char *str)
 static void
 add_volume_label (void)
 {
-  char buf[UINTMAX_STRSIZE_BOUND];
-  char *p = STRINGIFY_BIGINT (volno, buf);
   char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX
-                     + strlen (p) + 2);
-  sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p);
+                    + INT_BUFSIZE_BOUND (int) + 2);
+  sprintf (s, "%s %s %d", volume_label_option, VOL_SUFFIX, volno);
   _write_volume_label (s);
   free (s);
 }
index 8194463e8db34258357f849a11a7b3bcc27272e6..1a658cad3bc310845031b7c5c49cf1fb9ff46554 100644 (file)
@@ -234,8 +234,6 @@ format_checkpoint_string (FILE *fp, size_t len,
                          unsigned cpn)
 {
   const char *opstr = do_write ? gettext ("write") : gettext ("read");
-  char uintbuf[UINTMAX_STRSIZE_BOUND];
-  char *cps = STRINGIFY_BIGINT (cpn, uintbuf);
   const char *ip;
 
   static char *argbuf = NULL;
@@ -281,8 +279,7 @@ format_checkpoint_string (FILE *fp, size_t len,
              break;
 
            case 'u':
-             fputs (cps, fp);
-             len += strlen (cps);
+             len += fprintf (fp, "%u", cpn);
              break;
 
            case 's':
index c65e64d691f33db6e80fdd9ea9d9d3ab89f5068c..c2c22fc3a0d7347e557236e10f3b36ac5631a170 100644 (file)
 
 \f
 #include "arith.h"
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+#include <obstack.h>
+
 #include <attribute.h>
 #include <backupfile.h>
 #include <exclude.h>
+#include <full-read.h>
 #include <full-write.h>
 #include <idx.h>
+#include <intprops.h>
 #include <inttostr.h>
 #include <modechange.h>
+#include <paxlib.h>
+#include <progname.h>
 #include <quote.h>
 #include <safe-read.h>
-#include <full-read.h>
 #include <stat-time.h>
 #include <timespec.h>
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-#include <obstack.h>
-#include <progname.h>
+#include <verify.h>
 #include <xvasprintf.h>
 
-#include <paxlib.h>
-
 /* Log base 2 of common values.  */
 #define LG_8 3
 #define LG_64 6
@@ -661,6 +664,23 @@ char *namebuf_name (namebuf_t buf, const char *name);
 
 const char *tar_dirname (void);
 
+/* intmax (N) is like ((intmax_t) (N)) except without a cast so
+   that it is an error if N is a pointer.  Similarly for uintmax.  */
+COMMON_INLINE intmax_t
+intmax (intmax_t n)
+{
+  return n;
+}
+COMMON_INLINE uintmax_t
+uintmax (uintmax_t n)
+{
+  return n;
+}
+/* intmax should be used only with signed types, and uintmax for unsigned.
+   To bypass this check parenthesize the function, e.g., (intmax) (n).  */
+#define intmax(n) verify_expr (EXPR_SIGNED (n), (intmax) (n))
+#define uintmax(n) verify_expr (!EXPR_SIGNED (n), (uintmax) (n))
+
 /* Represent N using a signed integer I such that (uintmax_t) I == N.
    With a good optimizing compiler, this is equivalent to (intmax_t) i
    and requires zero machine instructions.  */
@@ -679,18 +699,18 @@ represent_uintmax (uintmax_t n)
     }
 }
 
-#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b)
 enum { UINTMAX_STRSIZE_BOUND = INT_BUFSIZE_BOUND (intmax_t) };
 enum { SYSINT_BUFSIZE =
         max (UINTMAX_STRSIZE_BOUND, INT_BUFSIZE_BOUND (intmax_t)) };
 char *sysinttostr (uintmax_t, intmax_t, uintmax_t, char buf[SYSINT_BUFSIZE]);
 intmax_t strtosysint (char const *, char **, intmax_t, uintmax_t);
+char *timetostr (time_t, char buf[SYSINT_BUFSIZE]);
 void code_ns_fraction (int ns, char *p);
 enum { BILLION = 1000000000, LOG10_BILLION = 9 };
 enum { TIMESPEC_STRSIZE_BOUND =
-         UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 };
+         SYSINT_BUFSIZE + LOG10_BILLION + sizeof "." - 1 };
 char const *code_timespec (struct timespec ts,
-                          char sbuf[TIMESPEC_STRSIZE_BOUND]);
+                          char tsbuf[TIMESPEC_STRSIZE_BOUND]);
 struct timespec decode_timespec (char const *, char **, bool);
 
 /* Return true if T does not represent an out-of-range or invalid value.  */
index 4c3162d00dad6a922ea434bd99bafcbe788d23c3..deb9b92efd745b343558d7b62440a3fa3671f89d 100644 (file)
@@ -607,15 +607,13 @@ verify_volume (void)
          set_next_block_after (current_header);
           if (!ignore_zeros_option)
             {
-             char buf[UINTMAX_STRSIZE_BOUND];
-
              status = read_header (&current_header, &current_stat_info,
                                    read_header_auto);
              if (status == HEADER_ZERO_BLOCK)
                break;
              WARNOPT (WARN_ALONE_ZERO_BLOCK,
-                      (0, 0, _("A lone zero block at %s"),
-                       STRINGIFY_BIGINT (current_block_ordinal (), buf)));
+                      (0, 0, _("A lone zero block at %jd"),
+                       intmax (current_block_ordinal ())));
             }
          continue;
        }
index 344bd6d347a409b217214333176097ab16d8c0fc..c3d88d6c33e5c08cbb01fa2de29ab3b6e7622ae4 100644 (file)
@@ -125,9 +125,9 @@ cachedir_file_p (int fd)
 /* The maximum uintmax_t value that can be represented with DIGITS digits,
    assuming that each digit is BITS_PER_DIGIT wide.  */
 #define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
-   ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
+   ((digits) * (bits_per_digit) < UINTMAX_WIDTH \
     ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
-    : (uintmax_t) -1)
+    : UINTMAX_MAX)
 
 /* The maximum uintmax_t value that can be represented with octal
    digits and a trailing NUL in BUFFER.  */
@@ -185,7 +185,7 @@ to_base256 (bool negative, uintmax_t value, char *where, size_t size)
 {
   uintmax_t v = value;
   uintmax_t propagated_sign_bits =
-    ((uintmax_t) - negative << (CHAR_BIT * sizeof v - LG_256));
+    ((uintmax_t) - negative << (UINTMAX_WIDTH - LG_256));
   size_t i = size;
 
   do
@@ -218,31 +218,12 @@ to_chars_subst (bool negative, bool gnu_format, uintmax_t value, size_t valsize,
   uintmax_t maxval = (gnu_format
                      ? MAX_VAL_WITH_DIGITS (size - 1, LG_256)
                      : MAX_VAL_WITH_DIGITS (size - 1, LG_8));
-  char valbuf[UINTMAX_STRSIZE_BOUND + 1];
-  char maxbuf[UINTMAX_STRSIZE_BOUND];
-  char minbuf[UINTMAX_STRSIZE_BOUND + 1];
-  char const *minval_string;
-  char const *maxval_string = STRINGIFY_BIGINT (maxval, maxbuf);
-  char const *value_string;
-
-  if (gnu_format)
-    {
-      uintmax_t m = maxval + 1 ? maxval + 1 : maxval / 2 + 1;
-      char *p = STRINGIFY_BIGINT (m, minbuf + 1);
-      *--p = '-';
-      minval_string = p;
-    }
-  else
-    minval_string = "0";
-
+  intmax_t minval = (!gnu_format ? 0
+                    : ckd_sub (&minval, -1, maxval) ? INTMAX_MIN
+                    : minval);
+  char const *valuesign = &"-"[!negative];
   if (negative)
-    {
-      char *p = STRINGIFY_BIGINT (- value, valbuf + 1);
-      *--p = '-';
-      value_string = p;
-    }
-  else
-    value_string = STRINGIFY_BIGINT (value, valbuf);
+    value = -value;
 
   if (substitute)
     {
@@ -256,18 +237,15 @@ to_chars_subst (bool negative, bool gnu_format, uintmax_t value, size_t valsize,
 
         Apart from this they are completely identical. */
       uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub;
-      char subbuf[UINTMAX_STRSIZE_BOUND + 1];
-      char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1);
-      if (negsub)
-       *--sub_string = '-';
-      WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
-            value_string, type, minval_string, maxval_string,
-            sub_string));
+      char const *ssign = &"-"[!negsub];
+      WARN ((0, 0, _("value %s%ju out of %s range %jd..%ju;"
+                    " substituting %s%ju"),
+            valuesign, value, type, minval, maxval, ssign, s));
       return to_chars (negsub, s, valsize, 0, where, size, type);
     }
   else
-    ERROR ((0, 0, _("value %s out of %s range %s..%s"),
-           value_string, type, minval_string, maxval_string));
+    ERROR ((0, 0, _("value %s%ju out of %s range %jd..%ju"),
+           valuesign, value, type, minval, maxval));
   return false;
 }
 
@@ -1097,15 +1075,16 @@ dump_regular_file (int fd, struct tar_stat_info *st)
 
       if (count != bufsize)
        {
-         char buf[UINTMAX_STRSIZE_BOUND];
          memset (blk->buffer + count, 0, bufsize - count);
          WARNOPT (WARN_FILE_SHRANK,
                   (0, 0,
-                   ngettext ("%s: File shrank by %s byte; padding with zeros",
-                             "%s: File shrank by %s bytes; padding with zeros",
+                   ngettext (("%s: File shrank by %jd byte;"
+                              " padding with zeros"),
+                             ("%s: File shrank by %jd bytes;"
+                              " padding with zeros"),
                              size_left),
                    quotearg_colon (st->orig_file_name),
-                   STRINGIFY_BIGINT (size_left, buf)));
+                   intmax (size_left)));
          if (! ignore_failed_read_option)
            set_exit_status (TAREXIT_DIFFERS);
          pad_archive (size_left - (bufsize - count));
index 11b0f5461731406c7ef2a262b80037f4d6e885c9..41dc8b1053bc35f3ec97d3154ae6069c87a074cf 100644 (file)
@@ -1126,9 +1126,6 @@ read_num (FILE *fp, char const *fieldname,
 {
   int i;
   char buf[INT_BUFSIZE_BOUND (intmax_t)];
-  char offbuf[INT_BUFSIZE_BOUND (off_t)];
-  char minbuf[INT_BUFSIZE_BOUND (intmax_t)];
-  char maxbuf[INT_BUFSIZE_BOUND (intmax_t)];
   int conversion_errno;
   int c = getc (fp);
   bool negative = c == '-';
@@ -1138,9 +1135,9 @@ read_num (FILE *fp, char const *fieldname,
       buf[i] = c;
       if (i == sizeof buf - 1)
        FATAL_ERROR ((0, 0,
-                     _("%s: byte %s: %s %.*s... too long"),
+                     _("%s: byte %jd: %s %.*s... too long"),
                      quotearg_colon (listed_incremental_option),
-                     offtostr (ftello (fp), offbuf),
+                     intmax (ftello (fp)),
                      fieldname, i + 1, buf));
       c = getc (fp);
     }
@@ -1162,9 +1159,9 @@ read_num (FILE *fp, char const *fieldname,
     {
       unsigned uc = c;
       FATAL_ERROR ((0, 0,
-                   _("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
+                   _("%s: byte %jd: %s %s followed by invalid byte 0x%02x"),
                    quotearg_colon (listed_incremental_option),
-                   offtostr (ftello (fp), offbuf),
+                   intmax (ftello (fp)),
                    fieldname, buf, uc));
     }
 
@@ -1175,16 +1172,14 @@ read_num (FILE *fp, char const *fieldname,
     {
     case ERANGE:
       FATAL_ERROR ((0, conversion_errno,
-                   _("%s: byte %s: (valid range %s..%s)\n\t%s %s"),
+                   _("%s: byte %jd: (valid range %jd..%ju)\n\t%s %s"),
                    quotearg_colon (listed_incremental_option),
-                   offtostr (ftello (fp), offbuf),
-                   imaxtostr (min_val, minbuf),
-                   umaxtostr (max_val, maxbuf), fieldname, buf));
+                   intmax (ftello (fp)), min_val, max_val, fieldname, buf));
     default:
       FATAL_ERROR ((0, conversion_errno,
-                   _("%s: byte %s: %s %s"),
+                   _("%s: byte %jd: %s %s"),
                    quotearg_colon (listed_incremental_option),
-                   offtostr (ftello (fp), offbuf), fieldname, buf));
+                   intmax (ftello (fp)), fieldname, buf));
     case 0:
       break;
     }
@@ -1420,11 +1415,10 @@ write_directory_file_entry (void *entry, void *data)
 
       s = DIR_IS_NFS (directory) ? "1" : "0";
       fwrite (s, 2, 1, fp);
-      s = sysinttostr (directory->mtime.tv_sec, TYPE_MINIMUM (time_t),
-                      TYPE_MAXIMUM (time_t), buf);
-      fwrite (s, strlen (s) + 1, 1, fp);
-      s = imaxtostr (directory->mtime.tv_nsec, buf);
+      s = timetostr (directory->mtime.tv_sec, buf);
       fwrite (s, strlen (s) + 1, 1, fp);
+      int ns = directory->mtime.tv_nsec;
+      fprintf (fp, "%d%c", ns, 0);
       s = sysinttostr (directory->device_number,
                       TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
       fwrite (s, strlen (s) + 1, 1, fp);
@@ -1454,26 +1448,20 @@ void
 write_directory_file (void)
 {
   FILE *fp = listed_incremental_stream;
-  char buf[UINTMAX_STRSIZE_BOUND];
-  char *s;
-
   if (! fp)
     return;
 
-  if (fseeko (fp, 0L, SEEK_SET) != 0)
+  if (fseeko (fp, 0, SEEK_SET) != 0)
     seek_error (listed_incremental_option);
   if (sys_truncate (fileno (fp)) != 0)
     truncate_error (listed_incremental_option);
 
-  fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
-          TAR_INCREMENTAL_VERSION);
-
-  s = (TYPE_SIGNED (time_t)
-       ? imaxtostr (start_time.tv_sec, buf)
-       : umaxtostr (start_time.tv_sec, buf));
-  fwrite (s, strlen (s) + 1, 1, fp);
-  s = umaxtostr (start_time.tv_nsec, buf);
-  fwrite (s, strlen (s) + 1, 1, fp);
+  int nsec = start_time.tv_nsec;
+  char buf[SYSINT_BUFSIZE];
+  fprintf (fp, "%s-%s-%d\n%s%c%d%c",
+          PACKAGE_NAME, PACKAGE_VERSION, TAR_INCREMENTAL_VERSION,
+          timetostr (start_time.tv_sec, buf),
+          0, nsec, 0);
 
   if (! ferror (fp) && directory_table)
     hash_do_for_each (directory_table, write_directory_file_entry, fp);
index f829f1b86c00ce9ed0c84558d143c299020efa24..f7f22c986a0d4d087030f89a8273643698eb2c15 100644 (file)
@@ -232,25 +232,20 @@ read_and (void (*do_something) (void))
 
        case HEADER_ZERO_BLOCK:
          if (block_number_option)
-           {
-             char buf[UINTMAX_STRSIZE_BOUND];
-             fprintf (stdlis, _("block %s: ** Block of NULs **\n"),
-                      STRINGIFY_BIGINT (current_block_ordinal (), buf));
-           }
+           fprintf (stdlis, _("block %jd: ** Block of NULs **\n"),
+                    intmax (current_block_ordinal ()));
 
          set_next_block_after (current_header);
 
          if (!ignore_zeros_option)
            {
-             char buf[UINTMAX_STRSIZE_BOUND];
-
              status = read_header (&current_header, &current_stat_info,
                                    read_header_auto);
              if (status == HEADER_ZERO_BLOCK)
                break;
              WARNOPT (WARN_ALONE_ZERO_BLOCK,
-                      (0, 0, _("A lone zero block at %s"),
-                       STRINGIFY_BIGINT (current_block_ordinal (), buf)));
+                      (0, 0, _("A lone zero block at %jd"),
+                       intmax (current_block_ordinal ())));
              break;
            }
          status = prev_status;
@@ -258,18 +253,12 @@ read_and (void (*do_something) (void))
 
        case HEADER_END_OF_FILE:
          if (!ignore_zeros_option)
-           {
-             char buf[UINTMAX_STRSIZE_BOUND];
-             WARNOPT (WARN_MISSING_ZERO_BLOCKS,
-                      (0, 0, _("Terminating zero blocks missing at %s"),
-                       STRINGIFY_BIGINT (current_block_ordinal (), buf)));
-           }
+           WARNOPT (WARN_MISSING_ZERO_BLOCKS,
+                    (0, 0, _("Terminating zero blocks missing at %jd"),
+                     intmax (current_block_ordinal ())));
          if (block_number_option)
-           {
-             char buf[UINTMAX_STRSIZE_BOUND];
-             fprintf (stdlis, _("block %s: ** End of File **\n"),
-                      STRINGIFY_BIGINT (current_block_ordinal (), buf));
-           }
+           fprintf (stdlis, _("block %jd: ** End of File **\n"),
+                    intmax (current_block_ordinal ()));
          break;
 
        case HEADER_FAILURE:
@@ -285,12 +274,11 @@ read_and (void (*do_something) (void))
            case HEADER_SUCCESS:
              if (block_number_option)
                {
-                 char buf[UINTMAX_STRSIZE_BOUND];
                  off_t block_ordinal = current_block_ordinal ();
                  block_ordinal -= recent_long_name_blocks;
                  block_ordinal -= recent_long_link_blocks;
-                 fprintf (stdlis, _("block %s: "),
-                          STRINGIFY_BIGINT (block_ordinal, buf));
+                 fprintf (stdlis, _("block %jd: "),
+                          intmax (block_ordinal));
                }
              ERROR ((0, 0, _("Skipping to next header")));
              break;
@@ -942,19 +930,10 @@ from_header (char const *where0, size_t digs, char const *type,
 
   if (type && !silent)
     {
-      char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
-      char maxval_buf[UINTMAX_STRSIZE_BOUND];
-      char value_buf[UINTMAX_STRSIZE_BOUND + 1];
-      char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
-      char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
-      if (negative)
-       *--value_string = '-';
-      if (minus_minval)
-       *--minval_string = '-';
+      char const *value_sign = &"-"[!negative];
       /* TRANSLATORS: Second %s is type name (gid_t,uid_t,etc.) */
-      ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
-             value_string, type,
-             minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
+      ERROR ((0, 0, _("Archive value %s%ju is out of %s range %jd..%ju"),
+             value_sign, value, type, minval, maxval));
     }
 
   return -1;
@@ -1070,8 +1049,8 @@ tartime (struct timespec t, bool full_time)
     {
       if (full_time)
        {
-         strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
-         code_ns_fraction (ns, buffer + strlen (buffer));
+         size_t n = strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
+         code_ns_fraction (ns, buffer + n);
        }
       else
        strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M", tm);
@@ -1129,12 +1108,11 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
   char *temp_name;
 
   /* These hold formatted ints.  */
-  char uform[max (INT_BUFSIZE_BOUND (intmax_t), UINTMAX_STRSIZE_BOUND)];
-  char gform[sizeof uform];
+  char uform[SYSINT_BUFSIZE];
+  char gform[SYSINT_BUFSIZE];
   char *user, *group;
   char size[2 * UINTMAX_STRSIZE_BOUND];
                                /* holds formatted size or major,minor */
-  char uintbuf[UINTMAX_STRSIZE_BOUND];
   int pad;
   int sizelen;
 
@@ -1145,13 +1123,11 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
 
   if (block_number_option)
     {
-      char buf[UINTMAX_STRSIZE_BOUND];
       if (block_ordinal < 0)
        block_ordinal = current_block_ordinal ();
       block_ordinal -= recent_long_name_blocks;
       block_ordinal -= recent_long_link_blocks;
-      fprintf (stdlis, _("block %s: "),
-              STRINGIFY_BIGINT (block_ordinal, buf));
+      fprintf (stdlis, _("block %jd: "), intmax (block_ordinal));
     }
 
   if (verbose_option <= 1)
@@ -1235,7 +1211,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
          && !numeric_owner_option)
        user = st->uname;
       else
-       user = STRINGIFY_BIGINT (st->stat.st_uid, uform);
+       user = sysinttostr (st->stat.st_uid, TYPE_MINIMUM (uid_t),
+                           TYPE_MAXIMUM (uid_t), uform);
 
       if (st->gname
          && st->gname[0]
@@ -1243,7 +1220,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
          && !numeric_owner_option)
        group = st->gname;
       else
-       group = STRINGIFY_BIGINT (st->stat.st_gid, gform);
+       group = sysinttostr (st->stat.st_gid, TYPE_MINIMUM (gid_t),
+                            TYPE_MAXIMUM (gid_t), gform);
 
       /* Format the file size or major/minor device numbers.  */
 
@@ -1251,22 +1229,24 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
        {
        case CHRTYPE:
        case BLKTYPE:
-         strcpy (size,
-                 STRINGIFY_BIGINT (major (st->stat.st_rdev), uintbuf));
-         strcat (size, ",");
-         strcat (size,
-                 STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf));
+         sizelen = ((EXPR_SIGNED (major (st->stat.st_rdev))
+                     && EXPR_SIGNED (minor (st->stat.st_rdev)))
+                    ? sprintf (size, "%jd,%jd",
+                               (intmax) (major (st->stat.st_rdev)),
+                               (intmax) (minor (st->stat.st_rdev)))
+                    : sprintf (size, "%ju,%ju",
+                               (uintmax) (major (st->stat.st_rdev)),
+                               (uintmax) (minor (st->stat.st_rdev))));
          break;
 
        default:
          /* st->stat.st_size keeps stored file size */
-         strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf));
+         sizelen = sprintf (size, "%jd", intmax (st->stat.st_size));
          break;
        }
 
       /* Figure out padding and print the whole line.  */
 
-      sizelen = strlen (size);
       pad = strlen (user) + 1 + strlen (group) + 1 + sizelen;
       if (pad > ugswidth)
        ugswidth = pad;
@@ -1324,11 +1304,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
          break;
 
        case GNUTYPE_MULTIVOL:
-         strcpy (size,
-                 STRINGIFY_BIGINT
-                 (UINTMAX_FROM_HEADER (blk->oldgnu_header.offset),
-                  uintbuf));
-         fprintf (stdlis, _("--Continued at byte %s--\n"), size);
+         fprintf (stdlis, _("--Continued at byte %ju--\n"),
+                  UINTMAX_FROM_HEADER (blk->oldgnu_header.offset));
          break;
        }
     }
@@ -1384,11 +1361,8 @@ print_for_mkdir (char *dirname, mode_t mode)
       pax_decode_mode (mode, modes + 1);
 
       if (block_number_option)
-       {
-         char buf[UINTMAX_STRSIZE_BOUND];
-         fprintf (stdlis, _("block %s: "),
-                  STRINGIFY_BIGINT (current_block_ordinal (), buf));
-       }
+       fprintf (stdlis, _("block %jd: "),
+                intmax (current_block_ordinal ()));
 
       fprintf (stdlis, "%s %*s %s\n", modes, ugswidth + 1 + datewidth,
               _("Creating directory:"), quotearg (dirname));
index 8388e1c7b144a6bcff29faf434da5900f844f419..87eb1b8445c7a944e4f9ceae49b4e990f26a0a74 100644 (file)
@@ -372,7 +372,7 @@ replace_prefix (char **pname, const char *samp, size_t slen,
 /* Handling numbers.  */
 
 /* Convert VALUE, which is converted from a system integer type whose
-   minimum value is MINVAL and maximum MINVAL, to an decimal
+   minimum value is MINVAL and maximum MINVAL, to a decimal
    integer string.  Use the storage in BUF and return a pointer to the
    converted string.  If VALUE is converted from a negative integer in
    the range MINVAL .. -1, represent it with a string representation
@@ -392,6 +392,14 @@ sysinttostr (uintmax_t value, intmax_t minval, uintmax_t maxval,
     }
 }
 
+/* Convert T to a decimal integer string.  Use the storage in BUF and
+   return a pointer to the converted string.  */
+char *
+timetostr (time_t t, char buf[SYSINT_BUFSIZE])
+{
+  return sysinttostr (t, TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t), buf);
+}
+
 /* Convert a prefix of the string ARG to a system integer type whose
    minimum value is MINVAL and maximum MAXVAL.  If MINVAL is negative,
    negative integers MINVAL .. -1 are assumed to be represented using
@@ -472,11 +480,10 @@ code_ns_fraction (int ns, char *p)
 }
 
 char const *
-code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
+code_timespec (struct timespec t, char tsbuf[TIMESPEC_STRSIZE_BOUND])
 {
   time_t s = t.tv_sec;
   int ns = t.tv_nsec;
-  char *np;
   bool negative = s < 0;
 
   /* ignore invalid values of ns */
@@ -489,11 +496,12 @@ code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
       ns = BILLION - ns;
     }
 
-  np = umaxtostr (negative ? - (uintmax_t) s : (uintmax_t) s, sbuf + 1);
-  if (negative)
-    *--np = '-';
-  code_ns_fraction (ns, sbuf + UINTMAX_STRSIZE_BOUND);
-  return np;
+  bool minus_zero = negative & !s;
+  char *sstr = timetostr (s, tsbuf + 1);
+  sstr[-1] = '-';
+  sstr -= minus_zero;
+  code_ns_fraction (ns, sstr + strlen (sstr));
+  return sstr;
 }
 
 struct timespec
index 0a12e3ed5a9abd827f230d48f39b66cea0c1a1dc..4ac4a40c10b44f84a0c78e82d3a68918609daca8 100644 (file)
@@ -439,9 +439,8 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
            }
          else
            {
-             char buf[UINTMAX_STRSIZE_BOUND];
              struct stat st;
-             size_t n;
+             off_t n;
              if (fstat (file->fd, &st) == 0)
                n = file->stat_info->stat.st_size - st.st_size;
              else
@@ -452,11 +451,11 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
 
              WARNOPT (WARN_FILE_SHRANK,
                       (0, 0,
-                       ngettext ("%s: File shrank by %s byte; padding with zeros",
-                                 "%s: File shrank by %s bytes; padding with zeros",
+                       ngettext ("%s: File shrank by %jd byte; padding with zeros",
+                                 "%s: File shrank by %jd bytes; padding with zeros",
                                  n),
                        quotearg_colon (file->stat_info->orig_file_name),
-                       STRINGIFY_BIGINT (n, buf)));
+                       intmax (n)));
              if (! ignore_failed_read_option)
                set_exit_status (TAREXIT_DIFFERS);
              return false;
index c07e2083f0cfff955dc1c04930a3393a20ea7a9b..29aab4ea1375c63f6f2234f701561b6791a56c80 100644 (file)
@@ -662,10 +662,8 @@ sys_child_open_for_uncompress (void)
 static void
 dec_to_env (char const *envar, uintmax_t num)
 {
-  char buf[UINTMAX_STRSIZE_BOUND];
-  char *numstr;
-
-  numstr = STRINGIFY_BIGINT (num, buf);
+  char numstr[UINTMAX_STRSIZE_BOUND];
+  sprintf (numstr, "%ju", num);
   if (setenv (envar, numstr, 1) != 0)
     xalloc_die ();
 }
@@ -823,15 +821,13 @@ sys_wait_command (void)
 int
 sys_exec_info_script (const char **archive_name, int volume_number)
 {
-  pid_t pid;
-  char uintbuf[UINTMAX_STRSIZE_BOUND];
   int p[2];
   static void (*saved_handler) (int sig);
 
   xpipe (p);
   saved_handler = signal (SIGPIPE, SIG_IGN);
 
-  pid = xfork ();
+  pid_t pid = xfork ();
 
   if (pid != 0)
     {
@@ -877,14 +873,17 @@ sys_exec_info_script (const char **archive_name, int volume_number)
   /* Child */
   setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
   setenv ("TAR_ARCHIVE", *archive_name, 1);
-  setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
-  setenv ("TAR_BLOCKING_FACTOR",
-         STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
+  char intbuf[INT_BUFSIZE_BOUND (int)];
+  sprintf (intbuf, "%d", volume_number);
+  setenv ("TAR_VOLUME", intbuf, 1);
+  sprintf (intbuf, "%d", blocking_factor);
+  setenv ("TAR_BLOCKING_FACTOR", intbuf, 1);
   setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
   setenv ("TAR_FORMAT",
          archive_format_string (current_format == DEFAULT_FORMAT ?
                                 archive_format : current_format), 1);
-  setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
+  sprintf (intbuf, "%d", p[PWRITE]);
+  setenv ("TAR_FD", intbuf, 1);
 
   xclose (p[PREAD]);
 
@@ -897,10 +896,7 @@ sys_exec_checkpoint_script (const char *script_name,
                            const char *archive_name,
                            int checkpoint_number)
 {
-  pid_t pid;
-  char uintbuf[UINTMAX_STRSIZE_BOUND];
-
-  pid = xfork ();
+  pid_t pid = xfork ();
 
   if (pid != 0)
     {
@@ -921,9 +917,11 @@ sys_exec_checkpoint_script (const char *script_name,
   /* Child */
   setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
   setenv ("TAR_ARCHIVE", archive_name, 1);
-  setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
-  setenv ("TAR_BLOCKING_FACTOR",
-         STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
+  char intbuf[INT_BUFSIZE_BOUND (int)];
+  sprintf (intbuf, "%d", checkpoint_number);
+  setenv ("TAR_CHECKPOINT", intbuf, 1);
+  sprintf (intbuf, "%d", blocking_factor);
+  setenv ("TAR_BLOCKING_FACTOR", intbuf, 1);
   setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
   setenv ("TAR_FORMAT",
          archive_format_string (current_format == DEFAULT_FORMAT ?
index d47cdac33619deec5a4750d43f9a507724054f1f..95ba25fc5825a09d0b9ecf7e4030cdaef19b0377 100644 (file)
--- a/src/tar.c
+++ b/src/tar.c
@@ -130,7 +130,6 @@ bool delay_directory_restore_option;
 #include <wordsplit.h>
 #include <sysexits.h>
 #include <quotearg.h>
-#include <verify.h>
 #include <version-etc.h>
 #include <xstrtol.h>
 #include <stdopen.h>
index 96762c34e141c848324eff4af4a60be2cbd836e5..cf37e2d982a32545963adbf726db4df79e2ece64 100644 (file)
@@ -999,15 +999,10 @@ static void
 out_of_range_header (char const *keyword, char const *value,
                     intmax_t minval, uintmax_t maxval)
 {
-  char minval_buf[INT_BUFSIZE_BOUND (intmax_t)];
-  char maxval_buf[UINTMAX_STRSIZE_BOUND];
-  char *minval_string = imaxtostr (minval, minval_buf);
-  char *maxval_string = umaxtostr (maxval, maxval_buf);
-
   /* TRANSLATORS: The first %s is the pax extended header keyword
      (atime, gid, etc.).  */
-  ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
-         keyword, value, minval_string, maxval_string));
+  ERROR ((0, 0, _("Extended header %s=%s is out of range %jd..%ju"),
+         keyword, value, minval, maxval));
 }
 
 static void