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