On Sat, Feb 22, 2025 at 9:49 AM Andreas Schwab <sch...@linux-m68k.org> wrote:
> On Feb 22 2025, Phi Debian wrote: > > > I forgot to mention your trick to nuke the fmt reuse still works > > > > $ printf '%s %s %s %999$s' A B C D E F G > > A B C > > As long as NL_ARGMAX >= 999. > Sounds like I was over optimistic $ echo $KSH_VERSION Version AJM 93u+m/1.1.0-alpha+b5087279 2025-01-15 $ printf '%s %s %999$s\n' 1 2 3 4 5 6 7 8 1 2 $ unset A B C D E F G H $ printf '%s %s %999$s\n' A B C D E F G H ./ksh: printf: C: parameter not set ./ksh: printf: D: parameter not set ./ksh: printf: E: parameter not set ./ksh: printf: F: parameter not set ./ksh: printf: G: parameter not set ./ksh: printf: H: parameter not set A B $ I admit I didn't entered a way big arg index (exceeding the actual number of args) in the QA suite for ksh93, will do soon, along with a fix to avoid such wrong error output. $ getconf NL_ARGMAX 4096 The idea to nuke fmt re-use is to use a index arg number bigger then the expected number of args, and if unknown got for the max :-) Thanx for raising this... But here we are talking bash 'possible' implementation of printf fmt indexed args access, and I wanted to share what I did for ksh93, kind of heads up of pitfall to watch out. So the implementation make '%s %s %s' as '%(seq++)s %(seq++)s %(seq++)' with (seq) a theorical syntax don't exist in reality. The problem that led me to go with seq++ access of unumbered args, i.e internally treat them as numbered in seq++ is that mix'n'match of numbered/unumbered not only occurs for each % but inside them i.e '%s %2% %s' is mix'n'match for % but indexed access also occurs in width.prec as Unnumbered $ printf '%*s\n' 2 4 4 numbered (works as documented in sprintf(3) ) $ printf '%2$*1$s\n' 2 4 4 Mix'n'match UGLY, don't use, but if you insist printf '%2$*s\n' 2 4 6 8 4 8 Here the arg value is indexed at 2$ but the width is not (unumbered), so here with 'my' implementation treat this like '%2$*(seq++)$s\n' really fetching the correct width, yet an explicit *1$ is much preferable. With an implementation (as was ksh93 when it was plain bugged) the unumbered would be next to last index and would be similar to %2$*3$s and would not work. By applying the rule (seq++) for any unumbered not only it works (in the sense produce something predictable), and it goes along with ftm reuse nicely. So this was my best guess for something that was ugly from the start, i.e mixin numbered/unumbered. The other approach consisting of refusing mix'n'match is more complicated internally, because it force a double pass on fmt string, while the seq++ just walk produce thing (not necessarilly to yourt liking) and is predictable. This this the reflexion that led me to this implementation...