diff mbox series

[v3,31/32] tools/nolibc: implement width padding in printf()

Message ID 20250411-nolibc-kselftest-harness-v3-31-4d9c0295893f@linutronix.de
State New
Headers show
Series kselftest harness and nolibc compatibility | expand

Commit Message

Thomas Weißschuh April 11, 2025, 9 a.m. UTC
printf can pad each argument to a certain width.
Implement this for compatibility with the kselftest harness.
Currently only padding with spaces is supported.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Acked-by: Willy Tarreau <w@1wt.eu>
---
 tools/include/nolibc/stdio.h                 | 17 ++++++++++++++++-
 tools/testing/selftests/nolibc/nolibc-test.c |  3 +++
 2 files changed, 19 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index 46bd90f96d654fadda20292baddc98358a3afc62..fb0417477759ee6c9663e84807c1d1067e735dec 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -220,7 +220,7 @@  int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char
 {
 	char escape, lpref, c;
 	unsigned long long v;
-	unsigned int written;
+	unsigned int written, width;
 	size_t len, ofs, w;
 	char tmpbuf[21];
 	const char *outstr;
@@ -228,10 +228,20 @@  int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char
 	written = ofs = escape = lpref = 0;
 	while (1) {
 		c = fmt[ofs++];
+		width = 0;
 
 		if (escape) {
 			/* we're in an escape sequence, ofs == 1 */
 			escape = 0;
+
+			/* width */
+			while (c >= '0' && c <= '9') {
+				width *= 10;
+				width += c - '0';
+
+				c = fmt[ofs++];
+			}
+
 			if (c == 'c' || c == 'd' || c == 'u' || c == 'x' || c == 'p') {
 				char *out = tmpbuf;
 
@@ -309,6 +319,11 @@  int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char
 			if (n) {
 				w = len < n ? len : n;
 				n -= w;
+				while (width-- > w) {
+					if (cb(state, " ", 1) != 0)
+						break;
+					written += 1;
+				}
 				if (cb(state, outstr, w) != 0)
 					break;
 			}
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 9bd0a9c68b903cbd660ff81d4b0386b0b7c13977..16ec4f658bbec43440679c5d5c35014827c377bc 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1415,6 +1415,9 @@  static int run_printf(int min, int max)
 		CASE_TEST(uintmax_t);    EXPECT_VFPRINTF(20, "18446744073709551615", "%ju", 0xffffffffffffffffULL); break;
 		CASE_TEST(intmax_t);     EXPECT_VFPRINTF(20, "-9223372036854775807", "%jd", 0x8000000000000001LL); break;
 		CASE_TEST(truncation);   EXPECT_VFPRINTF(25, "01234567890123456789", "%s", "0123456789012345678901234"); break;
+		CASE_TEST(string_width); EXPECT_VFPRINTF(10, "         1", "%10s", "1"); break;
+		CASE_TEST(number_width); EXPECT_VFPRINTF(10, "         1", "%10d", 1); break;
+		CASE_TEST(width_trunc);  EXPECT_VFPRINTF(25, "                    ", "%25d", 1); break;
 		CASE_TEST(scanf);        EXPECT_ZR(1, test_scanf()); break;
 		case __LINE__:
 			return ret; /* must be last */