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 27 #include "precomp.h" 28 29 static inline float __port_infinity(void) 30 { 31 static const unsigned __inf_bytes = 0x7f800000; 32 return *(const float *)&__inf_bytes; 33 } 34 #define INFINITY __port_infinity() 35 36 static inline float __port_nan(void) 37 { 38 static const unsigned __nan_bytes = 0x7fc00000; 39 return *(const float *)&__nan_bytes; 40 } 41 #define NAN __port_nan() 42 43 static inline float __port_ind(void) 44 { 45 static const unsigned __ind_bytes = 0xffc00000; 46 return *(const float *)&__ind_bytes; 47 } 48 #define IND __port_ind() 49 50 static int (__cdecl *p__vscprintf)(const char *format, __ms_va_list valist); 51 static int (__cdecl *p__vscwprintf)(const wchar_t *format, __ms_va_list valist); 52 static int (__cdecl *p__vsnwprintf_s)(wchar_t *str, size_t sizeOfBuffer, 53 size_t count, const wchar_t *format, 54 __ms_va_list valist); 55 static int (__cdecl *p__ecvt_s)(char *buffer, size_t length, double number, 56 int ndigits, int *decpt, int *sign); 57 static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number, 58 int ndigits, int *decpt, int *sign); 59 static unsigned int (__cdecl *p__get_output_format)(void); 60 static unsigned int (__cdecl *p__set_output_format)(unsigned int); 61 static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, __ms_va_list); 62 static int (__cdecl *p_vswprintf)(wchar_t *str, const wchar_t *format, __ms_va_list valist); 63 static int (__cdecl *p__vswprintf)(wchar_t *str, const wchar_t *format, __ms_va_list valist); 64 static int (__cdecl *p__vswprintf_l)(wchar_t *str, const wchar_t *format, 65 void *locale, __ms_va_list valist); 66 static int (__cdecl *p__vswprintf_c)(wchar_t *str, size_t size, const wchar_t *format, 67 __ms_va_list valist); 68 static int (__cdecl *p__vswprintf_c_l)(wchar_t *str, size_t size, const wchar_t *format, 69 void *locale, __ms_va_list valist); 70 static int (__cdecl *p__vswprintf_p_l)(wchar_t *str, size_t size, const wchar_t *format, 71 void *locale, __ms_va_list valist); 72 73 static void init( void ) 74 { 75 HMODULE hmod = GetModuleHandleA("msvcrt.dll"); 76 77 p__vscprintf = (void *)GetProcAddress(hmod, "_vscprintf"); 78 p__vscwprintf = (void *)GetProcAddress(hmod, "_vscwprintf"); 79 p__vsnwprintf_s = (void *)GetProcAddress(hmod, "_vsnwprintf_s"); 80 p__ecvt_s = (void *)GetProcAddress(hmod, "_ecvt_s"); 81 p__fcvt_s = (void *)GetProcAddress(hmod, "_fcvt_s"); 82 p__get_output_format = (void *)GetProcAddress(hmod, "_get_output_format"); 83 p__set_output_format = (void *)GetProcAddress(hmod, "_set_output_format"); 84 p__vsprintf_p = (void*)GetProcAddress(hmod, "_vsprintf_p"); 85 p_vswprintf = (void*)GetProcAddress(hmod, "vswprintf"); 86 p__vswprintf = (void*)GetProcAddress(hmod, "_vswprintf"); 87 p__vswprintf_l = (void*)GetProcAddress(hmod, "_vswprintf_l"); 88 p__vswprintf_c = (void*)GetProcAddress(hmod, "_vswprintf_c"); 89 p__vswprintf_c_l = (void*)GetProcAddress(hmod, "_vswprintf_c_l"); 90 p__vswprintf_p_l = (void*)GetProcAddress(hmod, "_vswprintf_p_l"); 91 } 92 93 static void test_sprintf( void ) 94 { 95 char buffer[100]; 96 const char *format; 97 double pnumber=789456123; 98 int x, r; 99 WCHAR wide[] = { 'w','i','d','e',0}; 100 101 format = "%+#23.15e"; 102 r = sprintf(buffer,format,pnumber); 103 ok(!strcmp(buffer,"+7.894561230000000e+008"),"+#23.15e failed: '%s'\n", buffer); 104 ok( r==23, "return count wrong\n"); 105 106 format = "%-#23.15e"; 107 r = sprintf(buffer,format,pnumber); 108 ok(!strcmp(buffer,"7.894561230000000e+008 "),"-#23.15e failed: '%s'\n", buffer); 109 ok( r==23, "return count wrong\n"); 110 111 format = "%#23.15e"; 112 r = sprintf(buffer,format,pnumber); 113 ok(!strcmp(buffer," 7.894561230000000e+008"),"#23.15e failed: '%s'\n", buffer); 114 ok( r==23, "return count wrong\n"); 115 116 format = "%#1.1g"; 117 r = sprintf(buffer,format,pnumber); 118 ok(!strcmp(buffer,"8.e+008"),"#1.1g failed: '%s'\n", buffer); 119 ok( r==7, "return count wrong\n"); 120 121 format = "%I64d"; 122 r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); 123 ok(!strcmp(buffer,"-8589934591"),"Problem with long long\n"); 124 ok( r==11, "return count wrong\n"); 125 126 format = "%+8I64d"; 127 r = sprintf(buffer,format,(LONGLONG)100); 128 ok(!strcmp(buffer," +100") && r==8,"+8I64d failed: '%s'\n", buffer); 129 130 format = "%+.8I64d"; 131 r = sprintf(buffer,format,(LONGLONG)100); 132 ok(!strcmp(buffer,"+00000100") && r==9,"+.8I64d failed: '%s'\n", buffer); 133 134 format = "%+10.8I64d"; 135 r = sprintf(buffer,format,(LONGLONG)100); 136 ok(!strcmp(buffer," +00000100") && r==10,"+10.8I64d failed: '%s'\n", buffer); 137 format = "%_1I64d"; 138 r = sprintf(buffer,format,(LONGLONG)100); 139 ok(!strcmp(buffer,"_1I64d") && r==6,"_1I64d failed\n"); 140 141 format = "%-1.5I64d"; 142 r = sprintf(buffer,format,(LONGLONG)-100); 143 ok(!strcmp(buffer,"-00100") && r==6,"-1.5I64d failed: '%s'\n", buffer); 144 145 format = "%5I64d"; 146 r = sprintf(buffer,format,(LONGLONG)100); 147 ok(!strcmp(buffer," 100") && r==5,"5I64d failed: '%s'\n", buffer); 148 149 format = "%5I64d"; 150 r = sprintf(buffer,format,(LONGLONG)-100); 151 ok(!strcmp(buffer," -100") && r==5,"5I64d failed: '%s'\n", buffer); 152 153 format = "%-5I64d"; 154 r = sprintf(buffer,format,(LONGLONG)100); 155 ok(!strcmp(buffer,"100 ") && r==5,"-5I64d failed: '%s'\n", buffer); 156 157 format = "%-5I64d"; 158 r = sprintf(buffer,format,(LONGLONG)-100); 159 ok(!strcmp(buffer,"-100 ") && r==5,"-5I64d failed: '%s'\n", buffer); 160 161 format = "%-.5I64d"; 162 r = sprintf(buffer,format,(LONGLONG)100); 163 ok(!strcmp(buffer,"00100") && r==5,"-.5I64d failed: '%s'\n", buffer); 164 165 format = "%-.5I64d"; 166 r = sprintf(buffer,format,(LONGLONG)-100); 167 ok(!strcmp(buffer,"-00100") && r==6,"-.5I64d failed: '%s'\n", buffer); 168 169 format = "%-8.5I64d"; 170 r = sprintf(buffer,format,(LONGLONG)100); 171 ok(!strcmp(buffer,"00100 ") && r==8,"-8.5I64d failed: '%s'\n", buffer); 172 173 format = "%-8.5I64d"; 174 r = sprintf(buffer,format,(LONGLONG)-100); 175 ok(!strcmp(buffer,"-00100 ") && r==8,"-8.5I64d failed: '%s'\n", buffer); 176 177 format = "%05I64d"; 178 r = sprintf(buffer,format,(LONGLONG)100); 179 ok(!strcmp(buffer,"00100") && r==5,"05I64d failed: '%s'\n", buffer); 180 181 format = "%05I64d"; 182 r = sprintf(buffer,format,(LONGLONG)-100); 183 ok(!strcmp(buffer,"-0100") && r==5,"05I64d failed: '%s'\n", buffer); 184 185 format = "% I64d"; 186 r = sprintf(buffer,format,(LONGLONG)100); 187 ok(!strcmp(buffer," 100") && r==4,"' I64d' failed: '%s'\n", buffer); 188 189 format = "% I64d"; 190 r = sprintf(buffer,format,(LONGLONG)-100); 191 ok(!strcmp(buffer,"-100") && r==4,"' I64d' failed: '%s'\n", buffer); 192 193 format = "% 5I64d"; 194 r = sprintf(buffer,format,(LONGLONG)100); 195 ok(!strcmp(buffer," 100") && r==5,"' 5I64d' failed: '%s'\n", buffer); 196 197 format = "% 5I64d"; 198 r = sprintf(buffer,format,(LONGLONG)-100); 199 ok(!strcmp(buffer," -100") && r==5,"' 5I64d' failed: '%s'\n", buffer); 200 201 format = "% .5I64d"; 202 r = sprintf(buffer,format,(LONGLONG)100); 203 ok(!strcmp(buffer," 00100") && r==6,"' .5I64d' failed: '%s'\n", buffer); 204 205 format = "% .5I64d"; 206 r = sprintf(buffer,format,(LONGLONG)-100); 207 ok(!strcmp(buffer,"-00100") && r==6,"' .5I64d' failed: '%s'\n", buffer); 208 209 format = "% 8.5I64d"; 210 r = sprintf(buffer,format,(LONGLONG)100); 211 ok(!strcmp(buffer," 00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer); 212 213 format = "% 8.5I64d"; 214 r = sprintf(buffer,format,(LONGLONG)-100); 215 ok(!strcmp(buffer," -00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer); 216 217 format = "%.0I64d"; 218 r = sprintf(buffer,format,(LONGLONG)0); 219 ok(r==0,".0I64d failed: '%s'\n", buffer); 220 221 format = "%#+21.18I64x"; 222 r = sprintf(buffer,format,(LONGLONG)-100); 223 ok(!strcmp(buffer," 0x00ffffffffffffff9c") && r==21,"#+21.18I64x failed: '%s'\n", buffer); 224 225 format = "%#.25I64o"; 226 r = sprintf(buffer,format,(LONGLONG)-100); 227 ok(!strcmp(buffer,"0001777777777777777777634") && r==25,"#.25I64o failed: '%s'\n", buffer); 228 229 format = "%#+24.20I64o"; 230 r = sprintf(buffer,format,(LONGLONG)-100); 231 ok(!strcmp(buffer," 01777777777777777777634") && r==24,"#+24.20I64o failed: '%s'\n", buffer); 232 233 format = "%#+18.21I64X"; 234 r = sprintf(buffer,format,(LONGLONG)-100); 235 ok(!strcmp(buffer,"0X00000FFFFFFFFFFFFFF9C") && r==23,"#+18.21I64X failed: '%s '\n", buffer); 236 237 format = "%#+20.24I64o"; 238 r = sprintf(buffer,format,(LONGLONG)-100); 239 ok(!strcmp(buffer,"001777777777777777777634") && r==24,"#+20.24I64o failed: '%s'\n", buffer); 240 241 format = "%#+25.22I64u"; 242 r = sprintf(buffer,format,(LONGLONG)-1); 243 ok(!strcmp(buffer," 0018446744073709551615") && r==25,"#+25.22I64u conversion failed: '%s'\n", buffer); 244 245 format = "%#+25.22I64u"; 246 r = sprintf(buffer,format,(LONGLONG)-1); 247 ok(!strcmp(buffer," 0018446744073709551615") && r==25,"#+25.22I64u failed: '%s'\n", buffer); 248 249 format = "%#+30.25I64u"; 250 r = sprintf(buffer,format,(LONGLONG)-1); 251 ok(!strcmp(buffer," 0000018446744073709551615") && r==30,"#+30.25I64u failed: '%s'\n", buffer); 252 253 format = "%+#25.22I64d"; 254 r = sprintf(buffer,format,(LONGLONG)-1); 255 ok(!strcmp(buffer," -0000000000000000000001") && r==25,"+#25.22I64d failed: '%s'\n", buffer); 256 257 format = "%#-8.5I64o"; 258 r = sprintf(buffer,format,(LONGLONG)100); 259 ok(!strcmp(buffer,"00144 ") && r==8,"-8.5I64o failed: '%s'\n", buffer); 260 261 format = "%#-+ 08.5I64d"; 262 r = sprintf(buffer,format,(LONGLONG)100); 263 ok(!strcmp(buffer,"+00100 ") && r==8,"'#-+ 08.5I64d failed: '%s'\n", buffer); 264 265 format = "%#-+ 08.5I64d"; 266 r = sprintf(buffer,format,(LONGLONG)100); 267 ok(!strcmp(buffer,"+00100 ") && r==8,"#-+ 08.5I64d failed: '%s'\n", buffer); 268 269 format = "%.80I64d"; 270 r = sprintf(buffer,format,(LONGLONG)1); 271 ok(r==80,"%s format failed\n", format); 272 273 format = "% .80I64d"; 274 r = sprintf(buffer,format,(LONGLONG)1); 275 ok(r==81,"%s format failed\n", format); 276 277 format = "% .80d"; 278 r = sprintf(buffer,format,1); 279 ok(r==81,"%s format failed\n", format); 280 281 format = "%lld"; 282 r = sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); 283 ok( r == 1 || r == 11, "return count wrong %d\n", r); 284 if (r == 11) /* %ll works on Vista */ 285 ok(!strcmp(buffer, "-8589934591"), "Problem with \"ll\" interpretation '%s'\n", buffer); 286 else 287 ok(!strcmp(buffer, "1"), "Problem with \"ll\" interpretation '%s'\n", buffer); 288 289 format = "%I"; 290 r = sprintf(buffer,format,1); 291 ok(!strcmp(buffer, "I"), "Problem with \"I\" interpretation\n"); 292 ok( r==1, "return count wrong\n"); 293 294 format = "%I0d"; 295 r = sprintf(buffer,format,1); 296 ok(!strcmp(buffer,"I0d"),"I0d failed\n"); 297 ok( r==3, "return count wrong\n"); 298 299 format = "%I32d"; 300 r = sprintf(buffer,format,1); 301 if (r == 1) 302 { 303 ok(!strcmp(buffer,"1"),"I32d failed, got '%s'\n",buffer); 304 } 305 else 306 { 307 /* Older versions don't grok I32 format */ 308 ok(r == 4 && !strcmp(buffer,"I32d"),"I32d failed, got '%s',%d\n",buffer,r); 309 } 310 311 format = "%I64D"; 312 r = sprintf(buffer,format,(LONGLONG)-1); 313 ok(!strcmp(buffer,"D"),"I64D failed: %s\n",buffer); 314 ok( r==1, "return count wrong\n"); 315 316 format = "%zx"; 317 r = sprintf(buffer,format,1); 318 ok(!strcmp(buffer, "zx"), "Problem with \"z\" interpretation\n"); 319 ok( r==2, "return count wrong\n"); 320 321 format = "% d"; 322 r = sprintf(buffer,format,1); 323 ok(!strcmp(buffer, " 1"),"Problem with sign place-holder: '%s'\n",buffer); 324 ok( r==2, "return count wrong\n"); 325 326 format = "%+ d"; 327 r = sprintf(buffer,format,1); 328 ok(!strcmp(buffer, "+1"),"Problem with sign flags: '%s'\n",buffer); 329 ok( r==2, "return count wrong\n"); 330 331 format = "%S"; 332 r = sprintf(buffer,format,wide); 333 ok(!strcmp(buffer,"wide"),"Problem with wide string format\n"); 334 ok( r==4, "return count wrong\n"); 335 336 format = "%04c"; 337 r = sprintf(buffer,format,'1'); 338 ok(!strcmp(buffer,"0001"),"Character not zero-prefixed \"%s\"\n",buffer); 339 ok( r==4, "return count wrong\n"); 340 341 format = "%-04c"; 342 r = sprintf(buffer,format,'1'); 343 ok(!strcmp(buffer,"1 "),"Character zero-padded and/or not left-adjusted \"%s\"\n",buffer); 344 ok( r==4, "return count wrong\n"); 345 346 format = "%#012x"; 347 r = sprintf(buffer,format,1); 348 ok(!strcmp(buffer,"0x0000000001"),"Hexadecimal zero-padded \"%s\"\n",buffer); 349 ok( r==12, "return count wrong\n"); 350 351 r = sprintf(buffer,format,0); 352 ok(!strcmp(buffer,"000000000000"),"Hexadecimal zero-padded \"%s\"\n",buffer); 353 ok( r==12, "return count wrong\n"); 354 355 format = "%#04.8x"; 356 r = sprintf(buffer,format,1); 357 ok(!strcmp(buffer,"0x00000001"), "Hexadecimal zero-padded precision \"%s\"\n",buffer); 358 ok( r==10, "return count wrong\n"); 359 360 r = sprintf(buffer,format,0); 361 ok(!strcmp(buffer,"00000000"), "Hexadecimal zero-padded precision \"%s\"\n",buffer); 362 ok( r==8, "return count wrong\n"); 363 364 format = "%#-08.2x"; 365 r = sprintf(buffer,format,1); 366 ok(!strcmp(buffer,"0x01 "), "Hexadecimal zero-padded not left-adjusted \"%s\"\n",buffer); 367 ok( r==8, "return count wrong\n"); 368 369 r = sprintf(buffer,format,0); 370 ok(!strcmp(buffer,"00 "), "Hexadecimal zero-padded not left-adjusted \"%s\"\n",buffer); 371 ok( r==8, "return count wrong\n"); 372 373 format = "%#.0x"; 374 r = sprintf(buffer,format,1); 375 ok(!strcmp(buffer,"0x1"), "Hexadecimal zero-padded zero-precision \"%s\"\n",buffer); 376 ok( r==3, "return count wrong\n"); 377 378 r = sprintf(buffer,format,0); 379 ok(!strcmp(buffer,""), "Hexadecimal zero-padded zero-precision \"%s\"\n",buffer); 380 ok( r==0, "return count wrong\n"); 381 382 format = "%#08o"; 383 r = sprintf(buffer,format,1); 384 ok(!strcmp(buffer,"00000001"), "Octal zero-padded \"%s\"\n",buffer); 385 ok( r==8, "return count wrong\n"); 386 387 format = "%#o"; 388 r = sprintf(buffer,format,1); 389 ok(!strcmp(buffer,"01"), "Octal zero-padded \"%s\"\n",buffer); 390 ok( r==2, "return count wrong\n"); 391 392 r = sprintf(buffer,format,0); 393 ok(!strcmp(buffer,"0"), "Octal zero-padded \"%s\"\n",buffer); 394 ok( r==1, "return count wrong\n"); 395 396 if (sizeof(void *) == 8) 397 { 398 format = "%p"; 399 r = sprintf(buffer,format,(void *)57); 400 ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly \"%s\"\n",buffer); 401 ok( r==16, "return count wrong\n"); 402 403 format = "%#020p"; 404 r = sprintf(buffer,format,(void *)57); 405 ok(!strcmp(buffer," 0X0000000000000039"),"Pointer formatted incorrectly\n"); 406 ok( r==20, "return count wrong\n"); 407 408 format = "%Fp"; 409 r = sprintf(buffer,format,(void *)57); 410 ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly \"%s\"\n",buffer); 411 ok( r==16, "return count wrong\n"); 412 413 format = "%Np"; 414 r = sprintf(buffer,format,(void *)57); 415 ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly \"%s\"\n",buffer); 416 ok( r==16, "return count wrong\n"); 417 418 format = "%#-020p"; 419 r = sprintf(buffer,format,(void *)57); 420 ok(!strcmp(buffer,"0X0000000000000039 "),"Pointer formatted incorrectly\n"); 421 ok( r==20, "return count wrong\n"); 422 423 format = "%Ix %d"; 424 r = sprintf(buffer,format,(size_t)0x12345678123456,1); 425 ok(!strcmp(buffer,"12345678123456 1"),"buffer = %s\n",buffer); 426 ok( r==16, "return count wrong\n"); 427 } 428 else 429 { 430 format = "%p"; 431 r = sprintf(buffer,format,(void *)57); 432 ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer); 433 ok( r==8, "return count wrong\n"); 434 435 format = "%#012p"; 436 r = sprintf(buffer,format,(void *)57); 437 ok(!strcmp(buffer," 0X00000039"),"Pointer formatted incorrectly\n"); 438 ok( r==12, "return count wrong\n"); 439 440 format = "%Fp"; 441 r = sprintf(buffer,format,(void *)57); 442 ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer); 443 ok( r==8, "return count wrong\n"); 444 445 format = "%Np"; 446 r = sprintf(buffer,format,(void *)57); 447 ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer); 448 ok( r==8, "return count wrong\n"); 449 450 format = "%#-012p"; 451 r = sprintf(buffer,format,(void *)57); 452 ok(!strcmp(buffer,"0X00000039 "),"Pointer formatted incorrectly\n"); 453 ok( r==12, "return count wrong\n"); 454 455 format = "%Ix %d"; 456 r = sprintf(buffer,format,0x123456,1); 457 ok(!strcmp(buffer,"123456 1"),"buffer = %s\n",buffer); 458 ok( r==8, "return count wrong\n"); 459 } 460 461 format = "%04s"; 462 r = sprintf(buffer,format,"foo"); 463 ok(!strcmp(buffer,"0foo"),"String not zero-prefixed \"%s\"\n",buffer); 464 ok( r==4, "return count wrong\n"); 465 466 format = "%.1s"; 467 r = sprintf(buffer,format,"foo"); 468 ok(!strcmp(buffer,"f"),"Precision ignored \"%s\"\n",buffer); 469 ok( r==1, "return count wrong\n"); 470 471 format = "%.*s"; 472 r = sprintf(buffer,format,1,"foo"); 473 ok(!strcmp(buffer,"f"),"Precision ignored \"%s\"\n",buffer); 474 ok( r==1, "return count wrong\n"); 475 476 format = "%*s"; 477 r = sprintf(buffer,format,-5,"foo"); 478 ok(!strcmp(buffer,"foo "),"Negative field width ignored \"%s\"\n",buffer); 479 ok( r==5, "return count wrong\n"); 480 481 format = "hello"; 482 r = sprintf(buffer, format); 483 ok(!strcmp(buffer,"hello"), "failed\n"); 484 ok( r==5, "return count wrong\n"); 485 486 format = "%ws"; 487 r = sprintf(buffer, format, wide); 488 ok(!strcmp(buffer,"wide"), "failed\n"); 489 ok( r==4, "return count wrong\n"); 490 491 format = "%-10ws"; 492 r = sprintf(buffer, format, wide ); 493 ok(!strcmp(buffer,"wide "), "failed\n"); 494 ok( r==10, "return count wrong\n"); 495 496 format = "%10ws"; 497 r = sprintf(buffer, format, wide ); 498 ok(!strcmp(buffer," wide"), "failed\n"); 499 ok( r==10, "return count wrong\n"); 500 501 format = "%#+ -03whlls"; 502 r = sprintf(buffer, format, wide ); 503 ok(!strcmp(buffer,"wide"), "failed\n"); 504 ok( r==4, "return count wrong\n"); 505 506 format = "%w0s"; 507 r = sprintf(buffer, format, wide ); 508 ok(!strcmp(buffer,"0s"), "failed\n"); 509 ok( r==2, "return count wrong\n"); 510 511 format = "%w-s"; 512 r = sprintf(buffer, format, wide ); 513 ok(!strcmp(buffer,"-s"), "failed\n"); 514 ok( r==2, "return count wrong\n"); 515 516 format = "%ls"; 517 r = sprintf(buffer, format, wide ); 518 ok(!strcmp(buffer,"wide"), "failed\n"); 519 ok( r==4, "return count wrong\n"); 520 521 format = "%Ls"; 522 r = sprintf(buffer, format, "not wide" ); 523 ok(!strcmp(buffer,"not wide"), "failed\n"); 524 ok( r==8, "return count wrong\n"); 525 526 format = "%b"; 527 r = sprintf(buffer, format); 528 ok(!strcmp(buffer,"b"), "failed\n"); 529 ok( r==1, "return count wrong\n"); 530 531 format = "%3c"; 532 r = sprintf(buffer, format,'a'); 533 ok(!strcmp(buffer," a"), "failed\n"); 534 ok( r==3, "return count wrong\n"); 535 536 format = "%3d"; 537 r = sprintf(buffer, format,1234); 538 ok(!strcmp(buffer,"1234"), "failed\n"); 539 ok( r==4, "return count wrong\n"); 540 541 format = "%3h"; 542 r = sprintf(buffer, format); 543 ok(!strcmp(buffer,""), "failed\n"); 544 ok( r==0, "return count wrong\n"); 545 546 format = "%j%k%m%q%r%t%v%y%z"; 547 r = sprintf(buffer, format); 548 ok(!strcmp(buffer,"jkmqrtvyz"), "failed\n"); 549 ok( r==9, "return count wrong\n"); 550 551 format = "asdf%n"; 552 x = 0; 553 r = sprintf(buffer, format, &x ); 554 if (r == -1) 555 { 556 /* %n format is disabled by default on vista */ 557 /* FIXME: should test with _set_printf_count_output */ 558 ok(x == 0, "should not write to x: %d\n", x); 559 } 560 else 561 { 562 ok(x == 4, "should write to x: %d\n", x); 563 ok(!strcmp(buffer,"asdf"), "failed\n"); 564 ok( r==4, "return count wrong: %d\n", r); 565 } 566 567 format = "%-1d"; 568 r = sprintf(buffer, format,2); 569 ok(!strcmp(buffer,"2"), "failed\n"); 570 ok( r==1, "return count wrong\n"); 571 572 format = "%2.4f"; 573 r = sprintf(buffer, format,8.6); 574 ok(!strcmp(buffer,"8.6000"), "failed\n"); 575 ok( r==6, "return count wrong\n"); 576 577 format = "%0f"; 578 r = sprintf(buffer, format,0.6); 579 ok(!strcmp(buffer,"0.600000"), "failed\n"); 580 ok( r==8, "return count wrong\n"); 581 582 format = "%.0f"; 583 r = sprintf(buffer, format,0.6); 584 ok(!strcmp(buffer,"1"), "failed\n"); 585 ok( r==1, "return count wrong\n"); 586 587 format = "%2.4e"; 588 r = sprintf(buffer, format,8.6); 589 ok(!strcmp(buffer,"8.6000e+000"), "failed\n"); 590 ok( r==11, "return count wrong\n"); 591 592 format = "% 2.4e"; 593 r = sprintf(buffer, format,8.6); 594 ok(!strcmp(buffer," 8.6000e+000"), "failed: %s\n", buffer); 595 ok( r==12, "return count wrong\n"); 596 597 format = "% 014.4e"; 598 r = sprintf(buffer, format,8.6); 599 ok(!strcmp(buffer," 008.6000e+000"), "failed: %s\n", buffer); 600 ok( r==14, "return count wrong\n"); 601 602 format = "% 2.4e"; 603 r = sprintf(buffer, format,-8.6); 604 ok(!strcmp(buffer,"-8.6000e+000"), "failed: %s\n", buffer); 605 ok( r==12, "return count wrong\n"); 606 607 format = "%+2.4e"; 608 r = sprintf(buffer, format,8.6); 609 ok(!strcmp(buffer,"+8.6000e+000"), "failed: %s\n", buffer); 610 ok( r==12, "return count wrong\n"); 611 612 format = "%2.4g"; 613 r = sprintf(buffer, format,8.6); 614 ok(!strcmp(buffer,"8.6"), "failed\n"); 615 ok( r==3, "return count wrong\n"); 616 617 format = "%-i"; 618 r = sprintf(buffer, format,-1); 619 ok(!strcmp(buffer,"-1"), "failed\n"); 620 ok( r==2, "return count wrong\n"); 621 622 format = "%-i"; 623 r = sprintf(buffer, format,1); 624 ok(!strcmp(buffer,"1"), "failed\n"); 625 ok( r==1, "return count wrong\n"); 626 627 format = "%+i"; 628 r = sprintf(buffer, format,1); 629 ok(!strcmp(buffer,"+1"), "failed\n"); 630 ok( r==2, "return count wrong\n"); 631 632 format = "%o"; 633 r = sprintf(buffer, format,10); 634 ok(!strcmp(buffer,"12"), "failed\n"); 635 ok( r==2, "return count wrong\n"); 636 637 format = "%p"; 638 r = sprintf(buffer, format,0); 639 if (sizeof(void *) == 8) 640 { 641 ok(!strcmp(buffer,"0000000000000000"), "failed\n"); 642 ok( r==16, "return count wrong\n"); 643 } 644 else 645 { 646 ok(!strcmp(buffer,"00000000"), "failed\n"); 647 ok( r==8, "return count wrong\n"); 648 } 649 650 format = "%s"; 651 r = sprintf(buffer, format,0); 652 ok(!strcmp(buffer,"(null)"), "failed\n"); 653 ok( r==6, "return count wrong\n"); 654 655 format = "%s"; 656 r = sprintf(buffer, format,"%%%%"); 657 ok(!strcmp(buffer,"%%%%"), "failed\n"); 658 ok( r==4, "return count wrong\n"); 659 660 format = "%u"; 661 r = sprintf(buffer, format,-1); 662 ok(!strcmp(buffer,"4294967295"), "failed\n"); 663 ok( r==10, "return count wrong\n"); 664 665 format = "%w"; 666 r = sprintf(buffer, format,-1); 667 ok(!strcmp(buffer,""), "failed\n"); 668 ok( r==0, "return count wrong\n"); 669 670 format = "%h"; 671 r = sprintf(buffer, format,-1); 672 ok(!strcmp(buffer,""), "failed\n"); 673 ok( r==0, "return count wrong\n"); 674 675 format = "%z"; 676 r = sprintf(buffer, format,-1); 677 ok(!strcmp(buffer,"z"), "failed\n"); 678 ok( r==1, "return count wrong\n"); 679 680 format = "%j"; 681 r = sprintf(buffer, format,-1); 682 ok(!strcmp(buffer,"j"), "failed\n"); 683 ok( r==1, "return count wrong\n"); 684 685 format = "%F"; 686 r = sprintf(buffer, format,-1); 687 ok(!strcmp(buffer,""), "failed\n"); 688 ok( r==0, "return count wrong\n"); 689 690 format = "%N"; 691 r = sprintf(buffer, format,-1); 692 ok(!strcmp(buffer,""), "failed\n"); 693 ok( r==0, "return count wrong\n"); 694 695 format = "%H"; 696 r = sprintf(buffer, format,-1); 697 ok(!strcmp(buffer,"H"), "failed\n"); 698 ok( r==1, "return count wrong\n"); 699 700 format = "x%cx"; 701 r = sprintf(buffer, format, 0x100+'X'); 702 ok(!strcmp(buffer,"xXx"), "failed\n"); 703 ok( r==3, "return count wrong\n"); 704 705 format = "%%0"; 706 r = sprintf(buffer, format); 707 ok(!strcmp(buffer,"%0"), "failed: \"%s\"\n", buffer); 708 ok( r==2, "return count wrong\n"); 709 710 format = "%hx"; 711 r = sprintf(buffer, format, 0x12345); 712 ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer); 713 714 format = "%hhx"; 715 r = sprintf(buffer, format, 0x123); 716 ok(!strcmp(buffer,"123"), "failed: \"%s\"\n", buffer); 717 r = sprintf(buffer, format, 0x12345); 718 ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer); 719 720 format = "%lf"; 721 r = sprintf(buffer, format, IND); 722 ok(r==9, "r = %d\n", r); 723 ok(!strcmp(buffer, "-1.#IND00"), "failed: \"%s\"\n", buffer); 724 r = sprintf(buffer, format, NAN); 725 ok(r==8, "r = %d\n", r); 726 ok(!strcmp(buffer, "1.#QNAN0"), "failed: \"%s\"\n", buffer); 727 r = sprintf(buffer, format, INFINITY); 728 ok(r==8, "r = %d\n", r); 729 ok(!strcmp(buffer, "1.#INF00"), "failed: \"%s\"\n", buffer); 730 731 format = "%le"; 732 r = sprintf(buffer, format, IND); 733 ok(r==14, "r = %d\n", r); 734 ok(!strcmp(buffer, "-1.#IND00e+000"), "failed: \"%s\"\n", buffer); 735 r = sprintf(buffer, format, NAN); 736 ok(r==13, "r = %d\n", r); 737 ok(!strcmp(buffer, "1.#QNAN0e+000"), "failed: \"%s\"\n", buffer); 738 r = sprintf(buffer, format, INFINITY); 739 ok(r==13, "r = %d\n", r); 740 ok(!strcmp(buffer, "1.#INF00e+000"), "failed: \"%s\"\n", buffer); 741 742 format = "%lg"; 743 r = sprintf(buffer, format, IND); 744 ok(r==7, "r = %d\n", r); 745 ok(!strcmp(buffer, "-1.#IND"), "failed: \"%s\"\n", buffer); 746 r = sprintf(buffer, format, NAN); 747 ok(r==7, "r = %d\n", r); 748 ok(!strcmp(buffer, "1.#QNAN"), "failed: \"%s\"\n", buffer); 749 r = sprintf(buffer, format, INFINITY); 750 ok(r==6, "r = %d\n", r); 751 ok(!strcmp(buffer, "1.#INF"), "failed: \"%s\"\n", buffer); 752 753 format = "%010.2lf"; 754 r = sprintf(buffer, format, IND); 755 ok(r==10, "r = %d\n", r); 756 ok(!strcmp(buffer, "-000001.#J"), "failed: \"%s\"\n", buffer); 757 r = sprintf(buffer, format, NAN); 758 ok(r==10, "r = %d\n", r); 759 ok(!strcmp(buffer, "0000001.#R"), "failed: \"%s\"\n", buffer); 760 r = sprintf(buffer, format, INFINITY); 761 ok(r==10, "r = %d\n", r); 762 ok(!strcmp(buffer, "0000001.#J"), "failed: \"%s\"\n", buffer); 763 764 format = "%c"; 765 r = sprintf(buffer, format, 'a'); 766 ok(r==1, "r = %d\n", r); 767 ok(!strcmp(buffer, "a"), "failed: \"%s\"\n", buffer); 768 r = sprintf(buffer, format, 0xa082); 769 ok(r==1, "r = %d\n", r); 770 ok(!strcmp(buffer, "\x82"), "failed: \"%s\"\n", buffer); 771 772 format = "%C"; 773 r = sprintf(buffer, format, 'a'); 774 ok(r==1, "r = %d\n", r); 775 ok(!strcmp(buffer, "a"), "failed: \"%s\"\n", buffer); 776 r = sprintf(buffer, format, 0x3042); 777 ok(r==0, "r = %d\n", r); 778 ok(!strcmp(buffer, ""), "failed: \"%s\"\n", buffer); 779 780 if(!setlocale(LC_ALL, "Japanese_Japan.932")) { 781 win_skip("Japanese_Japan.932 locale not available\n"); 782 return; 783 } 784 785 format = "%c"; 786 r = sprintf(buffer, format, 0xa082); 787 ok(r==1, "r = %d\n", r); 788 ok(!strcmp(buffer, "\x82"), "failed: \"%s\"\n", buffer); 789 790 format = "%C"; 791 r = sprintf(buffer, format, 0x3042); 792 ok(r==2, "r = %d\n", r); 793 ok(!strcmp(buffer, "\x82\xa0"), "failed: \"%s\"\n", buffer); 794 795 setlocale(LC_ALL, "C"); 796 } 797 798 static void test_swprintf( void ) 799 { 800 wchar_t buffer[100]; 801 const wchar_t I64d[] = {'%','I','6','4','d',0}; 802 double pnumber=789456123; 803 const wchar_t TwentyThreePoint15e[]= {'%','+','#','2','3','.','1','5','e',0}; 804 const wchar_t e008[] = {'e','+','0','0','8',0}; 805 const wchar_t string_w[] = {'s','t','r','i','n','g',0}; 806 const char string[] = "string"; 807 const wchar_t S[]={'%','S',0}; 808 const wchar_t hs[] = {'%', 'h', 's', 0}; 809 810 swprintf(buffer,TwentyThreePoint15e,pnumber); 811 ok(wcsstr(buffer,e008) != 0,"Sprintf different\n"); 812 swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff); 813 ok(wcslen(buffer) == 11,"Problem with long long\n"); 814 swprintf(buffer,S,string); 815 ok(wcslen(buffer) == 6,"Problem with \"%%S\" interpretation\n"); 816 swprintf(buffer, hs, string); 817 ok( wcscmp(string_w,buffer) == 0, "swprintf failed with %%hs\n"); 818 } 819 820 static void test_snprintf (void) 821 { 822 struct snprintf_test { 823 const char *format; 824 int expected; 825 }; 826 /* Pre-2.1 libc behaviour, not C99 compliant. */ 827 const struct snprintf_test tests[] = {{"short", 5}, 828 {"justfit", 7}, 829 {"justfits", 8}, 830 {"muchlonger", -1}}; 831 char buffer[8]; 832 const int bufsiz = sizeof buffer; 833 unsigned int i; 834 835 for (i = 0; i < sizeof tests / sizeof tests[0]; i++) { 836 const char *fmt = tests[i].format; 837 const int expect = tests[i].expected; 838 const int n = _snprintf (buffer, bufsiz, fmt); 839 const int valid = n < 0 ? bufsiz : (n == bufsiz ? n : n+1); 840 841 ok (n == expect, "\"%s\": expected %d, returned %d\n", 842 fmt, expect, n); 843 ok (!memcmp (fmt, buffer, valid), 844 "\"%s\": rendered \"%.*s\"\n", fmt, valid, buffer); 845 } 846 } 847 848 static void test_fprintf(void) 849 { 850 static const char file_name[] = "fprintf.tst"; 851 static const WCHAR utf16_test[] = {'u','n','i','c','o','d','e','\n',0}; 852 853 FILE *fp = fopen(file_name, "wb"); 854 char buf[1024]; 855 int ret; 856 857 ret = fprintf(fp, "simple test\n"); 858 ok(ret == 12, "ret = %d\n", ret); 859 ret = ftell(fp); 860 ok(ret == 12, "ftell returned %d\n", ret); 861 862 ret = fprintf(fp, "contains%cnull\n", '\0'); 863 ok(ret == 14, "ret = %d\n", ret); 864 ret = ftell(fp); 865 ok(ret == 26, "ftell returned %d\n", ret); 866 867 ret = fwprintf(fp, utf16_test); 868 ok(ret == 8, "ret = %d\n", ret); 869 ret = ftell(fp); 870 ok(ret == 42, "ftell returned %d\n", ret); 871 872 fclose(fp); 873 874 fp = fopen(file_name, "rb"); 875 ret = fscanf(fp, "%[^\n] ", buf); 876 ok(ret == 1, "ret = %d\n", ret); 877 ret = ftell(fp); 878 ok(ret == 12, "ftell returned %d\n", ret); 879 ok(!strcmp(buf, "simple test"), "buf = %s\n", buf); 880 881 fgets(buf, sizeof(buf), fp); 882 ret = ftell(fp); 883 ok(ret == 26, "ret = %d\n", ret); 884 ok(!memcmp(buf, "contains\0null\n", 14), "buf = %s\n", buf); 885 886 memset(buf, 0, sizeof(buf)); 887 fgets(buf, sizeof(buf), fp); 888 ret = ftell(fp); 889 ok(ret == 41, "ret = %d\n", ret); 890 ok(!memcmp(buf, utf16_test, sizeof(utf16_test)), 891 "buf = %s\n", wine_dbgstr_w((WCHAR*)buf)); 892 893 fclose(fp); 894 895 fp = fopen(file_name, "wt"); 896 897 ret = fprintf(fp, "simple test\n"); 898 ok(ret == 12, "ret = %d\n", ret); 899 ret = ftell(fp); 900 ok(ret == 13, "ftell returned %d\n", ret); 901 902 ret = fprintf(fp, "contains%cnull\n", '\0'); 903 ok(ret == 14, "ret = %d\n", ret); 904 ret = ftell(fp); 905 ok(ret == 28, "ftell returned %d\n", ret); 906 907 ret = fwprintf(fp, utf16_test); 908 ok(ret == 8, "ret = %d\n", ret); 909 ret = ftell(fp); 910 ok(ret == 37, "ftell returned %d\n", ret); 911 912 fclose(fp); 913 914 fp = fopen(file_name, "rb"); 915 ret = fscanf(fp, "%[^\n] ", buf); 916 ok(ret == 1, "ret = %d\n", ret); 917 ret = ftell(fp); 918 ok(ret == 13, "ftell returned %d\n", ret); 919 ok(!strcmp(buf, "simple test\r"), "buf = %s\n", buf); 920 921 fgets(buf, sizeof(buf), fp); 922 ret = ftell(fp); 923 ok(ret == 28, "ret = %d\n", ret); 924 ok(!memcmp(buf, "contains\0null\r\n", 15), "buf = %s\n", buf); 925 926 fgets(buf, sizeof(buf), fp); 927 ret = ftell(fp); 928 ok(ret == 37, "ret = %d\n", ret); 929 ok(!strcmp(buf, "unicode\r\n"), "buf = %s\n", buf); 930 931 fclose(fp); 932 unlink(file_name); 933 } 934 935 static void test_fcvt(void) 936 { 937 char *str; 938 int dec=100, sign=100; 939 940 /* Numbers less than 1.0 with different precisions */ 941 str = _fcvt(0.0001, 1, &dec, &sign ); 942 ok( 0 == strcmp(str,""), "bad return '%s'\n", str); 943 ok( -3 == dec, "dec wrong %d\n", dec); 944 ok( 0 == sign, "sign wrong\n"); 945 946 str = _fcvt(0.0001, -10, &dec, &sign ); 947 ok( 0 == strcmp(str,""), "bad return '%s'\n", str); 948 ok( -3 == dec, "dec wrong %d\n", dec); 949 ok( 0 == sign, "sign wrong\n"); 950 951 str = _fcvt(0.0001, 10, &dec, &sign ); 952 ok( 0 == strcmp(str,"1000000"), "bad return '%s'\n", str); 953 ok( -3 == dec, "dec wrong %d\n", dec); 954 ok( 0 == sign, "sign wrong\n"); 955 956 /* Basic sign test */ 957 str = _fcvt(-111.0001, 5, &dec, &sign ); 958 ok( 0 == strcmp(str,"11100010"), "bad return '%s'\n", str); 959 ok( 3 == dec, "dec wrong %d\n", dec); 960 ok( 1 == sign, "sign wrong\n"); 961 962 str = _fcvt(111.0001, 5, &dec, &sign ); 963 ok( 0 == strcmp(str,"11100010"), "bad return '%s'\n", str); 964 ok( 3 == dec, "dec wrong\n"); 965 ok( 0 == sign, "sign wrong\n"); 966 967 /* 0.0 with different precisions */ 968 str = _fcvt(0.0, 5, &dec, &sign ); 969 ok( 0 == strcmp(str,"00000"), "bad return '%s'\n", str); 970 ok( 0 == dec, "dec wrong %d\n", dec); 971 ok( 0 == sign, "sign wrong\n"); 972 973 str = _fcvt(0.0, 0, &dec, &sign ); 974 ok( 0 == strcmp(str,""), "bad return '%s'\n", str); 975 ok( 0 == dec, "dec wrong %d\n", dec); 976 ok( 0 == sign, "sign wrong\n"); 977 978 str = _fcvt(0.0, -1, &dec, &sign ); 979 ok( 0 == strcmp(str,""), "bad return '%s'\n", str); 980 ok( 0 == dec, "dec wrong %d\n", dec); 981 ok( 0 == sign, "sign wrong\n"); 982 983 /* Numbers > 1.0 with 0 or -ve precision */ 984 str = _fcvt(-123.0001, 0, &dec, &sign ); 985 ok( 0 == strcmp(str,"123"), "bad return '%s'\n", str); 986 ok( 3 == dec, "dec wrong %d\n", dec); 987 ok( 1 == sign, "sign wrong\n"); 988 989 str = _fcvt(-123.0001, -1, &dec, &sign ); 990 ok( 0 == strcmp(str,"12"), "bad return '%s'\n", str); 991 ok( 3 == dec, "dec wrong %d\n", dec); 992 ok( 1 == sign, "sign wrong\n"); 993 994 str = _fcvt(-123.0001, -2, &dec, &sign ); 995 ok( 0 == strcmp(str,"1"), "bad return '%s'\n", str); 996 ok( 3 == dec, "dec wrong %d\n", dec); 997 ok( 1 == sign, "sign wrong\n"); 998 999 str = _fcvt(-123.0001, -3, &dec, &sign ); 1000 ok( 0 == strcmp(str,""), "bad return '%s'\n", str); 1001 ok( 3 == dec, "dec wrong %d\n", dec); 1002 ok( 1 == sign, "sign wrong\n"); 1003 1004 /* Numbers > 1.0, but with rounding at the point of precision */ 1005 str = _fcvt(99.99, 1, &dec, &sign ); 1006 ok( 0 == strcmp(str,"1000"), "bad return '%s'\n", str); 1007 ok( 3 == dec, "dec wrong %d\n", dec); 1008 ok( 0 == sign, "sign wrong\n"); 1009 1010 /* Numbers < 1.0 where rounding occurs at the point of precision */ 1011 str = _fcvt(0.00636, 2, &dec, &sign ); 1012 ok( 0 == strcmp(str,"1"), "bad return '%s'\n", str); 1013 ok( -1 == dec, "dec wrong %d\n", dec); 1014 ok( 0 == sign, "sign wrong\n"); 1015 1016 str = _fcvt(0.00636, 3, &dec, &sign ); 1017 ok( 0 == strcmp(str,"6"), "bad return '%s'\n", str); 1018 ok( -2 == dec, "dec wrong %d\n", dec); 1019 ok( 0 == sign, "sign wrong\n"); 1020 1021 str = _fcvt(0.09999999996, 2, &dec, &sign ); 1022 ok( 0 == strcmp(str,"10"), "bad return '%s'\n", str); 1023 ok( 0 == dec, "dec wrong %d\n", dec); 1024 ok( 0 == sign, "sign wrong\n"); 1025 1026 str = _fcvt(0.6, 0, &dec, &sign ); 1027 ok( 0 == strcmp(str,"1"), "bad return '%s'\n", str); 1028 ok( 1 == dec, "dec wrong %d\n", dec); 1029 ok( 0 == sign, "sign wrong\n"); 1030 } 1031 1032 /* Don't test nrdigits < 0, msvcrt on Win9x and NT4 will corrupt memory by 1033 * writing outside allocated memory */ 1034 static struct { 1035 double value; 1036 int nrdigits; 1037 const char *expstr_e; 1038 const char *expstr_f; 1039 int expdecpt_e; 1040 int expdecpt_f; 1041 int expsign; 1042 } test_cvt_testcases[] = { 1043 { 45.0, 2, "45", "4500", 2, 2, 0 }, 1044 /* Numbers less than 1.0 with different precisions */ 1045 { 0.0001, 1, "1", "", -3, -3, 0 }, 1046 { 0.0001, 10,"1000000000", "1000000", -3, -3, 0 }, 1047 /* Basic sign test */ 1048 { -111.0001, 5, "11100", "11100010", 3, 3, 1 }, 1049 { 111.0001, 5, "11100", "11100010", 3, 3, 0 }, 1050 /* big numbers with low precision */ 1051 { 3333.3, 2, "33", "333330", 4, 4, 0 }, 1052 {999999999999.9, 3, "100","999999999999900", 13, 12, 0 }, 1053 /* 0.0 with different precisions */ 1054 { 0.0, 5, "00000", "00000", 0, 0, 0 }, 1055 { 0.0, 0, "", "", 0, 0, 0 }, 1056 { 0.0, -1, "", "", 0, 0, 0 }, 1057 /* Numbers > 1.0 with 0 or -ve precision */ 1058 { -123.0001, 0, "", "123", 3, 3, 1 }, 1059 { -123.0001, -1, "", "12", 3, 3, 1 }, 1060 { -123.0001, -2, "", "1", 3, 3, 1 }, 1061 { -123.0001, -3, "", "", 3, 3, 1 }, 1062 /* Numbers > 1.0, but with rounding at the point of precision */ 1063 { 99.99, 1, "1", "1000", 3, 3, 0 }, 1064 /* Numbers < 1.0 where rounding occurs at the point of precision */ 1065 { 0.0063, 2, "63", "1", -2, -1, 0 }, 1066 { 0.0063, 3, "630", "6", -2, -2, 0 }, 1067 { 0.09999999996, 2, "10", "10", 0, 0, 0 }, 1068 { 0.6, 1, "6", "6", 0, 0, 0 }, 1069 { 0.6, 0, "", "1", 1, 1, 0 }, 1070 { 0.4, 0, "", "", 0, 0, 0 }, 1071 { 0.49, 0, "", "", 0, 0, 0 }, 1072 { 0.51, 0, "", "1", 1, 1, 0 }, 1073 /* ask for ridiculous precision, ruin formatting this table */ 1074 { 1.0, 30, "100000000000000000000000000000", 1075 "1000000000000000000000000000000", 1, 1, 0}, 1076 { 123456789012345678901.0, 30, "123456789012345680000000000000", 1077 "123456789012345680000000000000000000000000000000000", 21, 21, 0}, 1078 /* end marker */ 1079 { 0, 0, "END"} 1080 }; 1081 1082 static void test_xcvt(void) 1083 { 1084 char *str; 1085 int i, decpt, sign, err; 1086 1087 for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ 1088 decpt = sign = 100; 1089 str = _ecvt( test_cvt_testcases[i].value, 1090 test_cvt_testcases[i].nrdigits, 1091 &decpt, 1092 &sign); 1093 ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15), 1094 "_ecvt() bad return, got \n'%s' expected \n'%s'\n", str, 1095 test_cvt_testcases[i].expstr_e); 1096 ok( decpt == test_cvt_testcases[i].expdecpt_e, 1097 "_ecvt() decimal point wrong, got %d expected %d\n", decpt, 1098 test_cvt_testcases[i].expdecpt_e); 1099 ok( sign == test_cvt_testcases[i].expsign, 1100 "_ecvt() sign wrong, got %d expected %d\n", sign, 1101 test_cvt_testcases[i].expsign); 1102 } 1103 for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ 1104 decpt = sign = 100; 1105 str = _fcvt( test_cvt_testcases[i].value, 1106 test_cvt_testcases[i].nrdigits, 1107 &decpt, 1108 &sign); 1109 ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15), 1110 "_fcvt() bad return, got \n'%s' expected \n'%s'\n", str, 1111 test_cvt_testcases[i].expstr_f); 1112 ok( decpt == test_cvt_testcases[i].expdecpt_f, 1113 "_fcvt() decimal point wrong, got %d expected %d\n", decpt, 1114 test_cvt_testcases[i].expdecpt_f); 1115 ok( sign == test_cvt_testcases[i].expsign, 1116 "_fcvt() sign wrong, got %d expected %d\n", sign, 1117 test_cvt_testcases[i].expsign); 1118 } 1119 1120 if (p__ecvt_s) 1121 { 1122 str = malloc(1024); 1123 for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ 1124 decpt = sign = 100; 1125 err = p__ecvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign); 1126 ok(err == 0, "_ecvt_s() failed with error code %d\n", err); 1127 ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15), 1128 "_ecvt_s() bad return, got \n'%s' expected \n'%s'\n", str, 1129 test_cvt_testcases[i].expstr_e); 1130 ok( decpt == test_cvt_testcases[i].expdecpt_e, 1131 "_ecvt_s() decimal point wrong, got %d expected %d\n", decpt, 1132 test_cvt_testcases[i].expdecpt_e); 1133 ok( sign == test_cvt_testcases[i].expsign, 1134 "_ecvt_s() sign wrong, got %d expected %d\n", sign, 1135 test_cvt_testcases[i].expsign); 1136 } 1137 free(str); 1138 } 1139 else 1140 win_skip("_ecvt_s not available\n"); 1141 1142 if (p__fcvt_s) 1143 { 1144 int i; 1145 1146 str = malloc(1024); 1147 1148 /* invalid arguments */ 1149 err = p__fcvt_s(NULL, 0, 0.0, 0, &i, &i); 1150 ok(err == EINVAL, "got %d, expected EINVAL\n", err); 1151 1152 err = p__fcvt_s(str, 0, 0.0, 0, &i, &i); 1153 ok(err == EINVAL, "got %d, expected EINVAL\n", err); 1154 1155 str[0] = ' '; 1156 str[1] = 0; 1157 err = p__fcvt_s(str, -1, 0.0, 0, &i, &i); 1158 ok(err == 0, "got %d, expected 0\n", err); 1159 ok(str[0] == 0, "got %c, expected 0\n", str[0]); 1160 ok(str[1] == 0, "got %c, expected 0\n", str[1]); 1161 1162 err = p__fcvt_s(str, 1, 0.0, 0, NULL, &i); 1163 ok(err == EINVAL, "got %d, expected EINVAL\n", err); 1164 1165 err = p__fcvt_s(str, 1, 0.0, 0, &i, NULL); 1166 ok(err == EINVAL, "got %d, expected EINVAL\n", err); 1167 1168 for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ 1169 decpt = sign = 100; 1170 err = p__fcvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign); 1171 ok(err == 0, "_fcvt_s() failed with error code %d\n", err); 1172 ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15), 1173 "_fcvt_s() bad return, got '%s' expected '%s'. test %d\n", str, 1174 test_cvt_testcases[i].expstr_f, i); 1175 ok( decpt == test_cvt_testcases[i].expdecpt_f, 1176 "_fcvt_s() decimal point wrong, got %d expected %d\n", decpt, 1177 test_cvt_testcases[i].expdecpt_f); 1178 ok( sign == test_cvt_testcases[i].expsign, 1179 "_fcvt_s() sign wrong, got %d expected %d\n", sign, 1180 test_cvt_testcases[i].expsign); 1181 } 1182 free(str); 1183 } 1184 else 1185 win_skip("_fcvt_s not available\n"); 1186 } 1187 1188 static int __cdecl _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...) 1189 { 1190 int ret; 1191 __ms_va_list valist; 1192 __ms_va_start(valist, format); 1193 ret = _vsnwprintf(str, len, format, valist); 1194 __ms_va_end(valist); 1195 return ret; 1196 } 1197 1198 static void test_vsnwprintf(void) 1199 { 1200 const wchar_t format[] = {'%','w','s','%','w','s','%','w','s',0}; 1201 const wchar_t one[] = {'o','n','e',0}; 1202 const wchar_t two[] = {'t','w','o',0}; 1203 const wchar_t three[] = {'t','h','r','e','e',0}; 1204 1205 int ret; 1206 wchar_t str[32]; 1207 char buf[32]; 1208 1209 ret = _vsnwprintf_wrapper( str, sizeof(str)/sizeof(str[0]), format, one, two, three ); 1210 1211 ok( ret == 11, "got %d expected 11\n", ret ); 1212 WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL ); 1213 ok( !strcmp(buf, "onetwothree"), "got %s expected 'onetwothree'\n", buf ); 1214 1215 ret = _vsnwprintf_wrapper( str, 0, format, one, two, three ); 1216 ok( ret == -1, "got %d, expected -1\n", ret ); 1217 1218 ret = _vsnwprintf_wrapper( NULL, 0, format, one, two, three ); 1219 ok( ret == 11 || broken(ret == -1 /* Win2k */), "got %d, expected 11\n", ret ); 1220 } 1221 1222 static int __cdecl vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) 1223 { 1224 int ret; 1225 __ms_va_list valist; 1226 __ms_va_start(valist, format); 1227 ret = p_vswprintf(str, format, valist); 1228 __ms_va_end(valist); 1229 return ret; 1230 } 1231 1232 static int __cdecl _vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) 1233 { 1234 int ret; 1235 __ms_va_list valist; 1236 __ms_va_start(valist, format); 1237 ret = p__vswprintf(str, format, valist); 1238 __ms_va_end(valist); 1239 return ret; 1240 } 1241 1242 static int __cdecl _vswprintf_l_wrapper(wchar_t *str, const wchar_t *format, void *locale, ...) 1243 { 1244 int ret; 1245 __ms_va_list valist; 1246 __ms_va_start(valist, locale); 1247 ret = p__vswprintf_l(str, format, locale, valist); 1248 __ms_va_end(valist); 1249 return ret; 1250 } 1251 1252 static int __cdecl _vswprintf_c_wrapper(wchar_t *str, size_t size, const wchar_t *format, ...) 1253 { 1254 int ret; 1255 __ms_va_list valist; 1256 __ms_va_start(valist, format); 1257 ret = p__vswprintf_c(str, size, format, valist); 1258 __ms_va_end(valist); 1259 return ret; 1260 } 1261 1262 static int __cdecl _vswprintf_c_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) 1263 { 1264 int ret; 1265 __ms_va_list valist; 1266 __ms_va_start(valist, locale); 1267 ret = p__vswprintf_c_l(str, size, format, locale, valist); 1268 __ms_va_end(valist); 1269 return ret; 1270 } 1271 1272 static int __cdecl _vswprintf_p_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) 1273 { 1274 int ret; 1275 __ms_va_list valist; 1276 __ms_va_start(valist, locale); 1277 ret = p__vswprintf_p_l(str, size, format, locale, valist); 1278 __ms_va_end(valist); 1279 return ret; 1280 } 1281 1282 static void test_vswprintf(void) 1283 { 1284 const wchar_t format[] = {'%','s',' ','%','d',0}; 1285 const wchar_t number[] = {'n','u','m','b','e','r',0}; 1286 const wchar_t out[] = {'n','u','m','b','e','r',' ','1','2','3',0}; 1287 wchar_t buf[20]; 1288 1289 int ret; 1290 1291 if (!p_vswprintf || !p__vswprintf || !p__vswprintf_l ||!p__vswprintf_c 1292 || !p__vswprintf_c_l || !p__vswprintf_p_l) 1293 { 1294 win_skip("_vswprintf or vswprintf not available\n"); 1295 return; 1296 } 1297 1298 ret = vswprintf_wrapper(buf, format, number, 123); 1299 ok(ret == 10, "got %d, expected 10\n", ret); 1300 ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); 1301 1302 memset(buf, 0, sizeof(buf)); 1303 ret = _vswprintf_wrapper(buf, format, number, 123); 1304 ok(ret == 10, "got %d, expected 10\n", ret); 1305 ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); 1306 1307 memset(buf, 0, sizeof(buf)); 1308 ret = _vswprintf_l_wrapper(buf, format, NULL, number, 123); 1309 ok(ret == 10, "got %d, expected 10\n", ret); 1310 ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); 1311 1312 memset(buf, 0, sizeof(buf)); 1313 ret = _vswprintf_c_wrapper(buf, 20, format, number, 123); 1314 ok(ret == 10, "got %d, expected 10\n", ret); 1315 ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); 1316 1317 memset(buf, 0, sizeof(buf)); 1318 ret = _vswprintf_c_l_wrapper(buf, 20, format, NULL, number, 123); 1319 ok(ret == 10, "got %d, expected 10\n", ret); 1320 ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); 1321 1322 memset(buf, 0, sizeof(buf)); 1323 ret = _vswprintf_p_l_wrapper(buf, 20, format, NULL, number, 123); 1324 ok(ret == 10, "got %d, expected 10\n", ret); 1325 ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); 1326 } 1327 1328 static int __cdecl _vscprintf_wrapper(const char *format, ...) 1329 { 1330 int ret; 1331 __ms_va_list valist; 1332 __ms_va_start(valist, format); 1333 ret = p__vscprintf(format, valist); 1334 __ms_va_end(valist); 1335 return ret; 1336 } 1337 1338 static void test_vscprintf(void) 1339 { 1340 int ret; 1341 1342 if (!p__vscprintf) 1343 { 1344 win_skip("_vscprintf not available\n"); 1345 return; 1346 } 1347 1348 ret = _vscprintf_wrapper( "%s %d", "number", 1 ); 1349 ok( ret == 8, "got %d expected 8\n", ret ); 1350 } 1351 1352 static int __cdecl _vscwprintf_wrapper(const wchar_t *format, ...) 1353 { 1354 int ret; 1355 __ms_va_list valist; 1356 __ms_va_start(valist, format); 1357 ret = p__vscwprintf(format, valist); 1358 __ms_va_end(valist); 1359 return ret; 1360 } 1361 1362 static void test_vscwprintf(void) 1363 { 1364 const wchar_t format[] = {'%','s',' ','%','d',0}; 1365 const wchar_t number[] = {'n','u','m','b','e','r',0}; 1366 1367 int ret; 1368 1369 if (!p__vscwprintf) 1370 { 1371 win_skip("_vscwprintf not available\n"); 1372 return; 1373 } 1374 1375 ret = _vscwprintf_wrapper( format, number, 1 ); 1376 ok( ret == 8, "got %d expected 8\n", ret ); 1377 } 1378 1379 static int __cdecl _vsnwprintf_s_wrapper(wchar_t *str, size_t sizeOfBuffer, 1380 size_t count, const wchar_t *format, ...) 1381 { 1382 int ret; 1383 __ms_va_list valist; 1384 __ms_va_start(valist, format); 1385 ret = p__vsnwprintf_s(str, sizeOfBuffer, count, format, valist); 1386 __ms_va_end(valist); 1387 return ret; 1388 } 1389 1390 static void test_vsnwprintf_s(void) 1391 { 1392 const wchar_t format[] = { 'A','B','%','u','C',0 }; 1393 const wchar_t out7[] = { 'A','B','1','2','3','C',0 }; 1394 const wchar_t out6[] = { 'A','B','1','2','3',0 }; 1395 const wchar_t out2[] = { 'A',0 }; 1396 const wchar_t out1[] = { 0 }; 1397 wchar_t buffer[14] = { 0 }; 1398 int exp, got; 1399 1400 if (!p__vsnwprintf_s) 1401 { 1402 win_skip("_vsnwprintf_s not available\n"); 1403 return; 1404 } 1405 1406 /* Enough room. */ 1407 exp = wcslen(out7); 1408 1409 got = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, format, 123); 1410 ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); 1411 ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); 1412 1413 got = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, format, 123); 1414 ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); 1415 ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); 1416 1417 got = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, format, 123); 1418 ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); 1419 ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); 1420 1421 /* Not enough room. */ 1422 exp = -1; 1423 1424 got = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, format, 123); 1425 ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); 1426 ok( !wcscmp(out6, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); 1427 1428 got = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, format, 123); 1429 ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); 1430 ok( !wcscmp(out2, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); 1431 1432 got = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, format, 123); 1433 ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); 1434 ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); 1435 } 1436 1437 static int __cdecl _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer, 1438 const char *format, ...) 1439 { 1440 int ret; 1441 __ms_va_list valist; 1442 __ms_va_start(valist, format); 1443 ret = p__vsprintf_p(str, sizeOfBuffer, format, valist); 1444 __ms_va_end(valist); 1445 return ret; 1446 } 1447 1448 static void test_vsprintf_p(void) 1449 { 1450 char buf[1024]; 1451 int ret; 1452 1453 if(!p__vsprintf_p) { 1454 win_skip("vsprintf_p not available\n"); 1455 return; 1456 } 1457 1458 ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%s %d", "test", 1234); 1459 ok(ret == 9, "ret = %d\n", ret); 1460 ok(!memcmp(buf, "test 1234", 10), "buf = %s\n", buf); 1461 1462 ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%1$d", 1234, "additional param"); 1463 ok(ret == 4, "ret = %d\n", ret); 1464 ok(!memcmp(buf, "1234", 5), "buf = %s\n", buf); 1465 1466 ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%2$s %1$d", 1234, "test"); 1467 ok(ret == 9, "ret = %d\n", ret); 1468 ok(!memcmp(buf, "test 1234", 10), "buf = %s\n", buf); 1469 1470 ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%2$*3$s %2$.*1$s", 2, "test", 3); 1471 ok(ret == 7, "ret = %d\n", ret); 1472 ok(!memcmp(buf, "test te", 8), "buf = %s\n", buf); 1473 1474 /* Following test invokes invalid parameter handler */ 1475 /* ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%d %1$d", 1234); */ 1476 } 1477 1478 static void test__get_output_format(void) 1479 { 1480 unsigned int ret; 1481 char buf[64]; 1482 int c; 1483 1484 if (!p__get_output_format || !p__set_output_format) 1485 { 1486 win_skip("_get_output_format or _set_output_format is not available\n"); 1487 return; 1488 } 1489 1490 ret = p__get_output_format(); 1491 ok(ret == 0, "got %d\n", ret); 1492 1493 c = sprintf(buf, "%E", 1.23); 1494 ok(c == 13, "c = %d\n", c); 1495 ok(!strcmp(buf, "1.230000E+000"), "buf = %s\n", buf); 1496 1497 ret = p__set_output_format(_TWO_DIGIT_EXPONENT); 1498 ok(ret == 0, "got %d\n", ret); 1499 1500 c = sprintf(buf, "%E", 1.23); 1501 ok(c == 12, "c = %d\n", c); 1502 ok(!strcmp(buf, "1.230000E+00"), "buf = %s\n", buf); 1503 1504 ret = p__get_output_format(); 1505 ok(ret == _TWO_DIGIT_EXPONENT, "got %d\n", ret); 1506 1507 ret = p__set_output_format(_TWO_DIGIT_EXPONENT); 1508 ok(ret == _TWO_DIGIT_EXPONENT, "got %d\n", ret); 1509 } 1510 1511 START_TEST(printf) 1512 { 1513 init(); 1514 1515 test_sprintf(); 1516 test_swprintf(); 1517 test_snprintf(); 1518 test_fprintf(); 1519 test_fcvt(); 1520 test_xcvt(); 1521 test_vsnwprintf(); 1522 test_vscprintf(); 1523 test_vscwprintf(); 1524 test_vswprintf(); 1525 test_vsnwprintf_s(); 1526 test_vsprintf_p(); 1527 test__get_output_format(); 1528 } 1529