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