Bug #321: dlls/msvct/vf[w]printf functions (Patch 2)

Jaco Greeff jaco at puxedo.org
Tue Oct 29 00:25:30 CST 2002

Alexandre Julliard wrote:
> - you can't use the libc printf to print unicode chars, the format is
>   not the same

Umm, I'm not and if I am, I should be shot. The logic behind what I'm 
doing is more or less as follows:

1. Print all non-formatting characters to file;
2. Parse the formatting string, converting between %S and %s.
3. Print the formatting string with arguments, converting the unicode 
strings via WideStringToMultiByte;

So yes, the strings will be converted before being printed since I'm 
printing them via the %s formatting specifier. (And the test code 
results does show that this is indeed the case)

> - WideCharToMultiByte can output several characters for a single
>   unicode char, you need to take that into account for buffer sizes

*grumble* Thanks. I'm now making now that I get the length of the result 
string via WideCharToMultiByte before allocating and filling the buffer 
with another call to WideCharToString. Initially I thought that a 
strlenW would suffice, obviously not.

> - you cannot cast a WCHAR* into a CHAR* to convert the format to ASCII

You had me stumped here for a while as to where I'm doing this 
stupidity. A search brought this up:

case (WCHAR)L'd':
case (WCHAR)L'i':
case (WCHAR)L'o':
case (WCHAR)L'u':
case (WCHAR)L'X':
case (WCHAR)L'x':
     pFormat->nType = VFMT_INTEGER;
     strncat(pFormat->szFmt, (CHAR *)szFmt, 1);

I want to grab the last formatting char and append it to my buffer. Now 
I could do,

case (WCHAR)L'u':
     pFormat->nType = VFMT_INTEGER;
     strcat(pFormat->szFmt, "u");
case (WCHAR)L'X':
     pFormat->nType = VFMT_INTEGER;
     strcat(pFormat->szFmt, "X");
case (WCHAR)L'x':
     pFormat->nType = VFMT_INTEGER;
     strcat(pFormat->szFmt, "x");

for every instance, which problably is more readable/understandable (and 
the way I had it before I "optimized" a bit :)). What I did put down in 
the first instance however, does work as intended since I'm only 
interrested in the first byte/character pointed to by the szFmt pointer. 
If "sizeof(CHAR) != 1" and "arch != ix86" then we are in trouble here. 
However, you are right, it is problably confusing and will make 
maintenance a bitch.

> - there's no point in using strncat if you don't pass it the real size
>   of the buffer

As I'm building up the format string, I'm using it to append only the 
current formatting character to the buffer I'll eventually be using to 
print. A suggestion for a better approach is always welcome.

> - please don't copy code from MSDN, it is copyrighted by Microsoft.

I won't include the test case in the next patch. As a real wine test 
case I'm anyway not sure of the full value, as a debugging tool and 
making sure that I get the correct output, it is extremely valuable.


More information about the wine-devel mailing list