diff --git a/src/include/options.h b/src/include/options.h index 8cbe183..6d5e696 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -34,6 +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 bufpercent; /* transfer buffer percentage flag */ size_t lastwritten; /* show N bytes last written */ bool force; /* force-if-not-terminal flag */ diff --git a/src/include/pv-internal.h b/src/include/pv-internal.h index 29ebef5..21f67d4 100644 --- a/src/include/pv-internal.h +++ b/src/include/pv-internal.h @@ -105,6 +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 null_terminated_lines; /* lines are null-terminated */ bool no_display; /* do nothing other than pipe data */ unsigned int skip_errors; /* skip read errors counter */ diff --git a/src/include/pv.h b/src/include/pv.h index a2c9132..7ef5234 100644 --- a/src/include/pv.h +++ b/src/include/pv.h @@ -164,6 +164,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_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); diff --git a/src/main/help.c b/src/main/help.c index bd2ce22..fcad22e 100644 --- a/src/main/help.c +++ b/src/main/help.c @@ -307,6 +307,9 @@ void display_help(void) { "-8", "--bits", NULL, N_("show number of bits transferred"), { 0, 0, 0, 0} }, + { "-k", "--si", NULL, + N_("show sizes in powers of 1000 (e.g., 1.1G)"), + { 0, 0, 0, 0} }, { "-T", "--buffer-percent", NULL, N_("show percentage of transfer buffer in use"), { 0, 0, 0, 0} }, diff --git a/src/main/main.c b/src/main/main.c index 653df68..de5fadf 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -278,6 +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_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); diff --git a/src/main/options.c b/src/main/options.c index 01df7a1..482d511 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -114,6 +114,7 @@ opts_t opts_parse(unsigned int argc, char **argv) { "average-rate", 0, NULL, (int) 'a' }, { "bytes", 0, NULL, (int) 'b' }, { "bits", 0, NULL, (int) '8' }, + { "si", 0, NULL, (int) 'k' }, { "buffer-percent", 0, NULL, (int) 'T' }, { "last-written", 1, NULL, (int) 'A' }, { "force", 0, NULL, (int) 'f' }, @@ -151,7 +152,7 @@ opts_t opts_parse(unsigned int argc, char **argv) /*@+nullassign@ */ int option_index = 0; #endif /* HAVE_GETOPT_LONG */ - char *short_options = "hVpteIrab8TA:fnqcWD:s:l0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:" + char *short_options = "hVpteIrab8kTA:fnqcWD:s:l0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:" #ifdef ENABLE_DEBUGGING "!:" #endif @@ -335,6 +336,9 @@ opts_t opts_parse(unsigned int argc, char **argv) opts->bits = true; numopts++; break; + case 'k': + opts->si = true; + break; case 'T': opts->bufpercent = true; numopts++; diff --git a/src/pv/display.c b/src/pv/display.c index dccda09..c65e3c4 100644 --- a/src/pv/display.c +++ b/src/pv/display.c @@ -146,10 +146,11 @@ static long pv__seconds_remaining(const off_t so_far, const off_t total, const l } /* - * Types of transfer count - bytes or lines. + * Types of transfer count - bytes, decimal bytes or lines. */ typedef enum { PV_TRANSFERCOUNT_BYTES, + PV_TRANSFERCOUNT_DECBYTES, PV_TRANSFERCOUNT_LINES } pv__transfercount_t; @@ -346,6 +347,9 @@ static void pv__sizestr(char *buffer, size_t bufsize, char *format, if (count_type == PV_TRANSFERCOUNT_BYTES) { suffix = suffix_bytes; divider = 1024.0; + } else if (count_type == PV_TRANSFERCOUNT_DECBYTES) { + suffix = suffix_bytes; + divider = 1000.0; } else { suffix = suffix_basic; divider = 1000.0; @@ -808,6 +812,7 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin time_t then; struct tm *time_ptr; char *time_format; + pv__transfercount_t count_type; if (!state->display.component[component_type].required) continue; @@ -828,6 +833,12 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin component_content[0] = '\0'; component_buf_size = PV_SIZEOF_COMPONENT_STR; + count_type = PV_TRANSFERCOUNT_BYTES; + if (state->control.linemode) + count_type = PV_TRANSFERCOUNT_LINES; + else if (state->control.si) + count_type = PV_TRANSFERCOUNT_DECBYTES; + switch (component_type) { case PV_COMPONENT_STRING: @@ -842,11 +853,10 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin /*@-mustfreefresh @ */ if (state->control.bits && !state->control.linemode) { pv__sizestr(component_content, component_buf_size, "%s", - (long double) total_bytes * 8, "", _("b"), PV_TRANSFERCOUNT_BYTES); + (long double) total_bytes * 8, "", _("b"), count_type); } else { pv__sizestr(component_content, component_buf_size, "%s", - (long double) total_bytes, "", _("B"), - state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES); + (long double) total_bytes, "", _("B"), count_type); } /*@+mustfreefresh @ */ /* splint: we trust gettext() not to really leak memory. */ @@ -888,12 +898,11 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin if (state->control.bits && !state->control.linemode) { /* bits per second */ pv__sizestr(component_content, component_buf_size, "[%s]", 8 * rate, "", _("b/s"), - PV_TRANSFERCOUNT_BYTES); + count_type); } else { /* bytes or lines per second */ pv__sizestr(component_content, component_buf_size, - "[%s]", rate, _("/s"), _("B/s"), - state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES); + "[%s]", rate, _("/s"), _("B/s"), count_type); } /*@+mustfreefresh @ *//* splint: see above. */ break; @@ -904,13 +913,12 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin if (state->control.bits && !state->control.linemode) { /* bits per second */ pv__sizestr(component_content, component_buf_size, - "[%s]", 8 * average_rate, "", _("b/s"), PV_TRANSFERCOUNT_BYTES); + "[%s]", 8 * average_rate, "", _("b/s"), count_type); } else { /* bytes or lines per second */ pv__sizestr(component_content, component_buf_size, - "[%s]", average_rate, _("/s"), _("B/s"), - state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES); + "[%s]", average_rate, _("/s"), _("B/s"), count_type); } /*@+mustfreefresh @ *//* splint: see above. */ break; diff --git a/src/pv/state.c b/src/pv/state.c index 428ceac..0e60eac 100644 --- a/src/pv/state.c +++ b/src/pv/state.c @@ -234,6 +234,11 @@ void pv_state_bits_set(pvstate_t state, bool bits) state->control.bits = bits; } +void pv_state_si_set(pvstate_t state, bool si) +{ + state->control.si = si; +} + void pv_state_null_terminated_lines_set(pvstate_t state, bool val) { state->control.null_terminated_lines = val;