2 * Unit test suite for string functions.
4 * Copyright 2004 Uwe Bonnes
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.
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.
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
21 #include "wine/test.h"
32 static char *buf_to_string(const unsigned char *bin
, int len
, int nr
)
34 static char buf
[2][1024];
38 for (i
= 0; i
< len
; i
++)
40 sprintf(w
, "%02x ", (unsigned char)bin
[i
]);
46 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
47 #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)); }
49 static void* (__cdecl
*pmemcpy
)(void *, const void *, size_t n
);
50 static int* (__cdecl
*pmemcmp
)(void *, const void *, size_t n
);
51 static int (__cdecl
*pstrcpy_s
)(char *dst
, size_t len
, const char *src
);
52 static int (__cdecl
*pstrcat_s
)(char *dst
, size_t len
, const char *src
);
53 static int (__cdecl
*p_mbsnbcpy_s
)(unsigned char * dst
, size_t size
, const unsigned char * src
, size_t count
);
54 static int (__cdecl
*p_wcscpy_s
)(wchar_t *wcDest
, size_t size
, const wchar_t *wcSrc
);
55 static int (__cdecl
*p_wcsupr_s
)(wchar_t *str
, size_t size
);
56 static size_t (__cdecl
*p_strnlen
)(const char *, size_t);
57 static __int64 (__cdecl
*p_strtoi64
)(const char *, char **, int);
58 static unsigned __int64 (__cdecl
*p_strtoui64
)(const char *, char **, int);
59 static int (__cdecl
*pwcstombs_s
)(size_t*,char*,size_t,const wchar_t*,size_t);
60 static int (__cdecl
*pmbstowcs_s
)(size_t*,wchar_t*,size_t,const char*,size_t);
61 static int *p__mb_cur_max
;
62 static unsigned char *p_mbctype
;
64 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
65 #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
69 static void test_swab( void ) {
70 char original
[] = "BADCFEHGJILKNMPORQTSVUXWZY@#";
71 char expected1
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#";
72 char expected2
[] = "ABCDEFGHIJKLMNOPQRSTUVWX$";
73 char expected3
[] = "$";
80 /* Test 1 - normal even case */
81 memset(to
,'$', sizeof(to
));
82 memset(from
,'@', sizeof(from
));
84 memcpy(from
, original
, testsize
);
85 _swab( from
, to
, testsize
);
86 ok(memcmp(to
,expected1
,testsize
) == 0, "Testing even size %d returned '%*.*s'\n", testsize
, testsize
, testsize
, to
);
88 /* Test 2 - uneven case */
89 memset(to
,'$', sizeof(to
));
90 memset(from
,'@', sizeof(from
));
92 memcpy(from
, original
, testsize
);
93 _swab( from
, to
, testsize
);
94 ok(memcmp(to
,expected2
,testsize
) == 0, "Testing odd size %d returned '%*.*s'\n", testsize
, testsize
, testsize
, to
);
96 /* Test 3 - from = to */
97 memset(to
,'$', sizeof(to
));
98 memset(from
,'@', sizeof(from
));
100 memcpy(to
, original
, testsize
);
101 _swab( to
, to
, testsize
);
102 ok(memcmp(to
,expected1
,testsize
) == 0, "Testing overlapped size %d returned '%*.*s'\n", testsize
, testsize
, testsize
, to
);
104 /* Test 4 - 1 bytes */
105 memset(to
,'$', sizeof(to
));
106 memset(from
,'@', sizeof(from
));
108 memcpy(from
, original
, testsize
);
109 _swab( from
, to
, testsize
);
110 ok(memcmp(to
,expected3
,testsize
) == 0, "Testing small size %d returned '%*.*s'\n", testsize
, testsize
, testsize
, to
);
113 #if 0 /* use this to generate more tests */
115 static void test_codepage(int cp
)
121 ok(_setmbcp(cp
) == 0, "Couldn't set mbcp\n");
124 printf("static int result_cp_%d_mbctype[] = { ", cp
);
125 for (i
= 1; i
< 257; i
++)
127 if (p_mbctype
[i
] != prev
)
129 printf("0x%x,%d, ", prev
, count
);
136 printf("0x%x,%d };\n", prev
, count
);
141 /* RLE-encoded mbctype tables for given codepages */
142 static int result_cp_932_mbctype
[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
143 0x0,1, 0x8,1, 0xc,31, 0x8,1, 0xa,5, 0x9,58, 0xc,29, 0,3 };
144 static int result_cp_936_mbctype
[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,6,
146 static int result_cp_949_mbctype
[] = { 0x0,66, 0x18,26, 0x8,6, 0x28,26, 0x8,6, 0xc,126,
148 static int result_cp_950_mbctype
[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
149 0x0,2, 0x4,32, 0xc,94, 0,1 };
151 static void test_cp_table(int cp
, int *result
)
157 for (i
= 0; i
< 256; i
++)
165 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
);
170 #define test_codepage(num) test_cp_table(num, result_cp_##num##_mbctype);
174 static void test_mbcp(void)
176 int mb_orig_max
= *p__mb_cur_max
;
177 int curr_mbcp
= _getmbcp();
178 unsigned char *mbstring
= (unsigned char *)"\xb0\xb1\xb2 \xb3\xb4 \xb5"; /* incorrect string */
179 unsigned char *mbstring2
= (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5"; /* correct string */
180 unsigned char *mbsonlylead
= (unsigned char *)"\xb0\0\xb1\xb2 \xb3";
181 unsigned char buf
[16];
186 /* An SBCS codepage test. The ctype of characters on e.g. CP1252 or CP1250 differs slightly
187 * between versions of Windows. Also Windows 9x seems to ignore the codepage and always uses
188 * CP1252 (or the ACP?) so we test only a few ASCII characters */
190 expect_eq(p_mbctype
[10], 0, char, "%x");
191 expect_eq(p_mbctype
[50], 0, char, "%x");
192 expect_eq(p_mbctype
[66], _SBUP
, char, "%x");
193 expect_eq(p_mbctype
[100], _SBLOW
, char, "%x");
194 expect_eq(p_mbctype
[128], 0, char, "%x");
196 expect_eq(p_mbctype
[10], 0, char, "%x");
197 expect_eq(p_mbctype
[50], 0, char, "%x");
198 expect_eq(p_mbctype
[66], _SBUP
, char, "%x");
199 expect_eq(p_mbctype
[100], _SBLOW
, char, "%x");
200 expect_eq(p_mbctype
[128], 0, char, "%x");
202 /* double byte code pages */
209 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
);
210 ok(_ismbblead('\354'), "\354 should be a lead byte\n");
211 ok(_ismbblead(' ') == FALSE
, "' ' should not be a lead byte\n");
212 ok(_ismbblead(0x1234b0), "0x1234b0 should not be a lead byte\n");
213 ok(_ismbblead(0x123420) == FALSE
, "0x123420 should not be a lead byte\n");
214 ok(_ismbbtrail('\xb0'), "\xa0 should be a trail byte\n");
215 ok(_ismbbtrail(' ') == FALSE
, "' ' should not be a trail byte\n");
218 expect_eq(_ismbslead(mbstring
, &mbstring
[0]), -1, int, "%d");
219 expect_eq(_ismbslead(mbstring
, &mbstring
[1]), FALSE
, int, "%d");
220 expect_eq(_ismbslead(mbstring
, &mbstring
[2]), -1, int, "%d");
221 expect_eq(_ismbslead(mbstring
, &mbstring
[3]), FALSE
, int, "%d");
222 expect_eq(_ismbslead(mbstring
, &mbstring
[4]), -1, int, "%d");
223 expect_eq(_ismbslead(mbstring
, &mbstring
[5]), FALSE
, int, "%d");
224 expect_eq(_ismbslead(mbstring
, &mbstring
[6]), FALSE
, int, "%d");
225 expect_eq(_ismbslead(mbstring
, &mbstring
[7]), -1, int, "%d");
226 expect_eq(_ismbslead(mbstring
, &mbstring
[8]), FALSE
, int, "%d");
228 expect_eq(_ismbslead(mbsonlylead
, &mbsonlylead
[0]), -1, int, "%d");
229 expect_eq(_ismbslead(mbsonlylead
, &mbsonlylead
[1]), FALSE
, int, "%d");
230 expect_eq(_ismbslead(mbsonlylead
, &mbsonlylead
[2]), FALSE
, int, "%d");
231 expect_eq(_ismbslead(mbsonlylead
, &mbsonlylead
[5]), FALSE
, int, "%d");
234 expect_eq(_ismbstrail(mbstring
, &mbstring
[0]), FALSE
, int, "%d");
235 expect_eq(_ismbstrail(mbstring
, &mbstring
[1]), -1, int, "%d");
236 expect_eq(_ismbstrail(mbstring
, &mbstring
[2]), FALSE
, int, "%d");
237 expect_eq(_ismbstrail(mbstring
, &mbstring
[3]), -1, int, "%d");
238 expect_eq(_ismbstrail(mbstring
, &mbstring
[4]), FALSE
, int, "%d");
239 expect_eq(_ismbstrail(mbstring
, &mbstring
[5]), -1, int, "%d");
240 expect_eq(_ismbstrail(mbstring
, &mbstring
[6]), FALSE
, int, "%d");
241 expect_eq(_ismbstrail(mbstring
, &mbstring
[7]), FALSE
, int, "%d");
242 expect_eq(_ismbstrail(mbstring
, &mbstring
[8]), -1, int, "%d");
244 expect_eq(_ismbstrail(mbsonlylead
, &mbsonlylead
[0]), FALSE
, int, "%d");
245 expect_eq(_ismbstrail(mbsonlylead
, &mbsonlylead
[1]), -1, int, "%d");
246 expect_eq(_ismbstrail(mbsonlylead
, &mbsonlylead
[2]), FALSE
, int, "%d");
247 expect_eq(_ismbstrail(mbsonlylead
, &mbsonlylead
[3]), FALSE
, int, "%d");
248 expect_eq(_ismbstrail(mbsonlylead
, &mbsonlylead
[4]), FALSE
, int, "%d");
249 expect_eq(_ismbstrail(mbsonlylead
, &mbsonlylead
[5]), FALSE
, int, "%d");
252 expect_eq(_mbsbtype(mbstring
, 0), _MBC_LEAD
, int, "%d");
253 expect_eq(_mbsbtype(mbstring
, 1), _MBC_TRAIL
, int, "%d");
254 expect_eq(_mbsbtype(mbstring
, 2), _MBC_LEAD
, int, "%d");
255 expect_eq(_mbsbtype(mbstring
, 3), _MBC_ILLEGAL
, int, "%d");
256 expect_eq(_mbsbtype(mbstring
, 4), _MBC_LEAD
, int, "%d");
257 expect_eq(_mbsbtype(mbstring
, 5), _MBC_TRAIL
, int, "%d");
258 expect_eq(_mbsbtype(mbstring
, 6), _MBC_SINGLE
, int, "%d");
259 expect_eq(_mbsbtype(mbstring
, 7), _MBC_LEAD
, int, "%d");
260 expect_eq(_mbsbtype(mbstring
, 8), _MBC_ILLEGAL
, int, "%d");
262 expect_eq(_mbsbtype(mbsonlylead
, 0), _MBC_LEAD
, int, "%d");
263 expect_eq(_mbsbtype(mbsonlylead
, 1), _MBC_ILLEGAL
, int, "%d");
264 expect_eq(_mbsbtype(mbsonlylead
, 2), _MBC_ILLEGAL
, int, "%d");
265 expect_eq(_mbsbtype(mbsonlylead
, 3), _MBC_ILLEGAL
, int, "%d");
266 expect_eq(_mbsbtype(mbsonlylead
, 4), _MBC_ILLEGAL
, int, "%d");
267 expect_eq(_mbsbtype(mbsonlylead
, 5), _MBC_ILLEGAL
, int, "%d");
270 expect_eq(_mbsnextc(mbstring
), 0xb0b1, int, "%x");
271 expect_eq(_mbsnextc(&mbstring
[2]), 0xb220, int, "%x"); /* lead + invalid tail */
272 expect_eq(_mbsnextc(&mbstring
[3]), 0x20, int, "%x"); /* single char */
274 /* _mbclen/_mbslen */
275 expect_eq(_mbclen(mbstring
), 2, int, "%d");
276 expect_eq(_mbclen(&mbstring
[2]), 2, int, "%d");
277 expect_eq(_mbclen(&mbstring
[3]), 1, int, "%d");
278 expect_eq(_mbslen(mbstring2
), 4, int, "%d");
279 expect_eq(_mbslen(mbsonlylead
), 0, int, "%d"); /* lead + NUL not counted as character */
280 expect_eq(_mbslen(mbstring
), 4, int, "%d"); /* lead + invalid trail counted */
282 /* _mbccpy/_mbsncpy */
283 memset(buf
, 0xff, sizeof(buf
));
284 _mbccpy(buf
, mbstring
);
285 expect_bin(buf
, "\xb0\xb1\xff", 3);
287 memset(buf
, 0xff, sizeof(buf
));
288 _mbsncpy(buf
, mbstring
, 1);
289 expect_bin(buf
, "\xb0\xb1\xff", 3);
290 memset(buf
, 0xff, sizeof(buf
));
291 _mbsncpy(buf
, mbstring
, 2);
292 expect_bin(buf
, "\xb0\xb1\xb2 \xff", 5);
293 memset(buf
, 0xff, sizeof(buf
));
294 _mbsncpy(buf
, mbstring
, 3);
295 expect_bin(buf
, "\xb0\xb1\xb2 \xb3\xb4\xff", 7);
296 memset(buf
, 0xff, sizeof(buf
));
297 _mbsncpy(buf
, mbstring
, 4);
298 expect_bin(buf
, "\xb0\xb1\xb2 \xb3\xb4 \xff", 8);
299 memset(buf
, 0xff, sizeof(buf
));
300 _mbsncpy(buf
, mbstring
, 5);
301 expect_bin(buf
, "\xb0\xb1\xb2 \xb3\xb4 \0\0\xff", 10);
302 memset(buf
, 0xff, sizeof(buf
));
303 _mbsncpy(buf
, mbsonlylead
, 6);
304 expect_bin(buf
, "\0\0\0\0\0\0\0\xff", 8);
306 memset(buf
, 0xff, sizeof(buf
));
307 _mbsnbcpy(buf
, mbstring2
, 2);
308 expect_bin(buf
, "\xb0\xb1\xff", 3);
309 _mbsnbcpy(buf
, mbstring2
, 3);
310 expect_bin(buf
, "\xb0\xb1\0\xff", 4);
311 _mbsnbcpy(buf
, mbstring2
, 4);
312 expect_bin(buf
, "\xb0\xb1\xb2\xb3\xff", 5);
313 memset(buf
, 0xff, sizeof(buf
));
314 _mbsnbcpy(buf
, mbsonlylead
, 5);
315 expect_bin(buf
, "\0\0\0\0\0\xff", 6);
318 step
= _mbsinc(mbstring
) - mbstring
;
319 ok(step
== 2, "_mbsinc adds %d (exp. 2)\n", step
);
320 step
= _mbsinc(&mbstring
[2]) - &mbstring
[2]; /* lead + invalid tail */
321 ok(step
== 2, "_mbsinc adds %d (exp. 2)\n", step
);
323 step
= _mbsninc(mbsonlylead
, 1) - mbsonlylead
;
324 ok(step
== 0, "_mbsninc adds %d (exp. 0)\n", step
);
325 step
= _mbsninc(mbsonlylead
, 2) - mbsonlylead
; /* lead + NUL byte + lead + char */
326 ok(step
== 0, "_mbsninc adds %d (exp. 0)\n", step
);
327 step
= _mbsninc(mbstring2
, 0) - mbstring2
;
328 ok(step
== 0, "_mbsninc adds %d (exp. 2)\n", step
);
329 step
= _mbsninc(mbstring2
, 1) - mbstring2
;
330 ok(step
== 2, "_mbsninc adds %d (exp. 2)\n", step
);
331 step
= _mbsninc(mbstring2
, 2) - mbstring2
;
332 ok(step
== 4, "_mbsninc adds %d (exp. 4)\n", step
);
333 step
= _mbsninc(mbstring2
, 3) - mbstring2
;
334 ok(step
== 5, "_mbsninc adds %d (exp. 5)\n", step
);
335 step
= _mbsninc(mbstring2
, 4) - mbstring2
;
336 ok(step
== 7, "_mbsninc adds %d (exp. 7)\n", step
);
337 step
= _mbsninc(mbstring2
, 5) - mbstring2
;
338 ok(step
== 7, "_mbsninc adds %d (exp. 7)\n", step
);
339 step
= _mbsninc(mbstring2
, 17) - mbstring2
;
340 ok(step
== 7, "_mbsninc adds %d (exp. 7)\n", step
);
342 /* functions that depend on locale codepage, not mbcp.
343 * we hope the current locale to be SBCS because setlocale(LC_ALL, ".1252") seems not to work yet
344 * (as of Wine 0.9.43)
346 if (*p__mb_cur_max
== 1)
348 expect_eq(mblen((char *)mbstring
, 3), 1, int, "%x");
349 expect_eq(_mbstrlen((char *)mbstring2
), 7, int, "%d");
352 skip("Current locale has double-byte charset - could leave to false positives\n");
355 expect_eq(_ismbblead(0x80), 0, int, "%d");
357 expect_eq(_ismbblead(0x81), 1, int, "%d");
358 expect_eq(_ismbblead(0x83), 1, int, "%d");
360 expect_eq(_ismbblead(0x84), 1, int, "%d");
361 expect_eq(_ismbblead(0xd3), 1, int, "%d");
362 expect_eq(_ismbblead(0xd7), 0, int, "%d");
364 expect_eq(_ismbblead(0xd8), 1, int, "%d");
366 expect_eq(_ismbblead(0xd9), 1, int, "%d");
368 expect_eq(_ismbbtrail(0x30), 0, int, "%d");
369 expect_eq(_ismbbtrail(0x31), 1, int, "%d");
370 expect_eq(_ismbbtrail(0x7e), 1, int, "%d");
371 expect_eq(_ismbbtrail(0x7f), 0, int, "%d");
372 expect_eq(_ismbbtrail(0x80), 0, int, "%d");
373 expect_eq(_ismbbtrail(0x81), 1, int, "%d");
374 expect_eq(_ismbbtrail(0xfe), 1, int, "%d");
375 expect_eq(_ismbbtrail(0xff), 0, int, "%d");
380 static void test_mbsspn( void)
382 unsigned char str1
[]="cabernet";
383 unsigned char str2
[]="shiraz";
384 unsigned char set
[]="abc";
385 unsigned char empty
[]="";
387 ret
=_mbsspn( str1
, set
);
388 ok( ret
==3, "_mbsspn returns %d should be 3\n", ret
);
389 ret
=_mbsspn( str2
, set
);
390 ok( ret
==0, "_mbsspn returns %d should be 0\n", ret
);
391 ret
=_mbsspn( str1
, empty
);
392 ok( ret
==0, "_mbsspn returns %d should be 0\n", ret
);
395 static void test_mbsspnp( void)
397 unsigned char str1
[]="cabernet";
398 unsigned char str2
[]="shiraz";
399 unsigned char set
[]="abc";
400 unsigned char empty
[]="";
401 unsigned char full
[]="abcenrt";
403 ret
=_mbsspnp( str1
, set
);
404 ok( ret
[0]=='e', "_mbsspnp returns %c should be e\n", ret
[0]);
405 ret
=_mbsspnp( str2
, set
);
406 ok( ret
[0]=='s', "_mbsspnp returns %c should be s\n", ret
[0]);
407 ret
=_mbsspnp( str1
, empty
);
408 ok( ret
[0]=='c', "_mbsspnp returns %c should be c\n", ret
[0]);
409 ret
=_mbsspnp( str1
, full
);
410 ok( ret
==NULL
, "_mbsspnp returns %p should be NULL\n", ret
);
413 static void test_strdup(void)
417 ok( str
== 0, "strdup returns %s should be 0\n", str
);
421 static void test_strcpy_s(void)
424 const char *small
= "small";
425 const char *big
= "atoolongstringforthislittledestination";
430 skip("strcpy_s not found\n");
434 memset(dest
, 'X', sizeof(dest
));
435 ret
= pstrcpy_s(dest
, sizeof(dest
), small
);
436 ok(ret
== 0, "Copying a string into a big enough destination returned %d, expected 0\n", ret
);
437 ok(dest
[0] == 's' && dest
[1] == 'm' && dest
[2] == 'a' && dest
[3] == 'l' &&
438 dest
[4] == 'l' && dest
[5] == '\0'&& dest
[6] == 'X' && dest
[7] == 'X',
439 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
440 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
442 memset(dest
, 'X', sizeof(dest
));
443 ret
= pstrcpy_s(dest
, 0, big
);
444 ok(ret
== EINVAL
, "Copying into a destination of size 0 returned %d, expected EINVAL\n", ret
);
445 ok(dest
[0] == 'X' && dest
[1] == 'X' && dest
[2] == 'X' && dest
[3] == 'X' &&
446 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
447 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
448 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
449 ret
= pstrcpy_s(dest
, 0, NULL
);
450 ok(ret
== EINVAL
, "Copying into a destination of size 0 returned %d, expected EINVAL\n", ret
);
451 ok(dest
[0] == 'X' && dest
[1] == 'X' && dest
[2] == 'X' && dest
[3] == 'X' &&
452 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
453 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
454 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
456 memset(dest
, 'X', sizeof(dest
));
457 ret
= pstrcpy_s(dest
, sizeof(dest
), big
);
458 ok(ret
== ERANGE
, "Copying a big string in a small location returned %d, expected ERANGE\n", ret
);
459 ok(dest
[0] == '\0'&& dest
[1] == 't' && dest
[2] == 'o' && dest
[3] == 'o' &&
460 dest
[4] == 'l' && dest
[5] == 'o' && dest
[6] == 'n' && dest
[7] == 'g',
461 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
462 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
464 memset(dest
, 'X', sizeof(dest
));
465 ret
= pstrcpy_s(dest
, sizeof(dest
), NULL
);
466 ok(ret
== EINVAL
, "Copying from a NULL source string returned %d, expected EINVAL\n", ret
);
467 ok(dest
[0] == '\0'&& dest
[1] == 'X' && dest
[2] == 'X' && dest
[3] == 'X' &&
468 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
469 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
470 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
472 ret
= pstrcpy_s(NULL
, sizeof(dest
), small
);
473 ok(ret
== EINVAL
, "Copying a big string a NULL dest returned %d, expected EINVAL\n", ret
);
476 static void test_strcat_s(void)
479 const char *small
= "sma";
484 skip("strcat_s not found\n");
488 memset(dest
, 'X', sizeof(dest
));
490 ret
= pstrcat_s(dest
, sizeof(dest
), small
);
491 ok(ret
== 0, "strcat_s: Copying a string into a big enough destination returned %d, expected 0\n", ret
);
492 ok(dest
[0] == 's' && dest
[1] == 'm' && dest
[2] == 'a' && dest
[3] == '\0'&&
493 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
494 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
495 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
496 ret
= pstrcat_s(dest
, sizeof(dest
), small
);
497 ok(ret
== 0, "strcat_s: Attaching a string to a big enough destination returned %d, expected 0\n", ret
);
498 ok(dest
[0] == 's' && dest
[1] == 'm' && dest
[2] == 'a' && dest
[3] == 's' &&
499 dest
[4] == 'm' && dest
[5] == 'a' && dest
[6] == '\0'&& dest
[7] == 'X',
500 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
501 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
503 ret
= pstrcat_s(dest
, sizeof(dest
), small
);
504 ok(ret
== ERANGE
, "strcat_s: Attaching a string to a filled up destination returned %d, expected ERANGE\n", ret
);
505 ok(dest
[0] == '\0'&& dest
[1] == 'm' && dest
[2] == 'a' && dest
[3] == 's' &&
506 dest
[4] == 'm' && dest
[5] == 'a' && dest
[6] == 's' && dest
[7] == 'm',
507 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
508 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
510 memset(dest
, 'X', sizeof(dest
));
514 ret
= pstrcat_s(dest
, 0, small
);
515 ok(ret
== EINVAL
, "strcat_s: Source len = 0 returned %d, expected EINVAL\n", ret
);
516 ok(dest
[0] == 'a' && dest
[1] == '\0'&& dest
[2] == 'X' && dest
[3] == 'X' &&
517 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
518 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
519 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
521 ret
= pstrcat_s(dest
, 0, NULL
);
522 ok(ret
== EINVAL
, "strcat_s: len = 0 and src = NULL returned %d, expected EINVAL\n", ret
);
523 ok(dest
[0] == 'a' && dest
[1] == '\0'&& dest
[2] == 'X' && dest
[3] == 'X' &&
524 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
525 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
526 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
528 ret
= pstrcat_s(dest
, sizeof(dest
), NULL
);
529 ok(ret
== EINVAL
, "strcat_s: Sourcing from NULL returned %d, expected EINVAL\n", ret
);
530 ok(dest
[0] == '\0'&& dest
[1] == '\0'&& dest
[2] == 'X' && dest
[3] == 'X' &&
531 dest
[4] == 'X' && dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
532 "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
533 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
535 ret
= pstrcat_s(NULL
, sizeof(dest
), small
);
536 ok(ret
== EINVAL
, "strcat_s: Writing to a NULL string returned %d, expected EINVAL\n", ret
);
539 static void test__mbsnbcpy_s(void)
541 unsigned char dest
[8];
542 const unsigned char big
[] = "atoolongstringforthislittledestination";
543 const unsigned char small
[] = "small";
548 skip("_mbsnbcpy_s not found\n");
552 memset(dest
, 'X', sizeof(dest
));
553 ret
= p_mbsnbcpy_s(dest
, sizeof(dest
), small
, sizeof(small
));
554 ok(ret
== 0, "_mbsnbcpy_s: Copying a string into a big enough destination returned %d, expected 0\n", ret
);
555 ok(dest
[0] == 's' && dest
[1] == 'm' && dest
[2] == 'a' && dest
[3] == 'l' &&
556 dest
[4] == 'l' && dest
[5] == '\0'&& dest
[6] == 'X' && dest
[7] == 'X',
557 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
558 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
561 memset(dest
, 'X', sizeof(dest
));
562 ret
= p_mbsnbcpy_s(dest
, sizeof(dest
) - 2, big
, sizeof(small
));
563 ok(ret
== ERANGE
, "_mbsnbcpy_s: Copying a too long string returned %d, expected ERANGE\n", ret
);
564 ok(dest
[0] == '\0'&& dest
[1] == 't' && dest
[2] == 'o' && dest
[3] == 'o' &&
565 dest
[4] == 'l' && dest
[5] == 'o' && dest
[6] == 'X' && dest
[7] == 'X',
566 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
567 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
569 memset(dest
, 'X', sizeof(dest
));
570 ret
= p_mbsnbcpy_s(dest
, sizeof(dest
) - 2, big
, 4);
571 ok(ret
== 0, "_mbsnbcpy_s: Copying a too long string with a count cap returned %d, expected 0\n", ret
);
572 ok(dest
[0] == 'a' && dest
[1] == 't' && dest
[2] == 'o' && dest
[3] == 'o' &&
573 dest
[4] == '\0'&& dest
[5] == 'X' && dest
[6] == 'X' && dest
[7] == 'X',
574 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
575 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
577 memset(dest
, 'X', sizeof(dest
));
578 ret
= p_mbsnbcpy_s(dest
, sizeof(dest
) - 2, small
, sizeof(small
) + 10);
579 ok(ret
== 0, "_mbsnbcpy_s: Copying more data than the source string len returned %d, expected 0\n", ret
);
580 ok(dest
[0] == 's' && dest
[1] == 'm' && dest
[2] == 'a' && dest
[3] == 'l' &&
581 dest
[4] == 'l' && dest
[5] == '\0'&& dest
[6] == 'X' && dest
[7] == 'X',
582 "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
583 dest
[0], dest
[1], dest
[2], dest
[3], dest
[4], dest
[5], dest
[6], dest
[7]);
586 static void test_wcscpy_s(void)
588 static const WCHAR szLongText
[] = { 'T','h','i','s','A','L','o','n','g','s','t','r','i','n','g',0 };
589 static WCHAR szDest
[18];
590 static WCHAR szDestShort
[8];
595 skip("wcscpy_s not found\n");
600 ret
= p_wcscpy_s(NULL
, 18, szLongText
);
601 ok(ret
== EINVAL
, "p_wcscpy_s expect EINVAL got %d\n", ret
);
603 /* Test NULL Source */
605 ret
= p_wcscpy_s(szDest
, 18, NULL
);
606 ok(ret
== EINVAL
, "expected EINVAL got %d\n", ret
);
607 ok(szDest
[0] == 0, "szDest[0] not 0\n");
609 /* Test invalid size */
611 ret
= p_wcscpy_s(szDest
, 0, szLongText
);
612 /* Later versions changed the return value for this case to EINVAL,
613 * and don't modify the result if the dest size is 0.
615 ok(ret
== ERANGE
|| ret
== EINVAL
, "expected ERANGE/EINVAL got %d\n", ret
);
616 ok(szDest
[0] == 0 || ret
== EINVAL
, "szDest[0] not 0\n");
618 /* Copy same buffer size */
619 ret
= p_wcscpy_s(szDest
, 18, szLongText
);
620 ok(ret
== 0, "expected 0 got %d\n", ret
);
621 ok(lstrcmpW(szDest
, szLongText
) == 0, "szDest != szLongText\n");
623 /* Copy smaller buffer size */
625 ret
= p_wcscpy_s(szDestShort
, 8, szLongText
);
626 ok(ret
== ERANGE
|| ret
== EINVAL
, "expected ERANGE/EINVAL got %d\n", ret
);
627 ok(szDestShort
[0] == 0, "szDestShort[0] not 0\n");
630 static void test__wcsupr_s(void)
632 static const WCHAR mixedString
[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w',
633 'e', 'r', 'U', 'P', 'P', 'E', 'R', 0};
634 static const WCHAR expectedString
[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O',
635 'W', 'E', 'R', 'U', 'P', 'P', 'E',
637 WCHAR testBuffer
[2*sizeof(mixedString
)/sizeof(WCHAR
)];
642 win_skip("_wcsupr_s not found\n");
646 /* Test NULL input string and invalid size. */
648 ret
= p_wcsupr_s(NULL
, 0);
649 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
650 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
652 /* Test NULL input string and valid size. */
654 ret
= p_wcsupr_s(NULL
, sizeof(testBuffer
)/sizeof(WCHAR
));
655 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
656 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
658 /* Test empty string with zero size. */
660 testBuffer
[0] = '\0';
661 ret
= p_wcsupr_s(testBuffer
, 0);
662 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
663 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
664 ok(testBuffer
[0] == '\0', "Expected the buffer to be unchanged\n");
666 /* Test empty string with size of one. */
667 testBuffer
[0] = '\0';
668 ret
= p_wcsupr_s(testBuffer
, 1);
669 ok(ret
== 0, "Expected _wcsupr_s to succeed, got %d\n", ret
);
670 ok(testBuffer
[0] == '\0', "Expected the buffer to be unchanged\n");
672 /* Test one-byte buffer with zero size. */
675 ret
= p_wcsupr_s(testBuffer
, 0);
676 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
677 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
678 ok(testBuffer
[0] == '\0', "Expected the first buffer character to be null\n");
680 /* Test one-byte buffer with size of one. */
683 ret
= p_wcsupr_s(testBuffer
, 1);
684 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
685 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
686 ok(testBuffer
[0] == '\0', "Expected the first buffer character to be null\n");
688 /* Test invalid size. */
689 wcscpy(testBuffer
, mixedString
);
691 ret
= p_wcsupr_s(testBuffer
, 0);
692 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
693 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
694 ok(testBuffer
[0] == '\0', "Expected the first buffer character to be null\n");
696 /* Test normal string uppercasing. */
697 wcscpy(testBuffer
, mixedString
);
698 ret
= p_wcsupr_s(testBuffer
, sizeof(mixedString
)/sizeof(WCHAR
));
699 ok(ret
== 0, "Expected _wcsupr_s to succeed, got %d\n", ret
);
700 ok(!wcscmp(testBuffer
, expectedString
), "Expected the string to be fully upper-case\n");
702 /* Test uppercasing with a shorter buffer size count. */
703 wcscpy(testBuffer
, mixedString
);
705 ret
= p_wcsupr_s(testBuffer
, sizeof(mixedString
)/sizeof(WCHAR
) - 1);
706 ok(ret
== EINVAL
, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret
);
707 ok(errno
== EINVAL
, "Expected errno to be EINVAL, got %d\n", errno
);
708 ok(testBuffer
[0] == '\0', "Expected the first buffer character to be null\n");
710 /* Test uppercasing with a longer buffer size count. */
711 wcscpy(testBuffer
, mixedString
);
712 ret
= p_wcsupr_s(testBuffer
, sizeof(testBuffer
)/sizeof(WCHAR
));
713 ok(ret
== 0, "Expected _wcsupr_s to succeed, got %d\n", ret
);
714 ok(!wcscmp(testBuffer
, expectedString
), "Expected the string to be fully upper-case\n");
717 static void test_mbcjisjms(void)
719 /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */
720 unsigned int jisjms
[][2] = { {0x2020, 0}, {0x2021, 0}, {0x2120, 0}, {0x2121, 0x8140},
721 {0x7f7f, 0}, {0x7f7e, 0}, {0x7e7f, 0}, {0x7e7e, 0xeffc},
722 {0x2121FFFF, 0}, {0x2223, 0x81a1}, {0x237e, 0x829e}, {0, 0}};
723 unsigned int ret
, exp
, i
;
728 ret
= _mbcjistojms(jisjms
[i
][0]);
730 if(_getmbcp() == 932) /* Japanese codepage? */
733 exp
= jisjms
[i
][0]; /* If not, no conversion */
735 ok(ret
== exp
, "Expected 0x%x, got 0x%x\n", exp
, ret
);
736 } while(jisjms
[i
++][0] != 0);
739 static void test_mbctombb(void)
741 static const unsigned int mbcmbb_932
[][2] = {
742 {0x829e, 0x829e}, {0x829f, 0xa7}, {0x82f1, 0xdd}, {0x82f2, 0x82f2},
743 {0x833f, 0x833f}, {0x8340, 0xa7}, {0x837e, 0xd0}, {0x837f, 0x837f},
744 {0x8380, 0xd1}, {0x8396, 0xb9}, {0x8397, 0x8397}, {0x813f, 0x813f},
745 {0x8140, 0x20}, {0x814c, 0x814c}, {0x814f, 0x5e}, {0x8197, 0x40},
746 {0x8198, 0x8198}, {0x8258, 0x39}, {0x8259, 0x8259}, {0x825f, 0x825f},
747 {0x8260, 0x41}, {0x82f1, 0xdd}, {0x82f2, 0x82f2}, {0,0}};
748 unsigned int exp
, ret
, i
;
749 unsigned int prev_cp
= _getmbcp();
752 for (i
= 0; mbcmbb_932
[i
][0] != 0; i
++)
754 ret
= _mbctombb(mbcmbb_932
[i
][0]);
755 exp
= mbcmbb_932
[i
][1];
756 ok(ret
== exp
, "Expected 0x%x, got 0x%x\n", exp
, ret
);
761 static void test_ismbclegal(void) {
762 unsigned int prev_cp
= _getmbcp();
766 _setmbcp(932); /* Japanese */
768 for(i
= 0; i
< 0x10000; i
++) {
769 ret
= _ismbclegal(i
);
770 exp
= ((HIBYTE(i
) >= 0x81 && HIBYTE(i
) <= 0x9F) ||
771 (HIBYTE(i
) >= 0xE0 && HIBYTE(i
) <= 0xFC)) &&
772 ((LOBYTE(i
) >= 0x40 && LOBYTE(i
) <= 0x7E) ||
773 (LOBYTE(i
) >= 0x80 && LOBYTE(i
) <= 0xFC));
779 ok(!err
, "_ismbclegal (932) : Expected 0x%x, got 0x%x (0x%x)\n", exp
, ret
, i
);
780 _setmbcp(936); /* Chinese (GBK) */
782 for(i
= 0; i
< 0x10000; i
++) {
783 ret
= _ismbclegal(i
);
784 exp
= HIBYTE(i
) >= 0x81 && HIBYTE(i
) <= 0xFE &&
785 LOBYTE(i
) >= 0x40 && LOBYTE(i
) <= 0xFE;
791 ok(!err
, "_ismbclegal (936) : Expected 0x%x, got 0x%x (0x%x)\n", exp
, ret
, i
);
792 _setmbcp(949); /* Korean */
794 for(i
= 0; i
< 0x10000; i
++) {
795 ret
= _ismbclegal(i
);
796 exp
= HIBYTE(i
) >= 0x81 && HIBYTE(i
) <= 0xFE &&
797 LOBYTE(i
) >= 0x41 && LOBYTE(i
) <= 0xFE;
803 ok(!err
, "_ismbclegal (949) : Expected 0x%x, got 0x%x (0x%x)\n", exp
, ret
, i
);
804 _setmbcp(950); /* Chinese (Big5) */
806 for(i
= 0; i
< 0x10000; i
++) {
807 ret
= _ismbclegal(i
);
808 exp
= HIBYTE(i
) >= 0x81 && HIBYTE(i
) <= 0xFE &&
809 ((LOBYTE(i
) >= 0x40 && LOBYTE(i
) <= 0x7E) ||
810 (LOBYTE(i
) >= 0xA1 && LOBYTE(i
) <= 0xFE));
816 ok(!err
, "_ismbclegal (950) : Expected 0x%x, got 0x%x (0x%x)\n", exp
, ret
, i
);
817 _setmbcp(1361); /* Korean (Johab) */
819 for(i
= 0; i
< 0x10000; i
++) {
820 ret
= _ismbclegal(i
);
821 exp
= ((HIBYTE(i
) >= 0x81 && HIBYTE(i
) <= 0xD3) ||
822 (HIBYTE(i
) >= 0xD8 && HIBYTE(i
) <= 0xF9)) &&
823 ((LOBYTE(i
) >= 0x31 && LOBYTE(i
) <= 0x7E) ||
824 (LOBYTE(i
) >= 0x81 && LOBYTE(i
) <= 0xFE)) &&
831 todo_wine
ok(!err
, "_ismbclegal (1361) : Expected 0x%x, got 0x%x (0x%x)\n", exp
, ret
, i
);
836 static const struct {
838 const char* delimiter
;
839 int exp_offsetret1
; /* returned offset from string after first call to strtok()
841 int exp_offsetret2
; /* returned offset from string after second call to strtok()
843 int exp_offsetret3
; /* returned offset from string after third call to strtok()
845 } testcases_strtok
[] = {
846 { "red cabernet", " ", 0, 4, -1 },
847 { "sparkling white riesling", " ", 0, 10, 16 },
848 { " pale cream sherry", "e ", 1, 6, 9 },
853 static void test_strtok(void)
858 for( i
= 0; testcases_strtok
[i
].string
; i
++){
859 strcpy( teststr
, testcases_strtok
[i
].string
);
860 strret
= strtok( teststr
, testcases_strtok
[i
].delimiter
);
861 ok( (int)(strret
- teststr
) == testcases_strtok
[i
].exp_offsetret1
||
862 (!strret
&& testcases_strtok
[i
].exp_offsetret1
== -1),
863 "string (%p) \'%s\' return %p\n",
864 teststr
, testcases_strtok
[i
].string
, strret
);
865 if( !strret
) continue;
866 strret
= strtok( NULL
, testcases_strtok
[i
].delimiter
);
867 ok( (int)(strret
- teststr
) == testcases_strtok
[i
].exp_offsetret2
||
868 (!strret
&& testcases_strtok
[i
].exp_offsetret2
== -1),
869 "second call string (%p) \'%s\' return %p\n",
870 teststr
, testcases_strtok
[i
].string
, strret
);
871 if( !strret
) continue;
872 strret
= strtok( NULL
, testcases_strtok
[i
].delimiter
);
873 ok( (int)(strret
- teststr
) == testcases_strtok
[i
].exp_offsetret3
||
874 (!strret
&& testcases_strtok
[i
].exp_offsetret3
== -1),
875 "third call string (%p) \'%s\' return %p\n",
876 teststr
, testcases_strtok
[i
].string
, strret
);
880 static void test_strtol(void)
886 /* errno is only set in case of error, so reset errno to EBADF to check for errno modification */
887 /* errno is modified on W2K8+ */
889 l
= strtol("-1234", &e
, 0);
890 ok(l
==-1234, "wrong value %d\n", l
);
891 ok(errno
== EBADF
|| broken(errno
== 0), "wrong errno %d\n", errno
);
893 ul
= strtoul("1234", &e
, 0);
894 ok(ul
==1234, "wrong value %u\n", ul
);
895 ok(errno
== EBADF
|| broken(errno
== 0), "wrong errno %d\n", errno
);
898 l
= strtol("2147483647L", &e
, 0);
899 ok(l
==2147483647, "wrong value %d\n", l
);
900 ok(errno
== EBADF
|| broken(errno
== 0), "wrong errno %d\n", errno
);
902 l
= strtol("-2147483648L", &e
, 0);
903 ok(l
==-2147483647L - 1, "wrong value %d\n", l
);
904 ok(errno
== EBADF
|| broken(errno
== 0), "wrong errno %d\n", errno
);
906 ul
= strtoul("4294967295UL", &e
, 0);
907 ok(ul
==4294967295ul, "wrong value %u\n", ul
);
908 ok(errno
== EBADF
|| broken(errno
== 0), "wrong errno %d\n", errno
);
911 l
= strtol("9223372036854775807L", &e
, 0);
912 ok(l
==2147483647, "wrong value %d\n", l
);
913 ok(errno
== ERANGE
, "wrong errno %d\n", errno
);
915 ul
= strtoul("9223372036854775807L", &e
, 0);
916 ok(ul
==4294967295ul, "wrong value %u\n", ul
);
917 ok(errno
== ERANGE
, "wrong errno %d\n", errno
);
920 static void test_strnlen(void)
922 static const char str
[] = "string";
926 win_skip("strnlen not found\n");
930 res
= p_strnlen(str
, 20);
931 ok(res
== 6, "Returned length = %d\n", (int)res
);
933 res
= p_strnlen(str
, 3);
934 ok(res
== 3, "Returned length = %d\n", (int)res
);
936 res
= p_strnlen(NULL
, 0);
937 ok(res
== 0, "Returned length = %d\n", (int)res
);
940 static void test__strtoi64(void)
942 static const char no1
[] = "31923";
943 static const char no2
[] = "-213312";
944 static const char no3
[] = "12aa";
945 static const char no4
[] = "abc12";
946 static const char overflow
[] = "99999999999999999999";
947 static const char neg_overflow
[] = "-99999999999999999999";
948 static const char hex
[] = "0x123";
949 static const char oct
[] = "000123";
950 static const char blanks
[] = " 12 212.31";
953 unsigned __int64 ures
;
956 if(!p_strtoi64
|| !p_strtoui64
) {
957 win_skip("_strtoi64 or _strtoui64 not found\n");
962 res
= p_strtoi64(no1
, NULL
, 10);
963 ok(res
== 31923, "res != 31923\n");
964 res
= p_strtoi64(no2
, NULL
, 10);
965 ok(res
== -213312, "res != -213312\n");
966 res
= p_strtoi64(no3
, NULL
, 10);
967 ok(res
== 12, "res != 12\n");
968 res
= p_strtoi64(no4
, &endpos
, 10);
969 ok(res
== 0, "res != 0\n");
970 ok(endpos
== no4
, "Scanning was not stopped on first character\n");
971 res
= p_strtoi64(hex
, &endpos
, 10);
972 ok(res
== 0, "res != 0\n");
973 ok(endpos
== hex
+1, "Incorrect endpos (%p-%p)\n", hex
, endpos
);
974 res
= p_strtoi64(oct
, &endpos
, 10);
975 ok(res
== 123, "res != 123\n");
976 ok(endpos
== oct
+strlen(oct
), "Incorrect endpos (%p-%p)\n", oct
, endpos
);
977 res
= p_strtoi64(blanks
, &endpos
, 10);
978 ok(res
== 12, "res != 12");
979 ok(endpos
== blanks
+10, "Incorrect endpos (%p-%p)\n", blanks
, endpos
);
980 ok(errno
== 0xdeadbeef, "errno = %x\n", errno
);
983 res
= p_strtoi64(overflow
, &endpos
, 10);
984 ok(res
== _I64_MAX
, "res != _I64_MAX\n");
985 ok(endpos
== overflow
+strlen(overflow
), "Incorrect endpos (%p-%p)\n", overflow
, endpos
);
986 ok(errno
== ERANGE
, "errno = %x\n", errno
);
989 res
= p_strtoi64(neg_overflow
, &endpos
, 10);
990 ok(res
== _I64_MIN
, "res != _I64_MIN\n");
991 ok(endpos
== neg_overflow
+strlen(neg_overflow
), "Incorrect endpos (%p-%p)\n", neg_overflow
, endpos
);
992 ok(errno
== ERANGE
, "errno = %x\n", errno
);
995 res
= p_strtoi64(no1
, &endpos
, 16);
996 ok(res
== 203043, "res != 203043\n");
997 ok(endpos
== no1
+strlen(no1
), "Incorrect endpos (%p-%p)\n", no1
, endpos
);
998 res
= p_strtoi64(no2
, &endpos
, 16);
999 ok(res
== -2175762, "res != -2175762\n");
1000 ok(endpos
== no2
+strlen(no2
), "Incorrect endpos (%p-%p)\n", no2
, endpos
);
1001 res
= p_strtoi64(no3
, &endpos
, 16);
1002 ok(res
== 4778, "res != 4778\n");
1003 ok(endpos
== no3
+strlen(no3
), "Incorrect endpos (%p-%p)\n", no3
, endpos
);
1004 res
= p_strtoi64(no4
, &endpos
, 16);
1005 ok(res
== 703506, "res != 703506\n");
1006 ok(endpos
== no4
+strlen(no4
), "Incorrect endpos (%p-%p)\n", no4
, endpos
);
1007 res
= p_strtoi64(hex
, &endpos
, 16);
1008 ok(res
== 291, "res != 291\n");
1009 ok(endpos
== hex
+strlen(hex
), "Incorrect endpos (%p-%p)\n", hex
, endpos
);
1010 res
= p_strtoi64(oct
, &endpos
, 16);
1011 ok(res
== 291, "res != 291\n");
1012 ok(endpos
== oct
+strlen(oct
), "Incorrect endpos (%p-%p)\n", oct
, endpos
);
1013 res
= p_strtoi64(blanks
, &endpos
, 16);
1014 ok(res
== 18, "res != 18\n");
1015 ok(endpos
== blanks
+10, "Incorrect endpos (%p-%p)\n", blanks
, endpos
);
1016 ok(errno
== 0xdeadbeef, "errno = %x\n", errno
);
1019 res
= p_strtoi64(hex
, &endpos
, 36);
1020 ok(res
== 1541019, "res != 1541019\n");
1021 ok(endpos
== hex
+strlen(hex
), "Incorrect endpos (%p-%p)\n", hex
, endpos
);
1022 ok(errno
== 0xdeadbeef, "errno = %x\n", errno
);
1025 res
= p_strtoi64(no1
, &endpos
, 0);
1026 ok(res
== 31923, "res != 31923\n");
1027 ok(endpos
== no1
+strlen(no1
), "Incorrect endpos (%p-%p)\n", no1
, endpos
);
1028 res
= p_strtoi64(no2
, &endpos
, 0);
1029 ok(res
== -213312, "res != -213312\n");
1030 ok(endpos
== no2
+strlen(no2
), "Incorrect endpos (%p-%p)\n", no2
, endpos
);
1031 res
= p_strtoi64(no3
, &endpos
, 10);
1032 ok(res
== 12, "res != 12\n");
1033 ok(endpos
== no3
+2, "Incorrect endpos (%p-%p)\n", no3
, endpos
);
1034 res
= p_strtoi64(no4
, &endpos
, 10);
1035 ok(res
== 0, "res != 0\n");
1036 ok(endpos
== no4
, "Incorrect endpos (%p-%p)\n", no4
, endpos
);
1037 res
= p_strtoi64(hex
, &endpos
, 10);
1038 ok(res
== 0, "res != 0\n");
1039 ok(endpos
== hex
+1, "Incorrect endpos (%p-%p)\n", hex
, endpos
);
1040 res
= p_strtoi64(oct
, &endpos
, 10);
1041 ok(res
== 123, "res != 123\n");
1042 ok(endpos
== oct
+strlen(oct
), "Incorrect endpos (%p-%p)\n", oct
, endpos
);
1043 res
= p_strtoi64(blanks
, &endpos
, 10);
1044 ok(res
== 12, "res != 12\n");
1045 ok(endpos
== blanks
+10, "Incorrect endpos (%p-%p)\n", blanks
, endpos
);
1046 ok(errno
== 0xdeadbeef, "errno = %x\n", errno
);
1049 ures
= p_strtoui64(no1
, &endpos
, 0);
1050 ok(ures
== 31923, "ures != 31923\n");
1051 ok(endpos
== no1
+strlen(no1
), "Incorrect endpos (%p-%p)\n", no1
, endpos
);
1052 ures
= p_strtoui64(no2
, &endpos
, 0);
1053 ok(ures
== -213312, "ures != -213312\n");
1054 ok(endpos
== no2
+strlen(no2
), "Incorrect endpos (%p-%p)\n", no2
, endpos
);
1055 ures
= p_strtoui64(no3
, &endpos
, 10);
1056 ok(ures
== 12, "ures != 12\n");
1057 ok(endpos
== no3
+2, "Incorrect endpos (%p-%p)\n", no3
, endpos
);
1058 ures
= p_strtoui64(no4
, &endpos
, 10);
1059 ok(ures
== 0, "ures != 0\n");
1060 ok(endpos
== no4
, "Incorrect endpos (%p-%p)\n", no4
, endpos
);
1061 ures
= p_strtoui64(hex
, &endpos
, 10);
1062 ok(ures
== 0, "ures != 0\n");
1063 ok(endpos
== hex
+1, "Incorrect endpos (%p-%p)\n", hex
, endpos
);
1064 ures
= p_strtoui64(oct
, &endpos
, 10);
1065 ok(ures
== 123, "ures != 123\n");
1066 ok(endpos
== oct
+strlen(oct
), "Incorrect endpos (%p-%p)\n", oct
, endpos
);
1067 ures
= p_strtoui64(blanks
, &endpos
, 10);
1068 ok(ures
== 12, "ures != 12\n");
1069 ok(endpos
== blanks
+10, "Incorrect endpos (%p-%p)\n", blanks
, endpos
);
1070 ok(errno
== 0xdeadbeef, "errno = %x\n", errno
);
1073 ures
= p_strtoui64(overflow
, &endpos
, 10);
1074 ok(ures
== _UI64_MAX
, "ures != _UI64_MAX\n");
1075 ok(endpos
== overflow
+strlen(overflow
), "Incorrect endpos (%p-%p)\n", overflow
, endpos
);
1076 ok(errno
== ERANGE
, "errno = %x\n", errno
);
1079 ures
= p_strtoui64(neg_overflow
, &endpos
, 10);
1080 ok(ures
== 1, "ures != 1\n");
1081 ok(endpos
== neg_overflow
+strlen(neg_overflow
), "Incorrect endpos (%p-%p)\n", neg_overflow
, endpos
);
1082 ok(errno
== ERANGE
, "errno = %x\n", errno
);
1085 static inline BOOL
almost_equal(double d1
, double d2
) {
1086 if(d1
-d2
>-1e-30 && d1
-d2
<1e-30)
1091 static void test__strtod(void)
1093 const char double1
[] = "12.1";
1094 const char double2
[] = "-13.721";
1095 const char double3
[] = "INF";
1096 const char double4
[] = ".21e12";
1097 const char double5
[] = "214353e-3";
1098 const char overflow
[] = "1d9999999999999999999";
1103 d
= strtod(double1
, &end
);
1104 ok(almost_equal(d
, 12.1), "d = %lf\n", d
);
1105 ok(end
== double1
+4, "incorrect end (%d)\n", end
-double1
);
1107 d
= strtod(double2
, &end
);
1108 ok(almost_equal(d
, -13.721), "d = %lf\n", d
);
1109 ok(end
== double2
+7, "incorrect end (%d)\n", end
-double2
);
1111 d
= strtod(double3
, &end
);
1112 ok(almost_equal(d
, 0), "d = %lf\n", d
);
1113 ok(end
== double3
, "incorrect end (%d)\n", end
-double3
);
1115 d
= strtod(double4
, &end
);
1116 ok(almost_equal(d
, 210000000000.0), "d = %lf\n", d
);
1117 ok(end
== double4
+6, "incorrect end (%d)\n", end
-double4
);
1119 d
= strtod(double5
, &end
);
1120 ok(almost_equal(d
, 214.353), "d = %lf\n", d
);
1121 ok(end
== double5
+9, "incorrect end (%d)\n", end
-double5
);
1123 d
= strtod("12.1d2", NULL
);
1124 ok(almost_equal(d
, 12.1e2
), "d = %lf\n", d
);
1126 /* Set locale with non '.' decimal point (',') */
1127 if(!setlocale(LC_ALL
, "Polish")) {
1128 win_skip("system with limited locales\n");
1132 d
= strtod("12.1", NULL
);
1133 ok(almost_equal(d
, 12.0), "d = %lf\n", d
);
1135 d
= strtod("12,1", NULL
);
1136 ok(almost_equal(d
, 12.1), "d = %lf\n", d
);
1138 setlocale(LC_ALL
, "C");
1140 /* Precision tests */
1141 d
= strtod("0.1", NULL
);
1142 ok(almost_equal(d
, 0.1), "d = %lf\n", d
);
1143 d
= strtod("-0.1", NULL
);
1144 ok(almost_equal(d
, -0.1), "d = %lf\n", d
);
1145 d
= strtod("0.1281832188491894198128921", NULL
);
1146 ok(almost_equal(d
, 0.1281832188491894198128921), "d = %lf\n", d
);
1147 d
= strtod("0.82181281288121", NULL
);
1148 ok(almost_equal(d
, 0.82181281288121), "d = %lf\n", d
);
1149 d
= strtod("21921922352523587651128218821", NULL
);
1150 ok(almost_equal(d
, 21921922352523587651128218821.0), "d = %lf\n", d
);
1151 d
= strtod("0.1d238", NULL
);
1152 ok(almost_equal(d
, 0.1e238L
), "d = %lf\n", d
);
1153 d
= strtod("0.1D-4736", NULL
);
1154 ok(almost_equal(d
, 0.1e-4736L), "d = %lf\n", d
);
1157 d
= strtod(overflow
, &end
);
1158 ok(errno
== ERANGE
, "errno = %x\n", errno
);
1159 ok(end
== overflow
+21, "incorrect end (%d)\n", end
-overflow
);
1162 strtod("-1d309", NULL
);
1163 ok(errno
== ERANGE
, "errno = %x\n", errno
);
1166 static void test_mbstowcs(void)
1168 static const wchar_t wSimple
[] = { 't','e','x','t',0 };
1169 static const wchar_t wHiragana
[] = { 0x3042,0x3043,0 };
1170 static const char mSimple
[] = "text";
1171 static const char mHiragana
[] = { 0x82,0xa0,0x82,0xa1,0 };
1178 wOut
[4] = '!'; wOut
[5] = '\0';
1179 mOut
[4] = '!'; mOut
[5] = '\0';
1181 ret
= mbstowcs(NULL
, mSimple
, 0);
1182 ok(ret
== 4, "ret = %d\n", ret
);
1184 ret
= mbstowcs(wOut
, mSimple
, 4);
1185 ok(ret
== 4, "ret = %d\n", ret
);
1186 ok(!memcmp(wOut
, wSimple
, 4*sizeof(wchar_t)), "wOut = %s\n", wine_dbgstr_w(wOut
));
1187 ok(wOut
[4] == '!', "wOut[4] != \'!\'\n");
1189 ret
= wcstombs(NULL
, wSimple
, 0);
1190 ok(ret
== 4, "ret = %d\n", ret
);
1192 ret
= wcstombs(mOut
, wSimple
, 6);
1193 ok(ret
== 4, "ret = %d\n", ret
);
1194 ok(!memcmp(mOut
, mSimple
, 5*sizeof(char)), "mOut = %s\n", mOut
);
1196 ret
= wcstombs(mOut
, wSimple
, 2);
1197 ok(ret
== 2, "ret = %d\n", ret
);
1198 ok(!memcmp(mOut
, mSimple
, 5*sizeof(char)), "mOut = %s\n", mOut
);
1200 if(!setlocale(LC_ALL
, "Japanese_Japan.932")) {
1201 win_skip("Japanese_Japan.932 locale not available\n");
1205 ret
= mbstowcs(wOut
, mHiragana
, 6);
1206 ok(ret
== 2, "ret = %d\n", ret
);
1207 ok(!memcmp(wOut
, wHiragana
, sizeof(wHiragana
)), "wOut = %s\n", wine_dbgstr_w(wOut
));
1209 ret
= wcstombs(mOut
, wHiragana
, 6);
1210 ok(ret
== 4, "ret = %d\n", ret
);
1211 ok(!memcmp(mOut
, mHiragana
, sizeof(mHiragana
)), "mOut = %s\n", mOut
);
1213 if(!pmbstowcs_s
|| !pwcstombs_s
) {
1214 win_skip("mbstowcs_s or wcstombs_s not available\n");
1218 err
= pmbstowcs_s(&ret
, wOut
, 6, mSimple
, _TRUNCATE
);
1219 ok(err
== 0, "err = %d\n", err
);
1220 ok(ret
== 5, "ret = %d\n", (int)ret
);
1221 ok(!memcmp(wOut
, wSimple
, sizeof(wSimple
)), "wOut = %s\n", wine_dbgstr_w(wOut
));
1223 err
= pmbstowcs_s(&ret
, wOut
, 6, mHiragana
, _TRUNCATE
);
1224 ok(err
== 0, "err = %d\n", err
);
1225 ok(ret
== 3, "ret = %d\n", (int)ret
);
1226 ok(!memcmp(wOut
, wHiragana
, sizeof(wHiragana
)), "wOut = %s\n", wine_dbgstr_w(wOut
));
1228 err
= pwcstombs_s(&ret
, mOut
, 6, wSimple
, _TRUNCATE
);
1229 ok(err
== 0, "err = %d\n", err
);
1230 ok(ret
== 5, "ret = %d\n", (int)ret
);
1231 ok(!memcmp(mOut
, mSimple
, sizeof(mSimple
)), "mOut = %s\n", mOut
);
1233 err
= pwcstombs_s(&ret
, mOut
, 6, wHiragana
, _TRUNCATE
);
1234 ok(err
== 0, "err = %d\n", err
);
1235 ok(ret
== 5, "ret = %d\n", (int)ret
);
1236 ok(!memcmp(mOut
, mHiragana
, sizeof(mHiragana
)), "mOut = %s\n", mOut
);
1242 static const char xilstring
[]="c:/xilinx";
1245 hMsvcrt
= GetModuleHandleA("msvcrt.dll");
1247 hMsvcrt
= GetModuleHandleA("msvcrtd.dll");
1248 ok(hMsvcrt
!= 0, "GetModuleHandleA failed\n");
1249 SET(pmemcpy
,"memcpy");
1250 SET(pmemcmp
,"memcmp");
1251 SET(p_mbctype
,"_mbctype");
1252 SET(p__mb_cur_max
,"__mb_cur_max");
1253 pstrcpy_s
= (void *)GetProcAddress( hMsvcrt
,"strcpy_s" );
1254 pstrcat_s
= (void *)GetProcAddress( hMsvcrt
,"strcat_s" );
1255 p_mbsnbcpy_s
= (void *)GetProcAddress( hMsvcrt
,"_mbsnbcpy_s" );
1256 p_wcscpy_s
= (void *)GetProcAddress( hMsvcrt
,"wcscpy_s" );
1257 p_wcsupr_s
= (void *)GetProcAddress( hMsvcrt
,"_wcsupr_s" );
1258 p_strnlen
= (void *)GetProcAddress( hMsvcrt
,"strnlen" );
1259 p_strtoi64
= (void *) GetProcAddress(hMsvcrt
, "_strtoi64");
1260 p_strtoui64
= (void *) GetProcAddress(hMsvcrt
, "_strtoui64");
1261 pmbstowcs_s
= (void *) GetProcAddress(hMsvcrt
, "mbstowcs_s");
1262 pwcstombs_s
= (void *) GetProcAddress(hMsvcrt
, "wcstombs_s");
1264 /* MSVCRT memcpy behaves like memmove for overlapping moves,
1265 MFC42 CString::Insert seems to rely on that behaviour */
1266 strcpy(mem
,xilstring
);
1267 nLen
=strlen(xilstring
);
1268 pmemcpy(mem
+5, mem
,nLen
+1);
1269 ok(pmemcmp(mem
+5,xilstring
, nLen
) == 0,
1270 "Got result %s\n",mem
+5);
1272 /* Test _swab function */