Pārlūkot izejas kodu

checkpoint actions: further improvements.

* NEWS: Update.
* doc/tar.texi: Update.
* src/buffer.c (print_stats): Avoid use of additional string buffer.
Allow for text to be NULL.
Call gettext if it is not.
(format_total_stats): Don't use gettext when calling print_stats.
* src/checkpoint.c (def_format): Change default format.
(format_checkpoint_string): Implement optional arguments for
T conversion.
(finish_checkpoint_actions): Rename to checkpoint_flush_actions,
make extern.  All uses changed.
* src/common.h (checkpoint_flush_actions): New proto.
* src/tar.c (main): Set error_hook
Sergey Poznyakoff 11 gadi atpakaļ
vecāks
revīzija
eb7e2aa933
6 mainītis faili ar 88 papildinājumiem un 42 dzēšanām
  1. 14 9
      NEWS
  2. 16 8
      doc/tar.texi
  3. 17 16
      src/buffer.c
  4. 38 9
      src/checkpoint.c
  5. 1 0
      src/common.h
  6. 2 0
      src/tar.c

+ 14 - 9
NEWS

@@ -1,4 +1,4 @@
-GNU tar NEWS - User visible changes. 2014-01-21
+GNU tar NEWS - User visible changes. 2014-01-22
 Please send GNU tar bug reports to <bug-tar@gnu.org>
 
 
@@ -11,14 +11,19 @@ total number of bytes transferred at each checkpoint.
 
 * Extended checkpoint format specification.
 
-New conversion specifiers are implemented:
-
-  %d  -  output number of seconds since tar started
-  %T  -  output I/O totals
-  %{FMT}t - output current local time using FMT as strftime(3) format
-            If {FMT} is omitted, use %c
-  %{N}*   - pad output with spaces to the Nth column, or to the 
-            current screen width, if {N} is not given.
+New conversion specifiers are implemented.  Some of them take
+optional arguments, supplied in curly braces between the percent
+sign and the specifier letter.
+
+  %d        -  output number of seconds since tar started
+  %{r,w,d}T -  output I/O totals; optional arguments supply prefixes
+               to be used before number of bytes read, written and
+	       deleted, correspondingly.
+  %{FMT}t   -  output current local time using FMT as strftime(3) format
+               If {FMT} is omitted, use %c
+  %{N}*     - pad output with spaces to the Nth column, or to the 
+              current screen width, if {N} is not given.
+  %c        -  a shortcut for "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r"
 
 
 version 1.27.1 - Sergey Poznyakoff, 2013-11-17

+ 16 - 8
doc/tar.texi

@@ -3975,7 +3975,10 @@ tar: Hit write checkpoint #20
 tar: Hit write checkpoint #30
 @end smallexample
 
-The complete list of available format specifiers follows:
+The complete list of available format specifiers follows.  Some of
+them can take optional arguments.  These arguments, if given, are
+supplied in curly braces between the percent sign and the specifier
+letter.
 
 @table @samp
 @item %s
@@ -3984,17 +3987,18 @@ Print type of the checkpoint (@samp{write} or @samp{read}).
 @item %u
 Print number of the checkpoint.
 
-@item %T
+@item %@{r,w,d@}T
 Print number of bytes transferred so far and approximate transfer
-speed.  The number is preceded by @samp{W:}, when writing and by
-@samp{R:} when reading.  If @command{tar} is performing delete
-operation (@pxref{delete}), three numbers are printed: number of bytes
-read, written and deleted, each of them prefixed by @samp{R:},
-@samp{W:} and @samp{D:} correspondingy.  For example:
+speed.  Optional arguments supply prefixes to be used before number
+of bytes read, written and deleted, correspondingly.  If absent,
+they default to @samp{R}. @samp{W}, @samp{D}.  Any or all of them can
+be omitted, so, that e.g. @samp{%@{@}T} means to print corresponding
+statistics without any prefixes.  Any surplus arguments, if present,
+are silently ignored.
 
 @example
 $ @kbd{tar --delete -f f.tar --checkpoint-action=echo="#%u: %T" main.c}
-tar: #1: R: 0 (0B, ?/s),W: 0 (0B, ?/s),D: 0
+tar: #1: R: 0 (0B, 0B/s),W: 0 (0B, 0B/s),D: 0
 tar: #2: R: 10240 (10KiB, 19MiB/s),W: 0 (0B, 0B/s),D: 10240
 @end example
 
@@ -4012,6 +4016,10 @@ for the current locale.
 Pad output with spaces to the @var{n}th column.  If the
 @samp{@{@var{n}@}} part is omitted, the current screen width
 is assumed.
+
+@item %@var{c}
+This is a shortcut for @samp{%@{%Y-%m-%d %H:%M:%S@}t: %ds, %@{read,wrote@}T%*\r},
+intended mainly for use with @samp{ttyout} action (see below).
 @end table
 
 Aside from format expansion, the message string is subject to

+ 17 - 16
src/buffer.c

