From ab1de187e282bde2f19e7a5fd8f20663a474c08f Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 22 Apr 2025 08:06:44 -0500 Subject: [PATCH] Add printf -r NUM to repeat, with -r 0 acting like "yes". (Note: you can't output a NUL byte with yes, but can with printf.) --- toys/posix/printf.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/toys/posix/printf.c b/toys/posix/printf.c index c80e6fe4..d56c9aee 100644 --- a/toys/posix/printf.c +++ b/toys/posix/printf.c @@ -7,21 +7,27 @@ * * TODO: *m$ ala printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec); -USE_PRINTF(NEWTOY(printf, "<1?^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK)) +USE_PRINTF(NEWTOY(printf, "<1?^r#", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK)) config PRINTF bool "printf" default y help - usage: printf FORMAT [ARGUMENT...] + usage: printf [-r COUNT] FORMAT [ARGUMENT...] Format and print ARGUMENT(s) according to FORMAT, using C printf syntax (% escapes for cdeEfgGiosuxX, \ escapes for abefnrtv0 or \OCTAL or \xHEX). + + -r Repeat output COUNT types (0 repeats until killed) */ #define FOR_printf #include "toys.h" +GLOBALS( + long r; +) + // Detect matching character (return true/false) and advance pointer if match. static int chrstart(char **s, char c) { @@ -139,6 +145,12 @@ void printf_main(void) // Posix says to keep looping through format until we consume all args. // This only works if the format actually consumed at least one arg. - if (!seen || !*arg) break; + if (!seen || !*arg) { + if (FLAG(r) && --TT.r) { + f = *toys.optargs; + arg = toys.optargs+1; + if (TT.r<0) TT.r++; + } else break; + } } } -- 2.39.5