tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Fwd: Re: fmtcheck() query



On 2017/12/11 23:17, Valery Ushakov wrote:
Due to this statement of SUS (it is found also in SUSv4
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html),
it is quite inconvenient to neglect some arguments *intentionally* in
the framework of printf(3); Missing some arguments in format strings
should probably be a mistake. I therefore agree with the current
behavior.

I guess the reason behind that requirement must be the fact that it's
not possible to skip arguments with va_arg().  So e.g. for "%3$s %1$d"
you wouldn't know how to get to the third argument as there's no type
info for the second: is it a 4-byte int, or 8-byte pointer, or 8-byte
double, etc.

Likewise it's obviously ok (technically) to ignore trailing args, you
just never move va_arg() that far into the argument list and there's
no problem with that.

I got it. Without specifying the lengths of 1st to (N-1)th args, it's
not possible to obtain the N-th argument. On the other hand, the
trailing args can be neglected safely.

OTOH, we can't tell if the format misses some arguments intentionally.
May be the call site added a new argument and the template message is
now updated to use it, but the translated message was not yet updated
and you'd obviously like to know about that.  This may be a flag
argument, I guess.

I'm still not sure whether unused trailing args should be neglected or
not. Unfortunately, fmtcheck(3) does not accept additional flags, and
it does not seem a good idea to me to increase similar non-standard
functions in libc...

On 2017/12/12 10:32, Robert Elz wrote:
   | OTOH, we can't tell if the format misses some arguments intentionally.

I don't think that's fmtcheck's job.   Its purpose is (or should be) to
make sure the program does not mis-use the args (print some part of a
floating value as if it were a pointer...) rather than that it is perfect.

There are good reasons why args might want to be omitted sometimes, and
I think that should really be supported (trailing args particularly.)

Well, I examined all the usages of fmtcheck(3) in our tree. (Sorry, I
must do this before I committed the "fix".) At the moment, we have only
four callers. Among them, only

- file

expected that fmtcheck(3) neglects unused trailing args (actually, each
format string takes one argument at most). This has already been fixed by
christos (and ryoon for the pkgsrc version). On the other hand, other
three examples,

- man
- libusbhid
- regress test of libevent

are cases where it is more convenient if fmtcheck(3) rigorously check
unused args. And it should also be useful when we check message catalogs.

These examples may be insufficient to conclude that unused args should
be accused. However, what situations do you expect? The example of
file(1) is enough for you? Am I missing something again?

On 2017/12/11 23:17, Valery Ushakov wrote:
I don't remember why the code complains if the tempalte refers to the
same argument multiple times.  I guess I was too lazy to make sure the
two references are compatible.

It should be allowed, as long as types are consistent, since SUSv4 says:

     "In format strings containing the "%n$" form of conversion
     specification, numbered arguments in the argument list can be
     referenced from the format string as many times as required."

Right, note that the code did not complain about multiple references
in the format, only in the template.  As I said, the original context
this code was written in was checking commands in man.conf, so it's a
bit different from the l10n context, where you have an English message
that is both a format used to actually print something and as a
template used to check translated messages.  In the man.conf case
there's simply no such prototype that is both a format and a template,
so there the template is purely something you supply to fmtcheck() to
tell it what the printf args will be.  In this kind of setup the
template will most likely be a straight sequential format without any
widths or extra formatting, not to mentioned positional arguments.
And, as I said, I was just lazy, so I just stuck that check there
("yeah, i remember about this case"), but made it punt.

Yeah, I belatedly read the source of man(1) and understood for what
purpose it uses fmtcheck(3).

Let us back to the original topic, how fmtcheck(3) be.  I think it
should be replaced by that based on printf_checkformat().

I'm obviously partial here.  But as long as I don't have to commit and
maintain it ... (did i mention i'm lazy? :)

Well. Of course, I'll take care of it if we can achieve some reasonable
agreement :-).

Thanks,
rin


Home | Main Index | Thread Index | Old Index