1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-08-17 09:06:50 +02:00

(C_ASCII, C_EBCDIC, C_IBM, C_BLOCK, C_UNBLOCK,

C_LCASE, C_UCASE, C_SWAB, C_NOERROR, C_NOTRUNC, C_SYNC, C_TWOBUFS,
C_NOCREAT, C_EXCL, C_FDATASYNC, C_FSYNC): Now constants, not
macros.
(STATUS_NOXFER, statuses): New constants.
(usage, print_stats, scanargs): Add support for status=noxfer.
(usage): Update status output to match new behavior.
(print_stats): Always output complete byte count.
Put space between numbers and units, as SI requires.
Use ngettext so that i18n can use plurals for "byte" and "second".
Don't multiply by 1e-9 (inexact); divide by 1e9 (which is exact).
(iflag_error_msgid, oflag_error_msgid): Remove; replace uses by
the string.
This commit is contained in:
Paul Eggert
2004-11-16 07:46:08 +00:00
parent 537acced26
commit 586b8823f9
+68 -31
View File
@@ -74,23 +74,36 @@
#define MAX_BLOCKSIZE MIN (SIZE_MAX, MIN (SSIZE_MAX, OFF_T_MAX))
/* Conversions bit masks. */
#define C_ASCII 01
#define C_EBCDIC 02
#define C_IBM 04
#define C_BLOCK 010
#define C_UNBLOCK 020
#define C_LCASE 040
#define C_UCASE 0100
#define C_SWAB 0200
#define C_NOERROR 0400
#define C_NOTRUNC 01000
#define C_SYNC 02000
/* Use separate input and output buffers, and combine partial input blocks. */
#define C_TWOBUFS 04000
#define C_NOCREAT 010000
#define C_EXCL 020000
#define C_FDATASYNC 040000
#define C_FSYNC 0100000
enum
{
C_ASCII = 01,
C_EBCDIC = 02,
C_IBM = 04,
C_BLOCK = 010,
C_UNBLOCK = 020,
C_LCASE = 040,
C_UCASE = 0100,
C_SWAB = 0200,
C_NOERROR = 0400,
C_NOTRUNC = 01000,
C_SYNC = 02000,
/* Use separate input and output buffers, and combine partial
input blocks. */
C_TWOBUFS = 04000,
C_NOCREAT = 010000,
C_EXCL = 020000,
C_FDATASYNC = 040000,
C_FSYNC = 0100000
};
/* Status bit masks. */
enum
{
STATUS_NOXFER = 01
};
/* The name this program was run with. */
char *program_name;
@@ -126,6 +139,9 @@ static int conversions_mask = 0;
static int input_flags = 0;
static int output_flags = 0;
/* Status flags for what is printed to stderr. */
static int status_flags = 0;
/* If nonzero, filter characters through the translation table. */
static bool translation_needed = false;
@@ -220,6 +236,13 @@ static struct symbol_value const flags[] =
{"", 0}
};
/* Status, for status="...". */
static struct symbol_value const statuses[] =
{
{"noxfer", STATUS_NOXFER},
{"", 0}
};
/* Translation table formed by applying successive transformations. */
static unsigned char trans_table[256];
@@ -361,6 +384,7 @@ Copy a file, converting and formatting according to the operands.\n\
oflag=FLAGS write as per the comma separated symbol list\n\
seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
status=noxfer suppress transfer statistics\n\
"), stdout);
fputs (_("\
\n\
@@ -414,9 +438,9 @@ print I/O statistics to standard error, then to resume copying.\n\
\n\
$ dd if=/dev/zero of=/dev/null& pid=$!\n\
$ kill -USR1 $pid; sleep 1; kill $pid\n\
10807656+0 records in\n\
10807656+0 records out\n\
5.5GB copied in 20.8225s (266MB/s)\n\
18335302+0 records in\n\
18335302+0 records out\n\
9387674624 bytes (9.4 GB) copied, 34.6279 seconds, 271 MB/s\n\
\n\
Options are:\n\
\n\
@@ -452,9 +476,11 @@ print_stats (void)
char buf[2][MAX (INT_BUFSIZE_BOUND (uintmax_t), LONGEST_HUMAN_READABLE + 1)];
struct timespec now;
int human_opts =
human_autoscale | human_round_to_nearest | human_SI | human_B;
(human_autoscale | human_round_to_nearest
| human_space_before_unit | human_SI | human_B);
uintmax_t start_sec = start_time.tv_sec;
enum { BILLION = 1000000000 };
double BILLIONe0 = BILLION;
double delta_s;
char const *bytes_per_second;
@@ -472,10 +498,19 @@ print_stats (void)
: _("truncated records")));
}
if (status_flags & STATUS_NOXFER)
return;
/* Use integer arithmetic to compute the transfer rate if possible,
since that makes it easy to use SI abbreviations; otherwise, fall
back on floating-point without abbreviations. */
fprintf (stderr,
ngettext ("%s byte (%s) copied",
"%s bytes (%s) copied", w_bytes == 1),
umaxtostr (w_bytes, buf[0]),
human_readable (w_bytes, buf[1], human_opts, 1, 1));
if ((start_time.tv_sec < now.tv_sec
|| (start_time.tv_sec == now.tv_sec
&& start_time.tv_nsec < now.tv_nsec))
@@ -483,7 +518,7 @@ print_stats (void)
{
uintmax_t delta_ns = (BILLION * (now.tv_sec - start_sec)
+ now.tv_nsec - start_time.tv_nsec);
delta_s = delta_ns / 1e9;
delta_s = delta_ns / BILLIONe0;
bytes_per_second = human_readable (w_bytes, buf[1], human_opts,
BILLION, delta_ns);
}
@@ -491,7 +526,7 @@ print_stats (void)
{
delta_s = now.tv_sec;
delta_s -= start_time.tv_sec;
delta_s += 1e-9 * (now.tv_nsec - start_time.tv_nsec);
delta_s += (now.tv_nsec - start_time.tv_nsec) / BILLIONe0;
if (0 < delta_s)
sprintf (buf[1], "%gB", w_bytes / delta_s);
else
@@ -499,8 +534,9 @@ print_stats (void)
bytes_per_second = buf[1];
}
fprintf (stderr, _("%s copied in %gs (%s/s)\n"),
human_readable (w_bytes, buf[0], human_opts, 1, 1),
fprintf (stderr,
ngettext (", %g second, %s/s\n",
", %g seconds, %s/s\n", delta_s == 1),
delta_s, bytes_per_second);
}
@@ -608,10 +644,6 @@ write_output (void)
oc = 0;
}
/* Diagnostics for invalid iflag="..." and oflag="..." symbols. */
static char const iflag_error_msgid[] = N_("invalid input flag: %s");
static char const oflag_error_msgid[] = N_("invalid output flag: %s");
/* Interpret one "conv=..." or similar operand STR according to the
symbols in TABLE, returning the flags specified. If the operand
cannot be parsed, use ERROR_MSGID to generate a diagnostic.
@@ -709,9 +741,14 @@ scanargs (int argc, char **argv)
conversions_mask |= parse_symbols (val, conversions,
N_("invalid conversion: %s"));
else if (STREQ (name, "iflag"))
input_flags |= parse_symbols (val, flags, iflag_error_msgid);
input_flags |= parse_symbols (val, flags,
N_("invalid input flag: %s"));
else if (STREQ (name, "oflag"))
output_flags |= parse_symbols (val, flags, oflag_error_msgid);
output_flags |= parse_symbols (val, flags,
N_("invalid output flag: %s"));
else if (STREQ (name, "status"))
status_flags |= parse_symbols (val, statuses,
N_("invalid status flag: %s"));
else
{
bool invalid = false;