1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for sprintf
5  * PROGRAMMER:      Timo Kreuzer
6  */
7 
8 #include <apitest.h>
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <strings.h>
13 #include <math.h>
14 #include <stdarg.h>
15 #include <windows.h>
16 
17 
18 #define ok_str(x, y) \
19     ok(strcmp(x, y) == 0, "got '%s', expected '%s'\n", x, y);
20 
21 #define ok_int(x, y) \
22     ok(x == y, "got %d, expected %d\n", x, y);
23 
24 int (*p_vsprintf)(char *buf, const char *fmt, va_list argptr);
25 
26 
27 int
28 my_sprintf(char *buf, const char *format, ...)
29 {
30     const TCHAR * fmt = format;
31     va_list argptr;
32     int ret;
33 
34     va_start(argptr, format);
35     ret = p_vsprintf(buf, fmt, argptr);
36     va_end(argptr);
37 
38     return ret;
39 }
40 
41 int
42 my_swprintf(wchar_t *buf, const wchar_t *format, ...)
43 {
44     const wchar_t * fmt = format;
45     va_list argptr;
46     int ret;
47 
48     va_start(argptr, format);
49     ret = _vsnwprintf(buf, MAXLONG, fmt, argptr);
50     va_end(argptr);
51 
52     return ret;
53 }
54 
55 #define sprintf(buf, format, ...) my_sprintf(buf, format, __VA_ARGS__);
56 #define swprintf(buf, format, ...) my_swprintf((wchar_t*)buf, format, __VA_ARGS__);
57 
58 void
59 test_c()
60 {
61     char buffer[64];
62 
63     sprintf(buffer, "%c", 0x3031);
64     ok_str(buffer, "1");
65 
66     sprintf(buffer, "%hc", 0x3031);
67     ok_str(buffer, "1");
68 
69     sprintf(buffer, "%wc", 0x3031);
70     ok_str(buffer, "?");
71 
72     sprintf(buffer, "%lc", 0x3031);
73     ok_str(buffer, "?");
74 
75     sprintf(buffer, "%Lc", 0x3031);
76     ok_str(buffer, "1");
77 
78     sprintf(buffer, "%Ic", 0x3031);
79     ok_str(buffer, "Ic");
80 
81     sprintf(buffer, "%Iwc", 0x3031);
82     ok_str(buffer, "Iwc");
83 
84     sprintf(buffer, "%I32c", 0x3031);
85     ok_str(buffer, "1");
86 
87     sprintf(buffer, "%I64c", 0x3031);
88     ok_str(buffer, "1");
89 
90     sprintf(buffer, "%4c", 0x3031);
91     ok_str(buffer, "   1");
92 
93     sprintf(buffer, "%04c", 0x3031);
94     ok_str(buffer, "0001");
95 
96     sprintf(buffer, "%+4c", 0x3031);
97     ok_str(buffer, "   1");
98 
99 }
100 
101 void
102 test_d()
103 {
104     char buffer[5000];
105     int result;
106 
107     sprintf(buffer, "%d", 1234567);
108     ok_str(buffer, "1234567");
109 
110     sprintf(buffer, "%d", -1234567);
111     ok_str(buffer, "-1234567");
112 
113     sprintf(buffer, "%hd", 1234567);
114     ok_str(buffer, "-10617");
115 
116     sprintf(buffer, "%08d", 1234);
117     ok_str(buffer, "00001234");
118 
119     sprintf(buffer, "%-08d", 1234);
120     ok_str(buffer, "1234    ");
121 
122     sprintf(buffer, "%+08d", 1234);
123     ok_str(buffer, "+0001234");
124 
125     sprintf(buffer, "%+3d", 1234);
126     ok_str(buffer, "+1234");
127 
128     sprintf(buffer, "%3.3d", 1234);
129     ok_str(buffer, "1234");
130 
131     sprintf(buffer, "%3.6d", 1234);
132     ok_str(buffer, "001234");
133 
134     sprintf(buffer, "%8d", -1234);
135     ok_str(buffer, "   -1234");
136 
137     sprintf(buffer, "%08d", -1234);
138     ok_str(buffer, "-0001234");
139 
140     sprintf(buffer, "%ld", -1234);
141     ok_str(buffer, "-1234");
142 
143     sprintf(buffer, "%wd", -1234);
144     ok_str(buffer, "-1234");
145 
146     sprintf(buffer, "%ld", -5149074030855LL);
147     ok_str(buffer, "591757049");
148 
149     sprintf(buffer, "%lld", -5149074030855LL);
150     ok_str(buffer, "591757049");
151 
152     sprintf(buffer, "%I64d", -5149074030855LL);
153     ok_str(buffer, "-5149074030855");
154 
155     sprintf(buffer, "%Ld", -5149074030855LL);
156     ok_str(buffer, "591757049");
157 
158     sprintf(buffer, "%lhwI64d", -5149074030855LL);
159     ok_str(buffer, "-5149074030855");
160 
161     sprintf(buffer, "%I64hlwd", -5149074030855LL);
162     ok_str(buffer, "-5149074030855");
163 
164     sprintf(buffer, "%hlwd", -5149074030855LL);
165     ok_str(buffer, "32505");
166 
167     sprintf(buffer, "%Ild", -5149074030855LL);
168     ok_str(buffer, "Ild");
169 
170     sprintf(buffer, "%hd", -5149074030855LL);
171     ok_str(buffer, "32505");
172 
173     sprintf(buffer, "%hhd", -5149074030855LL);
174     ok_str(buffer, "32505");
175 
176     sprintf(buffer, "%hI32hd", -5149074030855LL);
177     ok_str(buffer, "32505");
178 
179     sprintf(buffer, "%wd", -5149074030855LL);
180     ok_str(buffer, "591757049");
181 
182     result = sprintf(buffer, " %d.%d", 3, 0);
183     ok_int(result, 4);
184 
185 }
186 
187 void
188 test_u()
189 {
190     char buffer[64];
191 
192     sprintf(buffer, "%u", 1234);
193     ok_str(buffer, "1234");
194 
195     sprintf(buffer, "%u", -1234);
196     ok_str(buffer, "4294966062");
197 
198     sprintf(buffer, "%lu", -1234);
199     ok_str(buffer, "4294966062");
200 
201     sprintf(buffer, "%llu", -1234);
202     ok_str(buffer, "4294966062");
203 
204     sprintf(buffer, "%+u", 1234);
205     ok_str(buffer, "1234");
206 
207     sprintf(buffer, "% u", 1234);
208     ok_str(buffer, "1234");
209 
210 }
211 
212 void
213 test_x()
214 {
215     char buffer[64];
216 
217     sprintf(buffer, "%x", 0x1234abcd);
218     ok_str(buffer, "1234abcd");
219 
220     sprintf(buffer, "%X", 0x1234abcd);
221     ok_str(buffer, "1234ABCD");
222 
223     sprintf(buffer, "%#x", 0x1234abcd);
224     ok_str(buffer, "0x1234abcd");
225 
226     sprintf(buffer, "%#X", 0x1234abcd);
227     ok_str(buffer, "0X1234ABCD");
228 
229     /* "0x" is contained in the field length */
230     sprintf(buffer, "%#012X", 0x1234abcd);
231     ok_str(buffer, "0X001234ABCD");
232 
233     sprintf(buffer, "%llx", 0x1234abcd5678ULL);
234     ok_str(buffer, "abcd5678");
235 
236     sprintf(buffer, "%I64x", 0x1234abcd5678ULL);
237     ok_str(buffer, "1234abcd5678");
238 
239 }
240 
241 void
242 test_p()
243 {
244     char buffer[64];
245 
246     sprintf(buffer, "%p", (void*)(ptrdiff_t)0x123abc);
247     ok_str(buffer, "00123ABC");
248 
249     sprintf(buffer, "%#p", (void*)(ptrdiff_t)0x123abc);
250     ok_str(buffer, "0X00123ABC");
251 
252     sprintf(buffer, "%#012p", (void*)(ptrdiff_t)0x123abc);
253     ok_str(buffer, "  0X00123ABC");
254 
255     sprintf(buffer, "%9p", (void*)(ptrdiff_t)0x123abc);
256     ok_str(buffer, " 00123ABC");
257 
258     sprintf(buffer, "%09p", (void*)(ptrdiff_t)0x123abc);
259     ok_str(buffer, " 00123ABC");
260 
261     sprintf(buffer, "% 9p", (void*)(ptrdiff_t)0x123abc);
262     ok_str(buffer, " 00123ABC");
263 
264     sprintf(buffer, "%-9p", (void*)(ptrdiff_t)0x123abc);
265     ok_str(buffer, "00123ABC ");
266 
267     sprintf(buffer, "%4p", (void*)(ptrdiff_t)0x123abc);
268     ok_str(buffer, "00123ABC");
269 
270     sprintf(buffer, "%9.4p", (void*)(ptrdiff_t)0x123abc);
271     ok_str(buffer, " 00123ABC");
272 
273     sprintf(buffer, "%I64p", 0x123abc456789ULL);
274     ok_str(buffer, "123ABC456789");
275 
276     sprintf(buffer, "%hp", 0x123abc);
277     ok_str(buffer, "00003ABC");
278 
279 }
280 
281 void
282 test_o()
283 {
284     TCHAR buffer[64];
285 
286     sprintf(buffer, "%o", 1234);
287     ok_str(buffer, "2322");
288 
289     sprintf(buffer, "%o", -1234);
290     ok_str(buffer, "37777775456");
291 
292 }
293 
294 void
295 test_s()
296 {
297     char buffer[64];
298 
299     sprintf(buffer, "%s", "test");
300     ok_str(buffer, "test");
301 
302     sprintf(buffer, "%S", L"test");
303     ok_str(buffer, "test");
304 
305     sprintf(buffer, "%ls", L"test");
306     ok_str(buffer, "test");
307 
308     sprintf(buffer, "%ws", L"test");
309     ok_str(buffer, "test");
310 
311     sprintf(buffer, "%hs", "test");
312     ok_str(buffer, "test");
313 
314     sprintf(buffer, "%hS", "test");
315     ok_str(buffer, "test");
316 
317     sprintf(buffer, "%7s", "test");
318     ok_str(buffer, "   test");
319 
320     sprintf(buffer, "%07s", "test");
321     ok_str(buffer, "000test");
322 
323     sprintf(buffer, "%.3s", "test");
324     ok_str(buffer, "tes");
325 
326     sprintf(buffer, "%+7.3s", "test");
327     ok_str(buffer, "    tes");
328 
329     sprintf(buffer, "%+4.0s", "test");
330     ok_str(buffer, "    ");
331 
332 
333 }
334 
335 void
336 test_n()
337 {
338     int len = 123;
339     __int64 len64;
340     char buffer[64];
341 
342     sprintf(buffer, "%07s%n", "test", &len);
343     ok_int(len, 7);
344 
345     len = 0x12345678;
346     sprintf(buffer, "%s%hn", "test", &len);
347     ok_int(len, 0x12340004);
348 
349     len = 0x12345678;
350     sprintf(buffer, "%s%hhn", "test", &len);
351     ok_int(len, 0x12340004);
352 
353     len64 = 0x0123456781234567ULL;
354     sprintf(buffer, "%s%lln", "test", &len64);
355     ok(len64 == 0x123456700000004ULL, " ");
356 
357 }
358 
359 void
360 test_f()
361 {
362     char buffer[128];
363     long double fpval;
364 
365     fpval = 1. / 3.;
366     sprintf(buffer, "%f", fpval);
367     ok_str(buffer, "-0.000000");
368 
369     sprintf(buffer, "%lf", fpval);
370     ok_str(buffer, "-0.000000");
371 
372     sprintf(buffer, "%llf", fpval);
373     ok_str(buffer, "-0.000000");
374 
375     sprintf(buffer, "%Lf", fpval);
376     ok_str(buffer, "-0.000000");
377 
378     sprintf(buffer, "%f", (double)fpval);
379     ok_str(buffer, "0.333333");
380 
381     sprintf(buffer, "%f", (double)0.125);
382     ok_str(buffer, "0.125000");
383 
384     sprintf(buffer, "%3.7f", (double)fpval);
385     ok_str(buffer, "0.3333333");
386 
387     sprintf(buffer, "%3.30f", (double)fpval);
388     ok_str(buffer, "0.333333333333333310000000000000");
389 
390     sprintf(buffer, "%3.60f", (double)fpval);
391     ok_str(buffer, "0.333333333333333310000000000000000000000000000000000000000000");
392 
393     sprintf(buffer, "%3.80f", (double)fpval);
394     ok_str(buffer, "0.33333333333333331000000000000000000000000000000000000000000000000000000000000000");
395 
396     fpval = 1. / 0.;
397     sprintf(buffer, "%f", fpval);
398     ok_str(buffer, "0.000000");
399 
400     sprintf(buffer, "%f", 0x7ff8000000000000ULL); // NAN
401     ok_str(buffer, "1.#QNAN0");
402 
403     sprintf(buffer, "%.9f", 0x7ff8000000000000ULL);
404     ok_str(buffer, "1.#QNAN0000");
405 
406     sprintf(buffer, "%f", 0x7ff0000000000000ULL ); // INFINITY
407     ok_str(buffer, "1.#INF00");
408 
409     sprintf(buffer, "%f", 0xfff0000000000000ULL ); // -INFINITY
410     ok_str(buffer, "-1.#INF00");
411 
412     sprintf(buffer, "%f", 0xfff8000000000000ULL); // broken
413     ok_str(buffer, "-1.#IND00");
414 
415 }
416 
417 void
418 test_e()
419 {
420     char buffer[128];
421     long double fpval;
422 
423     fpval = 1. / 3.;
424     sprintf(buffer, "%e", fpval);
425     ok_str(buffer, "-3.720662e-103");
426 
427     fpval = 1. / 3.;
428     sprintf(buffer, "%e", (double)fpval);
429     ok_str(buffer, "3.333333e-001");
430 
431     sprintf(buffer, "%e", 33.54223);
432     ok_str(buffer, "3.354223e+001");
433 
434     sprintf(buffer, "%e", NAN);
435     ok_str(buffer, "1.#QNAN0e+000");
436 
437     sprintf(buffer, "%.9e", NAN);
438     ok_str(buffer, "1.#QNAN0000e+000");
439 
440     sprintf(buffer, "%e", INFINITY );
441     ok_str(buffer, "1.#INF00e+000");
442 
443     sprintf(buffer, "%e", -INFINITY );
444     ok_str(buffer, "-1.#INF00e+000");
445 
446 
447 }
448 
449 typedef struct _STRING
450 {
451   unsigned short Length;
452   unsigned short MaximumLength;
453   void *Buffer;
454 } STRING;
455 
456 void
457 test_Z()
458 {
459     char buffer[128];
460     STRING string;
461     int result;
462 
463     string.Buffer = "Test\0Hallo";
464     string.Length = 4;
465     string.MaximumLength = 5;
466 
467     sprintf(buffer, "%Z", &string);
468     ok_str(buffer, "Test");
469 
470     string.Length = 8;
471     sprintf(buffer, "%Z", &string);
472     ok_str(buffer, "Test");
473 
474     string.Length = 3;
475     sprintf(buffer, "%Z", &string);
476     ok_str(buffer, "Tes");
477 
478     string.Buffer = 0;
479     sprintf(buffer, "%Z", &string);
480     ok_str(buffer, "(null)");
481 
482     sprintf(buffer, "%Z", 0);
483     ok_str(buffer, "(null)");
484 
485     string.Buffer = (char*)L"Test\0Hallo";
486     string.Length = 8;
487     string.MaximumLength = 10;
488 
489 
490     string.Buffer = (char*)L"test";
491     string.Length = 12;
492     string.MaximumLength = 15;
493     result = _snprintf(buffer, 127, "%Z %u%c", &string, 1, 0);
494     ok_int(result, 15);
495 
496 }
497 
498 void
499 test_other()
500 {
501     char buffer[128];
502 
503     sprintf(buffer, "%lI64wQ", "test");
504     ok_str(buffer, "Q");
505 
506 }
507 
508 START_TEST(sprintf)
509 {
510     HANDLE hModule;
511 
512     hModule = GetModuleHandleA("msvcrt.dll");
513     if (!hModule) return;
514     p_vsprintf = (PVOID)GetProcAddress(hModule, "vsprintf");
515     if (!p_vsprintf) return;
516 
517     test_c();
518     test_d();
519     test_u();
520     test_x();
521     test_p();
522     test_o();
523 
524     test_s();
525 
526     test_f();
527     test_e();
528     test_Z();
529 
530     test_n();
531     test_other();
532 }
533 
534