MSVCRT: Re-implement *printf

Jesse Allen the3dfxdude at
Sat Jan 29 12:35:22 CST 2005

On Fri, 28 Jan 2005 18:18:40 -0700, Jesse Allen <the3dfxdude at> wrote:
> On Fri, 28 Jan 2005 12:48:12 +0000, Aneurin Price 
> >
> > Nobody has any comments about this?
> >
> >
> Sorry for being late at responding.  I took a look at it finally like
> a week ago.  You can definately break up the patch.

Erm,  nevermind on breaking it up yet.  I started to myself, but I
think it's more trouble than it's worth right now.  We can have that
done later if that is what is wanted to have it accepted.

I had another idea to help testing.  I added a comparison test in
_vsnprintf to go ahead and see if there is any difference between libc
and wine by calling libc's version.  If there is a difference, it will
print a warning.  Here's an obvious example in action while running

warn:msvcrt:_vsnprintf -- vsnprintf's differ --
warn:msvcrt:_vsnprintf Wine (20): "-4035225266123964415"
warn:msvcrt:_vsnprintf libc (64): "                                             
warn:msvcrt:_vsnprintf format string: "%I64d"

If we took a look at this, we would find that there is no bug in the
difference, and actually the improvement over libc's version that we
are expecting.  So this warning can be discarded.

If we found another warning, the difference may definately be a bug,
and then it can be fixed when analyzed.  We could also add a
conformance test to make sure it is fixed and doesn't happen again.

Of course this method doesn't help with crashing bugs.  And it makes
vsnprintf *2 slower, but it doesn't matter when we are testing it.

I have a diff below which is against wine CVS + your printf patch.


--- wine/dlls/msvcrt/printf.c   2005-01-29 11:21:54.000000000 -0700
+++ wine-printf/dlls/msvcrt/printf.c    2005-01-29 11:07:23.000000000 -0700
@@ -1134,6 +1134,8 @@
 int _vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
+    char *compare;
+    va_list argptrcpy = argptr;
     /* Since the meaning of type specifiers %S and %s (and C/c) invert
      * depending on whether the function called is *wprintf or *printf,
      * this doesn't simply convert to wide, call _vsnwprintf, and
@@ -1196,6 +1198,19 @@
     WideCharToMultiByte(CP_ACP, 0, out, -1, buffer, count + 1, NULL, NULL);
     HeapFree(GetProcessHeap(), 0, out);
     HeapFree(GetProcessHeap(), 0, in);
+    compare = HeapAlloc(GetProcessHeap(),0,count+1);
+    if (compare != NULL) {
+       int comparePrinted = vsnprintf(compare, count, format, argptrcpy);
+       if (strncmp(compare, buffer, count)!=0) {
+            WARN("-- vsnprintf's differ --\n");
+            WARN("Wine (%d): \"%s\"\n", charsPrinted, buffer);
+            WARN("libc (%d): \"%s\"\n", comparePrinted, compare);
+            WARN("format string: \"%s\"\n", format);
+       }
+       HeapFree(GetProcessHeap(), 0, compare);
+    }
     return charsPrinted;

More information about the wine-devel mailing list