From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F01E5325710 for ; Mon, 2 Mar 2026 10:18:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446721; cv=none; b=ucD/jZiqpDulry9CIUbOj4YxMgdqx091p94nRFYMGcv2deQB/rUz+APDvoef/w19MXmiuVOpqcsZPn0CAdxQgLtqP8g7l8Dj4gU6LoCjZJQqF3e21ehGLl1hyimVs92PYMPDo9u6KAYggw7Nudc/8NWACxuFE1YcJmqD6f6AVuY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446721; c=relaxed/simple; bh=YN8najSXFG6shutiPu+7KfH5wVMqRZEilU00Lyobh/Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Nyj87pRFCbuL8NLb/gwaX5loHOhBJQ/qRCjK8kxhzRsrHlOHKTby8mtR7Z8A5VTXSYMvswsS85WO1jPHqQ3k+O8Lw5YOtkAEIeCFEA4+4S/0lYNYp2lOE8GCnt13kkabmYoSJ9ZNY+Z7GE3LG4FUcdtbrToZlWh0sWNMWnZWFFA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=im0l5kiY; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="im0l5kiY" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0M9-003BXX-DH; Mon, 02 Mar 2026 11:18:29 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=5e+1/ip2QXYVpkzl6Yem7+UNhERpX0Crp3M4DpbkNRs=; b=im0l5kiYRUUpTCXfy6fyvsn0V2 itEHm8+7zL6ZvyCtt3TwVXmb2G4SmRMBgyXmxlo/PJqp+kInfDrOwPZV0puGg4uVrRDzb1mWZnLb6 /U4utsJE+fVg8+EhjsctVeKb6ZfhcxPOUbQLUT+gT+1gzK192aeJmxALpApJIHhiS+sW6TjrRuhgM ny9ChNaIJ4ZIKw1VdqiS1ZGBt1K9Uahrh/zgtyC3i6DH4LJQ4rPvZ/MbsxaAJFmcPT0PJiSre0GiI kVQfXSMUz+RheKrsgsV4hwfJLwVNehp/Ma1PyZ5Fzj6xfLcOB0IFY/RcGZ3IjqVpLNF4v1cANb6VC V1TiGPsQ==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0M9-0002wo-3O; Mon, 02 Mar 2026 11:18:29 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0M8-006y7o-L8; Mon, 02 Mar 2026 11:18:28 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 01/23] tools/nolibc: Add _NOLIBC_OPTIMIZER_HIDE_VAR() to compiler.h Date: Mon, 2 Mar 2026 10:17:53 +0000 Message-Id: <20260302101815.3043-2-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Needed to stop compiler 'optimisations' bloating code. Equivalent to the definition in include/linux/compiler.h Signed-off-by: David Laight Acked-by: Willy Tarreau --- Changes for v4: - Remove #if guard tools/include/nolibc/compiler.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compile= r.h index a8c7619dcdde..f03f84cfadce 100644 --- a/tools/include/nolibc/compiler.h +++ b/tools/include/nolibc/compiler.h @@ -71,4 +71,7 @@ # define __nolibc_static_assert(_t) #endif =20 +/* Make the optimizer believe the variable can be manipulated arbitrarily.= */ +#define _NOLIBC_OPTIMIZER_HIDE_VAR(var) __asm__ ("" : "+r" (var)) + #endif /* _NOLIBC_COMPILER_H */ --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77DF13A1A26 for ; Mon, 2 Mar 2026 10:18:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446741; cv=none; b=n+gQm6pl1PVXQDp52L6T3b6IVrtlykPc4EHjd3iT1sBbdFVNHBU4qI9mkIg896NLL8f4KSDGdzCzvXtRlhwi3OxVu+aYlOucUG8VMPy4OszKR69YfTKDrocDf0FrWzUzLtRe6/y+WYeApSsMn/3ZCv8XQF3th5I01VrBrveJPmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446741; c=relaxed/simple; bh=cT3l67nJJSwZ5/IJsp1A2MYVrZXWclT+13bVD9jsh40=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QzjDClFgqQa9AuHCFuGd9xZMd6oO0b9lcEZxvS4/tPGbDDiVk0phhjt4mLbH5+V3DZ+Rf+63zwnhznaq3X+spzwL1KbFHBJyIt+C3AKkj/X6cBAIlOvpwH3vw9h1nBrC2xHbEcFZmX+D5BnBh+JbaygyQHo7WG9Ha73inltkQ4g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=sslXVWCk; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="sslXVWCk" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MY-003BdB-AH; Mon, 02 Mar 2026 11:18:54 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=n4Ywia81sK3cCjsfCYb9dvWvREMVAccpZhYd33h28W0=; b=sslXVWCkbi/IkqvSKM1V7dV4gA l60MbcGpHBupJaf/DygEbQbGBBqlE9SRL0jVDxCRC7JjbrjHGW+oZ6mqVCpHGgFKi3ukRa9Fu5+qV aO2nNfu6OZUu4q9dlc2diC9bbBggtiuPo5yx5TSjcsTtVa6QtFpsKvsKoDoEr7YbYYfr4a5BvRL8W dd7hkMY1w7gCxPS+HjEl+BDX4yJFGqav2jDlMfmdNbV816D+ppUnTFDokugxcFxkfOzNg+C84idop qS6tr2WDbNtOjlGsoyNIesGLUoYn1IIuoNs6tTbRjupAQ4T0fweAbxdwua6h6bhtJzsFtYtrO9wQo GB+3maKQ==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MY-000560-0n; Mon, 02 Mar 2026 11:18:54 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0M8-006y7o-TT; Mon, 02 Mar 2026 11:18:28 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 02/23] tools/nolibc/printf: Move snprintf length check to callback Date: Mon, 2 Mar 2026 10:17:54 +0000 Message-Id: <20260302101815.3043-3-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Move output truncation to the snprintf() callback. This simplifies the main code and fixes truncation of padded fields. Add a zero length callback to 'finalise' the buffer rather than doing it in snprintf() itself. Fixes e90ce42e81381 ("tools/nolibc: implement width padding in printf()") Signed-off-by: David Laight Acked-by: Willy Tarreau --- For v4: - Avoid memcpy(ptr, NULL, 0) For v3: - Patch 2 in v2, patch 1 in v1. - Note that it fixes e90ce42e81381. - Update comments (again). - Rename size =3D> space in snprintf 'state. - Copy state->space to a local rather than relying on the compiler doing CSE, changes the code slightly for x86 (but not the size). - Unconditionally write a '\0' to terminate the old data before overwriting it with new data. Saves a few bytes of object code. tools/include/nolibc/stdio.h | 94 +++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 77d7669cdb80..a4df72d9a2d3 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -295,16 +295,25 @@ int fseek(FILE *stream, long offset, int whence) * - %[l*]{d,u,c,x,p} * - %s * - unknown modifiers are ignored. + * + * Called by vfprintf() and snprintf() to do the actual formatting. + * The callers provide a callback function to save the formatted data. + * The callback function is called multiple times: + * - for each group of literal characters in the format string. + * - for field padding. + * - for each conversion specifier. + * - with (NULL, 0) at the end of the __nolibc_printf. + * If the callback returns non-zero __nolibc_printf() immediately returns = -1. */ -typedef int (*__nolibc_printf_cb)(intptr_t state, const char *buf, size_t = size); +typedef int (*__nolibc_printf_cb)(void *state, const char *buf, size_t siz= e); =20 -static __attribute__((unused, format(printf, 4, 0))) -int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const= char *fmt, va_list args) +static __attribute__((unused, format(printf, 3, 0))) +int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, v= a_list args) { char escape, lpref, ch; unsigned long long v; unsigned int written, width; - size_t len, ofs, w; + size_t len, ofs; char outbuf[21]; const char *outstr; =20 @@ -406,17 +415,13 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t s= tate, size_t n, const char outstr =3D fmt; len =3D ofs - 1; flush_str: - if (n) { - w =3D len < n ? len : n; - n -=3D w; - while (width-- > w) { - if (cb(state, " ", 1) !=3D 0) - return -1; - written +=3D 1; - } - if (cb(state, outstr, w) !=3D 0) + while (width-- > len) { + if (cb(state, " ", 1) !=3D 0) return -1; + written +=3D 1; } + if (cb(state, outstr, len) !=3D 0) + return -1; =20 written +=3D len; do_escape: @@ -429,18 +434,25 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t s= tate, size_t n, const char =20 /* literal char, just queue it */ } + + /* Request a final '\0' be added to the snprintf() output. + * This may be the only call of the cb() function. + */ + if (cb(state, NULL, 0) !=3D 0) + return -1; + return written; } =20 -static int __nolibc_fprintf_cb(intptr_t state, const char *buf, size_t siz= e) +static int __nolibc_fprintf_cb(void *stream, const char *buf, size_t size) { - return _fwrite(buf, size, (FILE *)state); + return _fwrite(buf, size, stream); } =20 static __attribute__((unused, format(printf, 2, 0))) int vfprintf(FILE *stream, const char *fmt, va_list args) { - return __nolibc_printf(__nolibc_fprintf_cb, (intptr_t)stream, SIZE_MAX, f= mt, args); + return __nolibc_printf(__nolibc_fprintf_cb, stream, fmt, args); } =20 static __attribute__((unused, format(printf, 1, 0))) @@ -498,26 +510,54 @@ int dprintf(int fd, const char *fmt, ...) return ret; } =20 -static int __nolibc_sprintf_cb(intptr_t _state, const char *buf, size_t si= ze) +struct __nolibc_sprintf_cb_state { + char *buf; + size_t space; +}; + +static int __nolibc_sprintf_cb(void *v_state, const char *buf, size_t size) { - char **state =3D (char **)_state; + struct __nolibc_sprintf_cb_state *state =3D v_state; + size_t space =3D state->space; + char *tgt; + + /* Truncate the request to fit in the output buffer space. + * The last byte is reserved for the terminating '\0'. + * state->space can only be zero for snprintf(NULL, 0, fmt, args) + * so this normally lets through calls with 'size =3D=3D 0'. + */ + if (size >=3D space) { + if (space <=3D 1) + return 0; + size =3D space - 1; + } + tgt =3D state->buf; + + /* __nolibc_printf() ends with cb(state, NULL, 0) to request the output + * buffer be '\0' terminated. + * That will be the only cb() call for, eg, snprintf(buf, sz, ""). + * Zero lengths can occur at other times (eg "%s" for an empty string). + * Unconditionally write the '\0' byte to reduce code size, it is + * normally overwritten by the data being output. + * There is no point adding a '\0' after copied data - there is always + * another call. + */ + *tgt =3D '\0'; + if (size) { + state->space =3D space - size; + state->buf =3D tgt + size; + memcpy(tgt, buf, size); + } =20 - memcpy(*state, buf, size); - *state +=3D size; return 0; } =20 static __attribute__((unused, format(printf, 3, 0))) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { - char *state =3D buf; - int ret; + struct __nolibc_sprintf_cb_state state =3D { .buf =3D buf, .space =3D siz= e }; =20 - ret =3D __nolibc_printf(__nolibc_sprintf_cb, (intptr_t)&state, size, fmt,= args); - if (ret < 0) - return ret; - buf[(size_t)ret < size ? (size_t)ret : size - 1] =3D '\0'; - return ret; + return __nolibc_printf(__nolibc_sprintf_cb, &state, fmt, args); } =20 static __attribute__((unused, format(printf, 3, 4))) --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F23C530F94D for ; Mon, 2 Mar 2026 10:18:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446721; cv=none; b=T92xkihQ4Q1yg7pp/GTuXOpQlsuRRAzOvPg30GZvYYKclzSeUP2o+xnyntdiuy4iYxU9KYkPMyGqQ9xH4239dpoROWw0S37137Az6Rv9r6yTH31D5KtHZKdOFpKGCawQ7Zxhj2B5ttW00p7q/8STqR5+0Z3pLKRbZ55d3v5RTIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446721; c=relaxed/simple; bh=hjUAa9YKRvK7qqDyTf9kNhtjL1yAdZa9hoVLxRCF+uo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Cv+YI+9iPapqq8LxNc1ZeElFRP1teW8xzyyGNDdnPx6uQjnTS6TF52yDQDYb2vmL49sZfEBXfa5koWpx0/DUIcDTk8JYfHRwDAaf1SGDV3Uex6b00dKlTilveSXjwLq4/RQFNnmXgm640Qk5futn51cn9S9rONk8GsGVvPb8Nww= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=bbYK6iwH; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="bbYK6iwH" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0M9-0037zJ-PT; Mon, 02 Mar 2026 11:18:29 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=C13mqcG2akqQnwf5EJbKQoyR2tuPHd4Usz9szFB2aMI=; b=bbYK6iwHBfONdSuJ2IopRU28bh hhMmDF7fjaouy8fPCd/rL6WyNFab1SF9l4p2qiqZ8FU6eN+fnQRBn07DRNgkYuErJpfqNfeLkFuCy I/YWMBPr9SzGC8c3NvSbhBlFPIVmcnsu42qnhKamcmOgoXJYi+gyHdTKBUk7mS3j1w8Z2K16F4wm5 +LQQ9U8pixLOcmfn4JXbumCr1PJbMOXET/G0FNEi2LoeHu4Vf+dT/UXb+YZuTLGFYDUCl7Wt5cyKL WrP3djTNpVmYUrx+CQoN5P7Rshi8wyXHrN/zW/G/LYwp+ehODGX0RFodkHgru/F4LiGAWtA3PNYyv KtddpJGw==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0M9-0002wu-Fu; Mon, 02 Mar 2026 11:18:29 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0M9-006y7o-5b; Mon, 02 Mar 2026 11:18:29 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 03/23] selftests/nolibc: Return correct value when printf test fails Date: Mon, 2 Mar 2026 10:17:55 +0000 Message-Id: <20260302101815.3043-4-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Correctly return 1 (the number of errors) when strcmp() fails rather than the return value from strncmp() which is the signed difference between the mismatching characters. Signed-off-by: David Laight --- New patch for v4. Corrects the error reporting for test failures. But is really replaced by the next patch. tools/testing/selftests/nolibc/nolibc-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 0e8b3b9a86ef..9787e493523c 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1683,7 +1683,7 @@ static int expect_vfprintf(int llen, int c, const cha= r *expected, const char *fm } =20 llen +=3D printf(" \"%s\" =3D \"%s\"", expected, buf); - ret =3D strncmp(expected, buf, c); + ret =3D strncmp(expected, buf, c) !=3D 0; =20 result(llen, ret ? FAIL : OK); return ret; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 90A3C395D9B for ; Mon, 2 Mar 2026 10:18:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446737; cv=none; b=Ea9Xt1U+3LCKVu40nCvgeoje+ke2Ud60mbB/0uIR3ZYOSq9zv1Xs9bih5UAcwKPZOSSqRCHVB/vlNPJB5IbuL4QnS2sc4pM4gcpx+s6lmPanvakJ+c7j5LYGmrFrjhObQ5qDV3JI8SMGBbVApdNyQ7Yzye8JKJ0EZ8ERZO9rhI4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446737; c=relaxed/simple; bh=FDEbNZHxM5oJju2kC2dw9TTUbhlFm10AqW+2cMO05fk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LS5bgflXKRu/8KGeVIz9FZh99Nycf9ejzOwSlasdywPhnLKz51odpmNvIeMVlVW0uBACf7bK2lqo69s6vS60TO2q09zTfjp6ZnalIw72rscGLFoYthptWQ57nD1HJv1zr9YdA6lx5SvQHDaQvNg/d+SEo1pCnqOgOUTutsC9XDA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=NRMms2yw; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="NRMms2yw" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MX-003858-UN; Mon, 02 Mar 2026 11:18:53 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=zmOX8vrTgM8TZEKsPS4lzpMrTwpbveCMW8pTLSdRgvY=; b=NRMms2ywnMHN8SkPVFgBmj//o8 7a6+kUfBN/QQ9dwNoWWAV/rfgTIV+Y987+AS6K7lrcpLH3Y8AFr69T4oDHN7KEjywhllb+GukkfVZ P0K4F+IwiOoUKggxH5hgzgwdKBF3HNwNpmrsSApG4uVRI3hLtOwI1efgdYDE1yAJJPP9ON5quTCCb FO4VEjxNjRlYjV6RZ0w9gwqkSmBWgo9qsrwBI0+GE5cN/L5xSMLj7Pz6xArT50An4hluTqCn4k7lS +DqXQV7XMSbz5xv6YXwadE4Bx8kGCXrs5lUl2UsKzwkB5eP7OPtEuYFuM/wWHzV02jXFVvosdwfRe bvvqyaLA==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MX-0002yv-Kw; Mon, 02 Mar 2026 11:18:53 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0M9-006y7o-Dy; Mon, 02 Mar 2026 11:18:29 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 04/23] selftests/nolibc: check vsnprintf() output buffer before the length Date: Mon, 2 Mar 2026 10:17:56 +0000 Message-Id: <20260302101815.3043-5-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Check the string matches before checking the returned length. Only print the string once when it matches. Makes it a lot easier to diagnose any incorrect output. Signed-off-by: David Laight --- v4: split out from patch 3 tools/testing/selftests/nolibc/nolibc-test.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 9787e493523c..f4813764d56e 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1668,25 +1668,27 @@ static int expect_vfprintf(int llen, int c, const c= har *expected, const char *fm char buf[100]; va_list args; ssize_t w; - int ret; - =20 va_start(args, fmt); /* Only allow writing 21 bytes, to test truncation */ w =3D vsnprintf(buf, 21, fmt, args); va_end(args); =20 + llen +=3D printf(" \"%s\"", buf); + if (strncmp(expected, buf, c)) { + llen +=3D printf(" should be \"%s\"", expected); + result(llen, FAIL); + return 1; + } + if (w !=3D c) { llen +=3D printf(" written(%d) !=3D %d", (int)w, c); result(llen, FAIL); return 1; } =20 - llen +=3D printf(" \"%s\" =3D \"%s\"", expected, buf); - ret =3D strncmp(expected, buf, c) !=3D 0; - - result(llen, ret ? FAIL : OK); - return ret; + result(llen, OK); + return 0; } =20 static int test_scanf(void) --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 90BE239B96F for ; Mon, 2 Mar 2026 10:18:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446738; cv=none; b=dXw343YXU0fFWrQNbK7DgTFrLt/jpGHSecutO31MiDSqSE2dTEiQkEibW2oXF2dKGBgVcP8W66Au/T68132cAnT52D59CVonOuRs0ARWv/M/7kUh6T7/f3RBP6J/fkB1z2L313c7pevhSikbhHKn/fQGv6EoWRbEjbbF2ambV/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446738; c=relaxed/simple; bh=5BsBiOG7tF0nIGMZ7N95BCa5igR/H8JnvlprjuIjToU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dlP90q7797EbOtuXQgoksTZCgDvqkucfP/HlUC815BJV2CEPaqmyLRCka8HRUysgBntDEMW/qcAfXUXsXomOdce/UJdfEV2xTVz5vSPjTGqdnzxWKllED9r2YQ2gmOH6J8Rfq3qHVK7NVPFMi7ma9OaS4jeX+5e+/RoCo46/isM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=kg9GxFJP; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="kg9GxFJP" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MX-003850-Hi; Mon, 02 Mar 2026 11:18:53 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=zaRST1Uuvh431GacKGwhMaa1JzSEfqW4nhRFu8bcjaE=; b=kg9GxFJPTTVMK9JUpfeeVE37v/ DEBC169WsR9bHt3RVo7Pe5IdjOX6Wp/x5luZxnrfG0izl5sK0aWwN4cDnYRgIDWeD2Uzep8BzPLDV 6zQTyv4ldS6pO+8L/+cxTXmOfKiXZz+lsLyAdlKq2F2se4H6H9Z7lKvfWl8R/G6OAEUR3JiyVxzis 520mRCM/C0oFPP8bjgInaFzmFhE66Qtlj2ct6HXeJU0Y8vkYem4GVE4ScUZwgZxTexUqYtFS3tAvZ b7LekpMsxbLxRR2i8Y/aka6/8fBhcvO0GI6Nm+3XIIH++Di/6OJHkgeljn+n5QFzngKpKwUMC5mSR lVuCoKsw==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MX-00055u-8V; Mon, 02 Mar 2026 11:18:53 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0M9-006y7o-ML; Mon, 02 Mar 2026 11:18:29 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 05/23] selftests/nolibc: Use length of 'expected' string to check snprintf() output Date: Mon, 2 Mar 2026 10:17:57 +0000 Message-Id: <20260302101815.3043-6-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Instead of requiring the test cases specifying both the length and expected output, take the length from the expected output. Tests that expect the output be truncated are changed to specify the un-truncated output. Change the strncmp() to a memcmp() with an extra check that the output is actually terminated. Append a '+' to the printed output (after the final ") when the output is truncated. Signed-off-by: David Laight --- v4: split out from patch 3. tools/testing/selftests/nolibc/nolibc-test.c | 67 ++++++++++++-------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index f4813764d56e..dc60ac0d1a05 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1660,29 +1660,44 @@ int run_stdlib(int min, int max) return ret; } =20 -#define EXPECT_VFPRINTF(c, expected, fmt, ...) \ - ret +=3D expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__) +#define EXPECT_VFPRINTF(expected, fmt, ...) \ + ret +=3D expect_vfprintf(llen, expected, fmt, ##__VA_ARGS__) =20 -static int expect_vfprintf(int llen, int c, const char *expected, const ch= ar *fmt, ...) +#define VFPRINTF_LEN 20 +static int expect_vfprintf(int llen, const char *expected, const char *fmt= , ...) { - char buf[100]; + char buf[VFPRINTF_LEN + 80]; + unsigned int cmp_len; va_list args; - ssize_t w; + ssize_t w, expected_len; =20 va_start(args, fmt); - /* Only allow writing 21 bytes, to test truncation */ - w =3D vsnprintf(buf, 21, fmt, args); + /* Limit buffer length to test truncation */ + w =3D vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args); va_end(args); =20 llen +=3D printf(" \"%s\"", buf); - if (strncmp(expected, buf, c)) { - llen +=3D printf(" should be \"%s\"", expected); + + expected_len =3D strlen(expected); + if (expected_len > VFPRINTF_LEN) { + /* Indicate truncated in test output */ + llen +=3D printf("+"); + cmp_len =3D VFPRINTF_LEN; + } else { + cmp_len =3D expected_len; + } + + if (memcmp(expected, buf, cmp_len) || buf[cmp_len]) { + /* Copy and truncate until "%.*s" supported */ + memcpy(buf, expected, cmp_len); + buf[cmp_len] =3D 0; + llen +=3D printf(" should be \"%s\"", buf); result(llen, FAIL); return 1; } =20 - if (w !=3D c) { - llen +=3D printf(" written(%d) !=3D %d", (int)w, c); + if (w !=3D expected_len) { + llen +=3D printf(" written(%d) !=3D %d", (int)w, (int)expected_len); result(llen, FAIL); return 1; } @@ -1809,21 +1824,21 @@ static int run_printf(int min, int max) * test numbers. */ switch (test + __LINE__ + 1) { - CASE_TEST(empty); EXPECT_VFPRINTF(0, "", ""); break; - CASE_TEST(simple); EXPECT_VFPRINTF(3, "foo", "foo"); break; - CASE_TEST(string); EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break; - CASE_TEST(number); EXPECT_VFPRINTF(4, "1234", "%d", 1234); break; - CASE_TEST(negnumber); EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break; - CASE_TEST(unsigned); EXPECT_VFPRINTF(5, "12345", "%u", 12345); break; - CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; - CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break; - CASE_TEST(pointer); EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); = break; - CASE_TEST(uintmax_t); EXPECT_VFPRINTF(20, "18446744073709551615", "%j= u", 0xffffffffffffffffULL); break; - CASE_TEST(intmax_t); EXPECT_VFPRINTF(20, "-9223372036854775807", "%j= d", 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); b= reak; - CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%2= 5d", 1); break; + CASE_TEST(empty); EXPECT_VFPRINTF("", ""); break; + CASE_TEST(simple); EXPECT_VFPRINTF("foo", "foo"); break; + CASE_TEST(string); EXPECT_VFPRINTF("foo", "%s", "foo"); break; + CASE_TEST(number); EXPECT_VFPRINTF("1234", "%d", 1234); break; + CASE_TEST(negnumber); EXPECT_VFPRINTF("-1234", "%d", -1234); break; + CASE_TEST(unsigned); EXPECT_VFPRINTF("12345", "%u", 12345); break; + CASE_TEST(char); EXPECT_VFPRINTF("c", "%c", 'c'); break; + CASE_TEST(hex); EXPECT_VFPRINTF("f", "%x", 0xf); break; + CASE_TEST(pointer); EXPECT_VFPRINTF("0x1", "%p", (void *) 0x1); bre= ak; + CASE_TEST(uintmax_t); EXPECT_VFPRINTF("18446744073709551615", "%ju", = 0xffffffffffffffffULL); break; + CASE_TEST(intmax_t); EXPECT_VFPRINTF("-9223372036854775807", "%jd", = 0x8000000000000001LL); break; + CASE_TEST(truncation); EXPECT_VFPRINTF("0123456789012345678901234", "%= s", "0123456789012345678901234"); break; + CASE_TEST(string_width); EXPECT_VFPRINTF(" 1", "%10s", "1"); bre= ak; + CASE_TEST(number_width); EXPECT_VFPRINTF(" 1", "%10d", 1); break; + CASE_TEST(width_trunc); EXPECT_VFPRINTF(" 1", "%= 25d", 1); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 90AD3399006 for ; Mon, 2 Mar 2026 10:18:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446746; cv=none; b=I/AJSuWh9fTsi/pHZE9RP7liUaafUJcurDFkVRlz8wAheDLhnRv5Y/wMQ/etfXeZsZRg5fz3DHHMKUV2JjWrDstPsRU5dWZxhWOHoqXiiOdqtmPsWKtvJOcSDpHZBiM/nKJxZe7FRjJIDv+PBm5wRffKuhNB69DQNpWIKB0pNzM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446746; c=relaxed/simple; bh=yHpYWV1+rraIHu3lmbs4y5KQwoC7AkTkEii1/8vTzfs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZP5rQAYRqbVl6BI0Actj2YGCXArrK+kFHgio2MyhYkAUj/8/cwOjxM7noDmNLxCjzW0IdPVLSF7AqTLY7stq+gW3tOPuX3SnBQbuIlgS0r45LjiZcQJcCPYS8nzPQRPnO+nMwZkqISZPmLossJJg1Mqt/VzH6sNCRcMV6/QfH3o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=kIiHHCOP; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="kIiHHCOP" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MX-00384q-5n; Mon, 02 Mar 2026 11:18:53 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=cdMNrkGLFoBG9RhI7QFWdlWy3pp01bXEMox52yDwV5M=; b=kIiHHCOPsheqrz86vqjc6zuXav E5MLPVeJlRWTpq3KlkEeU/4riZJdLbJn1GEVZmACrSRfNZu5joaMPK9v/wPLbTEoqUIRQLNpoURwI Vhj3c6qSmhtSqbRsh0wNWP+OLNFMI4MNoCxaL/S72VHCGDK7PVxEYxGEvW0oVs9/LXt3CeboqKPo+ gwyJs60C5OAV5BALcPnvLWP+mYh85wmBsrV4CuTm3hEMJnAeNbz0MNu6HC4DvlccK7IEJU44vkxYn 4EFHhgYkAgyjjePYtIwB0W+d/vECMalE6DD7uyVkqW4vz4Evx7pn5n67eW3n8FBWQ8Minc4H4DG5r NF98DBUA==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MW-0002yp-SI; Mon, 02 Mar 2026 11:18:53 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0M9-006y7o-Uw; Mon, 02 Mar 2026 11:18:30 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 06/23] selftests/nolibc: Check that snprintf() doesn't write beyond the buffer end Date: Mon, 2 Mar 2026 10:17:58 +0000 Message-Id: <20260302101815.3043-7-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Fill buf[] with known data and check the vsnprintf() doesn't write beyond the specified buffer length. Would have picked up the bug in field padding. Signed-off-by: David Laight --- v4: split out from patch 3 tools/testing/selftests/nolibc/nolibc-test.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index dc60ac0d1a05..420f2d25e8cf 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1671,6 +1671,10 @@ static int expect_vfprintf(int llen, const char *exp= ected, const char *fmt, ...) va_list args; ssize_t w, expected_len; =20 + /* Fill and terminate buf[] to check for overlong/absent writes */ + memset(buf, 0xa5, sizeof(buf) - 1); + buf[sizeof(buf) - 1] =3D 0; + va_start(args, fmt); /* Limit buffer length to test truncation */ w =3D vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args); @@ -1702,6 +1706,15 @@ static int expect_vfprintf(int llen, const char *exp= ected, const char *fmt, ...) return 1; } =20 + /* Check for any overwrites after the actual data. */ + while (++cmp_len < sizeof(buf) - 1) { + if ((unsigned char)buf[cmp_len] !=3D 0xa5) { + llen +=3D printf(" overwrote buf[%d] with 0x%x", cmp_len, buf[cmp_len]); + result(llen, FAIL); + return 1; + } + } + result(llen, OK); return 0; } --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36661395D9B for ; Mon, 2 Mar 2026 10:18:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446722; cv=none; b=Eoa7Gvyh/kc4drRffyS8J9vsRQbSlmp3SWw2gwwrI1poV0v9/br738qnFW9eNFUiSau4uJSNl8KtKg/Bpxp7wKShd70aZqlNlwKExYR9Top//1+6kJDfWgN7jjI8tVNmZWmSAiJLJA4rrovesmIniAXonphujEZvt+O2ApkRnOM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446722; c=relaxed/simple; bh=5IwX7Xq9LPPMflMctz/LObqroKJVbPpDW97osJppcfo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Cn3repzT83AgcQE1ox8S3zntLschkdk+juakkoAzWVR3FKyCVJp99Kj2+OjIZ9d/iVWucHlYy7hkOqN9vxiXYNTZayAaMXVi7Iyn54k5j5134wHmFfRoRY0VJLPG22PsYVZdRSlnyYup5wETm4HhF7+1ebr/y1rpj8hGN9vcYhU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=IMsWKAmO; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="IMsWKAmO" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0ME-0037zU-Vq; Mon, 02 Mar 2026 11:18:35 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=8SH88166dxV2p/4Py6d86xiDUf9A5wxKjgItQsA1Rpo=; b=IMsWKAmOULt0u0BVOIbmzMp295 49vzWHaohs+LkiKnPQwy8zQtdqL0i0ZFKGcMpYhrMjbmYm/fQE1mkqME26w8jwOATFlhcQRF7nGAg RJ5o1FWtIwNgVzHKm3F/QbeBIU/MlCfh9npaOGvG7aNCXFvuM/9OVP+KmMXSoEmLT3eBz8fRWN4tM 79IykXCrfzvJ1WwvJNSbQBk+hHLhUI3biSYWE52DVE1Gkwjd0Wf0I06603XlVzeSOPOdMgPLi9H32 CoTmIL3QBy7flgrEYZ5jlPXzNTUB8sd97OBMQr4uc5ec1wsrnkGWf3a5dYtSWu/ANaLL7JLfjfkQv WLjCFw2g==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MA-000522-KH; Mon, 02 Mar 2026 11:18:34 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MA-006y7o-6q; Mon, 02 Mar 2026 11:18:30 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 07/23] selftests/nolibc: Let EXPECT_VFPRINTF() tests be skipped Date: Mon, 2 Mar 2026 10:17:59 +0000 Message-Id: <20260302101815.3043-8-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Tests that check explicit nolibc behavior (eg "%m") or test places where the nolibc behaviour deviates from the libc need skipping when compiled to use the host libc. Signed-off-by: David Laight --- Changes for v4: - Split out from patch 3. - Implement the 'skip' in EXPECT_VFPRINTF() not expect_vfprintf() to match the other tests. tools/testing/selftests/nolibc/nolibc-test.c | 34 ++++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 420f2d25e8cf..51390b709af1 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1660,8 +1660,8 @@ int run_stdlib(int min, int max) return ret; } =20 -#define EXPECT_VFPRINTF(expected, fmt, ...) \ - ret +=3D expect_vfprintf(llen, expected, fmt, ##__VA_ARGS__) +#define EXPECT_VFPRINTF(cond, expected, fmt, ...) \ + do { if (!(cond)) result(llen, SKIPPED); else ret +=3D expect_vfprintf(ll= en, expected, fmt, ##__VA_ARGS__); } while (0) =20 #define VFPRINTF_LEN 20 static int expect_vfprintf(int llen, const char *expected, const char *fmt= , ...) @@ -1837,21 +1837,21 @@ static int run_printf(int min, int max) * test numbers. */ switch (test + __LINE__ + 1) { - CASE_TEST(empty); EXPECT_VFPRINTF("", ""); break; - CASE_TEST(simple); EXPECT_VFPRINTF("foo", "foo"); break; - CASE_TEST(string); EXPECT_VFPRINTF("foo", "%s", "foo"); break; - CASE_TEST(number); EXPECT_VFPRINTF("1234", "%d", 1234); break; - CASE_TEST(negnumber); EXPECT_VFPRINTF("-1234", "%d", -1234); break; - CASE_TEST(unsigned); EXPECT_VFPRINTF("12345", "%u", 12345); break; - CASE_TEST(char); EXPECT_VFPRINTF("c", "%c", 'c'); break; - CASE_TEST(hex); EXPECT_VFPRINTF("f", "%x", 0xf); break; - CASE_TEST(pointer); EXPECT_VFPRINTF("0x1", "%p", (void *) 0x1); bre= ak; - CASE_TEST(uintmax_t); EXPECT_VFPRINTF("18446744073709551615", "%ju", = 0xffffffffffffffffULL); break; - CASE_TEST(intmax_t); EXPECT_VFPRINTF("-9223372036854775807", "%jd", = 0x8000000000000001LL); break; - CASE_TEST(truncation); EXPECT_VFPRINTF("0123456789012345678901234", "%= s", "0123456789012345678901234"); break; - CASE_TEST(string_width); EXPECT_VFPRINTF(" 1", "%10s", "1"); bre= ak; - CASE_TEST(number_width); EXPECT_VFPRINTF(" 1", "%10d", 1); break; - CASE_TEST(width_trunc); EXPECT_VFPRINTF(" 1", "%= 25d", 1); break; + CASE_TEST(empty); EXPECT_VFPRINTF(1, "", ""); break; + CASE_TEST(simple); EXPECT_VFPRINTF(1, "foo", "foo"); break; + CASE_TEST(string); EXPECT_VFPRINTF(1, "foo", "%s", "foo"); break; + CASE_TEST(number); EXPECT_VFPRINTF(1, "1234", "%d", 1234); break; + CASE_TEST(negnumber); EXPECT_VFPRINTF(1, "-1234", "%d", -1234); break; + CASE_TEST(unsigned); EXPECT_VFPRINTF(1, "12345", "%u", 12345); break; + CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; + CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break; + CASE_TEST(pointer); EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); = break; + CASE_TEST(uintmax_t); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju= ", 0xffffffffffffffffULL); break; + CASE_TEST(intmax_t); EXPECT_VFPRINTF(1, "-9223372036854775807", "%jd= ", 0x8000000000000001LL); break; + CASE_TEST(truncation); EXPECT_VFPRINTF(1, "0123456789012345678901234",= "%s", "0123456789012345678901234"); break; + CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); = break; + CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); br= eak; + CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1",= "%25d", 1); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C851239B965 for ; Mon, 2 Mar 2026 10:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446732; cv=none; b=LZwQM4SiJ/IgXkUbSPPCVLi28IaPwFGMmRtBstpx+tT6G+Ur+6Q3LIrGpHzv9W1yIt8ma4oOrBOXBpSrAjRhl0w8MhPzpOs5PELpP5Zjkr3owxOOmvw+0mmdhMMpouj93ogE1SoQ8s51/onhnZzdjXVk7fh6hGy5tc2nEz/dWTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446732; c=relaxed/simple; bh=XVgW8JsucUeHuoAk4t1KnY7Y0DHm3XaX1T6BD7BpQqI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BAUtx+FEuhQyLgV+SK1VElsiZe7Rncm7aAdSs4HOPEbGATct+4V7IhKLeiOhX+n2dMsCO/CDCLUb4RAf55KNasO6cq/j2RYJtpopY1BVwA3OSVbHc0yo+ZaEAbczuySx3qabnkDQNLRI9Hmc2DuJo57O6yVZ5/ElJieYjulLtu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=KHHxBD5d; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="KHHxBD5d" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MT-00382P-6P; Mon, 02 Mar 2026 11:18:49 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=85ZSTyhj/oNlbtSkQtp3rSGEwfg9LAyZv6ZK6KV1JQ4=; b=KHHxBD5dM7t6PZ8p9Rg5bbI762 j25QZy3wqRalFM2V+bVXIYzJoT4QcSDAKrT6sXl1S9ceJjd6/cajuYB8NjnQ2rvr0KQ22aJ5NvzPX 3QbWA74tY59YF9C4NJeSam6qon/mQIJTuQAwvJronK2gn68q5AtmWeoX0UOTtqUVaWjj2YuSjVskh xBEyNG5Bn+frs+smCXW0cqMdqbxso71uqu5FCx1CuLx1m6d0tiIREuIdcK1LmZzlfTWZZcrUXxxWm 7bzQBEOGPlr51/TGfVUnFbdCNHe7K4jVDv8dDg6CSbUjWB28nepPUfHT1zRnllu5kZee0Q0BVggGH W/WZJxZg==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MS-0002yF-Sm; Mon, 02 Mar 2026 11:18:49 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MA-006y7o-FH; Mon, 02 Mar 2026 11:18:30 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH 08/23] selftests/nolibc: Rename w to written in expect_vfprintf() Date: Mon, 2 Mar 2026 10:18:00 +0000 Message-Id: <20260302101815.3043-9-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Single character variable names don't make code easy to read. Rename 'w' (used for the return value from snprintf()) 'written'. Signed-off-by: David Laight --- V4: Split out from patch 4. tools/testing/selftests/nolibc/nolibc-test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 51390b709af1..9ebebe4ff253 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1669,7 +1669,7 @@ static int expect_vfprintf(int llen, const char *expe= cted, const char *fmt, ...) char buf[VFPRINTF_LEN + 80]; unsigned int cmp_len; va_list args; - ssize_t w, expected_len; + ssize_t written, expected_len; =20 /* Fill and terminate buf[] to check for overlong/absent writes */ memset(buf, 0xa5, sizeof(buf) - 1); @@ -1677,7 +1677,7 @@ static int expect_vfprintf(int llen, const char *expe= cted, const char *fmt, ...) =20 va_start(args, fmt); /* Limit buffer length to test truncation */ - w =3D vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args); + written =3D vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args); va_end(args); =20 llen +=3D printf(" \"%s\"", buf); @@ -1700,8 +1700,8 @@ static int expect_vfprintf(int llen, const char *expe= cted, const char *fmt, ...) return 1; } =20 - if (w !=3D expected_len) { - llen +=3D printf(" written(%d) !=3D %d", (int)w, (int)expected_len); + if (written !=3D expected_len) { + llen +=3D printf(" written(%d) !=3D %d", (int)written, (int)expected_len= ); result(llen, FAIL); return 1; } --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48C3D379EDF for ; Mon, 2 Mar 2026 10:18:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446732; cv=none; b=L3blmTuCfoN29tINT11PbxwJkoNCqfD0hUpqdT6gNfwPCk+7c007n5ktiMsA3RKlvkbRbg+w7c4BWDH986RNdzOsGMuGReyqTpyc7hDDu00uDfGbKf34xzgxRd4wDpTQHXXQDxNi2LxzR5vqwW7jOL25P4caf/6knVDYmgOZpuY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446732; c=relaxed/simple; bh=21Ni4sgy3oP/YfIQHf1CNpcmZ82ZbMS2bDhRc58HV80=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uiy2+yEWbgKxsP/0jkFS19a5h0Oq+Hf26m1pG6E/RI2xCSieCb9xpulk/EFnGjkE1hUbagEMozwmVkIbL7hZ67KUpUGYmETZ0E2HOFyPm7oLZBukPeov6kaaEzrrWsdVvr24B20W2XFhy11+Mn5l8tCHkbobrfeBLfN/53db6Iw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=gKxiCkbQ; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="gKxiCkbQ" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MT-003BZS-Kl; Mon, 02 Mar 2026 11:18:49 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=C2n+wgBdtz9zcscPp4wqXNFM9CAwkM9llyY5FovAdd4=; b=gKxiCkbQLK7ha/6krn7j4PDoDU Ab1J+UESmZyrgfclRK2nvXGkH7rQYeSEUGo4gGP6FiQk3VVUrRLOyDUnuYxL3m0RWh0k+UO59JZaz fGscuNhBgpacf7fJMn+AK/6u19FE1OGSE3GqoX/6ChE5+I6mGaKq0ad67fxeC4Epm4g8yX3sdDLPn GZ8nAz01sc+nW8oAyyRB3lcewn0bEp8yA7QvvR5JMDQylNHoc5cvQmGXi0c9A+uhzZK54BnmMBE/i uz8xxoKs0BuIayjF8nim6auZRaV06g3qc1wbg3b8B0LBeYdU43+R2EJPh73wqKXTB6XNk5CBLNFr/ nrgF0V+g==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MT-0002yL-9i; Mon, 02 Mar 2026 11:18:49 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MA-006y7o-Nd; Mon, 02 Mar 2026 11:18:30 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 09/23] tools/nolibc: Implement strerror() in terms of strerror_r() Date: Mon, 2 Mar 2026 10:18:01 +0000 Message-Id: <20260302101815.3043-10-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight strerror() can be the only part of a program that has a .data section. This requres 4k in the program file. Add a simple implementation of strerror_r() (ignores buflen) and use that in strerror() so that the "errno=3D" string is copied at run-time. Use __builtin_memcpy() because that optimises away the input string and just writes the required constants to the target buffer. Ignoring buflen is unlikely to be a problem given that the output is always short. Code size change largely depends on whether the inlining decision for strerror() changes. Change the tests to use the normal EXPECT_VFPRINTF() when testing %m. Skip the tests when !is_nolibc. Signed-off-by: David Laight --- v4: - Leave the NOLIBC_IGNORE_ERRNO check in __nolibc_printf(). - Don't rename the errno parameter to strerror() in this patch. tools/include/nolibc/stdio.h | 18 +++++++++++++++--- tools/testing/selftests/nolibc/nolibc-test.c | 20 ++------------------ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index a4df72d9a2d3..03fcd0229f90 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -722,14 +722,26 @@ int setvbuf(FILE *stream __attribute__((unused)), return 0; } =20 +static __attribute__((unused,)) +int strerror_r(int errnum, char *buf, size_t buflen __attribute__((unused)= )) +{ + __builtin_memcpy(buf, "errno=3D", 6); + return 6 + i64toa_r(errnum, buf + 6); +} + static __attribute__((unused)) const char *strerror(int errno) { - static char buf[18] =3D "errno=3D"; + static char buf[18]; + char *b =3D buf; + + /* Force gcc to use 'register offset' to access buf[]. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(b); =20 - i64toa_r(errno, &buf[6]); + /* Use strerror_r() to avoid having the only .data in small programs. */ + strerror_r(errno, b, sizeof(buf)); =20 - return buf; + return b; } =20 #endif /* _NOLIBC_STDIO_H */ diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 9ebebe4ff253..638f18fc5123 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1786,23 +1786,6 @@ static int test_scanf(void) return 0; } =20 -int test_strerror(void) -{ - char buf[100]; - ssize_t ret; - - memset(buf, 'A', sizeof(buf)); - - errno =3D EINVAL; - ret =3D snprintf(buf, sizeof(buf), "%m"); - if (is_nolibc) { - if (ret < 6 || memcmp(buf, "errno=3D", 6)) - return 1; - } - - return 0; -} - static int test_printf_error(void) { int fd, ret, saved_errno; @@ -1852,8 +1835,9 @@ static int run_printf(int min, int max) CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); = break; CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); br= eak; CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1",= "%25d", 1); break; + CASE_TEST(errno); errno =3D 22; EXPECT_VFPRINTF(is_nolibc, "errno= =3D22", "%m"); break; + CASE_TEST(errno-neg); errno =3D -22; EXPECT_VFPRINTF(is_nolibc, " e= rrno=3D-22", "%12m"); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; - CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; case __LINE__: return ret; /* must be last */ --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A138C30BF70 for ; Mon, 2 Mar 2026 10:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446738; cv=none; b=KVva4SryOm23jKRwqx6kgrRq8m8RXnzqOhMRJvk2+c9Q0nFIABUoHeBpHWfjdWNuh9AQEIZYRBxvlVVknld4fVrAYkgD2Z/Ggj6YLwP/H0ehFoZzWtWKlwZDf3r/Jet7xIdBvvg9akdbU3SXTiTEJnAaYcPZO7ijiRhRKiPBRTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446738; c=relaxed/simple; bh=mCSPed7AHFcMNuHHq0bG4fjc1cHlDqpqZWCT1XNyDU0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AMnthHGl/ZhyasMml74JppWtSoR1RRQlsawuJY+Cm1niy4sAEWesUhaUXB0vJbos63Yp+zfYMZZ6LJjOiwVjVuXcK2emClNUU9fuUtfYDZhaTKGKO3GVcPJFS/BkZVuGdngDgKsLJHA1FcAny4QJHXgqce5qhcPMNVH5UkQaqE8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=d+Pxy/aF; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="d+Pxy/aF" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MU-003BaM-0r; Mon, 02 Mar 2026 11:18:50 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=497xUsnVEtW9Xpu7mj/f0vOhWR1K3fzMfjlQ+XiJHU4=; b=d+Pxy/aFGMD+DgDJCZ9rjY1DV5 8I6zSkXxsplEtLlryaHLBWqJcHCwxH1xCi0Rsd2rVplNnWRRiSHGSZPaWGLOe8uNNmkA0OKxwWX+0 Re4E3SWwMQHmifhFfqQUjut7sSYFzQ2ErBWmRmZU3HBCHDdVzvfuAMcpylYsbM/j7l9JXkt0iducQ KGzZgGbWOBUfHOCm6vZsbEcjyPAVbYLRrwP/WOGLOMNjG3bjSW2TMUH/OraKOWnGTW9k/XFxXY5VJ 6rJ05aZaq1flaS10y/Izmdsqg0yXSt5MCLyj6gH9FW7ZfGxGKmFuhz4RIdeqnu9s/p/y99PRC6IcE 2HaukEOg==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MT-00055W-N9; Mon, 02 Mar 2026 11:18:49 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MA-006y7o-Vy; Mon, 02 Mar 2026 11:18:31 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 10/23] tools/nolibc: Rename the 'errnum' parameter to strerror() Date: Mon, 2 Mar 2026 10:18:02 +0000 Message-Id: <20260302101815.3043-11-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Change the parameter variable name from 'errno' to 'errnum'. Matches any documentation and avoids any issues that might happen if errno is actually a #define (which is not uncommon). Signed-off-by: David Laight Acked-by: Willy Tarreau --- v4: - split from the previous patch. tools/include/nolibc/stdio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 03fcd0229f90..a567b9a5c31e 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -730,7 +730,7 @@ int strerror_r(int errnum, char *buf, size_t buflen __a= ttribute__((unused))) } =20 static __attribute__((unused)) -const char *strerror(int errno) +const char *strerror(int errnum) { static char buf[18]; char *b =3D buf; @@ -739,7 +739,7 @@ const char *strerror(int errno) _NOLIBC_OPTIMIZER_HIDE_VAR(b); =20 /* Use strerror_r() to avoid having the only .data in small programs. */ - strerror_r(errno, b, sizeof(buf)); + strerror_r(errnum, b, sizeof(buf)); =20 return b; } --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 90B6039B4AD for ; Mon, 2 Mar 2026 10:18:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446742; cv=none; b=J/a2qjj5iK3MCxfkz7sdqlEaXT3avP0UhQUrg1xHuIPO5wYemnUBiLjFIaotrfEuNcuX2xrpcNr32+z3BOPnshEJqJqPJD81SOLkMjjR6pQg5S4wmQ/JRlxPJ+sSIv1dzTIYtIe53a6tXkj5aXD6krh4qrmeO3u037oL/KvFMfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446742; c=relaxed/simple; bh=qgSwzNHzo7XYyh5Kbk4YixAxkfYFqHpzmImd7S5yLxg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Gub3yJLKZAyWuEsp7NOFn8XMKCIsn4Cjqv66MLTa1PhJLu9lAvxBBCG4NVmLTwPLSrFyJT0nCTTOUn5+HW5RlJUEGEaY2IxVF1O55hckmwWVCS2odNbzxtbiUR0WTiR/as+QUq6SXF49s+CD/hTGEXvd6gcE6LqACL6HM2773C4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=iRnhI4yl; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="iRnhI4yl" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MW-00384k-Oo; Mon, 02 Mar 2026 11:18:52 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=5JXiJL2ibz7/9OE+ZqLhexoyD631zHM7ijt51sMSu1o=; b=iRnhI4ylgUWwKP5Qwr+nf0RyzH xKr0yJs6vOcuhvgbwM1inrT+cq6TEglU7hOFt0z65Uvcboy15Q0H7lG4t3GPzDtE2mAIRpCbzdWy9 ZDy6XrYMGJG09SZ7Gnc1e2HD8WfIZ9w+Ya5GeJPVmZmGA9VPOB3zmvsB9X3KJ7kikaPMWyJXBTTFb o1qCDCil5xUHRxY3f5rHwnCzAI7NZ/z5Fu0KtB0zrgUJjUQwAPFcOWjomVSHIvYyNrM5tYCKpjtjX VASTBe8n6hqFHy++Ft3EGqhXZNsC5PxZmNGVO2A/603ckDGs+YZ6vn3cyvVRbNylUzPescLzVBecO V6RTnW8g==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MW-00055o-FU; Mon, 02 Mar 2026 11:18:52 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MB-006y7o-84; Mon, 02 Mar 2026 11:18:31 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 11/23] tools/nolibc/printf: Output pad characters in 16 byte chunks Date: Mon, 2 Mar 2026 10:18:03 +0000 Message-Id: <20260302101815.3043-12-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Simple to do and saves calls to the callback function. Change variables written, width and len to 'signed int' to get better code. Acked-by: Willy Tarreau Signed-off-by: David Laight --- For v4: no change. For v3: - Change to signed variables here rather than a later patch. tools/include/nolibc/stdio.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index a567b9a5c31e..5368b710c3cb 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -312,8 +312,8 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list { char escape, lpref, ch; unsigned long long v; - unsigned int written, width; - size_t len, ofs; + int written, width, len; + size_t ofs; char outbuf[21]; const char *outstr; =20 @@ -415,10 +415,14 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list outstr =3D fmt; len =3D ofs - 1; flush_str: - while (width-- > len) { - if (cb(state, " ", 1) !=3D 0) + width -=3D len; + while (width > 0) { + /* Output pad in 16 byte blocks with the small block first. */ + int pad_len =3D ((width - 1) & 15) + 1; + width -=3D pad_len; + written +=3D pad_len; + if (cb(state, " ", pad_len) !=3D 0) return -1; - written +=3D 1; } if (cb(state, outstr, len) !=3D 0) return -1; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB1E039B97D for ; Mon, 2 Mar 2026 10:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446744; cv=none; b=ihFSF0GBW3wny+DAeOVpshG5yutVxWsHmWtYkdmuFHSKHjpOBCH2+79ilOdbpzjnjT0pbT5ABxG9dW7AiZQCXFQpeDpc82/7ITxuKI/7QSTTLLFwxarZIhbMM4Jkc9pEBeJ74z1v+xE556yzRYtqPIFKVmVA8aAZoHUWkespeMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446744; c=relaxed/simple; bh=1UiYV/UJYs1Cb0jmle9cVqXIpaJYiN5kW3D54sqDZtA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NA36+1q9wt2QKOTlq3WjLLYsSBAiVC4Ng/0NDXC6GFhgkqsqw0MJ0WYq3X2X+vFhkHqWg3od4OTdRShGtQ8RMvHZz3xqcJiNpboKQdhaJ/hGOfRKH2IgemBCizdeWRVAEGfzUND4YJakBpdaMvfWXfufn3nvu/XtbpJFfr8d3cM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=eOQvYM9x; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="eOQvYM9x" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MW-003BcP-0C; Mon, 02 Mar 2026 11:18:52 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=5btc/IupJFySBDUtKu5TYS3uCKBNnCKgOmRU41xQnsU=; b=eOQvYM9xL+aRXCR8Vw3VaD/sQ7 C2zPgSdJu6TslScr7rkgZRFdK9PpaYv+r2e9EzlDBWpa0KifgJd31dJOmJHH3UhWJblhrw71yYB1Z IJpNyZahYLpcyl7Y/KHqKeWjsTjoEtV1WM/rSylEBRmHleoQhNbokfhqk2T8MmjPzxumHrM8fuc44 88OVeb6NX2+sdtbDIDoQ2I3ciNHW8sxDoqQCtw0uApJ17iJC8rc/mnawKoU4XqSirv1lznKb5BTmp XdgrdD2edViiWJXpiAKgHF9BQRbToWjNcuDigdPCQFKG5lQHEKGK+dW54nD3A7antMRVdTLFxNjOu RUcnBASw==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MV-0002yd-Mi; Mon, 02 Mar 2026 11:18:51 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MB-006y7o-GP; Mon, 02 Mar 2026 11:18:31 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH 12/23] tools/nolibc/printf: Simplify __nolibc_printf() Date: Mon, 2 Mar 2026 10:18:04 +0000 Message-Id: <20260302101815.3043-13-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Move the check for the length modifiers into the format processing between the field width and conversion specifier. This lets the loop be simplified and a 'fast scan' for a format start used. If an error is detected (eg an invalid conversion specifier) then copy the invalid format to the output buffer. Reduces code size by about 10% on x86-64. Some versions of gcc bloat this version by generating a jump table. All goes away in the later patches. Acked-By; Willy Tarreau Signed-off-by: David Laight Acked-By; Willy Tarreau --- No change for v3 or v4. tools/include/nolibc/stdio.h | 104 ++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 5368b710c3cb..e0b7ff537b14 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -310,28 +310,52 @@ typedef int (*__nolibc_printf_cb)(void *state, const = char *buf, size_t size); static __attribute__((unused, format(printf, 3, 0))) int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, v= a_list args) { - char escape, lpref, ch; + char lpref, ch; unsigned long long v; int written, width, len; - size_t ofs; char outbuf[21]; const char *outstr; =20 - written =3D ofs =3D escape =3D lpref =3D 0; + written =3D 0; while (1) { - ch =3D fmt[ofs++]; + outstr =3D fmt; + ch =3D *fmt++; + if (!ch) + break; + width =3D 0; + if (ch !=3D '%') { + while (*fmt && *fmt !=3D '%') + fmt++; + /* Output characters from the format string. */ + len =3D fmt - outstr; + } else { + /* we're in a format sequence */ =20 - if (escape) { - /* we're in an escape sequence, ofs =3D=3D 1 */ - escape =3D 0; + ch =3D *fmt++; =20 /* width */ while (ch >=3D '0' && ch <=3D '9') { width *=3D 10; width +=3D ch - '0'; =20 - ch =3D fmt[ofs++]; + ch =3D *fmt++; + } + + /* Length modifiers */ + if (ch =3D=3D 'l') { + lpref =3D 1; + ch =3D *fmt++; + if (ch =3D=3D 'l') { + lpref =3D 2; + ch =3D *fmt++; + } + } else if (ch =3D=3D 'j') { + /* intmax_t is long long */ + lpref =3D 2; + ch =3D *fmt++; + } else { + lpref =3D 0; } =20 if (ch =3D=3D 'c' || ch =3D=3D 'd' || ch =3D=3D 'u' || ch =3D=3D 'x' ||= ch =3D=3D 'p') { @@ -387,56 +411,34 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list #else outstr =3D strerror(errno); #endif /* NOLIBC_IGNORE_ERRNO */ - } - else if (ch =3D=3D '%') { - /* queue it verbatim */ - continue; - } - else { - /* modifiers or final 0 */ - if (ch =3D=3D 'l') { - /* long format prefix, maintain the escape */ - lpref++; - } else if (ch =3D=3D 'j') { - lpref =3D 2; + } else { + if (ch !=3D '%') { + /* Invalid format: back up to output the format characters */ + fmt =3D outstr + 1; + /* and output a '%' now. */ } - escape =3D 1; - goto do_escape; + /* %% is documented as a 'conversion specifier'. + * Any flags, precision or length modifier are ignored. + */ + width =3D 0; + outstr =3D "%"; } len =3D strlen(outstr); - goto flush_str; } =20 - /* not an escape sequence */ - if (ch =3D=3D 0 || ch =3D=3D '%') { - /* flush pending data on escape or end */ - escape =3D 1; - lpref =3D 0; - outstr =3D fmt; - len =3D ofs - 1; - flush_str: - width -=3D len; - while (width > 0) { - /* Output pad in 16 byte blocks with the small block first. */ - int pad_len =3D ((width - 1) & 15) + 1; - width -=3D pad_len; - written +=3D pad_len; - if (cb(state, " ", pad_len) !=3D 0) - return -1; - } - if (cb(state, outstr, len) !=3D 0) - return -1; + written +=3D len; =20 - written +=3D len; - do_escape: - if (ch =3D=3D 0) - break; - fmt +=3D ofs; - ofs =3D 0; - continue; + width -=3D len; + while (width > 0) { + /* Output pad in 16 byte blocks with the small block first. */ + int pad_len =3D ((width - 1) & 15) + 1; + width -=3D pad_len; + written +=3D pad_len; + if (cb(state, " ", pad_len) !=3D 0) + return -1; } - - /* literal char, just queue it */ + if (cb(state, outstr, len) !=3D 0) + return -1; } =20 /* Request a final '\0' be added to the snprintf() output. --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 161AF396D2C for ; Mon, 2 Mar 2026 10:18:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446742; cv=none; b=p7IMdCkpWrNCETFnJKL/Wzl0vd/jlehw7iypxhJKS5pqTANTP8EZmx71IWHp4z809TrXjeogUyxv2cgdEjRNcZZJdGPJHD2J0ADzg/Y9eCAyK41yri2WJY5r2crl2Zymx56kzp8huHU3qWk7zpdnk3wT0FdDE6r6A7nFbE4SCJw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446742; c=relaxed/simple; bh=A+FpVaz84CooP3MBMg61Dqa8C3RslGxdPeyRIFOUPI4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=kV5FJhhbySQ/DNnlXAPiIbQyQ099N2uhIfYDvObnA/V7G1yVhffg1m2cdl0Wid+gDurtDMliyO9goK0suT61Y1/XCDlXUcQmjFQ7kDxGssk5qa+QY5TN/4pHvnuVL3gfXosy5vyBQTpbvUHNjac0WbwJo0cxpyfUZ/5h3L4we0o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=CYHFZh9Q; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="CYHFZh9Q" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MW-003BcX-CP; Mon, 02 Mar 2026 11:18:52 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=zFxnpaQvNzT51FlHrNI+KR5pzDWELCZtOj1K3JgcKBg=; b=CYHFZh9QIsptG4aigLLflWZ13p umR3BRIhPNDR0Ma4Ennd4tj6YrnzaohiG42z1Fdm7b/FsX7aeeh9HZgGzQ7jzoGkmBY2X9nyNDl7p xBM7VsgJ3Ap7LM45udW92JRNtDJhFj+iSNwjR7KZ3WQiOno8eix9xrW5qcSSUd1mojzm481guoptN sLFW9QguLZ9hzIISldFDhHIMBEnZha+y17UTQBHmGnytx4Wcu/P6PvFQ0FyJw9Zts0oBdjnvI95+0 vN02xMZqgHnBUimypwYGBv3VumeU+egUeTZahCKJ9lxztaHUTjp8HbeVyKvW12Iw13RY9en6tHrVm 3cjzbqew==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MW-0002yj-3F; Mon, 02 Mar 2026 11:18:52 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MB-006y7o-P5; Mon, 02 Mar 2026 11:18:31 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 13/23] tools/nolibc/printf: Use goto and reduce indentation Date: Mon, 2 Mar 2026 10:18:05 +0000 Message-Id: <20260302101815.3043-14-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Upcoming changes will need to use goto to jump to the code that outputs characters. Use 'goto do_output' to output a known number of characters. Use 'goto do_strlen_output' to output a '\0' terminated string. Removes a level of indentation from the format processing code. Signed-off-by: David Laight Acked-by: Willy Tarreau --- For v4: - Output a single '%' from the format string. New patch for v3. Makes the final code look better and there is less to change if done early. tools/include/nolibc/stdio.h | 170 +++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 78 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index e0b7ff537b14..13fe6c4d7f58 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -329,103 +329,117 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *st= ate, const char *fmt, va_list fmt++; /* Output characters from the format string. */ len =3D fmt - outstr; - } else { - /* we're in a format sequence */ + goto do_output; + } =20 - ch =3D *fmt++; + /* we're in a format sequence */ =20 - /* width */ - while (ch >=3D '0' && ch <=3D '9') { - width *=3D 10; - width +=3D ch - '0'; + ch =3D *fmt++; =20 - ch =3D *fmt++; - } + /* width */ + while (ch >=3D '0' && ch <=3D '9') { + width *=3D 10; + width +=3D ch - '0'; + + ch =3D *fmt++; + } =20 - /* Length modifiers */ + /* Length modifiers */ + if (ch =3D=3D 'l') { + lpref =3D 1; + ch =3D *fmt++; if (ch =3D=3D 'l') { - lpref =3D 1; - ch =3D *fmt++; - if (ch =3D=3D 'l') { - lpref =3D 2; - ch =3D *fmt++; - } - } else if (ch =3D=3D 'j') { - /* intmax_t is long long */ lpref =3D 2; ch =3D *fmt++; - } else { - lpref =3D 0; } + } else if (ch =3D=3D 'j') { + /* intmax_t is long long */ + lpref =3D 2; + ch =3D *fmt++; + } else { + lpref =3D 0; + } =20 - if (ch =3D=3D 'c' || ch =3D=3D 'd' || ch =3D=3D 'u' || ch =3D=3D 'x' ||= ch =3D=3D 'p') { - char *out =3D outbuf; + if (ch =3D=3D 'c' || ch =3D=3D 'd' || ch =3D=3D 'u' || ch =3D=3D 'x' || = ch =3D=3D 'p') { + char *out =3D outbuf; =20 - if (ch =3D=3D 'p') + if (ch =3D=3D 'p') + v =3D va_arg(args, unsigned long); + else if (lpref) { + if (lpref > 1) + v =3D va_arg(args, unsigned long long); + else v =3D va_arg(args, unsigned long); - else if (lpref) { - if (lpref > 1) - v =3D va_arg(args, unsigned long long); - else - v =3D va_arg(args, unsigned long); - } else - v =3D va_arg(args, unsigned int); - - if (ch =3D=3D 'd') { - /* sign-extend the value */ - if (lpref =3D=3D 0) - v =3D (long long)(int)v; - else if (lpref =3D=3D 1) - v =3D (long long)(long)v; - } + } else + v =3D va_arg(args, unsigned int); =20 - switch (ch) { - case 'c': - out[0] =3D v; - out[1] =3D 0; - break; - case 'd': - i64toa_r(v, out); - break; - case 'u': - u64toa_r(v, out); - break; - case 'p': - *(out++) =3D '0'; - *(out++) =3D 'x'; - __nolibc_fallthrough; - default: /* 'x' and 'p' above */ - u64toh_r(v, out); - break; - } - outstr =3D outbuf; + if (ch =3D=3D 'd') { + /* sign-extend the value */ + if (lpref =3D=3D 0) + v =3D (long long)(int)v; + else if (lpref =3D=3D 1) + v =3D (long long)(long)v; } - else if (ch =3D=3D 's') { - outstr =3D va_arg(args, char *); - if (!outstr) - outstr=3D"(null)"; + + switch (ch) { + case 'c': + out[0] =3D v; + out[1] =3D 0; + break; + case 'd': + i64toa_r(v, out); + break; + case 'u': + u64toa_r(v, out); + break; + case 'p': + *(out++) =3D '0'; + *(out++) =3D 'x'; + __nolibc_fallthrough; + default: /* 'x' and 'p' above */ + u64toh_r(v, out); + break; } - else if (ch =3D=3D 'm') { + outstr =3D outbuf; + goto do_strlen_output; + } + + if (ch =3D=3D 's') { + outstr =3D va_arg(args, char *); + if (!outstr) + outstr=3D"(null)"; + goto do_strlen_output; + } + + if (ch =3D=3D 'm') { #ifdef NOLIBC_IGNORE_ERRNO - outstr =3D "unknown error"; + outstr =3D "unknown error"; #else - outstr =3D strerror(errno); + outstr =3D strerror(errno); #endif /* NOLIBC_IGNORE_ERRNO */ - } else { - if (ch !=3D '%') { - /* Invalid format: back up to output the format characters */ - fmt =3D outstr + 1; - /* and output a '%' now. */ - } - /* %% is documented as a 'conversion specifier'. - * Any flags, precision or length modifier are ignored. - */ - width =3D 0; - outstr =3D "%"; - } - len =3D strlen(outstr); + goto do_strlen_output; } =20 + if (ch !=3D '%') { + /* Invalid format: back up to output the format characters */ + fmt =3D outstr + 1; + /* and output a '%' now. */ + } + /* %% is documented as a 'conversion specifier'. + * Any flags, precision or length modifier are ignored. + */ + len =3D 1; + width =3D 0; + outstr =3D fmt - 1; + goto do_output; + +do_strlen_output: + /* Open coded strlen() (slightly smaller). */ + for (len =3D 0;; len++) + if (!outstr[len]) + break; + +do_output: written +=3D len; =20 width -=3D len; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 370693A0E92 for ; Mon, 2 Mar 2026 10:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446737; cv=none; b=sTbfr3tyXskyupzXRHI4gQElaZx/NLylTzKEhhu2/fnX54QXWtLN2Zmjz5vf6ids/QCCQ9CpkTpm+x2pLQjPymbxPAutIQGxoefdNEEW6QOlqfeo7ModuaOktpVouaUhIIhRS5TgiF2DfLRpHc5necP8726qOLVZiP7VSuG6EOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446737; c=relaxed/simple; bh=YW6jr0+Uf7Wz8ERaW9encz8uoof1+x6V6bHR3n63By8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AiwQz6qhOVdsO5UEnodbOplbL32E3EGyXZvEuSXA7EMNNFryvppLLm8n9FIWqLyq3Tp0+ThEBW2uS0VgenO9M45s0O5rYbm/aHuJ44uvQdA8wvLD4EcVSeJmyuiW+W/9lxN8yzO6Cykl0Gz3yb9d9o4uUBwXGYx1W1zGYwUhrmo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=r+IxHM0a; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="r+IxHM0a" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MV-003BcI-Jg; Mon, 02 Mar 2026 11:18:51 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=bKwDQocMnxpzCei2/oJM3JKi1gcLDIcuAvHDKMr7yBc=; b=r+IxHM0aBn6UNuxi4GAL7xBxs9 JKqQJB4yFgpsPGXU/YQ7Gy+dqhW1tAnLxmiPvqi7/NGTUXOOl/SDN7RCoJHG8Mc2Cby0aXpSHnNk1 SKCumRJli3zPQ2qHfesx423U+yAtgCZcyaEL8xCLqg0xn66iZFzOT+Fb91EFuFWYVZv34eebDn4ha DVpxQ6ZpC1ihx9JikH13ILXWGXXaM+dZGcaEQKidJM8/ht3lb2NRuQD8GiUHnasU1WvEovH8v3ZRq idRmQAJcn3t86h/Xd/dJZ59ozH35GUgqQyqJg7zXL19pvfRCHyJVzTkX6uibYkrR25HWJgzp1Fapl NoH/6kJQ==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MV-0002yX-9j; Mon, 02 Mar 2026 11:18:51 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MC-006y7o-1u; Mon, 02 Mar 2026 11:18:32 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH 14/23] tools/nolibc/printf: Use bit-masks to hold requested flag, length and conversion chars Date: Mon, 2 Mar 2026 10:18:06 +0000 Message-Id: <20260302101815.3043-15-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Use flags bits (1u << (ch & 31)) for the flags, length modifiers, and conversion specifiers. This makes it easy to test for multiple values at once. Detect the conversion flags " #+-0" although they are currently all ignored. Unconditionally generate the signed values (for %d) to remove a second set of checks for the size. Separate out the formatting of single characters from numbers. Output the sign for negative values then negate and treat as unsigned. Acked-by: Willy Tarreau Signed-off-by: David Laight --- Changes for v4: - Move the support for length modifiers t, j, q, L and formats i and X to the next patch. - Convert ll to j (not q) since q isn't added until the next patch. Changes for v3: - Patch 6 in v2. - Move all the variable definitions to the top of the function. The loop body is a bit long to hide definitions at its top. - Avoid -Wtype-limits validating format characters. - Include changes to the selftests. Changes for v2: - Use #defines to make the code a lot more readable. - Include the changes from the old patch 10 that used masks for the conversion specifiers. - Detect all the valid flag characters even though they are not implemented. - Support for left justifying field is moved to patch 7. tools/include/nolibc/stdio.h | 157 ++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 13fe6c4d7f58..ea1288d87eea 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -291,10 +291,14 @@ int fseek(FILE *stream, long offset, int whence) } =20 =20 -/* minimal printf(). It supports the following formats: - * - %[l*]{d,u,c,x,p} - * - %s - * - unknown modifiers are ignored. +/* printf(). Supports the following integer and string formats. + * - %[#-+ 0][width][{l,ll,j}]{c,d,u,x,p,s,m,%} + * - %% generates a single % + * - %m outputs strerror(errno). + * - The modifiers [#-+ 0] are currently ignored. + * - No support for precision or variable widths. + * - No support for floating point or wide characters. + * - Invalid formats are copied to the output buffer. * * Called by vfprintf() and snprintf() to do the actual formatting. * The callers provide a callback function to save the formatted data. @@ -305,15 +309,43 @@ int fseek(FILE *stream, long offset, int whence) * - with (NULL, 0) at the end of the __nolibc_printf. * If the callback returns non-zero __nolibc_printf() immediately returns = -1. */ + typedef int (*__nolibc_printf_cb)(void *state, const char *buf, size_t siz= e); =20 +/* This code uses 'flag' variables that are indexed by the low 6 bits + * of characters to optimise checks for multiple characters. + * + * _NOLIBC_PF_FLAGS_CONTAIN(flags, 'a', 'b'. ...) + * returns non-zero if the bit for any of the specified characters is set. + * + * _NOLIBC_PF_CHAR_IS_ONE_OF(ch, 'a', 'b'. ...) + * returns the flag bit for ch if it is one of the specified characters. + * All the characters must be in the same 32 character block (non-alphabet= ic, + * upper case, or lower case) of the ASCII character set. + */ +#define _NOLIBC_PF_FLAG(ch) (1u << ((ch) & 0x1f)) +#define _NOLIBC_PF_FLAG_NZ(ch) ((ch) ? _NOLIBC_PF_FLAG(ch) : 0) +#define _NOLIBC_PF_FLAG8(cmp_1, cmp_2, cmp_3, cmp_4, cmp_5, cmp_6, cmp_7, = cmp_8, ...) \ + (_NOLIBC_PF_FLAG_NZ(cmp_1) | _NOLIBC_PF_FLAG_NZ(cmp_2) | \ + _NOLIBC_PF_FLAG_NZ(cmp_3) | _NOLIBC_PF_FLAG_NZ(cmp_4) | \ + _NOLIBC_PF_FLAG_NZ(cmp_5) | _NOLIBC_PF_FLAG_NZ(cmp_6) | \ + _NOLIBC_PF_FLAG_NZ(cmp_7) | _NOLIBC_PF_FLAG_NZ(cmp_8)) +#define _NOLIBC_PF_FLAGS_CONTAIN(flags, ...) \ + ((flags) & _NOLIBC_PF_FLAG8(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0)) +#define _NOLIBC_PF_CHAR_IS_ONE_OF(ch, cmp_1, ...) \ + ((unsigned int)(ch) - (cmp_1 & 0xe0) > 0x1f ? 0 : \ + _NOLIBC_PF_FLAGS_CONTAIN(_NOLIBC_PF_FLAG(ch), cmp_1, __VA_ARGS__)) + static __attribute__((unused, format(printf, 3, 0))) int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, v= a_list args) { - char lpref, ch; + char ch; unsigned long long v; + long long signed_v; int written, width, len; + unsigned int flags, ch_flag; char outbuf[21]; + char *out; const char *outstr; =20 written =3D 0; @@ -324,6 +356,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list break; =20 width =3D 0; + flags =3D 0; if (ch !=3D '%') { while (*fmt && *fmt !=3D '%') fmt++; @@ -334,7 +367,14 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list =20 /* we're in a format sequence */ =20 - ch =3D *fmt++; + /* Conversion flag characters */ + while (1) { + ch =3D *fmt++; + ch_flag =3D _NOLIBC_PF_CHAR_IS_ONE_OF(ch, ' ', '#', '+', '-', '0'); + if (!ch_flag) + break; + flags |=3D ch_flag; + } =20 /* width */ while (ch >=3D '0' && ch <=3D '9') { @@ -344,62 +384,78 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list ch =3D *fmt++; } =20 - /* Length modifiers */ - if (ch =3D=3D 'l') { - lpref =3D 1; - ch =3D *fmt++; - if (ch =3D=3D 'l') { - lpref =3D 2; - ch =3D *fmt++; + /* Length modifier. + * They miss the conversion flags characters " #+-0" so can go into flag= s. + * Change ll to j (both always 64bits). + */ + ch_flag =3D _NOLIBC_PF_CHAR_IS_ONE_OF(ch, 'l', 'j'); + if (ch_flag !=3D 0) { + if (ch =3D=3D 'l' && fmt[0] =3D=3D 'l') { + fmt++; + ch_flag =3D _NOLIBC_PF_FLAG('j'); } - } else if (ch =3D=3D 'j') { - /* intmax_t is long long */ - lpref =3D 2; + flags |=3D ch_flag; ch =3D *fmt++; - } else { - lpref =3D 0; } =20 - if (ch =3D=3D 'c' || ch =3D=3D 'd' || ch =3D=3D 'u' || ch =3D=3D 'x' || = ch =3D=3D 'p') { - char *out =3D outbuf; + /* Conversion specifiers. */ =20 - if (ch =3D=3D 'p') + /* Numeric and pointer conversion specifiers. + * + * Use an explicit bound check (rather than _NOLIBC_PF_CHAR_IS_ONE_OF()) + * so ch_flag can be used later. + */ + ch_flag =3D _NOLIBC_PF_FLAG(ch); + if ((ch >=3D 'a' && ch <=3D 'z') && + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'u', 'x', 'p')) { + /* 'long' is needed for pointer conversions and ltz lengths. + * A single test can be used provided 'p' (the same bit as '0') + * is masked from flags. + */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag | (flags & ~_NOLIBC_PF_FLAG('p')), + 'p', 'l')) { v =3D va_arg(args, unsigned long); - else if (lpref) { - if (lpref > 1) - v =3D va_arg(args, unsigned long long); - else - v =3D va_arg(args, unsigned long); - } else + signed_v =3D (long)v; + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j')) { + v =3D va_arg(args, unsigned long long); + signed_v =3D v; + } else { v =3D va_arg(args, unsigned int); + signed_v =3D (int)v; + } =20 - if (ch =3D=3D 'd') { - /* sign-extend the value */ - if (lpref =3D=3D 0) - v =3D (long long)(int)v; - else if (lpref =3D=3D 1) - v =3D (long long)(long)v; + if (ch =3D=3D 'c') { + /* "%c" - single character. */ + outbuf[0] =3D v; + len =3D 1; + outstr =3D outbuf; + goto do_output; } =20 - switch (ch) { - case 'c': - out[0] =3D v; - out[1] =3D 0; - break; - case 'd': - i64toa_r(v, out); - break; - case 'u': + out =3D outbuf; + + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd')) { + /* "%d" and "%i" - signed decimal numbers. */ + if (signed_v < 0) { + *out++ =3D '-'; + v =3D -(signed_v + 1); + v++; + } + } + + /* Convert the number to ascii in the required base. */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'u')) { + /* Base 10 */ u64toa_r(v, out); - break; - case 'p': - *(out++) =3D '0'; - *(out++) =3D 'x'; - __nolibc_fallthrough; - default: /* 'x' and 'p' above */ + } else { + /* Base 16 */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p')) { + *(out++) =3D '0'; + *(out++) =3D 'x'; + } u64toh_r(v, out); - break; } + outstr =3D outbuf; goto do_strlen_output; } @@ -442,6 +498,9 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list do_output: written +=3D len; =20 + /* Stop gcc back-merging this code into one of the conditionals above. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + width -=3D len; while (width > 0) { /* Output pad in 16 byte blocks with the small block first. */ --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA968396B85 for ; Mon, 2 Mar 2026 10:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446741; cv=none; b=uvi0FzaRHgRbY9FZIJh+Ep3E6GXuZzvCJBSDGA9zT7CPXailjoyz44NjxbwQOu8A3T3EVinbiKDtzTN2QcsBelc8+/RieFlAVeFrOkViSizM2ZNW8yBnWOyV9TunOyHNp8k3BePuOwzZekwGmTjFxkhPCkzTGuG8fhpkd+C/Fi0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446741; c=relaxed/simple; bh=QZcNFuzhE6cuFx0DsYKprPH5ZBYEDDfrMhyPdeZRuXY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PZnQJuW/4TCwxLYu3j/rY0QAV8W0MrZtzYwEKRvreN0iECeTyNjenq4DaAiqNmk1+FzF1E1FUJcTarw2r8ynA3H5Wg34t046ZvK/FIm0Gp3vrbu6c3Rtk4soW0l3NbbcpExyzlS7u/HAmwnjFYWcvg4eWO9I+Zbaqv1tWHLtWPM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=LkiAu21s; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="LkiAu21s" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MU-003Bbf-QO; Mon, 02 Mar 2026 11:18:50 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=TwHJ2KlZpg0cbG3t4PlbVej/YSrEwJyR73TCnhv4BqA=; b=LkiAu21sxWPrhbUyRpa57dH1VB AxpmjH90ByqP/dAZN+Lf+mqqXjUnfcoVmUDY7W8ss7/hZKNY/OFgMcmJ9EyNAiWULyaX5Cs9FJjSo rN9D/U+ogJ4OdUWmVsfqUn7aUSQhXbJjFJN01lt1a2zd/EiAZ7WmM2AtZaAVJO3mlXbUNg/UIugO2 UcTRyhpFYtP4gsqGfjMjuZ7LQyr/pCo1dD9k6f/7o3ncKwMLVvBUKrqVEld4Fp3OxxBxTfDAvMZlV 5bEepyDu0sQokYA4JeLTl3As4gRbCj1pL07EAvEVFO0+VZPCbVcTPIaFv4kk0qMt3bSJ0CHhKTxbV mMwzpNVw==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MU-00055i-GJ; Mon, 02 Mar 2026 11:18:50 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MC-006y7o-Cr; Mon, 02 Mar 2026 11:18:32 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 15/23] tools/nolibc/printf: Add support for length modifiers tzqL and formats iX Date: Mon, 2 Mar 2026 10:18:07 +0000 Message-Id: <20260302101815.3043-16-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Length modifiers t (ptrdiff_t) and z (size_t) are aliases for l (long), q and L are 64bit the same as j (intmax). Format i is an alias for d and X similar to x but uppper case. Supporting them is mostly just adding the relavant bit to the bit pattern used for maching characters. Although %X is detected the output will be lower case. Change/add tests to use conversions i and X, and length modifiers L and ll. Use the correct minimum value for "%Li". Acked-by: Willy Tarreau Signed-off-by: David Laight --- v4: Split from the previous patch. tools/include/nolibc/stdio.h | 27 ++++++++++++-------- tools/testing/selftests/nolibc/nolibc-test.c | 14 +++++++--- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index ea1288d87eea..4c7626dbd63f 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -291,10 +291,11 @@ int fseek(FILE *stream, long offset, int whence) } =20 =20 -/* printf(). Supports the following integer and string formats. - * - %[#-+ 0][width][{l,ll,j}]{c,d,u,x,p,s,m,%} +/* printf(). Supports most of the normal integer and string formats. + * - %[#-+ 0][width][{l,t,z,ll,L,j,q}]{c,d,i,u,x,X,p,s,m,%} * - %% generates a single % * - %m outputs strerror(errno). + * - %X outputs a..f the same as %x. * - The modifiers [#-+ 0] are currently ignored. * - No support for precision or variable widths. * - No support for floating point or wide characters. @@ -386,9 +387,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list =20 /* Length modifier. * They miss the conversion flags characters " #+-0" so can go into flag= s. - * Change ll to j (both always 64bits). + * Change both L and ll to j (all alwys 64bit). */ - ch_flag =3D _NOLIBC_PF_CHAR_IS_ONE_OF(ch, 'l', 'j'); + if (ch =3D=3D 'L') + ch =3D 'j'; + ch_flag =3D _NOLIBC_PF_CHAR_IS_ONE_OF(ch, 'l', 't', 'z', 'j', 'q'); if (ch_flag !=3D 0) { if (ch =3D=3D 'l' && fmt[0] =3D=3D 'l') { fmt++; @@ -403,20 +406,22 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list /* Numeric and pointer conversion specifiers. * * Use an explicit bound check (rather than _NOLIBC_PF_CHAR_IS_ONE_OF()) - * so ch_flag can be used later. + * so that 'X' can be allowed through. + * 'X' gets treated and 'x' because _NOLIBC_PF_FLAG() returns the same + * value for both. */ ch_flag =3D _NOLIBC_PF_FLAG(ch); - if ((ch >=3D 'a' && ch <=3D 'z') && - _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'u', 'x', 'p')) { + if (((ch >=3D 'a' && ch <=3D 'z') || ch =3D=3D 'X') && + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p')) { /* 'long' is needed for pointer conversions and ltz lengths. * A single test can be used provided 'p' (the same bit as '0') * is masked from flags. */ if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag | (flags & ~_NOLIBC_PF_FLAG('p')), - 'p', 'l')) { + 'p', 'l', 't', 'z')) { v =3D va_arg(args, unsigned long); signed_v =3D (long)v; - } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j')) { + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j', 'q')) { v =3D va_arg(args, unsigned long long); signed_v =3D v; } else { @@ -434,7 +439,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list =20 out =3D outbuf; =20 - if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd')) { + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) { /* "%d" and "%i" - signed decimal numbers. */ if (signed_v < 0) { *out++ =3D '-'; @@ -444,7 +449,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list } =20 /* Convert the number to ascii in the required base. */ - if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'u')) { + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) { /* Base 10 */ u64toa_r(v, out); } else { diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 638f18fc5123..a140c54e4d72 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1826,11 +1826,19 @@ static int run_printf(int min, int max) CASE_TEST(number); EXPECT_VFPRINTF(1, "1234", "%d", 1234); break; CASE_TEST(negnumber); EXPECT_VFPRINTF(1, "-1234", "%d", -1234); break; CASE_TEST(unsigned); EXPECT_VFPRINTF(1, "12345", "%u", 12345); break; + CASE_TEST(signed_max); EXPECT_VFPRINTF(1, "2147483647", "%i", ~0u >> 1= ); break; + CASE_TEST(signed_min); EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >>= 1) + 1); break; + CASE_TEST(unsigned_max); EXPECT_VFPRINTF(1, "4294967295", "%u", ~0u); br= eak; CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; - CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break; + CASE_TEST(hex_nolibc); EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", = 0xf, 0xd); break; + CASE_TEST(hex_libc); EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|",= 0xf, 0xd); break; CASE_TEST(pointer); EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); = break; - CASE_TEST(uintmax_t); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju= ", 0xffffffffffffffffULL); break; - CASE_TEST(intmax_t); EXPECT_VFPRINTF(1, "-9223372036854775807", "%jd= ", 0x8000000000000001LL); break; + CASE_TEST(percent); EXPECT_VFPRINTF(1, "a%d42%69%", "a%%d%d%%%d%%",= 42, 69); break; + CASE_TEST(perc_qual); EXPECT_VFPRINTF(1, "a%d2", "a%-14l%d%d", 2); br= eak; + CASE_TEST(invalid); EXPECT_VFPRINTF(1, "a%12yx3%y42%P", "a%12yx%d%y= %d%P", 3, 42); break; + CASE_TEST(intmax_max); EXPECT_VFPRINTF(1, "9223372036854775807", "%lld= ", ~0ULL >> 1); break; + CASE_TEST(intmax_min); EXPECT_VFPRINTF(1, "-9223372036854775808", "%Li= ", (~0ULL >> 1) + 1); break; + CASE_TEST(uintmax_max); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju= ", ~0ULL); break; CASE_TEST(truncation); EXPECT_VFPRINTF(1, "0123456789012345678901234",= "%s", "0123456789012345678901234"); break; CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); = break; CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); br= eak; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36F8839A81C for ; Mon, 2 Mar 2026 10:18:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446735; cv=none; b=G5fcusa4peGxNdOI73aF0IPdoammXlu+kVTZZnu6bJa9Uvyo1on4bxEBNaEjmSHshAOt9Seps5Y7AhxYKwpoMUDq12dsyD3GNkhcirdKAO13uRzKzviXCOprIl8X+icMgtwMCsdqwbuXo0qV6cATZyHJyos/uHBNPDOEV15+SzA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446735; c=relaxed/simple; bh=AzI5Ae/Nc2f7GDhwHjvhiTKxWEZ8clztvctCM8lf4tI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dw9H4xrAJxXVuGos/24dHzQ3C712XQM0qp8HgY0PsxvcnsSs3zCxB7iHw2qoKeEWnbwEQ0srOCuaUFJPj5Vnxlv7hfUg914iSaupG56GFz4VaRdNil1Qf7Ozh7xUk3SB32gPaBMncl5qmTQRAmwRIAFQUaN/BqMdVlRIKoSTSYc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=lTAGTmZC; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="lTAGTmZC" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MV-003Bbo-8A; Mon, 02 Mar 2026 11:18:51 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=2BKNgWMOvsEhkPs71HgPoPRLvfN6gLA0Noe+4f2IkL0=; b=lTAGTmZCWLzv+W4bYHX/4obzUF CBdXXCQ9nUTzuupZHZO1fP1DJpUTT9IkePlsFOOJQeMzldIMqxlQRdk1+AW1/iOhp3Ku5t0Nl1FaI 9RYDwrRdSByMn3XEcg4idinxUboi+CUDsO5krrhHFqdJ8ZkZOhKsL5SNJJ2xJU/fIoMyHqFjuia6D 3apT+O3D57q8MQYScuo6YQ9O+6sg8SyyfzSMUKdShbPP5aj2Se/BTEkiTzXVsT28WsAW2+/kXKUt1 gkfidNzEDNIzS0CNNAqnRLWXW9L5X/23FCsiKvxBPrxsBtXlB7HTzae0HkPX/LSzCJ0OZJirjPgIb q9c30jpw==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MU-0002yR-Sw; Mon, 02 Mar 2026 11:18:51 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MC-006y7o-LO; Mon, 02 Mar 2026 11:18:32 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 16/23] tools/nolibc/printf: Handle "%s" with the numeric formats Date: Mon, 2 Mar 2026 10:18:08 +0000 Message-Id: <20260302101815.3043-17-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Avoids the extra va_arg() call with is non-trivial on a lot of modern ABI. Signed-off-by: David Laight Acked-by: Willy Tarreau --- Unchanched for v4. Changes for v3: - Moved to its own patch (part of patch 7 in v2).. - Fix 32bit compile. tools/include/nolibc/stdio.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 4c7626dbd63f..484432ca87d5 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -412,13 +412,13 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list */ ch_flag =3D _NOLIBC_PF_FLAG(ch); if (((ch >=3D 'a' && ch <=3D 'z') || ch =3D=3D 'X') && - _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p')) { - /* 'long' is needed for pointer conversions and ltz lengths. + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p', 's')= ) { + /* 'long' is needed for pointer/string conversions and ltz lengths. * A single test can be used provided 'p' (the same bit as '0') * is masked from flags. */ if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag | (flags & ~_NOLIBC_PF_FLAG('p')), - 'p', 'l', 't', 'z')) { + 'p', 's', 'l', 't', 'z')) { v =3D va_arg(args, unsigned long); signed_v =3D (long)v; } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j', 'q')) { @@ -437,6 +437,15 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list goto do_output; } =20 + if (ch =3D=3D 's') { + /* "%s" - character string. */ + outstr =3D (const char *)(uintptr_t)v; + if (!outstr) { + outstr =3D "(null)"; + } + goto do_strlen_output; + } + out =3D outbuf; =20 if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) { @@ -465,13 +474,6 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list goto do_strlen_output; } =20 - if (ch =3D=3D 's') { - outstr =3D va_arg(args, char *); - if (!outstr) - outstr=3D"(null)"; - goto do_strlen_output; - } - if (ch =3D=3D 'm') { #ifdef NOLIBC_IGNORE_ERRNO outstr =3D "unknown error"; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 30E4A399036 for ; Mon, 2 Mar 2026 10:18:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446734; cv=none; b=nAsp5URs2XbOXaN4g0JRJO5AHfkHKTJRk2HH96YTKs5L0FuWASfPYhgRKTNrO+jzwXwytCVU3VWUTBfFIH30dktpZyk4lmZEIACYI9y3bZe78k+svt++4pvby9WijzNCghJr2Zcz5FGaA01Q23flJHzBjGF5Sdeh9XeX5RSBfSA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446734; c=relaxed/simple; bh=rT1izaWZp644rPOJMRiRSLG3lvtvISAe0h4eBE3L6ec=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Y5nFQNp1AyFK61zsn5knIWXdwnMXCHnpe5+vfWlfnvfDWDRCgk/UQjn5bbRuo4aTFqslrBWY4wtnHoD2mgnBmVH8c/WtsNNs0jcPR54qwuS77piAv7iQfJWenbJXj8R50Q3bWFA7sPFiFAIP4gCo20DukKt/vctGyMG/G8L2dFk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=EZfoiGos; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="EZfoiGos" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MU-003Bac-Da; Mon, 02 Mar 2026 11:18:50 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=+K22pr+zYjs+WNaEw7LiybMWACKGA99hlKFAYu09hVc=; b=EZfoiGos9IEiY9q2ROZd0W9Q6f 13QusR1v1FrVsR8OmvX/IgrVG6mz5NEDvL8F0HaUMAXMWwNVpio8G/nTQPRk5BtZkotp/ZzcoPI97 hd3wZ25edbMXaVNDi3jWsMExTulM+wpHz9zLPf+blZHdIFXMm947hYX+yFU0E4XMknTWPYQP+5+Re JdPmuS0RPFercHf7yId46axSA6gtpmzJM6ZZxGZZ+W7V0++wJOSeR3I0ic1wNJCJX3edGP7Lbip4E 30djdFqL+Pt0rh5q9JIvPjYapgFxHnpX5+UnwDo0bqGpXzPs9vY7d6Dzxz4MDEdlzG5nimOtxaInb bcnD1XOA==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MU-00055c-3u; Mon, 02 Mar 2026 11:18:50 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MC-006y7o-TY; Mon, 02 Mar 2026 11:18:32 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH 17/23] tools/nolibc/printf: Prepend sign to converted number Date: Mon, 2 Mar 2026 10:18:09 +0000 Message-Id: <20260302101815.3043-18-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Instead of appending the converted number to the sign, convert first and then prepend the sign (or "0x"). Use the length returned by u64toh_r() instead of calling strlen(). Needed so that zero padding can be inserted between the sign and digits in an upcoming patch. Signed-off-by: David Laight Acked-by: Willy Tarreau --- Changes for v4: - Split from the patch that supported modifiers " +#". tools/include/nolibc/stdio.h | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 484432ca87d5..fb310b7d023f 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -345,9 +345,10 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list long long signed_v; int written, width, len; unsigned int flags, ch_flag; - char outbuf[21]; + char outbuf[2 + 22 + 1]; char *out; const char *outstr; + unsigned int sign_prefix; =20 written =3D 0; while (1) { @@ -446,32 +447,47 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list goto do_strlen_output; } =20 - out =3D outbuf; + /* The 'sign_prefix' can be zero, one or two ("0x") characters. */ + sign_prefix =3D 0; =20 if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) { /* "%d" and "%i" - signed decimal numbers. */ if (signed_v < 0) { - *out++ =3D '-'; + sign_prefix =3D '-'; v =3D -(signed_v + 1); v++; } } =20 + /* The value is converted offset into the buffer so that + * the sign/prefix can be added in front. + * The longest digit string is 22 + 1 for octal conversions, the + * space is reserved even though octal isn't currently supported. + */ + out =3D outbuf + 2; + /* Convert the number to ascii in the required base. */ if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) { /* Base 10 */ - u64toa_r(v, out); + len =3D u64toa_r(v, out); } else { /* Base 16 */ if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p')) { - *(out++) =3D '0'; - *(out++) =3D 'x'; + /* "%p" needs "0x" prepending. */ + sign_prefix =3D 'x' | '0' << 8; } - u64toh_r(v, out); + len =3D u64toh_r(v, out); } =20 - outstr =3D outbuf; - goto do_strlen_output; + /* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */ + for (; sign_prefix; sign_prefix >>=3D 8) { + /* Force gcc to increment len inside the loop. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + len++; + *--out =3D sign_prefix; + } + outstr =3D out; + goto do_output; } =20 if (ch =3D=3D 'm') { --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3E8B39C636 for ; Mon, 2 Mar 2026 10:18:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446743; cv=none; b=JOOmmqzNy8v/H8TKnaM0nvz8N/XV0LeNnRhgKLN/qcKzqbF+ftOqIAbkOpg0+wJt56iSD0N30hps/36xmgBBPcFbbn63VndKpKNvD4jJSu32y1mz15sO2+8VluQYpMvk0fGu3RQ7qkSYOzXAtnprcnzw2lZJqwdSrELgxdV+A/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446743; c=relaxed/simple; bh=o/E44RG64+ZwVcYj7B9fCVBrrBAckLj412Timlk1+ks=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NYq4axbSrZ/ljcYl/YUfy+JoEKCTkygruZjQRw7OdKvL1FTjmAUfFqQju71Nib4Y+KAv1tGHaCzHJloX8ieCyRbnuHDb8Fnu7T7AA4JZhq88GvaoNRq0y2o6g0G0OhGw7Tv/b/3M2VoH/kN81Kb3Zbig2Bh5TV4e9MAI/FryPSE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=QCizkjLk; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="QCizkjLk" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MZ-003Bdf-IW; Mon, 02 Mar 2026 11:18:55 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=nmKYQ75Xj4T+FTlGUs6avSWf8c41BEjTyS/XIEM2MAw=; b=QCizkjLk8XA7kUAK+KTR/VpP8R g4JqAA5IM3ug8L1xwPYjvXGip9+CK3r5O9Le6QboeVOpogBA+LvY4bW2kzvvmsDHSeVdYchztlEGw TEMlCe3wVVNaIMKDgTsSAhMMJNTnF/xqZsuFPMLbZMu9C5gcQLKZfkvy5O+9OenONF9qD7zSK2JSC VuhhtxhDPEOk071f2YYeYyKti4wRgO2mHFVbGaDDgM9ecwUnaVRPL40Q1vB3OKjiyBQFyLy88Lf7f loG99mbRcdpid6LJRZrPIlLw5F/CC7DNNVVqbAv3tPD9yx8gDJqrIetn/HYL9LabLQmR1TpFRNQPF IoQIokrA==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MZ-0002z7-7c; Mon, 02 Mar 2026 11:18:55 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MD-006y7o-6U; Mon, 02 Mar 2026 11:18:33 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 18/23] tools/nolibc/printf: Add support for conversion flags space and plus Date: Mon, 2 Mar 2026 10:18:10 +0000 Message-Id: <20260302101815.3043-19-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Flags ' ' and '+' are sign characters for positive numbers. Signed-off-by: David Laight Acked-by: Willy Tarreau --- v4: Split from the previous patch and support for the # flag. tools/include/nolibc/stdio.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index fb310b7d023f..5d75e8530ce2 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -296,7 +296,7 @@ int fseek(FILE *stream, long offset, int whence) * - %% generates a single % * - %m outputs strerror(errno). * - %X outputs a..f the same as %x. - * - The modifiers [#-+ 0] are currently ignored. + * - The modifiers [#-0] are currently ignored. * - No support for precision or variable widths. * - No support for floating point or wide characters. * - Invalid formats are copied to the output buffer. @@ -456,6 +456,10 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list sign_prefix =3D '-'; v =3D -(signed_v + 1); v++; + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, '+')) { + sign_prefix =3D '+'; + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, ' ')) { + sign_prefix =3D ' '; } } =20 --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C239439B964 for ; Mon, 2 Mar 2026 10:18:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446743; cv=none; b=OT0Ft0JlexfLrl8ygC0e7GibcGlJjs1vhqLARTxt/rk4qJuELNn+SRdUOp5zvdS8P5FzuEvv4P3zTQTQc8MBR7IDK6BDjpwXOC85HswylFdP6h4YVMgug8921+5qlto8uoIv7iEf462PW/PoD2N/MqK36vd+dod+PYW4kOffbuM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446743; c=relaxed/simple; bh=GTP3oRZVXjBN+khWC+cEI8DoN0ewVC9GlCDUeil1B/M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CN2jP8LGiJVk2vNcZPeuLAEJD7pMlbXzYVbq5+OcwlJDRuXY829DM4j8cngiN/W2GygXklXaPtA4ZIvh4ZUJaM+L3clzbKkB2EbjC2zDSSHXiy81uPhz5ZOSpqIvAafB1Z6JdvOk+rcLhOLYT20Z+ChiqD5CTo5arDuokODWYR4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=QUKd00yf; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="QUKd00yf" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MZ-00385a-4C; Mon, 02 Mar 2026 11:18:55 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=88M3sbDF/zPomo+REuKBu8a/s7isuTXZs+VJlaLgUfQ=; b=QUKd00yf69Ncnacv/1+mZuIxSI TQgWzIIT9Hrn/34V1d2yk4+aTiXlOL3M48MpF/kQnvdE22b0Mk/OqtkvIFEwGK1bgb7ZUJFJiEP7/ klJPfVwPGC8/yec4XDjxf7WyMGeCU8rM65Rh3kxTlI2FL9WztKiTEFkAvscDPjurQfRRbj4Wep0Q7 uu5z6+qZH8YC3WrTr/+f1IzD4+iTc2w+v4x4pRLSZoNKtoHFprx7jyrS7AwMGANsybVan0H5uuGdu XPMvVWJquo55gcXbhVCiIr5dVGXfEii06OEbVSezeVKaYl0GlSwvoDGPDtDPcYFovjLll+hJhWB9c ZBRykfPQ==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MY-00056B-QN; Mon, 02 Mar 2026 11:18:54 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MD-006y7o-Et; Mon, 02 Mar 2026 11:18:33 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 19/23] tools/nolibc/printf: Special case 0 and add support for %#x Date: Mon, 2 Mar 2026 10:18:11 +0000 Message-Id: <20260302101815.3043-20-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight The output for %#x is almost the same as that for %p, both output in hexadecimal with a leading "0x". However for zero %#x should just output "0" (the same as decimal and ocal). For %p match glibc and output "(nil)" rather than "0x0" or "0". Add tests for "%#x", "% d", "%+d" and passing NULL to "%p". Signed-off-by: David Laight Acked-by: Willy Tarreau --- v4: Split into its' own patch. tools/include/nolibc/stdio.h | 38 ++++++++++++++------ tools/testing/selftests/nolibc/nolibc-test.c | 3 ++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 5d75e8530ce2..ef8e7069d5cf 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -296,7 +296,7 @@ int fseek(FILE *stream, long offset, int whence) * - %% generates a single % * - %m outputs strerror(errno). * - %X outputs a..f the same as %x. - * - The modifiers [#-0] are currently ignored. + * - The modifiers [-0] are currently ignored. * - No support for precision or variable widths. * - No support for floating point or wide characters. * - Invalid formats are copied to the output buffer. @@ -410,8 +410,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list * so that 'X' can be allowed through. * 'X' gets treated and 'x' because _NOLIBC_PF_FLAG() returns the same * value for both. + * + * We need to check for "%p" or "%#x" later, merging here gives better c= ode. + * But '#' collides with 'c' so shift right. */ - ch_flag =3D _NOLIBC_PF_FLAG(ch); + ch_flag =3D _NOLIBC_PF_FLAG(ch) | (flags & _NOLIBC_PF_FLAG('#')) >> 1; if (((ch >=3D 'a' && ch <=3D 'z') || ch =3D=3D 'X') && _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p', 's')= ) { /* 'long' is needed for pointer/string conversions and ltz lengths. @@ -470,17 +473,30 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list */ out =3D outbuf + 2; =20 - /* Convert the number to ascii in the required base. */ - if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) { - /* Base 10 */ - len =3D u64toa_r(v, out); - } else { - /* Base 16 */ + if (v =3D=3D 0) { + /* There are special rules for zero. */ if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p')) { - /* "%p" needs "0x" prepending. */ - sign_prefix =3D 'x' | '0' << 8; + /* "%p" match glibc, precision is ignored */ + outstr =3D "(nil)"; + len =3D 5; + goto do_output; + } + /* All other formats (including "%#x") just output "0". */ + out[0] =3D '0'; + len =3D 1; + } else { + /* Convert the number to ascii in the required base. */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) { + /* Base 10 */ + len =3D u64toa_r(v, out); + } else { + /* Base 16 */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p', '#' - 1)) { + /* "%p" and "%#x" need "0x" prepending. */ + sign_prefix =3D 'x' | '0' << 8; + } + len =3D u64toh_r(v, out); } - len =3D u64toh_r(v, out); } =20 /* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */ diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index a140c54e4d72..4267c69ec37c 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1825,6 +1825,7 @@ static int run_printf(int min, int max) CASE_TEST(string); EXPECT_VFPRINTF(1, "foo", "%s", "foo"); break; CASE_TEST(number); EXPECT_VFPRINTF(1, "1234", "%d", 1234); break; CASE_TEST(negnumber); EXPECT_VFPRINTF(1, "-1234", "%d", -1234); break; + CASE_TEST(num_sign); EXPECT_VFPRINTF(1, "| 1|+2|+3|+4|5|", "|% d|%+d= |% +d|%+ d|%#d|", 1, 2, 3, 4, 5); break; CASE_TEST(unsigned); EXPECT_VFPRINTF(1, "12345", "%u", 12345); break; CASE_TEST(signed_max); EXPECT_VFPRINTF(1, "2147483647", "%i", ~0u >> 1= ); break; CASE_TEST(signed_min); EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >>= 1) + 1); break; @@ -1832,7 +1833,9 @@ static int run_printf(int min, int max) CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; CASE_TEST(hex_nolibc); EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", = 0xf, 0xd); break; CASE_TEST(hex_libc); EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|",= 0xf, 0xd); break; + CASE_TEST(hex_alt); EXPECT_VFPRINTF(1, "|0x1| 0x2| 0|", "|%#x|%= #5x|%#5x|", 1, 2, 0); break; CASE_TEST(pointer); EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); = break; + CASE_TEST(pointer_NULL); EXPECT_VFPRINTF(1, "(nil)", "%p", (void *)0); b= reak; CASE_TEST(percent); EXPECT_VFPRINTF(1, "a%d42%69%", "a%%d%d%%%d%%",= 42, 69); break; CASE_TEST(perc_qual); EXPECT_VFPRINTF(1, "a%d2", "a%-14l%d%d", 2); br= eak; CASE_TEST(invalid); EXPECT_VFPRINTF(1, "a%12yx3%y42%P", "a%12yx%d%y= %d%P", 3, 42); break; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B687A3ACF16 for ; Mon, 2 Mar 2026 10:18:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446756; cv=none; b=OKYwjj4MQfK7kdPyJtU3pCeel25e+Vnrq/eiIRglh1YgYeXvcAXKx4oN/QtBoj2ssp2wzaTVPIOFEgFjnvSdjQvjVzr6z7+VUqgTUSG36MSVNz0ui0J1GtUYj/9fmyQNZ/kTDA7fd99S0ryZEBUcZB9fTgYtze8KSfXh3n4t9h8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446756; c=relaxed/simple; bh=oUuKM7Lz3NS9EPu4zb2IRkNBVb2Ts8eL5y+60Y2fCrk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BkN3gO6Iz1Og6ByANVFYw1+pfo40K7Zxv/607FK7hwhYBLsB5xaEVOEJVbLBPH07chNZIR6o1mU09ag4m0IW6OwnGjV+9EaIxh5szVCTn1hC6vPbR04aQ7vJNHpQomsiyvevBLACIyDxADxdJ//rGeCJL1TnHIdiieotgs+AXAQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=ul+xNE6X; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="ul+xNE6X" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MZ-003Bdp-UD; Mon, 02 Mar 2026 11:18:55 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=b4B3QhvEGTvDq9Z1PC3/IWKV0iKMpZ0UDqB4a5XMnIw=; b=ul+xNE6Xatt26RVKeMHMocm81m rhn3zUvbQyW8fOO6GWKwBolX8rFkpKQ8MGVb5rf83inOSmmwsLUEBbtPXvqNg0QZfuMLZiaagXQLV 3xqylsLHzgKe0PKkkULHdcjMyugYPegvDqwLmJuXoB95Klf9m1qNzHDDhVWWRz/RSc0pqgah0tIZd h4u78DPWhxK+S0Jlrrc6xAIsldxCb8QRQKwxspfLZACB1WBnJ37LudeXgr7UQt/R9ASWL3uPoHVz+ EfL6ehHLV0HkLY50PBQRa1M/pkouITWU8+zBgSaqKbb1k41wN6isFSfrY5yeALThd6ZhHxgiKBC7F wgfj7b4g==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MZ-0002zD-KO; Mon, 02 Mar 2026 11:18:55 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MD-006y7o-NP; Mon, 02 Mar 2026 11:18:33 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 20/23] tools/nolibc/printf: Add support for left aligning fields Date: Mon, 2 Mar 2026 10:18:12 +0000 Message-Id: <20260302101815.3043-21-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Output the characters before or after the pad - writing the pad takes more = code. Include additional/changed tests Signed-off-by: David Laight Acked-by: Willy Tarreau --- Unchanged for v4. Changes for v3: - Formally part of patch 7. tools/include/nolibc/stdio.h | 6 +++++- tools/testing/selftests/nolibc/nolibc-test.c | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index ef8e7069d5cf..695676b44151 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -544,7 +544,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list /* Stop gcc back-merging this code into one of the conditionals above. */ _NOLIBC_OPTIMIZER_HIDE_VAR(len); =20 + /* Output the characters on the required side of any padding. */ width -=3D len; + flags =3D _NOLIBC_PF_FLAGS_CONTAIN(flags, '-'); + if (flags && cb(state, outstr, len) !=3D 0) + return -1; while (width > 0) { /* Output pad in 16 byte blocks with the small block first. */ int pad_len =3D ((width - 1) & 15) + 1; @@ -553,7 +557,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list if (cb(state, " ", pad_len) !=3D 0) return -1; } - if (cb(state, outstr, len) !=3D 0) + if (!flags && cb(state, outstr, len) !=3D 0) return -1; } =20 diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 4267c69ec37c..89ded1dd7318 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1845,9 +1845,11 @@ static int run_printf(int min, int max) CASE_TEST(truncation); EXPECT_VFPRINTF(1, "0123456789012345678901234",= "%s", "0123456789012345678901234"); break; CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); = break; CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); br= eak; + CASE_TEST(number_left); EXPECT_VFPRINTF(1, "|-5 |", "|%-8d|", -5);= break; + CASE_TEST(string_align); EXPECT_VFPRINTF(1, "|foo |", "|%-8s|", "foo= "); break; CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1",= "%25d", 1); break; CASE_TEST(errno); errno =3D 22; EXPECT_VFPRINTF(is_nolibc, "errno= =3D22", "%m"); break; - CASE_TEST(errno-neg); errno =3D -22; EXPECT_VFPRINTF(is_nolibc, " e= rrno=3D-22", "%12m"); break; + CASE_TEST(errno-neg); errno =3D -22; EXPECT_VFPRINTF(is_nolibc, "errn= o=3D-22 ", "%-12m"); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; case __LINE__: --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77F583A1A2F for ; Mon, 2 Mar 2026 10:18:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446743; cv=none; b=Nlww/vS2rDPMBvjUdYUsNb9ccTuRrv5U1oECy6yQLOYPcd1uBBQCHuvv2Zjs5ahpTINnS6OqjuHWsBafwP0FNmEETeQVLrMq2I9G9oTDlJkX1yFRJAlq6om2Vdnh27v/HWM3D1oHaTJzwPQdjX0nhvNzt8IclwWLCWCYOPD7qto= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446743; c=relaxed/simple; bh=wuKTJHkUPCc+jKwLKVYSaBZhc/u4tOryivMlQ833T50=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HyK5dSNo2zzuwA9bws7RMaavJLkG1J5lx2NZyEHNGCDeU02j2yVrDeJzb0/cXDiSoMD7WFHJtplpbZT2nZnlfWmbyR/BB18OrUOn58mxSDd7W32MQt2StwdXp843m/FzeM9+PNdS9mGDurFOk7zWqMFtB66wwxXRC8DyVuxTWIU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=p2J2Wa62; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="p2J2Wa62" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MY-003BdI-NV; Mon, 02 Mar 2026 11:18:54 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=Z4+EzCHlUi8D2pglKCFeRPbtQywb8mCGPCbgVs4Eot0=; b=p2J2Wa62fL/XM0GUUk6dtpqCA6 A83BiMLg7MEAKixlT9M2DYU4wVPLrm9lTf/D/V7L29B5CteHOGXrzBv29bRqv9bKpKmp7qtKYqrmO bByY0R0xQV5G1+D5Z7VpNvaDuqvXTRj6OX+qCZZAxlyogpBWMrzulZYTjS4voYXY1EqQ0cpY3jd4b aR82thBMy7dmLBV/c7HYRCHx3kd6AtOTlvKIl9hU6f2+T/6pfcf0MKvJVcEBZupCmVPQ+ykNAKvhU JtFqEdUEAtXINUfPTeY6zGXyWJIJc06v6rkpi5crMob8yjfExovBDogy1cWTodxR0ALXFW6blA1Zq RgiU0kcA==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MY-0002z1-DB; Mon, 02 Mar 2026 11:18:54 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0MD-006y7o-W1; Mon, 02 Mar 2026 11:18:34 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 21/23] tools/nolibc/printf: Add support for zero padding and field precision Date: Mon, 2 Mar 2026 10:18:13 +0000 Message-Id: <20260302101815.3043-22-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Includes support for variable field widths (eg "%*.*d"). Zero padding is limited to 31 zero characters. This is wider than the largest numeric field so shouldn't be a problem. All the standard printf formats are now supported except octal and floating point. Add tests for new features Acked-by: Willy Tarreau Signed-off-by: David Laight -- Unchanged for v4. Changes for v3: - Formerly patch 8 - Extra comments. - Adjust offsets in outbuf[], support adding 31 '0' digits while still allowing enough room for octal support to be added and keeping outbuf[] at a nice round 56 bytes. Changes for v2: - These changes were previously in patch 9. However you need to apply the old patch 10 to get anything like the same source. The files then more of less match apart from 'c' being renamed 'ch' and the 'magic' #defines. tools/include/nolibc/stdio.h | 77 ++++++++++++++++---- tools/testing/selftests/nolibc/nolibc-test.c | 19 ++++- 2 files changed, 79 insertions(+), 17 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 695676b44151..08011345275a 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -292,12 +292,10 @@ int fseek(FILE *stream, long offset, int whence) =20 =20 /* printf(). Supports most of the normal integer and string formats. - * - %[#-+ 0][width][{l,t,z,ll,L,j,q}]{c,d,i,u,x,X,p,s,m,%} + * - %[#0-+ ][width|*[.precision|*}][{l,t,z,ll,L,j,q}]{c,d,i,u,x,X,p,s,m,= %} * - %% generates a single % * - %m outputs strerror(errno). * - %X outputs a..f the same as %x. - * - The modifiers [-0] are currently ignored. - * - No support for precision or variable widths. * - No support for floating point or wide characters. * - Invalid formats are copied to the output buffer. * @@ -343,9 +341,9 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list char ch; unsigned long long v; long long signed_v; - int written, width, len; + int written, width, precision, len; unsigned int flags, ch_flag; - char outbuf[2 + 22 + 1]; + char outbuf[2 + 31 + 22 + 1]; char *out; const char *outstr; unsigned int sign_prefix; @@ -378,12 +376,24 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list flags |=3D ch_flag; } =20 - /* width */ - while (ch >=3D '0' && ch <=3D '9') { - width *=3D 10; - width +=3D ch - '0'; - - ch =3D *fmt++; + /* Width and precision */ + for (;; ch =3D *fmt++) { + if (ch =3D=3D '*') { + precision =3D va_arg(args, unsigned int); + ch =3D *fmt++; + } else { + for (precision =3D 0; ch >=3D '0' && ch <=3D '9'; ch =3D *fmt++) + precision =3D precision * 10 + (ch - '0'); + } + if (_NOLIBC_PF_FLAGS_CONTAIN(flags, '.')) + break; + width =3D precision; + if (ch !=3D '.') { + /* Default precision for strings */ + precision =3D INT_MAX; + break; + } + flags |=3D _NOLIBC_PF_FLAG('.'); } =20 /* Length modifier. @@ -446,6 +456,9 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list outstr =3D (const char *)(uintptr_t)v; if (!outstr) { outstr =3D "(null)"; + /* Match glibc, nothing output if precision too small */ + len =3D precision >=3D 6 ? 6 : 0; + goto do_output; } goto do_strlen_output; } @@ -467,11 +480,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list } =20 /* The value is converted offset into the buffer so that - * the sign/prefix can be added in front. + * 31 zero pad characters and the sign/prefix can be added in front. * The longest digit string is 22 + 1 for octal conversions, the * space is reserved even though octal isn't currently supported. */ - out =3D outbuf + 2; + out =3D outbuf + 2 + 31; =20 if (v =3D=3D 0) { /* There are special rules for zero. */ @@ -481,6 +494,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list len =3D 5; goto do_output; } + if (!precision) { + /* Explicit %nn.0d, no digits output */ + len =3D 0; + goto prepend_sign; + } /* All other formats (including "%#x") just output "0". */ out[0] =3D '0'; len =3D 1; @@ -499,6 +517,35 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state= , const char *fmt, va_list } } =20 + /* Add zero padding */ + if (_NOLIBC_PF_FLAGS_CONTAIN(flags, '0', '.')) { + if (!_NOLIBC_PF_FLAGS_CONTAIN(flags, '.')) { + if (_NOLIBC_PF_FLAGS_CONTAIN(flags, '-')) + /* Left justify overrides zero pad */ + goto prepend_sign; + /* eg "%05d", Zero pad to field width less sign. + * Note that precision can end up negative so all + * the variables have to be 'signed int'. + */ + precision =3D width; + if (sign_prefix) { + precision--; + if (sign_prefix >=3D 256) + precision--; + } + } + if (precision > 31) + /* Don't run off the start of outbuf[], arbitrary limit + * longer than the longest number field. */ + precision =3D 31; + for (; len < precision; len++) { + /* Stop gcc generating horrid code and memset(). */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + *--out =3D '0'; + } + } + +prepend_sign: /* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */ for (; sign_prefix; sign_prefix >>=3D 8) { /* Force gcc to increment len inside the loop. */ @@ -533,8 +580,8 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list goto do_output; =20 do_strlen_output: - /* Open coded strlen() (slightly smaller). */ - for (len =3D 0;; len++) + /* Open coded strnlen() (slightly smaller). */ + for (len =3D 0; len < precision; len++) if (!outstr[len]) break; =20 diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 89ded1dd7318..7398827fa08b 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1830,12 +1830,15 @@ static int run_printf(int min, int max) CASE_TEST(signed_max); EXPECT_VFPRINTF(1, "2147483647", "%i", ~0u >> 1= ); break; CASE_TEST(signed_min); EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >>= 1) + 1); break; CASE_TEST(unsigned_max); EXPECT_VFPRINTF(1, "4294967295", "%u", ~0u); br= eak; - CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; + CASE_TEST(char); EXPECT_VFPRINTF(1, "|c|d| e|", "|%c|%.0c|%4c|= ", 'c', 'd', 'e'); break; CASE_TEST(hex_nolibc); EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", = 0xf, 0xd); break; CASE_TEST(hex_libc); EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|",= 0xf, 0xd); break; CASE_TEST(hex_alt); EXPECT_VFPRINTF(1, "|0x1| 0x2| 0|", "|%#x|%= #5x|%#5x|", 1, 2, 0); break; + CASE_TEST(hex_alt_prec); EXPECT_VFPRINTF(1, "| 0x02|0x03| 0x123|", "|%#5= .2x|%#04x|%#6.2x|", 2, 3, 0x123); break; + CASE_TEST(hex_0_alt); EXPECT_VFPRINTF(1, "|0|0000| 00|", "|%#x|%#04= x|%#5.2x|", 0, 0, 0); break; CASE_TEST(pointer); EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); = break; - CASE_TEST(pointer_NULL); EXPECT_VFPRINTF(1, "(nil)", "%p", (void *)0); b= reak; + CASE_TEST(pointer_NULL); EXPECT_VFPRINTF(1, "|(nil)|(nil)|", "|%p|%.4p|"= , (void *)0, (void *)0); break; + CASE_TEST(string_NULL); EXPECT_VFPRINTF(1, "|(null)||(null)|", "|%s|%.5= s|%.6s|", (void *)0, (void *)0, (void *)0); break; CASE_TEST(percent); EXPECT_VFPRINTF(1, "a%d42%69%", "a%%d%d%%%d%%",= 42, 69); break; CASE_TEST(perc_qual); EXPECT_VFPRINTF(1, "a%d2", "a%-14l%d%d", 2); br= eak; CASE_TEST(invalid); EXPECT_VFPRINTF(1, "a%12yx3%y42%P", "a%12yx%d%y= %d%P", 3, 42); break; @@ -1844,10 +1847,22 @@ static int run_printf(int min, int max) CASE_TEST(uintmax_max); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju= ", ~0ULL); break; CASE_TEST(truncation); EXPECT_VFPRINTF(1, "0123456789012345678901234",= "%s", "0123456789012345678901234"); break; CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); = break; + CASE_TEST(string_trunc); EXPECT_VFPRINTF(1, " 12345", "%10.5s", "123= 4567890"); break; CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); br= eak; CASE_TEST(number_left); EXPECT_VFPRINTF(1, "|-5 |", "|%-8d|", -5);= break; CASE_TEST(string_align); EXPECT_VFPRINTF(1, "|foo |", "|%-8s|", "foo= "); break; CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1",= "%25d", 1); break; + CASE_TEST(width_tr_lft); EXPECT_VFPRINTF(1, "1 = ", "%-30d", 1); break; + CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "0000000005", "%010d", 5); b= reak; + CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "|0000000005|0x1234|", "|%01= 0d|%#01x|", 5, 0x1234); break; + CASE_TEST(num_pad_neg); EXPECT_VFPRINTF(1, "-000000005", "%010d", -5); = break; + CASE_TEST(num_pad_hex); EXPECT_VFPRINTF(1, "00fffffffb", "%010x", -5); = break; + CASE_TEST(num_pad_trunc);EXPECT_VFPRINTF(is_nolibc, " 000000000000000= 0000000000000005", "%035d", 5); break; /* max 31 '0' can be added */ + CASE_TEST(num_p_tr_libc);EXPECT_VFPRINTF(!is_nolibc, "000000000000000000= 00000000000000005", "%035d", 5); break; + CASE_TEST(number_prec); EXPECT_VFPRINTF(1, " 00005", "%10.5d", 5); = break; + CASE_TEST(num_prec_neg); EXPECT_VFPRINTF(1, " -00005", "%10.5d", -5);= break; + CASE_TEST(num_prec_var); EXPECT_VFPRINTF(1, " -00005", "%*.*d", 10, 5= , -5); break; + CASE_TEST(num_0_prec_0); EXPECT_VFPRINTF(1, "|| |+||||", "|%.0d|% .0d|%+= .0d|%.0u|%.0x|%#.0x|", 0, 0, 0, 0, 0, 0); break; CASE_TEST(errno); errno =3D 22; EXPECT_VFPRINTF(is_nolibc, "errno= =3D22", "%m"); break; CASE_TEST(errno-neg); errno =3D -22; EXPECT_VFPRINTF(is_nolibc, "errn= o=3D-22 ", "%-12m"); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9586739B95E for ; Mon, 2 Mar 2026 10:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446733; cv=none; b=qx5+3cmg4TSa5/no2HTesMNsChX+jLvMvJ0KIO57mjw60R4sD7NS5OLa76HoCmR02EkcjBNz3YGPJNZItMt3QQYHCfupZHAeEpOCLoxGgmWHiY/IwYSeaoGa8CcuWJCfJZFsbVtNS/nVRMefYUs6c0e7y7GhFlQe1dsniYFhCpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446733; c=relaxed/simple; bh=NQBNwEHcSZ3FUO7C4h9L2HNkulBYqj+KD584ulTW/Ek=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PrgUluWsQyUE5GzxNXpJ6I3wgW62RlaQFAP6xqyXcoiQ4P/5OP73CuIDzDrCkl/KdXJ1U39pX49/cfuFx/ccL2c6aLOVkfO3oKkeiL5VMfFgsPp4EZemAkW+BAwh5FoPeS1wQ+wLZDffYFzpL28R7i9ClQTYeb0DqKvtMGIvNYk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=dGIyweYz; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="dGIyweYz" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MS-00380X-D4; Mon, 02 Mar 2026 11:18:48 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=sk7sBuvXIk2EMaYYG9091SXZBtOAM7kS3qT3qrmyl30=; b=dGIyweYzmKafiMrPpV/aB+TBaU ugWfJWiwMWLQcX9rzPF2NkJqEJRdXW7tUeEEJoTIPU3WZRI3zdhYm+WCYHngKKdSFT2ZtG5lqjNlu GmDB1L05GUGHO5t/IA/YfPCzdvDni3A7vniHlxuR7n6tasXF6ABPYGgQPOoLspspKxDqqd46whB/v QqyDsl+gPMW1+VjbZxYt6sxP6Qj2qF6HHIRBKXGF4gK4VgaMZwtq5/59EpvDsZhuTOdp3ydfzm/z6 xkisiEUr/JYKgCtWgelvRmKloiJrpUkYvvqBogCFgBID8BTG/cp1Hn8L2J1MVIJuHsbupgS3xLR2I iD9sQbVQ==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MS-0002y3-2D; Mon, 02 Mar 2026 11:18:48 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0ME-006y7o-8W; Mon, 02 Mar 2026 11:18:34 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 22/23] tools/nolibc/printf: Add support for octal output Date: Mon, 2 Mar 2026 10:18:14 +0000 Message-Id: <20260302101815.3043-23-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Octal output isn't often used, but adding it costs very little. Supporting "%#o" is mildly annoying, it has to add a leading '0' if there isn't one present. In simple cases this is the same as adding a sign of '0' - but that adds an extra '0' in a few places. So you need 3 tests, %o, # and no leading '0' (which can only be checked after the zero pad for precision). If all the test are deferred until after zero padding then too many values are 'live' across the call to _nolibc_u64toa_base() and get spilled to stac= k. Hence the check that ignores the 'sign' if it is the same as the first character of the output string. Add tests for octal output. Signed-off-by: David Laight Acked-by: Willy Tarreau --- v4: - Increase VFPRINTF_LEN to 25 to that 64bit octal output isn't truncated. Change truncation tests to match. (Was done earlier in v3.) New patch for v3. Relies on the changes to u64toa_r() etc in stdlib.h (patch 2). tools/include/nolibc/stdio.h | 50 ++++++++++++++------ tools/testing/selftests/nolibc/nolibc-test.c | 9 ++-- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 08011345275a..6036154be791 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -292,7 +292,7 @@ int fseek(FILE *stream, long offset, int whence) =20 =20 /* printf(). Supports most of the normal integer and string formats. - * - %[#0-+ ][width|*[.precision|*}][{l,t,z,ll,L,j,q}]{c,d,i,u,x,X,p,s,m,= %} + * - %[#0-+ ][width|*[.precision|*}][{l,t,z,ll,L,j,q}]{c,d,i,u,o,x,X,p,s,= m,%} * - %% generates a single % * - %m outputs strerror(errno). * - %X outputs a..f the same as %x. @@ -426,7 +426,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list */ ch_flag =3D _NOLIBC_PF_FLAG(ch) | (flags & _NOLIBC_PF_FLAG('#')) >> 1; if (((ch >=3D 'a' && ch <=3D 'z') || ch =3D=3D 'X') && - _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p', 's')= ) { + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'o', 'x', 'p',= 's')) { /* 'long' is needed for pointer/string conversions and ltz lengths. * A single test can be used provided 'p' (the same bit as '0') * is masked from flags. @@ -477,12 +477,19 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, ' ')) { sign_prefix =3D ' '; } + } else { + /* "#o" requires that the output always starts with a '0'. + * This needs another check after any zero padding to avoid + * adding an extra leading '0'. + */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'o') && + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, '#' - 1)) + sign_prefix =3D '0'; } =20 /* The value is converted offset into the buffer so that * 31 zero pad characters and the sign/prefix can be added in front. - * The longest digit string is 22 + 1 for octal conversions, the - * space is reserved even though octal isn't currently supported. + * The longest digit string is 22 + 1 for octal conversions. */ out =3D outbuf + 2 + 31; =20 @@ -495,7 +502,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state,= const char *fmt, va_list goto do_output; } if (!precision) { - /* Explicit %nn.0d, no digits output */ + /* Explicit %nn.0d, no digits output (except for %#.0o) */ len =3D 0; goto prepend_sign; } @@ -504,17 +511,23 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list len =3D 1; } else { /* Convert the number to ascii in the required base. */ + unsigned long long recip; + unsigned int base; if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) { - /* Base 10 */ - len =3D u64toa_r(v, out); + base =3D 10; + recip =3D _NOLIBC_U64TOA_RECIP(10); + } else if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'o')) { + base =3D 8; + recip =3D _NOLIBC_U64TOA_RECIP(8); } else { - /* Base 16 */ + base =3D 16; + recip =3D _NOLIBC_U64TOA_RECIP(16); if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p', '#' - 1)) { /* "%p" and "%#x" need "0x" prepending. */ sign_prefix =3D 'x' | '0' << 8; } - len =3D u64toh_r(v, out); } + len =3D _nolibc_u64toa_base(v, out, base, recip); } =20 /* Add zero padding */ @@ -545,13 +558,20 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *stat= e, const char *fmt, va_list } } =20 + /* %#o has set sign_prefix to '0', but we don't want so add an extra + * leading zero here. + * Since the only other byte values of sign_prefix are ' ', '+' and '-' + * it is enough to check that out[] doesn't already start with sign_pre= fix. + */ + if (sign_prefix !=3D *out) { prepend_sign: - /* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */ - for (; sign_prefix; sign_prefix >>=3D 8) { - /* Force gcc to increment len inside the loop. */ - _NOLIBC_OPTIMIZER_HIDE_VAR(len); - len++; - *--out =3D sign_prefix; + /* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */ + for (; sign_prefix; sign_prefix >>=3D 8) { + /* Force gcc to increment len inside the loop. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + len++; + *--out =3D sign_prefix; + } } outstr =3D out; goto do_output; diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 7398827fa08b..29ad1207464f 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1663,7 +1663,7 @@ int run_stdlib(int min, int max) #define EXPECT_VFPRINTF(cond, expected, fmt, ...) \ do { if (!(cond)) result(llen, SKIPPED); else ret +=3D expect_vfprintf(ll= en, expected, fmt, ##__VA_ARGS__); } while (0) =20 -#define VFPRINTF_LEN 20 +#define VFPRINTF_LEN 25 static int expect_vfprintf(int llen, const char *expected, const char *fmt= , ...) { char buf[VFPRINTF_LEN + 80]; @@ -1831,6 +1831,9 @@ static int run_printf(int min, int max) CASE_TEST(signed_min); EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >>= 1) + 1); break; CASE_TEST(unsigned_max); EXPECT_VFPRINTF(1, "4294967295", "%u", ~0u); br= eak; CASE_TEST(char); EXPECT_VFPRINTF(1, "|c|d| e|", "|%c|%.0c|%4c|= ", 'c', 'd', 'e'); break; + CASE_TEST(octal); EXPECT_VFPRINTF(1, "|17| 0033||", "|%o|%6.4o|%= .0o|", 017, 033, 0); break; + CASE_TEST(octal_max); EXPECT_VFPRINTF(1, "1777777777777777777777", "%= llo", ~0ULL); break; + CASE_TEST(octal_alt); EXPECT_VFPRINTF(1, "|0|01|02|034|0|", "|%#o|%#o= |%#02o|%#02o|%#.0o|", 0, 1, 2, 034, 0); break; CASE_TEST(hex_nolibc); EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", = 0xf, 0xd); break; CASE_TEST(hex_libc); EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|",= 0xf, 0xd); break; CASE_TEST(hex_alt); EXPECT_VFPRINTF(1, "|0x1| 0x2| 0|", "|%#x|%= #5x|%#5x|", 1, 2, 0); break; @@ -1845,13 +1848,13 @@ static int run_printf(int min, int max) CASE_TEST(intmax_max); EXPECT_VFPRINTF(1, "9223372036854775807", "%lld= ", ~0ULL >> 1); break; CASE_TEST(intmax_min); EXPECT_VFPRINTF(1, "-9223372036854775808", "%Li= ", (~0ULL >> 1) + 1); break; CASE_TEST(uintmax_max); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju= ", ~0ULL); break; - CASE_TEST(truncation); EXPECT_VFPRINTF(1, "0123456789012345678901234",= "%s", "0123456789012345678901234"); break; + CASE_TEST(truncation); EXPECT_VFPRINTF(1, "012345678901234567890123456= 789", "%s", "012345678901234567890123456789"); break; CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); = break; CASE_TEST(string_trunc); EXPECT_VFPRINTF(1, " 12345", "%10.5s", "123= 4567890"); break; CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); br= eak; CASE_TEST(number_left); EXPECT_VFPRINTF(1, "|-5 |", "|%-8d|", -5);= break; CASE_TEST(string_align); EXPECT_VFPRINTF(1, "|foo |", "|%-8s|", "foo= "); break; - CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1",= "%25d", 1); break; + CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " = 1", "%30d", 1); break; CASE_TEST(width_tr_lft); EXPECT_VFPRINTF(1, "1 = ", "%-30d", 1); break; CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "0000000005", "%010d", 5); b= reak; CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "|0000000005|0x1234|", "|%01= 0d|%#01x|", 5, 0x1234); break; --=20 2.39.5 From nobody Thu Apr 9 14:49:46 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C89F439B96B for ; Mon, 2 Mar 2026 10:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446732; cv=none; b=RVBQFdOZfD1LXE1D9lyuPRUiEMoc04kHrbf0LcIsnpmjVUlrGEaykrsfXoOinGkjpy7MY0ILl0xfsXTZUVR6OZKIISftDV0xZKY44w8YYCnWXAuwHJpn2JuobhWaw0HNXBHNvcmBtFvLn48qaOUJySlns1ngdPg9DYXsBRE3gv4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772446732; c=relaxed/simple; bh=9bOVIQApIg0yzck1zM2Lts2fEzItul/O3+juqIj7tT8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oA/kFhd7Jny1/IOuhfBULrHX2l7TI1FHdPu4BXtGR0nm4h/1vcKa5xIlmEHmE3zf0YPRcbO8yQUQDGXWqzY6zE3pvMsAb99m7RpCTDyO95weWdYJkdDhCFG11x7HOX84n2SuERPzj4fEDLRqow4YAt0aHfBEWds/6M0fDxTU+oI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=runbox.com; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b=oku9i7mg; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=runbox.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=runbox.com header.i=@runbox.com header.b="oku9i7mg" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vx0MS-003BYX-RP; Mon, 02 Mar 2026 11:18:48 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=selector2; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To :Message-Id:Date:Subject:Cc:To:From; bh=nMtv5CEz5u+mvhCGmTHG84fVYviigF1VOQzD6irpWg8=; b=oku9i7mg6xXg+h0q9cyDvJJeA4 apl/9THHz6V+g50+rIncbmm1sfRO0jQevi9iHtF3tXctf/izBqEaPKVzkgVp+W6J6nuCwRL2uWQhz LKOe/TBWKrDaSrmp/HEXOvqS8vkxmz8k4SU6ySlJi1o2bWTbKqmClqqWzO5x41LKNFiux2PPMuHib dUPLfPBeR7qIQLI2Lf26HYtLcDl7To7t4H07VWfeF/QEvLorCK/iWU4GKlEHGPWuWhIwbj70F0Ajl y/1q2lv7GLw2G6iJF+uFPFaOIX/QxqQ+yH/LMbRMiIEZzNRlt6dZg0/w3ked3y+ySb0g0rjwp7M6I UUIR6VQg==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vx0MS-0002y9-F8; Mon, 02 Mar 2026 11:18:48 +0100 Received: by submission01.runbox with esmtpsa [Authenticated ID (1493616)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vx0ME-006y7o-H1; Mon, 02 Mar 2026 11:18:34 +0100 From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH v4 next 23/23] selftests/nolibc: Use printf variable field widths and precisions Date: Mon, 2 Mar 2026 10:18:15 +0000 Message-Id: <20260302101815.3043-24-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260302101815.3043-1-david.laight.linux@gmail.com> References: <20260302101815.3043-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Now that printf supports '*' for field widths and precisions then can be used to simplify the test output. - aligning the "[OK]" strings. - reporting the expected sprintf() output when there is a mismatch. Acked-by: Willy Tarreau Signed-off-by: David Laight --- Unchanged for v4. tools/testing/selftests/nolibc/nolibc-test.c | 26 ++++---------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 29ad1207464f..ac4442c8c5fa 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -156,21 +156,6 @@ static const char *errorname(int err) } } =20 -static void align_result(size_t llen) -{ - const size_t align =3D 64; - char buf[align]; - size_t n; - - if (llen >=3D align) - return; - - n =3D align - llen; - memset(buf, ' ', n); - buf[n] =3D '\0'; - fputs(buf, stdout); -} - enum RESULT { OK, FAIL, @@ -188,8 +173,10 @@ static void result(int llen, enum RESULT r) else msg =3D " [FAIL]"; =20 - align_result(llen); - puts(msg); + llen =3D 64 - llen; + if (llen < 0) + llen =3D 0; + printf("%*s%s\n", llen, "", msg); } =20 /* The tests below are intended to be used by the macroes, which evaluate @@ -1692,10 +1679,7 @@ static int expect_vfprintf(int llen, const char *exp= ected, const char *fmt, ...) } =20 if (memcmp(expected, buf, cmp_len) || buf[cmp_len]) { - /* Copy and truncate until "%.*s" supported */ - memcpy(buf, expected, cmp_len); - buf[cmp_len] =3D 0; - llen +=3D printf(" should be \"%s\"", buf); + llen +=3D printf(" should be \"%.*s\"", VFPRINTF_LEN, expected); result(llen, FAIL); return 1; } --=20 2.39.5