Date: Mon, 26 Oct 2020 15:02:26 +0100 From: Joerg Schilling <joerg.schill...@fokus.fraunhofer.de> Message-ID: <5f96d6f2.jkFuBT5X4/F/wqwv%joerg.schill...@fokus.fraunhofer.de>
| If the code you are using is from FreeBSD (Garret Damore) Where it originated I don't know for sure, but it has been in the NetBSD source tree since 1993, which I think means it came from a CSRG BSD distribution (the log doesn't indicate explicitly) - after whjch it has had numerous fixes an updates by various NetBSD developers over the (many) years. The code does contain a (no longer used, that is, #if 0 surrounded) sccsid from CSRG: static char sccsid[] = "@(#)printf.c 8.2 (Berkeley) 3/22/95"; but that appeared when 4.4-lite2 was merged in 1997, the original in the NetBSD source tree contained static char sccsid[] = "@(#)printf.c 5.9 (Berkeley) 6/1/90"; if that's any help for you to work out the lineage and/or compare it to the FreeBSD version if that is (for some reason) relevant to anything. But none of this is the issue, our code does the same thing as bosh/bash/dash/yash for the issues in question. Those are related to what the standard actually requires, rather than what any of the current implementations actually does (except in as much as those indicate what the standard should say). The following has absolutely nothing to do with the issue I raised, but since you included it: | The code from bosh has been written from scratch to fully support | %n$ and this is what we should add to the standard in the near future. I'm not sure this is really required in the printf utility, as distinct from the printf (family of) functions, and causes all kinds of issues because of the way the utility reprocesses the format over and over until the args have all been used. Eg: consider printf '%1$d %4$d %2$d\n' 1 2 3 4 5 6 7 8 9 10 11 12 What is supposed to be printed from that? Bosh appears to print 1 4 2 5 8 6 9 12 10 Now consider some other locale (the only reason for supporting this stuff at all is when locales need to print the args in different orders or different actual args, in order to correctly represent the language conventions) where the format string that is used is '%1$d %3$d %2$d\n' With that one, bosh prints 1 3 2 4 6 5 7 9 8 10 12 11 Now it has run the format string 4 times instead of just 3 previously, and has printed all the args, whereas previously it never printed 3 7 or 11. How is this useful? For this, I'm not blaming the bosh printf implementation, given what it is being asked to do, there is very little else that it can do, though in the first example, after args 1 4 and 2 were used, it could have removed them and left 3 5 6 7 8 9 10 11 12 for the next iteration of the format string. I cannot think of a sane use for this, but at least it would end up using all of the args, and always run the format string the same number of times (presuming all formats actually consume the same number of args). The problem really is that where this method was invented, for printf() the function, the format string is only ever used once, if some of the args are never used, they're simply ignored. That can be used in a sensible way. With printf re-using the format string it really can't. One possible solution would be that if any n$ strings appear in the format string conversions, then the format is not restarted, even if all of the args are not consumed. That might make the system workable (as it then makes it equivalent to printf()). But that isn't what bosh does. kre