From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB448329E52 for ; Thu, 29 Jan 2026 10:31:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769682662; cv=none; b=C17NUMR34UTEA0DNPE0EmCm2G6qdOvsEhhi6Bie0RtnWkIhrzF3DOq1wosqhoIeC2jh0ziHmdrKGTFAsqPPaUJQBxEuJdrDk/QPXPc1RR+mRxbF+OrXOkPl6bVSXOjtVkTaMad/JD1SI3UZZpPm5xleffkYKeDKvZNKvz8lh/pM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769682662; c=relaxed/simple; bh=eGb6qjtecqgQZOunhTaQtZU+gZxo7zRLKl/KUUAeoCw=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fNGM0emvhtMPhEBGz+LJRL6lOdWJfEmahYosuoWrhrXWZdqhPZ99tkzsHnAAU/PN/kJTZ62EEhnMk87LlvIhTHrAXwRuxHMg87RH7Qqd+Kg82Bh9dwjcgzkyM4Lq6ditTcsx7aAPe6+r6F8arJnA2n7dUF0gXIvhTk7wZXKuJw4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HsFMPdaS; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HsFMPdaS" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-47fedb7c68dso7928085e9.2 for ; Thu, 29 Jan 2026 02:31:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769682659; x=1770287459; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=MnH/ms2wTyHst//h5R5jq0nkcVl3Rj3ZbL8bHxwUhbs=; b=HsFMPdaSCKcSfM0Mq15yZ+1U2qkeLiCLKlXr8QgLUZ0kOzXu4kX+Kp92NzI7zFTccl yjU+NDzzBkytTPciqx9LJfinSLCtGEC3Mo667tWdzh+dNJD+AGEWFIwfKdTIV3HDMLm9 vXftVBWlsDmvaiLQ2YWGtbZDOizrKMjIvcIZ0pRxlpHuHftUGtx20p8cOG0TA6gWg0mT tXyddZSzquWS6uVGHTAjmkOV1cbH5jp5N5wj3zOFCrCKs8A6iUwR+JaSzk3k0eX5kxuX xCy9zxjcsCH45unNBdigQPXN1NRynZDSCCk51bSaddXj16Fw95mDtjOKb7KsIFAJq6Fy 2IoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769682659; x=1770287459; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=MnH/ms2wTyHst//h5R5jq0nkcVl3Rj3ZbL8bHxwUhbs=; b=Ler5ncRa2K/6O5CcQCJFK9HKW6fatr4SrenPALJZ/QOtpHW4ANPHeKuyaiiET1wZ2R 8kwMddGBnMvmH3LJIRFOY298rIYqssqsTrhPQ77ZLxJhXEZgS/Z48IQ/L124ooiy2Nlb SiHKvAP7iaHQqW7ULHq49v4Tgmmzxe6EbtTlbFTaNXWt3H6tJsb54Htmg0VbTUldbG2s dA9GINcZoQ+5MGWrmJVa3wPNs0Lu3e8B4rWXL4miGIpAiija45+dl4gHtDm5/q/iCiEw RZ+u7/BI6oWowQOCUf+l98g16tqAZ8xskXSgaxXNGnv/KunPTCHsridK4TcSTdjXYMeq OdaQ== X-Forwarded-Encrypted: i=1; AJvYcCUHgmYXzt15EcRA0t/XXva+miRo+UQ9Q/18tbL/eN0nxhVQ6B1XJxfUx44JQY2/FxfEmFu6CIcdO8sCDxc=@vger.kernel.org X-Gm-Message-State: AOJu0YzMfaGQ2lTugci8Ab7ZqwNly9NJCrPKmxlU9nLX1yjZ5bbQOokq QYW57cA1zSU7A/F3fTVJohnATNu4LVUNH6eeccJHSgx8hbcYlcOGzJS3 X-Gm-Gg: AZuq6aKbRRYFAe3B1BRyyAAAO3j0i1lFIwHONOhpMSJFEDMP90QPYKc6P3E0D1Mmftz NQXi39lXxY9G3BF8Q/1UXZdOlQd/8ENMGF2FtsDIatwC1Vrzi3YgARZC/ic0EME7k9YeZ77VzqP 6DnvWxBupM74W4hYF6BIVDIfCcInI8PxcAVQ6H0xk5wc8y91bm0F4ZwRAMnF0K02JBJM9lFc2Eu 15sqNNrkerfAL6VokmBqoU61koNs0VLesLc2MkJsafKNQGnsj7r4pqHWMI7sBxZMPMqYA+27xCZ twpRq4c9CtmVwTZyNiNcQqaCDatK521XbQfa9N0zS4o05Y5glIa3o3htYAQAxfQVfYpGTlJmLCu 5g2/EenBYlF5ELp+z5zz/rrDn5qdh9eVrcplmmOlcmmU/dQ7x/ECm4zUZCpXJk0j5JfR70A5M5P 0vyWOCMFcURLXGlzbFwqGMoDn68WmsFiVdBWLF1Ny7su7fYOim5ydX X-Received: by 2002:a05:600c:8b85:b0:480:52fe:58f5 with SMTP id 5b1f17b1804b1-48069c57137mr123690445e9.31.1769682658843; Thu, 29 Jan 2026 02:30:58 -0800 (PST) Received: from pumpkin (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48066bfb58esm188821525e9.8.2026.01.29.02.30.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jan 2026 02:30:58 -0800 (PST) Date: Thu, 29 Jan 2026 10:30:57 +0000 From: David Laight To: "licheng.li" Cc: Willy Tarreau , Thomas =?UTF-8?B?V2Vpw59zY2h1aA==?= , linux-kernel@vger.kernel.org Subject: Re: [PATCH v2 1/2] tools/nolibc: support left alignment (-) and zero padding (0) in printf Message-ID: <20260129103057.324d654d@pumpkin> In-Reply-To: <20260128094224.11299-2-im.lechain@gmail.com> References: <20260128094224.11299-1-im.lechain@gmail.com> <20260128094224.11299-2-im.lechain@gmail.com> X-Mailer: Claws Mail 4.1.1 (GTK 3.24.38; arm-unknown-linux-gnueabihf) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Wed, 28 Jan 2026 17:42:23 +0800 "licheng.li" wrote: > From: Cheng Li > > Currently, __nolibc_printf() in nolibc parses the width field but always > pads with spaces on the left. It ignores the '-' flag (left alignment) > and treats leading zeros in the width as part of the number parsing > (resulting in space padding instead of zero padding). > > This patch implements support for: > 1. The '-' flag: forces left alignment by padding spaces on the right. > 2. The '0' flag: forces zero padding on the left instead of spaces. Does that work properly? I think it is padding zeros the wrong side of the sign (or "0x"). Try testing with a negative number or a pointer. You might need to limit the width for numeric fields to (say) 32, make the on-stack buffer 64 bytes and convert into the middle. Then add pad zeros to the front before adding any "-" or "0x". It then gets very close to supporting precisions as well as widths. It might be worth changing the 'pad' loop to: while (width > w) { unsigned int pad_len = ((width - w - 1) & 0xf) + 1; width -= pad_len; written += pad_len; if (cb(state, " ", pad_len) != 0) return -1; } while the code is marginally larger writing the pad in blocks of 16 will be much faster. The linker should merge all the strings of spaces. I looked at the (existing) version last night. If the 'l' flag code is moved to after the width is calculated it all becomes a lot simpler. Set 'outstr = fmt' at the top of the loop and the code can use *fmt++ and do a 'fast scan' of the format string for a '%' or '\0' then output the chars from the format string at the bottom. I didn't size the change, but getting rid of ofs and escape must help. Might post it later. David > > The implementation reuses the padding character logic to handle both > cases. > > Logic behavior: > - "%5d" -> " 12" (unchanged) > - "%-5d" -> "12 " (new: left align) > - "%05d" -> "00012" (new: zero pad) > - "%-05d"-> "12 " (new: left align overrides zero pad) > > The code is optimized to keep the binary size impact minimal. > Measuring the nolibc-test binary on x86_64: > > text data bss dec hex filename > 43552 248 112 43912 ab88 nolibc-test (before) > 43677 248 112 44037 ac05 nolibc-test (after) > > The net increase is 125 bytes. > > Suggested-by: Willy Tarreau > Signed-off-by: Cheng Li > --- > v2 changes: > - Adopted optimization suggestions from Willy Tarreau: > - Incremented 'written' counter at the start of loops. > - Reordered loop checks to optimize compiler register usage. > - Updated commit message to explicitly mention zero-padding ('0') support. > --- > tools/include/nolibc/stdio.h | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > index 1f16dab2ac88..df8a96e39986 100644 > --- a/tools/include/nolibc/stdio.h > +++ b/tools/include/nolibc/stdio.h > @@ -250,7 +250,7 @@ typedef int (*__nolibc_printf_cb)(intptr_t state, const char *buf, size_t size); > 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) > { > - char escape, lpref, c; > + char escape, lpref, padc, c; > unsigned long long v; > unsigned int written, width; > size_t len, ofs, w; > @@ -261,11 +261,17 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > while (1) { > c = fmt[ofs++]; > width = 0; > + padc = ' '; > > if (escape) { > /* we're in an escape sequence, ofs == 1 */ > escape = 0; > > + if (c == '-' || c == '0') { > + padc = c; > + c = fmt[ofs++]; > + } > + > /* width */ > while (c >= '0' && c <= '9') { > width *= 10; > @@ -358,13 +364,19 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > if (n) { > w = len < n ? len : n; > n -= w; > - while (width-- > w) { > - if (cb(state, " ", 1) != 0) > - return -1; > + while (width > w && padc != '-') { > written += 1; > + if (cb(state, &padc, 1) != 0) > + return -1; > + width--; > } > if (cb(state, outstr, w) != 0) > return -1; > + while (width-- > w) { > + written += 1; > + if (cb(state, " ", 1) != 0) > + return -1; > + } > } > > written += len;