mirror of
https://codeberg.org/landley/toybox.git
synced 2026-01-26 06:07:55 +00:00
Add human_readable_long() for more than 3 digits of output.
This commit is contained in:
parent
506b264702
commit
0536f45747
16
lib/lib.c
16
lib/lib.c
@ -1136,17 +1136,17 @@ match:
|
||||
closedir(dp);
|
||||
}
|
||||
|
||||
// display first few digits of number with power of two units
|
||||
int human_readable(char *buf, unsigned long long num, int style)
|
||||
// display first "dgt" many digits of number plus unit (kilo-exabytes)
|
||||
int human_readable_long(char *buf, unsigned long long num, int dgt, int style)
|
||||
{
|
||||
unsigned long long snap = 0;
|
||||
int len, unit, divisor = (style&HR_1000) ? 1000 : 1024;
|
||||
|
||||
// Divide rounding up until we have 3 or fewer digits. Since the part we
|
||||
// print is decimal, the test is 999 even when we divide by 1024.
|
||||
// We can't run out of units because 2<<64 is 18 exabytes.
|
||||
// test 5675 is 5.5k not 5.6k.
|
||||
for (unit = 0; num > 999; unit++) num = ((snap = num)+(divisor/2))/divisor;
|
||||
// We can't run out of units because 1<<64 is 18 exabytes.
|
||||
for (unit = 0; snprintf(0, 0, "%llu", num)>dgt; unit++)
|
||||
num = ((snap = num)+(divisor/2))/divisor;
|
||||
len = sprintf(buf, "%llu", num);
|
||||
if (unit && len == 1) {
|
||||
// Redo rounding for 1.2M case, this works with and without HR_1000.
|
||||
@ -1168,6 +1168,12 @@ int human_readable(char *buf, unsigned long long num, int style)
|
||||
return len;
|
||||
}
|
||||
|
||||
// Give 3 digit estimate + units ala 999M or 1.7T
|
||||
int human_readable(char *buf, unsigned long long num, int style)
|
||||
{
|
||||
return human_readable_long(buf, num, 3, style);
|
||||
}
|
||||
|
||||
// The qsort man page says you can use alphasort, the posix committee
|
||||
// disagreed, and doubled down: http://austingroupbugs.net/view.php?id=142
|
||||
// So just do our own. (The const is entirely to humor the stupid compiler.)
|
||||
|
||||
@ -269,6 +269,7 @@ void loggit(int priority, char *format, ...);
|
||||
#define HR_SPACE 1 // Space between number and units
|
||||
#define HR_B 2 // Use "B" for single byte units
|
||||
#define HR_1000 4 // Use decimal instead of binary units
|
||||
int human_readable_long(char *buf, unsigned long long num, int dgt, int style);
|
||||
int human_readable(char *buf, unsigned long long num, int style);
|
||||
|
||||
// env.c
|
||||
|
||||
@ -25,3 +25,5 @@ testcmd "units" "-b 1c 1b 1k 1kd 1m 1md 1g 1gd 1t 1td 1e 1ed" \
|
||||
testcmd "decimal units" "-d 1c 1b 1k 1kd 1m 1md 1g 1gd 1t 1td 1e 1ed" \
|
||||
"1\n512\n1.0k\n1.0k\n1.0M\n1.0M\n1.0G\n1.0G\n1.1T\n1.0T\n1.1E\n1.0E\n" \
|
||||
"" ""
|
||||
|
||||
testcmd "longer output" "-D6 123 1234567 1234567890" "123\n1206K\n1177M\n" "" ""
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
*
|
||||
* Copyright 2015 Rob Landley <rob@landley.net>
|
||||
|
||||
USE_DEMO_NUMBER(NEWTOY(demo_number, "hdbs", TOYFLAG_BIN))
|
||||
USE_DEMO_NUMBER(NEWTOY(demo_number, "D#=3<3hdbs", TOYFLAG_BIN))
|
||||
|
||||
config DEMO_NUMBER
|
||||
bool "demo_number"
|
||||
@ -16,8 +16,13 @@ config DEMO_NUMBER
|
||||
-s Space between number and units (HR_SPACE)
|
||||
*/
|
||||
|
||||
#define FOR_demo_number
|
||||
#include "toys.h"
|
||||
|
||||
GLOBALS(
|
||||
long D;
|
||||
)
|
||||
|
||||
void demo_number_main(void)
|
||||
{
|
||||
char **arg;
|
||||
@ -26,7 +31,7 @@ void demo_number_main(void)
|
||||
long long ll = atolx(*arg);
|
||||
|
||||
if (toys.optflags) {
|
||||
human_readable(toybuf, ll, toys.optflags);
|
||||
human_readable_long(toybuf, ll, TT.D, toys.optflags);
|
||||
xputs(toybuf);
|
||||
} else printf("%lld\n", ll);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user