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