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


Reply via email to