From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (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 4ECF4429828 for ; Fri, 6 Feb 2026 19:11:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770405094; cv=none; b=S4dIW6G1MgIonQbv7ODkQ3XshCbBwYgXWDg7O/55Tc9UtpKCvVs7meayglwupR26gPODmJ7gABsX6Tl3aJiGDZW1kB3IuRzm+yofXMsIhF/VcOi43Y64+gBmp/kZQczXesldnIxlO1jgPrBBlznpMU6Wol3Lza0Owr6q+7bucwI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770405094; c=relaxed/simple; bh=TiWouF+DCOEmpdmJM2vXwoXoaTd5/l1vBVOp4d6Dvjg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uVzFJVPJ6YW3vk8bYtC7sg24ZvIVCUMKc51PfLxSSE29GxPg1LaGFQLtl37PmwCoFbf0vjM02cHihzglvQSI0QkFTkmTA6WiRMKwdAatmKk4sdqK9ntwJBJLDYJKp/l0gXhvbd5/0+Zg+yRDpsXPOSoAI1r60XekaSFD0BClJr0= 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=Dg70BN/A; arc=none smtp.client-ip=209.85.128.46 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="Dg70BN/A" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4806cc07ce7so25149145e9.1 for ; Fri, 06 Feb 2026 11:11:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770405093; x=1771009893; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IYenYEMbES7F2pVkYVhENk/YQ/r/YwrlXyRLxNZrVVY=; b=Dg70BN/ApLHF/OAgCmbIQ8kYEXLmeJ9xBBvVT4QYVZ7pTMknTuF3qJVP5IvUtrjYOs jZ3XJmkjA8XhN+yEt39E1GEPqMpCMNzU9Mi9/9J86vs6D1ntYcU8L0YGDbkGPhBoFesn 1q+IM/RBWCwNigAbveLIAbcndrGyuCgHfJ2zzEcBx+bGPKSg5UUObEyBTacik9oDCNgu cTBjnklSbApJ+4izgLxzAY4qVdCPlJ529/h98LP2Rw36q+JD5yNvvVa4f+N79nDWj2+n rLvhegcO52yqqv98n+Nhx5CsuPWFBKXxSvHocjszVv1gWhmWLqTPHHpg3t6dRgCp3X6j 0tXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770405093; x=1771009893; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=IYenYEMbES7F2pVkYVhENk/YQ/r/YwrlXyRLxNZrVVY=; b=ASMIGb8QCwoaSHD9KflmH/mY6ZTpg6MI1QtQZFn42ZECPlAeFeYizGAqnXwd9cZgKt Vr+J2zHhk9Q0A1fkOlwdfDag1Q8z8A8DgF1UtFPkB/useeK+I+wuPY5hXoEP3h94EPmi DfM21T4/57j3HoGZFS0HXttS9H+0hLgn9C3CSrR/BcpgoIy5hzCZqXxliBRFSOKm2+K8 FaX4VCQW4hchUo022Kutlpe50yJu/zIWCBED3rYc5IcaeAY+JEuXXdf1yV9Vibex57Rs R4cDvgs1tRJahTsVe7nfSgKjChjD423jmWnG+PbmmOuSWooh6TpRejW6SJ92HUpodSHK +z2w== X-Forwarded-Encrypted: i=1; AJvYcCX1+P2/SiDsNDR7MMNhWfUy5uR9QY6jQCbDSMm9LrmQGHbexTXC04WAPz6ycYPDiZDYb0t34UJ+A528c9c=@vger.kernel.org X-Gm-Message-State: AOJu0YxkbXJPQA7mbp3qvDXybQsurcWURp0kJsiOvcQLqGYWFjPbJIL2 LMxixUBBQqj4UoHLidvj6SRnHpaDBQ5sD5pMbqxRRNni4LLdIuf0vpSM X-Gm-Gg: AZuq6aKYx7IBY3vothUsgdPl1TWSl4r7wT/rpvbEkVXrgvK+uXjbGa2kH/PaAiheBsG 9x9aPiM68UbBWQ4ImwX18J0+fN/gPbXDp77WHJyC6ZwwLlLEmOaiOrFAvT0VxKqThzImIajXKwy SVB8JCAp9YfOALfHwdj3UPy/x4TlOysokBQZ2Hl+ginWPB/Qgk2mWYr2x6ysBldQZXY4V5FgZvs 7PxNf4RTWL2Qi6YUR7nWR6y1Qk/s77FnSCpWqUqkmN02AQq0QpeinvJvRzeZgNwA4+UfQxx2tRK 27wmITr4eIPiZ1INO2K+YubSGMHRonjY55Rly7oyIEy8UHU3JyVaIY83a/cSB1YzBht8rh7rHNV 58eKL9F7kMLEHMvTIyQJ5ATDrvKHWBRxhLm9eTaDefdhQHSgaEZwv0KUe02fHKiY0qKzpxKA5tG ddLUwOh43pqgZivEVf3KAtaPrHgj70U+2a8/kjknva2A7rhQ9XF2MUMXdfNLpJ3msHnx8GmYDw X-Received: by 2002:a5d:5f88:0:b0:435:f29d:8c41 with SMTP id ffacd0b85a97d-436293a91aemr6355267f8f.62.1770405092599; Fri, 06 Feb 2026 11:11:32 -0800 (PST) Received: from snowdrop.snailnet.com (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4362972fb81sm8703681f8f.20.2026.02.06.11.11.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Feb 2026 11:11:32 -0800 (PST) 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 v2 next 05/11] tools/nolibc/printf: Simplify __nolibc_printf() Date: Fri, 6 Feb 2026 19:11:15 +0000 Message-Id: <20260206191121.3602-6-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260206191121.3602-1-david.laight.linux@gmail.com> References: <20260206191121.3602-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: 8bit 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. Signed-off-by: David Laight --- Unchanged from v1. tools/include/nolibc/stdio.h | 100 ++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index c044a6b3babe..bb54f488c228 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -250,28 +250,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, va_list args) { - char escape, lpref, ch; + char lpref, ch; unsigned long long v; unsigned int written, width; - size_t len, ofs; + size_t len; char tmpbuf[21]; const char *outstr; - written = ofs = escape = lpref = 0; + written = 0; while (1) { - ch = fmt[ofs++]; + outstr = fmt; + ch = *fmt++; + if (!ch) + break; + width = 0; + if (ch != '%') { + while (*fmt && *fmt != '%') + fmt++; + len = fmt - outstr; + } else { + /* we're in a format sequence */ - if (escape) { - /* we're in an escape sequence, ofs == 1 */ - escape = 0; + ch = *fmt++; /* width */ while (ch >= '0' && ch <= '9') { width *= 10; width += ch - '0'; - ch = fmt[ofs++]; + ch = *fmt++; + } + + /* Length modifiers */ + if (ch == 'l') { + lpref = 1; + ch = *fmt++; + if (ch == 'l') { + lpref = 2; + ch = *fmt++; + } + } else if (ch == 'j') { + /* intmax_t is long long */ + lpref = 2; + ch = *fmt++; + } else { + lpref = 0; } if (ch == 'c' || ch == 'd' || ch == 'u' || ch == 'x' || ch == 'p') { @@ -327,54 +351,32 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list #else outstr = strerror(errno); #endif /* NOLIBC_IGNORE_ERRNO */ - } - else if (ch == '%') { - /* queue it verbatim */ - continue; - } - else { - /* modifiers or final 0 */ - if (ch == 'l') { - /* long format prefix, maintain the escape */ - lpref++; - } else if (ch == 'j') { - lpref = 2; + } else { + if (ch != '%') { + /* Invalid format: back up to output the format characters */ + fmt = outstr + 1; + /* and output a '%' now. */ } - escape = 1; - goto do_escape; + /* %% is documented as a 'conversion specifier'. + * Any flags, precision or length modifier are ignored. + */ + width = 0; + outstr = "%"; } len = strlen(outstr); - goto flush_str; } - /* not an escape sequence */ - if (ch == 0 || ch == '%') { - /* flush pending data on escape or end */ - escape = 1; - lpref = 0; - outstr = fmt; - len = ofs - 1; - flush_str: - while (width > len) { - unsigned int pad_len = ((width - len - 1) & 15) + 1; - width -= pad_len; - written += pad_len; - if (cb(state, " ", pad_len) != 0) - return -1; - } - if (cb(state, outstr, len) != 0) - return -1; + written += len; - written += len; - do_escape: - if (ch == 0) - break; - fmt += ofs; - ofs = 0; - continue; + while (width > len) { + unsigned int pad_len = ((width - len - 1) & 15) + 1; + width -= pad_len; + written += pad_len; + if (cb(state, " ", pad_len) != 0) + return -1; } - - /* literal char, just queue it */ + if (cb(state, outstr, len) != 0) + return -1; } /* Flush/terminate any buffer. */ -- 2.39.5