lib: Add format_size() to format sizes as strings

Refactor print_size() to use a new format_size() helper that formats
a size into a buffer. This allows callers to get the formatted string
without printing it directly.

The format_size() function is only exported in U-Boot proper (controlled
by CONFIG_LIB_FORMAT_SIZE) to avoid code-size impact in SPL/TPL where it
remains static.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
Simon Glass
2025-11-28 09:22:20 -07:00
parent 69d2f4ab58
commit bf72ede55e
4 changed files with 59 additions and 10 deletions

View File

@@ -11,6 +11,20 @@
#include <linux/types.h>
#if CONFIG_IS_ENABLED(LIB_FORMAT_SIZE)
/**
* format_size() - Format a size with a suffix
*
* Format sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB",
* xxx GiB, xxx.y GiB, etc as needed
*
* @buf: Buffer to write to (must be at least 12 bytes)
* @size: Size to format
* Return: @buf
*/
char *format_size(char *buf, uint64_t size);
#endif
/**
* print_size() - Print a size with a suffix
*

View File

@@ -36,6 +36,13 @@ config BACKTRACE
stack. This is currently only available on sandbox. The backtrace
command can be used to print the backtrace.
config LIB_FORMAT_SIZE
bool
default y
help
Enables the format_size() helper which formats a size as a
human-readable string.
config BCH
bool "Enable Software based BCH ECC"
help

View File

@@ -98,7 +98,11 @@ void print_freq(uint64_t freq, const char *s)
printf(" %cHz%s", c, s);
}
void print_size(uint64_t size, const char *s)
#if CONFIG_IS_ENABLED(LIB_FORMAT_SIZE)
char *format_size(char *buf, uint64_t size)
#else
static char *format_size(char *buf, uint64_t size)
#endif
{
unsigned long m = 0, n;
uint64_t f;
@@ -107,6 +111,7 @@ void print_size(uint64_t size, const char *s)
char c = 0;
unsigned int i;
/* Find the best unit to display */
for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) {
if (size >> d) {
c = names[i];
@@ -116,12 +121,12 @@ void print_size(uint64_t size, const char *s)
if (!c) {
/*
* SPL tiny-printf is not capable for printing uint64_t.
* We have just checked that the size is small enought to fit
* SPL tiny-printf is not capable of printing uint64_t.
* We have just checked that the size is small enough to fit
* unsigned int safely.
*/
printf("%u Bytes%s", (unsigned int)size, s);
return;
sprintf(buf, "%u Bytes", (unsigned int)size);
return buf;
}
n = size >> d;
@@ -143,11 +148,20 @@ void print_size(uint64_t size, const char *s)
}
}
printf ("%lu", n);
if (m) {
printf (".%ld", m);
}
printf (" %ciB%s", c, s);
if (m)
sprintf(buf, "%lu.%ld %ciB", n, m, c);
else
sprintf(buf, "%lu %ciB", n, c);
return buf;
}
void print_size(uint64_t size, const char *s)
{
char buf[12];
format_size(buf, size);
printf("%s%s", buf, s);
}
#define MAX_LINE_LENGTH_BYTES 64

View File

@@ -68,3 +68,17 @@ static int lib_test_print_size(struct unit_test_state *uts)
return 0;
}
LIB_TEST(lib_test_print_size, UTF_CONSOLE);
static int lib_test_format_size(struct unit_test_state *uts)
{
char buf[12];
ut_asserteq_str("321 Bytes", format_size(buf, 321));
ut_asserteq_str("4.2 KiB", format_size(buf, 4321));
ut_asserteq_str("53 KiB", format_size(buf, 54321));
ut_asserteq_str("1 GiB", format_size(buf, 1073741824));
ut_asserteq_str("49.4 TiB", format_size(buf, 54321987654321));
return 0;
}
LIB_TEST(lib_test_format_size, 0);