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