dmloader: Mark internal symbols with hidden visibility.
[wine] / dlls / msvcrt / tests / printf.c
1 /*
2  * Conformance tests for *printf functions.
3  *
4  * Copyright 2002 Uwe Bonnes
5  * Copyright 2004 Aneurin Price
6  * Copyright 2005 Mike McCormack
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 /* With Visual Studio >= 2005,  swprintf() takes an extra parameter unless
24  * the following macro is defined.
25  */
26 #define _CRT_NON_CONFORMING_SWPRINTFS
27  
28 #include <stdio.h>
29 #include <errno.h>
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34
35 #include "wine/test.h"
36
37 static int (__cdecl *p__vscprintf)(const char *format, __ms_va_list valist);
38 static int (__cdecl *p__vscwprintf)(const wchar_t *format, __ms_va_list valist);
39 static int (__cdecl *p__vsnwprintf_s)(wchar_t *str, size_t sizeOfBuffer,
40                                       size_t count, const wchar_t *format,
41                                       __ms_va_list valist);
42 static int (__cdecl *p__ecvt_s)(char *buffer, size_t length, double number,
43                                 int ndigits, int *decpt, int *sign);
44 static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number,
45                                 int ndigits, int *decpt, int *sign);
46 static unsigned int (__cdecl *p__get_output_format)(void);
47 static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, __ms_va_list);
48
49 static void init( void )
50 {
51     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
52
53     p__vscprintf = (void *)GetProcAddress(hmod, "_vscprintf");
54     p__vscwprintf = (void *)GetProcAddress(hmod, "_vscwprintf");
55     p__vsnwprintf_s = (void *)GetProcAddress(hmod, "_vsnwprintf_s");
56     p__ecvt_s = (void *)GetProcAddress(hmod, "_ecvt_s");
57     p__fcvt_s = (void *)GetProcAddress(hmod, "_fcvt_s");
58     p__get_output_format = (void *)GetProcAddress(hmod, "_get_output_format");
59     p__vsprintf_p = (void*)GetProcAddress(hmod, "_vsprintf_p");
60 }
61
62 static void test_sprintf( void )
63 {
64     char buffer[100];
65     const char *format;
66     double pnumber=789456123;
67     int x, r;
68     WCHAR wide[] = { 'w','i','d','e',0};
69
70     format = "%+#23.15e";
71     r = sprintf(buffer,format,pnumber);
72     ok(!strcmp(buffer,"+7.894561230000000e+008"),"+#23.15e failed: '%s'\n", buffer);
73     ok( r==23, "return count wrong\n");
74
75     format = "%-#23.15e";
76     r = sprintf(buffer,format,pnumber);
77     ok(!strcmp(buffer,"7.894561230000000e+008 "),"-#23.15e failed: '%s'\n", buffer);
78     ok( r==23, "return count wrong\n");
79
80     format = "%#23.15e";
81     r = sprintf(buffer,format,pnumber);
82     ok(!strcmp(buffer," 7.894561230000000e+008"),"#23.15e failed: '%s'\n", buffer);
83     ok( r==23, "return count wrong\n");
84
85     format = "%#1.1g";
86     r = sprintf(buffer,format,pnumber);
87     ok(!strcmp(buffer,"8.e+008"),"#1.1g failed: '%s'\n", buffer);
88     ok( r==7, "return count wrong\n");
89
90     format = "%I64d";
91     r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff);
92     ok(!strcmp(buffer,"-8589934591"),"Problem with long long\n");
93     ok( r==11, "return count wrong\n");
94
95     format = "%+8I64d";
96     r = sprintf(buffer,format,(LONGLONG)100);
97     ok(!strcmp(buffer,"    +100") && r==8,"+8I64d failed: '%s'\n", buffer);
98
99     format = "%+.8I64d";
100     r = sprintf(buffer,format,(LONGLONG)100);
101     ok(!strcmp(buffer,"+00000100") && r==9,"+.8I64d failed: '%s'\n", buffer);
102
103     format = "%+10.8I64d";
104     r = sprintf(buffer,format,(LONGLONG)100);
105     ok(!strcmp(buffer," +00000100") && r==10,"+10.8I64d failed: '%s'\n", buffer);
106     format = "%_1I64d";
107     r = sprintf(buffer,format,(LONGLONG)100);
108     ok(!strcmp(buffer,"_1I64d") && r==6,"_1I64d failed\n");
109
110     format = "%-1.5I64d";
111     r = sprintf(buffer,format,(LONGLONG)-100);
112     ok(!strcmp(buffer,"-00100") && r==6,"-1.5I64d failed: '%s'\n", buffer);
113
114     format = "%5I64d";
115     r = sprintf(buffer,format,(LONGLONG)100);
116     ok(!strcmp(buffer,"  100") && r==5,"5I64d failed: '%s'\n", buffer);
117
118     format = "%5I64d";
119     r = sprintf(buffer,format,(LONGLONG)-100);
120     ok(!strcmp(buffer," -100") && r==5,"5I64d failed: '%s'\n", buffer);
121
122     format = "%-5I64d";
123     r = sprintf(buffer,format,(LONGLONG)100);
124     ok(!strcmp(buffer,"100  ") && r==5,"-5I64d failed: '%s'\n", buffer);
125
126     format = "%-5I64d";
127     r = sprintf(buffer,format,(LONGLONG)-100);
128     ok(!strcmp(buffer,"-100 ") && r==5,"-5I64d failed: '%s'\n", buffer);
129
130     format = "%-.5I64d";
131     r = sprintf(buffer,format,(LONGLONG)100);
132     ok(!strcmp(buffer,"00100") && r==5,"-.5I64d failed: '%s'\n", buffer);
133
134     format = "%-.5I64d";
135     r = sprintf(buffer,format,(LONGLONG)-100);
136     ok(!strcmp(buffer,"-00100") && r==6,"-.5I64d failed: '%s'\n", buffer);
137
138     format = "%-8.5I64d";
139     r = sprintf(buffer,format,(LONGLONG)100);
140     ok(!strcmp(buffer,"00100   ") && r==8,"-8.5I64d failed: '%s'\n", buffer);
141
142     format = "%-8.5I64d";
143     r = sprintf(buffer,format,(LONGLONG)-100);
144     ok(!strcmp(buffer,"-00100  ") && r==8,"-8.5I64d failed: '%s'\n", buffer);
145
146     format = "%05I64d";
147     r = sprintf(buffer,format,(LONGLONG)100);
148     ok(!strcmp(buffer,"00100") && r==5,"05I64d failed: '%s'\n", buffer);
149
150     format = "%05I64d";
151     r = sprintf(buffer,format,(LONGLONG)-100);
152     ok(!strcmp(buffer,"-0100") && r==5,"05I64d failed: '%s'\n", buffer);
153
154     format = "% I64d";
155     r = sprintf(buffer,format,(LONGLONG)100);
156     ok(!strcmp(buffer," 100") && r==4,"' I64d' failed: '%s'\n", buffer);
157
158     format = "% I64d";
159     r = sprintf(buffer,format,(LONGLONG)-100);
160     ok(!strcmp(buffer,"-100") && r==4,"' I64d' failed: '%s'\n", buffer);
161
162     format = "% 5I64d";
163     r = sprintf(buffer,format,(LONGLONG)100);
164     ok(!strcmp(buffer,"  100") && r==5,"' 5I64d' failed: '%s'\n", buffer);
165
166     format = "% 5I64d";
167     r = sprintf(buffer,format,(LONGLONG)-100);
168     ok(!strcmp(buffer," -100") && r==5,"' 5I64d' failed: '%s'\n", buffer);
169
170     format = "% .5I64d";
171     r = sprintf(buffer,format,(LONGLONG)100);
172     ok(!strcmp(buffer," 00100") && r==6,"' .5I64d' failed: '%s'\n", buffer);
173
174     format = "% .5I64d";
175     r = sprintf(buffer,format,(LONGLONG)-100);
176     ok(!strcmp(buffer,"-00100") && r==6,"' .5I64d' failed: '%s'\n", buffer);
177
178     format = "% 8.5I64d";
179     r = sprintf(buffer,format,(LONGLONG)100);
180     ok(!strcmp(buffer,"   00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer);
181
182     format = "% 8.5I64d";
183     r = sprintf(buffer,format,(LONGLONG)-100);
184     ok(!strcmp(buffer,"  -00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer);
185
186     format = "%.0I64d";
187     r = sprintf(buffer,format,(LONGLONG)0);
188     ok(r==0,".0I64d failed: '%s'\n", buffer);
189
190     format = "%#+21.18I64x";
191     r = sprintf(buffer,format,(LONGLONG)-100);
192     ok(!strcmp(buffer," 0x00ffffffffffffff9c") && r==21,"#+21.18I64x failed: '%s'\n", buffer);
193
194     format = "%#.25I64o";
195     r = sprintf(buffer,format,(LONGLONG)-100);
196     ok(!strcmp(buffer,"0001777777777777777777634") && r==25,"#.25I64o failed: '%s'\n", buffer);
197
198     format = "%#+24.20I64o";
199     r = sprintf(buffer,format,(LONGLONG)-100);
200     ok(!strcmp(buffer," 01777777777777777777634") && r==24,"#+24.20I64o failed: '%s'\n", buffer);
201
202     format = "%#+18.21I64X";
203     r = sprintf(buffer,format,(LONGLONG)-100);
204     ok(!strcmp(buffer,"0X00000FFFFFFFFFFFFFF9C") && r==23,"#+18.21I64X failed: '%s '\n", buffer);
205
206     format = "%#+20.24I64o";
207     r = sprintf(buffer,format,(LONGLONG)-100);
208     ok(!strcmp(buffer,"001777777777777777777634") && r==24,"#+20.24I64o failed: '%s'\n", buffer);
209
210     format = "%#+25.22I64u";
211     r = sprintf(buffer,format,(LONGLONG)-1);
212     ok(!strcmp(buffer,"   0018446744073709551615") && r==25,"#+25.22I64u conversion failed: '%s'\n", buffer);
213
214     format = "%#+25.22I64u";
215     r = sprintf(buffer,format,(LONGLONG)-1);
216     ok(!strcmp(buffer,"   0018446744073709551615") && r==25,"#+25.22I64u failed: '%s'\n", buffer);
217
218     format = "%#+30.25I64u";
219     r = sprintf(buffer,format,(LONGLONG)-1);
220     ok(!strcmp(buffer,"     0000018446744073709551615") && r==30,"#+30.25I64u failed: '%s'\n", buffer);
221
222     format = "%+#25.22I64d";
223     r = sprintf(buffer,format,(LONGLONG)-1);
224     ok(!strcmp(buffer,"  -0000000000000000000001") && r==25,"+#25.22I64d failed: '%s'\n", buffer);
225
226     format = "%#-8.5I64o";
227     r = sprintf(buffer,format,(LONGLONG)100);
228     ok(!strcmp(buffer,"00144   ") && r==8,"-8.5I64o failed: '%s'\n", buffer);
229
230     format = "%#-+ 08.5I64d";
231     r = sprintf(buffer,format,(LONGLONG)100);
232     ok(!strcmp(buffer,"+00100  ") && r==8,"'#-+ 08.5I64d failed: '%s'\n", buffer);
233
234     format = "%#-+ 08.5I64d";
235     r = sprintf(buffer,format,(LONGLONG)100);
236     ok(!strcmp(buffer,"+00100  ") && r==8,"#-+ 08.5I64d failed: '%s'\n", buffer);
237
238     format = "%.80I64d";
239     r = sprintf(buffer,format,(LONGLONG)1);
240     ok(r==80,"%s format failed\n", format);
241
242     format = "% .80I64d";
243     r = sprintf(buffer,format,(LONGLONG)1);
244     ok(r==81,"%s format failed\n", format);
245
246     format = "% .80d";
247     r = sprintf(buffer,format,1);
248     ok(r==81,"%s format failed\n", format);
249
250     format = "%lld";
251     r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff);
252     ok( r == 1 || r == 11, "return count wrong %d\n", r);
253     if (r == 11)  /* %ll works on Vista */
254         ok(!strcmp(buffer, "-8589934591"), "Problem with \"ll\" interpretation '%s'\n", buffer);
255     else
256         ok(!strcmp(buffer, "1"), "Problem with \"ll\" interpretation '%s'\n", buffer);
257
258     format = "%I";
259     r = sprintf(buffer,format,1);
260     ok(!strcmp(buffer, "I"), "Problem with \"I\" interpretation\n");
261     ok( r==1, "return count wrong\n");
262
263     format = "%I0d";
264     r = sprintf(buffer,format,1);
265     ok(!strcmp(buffer,"I0d"),"I0d failed\n");
266     ok( r==3, "return count wrong\n");
267
268     format = "%I32d";
269     r = sprintf(buffer,format,1);
270     if (r == 1)
271     {
272         ok(!strcmp(buffer,"1"),"I32d failed, got '%s'\n",buffer);
273     }
274     else
275     {
276         /* Older versions don't grok I32 format */
277         ok(r == 4 && !strcmp(buffer,"I32d"),"I32d failed, got '%s',%d\n",buffer,r);
278     }
279
280     format = "%I64D";
281     r = sprintf(buffer,format,(LONGLONG)-1);
282     ok(!strcmp(buffer,"D"),"I64D failed: %s\n",buffer);
283     ok( r==1, "return count wrong\n");
284
285     format = "% d";
286     r = sprintf(buffer,format,1);
287     ok(!strcmp(buffer, " 1"),"Problem with sign place-holder: '%s'\n",buffer);
288     ok( r==2, "return count wrong\n");
289
290     format = "%+ d";
291     r = sprintf(buffer,format,1);
292     ok(!strcmp(buffer, "+1"),"Problem with sign flags: '%s'\n",buffer);
293     ok( r==2, "return count wrong\n");
294
295     format = "%S";
296     r = sprintf(buffer,format,wide);
297     ok(!strcmp(buffer,"wide"),"Problem with wide string format\n");
298     ok( r==4, "return count wrong\n");
299
300     format = "%04c";
301     r = sprintf(buffer,format,'1');
302     ok(!strcmp(buffer,"0001"),"Character not zero-prefixed \"%s\"\n",buffer);
303     ok( r==4, "return count wrong\n");
304
305     format = "%-04c";
306     r = sprintf(buffer,format,'1');
307     ok(!strcmp(buffer,"1   "),"Character zero-padded and/or not left-adjusted \"%s\"\n",buffer);
308     ok( r==4, "return count wrong\n");
309
310     if (sizeof(void *) == 8)
311     {
312         format = "%p";
313         r = sprintf(buffer,format,(void *)57);
314         ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
315         ok( r==16, "return count wrong\n");
316
317         format = "%#020p";
318         r = sprintf(buffer,format,(void *)57);
319         ok(!strcmp(buffer,"  0X0000000000000039"),"Pointer formatted incorrectly\n");
320         ok( r==20, "return count wrong\n");
321
322         format = "%Fp";
323         r = sprintf(buffer,format,(void *)57);
324         ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
325         ok( r==16, "return count wrong\n");
326
327         format = "%#-020p";
328         r = sprintf(buffer,format,(void *)57);
329         ok(!strcmp(buffer,"0X0000000000000039  "),"Pointer formatted incorrectly\n");
330         ok( r==20, "return count wrong\n");
331     }
332     else
333     {
334         format = "%p";
335         r = sprintf(buffer,format,(void *)57);
336         ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
337         ok( r==8, "return count wrong\n");
338
339         format = "%#012p";
340         r = sprintf(buffer,format,(void *)57);
341         ok(!strcmp(buffer,"  0X00000039"),"Pointer formatted incorrectly\n");
342         ok( r==12, "return count wrong\n");
343
344         format = "%Fp";
345         r = sprintf(buffer,format,(void *)57);
346         ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
347         ok( r==8, "return count wrong\n");
348
349         format = "%#-012p";
350         r = sprintf(buffer,format,(void *)57);
351         ok(!strcmp(buffer,"0X00000039  "),"Pointer formatted incorrectly\n");
352         ok( r==12, "return count wrong\n");
353     }
354
355     format = "%04s";
356     r = sprintf(buffer,format,"foo");
357     ok(!strcmp(buffer,"0foo"),"String not zero-prefixed \"%s\"\n",buffer);
358     ok( r==4, "return count wrong\n");
359
360     format = "%.1s";
361     r = sprintf(buffer,format,"foo");
362     ok(!strcmp(buffer,"f"),"Precision ignored \"%s\"\n",buffer);
363     ok( r==1, "return count wrong\n");
364
365     format = "%.*s";
366     r = sprintf(buffer,format,1,"foo");
367     ok(!strcmp(buffer,"f"),"Precision ignored \"%s\"\n",buffer);
368     ok( r==1, "return count wrong\n");
369
370     format = "%*s";
371     r = sprintf(buffer,format,-5,"foo");
372     ok(!strcmp(buffer,"foo  "),"Negative field width ignored \"%s\"\n",buffer);
373     ok( r==5, "return count wrong\n");
374
375     format = "hello";
376     r = sprintf(buffer, format);
377     ok(!strcmp(buffer,"hello"), "failed\n");
378     ok( r==5, "return count wrong\n");
379
380     format = "%ws";
381     r = sprintf(buffer, format, wide);
382     ok(!strcmp(buffer,"wide"), "failed\n");
383     ok( r==4, "return count wrong\n");
384
385     format = "%-10ws";
386     r = sprintf(buffer, format, wide );
387     ok(!strcmp(buffer,"wide      "), "failed\n");
388     ok( r==10, "return count wrong\n");
389
390     format = "%10ws";
391     r = sprintf(buffer, format, wide );
392     ok(!strcmp(buffer,"      wide"), "failed\n");
393     ok( r==10, "return count wrong\n");
394
395     format = "%#+ -03whlls";
396     r = sprintf(buffer, format, wide );
397     ok(!strcmp(buffer,"wide"), "failed\n");
398     ok( r==4, "return count wrong\n");
399
400     format = "%w0s";
401     r = sprintf(buffer, format, wide );
402     ok(!strcmp(buffer,"0s"), "failed\n");
403     ok( r==2, "return count wrong\n");
404
405     format = "%w-s";
406     r = sprintf(buffer, format, wide );
407     ok(!strcmp(buffer,"-s"), "failed\n");
408     ok( r==2, "return count wrong\n");
409
410     format = "%ls";
411     r = sprintf(buffer, format, wide );
412     ok(!strcmp(buffer,"wide"), "failed\n");
413     ok( r==4, "return count wrong\n");
414
415     format = "%Ls";
416     r = sprintf(buffer, format, "not wide" );
417     ok(!strcmp(buffer,"not wide"), "failed\n");
418     ok( r==8, "return count wrong\n");
419
420     format = "%b";
421     r = sprintf(buffer, format);
422     ok(!strcmp(buffer,"b"), "failed\n");
423     ok( r==1, "return count wrong\n");
424
425     format = "%3c";
426     r = sprintf(buffer, format,'a');
427     ok(!strcmp(buffer,"  a"), "failed\n");
428     ok( r==3, "return count wrong\n");
429
430     format = "%3d";
431     r = sprintf(buffer, format,1234);
432     ok(!strcmp(buffer,"1234"), "failed\n");
433     ok( r==4, "return count wrong\n");
434
435     format = "%3h";
436     r = sprintf(buffer, format);
437     ok(!strcmp(buffer,""), "failed\n");
438     ok( r==0, "return count wrong\n");
439
440     format = "%j%k%m%q%r%t%v%y%z";
441     r = sprintf(buffer, format);
442     ok(!strcmp(buffer,"jkmqrtvyz"), "failed\n");
443     ok( r==9, "return count wrong\n");
444
445     format = "asdf%n";
446     x = 0;
447     r = sprintf(buffer, format, &x );
448     if (r == -1)
449     {
450         /* %n format is disabled by default on vista */
451         /* FIXME: should test with _set_printf_count_output */
452         ok(x == 0, "should not write to x: %d\n", x);
453     }
454     else
455     {
456         ok(x == 4, "should write to x: %d\n", x);
457         ok(!strcmp(buffer,"asdf"), "failed\n");
458         ok( r==4, "return count wrong: %d\n", r);
459     }
460
461     format = "%-1d";
462     r = sprintf(buffer, format,2);
463     ok(!strcmp(buffer,"2"), "failed\n");
464     ok( r==1, "return count wrong\n");
465
466     format = "%2.4f";
467     r = sprintf(buffer, format,8.6);
468     ok(!strcmp(buffer,"8.6000"), "failed\n");
469     ok( r==6, "return count wrong\n");
470
471     format = "%0f";
472     r = sprintf(buffer, format,0.6);
473     ok(!strcmp(buffer,"0.600000"), "failed\n");
474     ok( r==8, "return count wrong\n");
475
476     format = "%.0f";
477     r = sprintf(buffer, format,0.6);
478     ok(!strcmp(buffer,"1"), "failed\n");
479     ok( r==1, "return count wrong\n");
480
481     format = "%2.4e";
482     r = sprintf(buffer, format,8.6);
483     ok(!strcmp(buffer,"8.6000e+000"), "failed\n");
484     ok( r==11, "return count wrong\n");
485
486     format = "%2.4g";
487     r = sprintf(buffer, format,8.6);
488     ok(!strcmp(buffer,"8.6"), "failed\n");
489     ok( r==3, "return count wrong\n");
490
491     format = "%-i";
492     r = sprintf(buffer, format,-1);
493     ok(!strcmp(buffer,"-1"), "failed\n");
494     ok( r==2, "return count wrong\n");
495
496     format = "%-i";
497     r = sprintf(buffer, format,1);
498     ok(!strcmp(buffer,"1"), "failed\n");
499     ok( r==1, "return count wrong\n");
500
501     format = "%+i";
502     r = sprintf(buffer, format,1);
503     ok(!strcmp(buffer,"+1"), "failed\n");
504     ok( r==2, "return count wrong\n");
505
506     format = "%o";
507     r = sprintf(buffer, format,10);
508     ok(!strcmp(buffer,"12"), "failed\n");
509     ok( r==2, "return count wrong\n");
510
511     format = "%p";
512     r = sprintf(buffer, format,0);
513     if (sizeof(void *) == 8)
514     {
515         ok(!strcmp(buffer,"0000000000000000"), "failed\n");
516         ok( r==16, "return count wrong\n");
517     }
518     else
519     {
520         ok(!strcmp(buffer,"00000000"), "failed\n");
521         ok( r==8, "return count wrong\n");
522     }
523
524     format = "%s";
525     r = sprintf(buffer, format,0);
526     ok(!strcmp(buffer,"(null)"), "failed\n");
527     ok( r==6, "return count wrong\n");
528
529     format = "%s";
530     r = sprintf(buffer, format,"%%%%");
531     ok(!strcmp(buffer,"%%%%"), "failed\n");
532     ok( r==4, "return count wrong\n");
533
534     format = "%u";
535     r = sprintf(buffer, format,-1);
536     ok(!strcmp(buffer,"4294967295"), "failed\n");
537     ok( r==10, "return count wrong\n");
538
539     format = "%w";
540     r = sprintf(buffer, format,-1);
541     ok(!strcmp(buffer,""), "failed\n");
542     ok( r==0, "return count wrong\n");
543
544     format = "%h";
545     r = sprintf(buffer, format,-1);
546     ok(!strcmp(buffer,""), "failed\n");
547     ok( r==0, "return count wrong\n");
548
549     format = "%z";
550     r = sprintf(buffer, format,-1);
551     ok(!strcmp(buffer,"z"), "failed\n");
552     ok( r==1, "return count wrong\n");
553
554     format = "%j";
555     r = sprintf(buffer, format,-1);
556     ok(!strcmp(buffer,"j"), "failed\n");
557     ok( r==1, "return count wrong\n");
558
559     format = "%F";
560     r = sprintf(buffer, format,-1);
561     ok(!strcmp(buffer,""), "failed\n");
562     ok( r==0, "return count wrong\n");
563
564     format = "%H";
565     r = sprintf(buffer, format,-1);
566     ok(!strcmp(buffer,"H"), "failed\n");
567     ok( r==1, "return count wrong\n");
568
569     format = "x%cx";
570     r = sprintf(buffer, format, 0x100+'X');
571     ok(!strcmp(buffer,"xXx"), "failed\n");
572     ok( r==3, "return count wrong\n");
573
574     format = "%%0";
575     r = sprintf(buffer, format);
576     ok(!strcmp(buffer,"%0"), "failed: \"%s\"\n", buffer);
577     ok( r==2, "return count wrong\n");
578 }
579
580 static void test_swprintf( void )
581 {
582     wchar_t buffer[100];
583     const wchar_t I64d[] = {'%','I','6','4','d',0};
584     double pnumber=789456123;
585     const wchar_t TwentyThreePoint15e[]= {'%','+','#','2','3','.','1','5','e',0};
586     const wchar_t e008[] = {'e','+','0','0','8',0};
587     const wchar_t string_w[] = {'s','t','r','i','n','g',0};
588     const char string[] = "string";
589     const wchar_t S[]={'%','S',0};
590     const wchar_t hs[] = {'%', 'h', 's', 0};
591
592     swprintf(buffer,TwentyThreePoint15e,pnumber);
593     ok(wcsstr(buffer,e008) != 0,"Sprintf different\n");
594     swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff);
595       ok(wcslen(buffer) == 11,"Problem with long long\n");
596     swprintf(buffer,S,string);
597       ok(wcslen(buffer) == 6,"Problem with \"%%S\" interpretation\n");
598    swprintf(buffer, hs, string);
599    ok( wcscmp(string_w,buffer) == 0, "swprintf failed with %%hs\n");
600 }
601
602 static void test_snprintf (void)
603 {
604     struct snprintf_test {
605         const char *format;
606         int expected;
607     };
608     /* Pre-2.1 libc behaviour, not C99 compliant. */
609     const struct snprintf_test tests[] = {{"short", 5},
610                                           {"justfit", 7},
611                                           {"justfits", 8},
612                                           {"muchlonger", -1}};
613     char buffer[8];
614     const int bufsiz = sizeof buffer;
615     unsigned int i;
616
617     for (i = 0; i < sizeof tests / sizeof tests[0]; i++) {
618         const char *fmt  = tests[i].format;
619         const int expect = tests[i].expected;
620         const int n      = _snprintf (buffer, bufsiz, fmt);
621         const int valid  = n < 0 ? bufsiz : (n == bufsiz ? n : n+1);
622
623         ok (n == expect, "\"%s\": expected %d, returned %d\n",
624             fmt, expect, n);
625         ok (!memcmp (fmt, buffer, valid),
626             "\"%s\": rendered \"%.*s\"\n", fmt, valid, buffer);
627     };
628 }
629
630 static void test_fprintf(void)
631 {
632     static char file_name[] = "fprintf.tst";
633     FILE *fp = fopen(file_name, "wb");
634     char buf[1024];
635     int ret;
636
637     ret = fprintf(fp, "simple test\n");
638     ok(ret == 12, "ret = %d\n", ret);
639     ret = ftell(fp);
640     ok(ret == 12, "ftell returned %d\n", ret);
641
642     ret = fprintf(fp, "contains%cnull\n", '\0');
643     ok(ret == 14, "ret = %d\n", ret);
644     ret = ftell(fp);
645     ok(ret == 26, "ftell returned %d\n", ret);
646
647     fclose(fp);
648
649     fp = fopen(file_name, "rb");
650     ret = fscanf(fp, "%[^\n] ", buf);
651     ok(ret == 1, "ret = %d\n", ret);
652     ret = ftell(fp);
653     ok(ret == 12, "ftell returned %d\n", ret);
654     ok(!strcmp(buf, "simple test"), "buf = %s\n", buf);
655
656     fgets(buf, sizeof(buf), fp);
657     ret = ftell(fp);
658     ok(ret == 26, "ret = %d\n", ret);
659     ok(!memcmp(buf, "contains\0null\n", 14), "buf = %s\n", buf);
660
661     fclose(fp);
662     unlink(file_name);
663 }
664
665 static void test_fcvt(void)
666 {
667     char *str;
668     int dec=100, sign=100;
669     
670     /* Numbers less than 1.0 with different precisions */
671     str = _fcvt(0.0001, 1, &dec, &sign );
672     ok( 0 == strcmp(str,""), "bad return '%s'\n", str);
673     ok( -3 == dec, "dec wrong %d\n", dec);
674     ok( 0 == sign, "sign wrong\n");
675
676     str = _fcvt(0.0001, -10, &dec, &sign );
677     ok( 0 == strcmp(str,""), "bad return '%s'\n", str);
678     ok( -3 == dec, "dec wrong %d\n", dec);
679     ok( 0 == sign, "sign wrong\n");
680
681     str = _fcvt(0.0001, 10, &dec, &sign );
682     ok( 0 == strcmp(str,"1000000"), "bad return '%s'\n", str);
683     ok( -3 == dec, "dec wrong %d\n", dec);
684     ok( 0 == sign, "sign wrong\n");
685
686     /* Basic sign test */
687     str = _fcvt(-111.0001, 5, &dec, &sign );
688     ok( 0 == strcmp(str,"11100010"), "bad return '%s'\n", str);
689     ok( 3 == dec, "dec wrong %d\n", dec);
690     ok( 1 == sign, "sign wrong\n");
691
692     str = _fcvt(111.0001, 5, &dec, &sign );
693     ok( 0 == strcmp(str,"11100010"), "bad return '%s'\n", str);
694     ok( 3 == dec, "dec wrong\n");
695     ok( 0 == sign, "sign wrong\n");
696
697     /* 0.0 with different precisions */
698     str = _fcvt(0.0, 5, &dec, &sign );
699     ok( 0 == strcmp(str,"00000"), "bad return '%s'\n", str);
700     ok( 0 == dec, "dec wrong %d\n", dec);
701     ok( 0 == sign, "sign wrong\n");
702
703     str = _fcvt(0.0, 0, &dec, &sign );
704     ok( 0 == strcmp(str,""), "bad return '%s'\n", str);
705     ok( 0 == dec, "dec wrong %d\n", dec);
706     ok( 0 == sign, "sign wrong\n");
707
708     str = _fcvt(0.0, -1, &dec, &sign );
709     ok( 0 == strcmp(str,""), "bad return '%s'\n", str);
710     ok( 0 == dec, "dec wrong %d\n", dec);
711     ok( 0 == sign, "sign wrong\n");
712
713     /* Numbers > 1.0 with 0 or -ve precision */
714     str = _fcvt(-123.0001, 0, &dec, &sign );
715     ok( 0 == strcmp(str,"123"), "bad return '%s'\n", str);
716     ok( 3 == dec, "dec wrong %d\n", dec);
717     ok( 1 == sign, "sign wrong\n");
718
719     str = _fcvt(-123.0001, -1, &dec, &sign );
720     ok( 0 == strcmp(str,"12"), "bad return '%s'\n", str);
721     ok( 3 == dec, "dec wrong %d\n", dec);
722     ok( 1 == sign, "sign wrong\n");
723
724     str = _fcvt(-123.0001, -2, &dec, &sign );
725     ok( 0 == strcmp(str,"1"), "bad return '%s'\n", str);
726     ok( 3 == dec, "dec wrong %d\n", dec);
727     ok( 1 == sign, "sign wrong\n");
728
729     str = _fcvt(-123.0001, -3, &dec, &sign );
730     ok( 0 == strcmp(str,""), "bad return '%s'\n", str);
731     ok( 3 == dec, "dec wrong %d\n", dec);
732     ok( 1 == sign, "sign wrong\n");
733
734     /* Numbers > 1.0, but with rounding at the point of precision */
735     str = _fcvt(99.99, 1, &dec, &sign );
736     ok( 0 == strcmp(str,"1000"), "bad return '%s'\n", str);
737     ok( 3 == dec, "dec wrong %d\n", dec);
738     ok( 0 == sign, "sign wrong\n");
739
740     /* Numbers < 1.0 where rounding occurs at the point of precision */
741     str = _fcvt(0.00636, 2, &dec, &sign );
742     ok( 0 == strcmp(str,"1"), "bad return '%s'\n", str);
743     ok( -1 == dec, "dec wrong %d\n", dec);
744     ok( 0 == sign, "sign wrong\n");
745
746     str = _fcvt(0.00636, 3, &dec, &sign );
747     ok( 0 == strcmp(str,"6"), "bad return '%s'\n", str);
748     ok( -2 == dec, "dec wrong %d\n", dec);
749     ok( 0 == sign, "sign wrong\n");
750
751     str = _fcvt(0.09999999996, 2, &dec, &sign );
752     ok( 0 == strcmp(str,"10"), "bad return '%s'\n", str);
753     ok( 0 == dec, "dec wrong %d\n", dec);
754     ok( 0 == sign, "sign wrong\n");
755
756     str = _fcvt(0.6, 0, &dec, &sign );
757     ok( 0 == strcmp(str,"1"), "bad return '%s'\n", str);
758     ok( 1 == dec, "dec wrong %d\n", dec);
759     ok( 0 == sign, "sign wrong\n");
760 }
761
762 /* Don't test nrdigits < 0, msvcrt on Win9x and NT4 will corrupt memory by
763  * writing outside allocated memory */
764 static struct {
765     double value;
766     int nrdigits;
767     const char *expstr_e;
768     const char *expstr_f;
769     int expdecpt_e;
770     int expdecpt_f;
771     int expsign;
772 } test_cvt_testcases[] = {
773     {          45.0,   2,        "45",           "4500",          2,      2,      0 },
774     /* Numbers less than 1.0 with different precisions */
775     {        0.0001,   1,         "1",               "",         -3,     -3,     0 },
776     {        0.0001,  10,"1000000000",        "1000000",         -3,     -3,     0 },
777     /* Basic sign test */
778     {     -111.0001,   5,     "11100",       "11100010",          3,      3,     1 },
779     {      111.0001,   5,     "11100",       "11100010",          3,      3,     0 },
780     /* big numbers with low precision */
781     {        3333.3,   2,        "33",         "333330",          4,      4,     0 },
782     {999999999999.9,   3,       "100","999999999999900",         13,     12,     0 },
783     /* 0.0 with different precisions */
784     {           0.0,   5,     "00000",          "00000",          0,      0,     0 },
785     {           0.0,   0,          "",               "",          0,      0,     0 },
786     {           0.0,  -1,          "",               "",          0,      0,     0 },
787     /* Numbers > 1.0 with 0 or -ve precision */
788     {     -123.0001,   0,          "",            "123",          3,      3,     1 },
789     {     -123.0001,  -1,          "",             "12",          3,      3,     1 },
790     {     -123.0001,  -2,          "",              "1",          3,      3,     1 },
791     {     -123.0001,  -3,          "",               "",          3,      3,     1 },
792     /* Numbers > 1.0, but with rounding at the point of precision */
793     {         99.99,   1,         "1",           "1000",          3,      3,     0 },
794     /* Numbers < 1.0 where rounding occurs at the point of precision */
795     {        0.0063,   2,        "63",              "1",         -2,     -1,     0 },
796     {        0.0063,   3,        "630",             "6",         -2,     -2,     0 },
797     { 0.09999999996,   2,        "10",             "10",          0,      0,     0 },
798     {           0.6,   1,         "6",              "6",          0,      0,     0 },
799     {           0.6,   0,          "",              "1",          1,      1,     0 },
800     {           0.4,   0,          "",               "",          0,      0,     0 },
801     {          0.49,   0,          "",               "",          0,      0,     0 },
802     {          0.51,   0,          "",              "1",          1,      1,     0 },
803     /* ask for ridiculous precision, ruin formatting this table */
804     {           1.0,  30, "100000000000000000000000000000",
805                       "1000000000000000000000000000000",          1,      1,      0},
806     {           123456789012345678901.0,  30, "123456789012345680000000000000",
807                       "123456789012345680000000000000000000000000000000000",         21,    21,      0},
808     /* end marker */
809     { 0, 0, "END"}
810 };
811
812 static void test_xcvt(void)
813 {
814     char *str;
815     int i, decpt, sign, err;
816
817     for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){
818         decpt = sign = 100;
819         str = _ecvt( test_cvt_testcases[i].value,
820                 test_cvt_testcases[i].nrdigits,
821                 &decpt,
822                 &sign);
823         ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15),
824                "_ecvt() bad return, got \n'%s' expected \n'%s'\n", str,
825               test_cvt_testcases[i].expstr_e);
826         ok( decpt == test_cvt_testcases[i].expdecpt_e,
827                 "_ecvt() decimal point wrong, got %d expected %d\n", decpt,
828                 test_cvt_testcases[i].expdecpt_e);
829         ok( sign == test_cvt_testcases[i].expsign,
830                 "_ecvt() sign wrong, got %d expected %d\n", sign,
831                 test_cvt_testcases[i].expsign);
832     }
833     for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){
834         decpt = sign = 100;
835         str = _fcvt( test_cvt_testcases[i].value,
836                 test_cvt_testcases[i].nrdigits,
837                 &decpt,
838                 &sign);
839         ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15),
840                "_fcvt() bad return, got \n'%s' expected \n'%s'\n", str,
841               test_cvt_testcases[i].expstr_f);
842         ok( decpt == test_cvt_testcases[i].expdecpt_f,
843                 "_fcvt() decimal point wrong, got %d expected %d\n", decpt,
844                 test_cvt_testcases[i].expdecpt_f);
845         ok( sign == test_cvt_testcases[i].expsign,
846                 "_fcvt() sign wrong, got %d expected %d\n", sign,
847                 test_cvt_testcases[i].expsign);
848     }
849
850     if (p__ecvt_s)
851     {
852         str = malloc(1024);
853         for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){
854             decpt = sign = 100;
855             err = p__ecvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign);
856             ok(err == 0, "_ecvt_s() failed with error code %d\n", err);
857             ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15),
858                    "_ecvt_s() bad return, got \n'%s' expected \n'%s'\n", str,
859                   test_cvt_testcases[i].expstr_e);
860             ok( decpt == test_cvt_testcases[i].expdecpt_e,
861                     "_ecvt_s() decimal point wrong, got %d expected %d\n", decpt,
862                     test_cvt_testcases[i].expdecpt_e);
863             ok( sign == test_cvt_testcases[i].expsign,
864                     "_ecvt_s() sign wrong, got %d expected %d\n", sign,
865                     test_cvt_testcases[i].expsign);
866         }
867         free(str);
868     }
869     else
870         win_skip("_ecvt_s not available\n");
871
872     if (p__fcvt_s)
873     {
874         int i;
875
876         str = malloc(1024);
877
878         /* invalid arguments */
879         err = p__fcvt_s(NULL, 0, 0.0, 0, &i, &i);
880         ok(err == EINVAL, "got %d, expected EINVAL\n", err);
881
882         err = p__fcvt_s(str, 0, 0.0, 0, &i, &i);
883         ok(err == EINVAL, "got %d, expected EINVAL\n", err);
884
885         str[0] = ' ';
886         str[1] = 0;
887         err = p__fcvt_s(str, -1, 0.0, 0, &i, &i);
888         ok(err == 0, "got %d, expected 0\n", err);
889         ok(str[0] == 0, "got %c, expected 0\n", str[0]);
890         ok(str[1] == 0, "got %c, expected 0\n", str[1]);
891
892         err = p__fcvt_s(str, 1, 0.0, 0, NULL, &i);
893         ok(err == EINVAL, "got %d, expected EINVAL\n", err);
894
895         err = p__fcvt_s(str, 1, 0.0, 0, &i, NULL);
896         ok(err == EINVAL, "got %d, expected EINVAL\n", err);
897
898         for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){
899             decpt = sign = 100;
900             err = p__fcvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign);
901             ok(err == 0, "_fcvt_s() failed with error code %d\n", err);
902             ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15),
903                    "_fcvt_s() bad return, got '%s' expected '%s'. test %d\n", str,
904                   test_cvt_testcases[i].expstr_f, i);
905             ok( decpt == test_cvt_testcases[i].expdecpt_f,
906                     "_fcvt_s() decimal point wrong, got %d expected %d\n", decpt,
907                     test_cvt_testcases[i].expdecpt_f);
908             ok( sign == test_cvt_testcases[i].expsign,
909                     "_fcvt_s() sign wrong, got %d expected %d\n", sign,
910                     test_cvt_testcases[i].expsign);
911         }
912         free(str);
913     }
914     else
915         win_skip("_fcvt_s not available\n");
916 }
917
918 static int __cdecl _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...)
919 {
920     int ret;
921     __ms_va_list valist;
922     __ms_va_start(valist, format);
923     ret = _vsnwprintf(str, len, format, valist);
924     __ms_va_end(valist);
925     return ret;
926 }
927
928 static void test_vsnwprintf(void)
929 {
930     const wchar_t format[] = {'%','w','s','%','w','s','%','w','s',0};
931     const wchar_t one[]    = {'o','n','e',0};
932     const wchar_t two[]    = {'t','w','o',0};
933     const wchar_t three[]  = {'t','h','r','e','e',0};
934
935     int ret;
936     wchar_t str[32];
937     char buf[32];
938
939     ret = _vsnwprintf_wrapper( str, sizeof(str)/sizeof(str[0]), format, one, two, three );
940
941     ok( ret == 11, "got %d expected 11\n", ret );
942     WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL );
943     ok( !strcmp(buf, "onetwothree"), "got %s expected 'onetwothree'\n", buf );
944 }
945
946 static int __cdecl _vscprintf_wrapper(const char *format, ...)
947 {
948     int ret;
949     __ms_va_list valist;
950     __ms_va_start(valist, format);
951     ret = p__vscprintf(format, valist);
952     __ms_va_end(valist);
953     return ret;
954 }
955
956 static void test_vscprintf(void)
957 {
958     int ret;
959
960     if (!p__vscprintf)
961     {
962        win_skip("_vscprintf not available\n");
963        return;
964     }
965
966     ret = _vscprintf_wrapper( "%s %d", "number", 1 );
967     ok( ret == 8, "got %d expected 8\n", ret );
968 }
969
970 static int __cdecl _vscwprintf_wrapper(const wchar_t *format, ...)
971 {
972     int ret;
973     __ms_va_list valist;
974     __ms_va_start(valist, format);
975     ret = p__vscwprintf(format, valist);
976     __ms_va_end(valist);
977     return ret;
978 }
979
980 static void test_vscwprintf(void)
981 {
982     const wchar_t format[] = {'%','s',' ','%','d',0};
983     const wchar_t number[] = {'n','u','m','b','e','r',0};
984
985     int ret;
986
987     if (!p__vscwprintf)
988     {
989         win_skip("_vscwprintf not available\n");
990         return;
991     }
992
993     ret = _vscwprintf_wrapper( format, number, 1 );
994     ok( ret == 8, "got %d expected 8\n", ret );
995 }
996
997 static int __cdecl _vsnwprintf_s_wrapper(wchar_t *str, size_t sizeOfBuffer,
998                                  size_t count, const wchar_t *format, ...)
999 {
1000     int ret;
1001     __ms_va_list valist;
1002     __ms_va_start(valist, format);
1003     ret = p__vsnwprintf_s(str, sizeOfBuffer, count, format, valist);
1004     __ms_va_end(valist);
1005     return ret;
1006 }
1007
1008 static void test_vsnwprintf_s(void)
1009 {
1010     const wchar_t format[] = { 'A','B','%','u','C',0 };
1011     const wchar_t out7[] = { 'A','B','1','2','3','C',0 };
1012     const wchar_t out6[] = { 'A','B','1','2','3',0 };
1013     const wchar_t out2[] = { 'A',0 };
1014     const wchar_t out1[] = { 0 };
1015     wchar_t buffer[14] = { 0 };
1016     int exp, got;
1017
1018     if (!p__vsnwprintf_s)
1019     {
1020         win_skip("_vsnwprintf_s not available\n");
1021         return;
1022     }
1023
1024     /* Enough room. */
1025     exp = wcslen(out7);
1026
1027     got = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, format, 123);
1028     ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got);
1029     ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
1030
1031     got = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, format, 123);
1032     ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got);
1033     ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
1034
1035     got = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, format, 123);
1036     ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got);
1037     ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
1038
1039     /* Not enough room. */
1040     exp = -1;
1041
1042     got = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, format, 123);
1043     ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got);
1044     ok( !wcscmp(out6, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
1045
1046     got = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, format, 123);
1047     ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got);
1048     ok( !wcscmp(out2, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
1049
1050     got = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, format, 123);
1051     ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got);
1052     ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
1053 }
1054
1055 static int __cdecl _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer,
1056                                  const char *format, ...)
1057 {
1058     int ret;
1059     __ms_va_list valist;
1060     __ms_va_start(valist, format);
1061     ret = p__vsprintf_p(str, sizeOfBuffer, format, valist);
1062     __ms_va_end(valist);
1063     return ret;
1064 }
1065
1066 static void test_vsprintf_p(void)
1067 {
1068     char buf[1024];
1069     int ret;
1070
1071     if(!p__vsprintf_p) {
1072         win_skip("vsprintf_p not available\n");
1073         return;
1074     }
1075
1076     ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%s %d", "test", 1234);
1077     ok(ret == 9, "ret = %d\n", ret);
1078     ok(!memcmp(buf, "test 1234", 10), "buf = %s\n", buf);
1079
1080     ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%1$d", 1234, "additional param");
1081     ok(ret == 4, "ret = %d\n", ret);
1082     ok(!memcmp(buf, "1234", 5), "buf = %s\n", buf);
1083
1084     ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%2$s %1$d", 1234, "test");
1085     ok(ret == 9, "ret = %d\n", ret);
1086     ok(!memcmp(buf, "test 1234", 10), "buf = %s\n", buf);
1087
1088     ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%2$*3$s %2$.*1$s", 2, "test", 3);
1089     ok(ret == 7, "ret = %d\n", ret);
1090     ok(!memcmp(buf, "test te", 8), "buf = %s\n", buf);
1091
1092     /* Following test invokes invalid parameter handler */
1093     /* ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%d %1$d", 1234); */
1094 }
1095
1096 static void test__get_output_format(void)
1097 {
1098     unsigned int ret;
1099
1100     if (!p__get_output_format)
1101     {
1102         win_skip("_get_output_format not available\n");
1103         return;
1104     }
1105
1106     ret = p__get_output_format();
1107     ok(ret == 0, "got %d\n", ret);
1108 }
1109
1110 START_TEST(printf)
1111 {
1112     init();
1113
1114     test_sprintf();
1115     test_swprintf();
1116     test_snprintf();
1117     test_fprintf();
1118     test_fcvt();
1119     test_xcvt();
1120     test_vsnwprintf();
1121     test_vscprintf();
1122     test_vscwprintf();
1123     test_vsnwprintf_s();
1124     test_vsprintf_p();
1125     test__get_output_format();
1126 }