]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
tools/nolibc: implement width padding in printf()
authorThomas Weißschuh <thomas.weissschuh@linutronix.de>
Fri, 11 Apr 2025 09:00:55 +0000 (11:00 +0200)
committerThomas Weißschuh <linux@weissschuh.net>
Tue, 22 Apr 2025 08:59:06 +0000 (10:59 +0200)
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
tools/testing/selftests/nolibc/nolibc-test.c

index 46bd90f96d654fadda20292baddc98358a3afc62..fb0417477759ee6c9663e84807c1d1067e735dec 100644 (file)
@@ -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;
                        }
index 33cd64a1b768699148b2c594cb0f1c224ee9a20e..1ad0db92f0ed47f708363b2e558717fa0e686b8f 100644 (file)
@@ -1414,6 +1414,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 */