Reactos
at master 860 lines 28 kB view raw
1/* 2 * Copyright 2015 Martin Storsjo 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19#include <errno.h> 20#include <stdarg.h> 21#include <stdlib.h> 22#include <wchar.h> 23#include <stdio.h> 24#include <locale.h> 25#include <mbctype.h> 26#include <mbstring.h> 27 28#include <windef.h> 29#include <winbase.h> 30#include "wine/test.h" 31 32#include <math.h> 33 34#define DEFINE_EXPECT(func) \ 35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE 36 37#define SET_EXPECT(func) \ 38 expect_ ## func = TRUE 39 40#define CHECK_EXPECT2(func) \ 41 do { \ 42 ok(expect_ ##func, "unexpected call " #func "\n"); \ 43 called_ ## func = TRUE; \ 44 }while(0) 45 46#define CHECK_EXPECT(func) \ 47 do { \ 48 CHECK_EXPECT2(func); \ 49 expect_ ## func = FALSE; \ 50 }while(0) 51 52#define CHECK_CALLED(func) \ 53 do { \ 54 ok(called_ ## func, "expected " #func "\n"); \ 55 expect_ ## func = called_ ## func = FALSE; \ 56 }while(0) 57 58DEFINE_EXPECT(invalid_parameter_handler); 59 60static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, 61 const wchar_t *function, const wchar_t *file, 62 unsigned line, uintptr_t arg) 63{ 64 CHECK_EXPECT(invalid_parameter_handler); 65 ok(expression == NULL, "expression is not NULL\n"); 66 ok(function == NULL, "function is not NULL\n"); 67 ok(file == NULL, "file is not NULL\n"); 68 ok(line == 0, "line = %u\n", line); 69 ok(arg == 0, "arg = %Ix\n", arg); 70} 71 72_ACRTIMP int __cdecl _o_tolower(int); 73_ACRTIMP int __cdecl _o_toupper(int); 74 75static BOOL local_isnan(double d) 76{ 77 return d != d; 78} 79 80#define test_strtod_str_errno(string, value, length, err) _test_strtod_str(__LINE__, string, value, length, err) 81#define test_strtod_str(string, value, length) _test_strtod_str(__LINE__, string, value, length, 0) 82static void _test_strtod_str(int line, const char* string, double value, int length, int err) 83{ 84 char *end; 85 double d; 86 errno = 0xdeadbeef; 87 d = strtod(string, &end); 88 if(!err) 89 ok_(__FILE__, line)(errno == 0xdeadbeef, "errno = %d\n", errno); 90 else 91 ok_(__FILE__, line)(errno == err, "errno = %d\n", errno); 92 if (local_isnan(value)) 93 ok_(__FILE__, line)(local_isnan(d), "d = %.16le (\"%s\")\n", d, string); 94 else 95 ok_(__FILE__, line)(d == value, "d = %.16le (\"%s\")\n", d, string); 96 ok_(__FILE__, line)(end == string + length, "incorrect end (%d, \"%s\")\n", (int)(end - string), string); 97} 98 99static void test_strtod(void) 100{ 101 test_strtod_str("infinity", INFINITY, 8); 102 test_strtod_str("INFINITY", INFINITY, 8); 103 test_strtod_str("InFiNiTy", INFINITY, 8); 104 test_strtod_str("INF", INFINITY, 3); 105 test_strtod_str("-inf", -INFINITY, 4); 106 test_strtod_str("inf42", INFINITY, 3); 107 test_strtod_str("inffoo", INFINITY, 3); 108 test_strtod_str("infini", INFINITY, 3); 109 test_strtod_str("input", 0, 0); 110 test_strtod_str("-input", 0, 0); 111 test_strtod_str_errno("1.7976931348623159e+308", INFINITY, 23, ERANGE); 112 test_strtod_str_errno("-1.7976931348623159e+308", -INFINITY, 24, ERANGE); 113 114 test_strtod_str("NAN", NAN, 3); 115 test_strtod_str("nan", NAN, 3); 116 test_strtod_str("NaN", NAN, 3); 117 118 test_strtod_str("0x42", 66, 4); 119 test_strtod_str("0X42", 66, 4); 120 test_strtod_str("-0x42", -66, 5); 121 test_strtod_str("0x1p1", 2, 5); 122 test_strtod_str("0x1P1", 2, 5); 123 test_strtod_str("0x1p+1", 2, 6); 124 test_strtod_str("0x2p-1", 1, 6); 125 test_strtod_str("0xA", 10, 3); 126 test_strtod_str("0xa", 10, 3); 127 test_strtod_str("0xABCDEF", 11259375, 8); 128 test_strtod_str("0Xabcdef", 11259375, 8); 129 130 test_strtod_str("0x1.1", 1.0625, 5); 131 test_strtod_str("0x1.1p1", 2.125, 7); 132 test_strtod_str("0x1.A", 1.625, 5); 133 test_strtod_str("0x1p1a", 2, 5); 134 test_strtod_str("0xp3", 0, 1); 135 test_strtod_str("0x.", 0, 1); 136 test_strtod_str("0x.8", 0.5, 4); 137 test_strtod_str("0x.8p", 0.5, 4); 138 test_strtod_str("0x0p10000000000000000000000000", 0, 30); 139 test_strtod_str("0x1p-1026", 1.3906711615670009e-309, 9); 140 141 test_strtod_str("0x1ffffffffffffe.80000000000000000000", 9007199254740990.0, 37); 142 test_strtod_str("0x1ffffffffffffe.80000000000000000001", 9007199254740991.0, 37); 143 test_strtod_str("0x1fffffffffffff.80000000000000000000", 9007199254740992.0, 37); 144 test_strtod_str("0x1fffffffffffff.80000000000000000001", 9007199254740992.0, 37); 145 146 test_strtod_str("4.0621786324484881721115322e-53", 4.0621786324484881721115322e-53, 31); 147 test_strtod_str("1.8905590910042396899370942", 1.8905590910042396899370942, 27); 148 test_strtod_str("1.7976931348623158e+308", 1.7976931348623158e+308, 23); 149 test_strtod_str("2.2250738585072014e-308", 2.2250738585072014e-308, 23); 150 test_strtod_str("4.9406564584124654e-324", 4.9406564584124654e-324, 23); 151 test_strtod_str("2.48e-324", 4.9406564584124654e-324, 9); 152 test_strtod_str_errno("2.47e-324", 0, 9, ERANGE); 153} 154 155static void test_strtof(void) 156{ 157 static const struct { 158 const char *str; 159 int len; 160 float ret; 161 int err; 162 } tests[] = { 163 { "12.1", 4, 12.1f }, 164 { "-13.721", 7, -13.721f }, 165 { "1.e40", 5, INFINITY, ERANGE }, 166 { "-1.e40", 6, -INFINITY, ERANGE }, 167 { "0.0", 3, 0.0f }, 168 { "-0.0", 4, 0.0f }, 169 { "1.4e-45", 7, 1.4e-45f }, 170 { "-1.4e-45", 8, -1.4e-45f }, 171 { "1.e-60", 6, 0, ERANGE }, 172 { "-1.e-60", 7, 0, ERANGE }, 173 }; 174 175 char *end; 176 float f; 177 int i; 178 179 for (i=0; i<ARRAY_SIZE(tests); i++) 180 { 181 errno = 0xdeadbeef; 182 f = strtof(tests[i].str, &end); 183 ok(f == tests[i].ret, "%d) f = %.16e\n", i, f); 184 ok(end == tests[i].str + tests[i].len, "%d) len = %d\n", 185 i, (int)(end - tests[i].str)); 186 ok(errno == tests[i].err || (!tests[i].err && errno == 0xdeadbeef), 187 "%d) errno = %d\n", i, errno); 188 } 189} 190 191static void test__memicmp(void) 192{ 193 static const char *s1 = "abc"; 194 static const char *s2 = "aBd"; 195 int ret; 196 197 ret = _memicmp(NULL, NULL, 0); 198 ok(!ret, "got %d\n", ret); 199 200 SET_EXPECT(invalid_parameter_handler); 201 errno = 0xdeadbeef; 202 ret = _memicmp(NULL, NULL, 1); 203 ok(ret == _NLSCMPERROR, "got %d\n", ret); 204 ok(errno == EINVAL, "Unexpected errno = %d\n", errno); 205 CHECK_CALLED(invalid_parameter_handler); 206 207 SET_EXPECT(invalid_parameter_handler); 208 errno = 0xdeadbeef; 209 ret = _memicmp(s1, NULL, 1); 210 ok(ret == _NLSCMPERROR, "got %d\n", ret); 211 ok(errno == EINVAL, "Unexpected errno = %d\n", errno); 212 CHECK_CALLED(invalid_parameter_handler); 213 214 SET_EXPECT(invalid_parameter_handler); 215 errno = 0xdeadbeef; 216 ret = _memicmp(NULL, s2, 1); 217 ok(ret == _NLSCMPERROR, "got %d\n", ret); 218 ok(errno == EINVAL, "Unexpected errno = %d\n", errno); 219 CHECK_CALLED(invalid_parameter_handler); 220 221 ret = _memicmp(s1, s2, 2); 222 ok(!ret, "got %d\n", ret); 223 224 ret = _memicmp(s1, s2, 3); 225 ok(ret == -1, "got %d\n", ret); 226} 227 228static void test__memicmp_l(void) 229{ 230 static const char *s1 = "abc"; 231 static const char *s2 = "aBd"; 232 int ret; 233 234 ret = _memicmp_l(NULL, NULL, 0, NULL); 235 ok(!ret, "got %d\n", ret); 236 237 SET_EXPECT(invalid_parameter_handler); 238 errno = 0xdeadbeef; 239 ret = _memicmp_l(NULL, NULL, 1, NULL); 240 ok(ret == _NLSCMPERROR, "got %d\n", ret); 241 ok(errno == EINVAL, "Unexpected errno = %d\n", errno); 242 CHECK_CALLED(invalid_parameter_handler); 243 244 SET_EXPECT(invalid_parameter_handler); 245 errno = 0xdeadbeef; 246 ret = _memicmp_l(s1, NULL, 1, NULL); 247 ok(ret == _NLSCMPERROR, "got %d\n", ret); 248 ok(errno == EINVAL, "Unexpected errno = %d\n", errno); 249 CHECK_CALLED(invalid_parameter_handler); 250 251 SET_EXPECT(invalid_parameter_handler); 252 errno = 0xdeadbeef; 253 ret = _memicmp_l(NULL, s2, 1, NULL); 254 ok(ret == _NLSCMPERROR, "got %d\n", ret); 255 ok(errno == EINVAL, "Unexpected errno = %d\n", errno); 256 CHECK_CALLED(invalid_parameter_handler); 257 258 ret = _memicmp_l(s1, s2, 2, NULL); 259 ok(!ret, "got %d\n", ret); 260 261 ret = _memicmp_l(s1, s2, 3, NULL); 262 ok(ret == -1, "got %d\n", ret); 263} 264 265 266static void test___strncnt(void) 267{ 268 static const struct 269 { 270 const char *str; 271 size_t size; 272 size_t ret; 273 } 274 strncnt_tests[] = 275 { 276 { "a", 0, 0 }, 277 { "a", 1, 1 }, 278 { "a", 10, 1 }, 279 { "abc", 1, 1 }, 280 }; 281 unsigned int i; 282 size_t ret; 283 284 for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i) 285 { 286 ret = __strncnt(strncnt_tests[i].str, strncnt_tests[i].size); 287 ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret); 288 } 289 290 if (0) /* crashes */ 291 { 292 ret = __strncnt(NULL, 0); 293 ret = __strncnt(NULL, 1); 294 } 295} 296 297static void test_C_locale(void) 298{ 299 int i, j; 300 wint_t ret, exp; 301 _locale_t locale; 302 static const char *locales[] = { NULL, "C" }; 303 304 /* C locale only converts case for [a-zA-Z] */ 305 setlocale(LC_ALL, "C"); 306 for (i = 0; i <= 0xffff; i++) 307 { 308 ret = tolower(i); 309 if (i >= 'A' && i <= 'Z') 310 { 311 exp = i + 'a' - 'A'; 312 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 313 } 314 else 315 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 316 317 ret = _tolower(i); 318 exp = i + 'a' - 'A'; 319 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 320 321 ret = _o_tolower(i); 322 if (i >= 'A' && i <= 'Z') 323 { 324 exp = i + 'a' - 'A'; 325 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 326 } 327 else 328 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 329 330 ret = towlower(i); 331 if (i >= 'A' && i <= 'Z') 332 { 333 exp = i + 'a' - 'A'; 334 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 335 } 336 else 337 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 338 339 ret = toupper(i); 340 if (i >= 'a' && i <= 'z') 341 { 342 exp = i + 'A' - 'a'; 343 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 344 } 345 else 346 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 347 348 ret = _toupper(i); 349 exp = i + 'A' - 'a'; 350 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 351 352 ret = _o_toupper(i); 353 if (i >= 'a' && i <= 'z') 354 { 355 exp = i + 'A' - 'a'; 356 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 357 } 358 else 359 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 360 361 ret = towupper(i); 362 if (i >= 'a' && i <= 'z') 363 { 364 exp = i + 'A' - 'a'; 365 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 366 } 367 else 368 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 369 } 370 371 for (i = 0; i < ARRAY_SIZE(locales); i++) { 372 locale = locales[i] ? _create_locale(LC_ALL, locales[i]) : NULL; 373 374 for (j = 0; j <= 0xffff; j++) { 375 ret = _towlower_l(j, locale); 376 if (j >= 'A' && j <= 'Z') 377 { 378 exp = j + 'a' - 'A'; 379 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 380 } 381 else 382 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); 383 384 ret = _towupper_l(j, locale); 385 if (j >= 'a' && j <= 'z') 386 { 387 exp = j + 'A' - 'a'; 388 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 389 } 390 else 391 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); 392 } 393 394 _free_locale(locale); 395 } 396} 397 398static void test_mbsspn( void) 399{ 400 unsigned char str1[] = "cabernet"; 401 unsigned char str2[] = "shiraz"; 402 unsigned char set[] = "abc"; 403 unsigned char empty[] = ""; 404 unsigned char mbstr[] = " 2019\x94\x4e" "6\x8c\x8e" "29\x93\xfa"; 405 unsigned char mbset1[] = "0123456789 \x94\x4e"; 406 unsigned char mbset2[] = " \x94\x4e\x8c\x8e"; 407 unsigned char mbset3[] = "\x8e"; 408 int ret, cp = _getmbcp(); 409 410 ret = _mbsspn(str1, set); 411 ok(ret == 3, "_mbsspn returns %d should be 3\n", ret); 412 ret = _mbsspn(str2, set); 413 ok(ret == 0, "_mbsspn returns %d should be 0\n", ret); 414 ret = _mbsspn(str1, empty); 415 ok(ret == 0, "_mbsspn returns %d should be 0\n", ret); 416 417 _setmbcp(932); 418 ret = _mbsspn(mbstr, mbset1); 419 ok(ret == 8, "_mbsspn returns %d should be 8\n", ret); 420 ret = _mbsspn(mbstr, mbset2); 421 ok(ret == 1, "_mbsspn returns %d should be 1\n", ret); 422 ret = _mbsspn(mbstr+8, mbset1); 423 ok(ret == 0, "_mbsspn returns %d should be 0\n", ret); 424 ret = _mbsspn(mbstr+8, mbset2); 425 ok(ret == 2, "_mbsspn returns %d should be 2\n", ret); 426 ret = _mbsspn(mbstr, mbset3); 427 ok(ret == 14, "_mbsspn returns %d should be 14\n", ret); 428 429 _setmbcp(cp); 430} 431 432static void test_wcstok(void) 433{ 434 static const wchar_t *input = L"two words"; 435 wchar_t buffer[16]; 436 wchar_t *token; 437 wchar_t *next; 438 439 next = NULL; 440 wcscpy(buffer, input); 441 token = wcstok(buffer, L" ", &next); 442 ok(!wcscmp(L"two", token), "expected \"two\", got \"%ls\"\n", token); 443 ok(next == token + 4, "expected %p, got %p\n", token + 4, next); 444 token = wcstok(NULL, L" ", &next); 445 ok(!wcscmp(L"words", token), "expected \"words\", got \"%ls\"\n", token); 446 ok(next == token + 5, "expected %p, got %p\n", token + 5, next); 447 token = wcstok(NULL, L" ", &next); 448 ok(!token, "expected NULL, got %p\n", token); 449 450 wcscpy(buffer, input); 451 token = wcstok(buffer, L" ", NULL); 452 ok(!wcscmp(L"two", token), "expected \"two\", got \"%ls\"\n", token); 453 token = wcstok(NULL, L" ", NULL); 454 ok(!wcscmp(L"words", token), "expected \"words\", got \"%ls\"\n", token); 455 token = wcstok(NULL, L" ", NULL); 456 ok(!token, "expected NULL, got %p\n", token); 457 458 next = NULL; 459 wcscpy(buffer, input); 460 token = wcstok(buffer, L"=", &next); 461 ok(!wcscmp(token, input), "expected \"%ls\", got \"%ls\"\n", input, token); 462 ok(next == buffer + wcslen(input), "expected %p, got %p\n", buffer + wcslen(input), next); 463 token = wcstok(NULL, L"=", &next); 464 ok(!token, "expected NULL, got \"%ls\"\n", token); 465 ok(next == buffer + wcslen(input), "expected %p, got %p\n", buffer + wcslen(input), next); 466 467 next = NULL; 468 wcscpy(buffer, L""); 469 token = wcstok(buffer, L"=", &next); 470 ok(token == NULL, "expected NULL, got \"%ls\"\n", token); 471 ok(next == buffer, "expected %p, got %p\n", buffer, next); 472 token = wcstok(NULL, L"=", &next); 473 ok(!token, "expected NULL, got \"%ls\"\n", token); 474 ok(next == buffer, "expected %p, got %p\n", buffer, next); 475} 476 477static void test__strnicmp(void) 478{ 479 static const char str1[] = "TEST"; 480 static const char str2[] = "test"; 481 int ret; 482 483 SET_EXPECT(invalid_parameter_handler); 484 errno = 0xdeadbeef; 485 ret = _strnicmp(str1, NULL, 2); 486 CHECK_CALLED(invalid_parameter_handler); 487 ok(ret == _NLSCMPERROR, "got %d.\n", ret); 488 ok(errno == EINVAL, "Unexpected errno %d.\n", errno); 489 490 SET_EXPECT(invalid_parameter_handler); 491 errno = 0xdeadbeef; 492 ret = _strnicmp(str1, str2, -1); 493 CHECK_CALLED(invalid_parameter_handler); 494 ok(ret == _NLSCMPERROR, "got %d.\n", ret); 495 ok(errno == EINVAL, "Unexpected errno %d.\n", errno); 496 497 ret = _strnicmp(str1, str2, 0); 498 ok(!ret, "got %d.\n", ret); 499 500 ret = _strnicmp(str1, str2, 0x7fffffff); 501 ok(!ret, "got %d.\n", ret); 502 503 /* If numbers of characters to compare is too big return error */ 504 SET_EXPECT(invalid_parameter_handler); 505 errno = 0xdeadbeef; 506 ret = _strnicmp(str1, str2, 0x80000000); 507 CHECK_CALLED(invalid_parameter_handler); 508 ok(ret == _NLSCMPERROR, "got %d.\n", ret); 509 ok(errno == EINVAL, "Unexpected errno %d.\n", errno); 510} 511 512static void test_wcsnicmp(void) 513{ 514 static const wchar_t str1[] = L"TEST"; 515 static const wchar_t str2[] = L"test"; 516 int ret; 517 518 errno = 0xdeadbeef; 519 ret = wcsnicmp(str1, str2, -1); 520 ok(!ret, "got %d.\n", ret); 521 522 ret = wcsnicmp(str1, str2, 0x7fffffff); 523 ok(!ret, "got %d.\n", ret); 524} 525 526static void test_SpecialCasing(void) 527{ 528 int i; 529 wint_t ret, exp; 530 _locale_t locale; 531 struct test { 532 const char *lang; 533 wint_t ch; 534 wint_t exp; 535 }; 536 537 struct test ucases[] = { 538 {"English", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ 539 {"English", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ 540 541 {"Turkish", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ 542 {"Turkish", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ 543 }; 544 struct test lcases[] = { 545 {"English", 'i', 'I'}, /* LATIN SMALL LETTER I */ 546 {"English", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ 547 548 {"Turkish", 'i', 'I'}, /* LATIN SMALL LETTER I */ 549 {"Turkish", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ 550 }; 551 552 for (i = 0; i < ARRAY_SIZE(ucases); i++) { 553 if (!setlocale(LC_ALL, ucases[i].lang)) { 554 win_skip("skipping special case tests for %s\n", ucases[i].lang); 555 continue; 556 } 557 558 ret = towlower(ucases[i].ch); 559 exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; 560 ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", exp, ret, ucases[i].lang); 561 } 562 563 for (i = 0; i < ARRAY_SIZE(lcases); i++) { 564 if (!setlocale(LC_ALL, lcases[i].lang)) { 565 win_skip("skipping special case tests for %s\n", lcases[i].lang); 566 continue; 567 } 568 569 ret = towupper(lcases[i].ch); 570 exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; 571 ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", exp, ret, lcases[i].lang); 572 } 573 574 setlocale(LC_ALL, "C"); 575 576 /* test _towlower_l creating locale */ 577 for (i = 0; i < ARRAY_SIZE(ucases); i++) { 578 if (!(locale = _create_locale(LC_ALL, ucases[i].lang))) { 579 win_skip("locale %s not available. skipping\n", ucases[i].lang); 580 continue; 581 } 582 583 ret = _towlower_l(ucases[i].ch, locale); 584 exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; 585 ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", exp, ret, ucases[i].lang); 586 587 _free_locale(locale); 588 } 589 590 /* test _towupper_l creating locale */ 591 for (i = 0; i < ARRAY_SIZE(lcases); i++) { 592 if (!(locale = _create_locale(LC_ALL, lcases[i].lang))) { 593 win_skip("locale %s not available. skipping\n", lcases[i].lang); 594 continue; 595 } 596 597 ret = _towupper_l(lcases[i].ch, locale); 598 exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; 599 ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", exp, ret, lcases[i].lang); 600 601 _free_locale(locale); 602 } 603} 604 605static void test__mbbtype_l(void) 606{ 607 int expected, ret; 608 unsigned int c; 609 610 _setmbcp(_MB_CP_LOCALE); 611 for (c = 0; c < 256; ++c) 612 { 613 expected = _mbbtype(c, 0); 614 ret = _mbbtype_l(c, 0, NULL); 615 ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected); 616 617 expected = _mbbtype(c, 1); 618 ret = _mbbtype_l(c, 1, NULL); 619 ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected); 620 } 621} 622 623static void test_strcmp(void) 624{ 625 int ret = strcmp( "abc", "abcd" ); 626 ok( ret == -1, "wrong ret %d\n", ret ); 627 ret = strcmp( "", "abc" ); 628 ok( ret == -1, "wrong ret %d\n", ret ); 629 ret = strcmp( "abc", "ab\xa0" ); 630 ok( ret == -1, "wrong ret %d\n", ret ); 631 ret = strcmp( "ab\xb0", "ab\xa0" ); 632 ok( ret == 1, "wrong ret %d\n", ret ); 633 ret = strcmp( "ab\xc2", "ab\xc2" ); 634 ok( ret == 0, "wrong ret %d\n", ret ); 635 636 ret = strncmp( "abc", "abcd", 3 ); 637 ok( ret == 0, "wrong ret %d\n", ret ); 638 ret = strncmp( "", "abc", 3 ); 639 ok( ret == -1, "wrong ret %d\n", ret ); 640 ret = strncmp( "abc", "ab\xa0", 4 ); 641 ok( ret == -1, "wrong ret %d\n", ret ); 642 ret = strncmp( "ab\xb0", "ab\xa0", 3 ); 643 ok( ret == 1, "wrong ret %d\n", ret ); 644 ret = strncmp( "ab\xb0", "ab\xa0", 2 ); 645 ok( ret == 0, "wrong ret %d\n", ret ); 646 ret = strncmp( "ab\xc2", "ab\xc2", 3 ); 647 ok( ret == 0, "wrong ret %d\n", ret ); 648 ret = strncmp( "abc", "abd", 0 ); 649 ok( ret == 0, "wrong ret %d\n", ret ); 650 ret = strncmp( "abc", "abc", 12 ); 651 ok( ret == 0, "wrong ret %d\n", ret ); 652} 653 654#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, \ 655 "Binary buffer mismatch - expected %s, got %s\n", \ 656 debugstr_an(value, len), debugstr_an((char *)(buf), len)); } 657 658static void test__mbsncpy_s(void) 659{ 660 unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5\x0"; 661 unsigned char *mbstring2 = (unsigned char *)"\xb0\x0"; 662 unsigned char buf[16]; 663 errno_t err; 664 int oldcp; 665 666 oldcp = _getmbcp(); 667 if (_setmbcp(936)) 668 { 669 skip("Code page 936 is not available, skipping test.\n"); 670 return; 671 } 672 673 errno = 0xdeadbeef; 674 memset(buf, 0xcc, sizeof(buf)); 675 err = _mbsncpy_s(NULL, 0, mbstring, 0); 676 ok(errno == 0xdeadbeef, "got %d\n", errno); 677 ok(!err, "got %d.\n", err); 678 679 errno = 0xdeadbeef; 680 memset(buf, 0xcc, sizeof(buf)); 681 err = _mbsncpy_s(buf, 6, mbstring, 1); 682 ok(errno == 0xdeadbeef, "got %d\n", errno); 683 ok(!err, "got %d.\n", err); 684 expect_bin(buf, "\xb0\xb1\0\xcc", 4); 685 686 memset(buf, 0xcc, sizeof(buf)); 687 errno = 0xdeadbeef; 688 err = _mbsncpy_s(buf, 6, mbstring, 2); 689 ok(errno == 0xdeadbeef, "got %d\n", errno); 690 ok(!err, "got %d.\n", err); 691 expect_bin(buf, "\xb0\xb1\xb2\xb3\0\xcc", 6); 692 693 errno = 0xdeadbeef; 694 memset(buf, 0xcc, sizeof(buf)); 695 err = _mbsncpy_s(buf, 2, mbstring, _TRUNCATE); 696 ok(errno == 0xdeadbeef, "got %d\n", errno); 697 ok(err == STRUNCATE, "got %d.\n", err); 698 expect_bin(buf, "\x00\xb1\xcc", 3); 699 700 memset(buf, 0xcc, sizeof(buf)); 701 SET_EXPECT(invalid_parameter_handler); 702 errno = 0xdeadbeef; 703 err = _mbsncpy_s(buf, 2, mbstring, 1); 704 ok(errno == err, "got %d.\n", errno); 705 CHECK_CALLED(invalid_parameter_handler); 706 ok(err == ERANGE, "got %d.\n", err); 707 expect_bin(buf, "\x0\xcc\xcc", 3); 708 709 memset(buf, 0xcc, sizeof(buf)); 710 SET_EXPECT(invalid_parameter_handler); 711 errno = 0xdeadbeef; 712 err = _mbsncpy_s(buf, 2, mbstring, 3); 713 ok(errno == err, "got %d\n", errno); 714 CHECK_CALLED(invalid_parameter_handler); 715 ok(err == ERANGE, "got %d.\n", err); 716 expect_bin(buf, "\x0\xcc\xcc", 3); 717 718 memset(buf, 0xcc, sizeof(buf)); 719 SET_EXPECT(invalid_parameter_handler); 720 errno = 0xdeadbeef; 721 err = _mbsncpy_s(buf, 1, mbstring, 3); 722 ok(errno == err, "got %d\n", errno); 723 CHECK_CALLED(invalid_parameter_handler); 724 ok(err == ERANGE, "got %d.\n", err); 725 expect_bin(buf, "\x0\xcc", 2); 726 727 memset(buf, 0xcc, sizeof(buf)); 728 SET_EXPECT(invalid_parameter_handler); 729 errno = 0xdeadbeef; 730 err = _mbsncpy_s(buf, 0, mbstring, 3); 731 ok(errno == err, "got %d\n", errno); 732 CHECK_CALLED(invalid_parameter_handler); 733 ok(err == EINVAL, "got %d.\n", err); 734 expect_bin(buf, "\xcc", 1); 735 736 memset(buf, 0xcc, sizeof(buf)); 737 SET_EXPECT(invalid_parameter_handler); 738 errno = 0xdeadbeef; 739 err = _mbsncpy_s(buf, 0, mbstring, 0); 740 ok(errno == err, "got %d\n", errno); 741 CHECK_CALLED(invalid_parameter_handler); 742 ok(err == EINVAL, "got %d.\n", err); 743 expect_bin(buf, "\xcc", 1); 744 745 memset(buf, 0xcc, sizeof(buf)); 746 errno = 0xdeadbeef; 747 err = _mbsncpy_s(buf, -1, mbstring, 0); 748 ok(errno == 0xdeadbeef, "got %d\n", errno); 749 ok(!err, "got %d.\n", err); 750 expect_bin(buf, "\x0\xcc", 2); 751 752 memset(buf, 0xcc, sizeof(buf)); 753 errno = 0xdeadbeef; 754 err = _mbsncpy_s(buf, -1, mbstring, 256); 755 ok(errno == 0xdeadbeef, "got %d\n", errno); 756 ok(!err, "got %d.\n", err); 757 expect_bin(buf, "\xb0\xb1\xb2\xb3Q\xb4\xb5\x0\xcc", 9); 758 759 memset(buf, 0xcc, sizeof(buf)); 760 errno = 0xdeadbeef; 761 err = _mbsncpy_s(buf, 1, mbstring2, 4); 762 ok(errno == err, "got %d\n", errno); 763 ok(err == EILSEQ, "got %d.\n", err); 764 expect_bin(buf, "\x0\xcc", 2); 765 766 memset(buf, 0xcc, sizeof(buf)); 767 errno = 0xdeadbeef; 768 err = _mbsncpy_s(buf, 2, mbstring2, 4); 769 ok(errno == err, "got %d\n", errno); 770 ok(err == EILSEQ, "got %d.\n", err); 771 expect_bin(buf, "\x0\xcc", 2); 772 773 memset(buf, 0xcc, sizeof(buf)); 774 errno = 0xdeadbeef; 775 err = _mbsncpy_s(buf, 1, mbstring2, _TRUNCATE); 776 ok(errno == 0xdeadbeef, "got %d\n", errno); 777 ok(err == STRUNCATE, "got %d.\n", err); 778 expect_bin(buf, "\x0\xcc", 2); 779 780 memset(buf, 0xcc, sizeof(buf)); 781 errno = 0xdeadbeef; 782 err = _mbsncpy_s(buf, 2, mbstring2, _TRUNCATE); 783 ok(errno == 0xdeadbeef, "got %d\n", errno); 784 ok(!err, "got %d.\n", err); 785 expect_bin(buf, "\xb0\x0\xcc", 3); 786 787 memset(buf, 0xcc, sizeof(buf)); 788 errno = 0xdeadbeef; 789 err = _mbsncpy_s(buf, 1, mbstring2, 1); 790 ok(errno == err, "got %d\n", errno); 791 ok(err == EILSEQ, "got %d.\n", err); 792 expect_bin(buf, "\x0\xcc", 2); 793 794 memset(buf, 0xcc, sizeof(buf)); 795 errno = 0xdeadbeef; 796 err = _mbsncpy_s(buf, 2, mbstring2, 1); 797 ok(errno == err, "got %d\n", errno); 798 ok(err == EILSEQ, "got %d.\n", err); 799 expect_bin(buf, "\x0\xcc", 2); 800 801 memset(buf, 0xcc, sizeof(buf)); 802 errno = 0xdeadbeef; 803 err = _mbsncpy_s(buf, 3, mbstring2, 1); 804 ok(errno == err, "got %d\n", errno); 805 ok(err == EILSEQ, "got %d.\n", err); 806 expect_bin(buf, "\x0\xcc", 2); 807 808 memset(buf, 0xcc, sizeof(buf)); 809 errno = 0xdeadbeef; 810 err = _mbsncpy_s(buf, 3, mbstring2, 2); 811 ok(errno == err, "got %d\n", errno); 812 ok(err == EILSEQ, "got %d.\n", err); 813 expect_bin(buf, "\x0\xcc", 2); 814 815 _setmbcp(oldcp); 816} 817 818static void test_mbstowcs(void) 819{ 820 static const char mbs[] = { 0xc3, 0xa9, 0 }; 821 WCHAR wcs[2]; 822 size_t ret; 823 824 if (!setlocale(LC_ALL, "en_US.UTF-8")) 825 { 826 win_skip("skipping UTF8 mbstowcs tests\n"); 827 return; 828 } 829 830 ret = mbstowcs(NULL, mbs, 0); 831 ok(ret == 1, "mbstowcs returned %Id\n", ret); 832 memset(wcs, 0xfe, sizeof(wcs)); 833 ret = mbstowcs(wcs, mbs, 1); 834 ok(ret == 1, "mbstowcs returned %Id\n", ret); 835 ok(wcs[0] == 0xe9, "wcsstring[0] = %x\n", wcs[0]); 836 ok(wcs[1] == 0xfefe, "wcsstring[1] = %x\n", wcs[1]); 837 setlocale(LC_ALL, "C"); 838} 839 840START_TEST(string) 841{ 842 ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL, 843 "Invalid parameter handler was already set\n"); 844 845 test_strtod(); 846 test_strtof(); 847 test__memicmp(); 848 test__memicmp_l(); 849 test___strncnt(); 850 test_C_locale(); 851 test_mbsspn(); 852 test_wcstok(); 853 test__strnicmp(); 854 test_wcsnicmp(); 855 test_SpecialCasing(); 856 test__mbbtype_l(); 857 test_strcmp(); 858 test__mbsncpy_s(); 859 test_mbstowcs(); 860}