@@ -492,20 +492,20 @@ open_compressed_archive (void)
 static int
 print_stats (FILE *fp, const char *text, tarlong numbytes)
 {
-  char bytes[sizeof (tarlong) * CHAR_BIT];
   char abbr[LONGEST_HUMAN_READABLE + 1];
   char rate[LONGEST_HUMAN_READABLE + 1];
-
+  int n = 0;
+  
   int human_opts = human_autoscale | human_base_1024 | human_SI | human_B;
 
-  sprintf (bytes, TARLONG_FORMAT, numbytes);
-
-  return fprintf (fp, "%s: %s (%s, %s/s)",
-		  text, bytes,
-		  human_readable (numbytes, abbr, human_opts, 1, 1),
-		  (0 < duration && numbytes / duration < (uintmax_t) -1
-		   ? human_readable (numbytes / duration, rate, human_opts, 1, 1)
-		   : "?"));
+  if (text && text[0])
+    n += fprintf (fp, "%s: ", gettext (text));
+  return n + fprintf (fp, TARLONG_FORMAT " (%s, %s/s)",
+		      numbytes,
+		      human_readable (numbytes, abbr, human_opts, 1, 1),
+		      (0 < duration && numbytes / duration < (uintmax_t) -1
+		       ? human_readable (numbytes / duration, rate, human_opts, 1, 1)
+		       : "?"));
 }
 
 /* Format totals to file FP.  FORMATS is an array of strings to output
@@ -524,27 +524,28 @@ format_total_stats (FILE *fp, const char **formats, int eor, int eol)
     case CAT_SUBCOMMAND:
     case UPDATE_SUBCOMMAND:
     case APPEND_SUBCOMMAND:
-      n = print_stats (fp, _(formats[TF_WRITE]),
+      n = print_stats (fp, formats[TF_WRITE],
 		       prev_written + bytes_written);
       break;
 
     case DELETE_SUBCOMMAND:
       {
         char buf[UINTMAX_STRSIZE_BOUND];
-        n = print_stats (fp, _(formats[TF_READ]),
+        n = print_stats (fp, formats[TF_READ],
 			 records_read * record_size);
 
 	fputc (eor, fp);
 	n++;
 	
-        n += print_stats (fp, _(formats[TF_WRITE]),
+        n += print_stats (fp, formats[TF_WRITE],
 			  prev_written + bytes_written);
 
 	fputc (eor, fp);
 	n++;
-	
-        n += fprintf (fp, "%s: %s",
-		      _(formats[TF_DELETED]),
+
+	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));

+ 38 - 9
src/checkpoint.c

@@ -185,7 +185,8 @@ getarg (const char *input, const char ** endp, char **argbuf, size_t *arglen)
 
 static int tty_cleanup;
 
-static const char *def_format = "%s: %t: %T%*\r";
+static const char *def_format =
+  "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r";
 
 static int
 format_checkpoint_string (FILE *fp, size_t len,
@@ -254,8 +255,33 @@ format_checkpoint_string (FILE *fp, size_t len,
 	      break;
 	      
 	    case 'T':
-	      compute_duration ();
-	      len += format_total_stats (fp, checkpoint_total_format, ',', 0);
+	      {
+		const char **fmt = checkpoint_total_format, *fmtbuf[3];
+		struct wordsplit ws;
+		compute_duration ();
+		
+		if (arg)
+		  {
+		    ws.ws_delim = ",";
+		    if (wordsplit (arg, &ws, WRDSF_NOVAR | WRDSF_NOCMD |
+				           WRDSF_QUOTE | WRDSF_DELIM))
+		      ERROR ((0, 0, _("cannot split string '%s': %s"),
+			      arg, wordsplit_strerror (&ws)));
+		    else
+		      {
+			int i;
+
+			for (i = 0; i < ws.ws_wordc; i++)
+			  fmtbuf[i] = ws.ws_wordv[i];
+			for (; i < 3; i++)
+			  fmtbuf[i] = NULL;
+			fmt = fmtbuf;
+		      }
+		  }
+		len += format_total_stats (fp, fmt, ',', 0);
+		if (arg)
+		  wordsplit_free (&ws);
+	      }
 	      break;
 
 	    case 't':
@@ -362,11 +388,11 @@ run_checkpoint_actions (bool do_write)
     }
 }
 
-static void
-finish_checkpoint_actions (void)
+void
+checkpoint_flush_actions (void)
 {
   struct checkpoint_action *p;
-
+  
   for (p = checkpoint_action; p; p = p->next)
     {
       switch (p->opcode)
@@ -378,14 +404,13 @@ finish_checkpoint_actions (void)
 	      while (w--)
 		fputc (' ', tty);
 	      fputc ('\r', tty);
+	      fflush (tty);
 	    }
 	  break;
 	default:
 	  /* nothing */;
 	}
     }
-  if (tty)
-    fclose (tty);
 }
 
 void
@@ -399,5 +424,9 @@ void
 checkpoint_finish (void)
 {
   if (checkpoint_option)
-    finish_checkpoint_actions ();
+    {
+      checkpoint_flush_actions ();
+      if (tty)
+	fclose (tty);
+    }
 }

+ 1 - 0
src/common.h

@@ -862,6 +862,7 @@ void checkpoint_compile_action (const char *str);
 void checkpoint_finish_compile (void);
 void checkpoint_run (bool do_write);
 void checkpoint_finish (void);
+void checkpoint_flush_actions (void);
 
 /* Module warning.c */
 #define WARN_ALONE_ZERO_BLOCK    0x00000001

+ 2 - 0
src/tar.c

@@ -2623,6 +2623,8 @@ main (int argc, char **argv)
 
   exit_failure = TAREXIT_FAILURE;
   exit_status = TAREXIT_SUCCESS;
+  error_hook = checkpoint_flush_actions;
+  
   filename_terminator = '\n';
   set_quoting_style (0, DEFAULT_QUOTING_STYLE);