1 /* 2 * Unit test suite for string functions. 3 * 4 * Copyright 2004 Uwe Bonnes 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "wine/test.h" 22 #include <string.h> 23 #include <mbstring.h> 24 #include <wchar.h> 25 #include <stdlib.h> 26 #include <stdio.h> 27 #include <mbctype.h> 28 #include <locale.h> 29 #include <errno.h> 30 #include <limits.h> 31 #include <math.h> 32 33 /* make it use a definition from string.h */ 34 #undef strncpy 35 #include "winbase.h" 36 #include "winnls.h" 37 38 static char *buf_to_string(const unsigned char *bin, int len, int nr) 39 { 40 static char buf[2][1024]; 41 char *w = buf[nr]; 42 int i; 43 44 for (i = 0; i < len; i++) 45 { 46 sprintf(w, "%02x ", (unsigned char)bin[i]); 47 w += strlen(w); 48 } 49 return buf[nr]; 50 } 51 52 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); } 53 #define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, "Binary buffer mismatch - expected %s, got %s\n", buf_to_string((unsigned char *)value, len, 1), buf_to_string((buf), len, 0)); } 54 55 static void* (__cdecl *pmemcpy)(void *, const void *, size_t n); 56 static int (__cdecl *p_memcpy_s)(void *, size_t, const void *, size_t); 57 static int (__cdecl *p_memmove_s)(void *, size_t, const void *, size_t); 58 static int* (__cdecl *pmemcmp)(void *, const void *, size_t n); 59 static int (__cdecl *p_strcpy)(char *dst, const char *src); 60 static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src); 61 static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src); 62 static int (__cdecl *p_mbscat_s)(unsigned char *dst, size_t size, const unsigned char *src); 63 static int (__cdecl *p_mbsnbcat_s)(unsigned char *dst, size_t size, const unsigned char *src, size_t count); 64 static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count); 65 static int (__cdecl *p__mbscpy_s)(unsigned char*, size_t, const unsigned char*); 66 static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc); 67 static int (__cdecl *p_wcsncpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc, size_t count); 68 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count); 69 static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size); 70 static size_t (__cdecl *p_strnlen)(const char *, size_t); 71 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int); 72 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int); 73 static __int64 (__cdecl *p_wcstoi64)(const wchar_t *, wchar_t **, int); 74 static unsigned __int64 (__cdecl *p_wcstoui64)(const wchar_t *, wchar_t **, int); 75 static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t); 76 static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t); 77 static size_t (__cdecl *p_mbsrtowcs)(wchar_t*, const char**, size_t, mbstate_t*); 78 static int (__cdecl *p_mbsrtowcs_s)(size_t*,wchar_t*,size_t,const char**,size_t,mbstate_t*); 79 static size_t (__cdecl *pwcsrtombs)(char*, const wchar_t**, size_t, int*); 80 static errno_t (__cdecl *p_gcvt_s)(char*,size_t,double,int); 81 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int); 82 static errno_t (__cdecl *p_strlwr_s)(char*,size_t); 83 static errno_t (__cdecl *p_ultoa_s)(__msvcrt_ulong,char*,size_t,int); 84 static int *p__mb_cur_max; 85 static unsigned char *p_mbctype; 86 static int (__cdecl *p_wcslwr_s)(wchar_t*,size_t); 87 static errno_t (__cdecl *p_mbsupr_s)(unsigned char *str, size_t numberOfElements); 88 static errno_t (__cdecl *p_mbslwr_s)(unsigned char *str, size_t numberOfElements); 89 static int (__cdecl *p_wctob)(wint_t); 90 static size_t (__cdecl *p_wcrtomb)(char*, wchar_t, mbstate_t*); 91 static int (__cdecl *p_wcrtomb_s)(size_t*, char*, size_t, wchar_t, mbstate_t*); 92 static int (__cdecl *p_tolower)(int); 93 static int (__cdecl *p_towlower)(wint_t); 94 static int (__cdecl *p__towlower_l)(wint_t, _locale_t); 95 static int (__cdecl *p_towupper)(wint_t); 96 static int (__cdecl *p__towupper_l)(wint_t, _locale_t); 97 static _locale_t(__cdecl *p__create_locale)(int, const char*); 98 static void(__cdecl *p__free_locale)(_locale_t); 99 static size_t (__cdecl *p_mbrlen)(const char*, size_t, mbstate_t*); 100 static size_t (__cdecl *p_mbrtowc)(wchar_t*, const char*, size_t, mbstate_t*); 101 static int (__cdecl *p__atodbl_l)(_CRT_DOUBLE*,char*,_locale_t); 102 static double (__cdecl *p__atof_l)(const char*,_locale_t); 103 static double (__cdecl *p__strtod_l)(const char *,char**,_locale_t); 104 static int (__cdecl *p__strnset_s)(char*,size_t,int,size_t); 105 static int (__cdecl *p__wcsnset_s)(wchar_t*,size_t,wchar_t,size_t); 106 static int (__cdecl *p__wcsset_s)(wchar_t*,size_t,wchar_t); 107 static size_t (__cdecl *p__mbsnlen)(const unsigned char*, size_t); 108 static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned char*); 109 static int (__cdecl *p__memicmp)(const char*, const char*, size_t); 110 static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t); 111 static size_t (__cdecl *p___strncnt)(const char*, size_t); 112 113 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) 114 #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y) 115 116 static HMODULE hMsvcrt; 117 118 static void test_swab( void ) { 119 char original[] = "BADCFEHGJILKNMPORQTSVUXWZY@#"; 120 char expected1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#"; 121 char expected2[] = "ABCDEFGHIJKLMNOPQRSTUVWX$"; 122 char expected3[] = "$"; 123 124 char from[30]; 125 char to[30]; 126 127 int testsize; 128 129 /* Test 1 - normal even case */ 130 memset(to,'$', sizeof(to)); 131 memset(from,'@', sizeof(from)); 132 testsize = 26; 133 memcpy(from, original, testsize); 134 _swab( from, to, testsize ); 135 ok(memcmp(to,expected1,testsize) == 0, "Testing even size %d returned '%*.*s'\n", testsize, testsize, testsize, to); 136 137 /* Test 2 - uneven case */ 138 memset(to,'$', sizeof(to)); 139 memset(from,'@', sizeof(from)); 140 testsize = 25; 141 memcpy(from, original, testsize); 142 _swab( from, to, testsize ); 143 ok(memcmp(to,expected2,testsize) == 0, "Testing odd size %d returned '%*.*s'\n", testsize, testsize, testsize, to); 144 145 /* Test 3 - from = to */ 146 memset(to,'$', sizeof(to)); 147 memset(from,'@', sizeof(from)); 148 testsize = 26; 149 memcpy(to, original, testsize); 150 _swab( to, to, testsize ); 151 ok(memcmp(to,expected1,testsize) == 0, "Testing overlapped size %d returned '%*.*s'\n", testsize, testsize, testsize, to); 152 153 /* Test 4 - 1 bytes */ 154 memset(to,'$', sizeof(to)); 155 memset(from,'@', sizeof(from)); 156 testsize = 1; 157 memcpy(from, original, testsize); 158 _swab( from, to, testsize ); 159 ok(memcmp(to,expected3,testsize) == 0, "Testing small size %d returned '%*.*s'\n", testsize, testsize, testsize, to); 160 } 161 162 #if 0 /* use this to generate more tests */ 163 164 static void test_codepage(int cp) 165 { 166 int i; 167 int prev; 168 int count = 1; 169 170 ok(_setmbcp(cp) == 0, "Couldn't set mbcp\n"); 171 172 prev = p_mbctype[0]; 173 printf("static int result_cp_%d_mbctype[] = { ", cp); 174 for (i = 1; i < 257; i++) 175 { 176 if (p_mbctype[i] != prev) 177 { 178 printf("0x%x,%d, ", prev, count); 179 prev = p_mbctype[i]; 180 count = 1; 181 } 182 else 183 count++; 184 } 185 printf("0x%x,%d };\n", prev, count); 186 } 187 188 #else 189 190 /* RLE-encoded mbctype tables for given codepages */ 191 static int result_cp_932_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4, 192 0x0,1, 0x8,1, 0xc,31, 0x8,1, 0xa,5, 0x9,58, 0xc,29, 0,3 }; 193 static int result_cp_936_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,6, 194 0xc,126, 0,1 }; 195 static int result_cp_949_mbctype[] = { 0x0,66, 0x18,26, 0x8,6, 0x28,26, 0x8,6, 0xc,126, 196 0,1 }; 197 static int result_cp_950_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4, 198 0x0,2, 0x4,32, 0xc,94, 0,1 }; 199 200 static void test_cp_table(int cp, int *result) 201 { 202 int i; 203 int count = 0; 204 int curr = 0; 205 _setmbcp(cp); 206 for (i = 0; i < 256; i++) 207 { 208 if (count == 0) 209 { 210 curr = result[0]; 211 count = result[1]; 212 result += 2; 213 } 214 ok(p_mbctype[i] == curr, "CP%d: Mismatch in ctype for character %d - %d instead of %d\n", cp, i-1, p_mbctype[i], curr); 215 count--; 216 } 217 } 218 219 #define test_codepage(num) test_cp_table(num, result_cp_##num##_mbctype); 220 221 #endif 222 223 static void test_mbcp(void) 224 { 225 int mb_orig_max = *p__mb_cur_max; 226 int curr_mbcp = _getmbcp(); 227 unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2 \xb3\xb4 \xb5"; /* incorrect string */ 228 unsigned char *mbstring2 = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5"; /* correct string */ 229 unsigned char *mbsonlylead = (unsigned char *)"\xb0\0\xb1\xb2 \xb3"; 230 unsigned char buf[16]; 231 int step; 232 CPINFO cp_info; 233 234 /* _mbtype tests */ 235 236 /* An SBCS codepage test. The ctype of characters on e.g. CP1252 or CP1250 differs slightly 237 * between versions of Windows. Also Windows 9x seems to ignore the codepage and always uses 238 * CP1252 (or the ACP?) so we test only a few ASCII characters */ 239 _setmbcp(1252); 240 expect_eq(p_mbctype[10], 0, char, "%x"); 241 expect_eq(p_mbctype[50], 0, char, "%x"); 242 expect_eq(p_mbctype[66], _SBUP, char, "%x"); 243 expect_eq(p_mbctype[100], _SBLOW, char, "%x"); 244 expect_eq(p_mbctype[128], 0, char, "%x"); 245 _setmbcp(1250); 246 expect_eq(p_mbctype[10], 0, char, "%x"); 247 expect_eq(p_mbctype[50], 0, char, "%x"); 248 expect_eq(p_mbctype[66], _SBUP, char, "%x"); 249 expect_eq(p_mbctype[100], _SBLOW, char, "%x"); 250 expect_eq(p_mbctype[128], 0, char, "%x"); 251 252 /* double byte code pages */ 253 test_codepage(932); 254 test_codepage(936); 255 test_codepage(949); 256 test_codepage(950); 257 258 _setmbcp(936); 259 ok(*p__mb_cur_max == mb_orig_max, "__mb_cur_max shouldn't be updated (is %d != %d)\n", *p__mb_cur_max, mb_orig_max); 260 ok(_ismbblead('\354'), "\354 should be a lead byte\n"); 261 ok(_ismbblead(' ') == FALSE, "' ' should not be a lead byte\n"); 262 ok(_ismbblead(0x1234b0), "0x1234b0 should not be a lead byte\n"); 263 ok(_ismbblead(0x123420) == FALSE, "0x123420 should not be a lead byte\n"); 264 ok(_ismbbtrail('\xb0'), "\xa0 should be a trail byte\n"); 265 ok(_ismbbtrail(' ') == FALSE, "' ' should not be a trail byte\n"); 266 267 /* _ismbslead */ 268 expect_eq(_ismbslead(mbstring, &mbstring[0]), -1, int, "%d"); 269 expect_eq(_ismbslead(mbstring, &mbstring[1]), FALSE, int, "%d"); 270 expect_eq(_ismbslead(mbstring, &mbstring[2]), -1, int, "%d"); 271 expect_eq(_ismbslead(mbstring, &mbstring[3]), FALSE, int, "%d"); 272 expect_eq(_ismbslead(mbstring, &mbstring[4]), -1, int, "%d"); 273 expect_eq(_ismbslead(mbstring, &mbstring[5]), FALSE, int, "%d"); 274 expect_eq(_ismbslead(mbstring, &mbstring[6]), FALSE, int, "%d"); 275 expect_eq(_ismbslead(mbstring, &mbstring[7]), -1, int, "%d"); 276 expect_eq(_ismbslead(mbstring, &mbstring[8]), FALSE, int, "%d"); 277 278 expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[0]), -1, int, "%d"); 279 expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[1]), FALSE, int, "%d"); 280 expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[2]), FALSE, int, "%d"); 281 expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d"); 282 283 /* _ismbstrail */ 284 expect_eq(_ismbstrail(mbstring, &mbstring[0]), FALSE, int, "%d"); 285 expect_eq(_ismbstrail(mbstring, &mbstring[1]), -1, int, "%d"); 286 expect_eq(_ismbstrail(mbstring, &mbstring[2]), FALSE, int, "%d"); 287 expect_eq(_ismbstrail(mbstring, &mbstring[3]), -1, int, "%d"); 288 expect_eq(_ismbstrail(mbstring, &mbstring[4]), FALSE, int, "%d"); 289 expect_eq(_ismbstrail(mbstring, &mbstring[5]), -1, int, "%d"); 290 expect_eq(_ismbstrail(mbstring, &mbstring[6]), FALSE, int, "%d"); 291 expect_eq(_ismbstrail(mbstring, &mbstring[7]), FALSE, int, "%d"); 292 expect_eq(_ismbstrail(mbstring, &mbstring[8]), -1, int, "%d"); 293 294 expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[0]), FALSE, int, "%d"); 295 expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[1]), -1, int, "%d"); 296 expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[2]), FALSE, int, "%d"); 297 expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[3]), FALSE, int, "%d"); 298 expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[4]), FALSE, int, "%d"); 299 expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d"); 300 301 /* _mbsbtype */ 302 expect_eq(_mbsbtype(mbstring, 0), _MBC_LEAD, int, "%d"); 303 expect_eq(_mbsbtype(mbstring, 1), _MBC_TRAIL, int, "%d"); 304 expect_eq(_mbsbtype(mbstring, 2), _MBC_LEAD, int, "%d"); 305 expect_eq(_mbsbtype(mbstring, 3), _MBC_ILLEGAL, int, "%d"); 306 expect_eq(_mbsbtype(mbstring, 4), _MBC_LEAD, int, "%d"); 307 expect_eq(_mbsbtype(mbstring, 5), _MBC_TRAIL, int, "%d"); 308 expect_eq(_mbsbtype(mbstring, 6), _MBC_SINGLE, int, "%d"); 309 expect_eq(_mbsbtype(mbstring, 7), _MBC_LEAD, int, "%d"); 310 expect_eq(_mbsbtype(mbstring, 8), _MBC_ILLEGAL, int, "%d"); 311 312 expect_eq(_mbsbtype(mbsonlylead, 0), _MBC_LEAD, int, "%d"); 313 expect_eq(_mbsbtype(mbsonlylead, 1), _MBC_ILLEGAL, int, "%d"); 314 expect_eq(_mbsbtype(mbsonlylead, 2), _MBC_ILLEGAL, int, "%d"); 315 expect_eq(_mbsbtype(mbsonlylead, 3), _MBC_ILLEGAL, int, "%d"); 316 expect_eq(_mbsbtype(mbsonlylead, 4), _MBC_ILLEGAL, int, "%d"); 317 expect_eq(_mbsbtype(mbsonlylead, 5), _MBC_ILLEGAL, int, "%d"); 318 319 /* _mbsnextc */ 320 expect_eq(_mbsnextc(mbstring), 0xb0b1, int, "%x"); 321 expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x"); /* lead + invalid tail */ 322 expect_eq(_mbsnextc(&mbstring[3]), 0x20, int, "%x"); /* single char */ 323 324 /* _mbclen/_mbslen */ 325 expect_eq(_mbclen(mbstring), 2, int, "%d"); 326 expect_eq(_mbclen(&mbstring[2]), 2, int, "%d"); 327 expect_eq(_mbclen(&mbstring[3]), 1, int, "%d"); 328 expect_eq(_mbslen(mbstring2), 4, int, "%d"); 329 expect_eq(_mbslen(mbsonlylead), 0, int, "%d"); /* lead + NUL not counted as character */ 330 expect_eq(_mbslen(mbstring), 4, int, "%d"); /* lead + invalid trail counted */ 331 332 if(!p__mbsnlen) { 333 win_skip("_mbsnlen tests\n"); 334 }else { 335 expect_eq(p__mbsnlen(mbstring, 8), 8, int, "%d"); 336 expect_eq(p__mbsnlen(mbstring, 9), 4, int, "%d"); 337 expect_eq(p__mbsnlen(mbstring, 10), 4, int, "%d"); 338 expect_eq(p__mbsnlen(mbsonlylead, 0), 0, int, "%d"); 339 expect_eq(p__mbsnlen(mbsonlylead, 1), 1, int, "%d"); 340 expect_eq(p__mbsnlen(mbsonlylead, 2), 0, int, "%d"); 341 expect_eq(p__mbsnlen(mbstring2, 7), 7, int, "%d"); 342 expect_eq(p__mbsnlen(mbstring2, 8), 4, int, "%d"); 343 expect_eq(p__mbsnlen(mbstring2, 9), 4, int, "%d"); 344 } 345 346 /* mbrlen */ 347 if(!setlocale(LC_ALL, ".936") || !p_mbrlen) { 348 win_skip("mbrlen tests\n"); 349 }else { 350 mbstate_t state = 0; 351 expect_eq(p_mbrlen((const char*)mbstring, 2, NULL), 2, int, "%d"); 352 expect_eq(p_mbrlen((const char*)&mbstring[2], 2, NULL), 2, int, "%d"); 353 expect_eq(p_mbrlen((const char*)&mbstring[3], 2, NULL), 1, int, "%d"); 354 expect_eq(p_mbrlen((const char*)mbstring, 1, NULL), -2, int, "%d"); 355 expect_eq(p_mbrlen((const char*)mbstring, 1, &state), -2, int, "%d"); 356 ok(state == mbstring[0], "incorrect state value (%x)\n", state); 357 expect_eq(p_mbrlen((const char*)&mbstring[1], 1, &state), 2, int, "%d"); 358 } 359 360 /* mbrtowc */ 361 if(!setlocale(LC_ALL, ".936") || !p_mbrtowc) { 362 win_skip("mbrtowc tests\n"); 363 }else { 364 mbstate_t state = 0; 365 wchar_t dst; 366 expect_eq(p_mbrtowc(&dst, (const char*)mbstring, 2, NULL), 2, int, "%d"); 367 ok(dst == 0x6c28, "dst = %x, expected 0x6c28\n", dst); 368 expect_eq(p_mbrtowc(&dst, (const char*)mbstring+2, 2, NULL), 2, int, "%d"); 369 ok(dst == 0x3f, "dst = %x, expected 0x3f\n", dst); 370 expect_eq(p_mbrtowc(&dst, (const char*)mbstring+3, 2, NULL), 1, int, "%d"); 371 ok(dst == 0x20, "dst = %x, expected 0x20\n", dst); 372 expect_eq(p_mbrtowc(&dst, (const char*)mbstring, 1, NULL), -2, int, "%d"); 373 ok(dst == 0, "dst = %x, expected 0\n", dst); 374 expect_eq(p_mbrtowc(&dst, (const char*)mbstring, 1, &state), -2, int, "%d"); 375 ok(dst == 0, "dst = %x, expected 0\n", dst); 376 ok(state == mbstring[0], "incorrect state value (%x)\n", state); 377 expect_eq(p_mbrtowc(&dst, (const char*)mbstring+1, 1, &state), 2, int, "%d"); 378 ok(dst == 0x6c28, "dst = %x, expected 0x6c28\n", dst); 379 ok(state == 0, "incorrect state value (%x)\n", state); 380 } 381 setlocale(LC_ALL, "C"); 382 383 /* _mbccpy/_mbsncpy */ 384 memset(buf, 0xff, sizeof(buf)); 385 _mbccpy(buf, mbstring); 386 expect_bin(buf, "\xb0\xb1\xff", 3); 387 388 if(!p__mbccpy_s) { 389 win_skip("_mbccpy_s tests\n"); 390 }else { 391 int err, copied; 392 393 memset(buf, 0xff, sizeof(buf)); 394 copied = -1; 395 err = p__mbccpy_s(buf, 0, &copied, mbstring); 396 ok(err == EINVAL, "_mbccpy_s returned %d\n", err); 397 ok(!copied, "copied = %d\n", copied); 398 ok(buf[0] == 0xff, "buf[0] = %x\n", buf[0]); 399 400 memset(buf, 0xff, sizeof(buf)); 401 copied = -1; 402 err = p__mbccpy_s(buf, 1, &copied, mbstring); 403 ok(err == ERANGE, "_mbccpy_s returned %d\n", err); 404 ok(!copied, "copied = %d\n", copied); 405 ok(!buf[0], "buf[0] = %x\n", buf[0]); 406 407 memset(buf, 0xff, sizeof(buf)); 408 copied = -1; 409 err = p__mbccpy_s(buf, 2, &copied, mbstring); 410 ok(!err, "_mbccpy_s returned %d\n", err); 411 ok(copied == 2, "copied = %d\n", copied); 412 expect_bin(buf, "\xb0\xb1\xff", 3); 413 414 memset(buf, 0xff, sizeof(buf)); 415 copied = -1; 416 err = p__mbccpy_s(buf, 2, &copied, (unsigned char *)"\xb0"); 417 ok(err == EILSEQ, "_mbccpy_s returned %d\n", err); 418 ok(copied == 1, "copied = %d\n", copied); 419 expect_bin(buf, "\x00\xff", 2); 420 } 421 422 memset(buf, 0xff, sizeof(buf)); 423 _mbsncpy(buf, mbstring, 1); 424 expect_bin(buf, "\xb0\xb1\xff", 3); 425 memset(buf, 0xff, sizeof(buf)); 426 _mbsncpy(buf, mbstring, 2); 427 expect_bin(buf, "\xb0\xb1\xb2 \xff", 5); 428 memset(buf, 0xff, sizeof(buf)); 429 _mbsncpy(buf, mbstring, 3); 430 expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4\xff", 7); 431 memset(buf, 0xff, sizeof(buf)); 432 _mbsncpy(buf, mbstring, 4); 433 expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \xff", 8); 434 memset(buf, 0xff, sizeof(buf)); 435 _mbsncpy(buf, mbstring, 5); 436 expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \0\0\xff", 10); 437 memset(buf, 0xff, sizeof(buf)); 438 _mbsncpy(buf, mbsonlylead, 6); 439 expect_bin(buf, "\0\0\0\0\0\0\0\xff", 8); 440 441 memset(buf, 0xff, sizeof(buf)); 442 _mbsnbcpy(buf, mbstring2, 2); 443 expect_bin(buf, "\xb0\xb1\xff", 3); 444 _mbsnbcpy(buf, mbstring2, 3); 445 expect_bin(buf, "\xb0\xb1\0\xff", 4); 446 _mbsnbcpy(buf, mbstring2, 4); 447 expect_bin(buf, "\xb0\xb1\xb2\xb3\xff", 5); 448 memset(buf, 0xff, sizeof(buf)); 449 _mbsnbcpy(buf, mbsonlylead, 5); 450 expect_bin(buf, "\0\0\0\0\0\xff", 6); 451 452 /* _mbsinc/mbsdec */ 453 step = _mbsinc(mbstring) - mbstring; 454 ok(step == 2, "_mbsinc adds %d (exp. 2)\n", step); 455 step = _mbsinc(&mbstring[2]) - &mbstring[2]; /* lead + invalid tail */ 456 ok(step == 2, "_mbsinc adds %d (exp. 2)\n", step); 457 458 step = _mbsninc(mbsonlylead, 1) - mbsonlylead; 459 ok(step == 0, "_mbsninc adds %d (exp. 0)\n", step); 460 step = _mbsninc(mbsonlylead, 2) - mbsonlylead; /* lead + NUL byte + lead + char */ 461 ok(step == 0, "_mbsninc adds %d (exp. 0)\n", step); 462 step = _mbsninc(mbstring2, 0) - mbstring2; 463 ok(step == 0, "_mbsninc adds %d (exp. 2)\n", step); 464 step = _mbsninc(mbstring2, 1) - mbstring2; 465 ok(step == 2, "_mbsninc adds %d (exp. 2)\n", step); 466 step = _mbsninc(mbstring2, 2) - mbstring2; 467 ok(step == 4, "_mbsninc adds %d (exp. 4)\n", step); 468 step = _mbsninc(mbstring2, 3) - mbstring2; 469 ok(step == 5, "_mbsninc adds %d (exp. 5)\n", step); 470 step = _mbsninc(mbstring2, 4) - mbstring2; 471 ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step); 472 step = _mbsninc(mbstring2, 5) - mbstring2; 473 ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step); 474 step = _mbsninc(mbstring2, 17) - mbstring2; 475 ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step); 476 477 /* functions that depend on locale codepage, not mbcp. 478 * we hope the current locale to be SBCS because setlocale(LC_ALL, ".1252") seems not to work yet 479 * (as of Wine 0.9.43) 480 */ 481 GetCPInfo(GetACP(), &cp_info); 482 if (cp_info.MaxCharSize == 1) 483 { 484 expect_eq(mblen((char *)mbstring, 3), 1, int, "%x"); 485 expect_eq(_mbstrlen((char *)mbstring2), 7, int, "%d"); 486 } 487 else 488 skip("Current locale has double-byte charset - could lead to false positives\n"); 489 490 _setmbcp(1361); 491 expect_eq(_ismbblead(0x80), 0, int, "%d"); 492 todo_wine { 493 expect_eq(_ismbblead(0x81), 1, int, "%d"); 494 expect_eq(_ismbblead(0x83), 1, int, "%d"); 495 } 496 expect_eq(_ismbblead(0x84), 1, int, "%d"); 497 expect_eq(_ismbblead(0xd3), 1, int, "%d"); 498 expect_eq(_ismbblead(0xd7), 0, int, "%d"); 499 expect_eq(_ismbblead(0xd8), 1, int, "%d"); 500 expect_eq(_ismbblead(0xd9), 1, int, "%d"); 501 502 expect_eq(_ismbbtrail(0x30), 0, int, "%d"); 503 expect_eq(_ismbbtrail(0x31), 1, int, "%d"); 504 expect_eq(_ismbbtrail(0x7e), 1, int, "%d"); 505 expect_eq(_ismbbtrail(0x7f), 0, int, "%d"); 506 expect_eq(_ismbbtrail(0x80), 0, int, "%d"); 507 expect_eq(_ismbbtrail(0x81), 1, int, "%d"); 508 expect_eq(_ismbbtrail(0xfe), 1, int, "%d"); 509 expect_eq(_ismbbtrail(0xff), 0, int, "%d"); 510 511 _setmbcp(curr_mbcp); 512 } 513 514 static void test_mbsspn( void) 515 { 516 unsigned char str1[]="cabernet"; 517 unsigned char str2[]="shiraz"; 518 unsigned char set[]="abc"; 519 unsigned char empty[]=""; 520 unsigned char mbstr[]=" 2019\x94\x4e" "6\x8c\x8e" "29\x93\xfa"; 521 unsigned char mbset1[]="0123456789 \x94\x4e"; 522 unsigned char mbset2[]=" \x94\x4e\x8c\x8e"; 523 unsigned char mbset3[]="\x8e"; 524 int ret, cp = _getmbcp(); 525 526 ret=_mbsspn( str1, set); 527 ok( ret==3, "_mbsspn returns %d should be 3\n", ret); 528 ret=_mbsspn( str2, set); 529 ok( ret==0, "_mbsspn returns %d should be 0\n", ret); 530 ret=_mbsspn( str1, empty); 531 ok( ret==0, "_mbsspn returns %d should be 0\n", ret); 532 533 _setmbcp( 932); 534 ret=_mbsspn( mbstr, mbset1); 535 ok( ret==8, "_mbsspn returns %d should be 8\n", ret); 536 ret=_mbsspn( mbstr, mbset2); 537 ok( ret==1, "_mbsspn returns %d should be 1\n", ret); 538 ret=_mbsspn( mbstr+8, mbset1); 539 ok( ret==0, "_mbsspn returns %d should be 0\n", ret); 540 ret=_mbsspn( mbstr+8, mbset2); 541 ok( ret==2, "_mbsspn returns %d should be 2\n", ret); 542 ret=_mbsspn( mbstr, mbset3); 543 ok( ret==14, "_mbsspn returns %d should be 14\n", ret); 544 545 _setmbcp( cp); 546 } 547 548 static void test_mbsspnp( void) 549 { 550 unsigned char str1[]="cabernet"; 551 unsigned char str2[]="shiraz"; 552 unsigned char set[]="abc"; 553 unsigned char empty[]=""; 554 unsigned char full[]="abcenrt"; 555 unsigned char mbstr[]=" 2019\x94\x4e" "6\x8c\x8e" "29\x93\xfa"; 556 unsigned char mbset1[]="0123456789 \x94\x4e"; 557 unsigned char mbset2[]=" \x94\x4e\x8c\x8e"; 558 unsigned char* ret; 559 int cp = _getmbcp(); 560 561 ret=_mbsspnp( str1, set); 562 ok( ret[0]=='e', "_mbsspnp returns %c should be e\n", ret[0]); 563 ret=_mbsspnp( str2, set); 564 ok( ret[0]=='s', "_mbsspnp returns %c should be s\n", ret[0]); 565 ret=_mbsspnp( str1, empty); 566 ok( ret[0]=='c', "_mbsspnp returns %c should be c\n", ret[0]); 567 ret=_mbsspnp( str1, full); 568 ok( ret==NULL, "_mbsspnp returns %p should be NULL\n", ret); 569 570 _setmbcp( 932); 571 ret=_mbsspnp( mbstr, mbset1); 572 ok( ret==mbstr+8, "_mbsspnp returns %p should be %p\n", ret, mbstr+8); 573 ret=_mbsspnp( mbstr, mbset2); 574 ok( ret==mbstr+1, "_mbsspnp returns %p should be %p\n", ret, mbstr+1); 575 ret=_mbsspnp( mbstr+8, mbset1); 576 ok( ret==mbstr+8, "_mbsspnp returns %p should be %p\n", ret, mbstr+8); 577 ret=_mbsspnp( mbstr+8, mbset2); 578 ok( ret==mbstr+10, "_mbsspnp returns %p should be %p\n", ret, mbstr+10); 579 580 _setmbcp( cp); 581 } 582 583 static void test_strdup(void) 584 { 585 char *str; 586 str = _strdup( 0 ); 587 ok( str == 0, "strdup returns %s should be 0\n", str); 588 free( str ); 589 } 590 591 static void test_strcpy_s(void) 592 { 593 char dest[8]; 594 const char small[] = "small"; 595 const char big[] = "atoolongstringforthislittledestination"; 596 int ret; 597 598 if(!pstrcpy_s) 599 { 600 win_skip("strcpy_s not found\n"); 601 return; 602 } 603 604 memset(dest, 'X', sizeof(dest)); 605 ret = pstrcpy_s(dest, sizeof(dest), small); 606 ok(ret == 0, "Copying a string into a big enough destination returned %d, expected 0\n", ret); 607 ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' && 608 dest[4] == 'l' && dest[5] == '\0'&& dest[6] == 'X' && dest[7] == 'X', 609 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 610 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 611 612 memset(dest, 'X', sizeof(dest)); 613 ret = pstrcpy_s(dest, 0, big); 614 ok(ret == EINVAL, "Copying into a destination of size 0 returned %d, expected EINVAL\n", ret); 615 ok(dest[0] == 'X' && dest[1] == 'X' && dest[2] == 'X' && dest[3] == 'X' && 616 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 617 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 618 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 619 ret = pstrcpy_s(dest, 0, NULL); 620 ok(ret == EINVAL, "Copying into a destination of size 0 returned %d, expected EINVAL\n", ret); 621 ok(dest[0] == 'X' && dest[1] == 'X' && dest[2] == 'X' && dest[3] == 'X' && 622 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 623 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 624 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 625 626 memset(dest, 'X', sizeof(dest)); 627 ret = pstrcpy_s(dest, sizeof(dest), big); 628 ok(ret == ERANGE, "Copying a big string in a small location returned %d, expected ERANGE\n", ret); 629 ok(dest[0] == '\0'&& dest[1] == 't' && dest[2] == 'o' && dest[3] == 'o' && 630 dest[4] == 'l' && dest[5] == 'o' && dest[6] == 'n' && dest[7] == 'g', 631 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 632 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 633 634 memset(dest, 'X', sizeof(dest)); 635 ret = pstrcpy_s(dest, sizeof(dest), NULL); 636 ok(ret == EINVAL, "Copying from a NULL source string returned %d, expected EINVAL\n", ret); 637 ok(dest[0] == '\0'&& dest[1] == 'X' && dest[2] == 'X' && dest[3] == 'X' && 638 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 639 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 640 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 641 642 ret = pstrcpy_s(NULL, sizeof(dest), small); 643 ok(ret == EINVAL, "Copying a big string a NULL dest returned %d, expected EINVAL\n", ret); 644 645 /* strcpy overlapping buffers test */ 646 memset(dest, 'X', sizeof(dest)); 647 memcpy(dest+1, small, sizeof(small)); 648 p_strcpy(dest, dest+1); 649 ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' && 650 dest[4] == 'l' && dest[5] == '\0' && dest[6] == '\0' && dest[7] == 'X', 651 "Unexpected return data from strcpy: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 652 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 653 } 654 655 #define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \ 656 ok(dst[0] == b0 && dst[1] == b1 && dst[2] == b2 && dst[3] == b3 && \ 657 dst[4] == b4 && dst[5] == b5 && dst[6] == b6 && dst[7] == b7, \ 658 "Bad result: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",\ 659 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5], dst[6], dst[7]) 660 661 static void test_memcpy_s(void) 662 { 663 static char dest[8], buf[32]; 664 static const char tiny[] = {'T',0,'I','N','Y',0}; 665 static const char big[] = {'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0}; 666 int ret; 667 if (!p_memcpy_s) { 668 win_skip("memcpy_s not found\n"); 669 return; 670 } 671 672 /* Normal */ 673 memset(dest, 'X', sizeof(dest)); 674 ret = p_memcpy_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); 675 ok(ret == 0, "Copying a buffer into a big enough destination returned %d, expected 0\n", ret); 676 okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X'); 677 678 /* Vary source size */ 679 errno = 0xdeadbeef; 680 memset(dest, 'X', sizeof(dest)); 681 ret = p_memcpy_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big)); 682 ok(ret == ERANGE, "Copying a big buffer to a small destination returned %d, expected ERANGE\n", ret); 683 ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); 684 okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0); 685 686 /* Replace source with NULL */ 687 errno = 0xdeadbeef; 688 memset(dest, 'X', sizeof(dest)); 689 ret = p_memcpy_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny)); 690 ok(ret == EINVAL, "Copying a NULL source buffer returned %d, expected EINVAL\n", ret); 691 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 692 okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0); 693 694 /* Vary dest size */ 695 errno = 0xdeadbeef; 696 memset(dest, 'X', sizeof(dest)); 697 ret = p_memcpy_s(dest, 0, tiny, ARRAY_SIZE(tiny)); 698 ok(ret == ERANGE, "Copying into a destination of size 0 returned %d, expected ERANGE\n", ret); 699 ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); 700 okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); 701 702 /* Replace dest with NULL */ 703 errno = 0xdeadbeef; 704 ret = p_memcpy_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); 705 ok(ret == EINVAL, "Copying a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret); 706 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 707 708 /* Combinations */ 709 errno = 0xdeadbeef; 710 memset(dest, 'X', sizeof(dest)); 711 ret = p_memcpy_s(dest, 0, NULL, ARRAY_SIZE(tiny)); 712 ok(ret == EINVAL, "Copying a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret); 713 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 714 okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); 715 716 ret = p_memcpy_s(buf, ARRAY_SIZE(buf), big, ARRAY_SIZE(big)); 717 ok(!ret, "memcpy_s returned %d\n", ret); 718 ok(!memcmp(buf, big, sizeof(big)), "unexpected buf\n"); 719 720 ret = p_memcpy_s(buf + 1, ARRAY_SIZE(buf) - 1, buf, ARRAY_SIZE(big)); 721 ok(!ret, "memcpy_s returned %d\n", ret); 722 ok(!memcmp(buf + 1, big, sizeof(big)), "unexpected buf\n"); 723 724 ret = p_memcpy_s(buf, ARRAY_SIZE(buf), buf + 1, ARRAY_SIZE(big)); 725 ok(!ret, "memcpy_s returned %d\n", ret); 726 ok(!memcmp(buf, big, sizeof(big)), "unexpected buf\n"); 727 } 728 729 static void test_memmove_s(void) 730 { 731 static char dest[8]; 732 static const char tiny[] = {'T',0,'I','N','Y',0}; 733 static const char big[] = {'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0}; 734 int ret; 735 if (!p_memmove_s) { 736 win_skip("memmove_s not found\n"); 737 return; 738 } 739 740 /* Normal */ 741 memset(dest, 'X', sizeof(dest)); 742 ret = p_memmove_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); 743 ok(ret == 0, "Moving a buffer into a big enough destination returned %d, expected 0\n", ret); 744 okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X'); 745 746 /* Overlapping */ 747 memcpy(dest, big, sizeof(dest)); 748 ret = p_memmove_s(dest+1, ARRAY_SIZE(dest)-1, dest, ARRAY_SIZE(dest)-1); 749 ok(ret == 0, "Moving a buffer up one char returned %d, expected 0\n", ret); 750 okchars(dest, big[0], big[0], big[1], big[2], big[3], big[4], big[5], big[6]); 751 752 /* Vary source size */ 753 errno = 0xdeadbeef; 754 memset(dest, 'X', sizeof(dest)); 755 ret = p_memmove_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big)); 756 ok(ret == ERANGE, "Moving a big buffer to a small destination returned %d, expected ERANGE\n", ret); 757 ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); 758 okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); 759 760 /* Replace source with NULL */ 761 errno = 0xdeadbeef; 762 memset(dest, 'X', sizeof(dest)); 763 ret = p_memmove_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny)); 764 ok(ret == EINVAL, "Moving a NULL source buffer returned %d, expected EINVAL\n", ret); 765 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 766 okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); 767 768 /* Vary dest size */ 769 errno = 0xdeadbeef; 770 memset(dest, 'X', sizeof(dest)); 771 ret = p_memmove_s(dest, 0, tiny, ARRAY_SIZE(tiny)); 772 ok(ret == ERANGE, "Moving into a destination of size 0 returned %d, expected ERANGE\n", ret); 773 ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); 774 okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); 775 776 /* Replace dest with NULL */ 777 errno = 0xdeadbeef; 778 ret = p_memmove_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); 779 ok(ret == EINVAL, "Moving a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret); 780 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 781 782 /* Combinations */ 783 errno = 0xdeadbeef; 784 memset(dest, 'X', sizeof(dest)); 785 ret = p_memmove_s(dest, 0, NULL, ARRAY_SIZE(tiny)); 786 ok(ret == EINVAL, "Moving a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret); 787 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 788 okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); 789 } 790 791 static void test_strcat_s(void) 792 { 793 char dest[8]; 794 const char *small = "sma"; 795 int ret; 796 797 if(!pstrcat_s) 798 { 799 win_skip("strcat_s not found\n"); 800 return; 801 } 802 803 memset(dest, 'X', sizeof(dest)); 804 dest[0] = '\0'; 805 ret = pstrcat_s(dest, sizeof(dest), small); 806 ok(ret == 0, "strcat_s: Copying a string into a big enough destination returned %d, expected 0\n", ret); 807 ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == '\0'&& 808 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 809 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 810 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 811 ret = pstrcat_s(dest, sizeof(dest), small); 812 ok(ret == 0, "strcat_s: Attaching a string to a big enough destination returned %d, expected 0\n", ret); 813 ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 's' && 814 dest[4] == 'm' && dest[5] == 'a' && dest[6] == '\0'&& dest[7] == 'X', 815 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 816 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 817 818 ret = pstrcat_s(dest, sizeof(dest), small); 819 ok(ret == ERANGE, "strcat_s: Attaching a string to a filled up destination returned %d, expected ERANGE\n", ret); 820 ok(dest[0] == '\0'&& dest[1] == 'm' && dest[2] == 'a' && dest[3] == 's' && 821 dest[4] == 'm' && dest[5] == 'a' && dest[6] == 's' && dest[7] == 'm', 822 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 823 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 824 825 memset(dest, 'X', sizeof(dest)); 826 dest[0] = 'a'; 827 dest[1] = '\0'; 828 829 ret = pstrcat_s(dest, 0, small); 830 ok(ret == EINVAL, "strcat_s: Source len = 0 returned %d, expected EINVAL\n", ret); 831 ok(dest[0] == 'a' && dest[1] == '\0'&& dest[2] == 'X' && dest[3] == 'X' && 832 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 833 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 834 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 835 836 ret = pstrcat_s(dest, 0, NULL); 837 ok(ret == EINVAL, "strcat_s: len = 0 and src = NULL returned %d, expected EINVAL\n", ret); 838 ok(dest[0] == 'a' && dest[1] == '\0'&& dest[2] == 'X' && dest[3] == 'X' && 839 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 840 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 841 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 842 843 ret = pstrcat_s(dest, sizeof(dest), NULL); 844 ok(ret == EINVAL, "strcat_s: Sourcing from NULL returned %d, expected EINVAL\n", ret); 845 ok(dest[0] == '\0'&& dest[1] == '\0'&& dest[2] == 'X' && dest[3] == 'X' && 846 dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 847 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 848 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 849 850 ret = pstrcat_s(NULL, sizeof(dest), small); 851 ok(ret == EINVAL, "strcat_s: Writing to a NULL string returned %d, expected EINVAL\n", ret); 852 } 853 854 static void test__mbscat_s(void) 855 { 856 unsigned char dst[8], src[4]; 857 int err; 858 int prev_cp = _getmbcp(); 859 860 if(!p_mbscat_s) 861 { 862 win_skip("_mbscat_s not found\n"); 863 return; 864 } 865 866 867 src[0] = dst[0] = 0; 868 err = p_mbscat_s(NULL, sizeof(dst), src); 869 ok(err == EINVAL, "_mbscat_s returned %d\n", err); 870 871 err = p_mbscat_s(dst, sizeof(dst), NULL); 872 ok(err == EINVAL, "_mbscat_s returned %d\n", err); 873 874 dst[0] = 'a'; 875 err = p_mbscat_s(dst, 1, src); 876 ok(err == EINVAL, "_mbscat_s returned %d\n", err); 877 878 memset(dst, 'a', sizeof(dst)); 879 dst[6] = 0; 880 src[0] = 'b'; 881 src[1] = 0; 882 883 err = p_mbscat_s(dst, sizeof(dst), src); 884 ok(err == 0, "_mbscat_s returned %d\n", err); 885 ok(!memcmp(dst, "aaaaaab", 8), "dst = %s\n", dst); 886 887 err = p_mbscat_s(dst, sizeof(dst), src); 888 ok(err == ERANGE, "_mbscat_s returned %d\n", err); 889 ok(!dst[0], "dst[0] = %c\n", dst[0]); 890 ok(dst[1] == 'a', "dst[1] = %c\n", dst[1]); 891 892 _setmbcp(932); 893 /* test invalid str in dst */ 894 dst[0] = 0x81; 895 dst[1] = 0x81; 896 dst[2] = 0x52; 897 dst[3] = 0; 898 src[0] = 'a'; 899 src[1] = 0; 900 err = p_mbscat_s(dst, sizeof(dst), src); 901 ok(err == 0, "_mbscat_s returned %d\n", err); 902 903 /* test invalid str in src */ 904 dst[0] = 0; 905 src[0] = 0x81; 906 src[1] = 0x81; 907 src[2] = 0x52; 908 src[3] = 0; 909 err = p_mbscat_s(dst, sizeof(dst), src); 910 ok(err == 0, "_mbscat_s returned %d\n", err); 911 912 /* test dst with leading byte on the end of buffer */ 913 dst[0] = 'a'; 914 dst[1] = 0x81; 915 dst[2] = 0; 916 src[0] = 'R'; 917 src[1] = 0; 918 err = p_mbscat_s(dst, sizeof(dst), src); 919 ok(err == EILSEQ, "_mbscat_s returned %d\n", err); 920 ok(!memcmp(dst, "aR", 3), "dst = %s\n", dst); 921 922 /* test src with leading byte on the end of buffer */ 923 dst[0] = 'a'; 924 dst[1] = 0; 925 src[0] = 'b'; 926 src[1] = 0x81; 927 src[2] = 0; 928 err = p_mbscat_s(dst, sizeof(dst), src); 929 ok(err == EILSEQ, "_mbscat_s returned %d\n", err); 930 ok(!memcmp(dst, "ab", 3), "dst = %s\n", dst); 931 _setmbcp(prev_cp); 932 } 933 934 static void test__mbsnbcpy_s(void) 935 { 936 unsigned char dest[8]; 937 const unsigned char big[] = "atoolongstringforthislittledestination"; 938 const unsigned char small[] = "small"; 939 int ret; 940 941 if(!p_mbsnbcpy_s) 942 { 943 win_skip("_mbsnbcpy_s not found\n"); 944 return; 945 } 946 947 memset(dest, 'X', sizeof(dest)); 948 ret = p_mbsnbcpy_s(dest, sizeof(dest), small, sizeof(small)); 949 ok(ret == 0, "_mbsnbcpy_s: Copying a string into a big enough destination returned %d, expected 0\n", ret); 950 ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' && 951 dest[4] == 'l' && dest[5] == '\0'&& dest[6] == 'X' && dest[7] == 'X', 952 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 953 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 954 955 /* WTF? */ 956 memset(dest, 'X', sizeof(dest)); 957 ret = p_mbsnbcpy_s(dest, sizeof(dest) - 2, big, sizeof(small)); 958 ok(ret == ERANGE, "_mbsnbcpy_s: Copying a too long string returned %d, expected ERANGE\n", ret); 959 ok(dest[0] == '\0'&& dest[1] == 't' && dest[2] == 'o' && dest[3] == 'o' && 960 dest[4] == 'l' && dest[5] == 'o' && dest[6] == 'X' && dest[7] == 'X', 961 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 962 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 963 964 memset(dest, 'X', sizeof(dest)); 965 ret = p_mbsnbcpy_s(dest, sizeof(dest) - 2, big, 4); 966 ok(ret == 0, "_mbsnbcpy_s: Copying a too long string with a count cap returned %d, expected 0\n", ret); 967 ok(dest[0] == 'a' && dest[1] == 't' && dest[2] == 'o' && dest[3] == 'o' && 968 dest[4] == '\0'&& dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X', 969 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 970 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 971 972 memset(dest, 'X', sizeof(dest)); 973 ret = p_mbsnbcpy_s(dest, sizeof(dest) - 2, small, sizeof(small) + 10); 974 ok(ret == 0, "_mbsnbcpy_s: Copying more data than the source string len returned %d, expected 0\n", ret); 975 ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' && 976 dest[4] == 'l' && dest[5] == '\0'&& dest[6] == 'X' && dest[7] == 'X', 977 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 978 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); 979 } 980 981 static void test__mbscpy_s(void) 982 { 983 const unsigned char src[] = "source string"; 984 unsigned char dest[16]; 985 int ret; 986 987 if(!p__mbscpy_s) 988 { 989 win_skip("_mbscpy_s not found\n"); 990 return; 991 } 992 993 ret = p__mbscpy_s(NULL, 0, src); 994 ok(ret == EINVAL, "got %d\n", ret); 995 ret = p__mbscpy_s(NULL, sizeof(dest), src); 996 ok(ret == EINVAL, "got %d\n", ret); 997 ret = p__mbscpy_s(dest, 0, src); 998 ok(ret == EINVAL, "got %d\n", ret); 999 dest[0] = 'x'; 1000 ret = p__mbscpy_s(dest, sizeof(dest), NULL); 1001 ok(ret == EINVAL, "got %d\n", ret); 1002 ok(!dest[0], "dest buffer was not modified on invalid argument\n"); 1003 1004 memset(dest, 'X', sizeof(dest)); 1005 ret = p__mbscpy_s(dest, sizeof(dest), src); 1006 ok(!ret, "got %d\n", ret); 1007 ok(!memcmp(dest, src, sizeof(src)), "dest = %s\n", dest); 1008 ok(dest[sizeof(src)] == 'X', "unused part of buffer was modified\n"); 1009 1010 memset(dest, 'X', sizeof(dest)); 1011 ret = p__mbscpy_s(dest, 4, src); 1012 ok(ret == ERANGE, "got %d\n", ret); 1013 ok(!dest[0], "incorrect dest buffer (%d)\n", dest[0]); 1014 ok(dest[1] == src[1], "incorrect dest buffer (%d)\n", dest[1]); 1015 } 1016 1017 static void test_wcscpy_s(void) 1018 { 1019 static const WCHAR szLongText[] = { 'T','h','i','s','A','L','o','n','g','s','t','r','i','n','g',0 }; 1020 static WCHAR szDest[18]; 1021 static WCHAR szDestShort[8]; 1022 int ret; 1023 1024 if(!p_wcscpy_s) 1025 { 1026 win_skip("wcscpy_s not found\n"); 1027 return; 1028 } 1029 1030 /* Test NULL Dest */ 1031 errno = EBADF; 1032 ret = p_wcscpy_s(NULL, 18, szLongText); 1033 ok(ret == EINVAL, "p_wcscpy_s expect EINVAL got %d\n", ret); 1034 ok(errno == EINVAL, "expected errno EINVAL got %d\n", errno); 1035 1036 /* Test NULL Source */ 1037 errno = EBADF; 1038 szDest[0] = 'A'; 1039 ret = p_wcscpy_s(szDest, 18, NULL); 1040 ok(ret == EINVAL, "expected EINVAL got %d\n", ret); 1041 ok(errno == EINVAL, "expected errno EINVAL got %d\n", errno); 1042 ok(szDest[0] == 0, "szDest[0] not 0, got %c\n", szDest[0]); 1043 1044 /* Test invalid size */ 1045 errno = EBADF; 1046 szDest[0] = 'A'; 1047 ret = p_wcscpy_s(szDest, 0, szLongText); 1048 /* Later versions changed the return value for this case to EINVAL, 1049 * and don't modify the result if the dest size is 0. 1050 */ 1051 ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); 1052 ok(errno == ERANGE || errno == EINVAL, "expected errno ERANGE/EINVAL got %d\n", errno); 1053 ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n"); 1054 1055 /* Copy same buffer size */ 1056 ret = p_wcscpy_s(szDest, 18, szLongText); 1057 ok(ret == 0, "expected 0 got %d\n", ret); 1058 ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n"); 1059 1060 /* dest == source */ 1061 ret = p_wcscpy_s(szDest, 18, szDest); 1062 ok(ret == 0, "expected 0 got %d\n", ret); 1063 ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n"); 1064 1065 /* Copy smaller buffer size */ 1066 errno = EBADF; 1067 szDest[0] = 'A'; 1068 ret = p_wcscpy_s(szDestShort, 8, szLongText); 1069 ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); 1070 ok(errno == ERANGE || errno == EINVAL, "expected errno ERANGE/EINVAL got %d\n", errno); 1071 ok(szDestShort[0] == 0, "szDestShort[0] not 0\n"); 1072 1073 if(!p_wcsncpy_s) 1074 { 1075 win_skip("wcsncpy_s not found\n"); 1076 return; 1077 } 1078 1079 ret = p_wcsncpy_s(NULL, 18, szLongText, ARRAY_SIZE(szLongText)); 1080 ok(ret == EINVAL, "p_wcsncpy_s expect EINVAL got %d\n", ret); 1081 1082 szDest[0] = 'A'; 1083 ret = p_wcsncpy_s(szDest, 18, NULL, 1); 1084 ok(ret == EINVAL, "expected EINVAL got %d\n", ret); 1085 ok(szDest[0] == 0, "szDest[0] not 0\n"); 1086 1087 szDest[0] = 'A'; 1088 ret = p_wcsncpy_s(szDest, 18, NULL, 0); 1089 ok(ret == 0, "expected ERROR_SUCCESS got %d\n", ret); 1090 ok(szDest[0] == 0, "szDest[0] not 0\n"); 1091 1092 szDest[0] = 'A'; 1093 ret = p_wcsncpy_s(szDest, 0, szLongText, ARRAY_SIZE(szLongText)); 1094 ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); 1095 ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n"); 1096 1097 ret = p_wcsncpy_s(szDest, 18, szLongText, ARRAY_SIZE(szLongText)); 1098 ok(ret == 0, "expected 0 got %d\n", ret); 1099 ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n"); 1100 1101 szDest[0] = 'A'; 1102 ret = p_wcsncpy_s(szDestShort, 8, szLongText, ARRAY_SIZE(szLongText)); 1103 ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); 1104 ok(szDestShort[0] == 0, "szDestShort[0] not 0\n"); 1105 1106 szDest[0] = 'A'; 1107 ret = p_wcsncpy_s(szDest, 5, szLongText, -1); 1108 ok(ret == STRUNCATE, "expected STRUNCATE got %d\n", ret); 1109 ok(szDest[4] == 0, "szDest[4] not 0\n"); 1110 ok(!memcmp(szDest, szLongText, 4*sizeof(WCHAR)), "szDest = %s\n", wine_dbgstr_w(szDest)); 1111 1112 ret = p_wcsncpy_s(NULL, 0, (void*)0xdeadbeef, 0); 1113 ok(ret == 0, "ret = %d\n", ret); 1114 1115 szDestShort[0] = '1'; 1116 szDestShort[1] = 0; 1117 ret = p_wcsncpy_s(szDestShort+1, 4, szDestShort, -1); 1118 ok(ret == STRUNCATE, "expected ERROR_SUCCESS got %d\n", ret); 1119 ok(szDestShort[0]=='1' && szDestShort[1]=='1' && szDestShort[2]=='1' && szDestShort[3]=='1', 1120 "szDestShort = %s\n", wine_dbgstr_w(szDestShort)); 1121 } 1122 1123 static void test__wcsupr_s(void) 1124 { 1125 static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w', 1126 'e', 'r', 'U', 'P', 'P', 'E', 'R', 0}; 1127 static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O', 1128 'W', 'E', 'R', 'U', 'P', 'P', 'E', 1129 'R', 0}; 1130 WCHAR testBuffer[2*ARRAY_SIZE(mixedString)]; 1131 int ret; 1132 1133 if (!p_wcsupr_s) 1134 { 1135 win_skip("_wcsupr_s not found\n"); 1136 return; 1137 } 1138 1139 /* Test NULL input string and invalid size. */ 1140 errno = EBADF; 1141 ret = p_wcsupr_s(NULL, 0); 1142 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1143 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1144 1145 /* Test NULL input string and valid size. */ 1146 errno = EBADF; 1147 ret = p_wcsupr_s(NULL, ARRAY_SIZE(testBuffer)); 1148 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1149 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1150 1151 /* Test empty string with zero size. */ 1152 errno = EBADF; 1153 testBuffer[0] = '\0'; 1154 ret = p_wcsupr_s(testBuffer, 0); 1155 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1156 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1157 ok(testBuffer[0] == '\0', "Expected the buffer to be unchanged\n"); 1158 1159 /* Test empty string with size of one. */ 1160 testBuffer[0] = '\0'; 1161 ret = p_wcsupr_s(testBuffer, 1); 1162 ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); 1163 ok(testBuffer[0] == '\0', "Expected the buffer to be unchanged\n"); 1164 1165 /* Test one-byte buffer with zero size. */ 1166 errno = EBADF; 1167 testBuffer[0] = 'x'; 1168 ret = p_wcsupr_s(testBuffer, 0); 1169 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1170 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1171 ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); 1172 1173 /* Test one-byte buffer with size of one. */ 1174 errno = EBADF; 1175 testBuffer[0] = 'x'; 1176 ret = p_wcsupr_s(testBuffer, 1); 1177 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1178 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1179 ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); 1180 1181 /* Test invalid size. */ 1182 wcscpy(testBuffer, mixedString); 1183 errno = EBADF; 1184 ret = p_wcsupr_s(testBuffer, 0); 1185 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1186 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1187 ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); 1188 1189 /* Test normal string uppercasing. */ 1190 wcscpy(testBuffer, mixedString); 1191 ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString)); 1192 ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); 1193 ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n"); 1194 1195 /* Test uppercasing with a shorter buffer size count. */ 1196 wcscpy(testBuffer, mixedString); 1197 errno = EBADF; 1198 ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString) - 1); 1199 ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); 1200 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 1201 ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); 1202 1203 /* Test uppercasing with a longer buffer size count. */ 1204 wcscpy(testBuffer, mixedString); 1205 ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(testBuffer)); 1206 ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); 1207 ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n"); 1208 } 1209 1210 static void test__wcslwr_s(void) 1211 { 1212 static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w', 1213 'e', 'r', 'U', 'P', 'P', 'E', 'R', 0}; 1214 static const WCHAR expectedString[] = {'m', 'i', 'x', 'e', 'd', 'l', 'o', 1215 'w', 'e', 'r', 'u', 'p', 'p', 'e', 1216 'r', 0}; 1217 WCHAR buffer[2*ARRAY_SIZE(mixedString)]; 1218 int ret; 1219 1220 if (!p_wcslwr_s) 1221 { 1222 win_skip("_wcslwr_s not found\n"); 1223 return; 1224 } 1225 1226 /* Test NULL input string and invalid size. */ 1227 errno = EBADF; 1228 ret = p_wcslwr_s(NULL, 0); 1229 ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); 1230 ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno); 1231 1232 /* Test NULL input string and valid size. */ 1233 errno = EBADF; 1234 ret = p_wcslwr_s(NULL, ARRAY_SIZE(buffer)); 1235 ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); 1236 ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno); 1237 1238 /* Test empty string with zero size. */ 1239 errno = EBADF; 1240 buffer[0] = 'a'; 1241 ret = p_wcslwr_s(buffer, 0); 1242 ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); 1243 ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno); 1244 ok(buffer[0] == 0, "expected empty string\n"); 1245 1246 /* Test empty string with size of one. */ 1247 buffer[0] = 0; 1248 ret = p_wcslwr_s(buffer, 1); 1249 ok(ret == 0, "got %d\n", ret); 1250 ok(buffer[0] == 0, "expected buffer to be unchanged\n"); 1251 1252 /* Test one-byte buffer with zero size. */ 1253 errno = EBADF; 1254 buffer[0] = 'x'; 1255 ret = p_wcslwr_s(buffer, 0); 1256 ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); 1257 ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno); 1258 ok(buffer[0] == '\0', "expected empty string\n"); 1259 1260 /* Test one-byte buffer with size of one. */ 1261 errno = EBADF; 1262 buffer[0] = 'x'; 1263 ret = p_wcslwr_s(buffer, 1); 1264 ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); 1265 ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno); 1266 ok(buffer[0] == '\0', "expected empty string\n"); 1267 1268 /* Test invalid size. */ 1269 wcscpy(buffer, mixedString); 1270 errno = EBADF; 1271 ret = p_wcslwr_s(buffer, 0); 1272 ok(ret == EINVAL, "Expected EINVAL, got %d\n", ret); 1273 ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno); 1274 ok(buffer[0] == '\0', "expected empty string\n"); 1275 1276 /* Test normal string uppercasing. */ 1277 wcscpy(buffer, mixedString); 1278 ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString)); 1279 ok(ret == 0, "expected 0, got %d\n", ret); 1280 ok(!wcscmp(buffer, expectedString), "expected lowercase\n"); 1281 1282 /* Test uppercasing with a shorter buffer size count. */ 1283 wcscpy(buffer, mixedString); 1284 errno = EBADF; 1285 ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString) - 1); 1286 ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); 1287 ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno); 1288 ok(buffer[0] == '\0', "expected empty string\n"); 1289 1290 /* Test uppercasing with a longer buffer size count. */ 1291 wcscpy(buffer, mixedString); 1292 ret = p_wcslwr_s(buffer, ARRAY_SIZE(buffer)); 1293 ok(ret == 0, "expected 0, got %d\n", ret); 1294 ok(!wcscmp(buffer, expectedString), "expected lowercase\n"); 1295 } 1296 1297 static void test_mbcjisjms(void) 1298 { 1299 /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */ 1300 unsigned int jisjms[][2] = { {0x2020, 0}, {0x2021, 0}, {0x2120, 0}, {0x2121, 0x8140}, 1301 {0x7f7f, 0}, {0x7f7e, 0}, {0x7e7f, 0}, {0x7e7e, 0xeffc}, 1302 {0x255f, 0x837e}, {0x2560, 0x8380}, {0x2561, 0x8381}, 1303 {0x2121FFFF, 0}, {0x2223, 0x81a1}, {0x237e, 0x829e}, {0, 0}}; 1304 int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS }; 1305 unsigned int i, j; 1306 int prev_cp = _getmbcp(); 1307 1308 for (i = 0; i < ARRAY_SIZE(cp); i++) 1309 { 1310 _setmbcp(cp[i]); 1311 for (j = 0; jisjms[j][0] != 0; j++) 1312 { 1313 unsigned int ret, exp; 1314 ret = _mbcjistojms(jisjms[j][0]); 1315 exp = (cp[i] == 932) ? jisjms[j][1] : jisjms[j][0]; 1316 ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage=%d)\n", 1317 exp, ret, jisjms[j][0], cp[i]); 1318 } 1319 } 1320 _setmbcp(prev_cp); 1321 } 1322 1323 static void test_mbcjmsjis(void) 1324 { 1325 /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */ 1326 unsigned int jmsjis[][2] = { {0x80fc, 0}, {0x813f, 0}, {0x8140, 0x2121}, 1327 {0x817e, 0x215f}, {0x817f, 0}, {0x8180, 0x2160}, 1328 {0x819e, 0x217e}, {0x819f, 0x2221}, {0x81fc, 0x227e}, 1329 {0x81fd, 0}, {0x9ffc, 0x5e7e}, {0x9ffd, 0}, 1330 {0xa040, 0}, {0xdffc, 0}, {0xe040, 0x5f21}, 1331 {0xeffc, 0x7e7e}, {0xf040, 0}, {0x21, 0}, {0, 0}}; 1332 int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS }; 1333 unsigned int i, j; 1334 int prev_cp = _getmbcp(); 1335 1336 for (i = 0; i < ARRAY_SIZE(cp); i++) 1337 { 1338 _setmbcp(cp[i]); 1339 for (j = 0; jmsjis[j][0] != 0; j++) 1340 { 1341 unsigned int ret, exp; 1342 ret = _mbcjmstojis(jmsjis[j][0]); 1343 exp = (cp[i] == 932) ? jmsjis[j][1] : jmsjis[j][0]; 1344 ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage=%d)\n", 1345 exp, ret, jmsjis[j][0], cp[i]); 1346 } 1347 } 1348 _setmbcp(prev_cp); 1349 } 1350 1351 static void test_mbctohira(void) 1352 { 1353 static const unsigned int mbchira_932[][2] = { 1354 {0x8152, 0x8152}, {0x8153, 0x8153}, {0x8154, 0x8154}, {0x8155, 0x8155}, 1355 {0x82a0, 0x82a0}, {0x833f, 0x833f}, {0x8340, 0x829f}, {0x837e, 0x82dd}, 1356 {0x837f, 0x837f}, {0x8380, 0x82de}, {0x8393, 0x82f1}, {0x8394, 0x8394}, 1357 {0x8396, 0x8396}, {0x8397, 0x8397}, 1358 {0xa5, 0xa5}, {0xb0, 0xb0}, {0xdd, 0xdd} }; 1359 unsigned int i; 1360 unsigned int prev_cp = _getmbcp(); 1361 1362 _setmbcp(_MB_CP_SBCS); 1363 for (i = 0; i < ARRAY_SIZE(mbchira_932); i++) 1364 { 1365 int ret, exp = mbchira_932[i][0]; 1366 ret = _mbctohira(mbchira_932[i][0]); 1367 ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret); 1368 } 1369 1370 _setmbcp(932); 1371 for (i = 0; i < ARRAY_SIZE(mbchira_932); i++) 1372 { 1373 unsigned int ret, exp; 1374 ret = _mbctohira(mbchira_932[i][0]); 1375 exp = mbchira_932[i][1]; 1376 ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret); 1377 } 1378 _setmbcp(prev_cp); 1379 } 1380 1381 static void test_mbctokata(void) 1382 { 1383 static const unsigned int mbckata_932[][2] = { 1384 {0x8152, 0x8152}, {0x8153, 0x8153}, {0x8154, 0x8154}, {0x8155, 0x8155}, 1385 {0x833f, 0x833f}, {0x829f, 0x8340}, {0x82dd, 0x837e}, {0x837f, 0x837f}, 1386 {0x82de, 0x8380}, {0x8394, 0x8394}, {0x8397, 0x8397}, 1387 {0xa5, 0xa5}, {0xb0, 0xb0}, {0xdd, 0xdd} }; 1388 unsigned int i; 1389 unsigned int prev_cp = _getmbcp(); 1390 1391 _setmbcp(_MB_CP_SBCS); 1392 for (i = 0; i < ARRAY_SIZE(mbckata_932); i++) 1393 { 1394 int ret, exp = mbckata_932[i][0]; 1395 ret = _mbctokata(mbckata_932[i][0]); 1396 ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret); 1397 } 1398 1399 _setmbcp(932); 1400 for (i = 0; i < ARRAY_SIZE(mbckata_932); i++) 1401 { 1402 unsigned int ret, exp; 1403 ret = _mbctokata(mbckata_932[i][0]); 1404 exp = mbckata_932[i][1]; 1405 ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret); 1406 } 1407 _setmbcp(prev_cp); 1408 } 1409 1410 static void test_mbbtombc(void) 1411 { 1412 static const unsigned int mbbmbc[][2] = { 1413 {0x1f, 0x1f}, {0x20, 0x8140}, {0x39, 0x8258}, {0x40, 0x8197}, 1414 {0x41, 0x8260}, {0x5e, 0x814f}, {0x7e, 0x8150}, {0x7f, 0x7f}, 1415 {0x80, 0x80}, {0x81, 0x81}, {0xa0, 0xa0}, {0xa7, 0x8340}, 1416 {0xb0, 0x815b}, {0xd1, 0x8380}, {0xff, 0xff}, {0,0}}; 1417 int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS }; 1418 int i, j; 1419 int prev_cp = _getmbcp(); 1420 1421 for (i = 0; i < ARRAY_SIZE(cp); i++) 1422 { 1423 _setmbcp(cp[i]); 1424 for (j = 0; mbbmbc[j][0] != 0; j++) 1425 { 1426 unsigned int exp, ret; 1427 ret = _mbbtombc(mbbmbc[j][0]); 1428 exp = (cp[i] == 932) ? mbbmbc[j][1] : mbbmbc[j][0]; 1429 ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage %d)\n", 1430 exp, ret, mbbmbc[j][0], cp[i]); 1431 } 1432 } 1433 _setmbcp(prev_cp); 1434 } 1435 1436 static void test_mbctombb(void) 1437 { 1438 static const unsigned int mbcmbb_932[][2] = { 1439 {0x829e, 0x829e}, {0x829f, 0xa7}, {0x82f1, 0xdd}, {0x82f2, 0x82f2}, 1440 {0x833f, 0x833f}, {0x8340, 0xa7}, {0x837e, 0xd0}, {0x837f, 0x837f}, 1441 {0x8380, 0xd1}, {0x8396, 0xb9}, {0x8397, 0x8397}, {0x813f, 0x813f}, 1442 {0x8140, 0x20}, {0x814c, 0x814c}, {0x814f, 0x5e}, {0x8197, 0x40}, 1443 {0x8198, 0x8198}, {0x8258, 0x39}, {0x8259, 0x8259}, {0x825f, 0x825f}, 1444 {0x8260, 0x41}, {0x82f1, 0xdd}, {0x82f2, 0x82f2}, {0,0}}; 1445 unsigned int exp, ret, i; 1446 unsigned int prev_cp = _getmbcp(); 1447 1448 _setmbcp(932); 1449 for (i = 0; mbcmbb_932[i][0] != 0; i++) 1450 { 1451 ret = _mbctombb(mbcmbb_932[i][0]); 1452 exp = mbcmbb_932[i][1]; 1453 ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret); 1454 } 1455 _setmbcp(prev_cp); 1456 } 1457 1458 static void test_ismbckata(void) { 1459 struct katakana_pair { 1460 UINT c; 1461 BOOL exp; 1462 }; 1463 static const struct katakana_pair tests[] = { 1464 {0x8152, FALSE}, {0x8153, FALSE}, {0x8154, FALSE}, {0x8155, FALSE}, 1465 {0x82a0, FALSE}, {0x833f, FALSE}, {0x8340, TRUE }, {0x837e, TRUE }, 1466 {0x837f, FALSE}, {0x8380, TRUE }, {0x8396, TRUE }, {0x8397, FALSE}, 1467 {0xa5, FALSE}, {0xb0, FALSE}, {0xdd, FALSE} 1468 }; 1469 unsigned int prev_cp = _getmbcp(); 1470 int ret; 1471 unsigned int i; 1472 1473 _setmbcp(_MB_CP_SBCS); 1474 for (i = 0; i < ARRAY_SIZE(tests); i++) { 1475 ret = _ismbckata(tests[i].c); 1476 ok(!ret, "expected 0, got %d for %04x\n", ret, tests[i].c); 1477 } 1478 1479 _setmbcp(932); 1480 for (i = 0; i < ARRAY_SIZE(tests); i++) { 1481 ret = _ismbckata(tests[i].c); 1482 ok(!!ret == tests[i].exp, "expected %d, got %d for %04x\n", 1483 tests[i].exp, !!ret, tests[i].c); 1484 } 1485 1486 _setmbcp(prev_cp); 1487 } 1488 1489 static void test_ismbclegal(void) { 1490 unsigned int prev_cp = _getmbcp(); 1491 int ret, exp, err; 1492 unsigned int i; 1493 1494 _setmbcp(932); /* Japanese */ 1495 err = 0; 1496 for(i = 0; i < 0x10000; i++) { 1497 ret = _ismbclegal(i); 1498 exp = ((HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0x9F) || 1499 (HIBYTE(i) >= 0xE0 && HIBYTE(i) <= 0xFC)) && 1500 ((LOBYTE(i) >= 0x40 && LOBYTE(i) <= 0x7E) || 1501 (LOBYTE(i) >= 0x80 && LOBYTE(i) <= 0xFC)); 1502 if(ret != exp) { 1503 err = 1; 1504 break; 1505 } 1506 } 1507 ok(!err, "_ismbclegal (932) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i); 1508 _setmbcp(936); /* Chinese (GBK) */ 1509 err = 0; 1510 for(i = 0; i < 0x10000; i++) { 1511 ret = _ismbclegal(i); 1512 exp = HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xFE && 1513 LOBYTE(i) >= 0x40 && LOBYTE(i) <= 0xFE; 1514 if(ret != exp) { 1515 err = 1; 1516 break; 1517 } 1518 } 1519 ok(!err, "_ismbclegal (936) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i); 1520 _setmbcp(949); /* Korean */ 1521 err = 0; 1522 for(i = 0; i < 0x10000; i++) { 1523 ret = _ismbclegal(i); 1524 exp = HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xFE && 1525 LOBYTE(i) >= 0x41 && LOBYTE(i) <= 0xFE; 1526 if(ret != exp) { 1527 err = 1; 1528 break; 1529 } 1530 } 1531 ok(!err, "_ismbclegal (949) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i); 1532 _setmbcp(950); /* Chinese (Big5) */ 1533 err = 0; 1534 for(i = 0; i < 0x10000; i++) { 1535 ret = _ismbclegal(i); 1536 exp = HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xFE && 1537 ((LOBYTE(i) >= 0x40 && LOBYTE(i) <= 0x7E) || 1538 (LOBYTE(i) >= 0xA1 && LOBYTE(i) <= 0xFE)); 1539 if(ret != exp) { 1540 err = 1; 1541 break; 1542 } 1543 } 1544 ok(!err, "_ismbclegal (950) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i); 1545 _setmbcp(1361); /* Korean (Johab) */ 1546 err = 0; 1547 for(i = 0; i < 0x10000; i++) { 1548 ret = _ismbclegal(i); 1549 exp = ((HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xD3) || 1550 (HIBYTE(i) >= 0xD8 && HIBYTE(i) <= 0xF9)) && 1551 ((LOBYTE(i) >= 0x31 && LOBYTE(i) <= 0x7E) || 1552 (LOBYTE(i) >= 0x81 && LOBYTE(i) <= 0xFE)) && 1553 HIBYTE(i) != 0xDF; 1554 if(ret != exp) { 1555 err = 1; 1556 break; 1557 } 1558 } 1559 todo_wine ok(!err, "_ismbclegal (1361) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i); 1560 1561 _setmbcp(prev_cp); 1562 } 1563 1564 static const struct { 1565 const char* string; 1566 const char* delimiter; 1567 int exp_offsetret1; /* returned offset from string after first call to strtok() 1568 -1 means NULL */ 1569 int exp_offsetret2; /* returned offset from string after second call to strtok() 1570 -1 means NULL */ 1571 int exp_offsetret3; /* returned offset from string after third call to strtok() 1572 -1 means NULL */ 1573 } testcases_strtok[] = { 1574 { "red cabernet", " ", 0, 4, -1 }, 1575 { "sparkling white riesling", " ", 0, 10, 16 }, 1576 { " pale cream sherry", "e ", 1, 6, 9 }, 1577 /* end mark */ 1578 { 0} 1579 }; 1580 1581 static void test_strtok(void) 1582 { 1583 int i; 1584 char *strret; 1585 char teststr[100]; 1586 for( i = 0; testcases_strtok[i].string; i++){ 1587 strcpy( teststr, testcases_strtok[i].string); 1588 strret = strtok( teststr, testcases_strtok[i].delimiter); 1589 ok( (int)(strret - teststr) == testcases_strtok[i].exp_offsetret1 || 1590 (!strret && testcases_strtok[i].exp_offsetret1 == -1), 1591 "string (%p) \'%s\' return %p\n", 1592 teststr, testcases_strtok[i].string, strret); 1593 if( !strret) continue; 1594 strret = strtok( NULL, testcases_strtok[i].delimiter); 1595 ok( (int)(strret - teststr) == testcases_strtok[i].exp_offsetret2 || 1596 (!strret && testcases_strtok[i].exp_offsetret2 == -1), 1597 "second call string (%p) \'%s\' return %p\n", 1598 teststr, testcases_strtok[i].string, strret); 1599 if( !strret) continue; 1600 strret = strtok( NULL, testcases_strtok[i].delimiter); 1601 ok( (int)(strret - teststr) == testcases_strtok[i].exp_offsetret3 || 1602 (!strret && testcases_strtok[i].exp_offsetret3 == -1), 1603 "third call string (%p) \'%s\' return %p\n", 1604 teststr, testcases_strtok[i].string, strret); 1605 } 1606 } 1607 1608 static void test_strtol(void) 1609 { 1610 static char neg[] = "-0x"; 1611 1612 char* e; 1613 LONG l; 1614 ULONG ul; 1615 1616 /* errno is only set in case of error, so reset errno to EBADF to check for errno modification */ 1617 /* errno is modified on W2K8+ */ 1618 errno = EBADF; 1619 l = strtol("-1234", &e, 0); 1620 ok(l==-1234, "wrong value %d\n", l); 1621 ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); 1622 errno = EBADF; 1623 ul = strtoul("1234", &e, 0); 1624 ok(ul==1234, "wrong value %u\n", ul); 1625 ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); 1626 1627 errno = EBADF; 1628 l = strtol("2147483647L", &e, 0); 1629 ok(l==2147483647, "wrong value %d\n", l); 1630 ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); 1631 errno = EBADF; 1632 l = strtol("-2147483648L", &e, 0); 1633 ok(l==-2147483647L - 1, "wrong value %d\n", l); 1634 ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); 1635 errno = EBADF; 1636 ul = strtoul("4294967295UL", &e, 0); 1637 ok(ul==4294967295ul, "wrong value %u\n", ul); 1638 ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); 1639 1640 errno = 0; 1641 l = strtol("9223372036854775807L", &e, 0); 1642 ok(l==2147483647, "wrong value %d\n", l); 1643 ok(errno == ERANGE, "wrong errno %d\n", errno); 1644 errno = 0; 1645 ul = strtoul("9223372036854775807L", &e, 0); 1646 ok(ul==4294967295ul, "wrong value %u\n", ul); 1647 ok(errno == ERANGE, "wrong errno %d\n", errno); 1648 1649 errno = 0; 1650 ul = strtoul("-2", NULL, 0); 1651 ok(ul == -2, "wrong value %u\n", ul); 1652 ok(errno == 0, "wrong errno %d\n", errno); 1653 1654 errno = 0; 1655 ul = strtoul("-4294967294", NULL, 0); 1656 ok(ul == 2, "wrong value %u\n", ul); 1657 ok(errno == 0, "wrong errno %d\n", errno); 1658 1659 errno = 0; 1660 ul = strtoul("-4294967295", NULL, 0); 1661 ok(ul==1, "wrong value %u\n", ul); 1662 ok(errno == 0, "wrong errno %d\n", errno); 1663 1664 errno = 0; 1665 ul = strtoul("-4294967296", NULL, 0); 1666 ok(ul == 1, "wrong value %u\n", ul); 1667 ok(errno == ERANGE, "wrong errno %d\n", errno); 1668 1669 errno = 0; 1670 l = strtol(neg, &e, 0); 1671 ok(l == 0, "wrong value %d\n", l); 1672 ok(errno == 0, "wrong errno %d\n", errno); 1673 ok(e == neg, "e = %p, neg = %p\n", e, neg); 1674 } 1675 1676 static void test_strnlen(void) 1677 { 1678 static const char str[] = "string"; 1679 size_t res; 1680 1681 if(!p_strnlen) { 1682 win_skip("strnlen not found\n"); 1683 return; 1684 } 1685 1686 res = p_strnlen(str, 20); 1687 ok(res == 6, "Returned length = %d\n", (int)res); 1688 1689 res = p_strnlen(str, 3); 1690 ok(res == 3, "Returned length = %d\n", (int)res); 1691 1692 res = p_strnlen(NULL, 0); 1693 ok(res == 0, "Returned length = %d\n", (int)res); 1694 } 1695 1696 static void test__strtoi64(void) 1697 { 1698 static const char no1[] = "31923"; 1699 static const char no2[] = "-213312"; 1700 static const char no3[] = "12aa"; 1701 static const char no4[] = "abc12"; 1702 static const char overflow[] = "99999999999999999999"; 1703 static const char neg_overflow[] = "-99999999999999999999"; 1704 static const char hex[] = "0x123"; 1705 static const char oct[] = "000123"; 1706 static const char blanks[] = " 12 212.31"; 1707 1708 __int64 res; 1709 unsigned __int64 ures; 1710 char *endpos; 1711 1712 if(!p_strtoi64 || !p_strtoui64) { 1713 win_skip("_strtoi64 or _strtoui64 not found\n"); 1714 return; 1715 } 1716 1717 errno = 0xdeadbeef; 1718 res = p_strtoi64(no1, NULL, 10); 1719 ok(res == 31923, "res != 31923\n"); 1720 res = p_strtoi64(no2, NULL, 10); 1721 ok(res == -213312, "res != -213312\n"); 1722 res = p_strtoi64(no3, NULL, 10); 1723 ok(res == 12, "res != 12\n"); 1724 res = p_strtoi64(no4, &endpos, 10); 1725 ok(res == 0, "res != 0\n"); 1726 ok(endpos == no4, "Scanning was not stopped on first character\n"); 1727 res = p_strtoi64(hex, &endpos, 10); 1728 ok(res == 0, "res != 0\n"); 1729 ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos); 1730 res = p_strtoi64(oct, &endpos, 10); 1731 ok(res == 123, "res != 123\n"); 1732 ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); 1733 res = p_strtoi64(blanks, &endpos, 10); 1734 ok(res == 12, "res != 12\n"); 1735 ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); 1736 ok(errno == 0xdeadbeef, "errno = %x\n", errno); 1737 1738 errno = 0xdeadbeef; 1739 res = p_strtoi64(overflow, &endpos, 10); 1740 ok(res == _I64_MAX, "res != _I64_MAX\n"); 1741 ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos); 1742 ok(errno == ERANGE, "errno = %x\n", errno); 1743 1744 errno = 0xdeadbeef; 1745 res = p_strtoi64(neg_overflow, &endpos, 10); 1746 ok(res == _I64_MIN, "res != _I64_MIN\n"); 1747 ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos); 1748 ok(errno == ERANGE, "errno = %x\n", errno); 1749 1750 errno = 0xdeadbeef; 1751 res = p_strtoi64(no1, &endpos, 16); 1752 ok(res == 203043, "res != 203043\n"); 1753 ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos); 1754 res = p_strtoi64(no2, &endpos, 16); 1755 ok(res == -2175762, "res != -2175762\n"); 1756 ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos); 1757 res = p_strtoi64(no3, &endpos, 16); 1758 ok(res == 4778, "res != 4778\n"); 1759 ok(endpos == no3+strlen(no3), "Incorrect endpos (%p-%p)\n", no3, endpos); 1760 res = p_strtoi64(no4, &endpos, 16); 1761 ok(res == 703506, "res != 703506\n"); 1762 ok(endpos == no4+strlen(no4), "Incorrect endpos (%p-%p)\n", no4, endpos); 1763 res = p_strtoi64(hex, &endpos, 16); 1764 ok(res == 291, "res != 291\n"); 1765 ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos); 1766 res = p_strtoi64(oct, &endpos, 16); 1767 ok(res == 291, "res != 291\n"); 1768 ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); 1769 res = p_strtoi64(blanks, &endpos, 16); 1770 ok(res == 18, "res != 18\n"); 1771 ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); 1772 ok(errno == 0xdeadbeef, "errno = %x\n", errno); 1773 1774 errno = 0xdeadbeef; 1775 res = p_strtoi64(hex, &endpos, 36); 1776 ok(res == 1541019, "res != 1541019\n"); 1777 ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos); 1778 ok(errno == 0xdeadbeef, "errno = %x\n", errno); 1779 1780 errno = 0xdeadbeef; 1781 res = p_strtoi64(no1, &endpos, 0); 1782 ok(res == 31923, "res != 31923\n"); 1783 ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos); 1784 res = p_strtoi64(no2, &endpos, 0); 1785 ok(res == -213312, "res != -213312\n"); 1786 ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos); 1787 res = p_strtoi64(no3, &endpos, 10); 1788 ok(res == 12, "res != 12\n"); 1789 ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos); 1790 res = p_strtoi64(no4, &endpos, 10); 1791 ok(res == 0, "res != 0\n"); 1792 ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos); 1793 res = p_strtoi64(hex, &endpos, 10); 1794 ok(res == 0, "res != 0\n"); 1795 ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos); 1796 res = p_strtoi64(oct, &endpos, 10); 1797 ok(res == 123, "res != 123\n"); 1798 ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); 1799 res = p_strtoi64(blanks, &endpos, 10); 1800 ok(res == 12, "res != 12\n"); 1801 ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); 1802 ok(errno == 0xdeadbeef, "errno = %x\n", errno); 1803 1804 errno = 0xdeadbeef; 1805 ures = p_strtoui64(no1, &endpos, 0); 1806 ok(ures == 31923, "ures != 31923\n"); 1807 ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos); 1808 ures = p_strtoui64(no2, &endpos, 0); 1809 ok(ures == -213312, "ures != -213312\n"); 1810 ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos); 1811 ures = p_strtoui64(no3, &endpos, 10); 1812 ok(ures == 12, "ures != 12\n"); 1813 ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos); 1814 ures = p_strtoui64(no4, &endpos, 10); 1815 ok(ures == 0, "ures != 0\n"); 1816 ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos); 1817 ures = p_strtoui64(hex, &endpos, 10); 1818 ok(ures == 0, "ures != 0\n"); 1819 ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos); 1820 ures = p_strtoui64(oct, &endpos, 10); 1821 ok(ures == 123, "ures != 123\n"); 1822 ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos); 1823 ures = p_strtoui64(blanks, &endpos, 10); 1824 ok(ures == 12, "ures != 12\n"); 1825 ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos); 1826 ok(errno == 0xdeadbeef, "errno = %x\n", errno); 1827 1828 errno = 0xdeadbeef; 1829 ures = p_strtoui64(overflow, &endpos, 10); 1830 ok(ures == _UI64_MAX, "ures != _UI64_MAX\n"); 1831 ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos); 1832 ok(errno == ERANGE, "errno = %x\n", errno); 1833 1834 errno = 0xdeadbeef; 1835 ures = p_strtoui64(neg_overflow, &endpos, 10); 1836 ok(ures == 1, "ures != 1\n"); 1837 ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos); 1838 ok(errno == ERANGE, "errno = %x\n", errno); 1839 } 1840 1841 static inline BOOL almost_equal(double d1, double d2) { 1842 if(d1-d2>-1e-30 && d1-d2<1e-30) 1843 return TRUE; 1844 return FALSE; 1845 } 1846 1847 static void test__strtod(void) 1848 { 1849 const char double1[] = "12.1"; 1850 const char double2[] = "-13.721"; 1851 const char double3[] = "INF"; 1852 const char double4[] = ".21e12"; 1853 const char double5[] = "214353e-3"; 1854 const char double6[] = "NAN"; 1855 const char overflow[] = "1d9999999999999999999"; 1856 const char white_chars[] = " d10"; 1857 1858 char *end; 1859 double d; 1860 1861 d = strtod(double1, &end); 1862 ok(almost_equal(d, 12.1), "d = %lf\n", d); 1863 ok(end == double1+4, "incorrect end (%d)\n", (int)(end-double1)); 1864 1865 d = strtod(double2, &end); 1866 ok(almost_equal(d, -13.721), "d = %lf\n", d); 1867 ok(end == double2+7, "incorrect end (%d)\n", (int)(end-double2)); 1868 1869 d = strtod(double3, &end); 1870 ok(almost_equal(d, 0), "d = %lf\n", d); 1871 ok(end == double3, "incorrect end (%d)\n", (int)(end-double3)); 1872 1873 d = strtod(double4, &end); 1874 ok(almost_equal(d, 210000000000.0), "d = %lf\n", d); 1875 ok(end == double4+6, "incorrect end (%d)\n", (int)(end-double4)); 1876 1877 d = strtod(double5, &end); 1878 ok(almost_equal(d, 214.353), "d = %lf\n", d); 1879 ok(end == double5+9, "incorrect end (%d)\n", (int)(end-double5)); 1880 1881 d = strtod(double6, &end); 1882 ok(almost_equal(d, 0), "d = %lf\n", d); 1883 ok(end == double6, "incorrect end (%d)\n", (int)(end-double6)); 1884 1885 d = strtod("12.1d2", NULL); 1886 ok(almost_equal(d, 12.1e2), "d = %lf\n", d); 1887 1888 d = strtod(white_chars, &end); 1889 ok(almost_equal(d, 0), "d = %lf\n", d); 1890 ok(end == white_chars, "incorrect end (%d)\n", (int)(end-white_chars)); 1891 1892 if (!p__strtod_l) 1893 win_skip("_strtod_l not found\n"); 1894 else 1895 { 1896 errno = EBADF; 1897 d = strtod(NULL, NULL); 1898 ok(almost_equal(d, 0.0), "d = %lf\n", d); 1899 ok(errno == EINVAL, "errno = %x\n", errno); 1900 1901 errno = EBADF; 1902 end = (char *)0xdeadbeef; 1903 d = strtod(NULL, &end); 1904 ok(almost_equal(d, 0.0), "d = %lf\n", d); 1905 ok(errno == EINVAL, "errno = %x\n", errno); 1906 ok(!end, "incorrect end ptr %p\n", end); 1907 1908 errno = EBADF; 1909 d = p__strtod_l(NULL, NULL, NULL); 1910 ok(almost_equal(d, 0.0), "d = %lf\n", d); 1911 ok(errno == EINVAL, "errno = %x\n", errno); 1912 } 1913 1914 /* Set locale with non '.' decimal point (',') */ 1915 if(!setlocale(LC_ALL, "Polish")) { 1916 win_skip("system with limited locales\n"); 1917 return; 1918 } 1919 1920 d = strtod("12.1", NULL); 1921 ok(almost_equal(d, 12.0), "d = %lf\n", d); 1922 1923 d = strtod("12,1", NULL); 1924 ok(almost_equal(d, 12.1), "d = %lf\n", d); 1925 1926 setlocale(LC_ALL, "C"); 1927 1928 /* Precision tests */ 1929 d = strtod("0.1", NULL); 1930 ok(almost_equal(d, 0.1), "d = %lf\n", d); 1931 d = strtod("-0.1", NULL); 1932 ok(almost_equal(d, -0.1), "d = %lf\n", d); 1933 d = strtod("0.1281832188491894198128921", NULL); 1934 ok(almost_equal(d, 0.1281832188491894198128921), "d = %lf\n", d); 1935 d = strtod("0.82181281288121", NULL); 1936 ok(almost_equal(d, 0.82181281288121), "d = %lf\n", d); 1937 d = strtod("21921922352523587651128218821", NULL); 1938 ok(almost_equal(d, 21921922352523587651128218821.0), "d = %lf\n", d); 1939 d = strtod("0.1d238", NULL); 1940 ok(almost_equal(d, 0.1e238L), "d = %lf\n", d); 1941 d = strtod("0.1D-4736", NULL); 1942 ok(almost_equal(d, 0.1e-4736L), "d = %lf\n", d); 1943 1944 errno = 0xdeadbeef; 1945 strtod(overflow, &end); 1946 ok(errno == ERANGE, "errno = %x\n", errno); 1947 ok(end == overflow+21, "incorrect end (%d)\n", (int)(end-overflow)); 1948 1949 errno = 0xdeadbeef; 1950 strtod("-1d309", NULL); 1951 ok(errno == ERANGE, "errno = %x\n", errno); 1952 } 1953 1954 static void test_mbstowcs(void) 1955 { 1956 static const wchar_t wSimple[] = { 't','e','x','t',0 }; 1957 static const wchar_t wHiragana[] = { 0x3042,0x3043,0 }; 1958 static const wchar_t wEmpty[] = { 0 }; 1959 static const char mSimple[] = "text"; 1960 static const char mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 }; 1961 static const char mEmpty[] = { 0 }; 1962 1963 const wchar_t *pwstr; 1964 wchar_t wOut[6]; 1965 char mOut[6]; 1966 size_t ret; 1967 int err; 1968 const char *pmbstr; 1969 mbstate_t state; 1970 1971 wOut[4] = '!'; wOut[5] = '\0'; 1972 mOut[4] = '!'; mOut[5] = '\0'; 1973 1974 if(pmbstowcs_s) { 1975 /* crashes on some systems */ 1976 errno = 0xdeadbeef; 1977 ret = mbstowcs(wOut, NULL, 4); 1978 ok(ret == -1, "mbstowcs did not return -1\n"); 1979 ok(errno == EINVAL, "errno = %d\n", errno); 1980 } 1981 1982 ret = mbstowcs(NULL, mSimple, 0); 1983 ok(ret == 4, "mbstowcs did not return 4\n"); 1984 1985 ret = mbstowcs(wOut, mSimple, 4); 1986 ok(ret == 4, "mbstowcs did not return 4\n"); 1987 ok(!memcmp(wOut, wSimple, 4*sizeof(wchar_t)), "wOut = %s\n", wine_dbgstr_w(wOut)); 1988 ok(wOut[4] == '!', "wOut[4] != \'!\'\n"); 1989 1990 ret = mbstowcs(NULL, mEmpty, 1); 1991 ok(ret == 0, "mbstowcs did not return 0, got %d\n", (int)ret); 1992 1993 ret = mbstowcs(wOut, mEmpty, 1); 1994 ok(ret == 0, "mbstowcs did not return 0, got %d\n", (int)ret); 1995 ok(!memcmp(wOut, wEmpty, sizeof(wEmpty)), "wOut = %s\n", wine_dbgstr_w(wOut)); 1996 1997 ret = wcstombs(NULL, wSimple, 0); 1998 ok(ret == 4, "wcstombs did not return 4\n"); 1999 2000 ret = wcstombs(mOut, wSimple, 6); 2001 ok(ret == 4, "wcstombs did not return 4\n"); 2002 ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut); 2003 2004 ret = wcstombs(mOut, wSimple, 2); 2005 ok(ret == 2, "wcstombs did not return 2\n"); 2006 ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut); 2007 2008 ret = wcstombs(NULL, wEmpty, 1); 2009 ok(ret == 0, "wcstombs did not return 0, got %d\n", (int)ret); 2010 2011 ret = wcstombs(mOut, wEmpty, 1); 2012 ok(ret == 0, "wcstombs did not return 0, got %d\n", (int)ret); 2013 ok(!memcmp(mOut, mEmpty, sizeof(mEmpty)), "mOut = %s\n", mOut); 2014 2015 if(!setlocale(LC_ALL, "Japanese_Japan.932")) { 2016 win_skip("Japanese_Japan.932 locale not available\n"); 2017 return; 2018 } 2019 2020 ret = mbstowcs(wOut, mHiragana, 6); 2021 ok(ret == 2, "mbstowcs did not return 2\n"); 2022 ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut)); 2023 2024 ret = mbstowcs(wOut, mEmpty, 6); 2025 ok(ret == 0, "mbstowcs did not return 0, got %d\n", (int)ret); 2026 ok(!memcmp(wOut, wEmpty, sizeof(wEmpty)), "wOut = %s\n", wine_dbgstr_w(wOut)); 2027 2028 ret = wcstombs(mOut, wHiragana, 6); 2029 ok(ret == 4, "wcstombs did not return 4\n"); 2030 ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut); 2031 2032 ret = wcstombs(mOut, wEmpty, 6); 2033 ok(ret == 0, "wcstombs did not return 0, got %d\n", (int)ret); 2034 ok(!memcmp(mOut, mEmpty, sizeof(mEmpty)), "mOut = %s\n", mOut); 2035 2036 if(!pmbstowcs_s || !pwcstombs_s) { 2037 setlocale(LC_ALL, "C"); 2038 win_skip("mbstowcs_s or wcstombs_s not available\n"); 2039 return; 2040 } 2041 2042 err = pmbstowcs_s(&ret, wOut, 6, mSimple, _TRUNCATE); 2043 ok(err == 0, "err = %d\n", err); 2044 ok(ret == 5, "mbstowcs_s did not return 5\n"); 2045 ok(!memcmp(wOut, wSimple, sizeof(wSimple)), "wOut = %s\n", wine_dbgstr_w(wOut)); 2046 2047 err = pmbstowcs_s(&ret, wOut, 6, mHiragana, _TRUNCATE); 2048 ok(err == 0, "err = %d\n", err); 2049 ok(ret == 3, "mbstowcs_s did not return 3\n"); 2050 ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut)); 2051 2052 err = pmbstowcs_s(&ret, wOut, 6, mEmpty, _TRUNCATE); 2053 ok(err == 0, "err = %d\n", err); 2054 ok(ret == 1, "mbstowcs_s did not return 1, got %d\n", (int)ret); 2055 ok(!memcmp(wOut, wEmpty, sizeof(wEmpty)), "wOut = %s\n", wine_dbgstr_w(wOut)); 2056 2057 err = pmbstowcs_s(&ret, NULL, 0, mHiragana, 1); 2058 ok(err == 0, "err = %d\n", err); 2059 ok(ret == 3, "mbstowcs_s did not return 3\n"); 2060 2061 err = pwcstombs_s(&ret, mOut, 6, wSimple, _TRUNCATE); 2062 ok(err == 0, "err = %d\n", err); 2063 ok(ret == 5, "wcstombs_s did not return 5\n"); 2064 ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut); 2065 2066 err = pwcstombs_s(&ret, mOut, 6, wHiragana, _TRUNCATE); 2067 ok(err == 0, "err = %d\n", err); 2068 ok(ret == 5, "wcstombs_s did not return 5\n"); 2069 ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut); 2070 2071 err = pwcstombs_s(&ret, mOut, 6, wEmpty, _TRUNCATE); 2072 ok(err == 0, "err = %d\n", err); 2073 ok(ret == 1, "wcstombs_s did not return 1, got %d\n", (int)ret); 2074 ok(!memcmp(mOut, mEmpty, sizeof(mEmpty)), "mOut = %s\n", mOut); 2075 2076 err = pwcstombs_s(&ret, NULL, 0, wHiragana, 1); 2077 ok(err == 0, "err = %d\n", err); 2078 ok(ret == 5, "wcstombs_s did not return 5\n"); 2079 2080 if(!pwcsrtombs) { 2081 setlocale(LC_ALL, "C"); 2082 win_skip("wcsrtombs not available\n"); 2083 return; 2084 } 2085 2086 pwstr = wSimple; 2087 err = -3; 2088 ret = pwcsrtombs(mOut, &pwstr, 4, &err); 2089 ok(ret == 4, "wcsrtombs did not return 4\n"); 2090 ok(err == 0, "err = %d\n", err); 2091 ok(pwstr == wSimple+4, "pwstr = %p (wszSimple = %p)\n", pwstr, wSimple); 2092 ok(!memcmp(mOut, mSimple, ret), "mOut = %s\n", mOut); 2093 2094 pwstr = wSimple; 2095 ret = pwcsrtombs(mOut, &pwstr, 5, NULL); 2096 ok(ret == 4, "wcsrtombs did not return 4\n"); 2097 ok(pwstr == NULL, "pwstr != NULL\n"); 2098 ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut); 2099 2100 if(!p_mbsrtowcs) { 2101 setlocale(LC_ALL, "C"); 2102 win_skip("mbsrtowcs not available\n"); 2103 return; 2104 } 2105 2106 pmbstr = mHiragana; 2107 ret = p_mbsrtowcs(NULL, &pmbstr, 6, NULL); 2108 ok(ret == 2, "mbsrtowcs did not return 2\n"); 2109 ok(pmbstr == mHiragana, "pmbstr = %p, expected %p\n", pmbstr, mHiragana); 2110 2111 pmbstr = mHiragana; 2112 ret = p_mbsrtowcs(wOut, &pmbstr, 6, NULL); 2113 ok(ret == 2, "mbsrtowcs did not return 2\n"); 2114 ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut)); 2115 ok(!pmbstr, "pmbstr != NULL\n"); 2116 2117 state = mHiragana[0]; 2118 pmbstr = mHiragana+1; 2119 ret = p_mbsrtowcs(wOut, &pmbstr, 6, &state); 2120 ok(ret == 2, "mbsrtowcs did not return 2\n"); 2121 ok(wOut[0] == 0x3042, "wOut[0] = %x\n", wOut[0]); 2122 ok(wOut[1] == 0xff61, "wOut[1] = %x\n", wOut[1]); 2123 ok(wOut[2] == 0, "wOut[2] = %x\n", wOut[2]); 2124 ok(!pmbstr, "pmbstr != NULL\n"); 2125 2126 errno = EBADF; 2127 ret = p_mbsrtowcs(wOut, NULL, 6, &state); 2128 ok(ret == -1, "mbsrtowcs did not return -1\n"); 2129 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2130 2131 if(!p_mbsrtowcs_s) { 2132 setlocale(LC_ALL, "C"); 2133 win_skip("mbsrtowcs_s not available\n"); 2134 return; 2135 } 2136 2137 pmbstr = mHiragana; 2138 err = p_mbsrtowcs_s(&ret, NULL, 0, NULL, 6, NULL); 2139 ok(ret == -1, "mbsrtowcs_s did not return -1\n"); 2140 ok(err == EINVAL, "err = %d\n", err); 2141 err = p_mbsrtowcs_s(&ret, NULL, 1, &pmbstr, 6, NULL); 2142 ok(ret == -1, "mbsrtowcs_s did not return -1\n"); 2143 ok(err == EINVAL, "err = %d\n", err); 2144 err = p_mbsrtowcs_s(&ret, wOut, 0, &pmbstr, 6, NULL); 2145 ok(ret == -1, "mbsrtowcs_s did not return -1\n"); 2146 ok(err == EINVAL, "err = %d\n", err); 2147 2148 pmbstr = mHiragana; 2149 errno = 0; 2150 err = p_mbsrtowcs_s(&ret, NULL, 0, &pmbstr, 6, NULL); 2151 ok(ret == 3, "mbsrtowcs_s did not return 3\n"); 2152 ok(err == 0, "err = %d\n", err); 2153 ok(pmbstr == mHiragana, "pmbstr = %p, expected %p\n", pmbstr, mHiragana); 2154 ok(errno == 0, "errno = %d\n", errno); 2155 2156 pmbstr = mHiragana; 2157 err = p_mbsrtowcs_s(&ret, wOut, 1, &pmbstr, 6, NULL); 2158 ok(ret == 2, "mbsrtowcs_s did not return 2\n"); 2159 ok(err == 0, "err = %d\n", err); 2160 ok(!wOut[0], "wOut[0] = '%c'\n", wOut[0]); 2161 ok(pmbstr == mHiragana+2, "pmbstr = %p, expected %p\n", pmbstr, mHiragana+2); 2162 ok(errno == 0, "errno = %d\n", errno); 2163 2164 pmbstr = mHiragana; 2165 err = p_mbsrtowcs_s(&ret, wOut, 2, &pmbstr, 6, NULL); 2166 ok(ret == 3, "mbsrtowcs_s did not return 3\n"); 2167 ok(err == 0, "err = %d\n", err); 2168 ok(!wOut[0], "wOut[0] = '%c'\n", wOut[0]); 2169 ok(pmbstr == mHiragana+4, "pmbstr = %p, expected %p\n", pmbstr, mHiragana+4); 2170 ok(errno == 0, "errno = %d\n", errno); 2171 2172 pmbstr = mHiragana; 2173 err = p_mbsrtowcs_s(&ret, wOut, 3, &pmbstr, 6, NULL); 2174 ok(ret == 3, "mbsrtowcs_s did not return 3\n"); 2175 ok(err == 0, "err = %d\n", err); 2176 ok(!pmbstr, "pmbstr != NULL\n"); 2177 ok(errno == 0, "errno = %d\n", errno); 2178 2179 setlocale(LC_ALL, "C"); 2180 } 2181 2182 static void test_gcvt(void) 2183 { 2184 char buf[1024], *res; 2185 errno_t err; 2186 2187 if(!p_gcvt_s) { 2188 win_skip("Skipping _gcvt tests\n"); 2189 return; 2190 } 2191 2192 errno = 0; 2193 res = _gcvt(1.2, -1, buf); 2194 ok(res == NULL, "res != NULL\n"); 2195 ok(errno == ERANGE, "errno = %d\n", errno); 2196 2197 errno = 0; 2198 res = _gcvt(1.2, 5, NULL); 2199 ok(res == NULL, "res != NULL\n"); 2200 ok(errno == EINVAL, "errno = %d\n", errno); 2201 2202 res = gcvt(1.2, 5, buf); 2203 ok(res == buf, "res != buf\n"); 2204 ok(!strcmp(buf, "1.2"), "buf = %s\n", buf); 2205 2206 buf[0] = 'x'; 2207 err = p_gcvt_s(buf, 5, 1.2, 10); 2208 ok(err == ERANGE, "err = %d\n", err); 2209 ok(buf[0] == '\0', "buf[0] = %c\n", buf[0]); 2210 2211 buf[0] = 'x'; 2212 err = p_gcvt_s(buf, 4, 123456, 2); 2213 ok(err == ERANGE, "err = %d\n", err); 2214 ok(buf[0] == '\0', "buf[0] = %c\n", buf[0]); 2215 } 2216 2217 static void test__itoa_s(void) 2218 { 2219 errno_t ret; 2220 char buffer[33]; 2221 2222 if (!p_itoa_s) 2223 { 2224 win_skip("Skipping _itoa_s tests\n"); 2225 return; 2226 } 2227 2228 errno = EBADF; 2229 ret = p_itoa_s(0, NULL, 0, 0); 2230 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret); 2231 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2232 2233 memset(buffer, 'X', sizeof(buffer)); 2234 errno = EBADF; 2235 ret = p_itoa_s(0, buffer, 0, 0); 2236 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret); 2237 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2238 ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n"); 2239 2240 memset(buffer, 'X', sizeof(buffer)); 2241 errno = EBADF; 2242 ret = p_itoa_s(0, buffer, sizeof(buffer), 0); 2243 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret); 2244 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2245 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n"); 2246 2247 memset(buffer, 'X', sizeof(buffer)); 2248 errno = EBADF; 2249 ret = p_itoa_s(0, buffer, sizeof(buffer), 64); 2250 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret); 2251 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2252 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n"); 2253 2254 memset(buffer, 'X', sizeof(buffer)); 2255 errno = EBADF; 2256 ret = p_itoa_s(12345678, buffer, 4, 10); 2257 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret); 2258 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2259 ok(!memcmp(buffer, "\000765", 4), 2260 "Expected the output buffer to be null terminated with truncated output\n"); 2261 2262 memset(buffer, 'X', sizeof(buffer)); 2263 errno = EBADF; 2264 ret = p_itoa_s(12345678, buffer, 8, 10); 2265 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret); 2266 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2267 ok(!memcmp(buffer, "\0007654321", 8), 2268 "Expected the output buffer to be null terminated with truncated output\n"); 2269 2270 memset(buffer, 'X', sizeof(buffer)); 2271 errno = EBADF; 2272 ret = p_itoa_s(-12345678, buffer, 9, 10); 2273 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret); 2274 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2275 ok(!memcmp(buffer, "\00087654321", 9), 2276 "Expected the output buffer to be null terminated with truncated output\n"); 2277 2278 ret = p_itoa_s(12345678, buffer, 9, 10); 2279 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret); 2280 ok(!strcmp(buffer, "12345678"), 2281 "Expected output buffer string to be \"12345678\", got \"%s\"\n", 2282 buffer); 2283 2284 ret = p_itoa_s(43690, buffer, sizeof(buffer), 2); 2285 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret); 2286 ok(!strcmp(buffer, "1010101010101010"), 2287 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n", 2288 buffer); 2289 2290 ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36); 2291 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret); 2292 ok(!strcmp(buffer, "nell"), 2293 "Expected output buffer string to be \"nell\", got \"%s\"\n", 2294 buffer); 2295 2296 ret = p_itoa_s(5704, buffer, sizeof(buffer), 18); 2297 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret); 2298 ok(!strcmp(buffer, "hag"), 2299 "Expected output buffer string to be \"hag\", got \"%s\"\n", 2300 buffer); 2301 2302 ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10); 2303 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret); 2304 ok(!strcmp(buffer, "-12345678"), 2305 "Expected output buffer string to be \"-12345678\", got \"%s\"\n", 2306 buffer); 2307 2308 itoa(100, buffer, 100); 2309 ok(!strcmp(buffer, "10"), 2310 "Expected output buffer string to be \"10\", got \"%s\"\n", buffer); 2311 } 2312 2313 static void test__strlwr_s(void) 2314 { 2315 errno_t ret; 2316 char buffer[20]; 2317 2318 if (!p_strlwr_s) 2319 { 2320 win_skip("Skipping _strlwr_s tests\n"); 2321 return; 2322 } 2323 2324 errno = EBADF; 2325 ret = p_strlwr_s(NULL, 0); 2326 ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret); 2327 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2328 2329 errno = EBADF; 2330 ret = p_strlwr_s(NULL, sizeof(buffer)); 2331 ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret); 2332 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2333 2334 errno = EBADF; 2335 ret = p_strlwr_s(buffer, 0); 2336 ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret); 2337 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2338 2339 strcpy(buffer, "GoRrIsTeR"); 2340 errno = EBADF; 2341 ret = p_strlwr_s(buffer, 5); 2342 ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret); 2343 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2344 ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")), 2345 "Expected the output buffer to be \"\\0oRrIsTeR\"\n"); 2346 2347 strcpy(buffer, "GoRrIsTeR"); 2348 errno = EBADF; 2349 ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR") - 1); 2350 ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret); 2351 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2352 ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")), 2353 "Expected the output buffer to be \"\\0oRrIsTeR\"\n"); 2354 2355 strcpy(buffer, "GoRrIsTeR"); 2356 ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR")); 2357 ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret); 2358 ok(!strcmp(buffer, "gorrister"), 2359 "Expected the output buffer to be \"gorrister\", got \"%s\"\n", 2360 buffer); 2361 2362 memcpy(buffer, "GoRrIsTeR\0ELLEN", sizeof("GoRrIsTeR\0ELLEN")); 2363 ret = p_strlwr_s(buffer, sizeof(buffer)); 2364 ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret); 2365 ok(!memcmp(buffer, "gorrister\0ELLEN", sizeof("gorrister\0ELLEN")), 2366 "Expected the output buffer to be \"gorrister\\0ELLEN\", got \"%s\"\n", 2367 buffer); 2368 } 2369 2370 static void test_wcsncat_s(void) 2371 { 2372 static wchar_t abcW[] = {'a','b','c',0}; 2373 int ret; 2374 wchar_t dst[4]; 2375 wchar_t src[4]; 2376 2377 if (!p_wcsncat_s) 2378 { 2379 win_skip("skipping wcsncat_s tests\n"); 2380 return; 2381 } 2382 2383 memcpy(src, abcW, sizeof(abcW)); 2384 dst[0] = 0; 2385 ret = p_wcsncat_s(NULL, 4, src, 4); 2386 ok(ret == EINVAL, "err = %d\n", ret); 2387 ret = p_wcsncat_s(dst, 0, src, 4); 2388 ok(ret == EINVAL, "err = %d\n", ret); 2389 ret = p_wcsncat_s(dst, 0, src, _TRUNCATE); 2390 ok(ret == EINVAL, "err = %d\n", ret); 2391 ret = p_wcsncat_s(dst, 4, NULL, 0); 2392 ok(ret == 0, "err = %d\n", ret); 2393 2394 dst[0] = 0; 2395 ret = p_wcsncat_s(dst, 2, src, 4); 2396 ok(ret == ERANGE, "err = %d\n", ret); 2397 2398 dst[0] = 0; 2399 ret = p_wcsncat_s(dst, 2, src, _TRUNCATE); 2400 ok(ret == STRUNCATE, "err = %d\n", ret); 2401 ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst)); 2402 2403 memcpy(dst, abcW, sizeof(abcW)); 2404 dst[3] = 'd'; 2405 ret = p_wcsncat_s(dst, 4, src, 4); 2406 ok(ret == EINVAL, "err = %d\n", ret); 2407 } 2408 2409 static void test__mbsnbcat_s(void) 2410 { 2411 unsigned char dest[16]; 2412 const unsigned char first[] = "dinosaur"; 2413 const unsigned char second[] = "duck"; 2414 int ret; 2415 2416 if (!p_mbsnbcat_s) 2417 { 2418 win_skip("Skipping _mbsnbcat_s tests\n"); 2419 return; 2420 } 2421 2422 /* Test invalid arguments. */ 2423 ret = p_mbsnbcat_s(NULL, 0, NULL, 0); 2424 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2425 2426 errno = EBADF; 2427 ret = p_mbsnbcat_s(NULL, 10, NULL, 0); 2428 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2429 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2430 2431 errno = EBADF; 2432 ret = p_mbsnbcat_s(NULL, 0, NULL, 10); 2433 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2434 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2435 2436 memset(dest, 'X', sizeof(dest)); 2437 errno = EBADF; 2438 ret = p_mbsnbcat_s(dest, 0, NULL, 0); 2439 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2440 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2441 ok(dest[0] == 'X', "Expected the output buffer to be untouched\n"); 2442 2443 memset(dest, 'X', sizeof(dest)); 2444 errno = EBADF; 2445 ret = p_mbsnbcat_s(dest, 0, second, 0); 2446 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2447 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2448 ok(dest[0] == 'X', "Expected the output buffer to be untouched\n"); 2449 2450 memset(dest, 'X', sizeof(dest)); 2451 errno = EBADF; 2452 ret = p_mbsnbcat_s(dest, sizeof(dest), NULL, 0); 2453 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2454 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2455 ok(dest[0] == '\0', "Expected the output buffer to be null terminated\n"); 2456 2457 memset(dest, 'X', sizeof(dest)); 2458 errno = EBADF; 2459 ret = p_mbsnbcat_s(dest, sizeof(dest), NULL, 10); 2460 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2461 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2462 ok(dest[0] == '\0', "Expected the output buffer to be null terminated\n"); 2463 2464 memset(dest, 'X', sizeof(dest)); 2465 dest[0] = '\0'; 2466 ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second)); 2467 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2468 ok(!memcmp(dest, second, sizeof(second)), 2469 "Expected the output buffer string to be \"duck\"\n"); 2470 2471 /* Test source truncation behavior. */ 2472 memset(dest, 'X', sizeof(dest)); 2473 memcpy(dest, first, sizeof(first)); 2474 ret = p_mbsnbcat_s(dest, sizeof(dest), second, 0); 2475 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2476 ok(!memcmp(dest, first, sizeof(first)), 2477 "Expected the output buffer string to be \"dinosaur\"\n"); 2478 2479 memset(dest, 'X', sizeof(dest)); 2480 memcpy(dest, first, sizeof(first)); 2481 ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second)); 2482 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2483 ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")), 2484 "Expected the output buffer string to be \"dinosaurduck\"\n"); 2485 2486 memset(dest, 'X', sizeof(dest)); 2487 memcpy(dest, first, sizeof(first)); 2488 ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second) + 1); 2489 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2490 ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")), 2491 "Expected the output buffer string to be \"dinosaurduck\"\n"); 2492 2493 memset(dest, 'X', sizeof(dest)); 2494 memcpy(dest, first, sizeof(first)); 2495 ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second) - 1); 2496 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2497 ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")), 2498 "Expected the output buffer string to be \"dinosaurduck\"\n"); 2499 2500 memset(dest, 'X', sizeof(dest)); 2501 memcpy(dest, first, sizeof(first)); 2502 ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second) - 2); 2503 ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret); 2504 ok(!memcmp(dest, "dinosaurduc", sizeof("dinosaurduc")), 2505 "Expected the output buffer string to be \"dinosaurduc\"\n"); 2506 2507 /* Test destination truncation behavior. */ 2508 memset(dest, 'X', sizeof(dest)); 2509 memcpy(dest, first, sizeof(first)); 2510 errno = EBADF; 2511 ret = p_mbsnbcat_s(dest, sizeof(first) - 1, second, sizeof(second)); 2512 ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret); 2513 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2514 ok(!memcmp(dest, "\0inosaur", sizeof("\0inosaur") - 1), 2515 "Expected the output buffer string to be \"\\0inosaur\" without ending null terminator\n"); 2516 2517 memset(dest, 'X', sizeof(dest)); 2518 memcpy(dest, first, sizeof(first)); 2519 errno = EBADF; 2520 ret = p_mbsnbcat_s(dest, sizeof(first), second, sizeof(second)); 2521 ok(ret == ERANGE, "Expected _mbsnbcat_s to return ERANGE, got %d\n", ret); 2522 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2523 ok(!memcmp(dest, "\0inosaurd", sizeof("\0inosaurd") - 1), 2524 "Expected the output buffer string to be \"\\0inosaurd\" without ending null terminator\n"); 2525 2526 memset(dest, 'X', sizeof(dest)); 2527 memcpy(dest, first, sizeof(first)); 2528 errno = EBADF; 2529 ret = p_mbsnbcat_s(dest, sizeof(first) + 1, second, sizeof(second)); 2530 ok(ret == ERANGE, "Expected _mbsnbcat_s to return ERANGE, got %d\n", ret); 2531 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2532 ok(!memcmp(dest, "\0inosaurdu", sizeof("\0inosaurdu") - 1), 2533 "Expected the output buffer string to be \"\\0inosaurdu\" without ending null terminator\n"); 2534 } 2535 2536 static void test__mbsupr_s(void) 2537 { 2538 errno_t ret; 2539 unsigned char buffer[20]; 2540 2541 if (!p_mbsupr_s) 2542 { 2543 win_skip("Skipping _mbsupr_s tests\n"); 2544 return; 2545 } 2546 2547 errno = EBADF; 2548 ret = p_mbsupr_s(NULL, 0); 2549 ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); 2550 2551 errno = EBADF; 2552 ret = p_mbsupr_s(NULL, sizeof(buffer)); 2553 ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); 2554 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2555 2556 errno = EBADF; 2557 ret = p_mbsupr_s(buffer, 0); 2558 ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); 2559 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2560 2561 memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); 2562 errno = EBADF; 2563 ret = p_mbsupr_s(buffer, sizeof("abcdefgh")); 2564 ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); 2565 ok(!memcmp(buffer, "ABCDEFGH", sizeof("ABCDEFGH")), 2566 "Expected the output buffer to be \"ABCDEFGH\", got \"%s\"\n", 2567 buffer); 2568 2569 memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); 2570 errno = EBADF; 2571 ret = p_mbsupr_s(buffer, sizeof(buffer)); 2572 ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); 2573 ok(!memcmp(buffer, "ABCDEFGH", sizeof("ABCDEFGH")), 2574 "Expected the output buffer to be \"ABCDEFGH\", got \"%s\"\n", 2575 buffer); 2576 2577 memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); 2578 errno = EBADF; 2579 ret = p_mbsupr_s(buffer, 4); 2580 ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); 2581 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2582 2583 memcpy(buffer, "abcdefgh\0ijklmnop", sizeof("abcdefgh\0ijklmnop")); 2584 errno = EBADF; 2585 ret = p_mbsupr_s(buffer, sizeof(buffer)); 2586 ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); 2587 ok(!memcmp(buffer, "ABCDEFGH\0ijklmnop", sizeof("ABCDEFGH\0ijklmnop")), 2588 "Expected the output buffer to be \"ABCDEFGH\\0ijklmnop\", got \"%s\"\n", 2589 buffer); 2590 2591 } 2592 2593 static void test__mbslwr_s(void) 2594 { 2595 errno_t ret; 2596 unsigned char buffer[20]; 2597 2598 if (!p_mbslwr_s) 2599 { 2600 win_skip("Skipping _mbslwr_s tests\n"); 2601 return; 2602 } 2603 2604 errno = EBADF; 2605 ret = p_mbslwr_s(NULL, 0); 2606 ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret); 2607 2608 errno = EBADF; 2609 ret = p_mbslwr_s(NULL, sizeof(buffer)); 2610 ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret); 2611 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2612 2613 errno = EBADF; 2614 ret = p_mbslwr_s(buffer, 0); 2615 ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret); 2616 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2617 2618 memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH")); 2619 errno = EBADF; 2620 ret = p_mbslwr_s(buffer, sizeof("ABCDEFGH")); 2621 ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret); 2622 ok(!memcmp(buffer, "abcdefgh", sizeof("abcdefgh")), 2623 "Expected the output buffer to be \"abcdefgh\", got \"%s\"\n", 2624 buffer); 2625 2626 memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH")); 2627 errno = EBADF; 2628 ret = p_mbslwr_s(buffer, sizeof(buffer)); 2629 ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret); 2630 ok(!memcmp(buffer, "abcdefgh", sizeof("abcdefgh")), 2631 "Expected the output buffer to be \"abcdefgh\", got \"%s\"\n", 2632 buffer); 2633 2634 memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH")); 2635 errno = EBADF; 2636 ret = p_mbslwr_s(buffer, 4); 2637 ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret); 2638 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2639 2640 memcpy(buffer, "ABCDEFGH\0IJKLMNOP", sizeof("ABCDEFGH\0IJKLMNOP")); 2641 errno = EBADF; 2642 ret = p_mbslwr_s(buffer, sizeof(buffer)); 2643 ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret); 2644 ok(!memcmp(buffer, "abcdefgh\0IJKLMNOP", sizeof("abcdefgh\0IJKLMNOP")), 2645 "Expected the output buffer to be \"abcdefgh\\0IJKLMNOP\", got \"%s\"\n", 2646 buffer); 2647 } 2648 2649 static void test__mbstok(void) 2650 { 2651 const unsigned char delim[] = "t"; 2652 2653 char str[] = "!.!test"; 2654 unsigned char *ret; 2655 2656 strtok(str, "!"); 2657 2658 ret = _mbstok(NULL, delim); 2659 /* most versions of msvcrt use the same buffer for strtok and _mbstok */ 2660 ok(!ret || broken((char*)ret==str+4), 2661 "_mbstok(NULL, \"t\") = %p, expected NULL (%p)\n", ret, str); 2662 2663 ret = _mbstok(NULL, delim); 2664 ok(!ret, "_mbstok(NULL, \"t\") = %p, expected NULL\n", ret); 2665 } 2666 2667 static void test__ultoa_s(void) 2668 { 2669 errno_t ret; 2670 char buffer[33]; 2671 2672 if (!p_ultoa_s) 2673 { 2674 win_skip("Skipping _ultoa_s tests\n"); 2675 return; 2676 } 2677 2678 errno = EBADF; 2679 ret = p_ultoa_s(0, NULL, 0, 0); 2680 ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret); 2681 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2682 2683 memset(buffer, 'X', sizeof(buffer)); 2684 errno = EBADF; 2685 ret = p_ultoa_s(0, buffer, 0, 0); 2686 ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret); 2687 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2688 ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n"); 2689 2690 memset(buffer, 'X', sizeof(buffer)); 2691 errno = EBADF; 2692 ret = p_ultoa_s(0, buffer, sizeof(buffer), 0); 2693 ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret); 2694 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2695 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n"); 2696 2697 memset(buffer, 'X', sizeof(buffer)); 2698 errno = EBADF; 2699 ret = p_ultoa_s(0, buffer, sizeof(buffer), 64); 2700 ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret); 2701 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); 2702 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n"); 2703 2704 memset(buffer, 'X', sizeof(buffer)); 2705 errno = EBADF; 2706 ret = p_ultoa_s(12345678, buffer, 4, 10); 2707 ok(ret == ERANGE, "Expected _ultoa_s to return ERANGE, got %d\n", ret); 2708 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2709 ok(!memcmp(buffer, "\000765", 4), 2710 "Expected the output buffer to be null terminated with truncated output\n"); 2711 2712 memset(buffer, 'X', sizeof(buffer)); 2713 errno = EBADF; 2714 ret = p_ultoa_s(12345678, buffer, 8, 10); 2715 ok(ret == ERANGE, "Expected _ultoa_s to return ERANGE, got %d\n", ret); 2716 ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno); 2717 ok(!memcmp(buffer, "\0007654321", 8), 2718 "Expected the output buffer to be null terminated with truncated output\n"); 2719 2720 ret = p_ultoa_s(12345678, buffer, 9, 10); 2721 ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret); 2722 ok(!strcmp(buffer, "12345678"), 2723 "Expected output buffer string to be \"12345678\", got \"%s\"\n", 2724 buffer); 2725 2726 ret = p_ultoa_s(43690, buffer, sizeof(buffer), 2); 2727 ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret); 2728 ok(!strcmp(buffer, "1010101010101010"), 2729 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n", 2730 buffer); 2731 2732 ret = p_ultoa_s(1092009, buffer, sizeof(buffer), 36); 2733 ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret); 2734 ok(!strcmp(buffer, "nell"), 2735 "Expected output buffer string to be \"nell\", got \"%s\"\n", 2736 buffer); 2737 2738 ret = p_ultoa_s(5704, buffer, sizeof(buffer), 18); 2739 ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret); 2740 ok(!strcmp(buffer, "hag"), 2741 "Expected output buffer string to be \"hag\", got \"%s\"\n", 2742 buffer); 2743 } 2744 2745 static void test_wctob(void) 2746 { 2747 int ret, cp = _getmbcp(); 2748 2749 if(!p_wctob || !setlocale(LC_ALL, "chinese-traditional")) { 2750 win_skip("Skipping wctob tests\n"); 2751 return; 2752 } 2753 2754 ret = p_wctob(0x8141); 2755 ok(ret == EOF, "ret = %x\n", ret); 2756 2757 ret = p_wctob(0x81); 2758 ok(ret == EOF, "ret = %x\n", ret); 2759 2760 ret = p_wctob(0xe0); 2761 ok(ret == 0x61, "ret = %x\n", ret); 2762 2763 _setmbcp(1250); 2764 ret = p_wctob(0x81); 2765 ok(ret == EOF, "ret = %x\n", ret); 2766 2767 setlocale(LC_ALL, "C"); 2768 ret = p_wctob(0x8141); 2769 ok(ret == EOF, "ret = %x\n", ret); 2770 2771 ret = p_wctob(0x81); 2772 ok(ret == (int)(char)0x81, "ret = %x\n", ret); 2773 2774 ret = p_wctob(0x9f); 2775 ok(ret == (int)(char)0x9f, "ret = %x\n", ret); 2776 2777 ret = p_wctob(0xe0); 2778 ok(ret == (int)(char)0xe0, "ret = %x\n", ret); 2779 2780 _setmbcp(cp); 2781 } 2782 2783 static void test_wctomb(void) 2784 { 2785 mbstate_t state; 2786 unsigned char dst[10]; 2787 size_t ret; 2788 int err; 2789 2790 if(!p_wcrtomb || !setlocale(LC_ALL, "Japanese_Japan.932")) { 2791 win_skip("wcrtomb tests\n"); 2792 return; 2793 } 2794 2795 ret = p_wcrtomb(NULL, 0x3042, NULL); 2796 ok(ret == 2, "wcrtomb did not return 2\n"); 2797 2798 state = 1; 2799 dst[2] = 'a'; 2800 ret = p_wcrtomb((char*)dst, 0x3042, &state); 2801 ok(ret == 2, "wcrtomb did not return 2\n"); 2802 ok(state == 0, "state != 0\n"); 2803 ok(dst[0] == 0x82, "dst[0] = %x, expected 0x82\n", dst[0]); 2804 ok(dst[1] == 0xa0, "dst[1] = %x, expected 0xa0\n", dst[1]); 2805 ok(dst[2] == 'a', "dst[2] != 'a'\n"); 2806 2807 ret = p_wcrtomb((char*)dst, 0x3043, NULL); 2808 ok(ret == 2, "wcrtomb did not return 2\n"); 2809 ok(dst[0] == 0x82, "dst[0] = %x, expected 0x82\n", dst[0]); 2810 ok(dst[1] == 0xa1, "dst[1] = %x, expected 0xa1\n", dst[1]); 2811 2812 ret = p_wcrtomb((char*)dst, 0x20, NULL); 2813 ok(ret == 1, "wcrtomb did not return 1\n"); 2814 ok(dst[0] == 0x20, "dst[0] = %x, expected 0x20\n", dst[0]); 2815 2816 ret = p_wcrtomb((char*)dst, 0xffff, NULL); 2817 ok(ret == -1, "wcrtomb did not return -1\n"); 2818 ok(dst[0] == 0x3f, "dst[0] = %x, expected 0x3f\n", dst[0]); 2819 2820 if(!p_wcrtomb_s) { 2821 win_skip("wcrtomb_s tests\n"); 2822 setlocale(LC_ALL, "C"); 2823 return; 2824 } 2825 2826 state = 1; 2827 dst[2] = 'a'; 2828 err = p_wcrtomb_s(&ret, (char*)dst, sizeof(dst), 0x3042, &state); 2829 ok(!err, "err = %d\n", err); 2830 ok(ret == 2, "ret != 2\n"); 2831 ok(!state, "state != 0\n"); 2832 ok(dst[0] == 0x82, "dst[0] = %x, expected 0x82\n", dst[0]); 2833 ok(dst[1] == 0xa0, "dst[1] = %x, expected 0xa0\n", dst[1]); 2834 ok(dst[2] == 'a', "dst[2] != 'a'\n"); 2835 2836 err = p_wcrtomb_s(&ret, (char*)dst, sizeof(dst), 0x3042, NULL); 2837 ok(!err, "err = %d\n", err); 2838 ok(ret == 2, "ret != 2\n"); 2839 ok(!state, "state != 0\n"); 2840 ok(dst[0] == 0x82, "dst[0] = %x, expected 0x82\n", dst[0]); 2841 ok(dst[1] == 0xa0, "dst[1] = %x, expected 0xa0\n", dst[1]); 2842 2843 err = p_wcrtomb_s(&ret, (char*)dst, sizeof(dst), 0x20, NULL); 2844 ok(!err, "err = %d\n", err); 2845 ok(ret == 1, "ret != 1\n"); 2846 ok(dst[0] == 0x20, "dst[0] = %x, expected 0x20\n", dst[0]); 2847 2848 err = p_wcrtomb_s(&ret, NULL, 0, 0x20, NULL); 2849 ok(!err, "err = %d\n", err); 2850 ok(ret == 1, "ret != 1\n"); 2851 2852 err = p_wcrtomb_s(&ret, (char*)dst, sizeof(dst), 0xffff, NULL); 2853 ok(err == EILSEQ, "err = %d\n", err); 2854 ok(ret == -1, "wcrtomb did not return -1\n"); 2855 ok(dst[0] == 0x3f, "dst[0] = %x, expected 0x3f\n", dst[0]); 2856 2857 setlocale(LC_ALL, "C"); 2858 } 2859 2860 static void test_tolower(void) 2861 { 2862 WCHAR chw, lower; 2863 char ch, lch; 2864 int ret, len; 2865 2866 /* test C locale when locale was never changed */ 2867 ret = p_tolower(0x41); 2868 ok(ret == 0x61, "ret = %x\n", ret); 2869 2870 ret = p_tolower(0xF4); 2871 ok(ret == 0xF4, "ret = %x\n", ret); 2872 2873 errno = 0xdeadbeef; 2874 ret = p_tolower((char)0xF4); 2875 ok(ret == (char)0xF4, "ret = %x\n", ret); 2876 ok(errno == 0xdeadbeef, "errno = %d\n", errno); 2877 2878 errno = 0xdeadbeef; 2879 ret = p_tolower((char)0xD0); 2880 ok(ret == (char)0xD0, "ret = %x\n", ret); 2881 ok(errno == 0xdeadbeef, "errno = %d\n", errno); 2882 2883 setlocale(LC_ALL, "C"); 2884 errno = 0xdeadbeef; 2885 ret = p_tolower((char)0xF4); 2886 ok(ret == (char)0xF4, "ret = %x\n", ret); 2887 ok(errno == 0xdeadbeef, "errno = %d\n", errno); 2888 2889 /* test C locale after setting locale */ 2890 if(!setlocale(LC_ALL, "us")) { 2891 win_skip("skipping tolower tests that depends on locale\n"); 2892 return; 2893 } 2894 setlocale(LC_ALL, "C"); 2895 2896 ch = 0xF4; 2897 errno = 0xdeadbeef; 2898 ret = p_tolower(ch); 2899 if(!MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, &ch, 1, &chw, 1) || 2900 LCMapStringW(CP_ACP, LCMAP_LOWERCASE, &chw, 1, &lower, 1) != 1 || 2901 (len = WideCharToMultiByte(CP_ACP, 0, &lower, 1, &lch, 1, NULL, NULL)) != 1) 2902 len = 0; 2903 if(len) 2904 ok(ret==(unsigned char)lch || broken(ret==ch)/*WinXP-*/, "ret = %x\n", ret); 2905 else 2906 ok(ret == ch, "ret = %x\n", ret); 2907 if(!len || ret==(unsigned char)lch) 2908 ok(errno == EILSEQ, "errno = %d\n", errno); 2909 2910 ch = 0xD0; 2911 errno = 0xdeadbeef; 2912 ret = p_tolower(ch); 2913 if(!MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, &ch, 1, &chw, 1) || 2914 LCMapStringW(CP_ACP, LCMAP_LOWERCASE, &chw, 1, &lower, 1) != 1 || 2915 (len = WideCharToMultiByte(CP_ACP, 0, &lower, 1, &lch, 1, NULL, NULL)) != 1) 2916 len = 0; 2917 if(len) 2918 ok(ret==(unsigned char)lch || broken(ret==ch)/*WinXP-*/, "ret = %x\n", ret); 2919 else 2920 ok(ret == ch, "ret = %x\n", ret); 2921 if(!len || ret==(unsigned char)lch) 2922 ok(errno == EILSEQ, "errno = %d\n", errno); 2923 2924 ret = p_tolower(0xD0); 2925 ok(ret == 0xD0, "ret = %x\n", ret); 2926 2927 ok(setlocale(LC_ALL, "us") != NULL, "setlocale failed\n"); 2928 2929 ret = p_tolower((char)0xD0); 2930 ok(ret == 0xF0, "ret = %x\n", ret); 2931 2932 ret = p_tolower(0xD0); 2933 ok(ret == 0xF0, "ret = %x\n", ret); 2934 2935 setlocale(LC_ALL, "C"); 2936 } 2937 2938 static void test__atodbl(void) 2939 { 2940 _CRT_DOUBLE d; 2941 char num[32]; 2942 int ret; 2943 2944 if(!p__atodbl_l) { 2945 /* Old versions of msvcrt use different values for _OVERFLOW and _UNDERFLOW 2946 * Because of this lets skip _atodbl tests when _atodbl_l is not available */ 2947 win_skip("_atodbl_l is not available\n"); 2948 return; 2949 } 2950 2951 num[0] = 0; 2952 ret = p__atodbl_l(&d, num, NULL); 2953 ok(ret == 0, "_atodbl_l(&d, \"\", NULL) returned %d, expected 0\n", ret); 2954 ok(d.x == 0, "d.x = %lf, expected 0\n", d.x); 2955 ret = _atodbl(&d, num); 2956 ok(ret == 0, "_atodbl(&d, \"\") returned %d, expected 0\n", ret); 2957 ok(d.x == 0, "d.x = %lf, expected 0\n", d.x); 2958 2959 strcpy(num, "t"); 2960 ret = p__atodbl_l(&d, num, NULL); 2961 ok(ret == 0, "_atodbl_l(&d, \"t\", NULL) returned %d, expected 0\n", ret); 2962 ok(d.x == 0, "d.x = %lf, expected 0\n", d.x); 2963 ret = _atodbl(&d, num); 2964 ok(ret == 0, "_atodbl(&d, \"t\") returned %d, expected 0\n", ret); 2965 ok(d.x == 0, "d.x = %lf, expected 0\n", d.x); 2966 2967 strcpy(num, "0"); 2968 ret = p__atodbl_l(&d, num, NULL); 2969 ok(ret == 0, "_atodbl_l(&d, \"0\", NULL) returned %d, expected 0\n", ret); 2970 ok(d.x == 0, "d.x = %lf, expected 0\n", d.x); 2971 ret = _atodbl(&d, num); 2972 ok(ret == 0, "_atodbl(&d, \"0\") returned %d, expected 0\n", ret); 2973 ok(d.x == 0, "d.x = %lf, expected 0\n", d.x); 2974 2975 strcpy(num, "123"); 2976 ret = p__atodbl_l(&d, num, NULL); 2977 ok(ret == 0, "_atodbl_l(&d, \"123\", NULL) returned %d, expected 0\n", ret); 2978 ok(d.x == 123, "d.x = %lf, expected 123\n", d.x); 2979 ret = _atodbl(&d, num); 2980 ok(ret == 0, "_atodbl(&d, \"123\") returned %d, expected 0\n", ret); 2981 ok(d.x == 123, "d.x = %lf, expected 123\n", d.x); 2982 2983 strcpy(num, "1e-309"); 2984 ret = p__atodbl_l(&d, num, NULL); 2985 ok(ret == _UNDERFLOW, "_atodbl_l(&d, \"1e-309\", NULL) returned %d, expected _UNDERFLOW\n", ret); 2986 ok(d.x!=0 && almost_equal(d.x, 0), "d.x = %le, expected 0\n", d.x); 2987 ret = _atodbl(&d, num); 2988 ok(ret == _UNDERFLOW, "_atodbl(&d, \"1e-309\") returned %d, expected _UNDERFLOW\n", ret); 2989 ok(d.x!=0 && almost_equal(d.x, 0), "d.x = %le, expected 0\n", d.x); 2990 2991 strcpy(num, "1e309"); 2992 ret = p__atodbl_l(&d, num, NULL); 2993 ok(ret == _OVERFLOW, "_atodbl_l(&d, \"1e309\", NULL) returned %d, expected _OVERFLOW\n", ret); 2994 ret = _atodbl(&d, num); 2995 ok(ret == _OVERFLOW, "_atodbl(&d, \"1e309\") returned %d, expected _OVERFLOW\n", ret); 2996 } 2997 2998 static void test__stricmp(void) 2999 { 3000 int ret; 3001 3002 ret = _stricmp("test", "test"); 3003 ok(ret == 0, "_stricmp returned %d\n", ret); 3004 ret = _stricmp("a", "z"); 3005 ok(ret < 0, "_stricmp returned %d\n", ret); 3006 ret = _stricmp("z", "a"); 3007 ok(ret > 0, "_stricmp returned %d\n", ret); 3008 ret = _stricmp("\xa5", "\xb9"); 3009 ok(ret < 0, "_stricmp returned %d\n", ret); 3010 3011 if(!setlocale(LC_ALL, "polish")) { 3012 win_skip("stricmp tests\n"); 3013 return; 3014 } 3015 3016 ret = _stricmp("test", "test"); 3017 ok(ret == 0, "_stricmp returned %d\n", ret); 3018 ret = _stricmp("a", "z"); 3019 ok(ret < 0, "_stricmp returned %d\n", ret); 3020 ret = _stricmp("z", "a"); 3021 ok(ret > 0, "_stricmp returned %d\n", ret); 3022 ret = _stricmp("\xa5", "\xb9"); 3023 ok(ret == 0, "_stricmp returned %d\n", ret); 3024 ret = _stricmp("a", "\xb9"); 3025 ok(ret < 0, "_stricmp returned %d\n", ret); 3026 3027 setlocale(LC_ALL, "C"); 3028 } 3029 3030 static void test__wcstoi64(void) 3031 { 3032 static const WCHAR digit[] = { '9', 0 }; 3033 static const WCHAR space[] = { ' ', 0 }; 3034 static const WCHAR stock[] = { 0x3231, 0 }; /* PARENTHESIZED IDEOGRAPH STOCK */ 3035 static const WCHAR cjk_1[] = { 0x4e00, 0 }; /* CJK Ideograph, First */ 3036 static const WCHAR tamil[] = { 0x0bef, 0 }; /* TAMIL DIGIT NINE */ 3037 static const WCHAR thai[] = { 0x0e59, 0 }; /* THAI DIGIT NINE */ 3038 static const WCHAR fullwidth[] = { 0xff19, 0 }; /* FULLWIDTH DIGIT NINE */ 3039 static const WCHAR superscript1[] = { 0xb9, 0 }; /* SUPERSCRIPT ONE */ 3040 static const WCHAR minus_0x91[] = { '-', 0x0e50, 'x', 0xff19, '1', 0 }; 3041 static const WCHAR plus_071[] = { '+', 0x0e50, 0xff17, '1', 0 }; 3042 static const WCHAR hex[] = { 0xff19, 'f', 0x0e59, 0xff46, 0 }; 3043 static const WCHAR zeros[] = { 3044 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6, 3045 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10 3046 }; 3047 int i; 3048 3049 __int64 res; 3050 unsigned __int64 ures; 3051 WCHAR *endpos; 3052 3053 if (!p_wcstoi64 || !p_wcstoui64) { 3054 win_skip("_wcstoi64 or _wcstoui64 not found\n"); 3055 return; 3056 } 3057 3058 res = p_wcstoi64(digit, NULL, 10); 3059 ok(res == 9, "res != 9\n"); 3060 res = p_wcstoi64(space, &endpos, 0); 3061 ok(endpos == space, "endpos != space\n"); 3062 res = p_wcstoi64(stock, &endpos, 10); 3063 ok(res == 0, "res != 0\n"); 3064 ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos); 3065 res = p_wcstoi64(cjk_1, NULL, 0); 3066 ok(res == 0, "res != 0\n"); 3067 res = p_wcstoi64(tamil, &endpos, 10); 3068 ok(res == 0, "res != 0\n"); 3069 ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos); 3070 res = p_wcstoi64(thai, NULL, 10); 3071 ok(res == 9, "res != 9\n"); 3072 res = p_wcstoi64(fullwidth, NULL, 10); 3073 ok(res == 9, "res != 9\n"); 3074 res = p_wcstoi64(superscript1, NULL, 10); 3075 ok(res == 0, "res != 0\n"); 3076 res = p_wcstoi64(hex, NULL, 16); 3077 ok(res == 0x9f9, "res != 0x9f9\n"); 3078 res = p_wcstoi64(minus_0x91, NULL, 0); 3079 ok(res == -0x91, "res != -0x91\n"); 3080 res = p_wcstoi64(plus_071, NULL, 0); 3081 ok(res == 071, "res != 071\n"); 3082 3083 ures = p_wcstoui64(digit, NULL, 10); 3084 ok(ures == 9, "ures != 9\n"); 3085 ures = p_wcstoui64(space, &endpos, 0); 3086 ok(endpos == space, "endpos != space\n"); 3087 ures = p_wcstoui64(stock, &endpos, 10); 3088 ok(ures == 0, "ures != 0\n"); 3089 ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos); 3090 ures = p_wcstoui64(tamil, &endpos, 10); 3091 ok(ures == 0, "ures != 0\n"); 3092 ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos); 3093 ures = p_wcstoui64(thai, NULL, 10); 3094 ok(ures == 9, "ures != 9\n"); 3095 ures = p_wcstoui64(fullwidth, NULL, 10); 3096 ok(ures == 9, "ures != 9\n"); 3097 ures = p_wcstoui64(superscript1, NULL, 10); 3098 ok(ures == 0, "ures != 0\n"); 3099 ures = p_wcstoui64(hex, NULL, 16); 3100 ok(ures == 0x9f9, "ures != 0x9f9\n"); 3101 ures = p_wcstoui64(plus_071, NULL, 0); 3102 ok(ures == 071, "ures != 071\n"); 3103 3104 /* Test various unicode digits */ 3105 for (i = 0; i < ARRAY_SIZE(zeros); ++i) { 3106 WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0}; 3107 res = p_wcstoi64(tmp, NULL, 0); 3108 ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res); 3109 tmp[1] = zeros[i] + 10; 3110 res = p_wcstoi64(tmp, NULL, 16); 3111 ok(res == 4, "with zero = U+%04X: got %d, expected 4\n", zeros[i], (int)res); 3112 } 3113 3114 return; 3115 } 3116 3117 static void test_atoi(void) 3118 { 3119 int r; 3120 3121 r = atoi("0"); 3122 ok(r == 0, "atoi(0) = %d\n", r); 3123 3124 r = atoi("-1"); 3125 ok(r == -1, "atoi(-1) = %d\n", r); 3126 3127 r = atoi("1"); 3128 ok(r == 1, "atoi(1) = %d\n", r); 3129 3130 r = atoi("4294967296"); 3131 ok(r == 0, "atoi(4294967296) = %d\n", r); 3132 } 3133 3134 static void test_atol(void) 3135 { 3136 int r; 3137 3138 r = atol("0"); 3139 ok(r == 0, "atol(0) = %d\n", r); 3140 3141 r = atol("-1"); 3142 ok(r == -1, "atol(-1) = %d\n", r); 3143 3144 r = atol("1"); 3145 ok(r == 1, "atol(1) = %d\n", r); 3146 3147 r = atol("4294967296"); 3148 ok(r == 0, "atol(4294967296) = %d\n", r); 3149 } 3150 3151 static void test_atof(void) 3152 { 3153 double d; 3154 3155 d = atof("0.0"); 3156 ok(almost_equal(d, 0.0), "d = %lf\n", d); 3157 3158 d = atof("1.0"); 3159 ok(almost_equal(d, 1.0), "d = %lf\n", d); 3160 3161 d = atof("-1.0"); 3162 ok(almost_equal(d, -1.0), "d = %lf\n", d); 3163 3164 if (!p__atof_l) 3165 { 3166 win_skip("_atof_l not found\n"); 3167 return; 3168 } 3169 3170 errno = EBADF; 3171 d = atof(NULL); 3172 ok(almost_equal(d, 0.0), "d = %lf\n", d); 3173 ok(errno == EINVAL, "errno = %x\n", errno); 3174 3175 errno = EBADF; 3176 d = p__atof_l(NULL, NULL); 3177 ok(almost_equal(d, 0.0), "d = %lf\n", d); 3178 ok(errno == EINVAL, "errno = %x\n", errno); 3179 } 3180 3181 static void test_strncpy(void) 3182 { 3183 #define TEST_STRNCPY_LEN 10 3184 /* use function pointer to bypass gcc builtin */ 3185 char *(__cdecl *p_strncpy)(char*,const char*,size_t); 3186 char *ret; 3187 char dst[TEST_STRNCPY_LEN + 1]; 3188 char not_null_terminated[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; 3189 3190 p_strncpy = (void *)GetProcAddress( GetModuleHandleA("msvcrt.dll"), "strncpy"); 3191 3192 /* strlen(src) > TEST_STRNCPY_LEN */ 3193 ret = p_strncpy(dst, "01234567890123456789", TEST_STRNCPY_LEN); 3194 ok(ret == dst, "ret != dst\n"); 3195 ok(!strncmp(dst, "0123456789", TEST_STRNCPY_LEN), "dst != 0123456789\n"); 3196 3197 /* without null-terminated */ 3198 ret = p_strncpy(dst, not_null_terminated, TEST_STRNCPY_LEN); 3199 ok(ret == dst, "ret != dst\n"); 3200 ok(!strncmp(dst, "0123456789", TEST_STRNCPY_LEN), "dst != 0123456789\n"); 3201 3202 /* strlen(src) < TEST_STRNCPY_LEN */ 3203 strcpy(dst, "0123456789"); 3204 ret = p_strncpy(dst, "012345", TEST_STRNCPY_LEN); 3205 ok(ret == dst, "ret != dst\n"); 3206 ok(!strcmp(dst, "012345"), "dst != 012345\n"); 3207 ok(dst[TEST_STRNCPY_LEN - 1] == '\0', "dst[TEST_STRNCPY_LEN - 1] != 0\n"); 3208 3209 /* strlen(src) == TEST_STRNCPY_LEN */ 3210 ret = p_strncpy(dst, "0123456789", TEST_STRNCPY_LEN); 3211 ok(ret == dst, "ret != dst\n"); 3212 ok(!strncmp(dst, "0123456789", TEST_STRNCPY_LEN), "dst != 0123456789\n"); 3213 } 3214 3215 static void test_strxfrm(void) 3216 { 3217 char dest[256]; 3218 size_t ret; 3219 3220 /* crashes on old version of msvcrt */ 3221 if(p__atodbl_l) { 3222 errno = 0xdeadbeef; 3223 ret = strxfrm(NULL, "src", 1); 3224 ok(ret == INT_MAX, "ret = %d\n", (int)ret); 3225 ok(errno == EINVAL, "errno = %d\n", errno); 3226 3227 errno = 0xdeadbeef; 3228 ret = strxfrm(dest, NULL, 100); 3229 ok(ret == INT_MAX, "ret = %d\n", (int)ret); 3230 ok(errno == EINVAL, "errno = %d\n", errno); 3231 } 3232 3233 ret = strxfrm(NULL, "src", 0); 3234 ok(ret == 3, "ret = %d\n", (int)ret); 3235 dest[0] = 'a'; 3236 ret = strxfrm(dest, "src", 0); 3237 ok(ret == 3, "ret = %d\n", (int)ret); 3238 ok(dest[0] == 'a', "dest[0] = %d\n", dest[0]); 3239 3240 dest[3] = 'a'; 3241 ret = strxfrm(dest, "src", 5); 3242 ok(ret == 3, "ret = %d\n", (int)ret); 3243 ok(!strcmp(dest, "src"), "dest = %s\n", dest); 3244 3245 errno = 0xdeadbeef; 3246 dest[1] = 'a'; 3247 ret = strxfrm(dest, "src", 1); 3248 ok(ret == 3, "ret = %d\n", (int)ret); 3249 ok(dest[0] == 's', "dest[0] = %d\n", dest[0]); 3250 ok(dest[1] == 'a', "dest[1] = %d\n", dest[1]); 3251 ok(errno == 0xdeadbeef, "errno = %d\n", errno); 3252 3253 ret = strxfrm(dest, "", 5); 3254 ok(ret == 0, "ret = %d\n", (int)ret); 3255 ok(!dest[0], "dest[0] = %d\n", dest[0]); 3256 3257 if(!setlocale(LC_ALL, "polish")) { 3258 win_skip("stxfrm tests\n"); 3259 return; 3260 } 3261 3262 ret = strxfrm(NULL, "src", 0); 3263 ok(ret < sizeof(dest)-1, "ret = %d\n", (int)ret); 3264 dest[0] = 'a'; 3265 ret = strxfrm(dest, "src", 0); 3266 ok(ret < sizeof(dest)-1, "ret = %d\n", (int)ret); 3267 ok(dest[0] == 'a', "dest[0] = %d\n", dest[0]); 3268 3269 ret = strxfrm(dest, "src", ret+1); 3270 ok(ret < sizeof(dest)-1, "ret = %d\n", (int)ret); 3271 ok(dest[0], "dest[0] = 0\n"); 3272 3273 errno = 0xdeadbeef; 3274 dest[0] = 'a'; 3275 ret = strxfrm(dest, "src", 5); 3276 ok(ret>5 && ret<sizeof(dest)-1, "ret = %d\n", (int)ret); 3277 ok(!dest[0] || broken(!p__atodbl_l && dest[0]=='a'), "dest[0] = %d\n", dest[0]); 3278 3279 setlocale(LC_ALL, "C"); 3280 } 3281 3282 static void test__strnset_s(void) 3283 { 3284 char buf[5] = {0}; 3285 int r; 3286 3287 if(!p__strnset_s) { 3288 win_skip("_strnset_s not available\n"); 3289 return; 3290 } 3291 3292 r = p__strnset_s(NULL, 0, 'a', 0); 3293 ok(r == 0, "r = %d\n", r); 3294 3295 buf[0] = buf[1] = buf[2] = 'b'; 3296 r = p__strnset_s(buf, sizeof(buf), 'a', 2); 3297 ok(r == 0, "r = %d\n", r); 3298 ok(!strcmp(buf, "aab"), "buf = %s\n", buf); 3299 3300 r = p__strnset_s(buf, 0, 'a', 0); 3301 ok(r == EINVAL, "r = %d\n", r); 3302 3303 r = p__strnset_s(NULL, 0, 'a', 1); 3304 ok(r == EINVAL, "r = %d\n", r); 3305 3306 buf[3] = 'b'; 3307 r = p__strnset_s(buf, sizeof(buf)-1, 'c', 2); 3308 ok(r == EINVAL, "r = %d\n", r); 3309 ok(!buf[0] && buf[1]=='c' && buf[2]=='b', "buf = %s\n", buf); 3310 } 3311 3312 static void test__wcsnset_s(void) 3313 { 3314 wchar_t text[] = { 't','e','x','t',0 }; 3315 int r; 3316 3317 if(!p__wcsnset_s) { 3318 win_skip("_wcsnset_s not available\n"); 3319 return; 3320 } 3321 3322 r = p__wcsnset_s(NULL, 0, 'a', 0); 3323 ok(r == 0, "r = %d\n", r); 3324 3325 r = p__wcsnset_s(text, 0, 'a', 1); 3326 ok(r == EINVAL, "r = %d\n", r); 3327 ok(text[0] == 't', "text[0] = %d\n", text[0]); 3328 3329 r = p__wcsnset_s(NULL, 2, 'a', 1); 3330 ok(r == EINVAL, "r = %d\n", r); 3331 3332 r = p__wcsnset_s(text, 2, 'a', 3); 3333 ok(r == EINVAL, "r = %d\n", r); 3334 ok(text[0] == 0, "text[0] = %d\n", text[0]); 3335 ok(text[1] == 'e', "text[1] = %d\n", text[1]); 3336 3337 text[0] = 't'; 3338 r = p__wcsnset_s(text, 5, 'a', 1); 3339 ok(r == 0, "r = %d\n", r); 3340 ok(text[0] == 'a', "text[0] = %d\n", text[0]); 3341 ok(text[1] == 'e', "text[1] = %d\n", text[1]); 3342 3343 text[1] = 0; 3344 r = p__wcsnset_s(text, 5, 'b', 3); 3345 ok(r == 0, "r = %d\n", r); 3346 ok(text[0] == 'b', "text[0] = %d\n", text[0]); 3347 ok(text[1] == 0, "text[1] = %d\n", text[1]); 3348 ok(text[2] == 'x', "text[2] = %d\n", text[2]); 3349 } 3350 3351 static void test__wcsset_s(void) 3352 { 3353 wchar_t str[10]; 3354 int r; 3355 3356 if(!p__wcsset_s) { 3357 win_skip("_wcsset_s not available\n"); 3358 return; 3359 } 3360 3361 r = p__wcsset_s(NULL, 0, 'a'); 3362 ok(r == EINVAL, "r = %d\n", r); 3363 3364 str[0] = 'a'; 3365 r = p__wcsset_s(str, 0, 'a'); 3366 ok(r == EINVAL, "r = %d\n", r); 3367 ok(str[0] == 'a', "str[0] = %d\n", str[0]); 3368 3369 str[0] = 'a'; 3370 str[1] = 'b'; 3371 r = p__wcsset_s(str, 2, 'c'); 3372 ok(r == EINVAL, "r = %d\n", r); 3373 ok(!str[0], "str[0] = %d\n", str[0]); 3374 ok(str[1] == 'b', "str[1] = %d\n", str[1]); 3375 3376 str[0] = 'a'; 3377 str[1] = 0; 3378 str[2] = 'b'; 3379 r = p__wcsset_s(str, 3, 'c'); 3380 ok(r == 0, "r = %d\n", r); 3381 ok(str[0] == 'c', "str[0] = %d\n", str[0]); 3382 ok(str[1] == 0, "str[1] = %d\n", str[1]); 3383 ok(str[2] == 'b', "str[2] = %d\n", str[2]); 3384 } 3385 3386 static void test__mbscmp(void) 3387 { 3388 static const unsigned char a[] = {'a',0}, b[] = {'b',0}; 3389 int ret; 3390 3391 if (!p_mbrlen) 3392 { 3393 win_skip("_mbscmp tests\n"); 3394 return; 3395 } 3396 3397 ret = _mbscmp(NULL, NULL); 3398 ok(ret == INT_MAX, "got %d\n", ret); 3399 3400 ret = _mbscmp(a, NULL); 3401 ok(ret == INT_MAX, "got %d\n", ret); 3402 3403 ret = _mbscmp(NULL, a); 3404 ok(ret == INT_MAX, "got %d\n", ret); 3405 3406 ret = _mbscmp(a, a); 3407 ok(!ret, "got %d\n", ret); 3408 3409 ret = _mbscmp(a, b); 3410 ok(ret == -1, "got %d\n", ret); 3411 3412 ret = _mbscmp(b, a); 3413 ok(ret == 1, "got %d\n", ret); 3414 } 3415 3416 static void test__ismbclx(void) 3417 { 3418 int ret, cp = _getmbcp(); 3419 3420 ret = _ismbcl0(0); 3421 ok(!ret, "got %d\n", ret); 3422 3423 ret = _ismbcl1(0); 3424 ok(!ret, "got %d\n", ret); 3425 3426 ret = _ismbcl2(0); 3427 ok(!ret, "got %d\n", ret); 3428 3429 _setmbcp(1252); 3430 3431 ret = _ismbcl0(0x8140); 3432 ok(!ret, "got %d\n", ret); 3433 3434 ret = _ismbcl1(0x889f); 3435 ok(!ret, "got %d\n", ret); 3436 3437 ret = _ismbcl2(0x989f); 3438 ok(!ret, "got %d\n", ret); 3439 3440 _setmbcp(932); 3441 3442 ret = _ismbcl0(0); 3443 ok(!ret, "got %d\n", ret); 3444 3445 ret = _ismbcl0(0x8140); 3446 ok(ret, "got %d\n", ret); 3447 3448 ret = _ismbcl0(0x817f); 3449 ok(!ret, "got %d\n", ret); 3450 3451 ret = _ismbcl1(0); 3452 ok(!ret, "got %d\n", ret); 3453 3454 ret = _ismbcl1(0x889f); 3455 ok(ret, "got %d\n", ret); 3456 3457 ret = _ismbcl1(0x88fd); 3458 ok(!ret, "got %d\n", ret); 3459 3460 ret = _ismbcl2(0); 3461 ok(!ret, "got %d\n", ret); 3462 3463 ret = _ismbcl2(0x989f); 3464 ok(ret, "got %d\n", ret); 3465 3466 ret = _ismbcl2(0x993f); 3467 ok(!ret, "got %d\n", ret); 3468 3469 _setmbcp(cp); 3470 } 3471 3472 static void test__memicmp(void) 3473 { 3474 static const char *s1 = "abc"; 3475 static const char *s2 = "aBd"; 3476 int ret; 3477 3478 ret = p__memicmp(NULL, NULL, 0); 3479 ok(!ret, "got %d\n", ret); 3480 3481 ret = p__memicmp(s1, s2, 2); 3482 ok(!ret, "got %d\n", ret); 3483 3484 ret = p__memicmp(s1, s2, 3); 3485 ok(ret == -1, "got %d\n", ret); 3486 3487 if (!p__memicmp_l) 3488 return; 3489 3490 /* Following calls crash on WinXP/W2k3. */ 3491 errno = 0xdeadbeef; 3492 ret = p__memicmp(NULL, NULL, 1); 3493 ok(ret == _NLSCMPERROR, "got %d\n", ret); 3494 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 3495 3496 errno = 0xdeadbeef; 3497 ret = p__memicmp(s1, NULL, 1); 3498 ok(ret == _NLSCMPERROR, "got %d\n", ret); 3499 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 3500 3501 errno = 0xdeadbeef; 3502 ret = p__memicmp(NULL, s2, 1); 3503 ok(ret == _NLSCMPERROR, "got %d\n", ret); 3504 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 3505 } 3506 3507 static void test__memicmp_l(void) 3508 { 3509 static const char *s1 = "abc"; 3510 static const char *s2 = "aBd"; 3511 int ret; 3512 3513 if (!p__memicmp_l) 3514 { 3515 win_skip("_memicmp_l not found.\n"); 3516 return; 3517 } 3518 3519 errno = 0xdeadbeef; 3520 ret = p__memicmp_l(NULL, NULL, 0, NULL); 3521 ok(!ret, "got %d\n", ret); 3522 ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); 3523 3524 errno = 0xdeadbeef; 3525 ret = p__memicmp_l(NULL, NULL, 1, NULL); 3526 ok(ret == _NLSCMPERROR, "got %d\n", ret); 3527 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 3528 3529 errno = 0xdeadbeef; 3530 ret = p__memicmp_l(s1, NULL, 1, NULL); 3531 ok(ret == _NLSCMPERROR, "got %d\n", ret); 3532 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 3533 3534 errno = 0xdeadbeef; 3535 ret = p__memicmp_l(NULL, s2, 1, NULL); 3536 ok(ret == _NLSCMPERROR, "got %d\n", ret); 3537 ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); 3538 3539 errno = 0xdeadbeef; 3540 ret = p__memicmp_l(s1, s2, 2, NULL); 3541 ok(!ret, "got %d\n", ret); 3542 ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); 3543 3544 errno = 0xdeadbeef; 3545 ret = p__memicmp_l(s1, s2, 3, NULL); 3546 ok(ret == -1, "got %d\n", ret); 3547 ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); 3548 } 3549 3550 static void test__strupr(void) 3551 { 3552 const char str[] = "123"; 3553 char str2[4]; 3554 char *mem, *p; 3555 DWORD prot; 3556 3557 mem = VirtualAlloc(NULL, sizeof(str), MEM_COMMIT, PAGE_READWRITE); 3558 ok(mem != NULL, "VirtualAlloc failed\n"); 3559 memcpy(mem, str, sizeof(str)); 3560 ok(VirtualProtect(mem, sizeof(str), PAGE_READONLY, &prot), "VirtualProtect failed\n"); 3561 3562 strcpy(str2, "aBc"); 3563 p = _strupr(str2); 3564 ok(p == str2, "_strupr returned %p\n", p); 3565 ok(!strcmp(str2, "ABC"), "str2 = %s\n", str2); 3566 3567 p = _strupr(mem); 3568 ok(p == mem, "_strupr returned %p\n", p); 3569 ok(!strcmp(mem, "123"), "mem = %s\n", mem); 3570 3571 if(!setlocale(LC_ALL, "english")) { 3572 VirtualFree(mem, sizeof(str), MEM_RELEASE); 3573 win_skip("English locale _strupr tests\n"); 3574 return; 3575 } 3576 3577 strcpy(str2, "aBc"); 3578 p = _strupr(str2); 3579 ok(p == str2, "_strupr returned %p\n", p); 3580 ok(!strcmp(str2, "ABC"), "str2 = %s\n", str2); 3581 3582 if (0) /* crashes on Windows */ 3583 { 3584 p = _strupr(mem); 3585 ok(p == mem, "_strupr returned %p\n", p); 3586 ok(!strcmp(mem, "123"), "mem = %s\n", mem); 3587 } 3588 3589 setlocale(LC_ALL, "C"); 3590 VirtualFree(mem, sizeof(str), MEM_RELEASE); 3591 } 3592 3593 static void test__tcsncoll(void) 3594 { 3595 struct test { 3596 const char *locale; 3597 const char *str1; 3598 const char *str2; 3599 size_t count; 3600 int exp; 3601 }; 3602 static const struct test tests[] = { 3603 { "English", "ABCD", "ABCD", 4, 0 }, 3604 { "English", "ABCD", "ABCD", 10, 0 }, 3605 3606 { "English", "ABC", "ABCD", 3, 0 }, 3607 { "English", "ABC", "ABCD", 4, -1 }, 3608 { "English", "ABC", "ABCD", 10, -1 }, 3609 3610 { "English", "ABCD", "ABC", 3, 0 }, 3611 { "English", "ABCD", "ABC", 4, 1 }, 3612 { "English", "ABCD", "ABC", 10, 1 }, 3613 3614 { "English", "ABCe", "ABCf", 3, 0 }, 3615 { "English", "abcd", "ABCD", 10, -1 }, 3616 3617 { "C", "ABCD", "ABCD", 4, 0 }, 3618 { "C", "ABCD", "ABCD", 10, 0 }, 3619 3620 { "C", "ABC", "ABCD", 3, 0 }, 3621 { "C", "ABC", "ABCD", 10, -1 }, 3622 3623 { "C", "ABCD", "ABC", 3, 0 }, 3624 { "C", "ABCD", "ABC", 10, 1 }, 3625 3626 { "C", "ABCe", "ABCf", 3, 0 }, 3627 { "C", "abcd", "ABCD", 10, 1 }, 3628 }; 3629 WCHAR str1W[16]; 3630 WCHAR str2W[16]; 3631 char str1[16]; 3632 char str2[16]; 3633 size_t len; 3634 int i, ret; 3635 3636 for (i = 0; i < ARRAY_SIZE(tests); i++) 3637 { 3638 if (!setlocale(LC_ALL, tests[i].locale)) 3639 { 3640 win_skip("%s locale _tcsncoll tests\n", tests[i].locale); 3641 for (; i+1 < ARRAY_SIZE(tests); i++) 3642 if (strcmp(tests[i].locale, tests[i+1].locale)) break; 3643 continue; 3644 } 3645 3646 memset(str1, 0xee, sizeof(str1)); 3647 strcpy(str1, tests[i].str1); 3648 3649 memset(str2, 0xff, sizeof(str2)); 3650 strcpy(str2, tests[i].str2); 3651 3652 ret = _strncoll(str1, str2, tests[i].count); 3653 if (!tests[i].exp) 3654 ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3655 else if (tests[i].exp < 0) 3656 ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3657 else 3658 ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3659 3660 memset(str1W, 0xee, sizeof(str1W)); 3661 len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); 3662 str1W[len] = 0; 3663 3664 memset(str2W, 0xff, sizeof(str2W)); 3665 len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W)); 3666 str2W[len] = 0; 3667 3668 ret = _wcsncoll(str1W, str2W, tests[i].count); 3669 if (!tests[i].exp) 3670 ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3671 else if (tests[i].exp < 0) 3672 ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3673 else 3674 ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3675 } 3676 } 3677 3678 static void test__tcsnicoll(void) 3679 { 3680 struct test { 3681 const char *locale; 3682 const char *str1; 3683 const char *str2; 3684 size_t count; 3685 int exp; 3686 }; 3687 static const struct test tests[] = { 3688 { "English", "abcd", "ABCD", 4, 0 }, 3689 { "English", "abcd", "ABCD", 10, 0 }, 3690 3691 { "English", "abc", "ABCD", 3, 0 }, 3692 { "English", "abc", "ABCD", 4, -1 }, 3693 { "English", "abc", "ABCD", 10, -1 }, 3694 3695 { "English", "abcd", "ABC", 3, 0 }, 3696 { "English", "abcd", "ABC", 4, 1 }, 3697 { "English", "abcd", "ABC", 10, 1 }, 3698 3699 { "English", "abcE", "ABCF", 3, 0 }, 3700 3701 { "C", "abcd", "ABCD", 4, 0 }, 3702 { "C", "abcd", "ABCD", 10, 0 }, 3703 3704 { "C", "abc", "ABCD", 3, 0 }, 3705 { "C", "abc", "ABCD", 10, -1 }, 3706 3707 { "C", "abcd", "ABC", 3, 0 }, 3708 { "C", "abcd", "ABC", 10, 1 }, 3709 3710 { "C", "abce", "ABCf", 3, 0 }, 3711 }; 3712 WCHAR str1W[16]; 3713 WCHAR str2W[16]; 3714 char str1[16]; 3715 char str2[16]; 3716 size_t len; 3717 int i, ret; 3718 3719 for (i = 0; i < ARRAY_SIZE(tests); i++) 3720 { 3721 if (!setlocale(LC_ALL, tests[i].locale)) 3722 { 3723 win_skip("%s locale _tcsnicoll tests\n", tests[i].locale); 3724 for (; i+1 < ARRAY_SIZE(tests); i++) 3725 if (strcmp(tests[i].locale, tests[i+1].locale)) break; 3726 continue; 3727 } 3728 3729 memset(str1, 0xee, sizeof(str1)); 3730 strcpy(str1, tests[i].str1); 3731 3732 memset(str2, 0xff, sizeof(str2)); 3733 strcpy(str2, tests[i].str2); 3734 3735 ret = _strnicoll(str1, str2, tests[i].count); 3736 if (!tests[i].exp) 3737 ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3738 else if (tests[i].exp < 0) 3739 ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3740 else 3741 ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3742 3743 memset(str1W, 0xee, sizeof(str1W)); 3744 len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); 3745 str1W[len] = 0; 3746 3747 memset(str2W, 0xff, sizeof(str2W)); 3748 len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W)); 3749 str2W[len] = 0; 3750 3751 ret = _wcsnicoll(str1W, str2W, tests[i].count); 3752 if (!tests[i].exp) 3753 ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3754 else if (tests[i].exp < 0) 3755 ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3756 else 3757 ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); 3758 } 3759 } 3760 3761 static void test___strncnt(void) 3762 { 3763 static const struct 3764 { 3765 const char *str; 3766 size_t size; 3767 size_t ret; 3768 } 3769 strncnt_tests[] = 3770 { 3771 { NULL, 0, 0 }, 3772 { "a", 0, 0 }, 3773 { "a", 1, 1 }, 3774 { "a", 10, 1 }, 3775 { "abc", 1, 1 }, 3776 }; 3777 unsigned int i; 3778 size_t ret; 3779 3780 if (!p___strncnt) 3781 { 3782 win_skip("__strncnt() is not available.\n"); 3783 return; 3784 } 3785 3786 if (0) /* crashes */ 3787 ret = p___strncnt(NULL, 1); 3788 3789 for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i) 3790 { 3791 ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size); 3792 ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret); 3793 } 3794 } 3795 3796 static void test_C_locale(void) 3797 { 3798 int i, j; 3799 wint_t ret, exp; 3800 _locale_t locale; 3801 static const char *locales[] = { NULL, "C" }; 3802 3803 /* C locale only converts case for [a-zA-Z] */ 3804 setlocale(LC_ALL, "C"); 3805 for (i = 0; i <= 0xffff; i++) 3806 { 3807 ret = p_towlower(i); 3808 if (i >= 'A' && i <= 'Z') 3809 { 3810 exp = i + 'a' - 'A'; 3811 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 3812 } 3813 else 3814 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 3815 3816 ret = p_towupper(i); 3817 if (i >= 'a' && i <= 'z') 3818 { 3819 exp = i + 'A' - 'a'; 3820 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 3821 } 3822 else 3823 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); 3824 } 3825 3826 if (!p__towlower_l || !p__towupper_l || !p__create_locale) 3827 { 3828 win_skip("_towlower_l/_towupper_l/_create_locale not available\n"); 3829 return; 3830 } 3831 3832 for (i = 0; i < ARRAY_SIZE(locales); i++) { 3833 locale = locales[i] ? p__create_locale(LC_ALL, locales[i]) : NULL; 3834 3835 for (j = 0; j <= 0xffff; j++) { 3836 ret = p__towlower_l(j, locale); 3837 if (j >= 'A' && j <= 'Z') 3838 { 3839 exp = j + 'a' - 'A'; 3840 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 3841 } 3842 else 3843 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); 3844 3845 ret = p__towupper_l(j, locale); 3846 if (j >= 'a' && j <= 'z') 3847 { 3848 exp = j + 'A' - 'a'; 3849 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); 3850 } 3851 else 3852 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); 3853 } 3854 3855 p__free_locale(locale); 3856 } 3857 } 3858 3859 START_TEST(string) 3860 { 3861 char mem[100]; 3862 static const char xilstring[]="c:/xilinx"; 3863 int nLen; 3864 3865 hMsvcrt = GetModuleHandleA("msvcrt.dll"); 3866 if (!hMsvcrt) 3867 hMsvcrt = GetModuleHandleA("msvcrtd.dll"); 3868 ok(hMsvcrt != 0, "GetModuleHandleA failed\n"); 3869 SET(pmemcpy,"memcpy"); 3870 p_memcpy_s = (void*)GetProcAddress( hMsvcrt, "memcpy_s" ); 3871 p_memmove_s = (void*)GetProcAddress( hMsvcrt, "memmove_s" ); 3872 SET(pmemcmp,"memcmp"); 3873 SET(p_mbctype,"_mbctype"); 3874 SET(p__mb_cur_max,"__mb_cur_max"); 3875 SET(p_strcpy, "strcpy"); 3876 pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" ); 3877 pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" ); 3878 p_mbscat_s = (void*)GetProcAddress( hMsvcrt, "_mbscat_s" ); 3879 p_mbsnbcat_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcat_s" ); 3880 p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" ); 3881 p__mbscpy_s = (void *)GetProcAddress( hMsvcrt,"_mbscpy_s" ); 3882 p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" ); 3883 p_wcsncpy_s = (void *)GetProcAddress( hMsvcrt,"wcsncpy_s" ); 3884 p_wcsncat_s = (void *)GetProcAddress( hMsvcrt,"wcsncat_s" ); 3885 p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" ); 3886 p_strnlen = (void *)GetProcAddress( hMsvcrt,"strnlen" ); 3887 p_strtoi64 = (void *)GetProcAddress(hMsvcrt, "_strtoi64"); 3888 p_strtoui64 = (void *)GetProcAddress(hMsvcrt, "_strtoui64"); 3889 p_wcstoi64 = (void *)GetProcAddress(hMsvcrt, "_wcstoi64"); 3890 p_wcstoui64 = (void *)GetProcAddress(hMsvcrt, "_wcstoui64"); 3891 pmbstowcs_s = (void *)GetProcAddress(hMsvcrt, "mbstowcs_s"); 3892 pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s"); 3893 pwcsrtombs = (void *)GetProcAddress(hMsvcrt, "wcsrtombs"); 3894 p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s"); 3895 p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s"); 3896 p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s"); 3897 p_ultoa_s = (void *)GetProcAddress(hMsvcrt, "_ultoa_s"); 3898 p_wcslwr_s = (void*)GetProcAddress(hMsvcrt, "_wcslwr_s"); 3899 p_mbsupr_s = (void*)GetProcAddress(hMsvcrt, "_mbsupr_s"); 3900 p_mbslwr_s = (void*)GetProcAddress(hMsvcrt, "_mbslwr_s"); 3901 p_wctob = (void*)GetProcAddress(hMsvcrt, "wctob"); 3902 p_wcrtomb = (void*)GetProcAddress(hMsvcrt, "wcrtomb"); 3903 p_wcrtomb_s = (void*)GetProcAddress(hMsvcrt, "wcrtomb_s"); 3904 p_tolower = (void*)GetProcAddress(hMsvcrt, "tolower"); 3905 p_towlower = (void*)GetProcAddress(hMsvcrt, "towlower"); 3906 p__towlower_l = (void*)GetProcAddress(hMsvcrt, "_towlower_l"); 3907 p_towupper = (void*)GetProcAddress(hMsvcrt, "towupper"); 3908 p__towupper_l = (void*)GetProcAddress(hMsvcrt, "_towupper_l"); 3909 p__create_locale = (void*)GetProcAddress(hMsvcrt, "_create_locale"); 3910 p__free_locale = (void*)GetProcAddress(hMsvcrt, "_free_locale"); 3911 p_mbrlen = (void*)GetProcAddress(hMsvcrt, "mbrlen"); 3912 p_mbrtowc = (void*)GetProcAddress(hMsvcrt, "mbrtowc"); 3913 p_mbsrtowcs = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs"); 3914 p_mbsrtowcs_s = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs_s"); 3915 p__atodbl_l = (void*)GetProcAddress(hMsvcrt, "_atodbl_l"); 3916 p__atof_l = (void*)GetProcAddress(hMsvcrt, "_atof_l"); 3917 p__strtod_l = (void*)GetProcAddress(hMsvcrt, "_strtod_l"); 3918 p__strnset_s = (void*)GetProcAddress(hMsvcrt, "_strnset_s"); 3919 p__wcsnset_s = (void*)GetProcAddress(hMsvcrt, "_wcsnset_s"); 3920 p__wcsset_s = (void*)GetProcAddress(hMsvcrt, "_wcsset_s"); 3921 p__mbsnlen = (void*)GetProcAddress(hMsvcrt, "_mbsnlen"); 3922 p__mbccpy_s = (void*)GetProcAddress(hMsvcrt, "_mbccpy_s"); 3923 p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp"); 3924 p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l"); 3925 p___strncnt = (void*)GetProcAddress(hMsvcrt, "__strncnt"); 3926 3927 /* MSVCRT memcpy behaves like memmove for overlapping moves, 3928 MFC42 CString::Insert seems to rely on that behaviour */ 3929 strcpy(mem,xilstring); 3930 nLen=strlen(xilstring); 3931 pmemcpy(mem+5, mem,nLen+1); 3932 ok(pmemcmp(mem+5,xilstring, nLen) == 0, 3933 "Got result %s\n",mem+5); 3934 3935 /* run tolower tests first */ 3936 test_tolower(); 3937 test_swab(); 3938 test_mbcp(); 3939 test_mbsspn(); 3940 test_mbsspnp(); 3941 test_strdup(); 3942 test_strcpy_s(); 3943 test_memcpy_s(); 3944 test_memmove_s(); 3945 test_strcat_s(); 3946 test__mbscat_s(); 3947 test__mbsnbcpy_s(); 3948 test__mbscpy_s(); 3949 test_mbcjisjms(); 3950 test_mbcjmsjis(); 3951 test_mbctohira(); 3952 test_mbctokata(); 3953 test_mbbtombc(); 3954 test_mbctombb(); 3955 test_ismbckata(); 3956 test_ismbclegal(); 3957 test_strtok(); 3958 test__mbstok(); 3959 test_wcscpy_s(); 3960 test__wcsupr_s(); 3961 test_strtol(); 3962 test_strnlen(); 3963 test__strtoi64(); 3964 test__strtod(); 3965 test_mbstowcs(); 3966 test_gcvt(); 3967 test__itoa_s(); 3968 test__strlwr_s(); 3969 test_wcsncat_s(); 3970 test__mbsnbcat_s(); 3971 test__ultoa_s(); 3972 test__wcslwr_s(); 3973 test__mbsupr_s(); 3974 test__mbslwr_s(); 3975 test_wctob(); 3976 test_wctomb(); 3977 test__atodbl(); 3978 test__stricmp(); 3979 test__wcstoi64(); 3980 test_atoi(); 3981 test_atol(); 3982 test_atof(); 3983 test_strncpy(); 3984 test_strxfrm(); 3985 test__strnset_s(); 3986 test__wcsnset_s(); 3987 test__wcsset_s(); 3988 test__mbscmp(); 3989 test__ismbclx(); 3990 test__memicmp(); 3991 test__memicmp_l(); 3992 test__strupr(); 3993 test__tcsncoll(); 3994 test__tcsnicoll(); 3995 test___strncnt(); 3996 test_C_locale(); 3997 } 3998