Adjust the decimal units flag variable name from "si" to "decimal_units" so it does not overlap with other words like "size" and "signal"; add man page entry and adjust the "-L" man page entry; and allow this flag to also change how input prefixes are processed.

This commit is contained in:
Andrew Wood
2024-03-19 22:17:43 +00:00
parent 3b721112e6
commit c9dede08d4
13 changed files with 95 additions and 50 deletions
+1
View File
@@ -1,5 +1,6 @@
### NOT YET RELEASED
* feature: new "`--si`" option to display and interpret size suffixes in multiples of 1000 rather than 1024 (pull request [#85](https://codeberg.org/a-j-wood/pv/pulls/85)) supplied by [kevinruddy](https://codeberg.org/kevinruddy)
* i18n: corrections and missing strings added to French translations (pull request [#83](https://codeberg.org/a-j-wood/pv/pulls/83)) supplied by [Thomas Bertels](https://codeberg.org/tbertels)
### 1.8.5 - 19 November 2023
+12 -3
View File
@@ -1,4 +1,4 @@
.TH PV 1 "November 2023" Linux "User Manuals"
.TH PV 1 "March 2024" Linux "User Manuals"
.SH NAME
pv \- monitor the progress of data through a pipe
.SH SYNOPSIS
@@ -154,6 +154,11 @@ data transferred so far.
Display the total bits instead of the total bytes. The output suffix will
be "b" instead of "B".
.TP
.B \-k, \-\-si
Display and interpret suffixes as multiples of 1000 rather than the default
of 1024. Note that this only takes effect on options after this one, so for
consistency, specify this option first.
.TP
.B \-T, \-\-buffer\-percent
Turn on the transfer buffer percentage display. This will show the
percentage of the transfer buffer in use - but see the caveat under
@@ -343,7 +348,11 @@ invocations in a single, long, pipeline.
Limit the transfer to a maximum of
.I RATE
bytes per second. A suffix of "K", "M", "G", or "T" can be added to denote
kibibytes (*1024), mebibytes, and so on.
kibibytes (*1024), mebibytes, and so on. If
.B \-\-si
was also passed, suffixes will denote kilobytes (*1000), megabytes, etc.
Note the caveat about the positioning of
.B \-\-si .
.TP
.BI \-B\ BYTES \fR,\ \fB\-\-buffer-size\ BYTES
Use a transfer buffer size of
@@ -716,7 +725,7 @@ home page: <https://www.ivarch.com/programs/pv.shtml>
.BR O_DIRECT )
.SH COPYRIGHT
Copyright \(co 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood.
Copyright \(co 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood.
License GPLv3+: GNU GPL version 3 or later <https://www.gnu.org/licenses/gpl-3.0.html>.
+11 -2
View File
@@ -121,6 +121,12 @@ that are explicitly switched on will be shown.
: Display the total bits instead of the total bytes. The output suffix
will be \"b\" instead of \"B\".
**-k, \--si**
: Display and interpret suffixes as multiples of 1000 rather than the
default of 1024. Note that this only takes effect on options after
this one, so for consistency, specify this option first.
**-T, \--buffer-percent**
: Turn on the transfer buffer percentage display. This will show the
@@ -255,7 +261,9 @@ that are explicitly switched on will be shown.
: Limit the transfer to a maximum of *RATE* bytes per second. A suffix
of \"K\", \"M\", \"G\", or \"T\" can be added to denote kibibytes
(\*1024), mebibytes, and so on.
(\*1024), mebibytes, and so on. If **\--si** was also passed,
suffixes will denote kilobytes (\*1000), megabytes, etc. Note the
caveat about the positioning of **\--si .**
**-B BYTES, \--buffer-size BYTES**
@@ -535,7 +543,8 @@ Alternatively, use the issue tracker linked from the **pv** home page:
# COPYRIGHT
Copyright © 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood.
Copyright © 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew
Wood.
License GPLv3+: GNU GPL version 3 or later
\<https://www.gnu.org/licenses/gpl-3.0.html\>.
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Global program option structure and the parsing function prototype.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -34,7 +34,7 @@ struct opts_s { /* structure describing run-time options */
bool average_rate; /* average rate counter flag */
bool bytes; /* bytes transferred flag */
bool bits; /* report transfer size in bits */
bool si; /* decimal prefix flag */
bool decimal_units; /* decimal prefix flag */
bool bufpercent; /* transfer buffer percentage flag */
size_t lastwritten; /* show N bytes last written */
bool force; /* force-if-not-terminal flag */
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Functions internal to the PV library. Include "config.h" first.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -105,7 +105,7 @@ struct pvstate_s {
bool wait; /* wait for data before display */
bool linemode; /* count lines instead of bytes */
bool bits; /* report bits instead of bytes */
bool si; /* use decimal prefixes */
bool decimal_units; /* use decimal prefixes */
bool null_terminated_lines; /* lines are null-terminated */
bool no_display; /* do nothing other than pipe data */
unsigned int skip_errors; /* skip read errors counter */
+7 -5
View File
@@ -1,7 +1,7 @@
/*
* Functions used across the program.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -49,15 +49,17 @@ typedef enum {
extern double pv_getnum_interval(const char *);
/*
* Return the given string converted to an off_t, for use as a size.
* Return the given string converted to an off_t, for use as a size,
* optionally interpreting suffixes in decimal units (multiples of 1000)
* instead of multiples of 1024.
*/
extern off_t pv_getnum_size(const char *);
extern off_t pv_getnum_size(const char *, bool);
/*
* Return the given string converted to an unsigned integer, for use as a
* count such as screen width.
*/
extern unsigned int pv_getnum_count(const char *);
extern unsigned int pv_getnum_count(const char *, bool);
/*
* Return true if the given string is a number of the given type. NB an
@@ -164,7 +166,7 @@ extern void pv_state_wait_set(pvstate_t, bool);
extern void pv_state_delay_start_set(pvstate_t, double);
extern void pv_state_linemode_set(pvstate_t, bool);
extern void pv_state_bits_set(pvstate_t, bool);
extern void pv_state_si_set(pvstate_t, bool);
extern void pv_state_decimal_units_set(pvstate_t, bool);
extern void pv_state_null_terminated_lines_set(pvstate_t, bool);
extern void pv_state_no_display_set(pvstate_t, bool);
extern void pv_state_skip_errors_set(pvstate_t, unsigned int);
+1 -1
View File
@@ -308,7 +308,7 @@ void display_help(void)
N_("show number of bits transferred"),
{ 0, 0, 0, 0} },
{ "-k", "--si", NULL,
N_("show sizes in powers of 1000 (e.g., 1.1G)"),
N_("treat suffixes as multiples of 1000 rather than 1024"),
{ 0, 0, 0, 0} },
{ "-T", "--buffer-percent", NULL,
N_("show percentage of transfer buffer in use"),
+2 -2
View File
@@ -2,7 +2,7 @@
* Main program entry point - read the command line options, then perform
* the appropriate actions.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -278,7 +278,7 @@ int main(int argc, char **argv)
pv_state_delay_start_set(state, opts->delay_start);
pv_state_linemode_set(state, opts->linemode);
pv_state_bits_set(state, opts->bits);
pv_state_si_set(state, opts->si);
pv_state_decimal_units_set(state, opts->decimal_units);
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
pv_state_skip_errors_set(state, opts->skip_errors);
pv_state_error_skip_block_set(state, opts->error_skip_block);
+11 -11
View File
@@ -1,7 +1,7 @@
/*
* Parse command-line options.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -337,7 +337,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
numopts++;
break;
case 'k':
opts->si = true;
opts->decimal_units = true;
break;
case 'T':
opts->bufpercent = true;
@@ -345,7 +345,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->no_splice = true;
break;
case 'A':
opts->lastwritten = (size_t) pv_getnum_count(optarg);
opts->lastwritten = (size_t) pv_getnum_count(optarg, opts->decimal_units);
numopts++;
opts->no_splice = true;
break;
@@ -391,7 +391,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
/*@+mustfreefresh@ */
}
} else {
opts->size = pv_getnum_size(optarg);
opts->size = pv_getnum_size(optarg, opts->decimal_units);
}
break;
case 'l':
@@ -405,11 +405,11 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->interval = pv_getnum_interval(optarg);
break;
case 'w':
opts->width = pv_getnum_count(optarg);
opts->width = pv_getnum_count(optarg, opts->decimal_units);
opts->width_set_manually = opts->width == 0 ? false : true;
break;
case 'H':
opts->height = pv_getnum_count(optarg);
opts->height = pv_getnum_count(optarg, opts->decimal_units);
opts->height_set_manually = opts->height == 0 ? false : true;
break;
case 'N':
@@ -421,10 +421,10 @@ opts_t opts_parse(unsigned int argc, char **argv)
}
break;
case 'L':
opts->rate_limit = pv_getnum_size(optarg);
opts->rate_limit = pv_getnum_size(optarg, opts->decimal_units);
break;
case 'B':
opts->buffer_size = (size_t) pv_getnum_size(optarg);
opts->buffer_size = (size_t) pv_getnum_size(optarg, opts->decimal_units);
opts->no_splice = true;
break;
case 'C':
@@ -434,7 +434,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->skip_errors++;
break;
case 'Z':
opts->error_skip_block = pv_getnum_size(optarg);
opts->error_skip_block = pv_getnum_size(optarg, opts->decimal_units);
break;
case 'S':
opts->stop_at_size = true;
@@ -450,7 +450,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->no_splice = true;
break;
case 'R':
opts->remote = pv_getnum_count(optarg);
opts->remote = pv_getnum_count(optarg, false);
break;
case 'P':
opts->pidfile = pv_strdup(optarg);
@@ -477,7 +477,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->watch_fd = parse_fd;
break;
case 'm':
opts->average_rate_window = pv_getnum_count(optarg);
opts->average_rate_window = pv_getnum_count(optarg, opts->decimal_units);
break;
#ifdef ENABLE_DEBUGGING
case '!':
+2 -2
View File
@@ -10,7 +10,7 @@
* terminal, so we try to use a lockfile if terminal locking doesn't work,
* and finally abort if even that is unavailable.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -293,7 +293,7 @@ static int pv_crs_get_ypos(int terminalfd)
}
#endif /* !CURSOR_ANSWERBACK_BYTE_BY_BYTE */
ypos = (int) pv_getnum_count(cpr + 2);
ypos = (int) pv_getnum_count(cpr + 2, false);
if (0 != tcsetattr(terminalfd, TCSANOW | TCSAFLUSH, &old_tty)) {
debug("%s: %s", "tcsetattr (2) failed", strerror(errno));
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Display functions.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -836,7 +836,7 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
count_type = PV_TRANSFERCOUNT_BYTES;
if (state->control.linemode)
count_type = PV_TRANSFERCOUNT_LINES;
else if (state->control.si)
else if (state->control.decimal_units)
count_type = PV_TRANSFERCOUNT_DECBYTES;
switch (component_type) {
+39 -15
View File
@@ -1,7 +1,7 @@
/*
* Functions for converting strings to numbers.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -27,14 +27,16 @@ static bool pv__isdigit(char c)
* Return the numeric value of "str", as an off_t, where "str" is expected
* to be a sequence of digits (without a thousands separator), possibly with
* a fractional part, optionally followed by a units suffix such as "K" for
* kibibytes.
* kibibytes. If "decimal_units" is true, suffixes are interpreted as
* multiples of 1000, rather than multiples of 1024.
*/
off_t pv_getnum_size(const char *str)
off_t pv_getnum_size(const char *str, bool decimal_units)
{
off_t integral_part = 0;
off_t fractional_part = 0;
unsigned int fractional_divisor = 1;
unsigned int shift = 0;
unsigned int binary_shift = 0;
off_t decimal_multiplier = 0;
if (NULL == str)
return (off_t) 0;
@@ -74,7 +76,7 @@ off_t pv_getnum_size(const char *str)
/*
* Parse any units given (K=KiB=*1024, M=MiB=1024KiB, G=GiB=1024MiB,
* T=TiB=1024GiB).
* T=TiB=1024GiB; replace 1024 with 1000 if decimal_units is true).
*/
if (str[0] != '\0') {
/* Skip any spaces or tabs after the digits. */
@@ -83,19 +85,23 @@ off_t pv_getnum_size(const char *str)
switch (str[0]) {
case 'k':
case 'K':
shift = 10;
binary_shift = 10;
decimal_multiplier = 1000;
break;
case 'm':
case 'M':
shift = 20;
binary_shift = 20;
decimal_multiplier = 1000000;
break;
case 'g':
case 'G':
shift = 30;
binary_shift = 30;
decimal_multiplier = 1000000000;
break;
case 't':
case 'T':
shift = 40;
binary_shift = 40;
decimal_multiplier = 1000000000000;
break;
default:
break;
@@ -103,14 +109,24 @@ off_t pv_getnum_size(const char *str)
}
/*
* Binary left-shift the supplied number by "shift" times, i.e.
* If decimal_units is false, zero decimal_multiplier; if true, zero
* binary_shift. This is so we only do one or the other.
*/
if (decimal_units) {
binary_shift = 0;
} else {
decimal_multiplier = 0;
}
/*
* Binary left-shift the supplied number by "binary_shift" times, i.e.
* apply the given units (KiB, MiB, etc) to it, but never shift left
* more than 30 at a time to avoid overflows.
*/
while (shift > 0) {
while (binary_shift > 0) {
unsigned int shiftby;
shiftby = shift;
shiftby = binary_shift;
if (shiftby > 30)
shiftby = 30;
@@ -124,7 +140,15 @@ off_t pv_getnum_size(const char *str)
fractional_part = (off_t) (fractional_part << shiftby);
/*@+shiftimplementation@ */
shift -= shiftby;
binary_shift -= shiftby;
}
/*
* Multiply the supplied number by the decimal multiplier.
*/
if (decimal_multiplier > 0) {
integral_part = integral_part * decimal_multiplier;
fractional_part = fractional_part * decimal_multiplier;
}
/*
@@ -183,9 +207,9 @@ double pv_getnum_interval(const char *str)
* rules as pv_getnum_size(), expecting "str" to express a value to be used
* as a count (such as number of screen columns, or size of a buffer).
*/
unsigned int pv_getnum_count(const char *str)
unsigned int pv_getnum_count(const char *str, bool decimal_units)
{
return (unsigned int) pv_getnum_size(str);
return (unsigned int) pv_getnum_size(str, decimal_units);
}
+3 -3
View File
@@ -1,7 +1,7 @@
/*
* State management functions.
*
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
*
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
*/
@@ -234,9 +234,9 @@ void pv_state_bits_set(pvstate_t state, bool bits)
state->control.bits = bits;
}
void pv_state_si_set(pvstate_t state, bool si)
void pv_state_decimal_units_set(pvstate_t state, bool decimal_units)
{
state->control.si = si;
state->control.decimal_units = decimal_units;
}
void pv_state_null_terminated_lines_set(pvstate_t state, bool val)