Re: [HACKERS] snprintf causes regression tests to fail

Nicolai Tufar <[email protected]>
Newsgroups gmane.comp.db.postgresql.devel.win32
Message-ID <[email protected]>
> Having looked at the current snprintf.c, I don't actually believe that
> it works at all in the presence of positional parameter specs.  It picks
> up the arguments in the order they are mentioned in the format string,
> which is exactly not what it's supposed to do, if I understand the
> concept of positional specifiers properly.  This is certain to give the
> wrong answers when the arguments are of different widths.

It picks up arguments in order of appearance, places them in
array then shuffles them according to %n$ positional parameter.
I checked it with in many different combinations, it works!

> I'm also less than thrilled with the 300K+ local array ;-).  I don't see
> any point in saving the width specs from the first pass to the second
> when they are not needed in the first pass.  NL_ARGMAX could have a more
> sane value (surely not more than a couple hundred) and we need some
> checks that it's not exceeded in any case.  On the other side of the
> coin, the hardwired 4K limit in printf() is certainly *not* enough.

How would one solve this issue. Calling malloc() from a print function
would be rather expensive. Maybe call snprintf() from printf() and
see if resulting string is 4K long then allocate a new buffer and
call snprintf() again? And by the way, what should I use malloc()
or palloc()?

What would you think will be a good value for NL_ARGMAX?

> I think a correct implementation is probably a three-pass affair:
> 
> 1. Scan format string to determine the basic datatypes (int, float, char*,
> etc) of each actual parameter and their positions.  Note that runtime
> width and precision specs have to be counted as actual parameters.
> 
> 2. Perform the va_arg() fetches in position order, and stash the actual
> parameter values into a local array.

I actually do it. But in one step. I left the scanning loop in place 
but replaced calls to actual printing functions with code to fill
the array, preserving width and precision. Plus I store pointers
to beginning and endings of format placeholders to not to have 
to scan format string again in the next step.

> 3. Rescan format string and do the outputting.

My version: reorder the array and do the outputting.
/* shuffle pointers */ comment in source is misleading,
it should have been /* reorder pointers */.

> I don't offhand see what is making the regression tests fail (it's not
> the above because the problem occurs with a nonpositional format string);
> but there's not much point in trying to get rid of porting issues when
> the fundamental algorithm is wrong.

I believe my algorithm is working and it is faster than your proposed algorithm.
But if it is not acceptable I am willing to change as deemed necessary. I tested
the function separately and it passed regression tests on many platforms.
Situation with win32 is really unusual. We may need a win32 and MinGG internals
guru to have a look a the issue.

>                       regards, tom lane
Nicolai Tufar

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
      joining column's datatypes do not match
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.