free: Clean up scale_size and fix free -h --si
- Simplify control flow a bit. We don't need two loop variables, either. - Consistently use %lld for bytes. - Fix the base handling for human-readable output. The code used to calculate *mebibytes* first, then scale that to the required exponent with the selected base, which is patently wrong. Fixes https://gitlab.com/procps-ng/procps/-/issues/133
This commit is contained in:
parent
8281ac4f98
commit
4e400b5942
73
free.c
73
free.c
@ -107,74 +107,53 @@ double power(unsigned int base, unsigned int expo)
|
|||||||
/* idea of this function is copied from top size scaling */
|
/* idea of this function is copied from top size scaling */
|
||||||
static const char *scale_size(unsigned long size, int flags, struct commandline_arguments args)
|
static const char *scale_size(unsigned long size, int flags, struct commandline_arguments args)
|
||||||
{
|
{
|
||||||
static char nextup[] = { 'B', 'K', 'M', 'G', 'T', 'P', 0 };
|
static char up[] = { 'B', 'K', 'M', 'G', 'T', 'P', 0 };
|
||||||
static char buf[BUFSIZ];
|
static char buf[BUFSIZ];
|
||||||
int i;
|
int i;
|
||||||
char *up;
|
|
||||||
float base;
|
float base;
|
||||||
|
long long bytes;
|
||||||
|
|
||||||
if (flags & FREE_SI)
|
base = (flags & FREE_SI) ? 1000.0 : 1024.0;
|
||||||
base = 1000.0;
|
bytes = size * 1024LL;
|
||||||
else
|
|
||||||
base = 1024.0;
|
|
||||||
|
|
||||||
/* default output */
|
|
||||||
if (args.exponent == 0 && !(flags & FREE_HUMANREADABLE)) {
|
|
||||||
snprintf(buf, sizeof(buf), "%ld", size);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & FREE_HUMANREADABLE)) {
|
if (!(flags & FREE_HUMANREADABLE)) {
|
||||||
if (args.exponent == 1) {
|
switch (args.exponent) {
|
||||||
/* in bytes, which can not be in SI */
|
case 0:
|
||||||
snprintf(buf, sizeof(buf), "%lld", ((long long int)size) * 1024);
|
/* default output */
|
||||||
|
snprintf(buf, sizeof(buf), "%ld", size);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
case 1:
|
||||||
if (args.exponent > 1) {
|
/* in bytes, which can not be in SI */
|
||||||
|
snprintf(buf, sizeof(buf), "%lld", bytes);
|
||||||
|
return buf;
|
||||||
|
default:
|
||||||
/* In desired scale. */
|
/* In desired scale. */
|
||||||
snprintf(buf, sizeof(buf), "%ld",
|
snprintf(buf, sizeof(buf), "%ld",
|
||||||
(long int)((size * 1024.0) / power(base, args.exponent-1))
|
(long)(bytes / power(base, args.exponent-1)));
|
||||||
);
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* human readable output */
|
/* human readable output */
|
||||||
up = nextup;
|
if (4 >= snprintf(buf, sizeof(buf), "%lld%c", bytes, up[0]))
|
||||||
for (i = 1; up[0] != 0; i++, up++) {
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
if (4 >= snprintf(buf, sizeof(buf), "%ld%c", (long)size * 1024, *up))
|
|
||||||
return buf;
|
return buf;
|
||||||
break;
|
|
||||||
case 2:
|
for (i = 1; up[i] != 0; i++) {
|
||||||
case 3:
|
if (flags & FREE_SI) {
|
||||||
case 4:
|
if (4 >= snprintf(buf, sizeof(buf), "%.1f%c",
|
||||||
case 5:
|
(float)(bytes / power(base, i)), up[i]))
|
||||||
case 6:
|
|
||||||
if (!(flags & FREE_SI)) {
|
|
||||||
if (5 >=
|
|
||||||
snprintf(buf, sizeof(buf), "%.1f%ci",
|
|
||||||
(float)((size / 1024) * base / power(base, i - 2)), *up))
|
|
||||||
return buf;
|
return buf;
|
||||||
if (5 >=
|
if (4 >= snprintf(buf, sizeof(buf), "%ld%c",
|
||||||
snprintf(buf, sizeof(buf), "%ld%ci",
|
(long)(bytes / power(base, i)), up[i]))
|
||||||
(long)((size / 1024) * base / power(base, i - 2)), *up))
|
|
||||||
return buf;
|
return buf;
|
||||||
} else {
|
} else {
|
||||||
if (4 >=
|
if (5 >= snprintf(buf, sizeof(buf), "%.1f%ci",
|
||||||
snprintf(buf, sizeof(buf), "%.1f%c",
|
(float)(bytes / power(base, i)), up[i]))
|
||||||
(float)((size / 1024) * base / power(base, i - 2)), *up))
|
|
||||||
return buf;
|
return buf;
|
||||||
if (4 >=
|
if (5 >= snprintf(buf, sizeof(buf), "%ld%ci",
|
||||||
snprintf(buf, sizeof(buf), "%ld%c",
|
(long)(bytes / power(base, i)), up[i]))
|
||||||
(long)((size / 1024) * base / power(base, i - 2)), *up))
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* On system where there is more than exbibyte of memory or swap the
|
* On system where there is more than exbibyte of memory or swap the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user