ReactOS 0.4.16-dev-927-g467dec4
string.c
Go to the documentation of this file.
1/*
2 * Copyright 2015 Martin Storsjo
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <errno.h>
20#include <stdarg.h>
21#include <stdlib.h>
22#include <wchar.h>
23#include <stdio.h>
24#include <locale.h>
25#include <mbctype.h>
26#include <mbstring.h>
27
28#include <windef.h>
29#include <winbase.h>
30#include "wine/test.h"
31
32#include <math.h>
33
34#define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
36
37#define SET_EXPECT(func) \
38 expect_ ## func = TRUE
39
40#define CHECK_EXPECT2(func) \
41 do { \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 called_ ## func = TRUE; \
44 }while(0)
45
46#define CHECK_EXPECT(func) \
47 do { \
48 CHECK_EXPECT2(func); \
49 expect_ ## func = FALSE; \
50 }while(0)
51
52#define CHECK_CALLED(func) \
53 do { \
54 ok(called_ ## func, "expected " #func "\n"); \
55 expect_ ## func = called_ ## func = FALSE; \
56 }while(0)
57
59
60static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
61 const wchar_t *function, const wchar_t *file,
62 unsigned line, uintptr_t arg)
63{
65 ok(expression == NULL, "expression is not NULL\n");
66 ok(function == NULL, "function is not NULL\n");
67 ok(file == NULL, "file is not NULL\n");
68 ok(line == 0, "line = %u\n", line);
69 ok(arg == 0, "arg = %Ix\n", arg);
70}
71
74
75static BOOL local_isnan(double d)
76{
77 return d != d;
78}
79
80#define test_strtod_str_errno(string, value, length, err) _test_strtod_str(__LINE__, string, value, length, err)
81#define test_strtod_str(string, value, length) _test_strtod_str(__LINE__, string, value, length, 0)
82static void _test_strtod_str(int line, const char* string, double value, int length, int err)
83{
84 char *end;
85 double d;
86 errno = 0xdeadbeef;
87 d = strtod(string, &end);
88 if(!err)
89 ok_(__FILE__, line)(errno == 0xdeadbeef, "errno = %d\n", errno);
90 else
91 ok_(__FILE__, line)(errno == err, "errno = %d\n", errno);
92 if (local_isnan(value))
93 ok_(__FILE__, line)(local_isnan(d), "d = %.16le (\"%s\")\n", d, string);
94 else
95 ok_(__FILE__, line)(d == value, "d = %.16le (\"%s\")\n", d, string);
96 ok_(__FILE__, line)(end == string + length, "incorrect end (%d, \"%s\")\n", (int)(end - string), string);
97}
98
99static void test_strtod(void)
100{
101 test_strtod_str("infinity", INFINITY, 8);
102 test_strtod_str("INFINITY", INFINITY, 8);
103 test_strtod_str("InFiNiTy", INFINITY, 8);
104 test_strtod_str("INF", INFINITY, 3);
105 test_strtod_str("-inf", -INFINITY, 4);
106 test_strtod_str("inf42", INFINITY, 3);
107 test_strtod_str("inffoo", INFINITY, 3);
108 test_strtod_str("infini", INFINITY, 3);
109 test_strtod_str("input", 0, 0);
110 test_strtod_str("-input", 0, 0);
111 test_strtod_str_errno("1.7976931348623159e+308", INFINITY, 23, ERANGE);
112 test_strtod_str_errno("-1.7976931348623159e+308", -INFINITY, 24, ERANGE);
113
114 test_strtod_str("NAN", NAN, 3);
115 test_strtod_str("nan", NAN, 3);
116 test_strtod_str("NaN", NAN, 3);
117
118 test_strtod_str("0x42", 66, 4);
119 test_strtod_str("0X42", 66, 4);
120 test_strtod_str("-0x42", -66, 5);
121 test_strtod_str("0x1p1", 2, 5);
122 test_strtod_str("0x1P1", 2, 5);
123 test_strtod_str("0x1p+1", 2, 6);
124 test_strtod_str("0x2p-1", 1, 6);
125 test_strtod_str("0xA", 10, 3);
126 test_strtod_str("0xa", 10, 3);
127 test_strtod_str("0xABCDEF", 11259375, 8);
128 test_strtod_str("0Xabcdef", 11259375, 8);
129
130 test_strtod_str("0x1.1", 1.0625, 5);
131 test_strtod_str("0x1.1p1", 2.125, 7);
132 test_strtod_str("0x1.A", 1.625, 5);
133 test_strtod_str("0x1p1a", 2, 5);
134 test_strtod_str("0xp3", 0, 1);
135 test_strtod_str("0x.", 0, 1);
136 test_strtod_str("0x.8", 0.5, 4);
137 test_strtod_str("0x.8p", 0.5, 4);
138 test_strtod_str("0x0p10000000000000000000000000", 0, 30);
139 test_strtod_str("0x1p-1026", 1.3906711615670009e-309, 9);
140
141 test_strtod_str("0x1ffffffffffffe.80000000000000000000", 9007199254740990.0, 37);
142 test_strtod_str("0x1ffffffffffffe.80000000000000000001", 9007199254740991.0, 37);
143 test_strtod_str("0x1fffffffffffff.80000000000000000000", 9007199254740992.0, 37);
144 test_strtod_str("0x1fffffffffffff.80000000000000000001", 9007199254740992.0, 37);
145
146 test_strtod_str("4.0621786324484881721115322e-53", 4.0621786324484881721115322e-53, 31);
147 test_strtod_str("1.8905590910042396899370942", 1.8905590910042396899370942, 27);
148 test_strtod_str("1.7976931348623158e+308", 1.7976931348623158e+308, 23);
149 test_strtod_str("2.2250738585072014e-308", 2.2250738585072014e-308, 23);
150 test_strtod_str("4.9406564584124654e-324", 4.9406564584124654e-324, 23);
151 test_strtod_str("2.48e-324", 4.9406564584124654e-324, 9);
152 test_strtod_str_errno("2.47e-324", 0, 9, ERANGE);
153}
154
155static void test_strtof(void)
156{
157 static const struct {
158 const char *str;
159 int len;
160 float ret;
161 int err;
162 } tests[] = {
163 { "12.1", 4, 12.1f },
164 { "-13.721", 7, -13.721f },
165 { "1.e40", 5, INFINITY, ERANGE },
166 { "-1.e40", 6, -INFINITY, ERANGE },
167 { "0.0", 3, 0.0f },
168 { "-0.0", 4, 0.0f },
169 { "1.4e-45", 7, 1.4e-45f },
170 { "-1.4e-45", 8, -1.4e-45f },
171 { "1.e-60", 6, 0, ERANGE },
172 { "-1.e-60", 7, 0, ERANGE },
173 };
174
175 char *end;
176 float f;
177 int i;
178
179 for (i=0; i<ARRAY_SIZE(tests); i++)
180 {
181 errno = 0xdeadbeef;
182 f = strtof(tests[i].str, &end);
183 ok(f == tests[i].ret, "%d) f = %.16e\n", i, f);
184 ok(end == tests[i].str + tests[i].len, "%d) len = %d\n",
185 i, (int)(end - tests[i].str));
186 ok(errno == tests[i].err || (!tests[i].err && errno == 0xdeadbeef),
187 "%d) errno = %d\n", i, errno);
188 }
189}
190
191static void test__memicmp(void)
192{
193 static const char *s1 = "abc";
194 static const char *s2 = "aBd";
195 int ret;
196
197 ret = _memicmp(NULL, NULL, 0);
198 ok(!ret, "got %d\n", ret);
199
201 errno = 0xdeadbeef;
202 ret = _memicmp(NULL, NULL, 1);
203 ok(ret == _NLSCMPERROR, "got %d\n", ret);
204 ok(errno == EINVAL, "Unexpected errno = %d\n", errno);
206
208 errno = 0xdeadbeef;
209 ret = _memicmp(s1, NULL, 1);
210 ok(ret == _NLSCMPERROR, "got %d\n", ret);
211 ok(errno == EINVAL, "Unexpected errno = %d\n", errno);
213
215 errno = 0xdeadbeef;
216 ret = _memicmp(NULL, s2, 1);
217 ok(ret == _NLSCMPERROR, "got %d\n", ret);
218 ok(errno == EINVAL, "Unexpected errno = %d\n", errno);
220
221 ret = _memicmp(s1, s2, 2);
222 ok(!ret, "got %d\n", ret);
223
224 ret = _memicmp(s1, s2, 3);
225 ok(ret == -1, "got %d\n", ret);
226}
227
228static void test__memicmp_l(void)
229{
230 static const char *s1 = "abc";
231 static const char *s2 = "aBd";
232 int ret;
233
234 ret = _memicmp_l(NULL, NULL, 0, NULL);
235 ok(!ret, "got %d\n", ret);
236
238 errno = 0xdeadbeef;
239 ret = _memicmp_l(NULL, NULL, 1, NULL);
240 ok(ret == _NLSCMPERROR, "got %d\n", ret);
241 ok(errno == EINVAL, "Unexpected errno = %d\n", errno);
243
245 errno = 0xdeadbeef;
246 ret = _memicmp_l(s1, NULL, 1, NULL);
247 ok(ret == _NLSCMPERROR, "got %d\n", ret);
248 ok(errno == EINVAL, "Unexpected errno = %d\n", errno);
250
252 errno = 0xdeadbeef;
253 ret = _memicmp_l(NULL, s2, 1, NULL);
254 ok(ret == _NLSCMPERROR, "got %d\n", ret);
255 ok(errno == EINVAL, "Unexpected errno = %d\n", errno);
257
258 ret = _memicmp_l(s1, s2, 2, NULL);
259 ok(!ret, "got %d\n", ret);
260
261 ret = _memicmp_l(s1, s2, 3, NULL);
262 ok(ret == -1, "got %d\n", ret);
263}
264
265
266static void test___strncnt(void)
267{
268 static const struct
269 {
270 const char *str;
271 size_t size;
272 size_t ret;
273 }
274 strncnt_tests[] =
275 {
276 { "a", 0, 0 },
277 { "a", 1, 1 },
278 { "a", 10, 1 },
279 { "abc", 1, 1 },
280 };
281 unsigned int i;
282 size_t ret;
283
284 for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
285 {
286 ret = __strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
287 ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
288 }
289
290 if (0) /* crashes */
291 {
292 ret = __strncnt(NULL, 0);
293 ret = __strncnt(NULL, 1);
294 }
295}
296
297static void test_C_locale(void)
298{
299 int i, j;
300 wint_t ret, exp;
302 static const char *locales[] = { NULL, "C" };
303
304 /* C locale only converts case for [a-zA-Z] */
305 setlocale(LC_ALL, "C");
306 for (i = 0; i <= 0xffff; i++)
307 {
308 ret = tolower(i);
309 if (i >= 'A' && i <= 'Z')
310 {
311 exp = i + 'a' - 'A';
312 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
313 }
314 else
315 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
316
317 ret = _tolower(i);
318 exp = i + 'a' - 'A';
319 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
320
321 ret = _o_tolower(i);
322 if (i >= 'A' && i <= 'Z')
323 {
324 exp = i + 'a' - 'A';
325 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
326 }
327 else
328 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
329
330 ret = towlower(i);
331 if (i >= 'A' && i <= 'Z')
332 {
333 exp = i + 'a' - 'A';
334 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
335 }
336 else
337 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
338
339 ret = toupper(i);
340 if (i >= 'a' && i <= 'z')
341 {
342 exp = i + 'A' - 'a';
343 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
344 }
345 else
346 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
347
348 ret = _toupper(i);
349 exp = i + 'A' - 'a';
350 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
351
352 ret = _o_toupper(i);
353 if (i >= 'a' && i <= 'z')
354 {
355 exp = i + 'A' - 'a';
356 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
357 }
358 else
359 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
360
361 ret = towupper(i);
362 if (i >= 'a' && i <= 'z')
363 {
364 exp = i + 'A' - 'a';
365 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
366 }
367 else
368 ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
369 }
370
371 for (i = 0; i < ARRAY_SIZE(locales); i++) {
372 locale = locales[i] ? _create_locale(LC_ALL, locales[i]) : NULL;
373
374 for (j = 0; j <= 0xffff; j++) {
376 if (j >= 'A' && j <= 'Z')
377 {
378 exp = j + 'a' - 'A';
379 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
380 }
381 else
382 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret);
383
385 if (j >= 'a' && j <= 'z')
386 {
387 exp = j + 'A' - 'a';
388 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
389 }
390 else
391 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret);
392 }
393
395 }
396}
397
398static void test_mbsspn( void)
399{
400 unsigned char str1[] = "cabernet";
401 unsigned char str2[] = "shiraz";
402 unsigned char set[] = "abc";
403 unsigned char empty[] = "";
404 unsigned char mbstr[] = " 2019\x94\x4e" "6\x8c\x8e" "29\x93\xfa";
405 unsigned char mbset1[] = "0123456789 \x94\x4e";
406 unsigned char mbset2[] = " \x94\x4e\x8c\x8e";
407 unsigned char mbset3[] = "\x8e";
408 int ret, cp = _getmbcp();
409
410 ret = _mbsspn(str1, set);
411 ok(ret == 3, "_mbsspn returns %d should be 3\n", ret);
412 ret = _mbsspn(str2, set);
413 ok(ret == 0, "_mbsspn returns %d should be 0\n", ret);
414 ret = _mbsspn(str1, empty);
415 ok(ret == 0, "_mbsspn returns %d should be 0\n", ret);
416
417 _setmbcp(932);
418 ret = _mbsspn(mbstr, mbset1);
419 ok(ret == 8, "_mbsspn returns %d should be 8\n", ret);
420 ret = _mbsspn(mbstr, mbset2);
421 ok(ret == 1, "_mbsspn returns %d should be 1\n", ret);
422 ret = _mbsspn(mbstr+8, mbset1);
423 ok(ret == 0, "_mbsspn returns %d should be 0\n", ret);
424 ret = _mbsspn(mbstr+8, mbset2);
425 ok(ret == 2, "_mbsspn returns %d should be 2\n", ret);
426 ret = _mbsspn(mbstr, mbset3);
427 ok(ret == 14, "_mbsspn returns %d should be 14\n", ret);
428
429 _setmbcp(cp);
430}
431
432static void test_wcstok(void)
433{
434 static const wchar_t *input = L"two words";
435 wchar_t buffer[16];
436 wchar_t *token;
437 wchar_t *next;
438
439 next = NULL;
441 token = wcstok(buffer, L" ", &next);
442 ok(!wcscmp(L"two", token), "expected \"two\", got \"%ls\"\n", token);
443 ok(next == token + 4, "expected %p, got %p\n", token + 4, next);
444 token = wcstok(NULL, L" ", &next);
445 ok(!wcscmp(L"words", token), "expected \"words\", got \"%ls\"\n", token);
446 ok(next == token + 5, "expected %p, got %p\n", token + 5, next);
447 token = wcstok(NULL, L" ", &next);
448 ok(!token, "expected NULL, got %p\n", token);
449
451 token = wcstok(buffer, L" ", NULL);
452 ok(!wcscmp(L"two", token), "expected \"two\", got \"%ls\"\n", token);
453 token = wcstok(NULL, L" ", NULL);
454 ok(!wcscmp(L"words", token), "expected \"words\", got \"%ls\"\n", token);
455 token = wcstok(NULL, L" ", NULL);
456 ok(!token, "expected NULL, got %p\n", token);
457
458 next = NULL;
460 token = wcstok(buffer, L"=", &next);
461 ok(!wcscmp(token, input), "expected \"%ls\", got \"%ls\"\n", input, token);
462 ok(next == buffer + wcslen(input), "expected %p, got %p\n", buffer + wcslen(input), next);
463 token = wcstok(NULL, L"=", &next);
464 ok(!token, "expected NULL, got \"%ls\"\n", token);
465 ok(next == buffer + wcslen(input), "expected %p, got %p\n", buffer + wcslen(input), next);
466
467 next = NULL;
468 wcscpy(buffer, L"");
469 token = wcstok(buffer, L"=", &next);
470 ok(token == NULL, "expected NULL, got \"%ls\"\n", token);
471 ok(next == buffer, "expected %p, got %p\n", buffer, next);
472 token = wcstok(NULL, L"=", &next);
473 ok(!token, "expected NULL, got \"%ls\"\n", token);
474 ok(next == buffer, "expected %p, got %p\n", buffer, next);
475}
476
477static void test__strnicmp(void)
478{
479 static const char str1[] = "TEST";
480 static const char str2[] = "test";
481 int ret;
482
484 errno = 0xdeadbeef;
485 ret = _strnicmp(str1, NULL, 2);
487 ok(ret == _NLSCMPERROR, "got %d.\n", ret);
488 ok(errno == EINVAL, "Unexpected errno %d.\n", errno);
489
491 errno = 0xdeadbeef;
492 ret = _strnicmp(str1, str2, -1);
494 ok(ret == _NLSCMPERROR, "got %d.\n", ret);
495 ok(errno == EINVAL, "Unexpected errno %d.\n", errno);
496
497 ret = _strnicmp(str1, str2, 0);
498 ok(!ret, "got %d.\n", ret);
499
500 ret = _strnicmp(str1, str2, 0x7fffffff);
501 ok(!ret, "got %d.\n", ret);
502
503 /* If numbers of characters to compare is too big return error */
505 errno = 0xdeadbeef;
506 ret = _strnicmp(str1, str2, 0x80000000);
508 ok(ret == _NLSCMPERROR, "got %d.\n", ret);
509 ok(errno == EINVAL, "Unexpected errno %d.\n", errno);
510}
511
512static void test_wcsnicmp(void)
513{
514 static const wchar_t str1[] = L"TEST";
515 static const wchar_t str2[] = L"test";
516 int ret;
517
518 errno = 0xdeadbeef;
519 ret = wcsnicmp(str1, str2, -1);
520 ok(!ret, "got %d.\n", ret);
521
522 ret = wcsnicmp(str1, str2, 0x7fffffff);
523 ok(!ret, "got %d.\n", ret);
524}
525
526static void test_SpecialCasing(void)
527{
528 int i;
529 wint_t ret, exp;
531 struct test {
532 const char *lang;
533 wint_t ch;
534 wint_t exp;
535 };
536
537 struct test ucases[] = {
538 {"English", 'I', 'i'}, /* LATIN CAPITAL LETTER I */
539 {"English", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
540
541 {"Turkish", 'I', 'i'}, /* LATIN CAPITAL LETTER I */
542 {"Turkish", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
543 };
544 struct test lcases[] = {
545 {"English", 'i', 'I'}, /* LATIN SMALL LETTER I */
546 {"English", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */
547
548 {"Turkish", 'i', 'I'}, /* LATIN SMALL LETTER I */
549 {"Turkish", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */
550 };
551
552 for (i = 0; i < ARRAY_SIZE(ucases); i++) {
553 if (!setlocale(LC_ALL, ucases[i].lang)) {
554 win_skip("skipping special case tests for %s\n", ucases[i].lang);
555 continue;
556 }
557
558 ret = towlower(ucases[i].ch);
559 exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch;
560 ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", exp, ret, ucases[i].lang);
561 }
562
563 for (i = 0; i < ARRAY_SIZE(lcases); i++) {
564 if (!setlocale(LC_ALL, lcases[i].lang)) {
565 win_skip("skipping special case tests for %s\n", lcases[i].lang);
566 continue;
567 }
568
569 ret = towupper(lcases[i].ch);
570 exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch;
571 ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", exp, ret, lcases[i].lang);
572 }
573
574 setlocale(LC_ALL, "C");
575
576 /* test _towlower_l creating locale */
577 for (i = 0; i < ARRAY_SIZE(ucases); i++) {
578 if (!(locale = _create_locale(LC_ALL, ucases[i].lang))) {
579 win_skip("locale %s not available. skipping\n", ucases[i].lang);
580 continue;
581 }
582
583 ret = _towlower_l(ucases[i].ch, locale);
584 exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch;
585 ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", exp, ret, ucases[i].lang);
586
588 }
589
590 /* test _towupper_l creating locale */
591 for (i = 0; i < ARRAY_SIZE(lcases); i++) {
592 if (!(locale = _create_locale(LC_ALL, lcases[i].lang))) {
593 win_skip("locale %s not available. skipping\n", lcases[i].lang);
594 continue;
595 }
596
597 ret = _towupper_l(lcases[i].ch, locale);
598 exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch;
599 ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", exp, ret, lcases[i].lang);
600
602 }
603}
604
605static void test__mbbtype_l(void)
606{
607 int expected, ret;
608 unsigned int c;
609
611 for (c = 0; c < 256; ++c)
612 {
613 expected = _mbbtype(c, 0);
614 ret = _mbbtype_l(c, 0, NULL);
615 ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected);
616
617 expected = _mbbtype(c, 1);
618 ret = _mbbtype_l(c, 1, NULL);
619 ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected);
620 }
621}
622
623static void test_strcmp(void)
624{
625 int ret = strcmp( "abc", "abcd" );
626 ok( ret == -1, "wrong ret %d\n", ret );
627 ret = strcmp( "", "abc" );
628 ok( ret == -1, "wrong ret %d\n", ret );
629 ret = strcmp( "abc", "ab\xa0" );
630 ok( ret == -1, "wrong ret %d\n", ret );
631 ret = strcmp( "ab\xb0", "ab\xa0" );
632 ok( ret == 1, "wrong ret %d\n", ret );
633 ret = strcmp( "ab\xc2", "ab\xc2" );
634 ok( ret == 0, "wrong ret %d\n", ret );
635
636 ret = strncmp( "abc", "abcd", 3 );
637 ok( ret == 0, "wrong ret %d\n", ret );
638 ret = strncmp( "", "abc", 3 );
639 ok( ret == -1, "wrong ret %d\n", ret );
640 ret = strncmp( "abc", "ab\xa0", 4 );
641 ok( ret == -1, "wrong ret %d\n", ret );
642 ret = strncmp( "ab\xb0", "ab\xa0", 3 );
643 ok( ret == 1, "wrong ret %d\n", ret );
644 ret = strncmp( "ab\xb0", "ab\xa0", 2 );
645 ok( ret == 0, "wrong ret %d\n", ret );
646 ret = strncmp( "ab\xc2", "ab\xc2", 3 );
647 ok( ret == 0, "wrong ret %d\n", ret );
648 ret = strncmp( "abc", "abd", 0 );
649 ok( ret == 0, "wrong ret %d\n", ret );
650 ret = strncmp( "abc", "abc", 12 );
651 ok( ret == 0, "wrong ret %d\n", ret );
652}
653
654#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, \
655 "Binary buffer mismatch - expected %s, got %s\n", \
656 debugstr_an(value, len), debugstr_an((char *)(buf), len)); }
657
658static void test__mbsncpy_s(void)
659{
660 unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5\x0";
661 unsigned char *mbstring2 = (unsigned char *)"\xb0\x0";
662 unsigned char buf[16];
663 errno_t err;
664 int oldcp;
665
666 oldcp = _getmbcp();
667 if (_setmbcp(936))
668 {
669 skip("Code page 936 is not available, skipping test.\n");
670 return;
671 }
672
673 errno = 0xdeadbeef;
674 memset(buf, 0xcc, sizeof(buf));
675 err = _mbsncpy_s(NULL, 0, mbstring, 0);
676 ok(errno == 0xdeadbeef, "got %d\n", errno);
677 ok(!err, "got %d.\n", err);
678
679 errno = 0xdeadbeef;
680 memset(buf, 0xcc, sizeof(buf));
681 err = _mbsncpy_s(buf, 6, mbstring, 1);
682 ok(errno == 0xdeadbeef, "got %d\n", errno);
683 ok(!err, "got %d.\n", err);
684 expect_bin(buf, "\xb0\xb1\0\xcc", 4);
685
686 memset(buf, 0xcc, sizeof(buf));
687 errno = 0xdeadbeef;
688 err = _mbsncpy_s(buf, 6, mbstring, 2);
689 ok(errno == 0xdeadbeef, "got %d\n", errno);
690 ok(!err, "got %d.\n", err);
691 expect_bin(buf, "\xb0\xb1\xb2\xb3\0\xcc", 6);
692
693 errno = 0xdeadbeef;
694 memset(buf, 0xcc, sizeof(buf));
695 err = _mbsncpy_s(buf, 2, mbstring, _TRUNCATE);
696 ok(errno == 0xdeadbeef, "got %d\n", errno);
697 ok(err == STRUNCATE, "got %d.\n", err);
698 expect_bin(buf, "\x00\xb1\xcc", 3);
699
700 memset(buf, 0xcc, sizeof(buf));
702 errno = 0xdeadbeef;
703 err = _mbsncpy_s(buf, 2, mbstring, 1);
704 ok(errno == err, "got %d.\n", errno);
706 ok(err == ERANGE, "got %d.\n", err);
707 expect_bin(buf, "\x0\xcc\xcc", 3);
708
709 memset(buf, 0xcc, sizeof(buf));
711 errno = 0xdeadbeef;
712 err = _mbsncpy_s(buf, 2, mbstring, 3);
713 ok(errno == err, "got %d\n", errno);
715 ok(err == ERANGE, "got %d.\n", err);
716 expect_bin(buf, "\x0\xcc\xcc", 3);
717
718 memset(buf, 0xcc, sizeof(buf));
720 errno = 0xdeadbeef;
721 err = _mbsncpy_s(buf, 1, mbstring, 3);
722 ok(errno == err, "got %d\n", errno);
724 ok(err == ERANGE, "got %d.\n", err);
725 expect_bin(buf, "\x0\xcc", 2);
726
727 memset(buf, 0xcc, sizeof(buf));
729 errno = 0xdeadbeef;
730 err = _mbsncpy_s(buf, 0, mbstring, 3);
731 ok(errno == err, "got %d\n", errno);
733 ok(err == EINVAL, "got %d.\n", err);
734 expect_bin(buf, "\xcc", 1);
735
736 memset(buf, 0xcc, sizeof(buf));
738 errno = 0xdeadbeef;
739 err = _mbsncpy_s(buf, 0, mbstring, 0);
740 ok(errno == err, "got %d\n", errno);
742 ok(err == EINVAL, "got %d.\n", err);
743 expect_bin(buf, "\xcc", 1);
744
745 memset(buf, 0xcc, sizeof(buf));
746 errno = 0xdeadbeef;
747 err = _mbsncpy_s(buf, -1, mbstring, 0);
748 ok(errno == 0xdeadbeef, "got %d\n", errno);
749 ok(!err, "got %d.\n", err);
750 expect_bin(buf, "\x0\xcc", 2);
751
752 memset(buf, 0xcc, sizeof(buf));
753 errno = 0xdeadbeef;
754 err = _mbsncpy_s(buf, -1, mbstring, 256);
755 ok(errno == 0xdeadbeef, "got %d\n", errno);
756 ok(!err, "got %d.\n", err);
757 expect_bin(buf, "\xb0\xb1\xb2\xb3Q\xb4\xb5\x0\xcc", 9);
758
759 memset(buf, 0xcc, sizeof(buf));
760 errno = 0xdeadbeef;
761 err = _mbsncpy_s(buf, 1, mbstring2, 4);
762 ok(errno == err, "got %d\n", errno);
763 ok(err == EILSEQ, "got %d.\n", err);
764 expect_bin(buf, "\x0\xcc", 2);
765
766 memset(buf, 0xcc, sizeof(buf));
767 errno = 0xdeadbeef;
768 err = _mbsncpy_s(buf, 2, mbstring2, 4);
769 ok(errno == err, "got %d\n", errno);
770 ok(err == EILSEQ, "got %d.\n", err);
771 expect_bin(buf, "\x0\xcc", 2);
772
773 memset(buf, 0xcc, sizeof(buf));
774 errno = 0xdeadbeef;
775 err = _mbsncpy_s(buf, 1, mbstring2, _TRUNCATE);
776 ok(errno == 0xdeadbeef, "got %d\n", errno);
777 ok(err == STRUNCATE, "got %d.\n", err);
778 expect_bin(buf, "\x0\xcc", 2);
779
780 memset(buf, 0xcc, sizeof(buf));
781 errno = 0xdeadbeef;
782 err = _mbsncpy_s(buf, 2, mbstring2, _TRUNCATE);
783 ok(errno == 0xdeadbeef, "got %d\n", errno);
784 ok(!err, "got %d.\n", err);
785 expect_bin(buf, "\xb0\x0\xcc", 3);
786
787 memset(buf, 0xcc, sizeof(buf));
788 errno = 0xdeadbeef;
789 err = _mbsncpy_s(buf, 1, mbstring2, 1);
790 ok(errno == err, "got %d\n", errno);
791 ok(err == EILSEQ, "got %d.\n", err);
792 expect_bin(buf, "\x0\xcc", 2);
793
794 memset(buf, 0xcc, sizeof(buf));
795 errno = 0xdeadbeef;
796 err = _mbsncpy_s(buf, 2, mbstring2, 1);
797 ok(errno == err, "got %d\n", errno);
798 ok(err == EILSEQ, "got %d.\n", err);
799 expect_bin(buf, "\x0\xcc", 2);
800
801 memset(buf, 0xcc, sizeof(buf));
802 errno = 0xdeadbeef;
803 err = _mbsncpy_s(buf, 3, mbstring2, 1);
804 ok(errno == err, "got %d\n", errno);
805 ok(err == EILSEQ, "got %d.\n", err);
806 expect_bin(buf, "\x0\xcc", 2);
807
808 memset(buf, 0xcc, sizeof(buf));
809 errno = 0xdeadbeef;
810 err = _mbsncpy_s(buf, 3, mbstring2, 2);
811 ok(errno == err, "got %d\n", errno);
812 ok(err == EILSEQ, "got %d.\n", err);
813 expect_bin(buf, "\x0\xcc", 2);
814
815 _setmbcp(oldcp);
816}
817
818static void test_mbstowcs(void)
819{
820 static const char mbs[] = { 0xc3, 0xa9, 0 };
821 WCHAR wcs[2];
822 size_t ret;
823
824 if (!setlocale(LC_ALL, "en_US.UTF-8"))
825 {
826 win_skip("skipping UTF8 mbstowcs tests\n");
827 return;
828 }
829
830 ret = mbstowcs(NULL, mbs, 0);
831 ok(ret == 1, "mbstowcs returned %Id\n", ret);
832 memset(wcs, 0xfe, sizeof(wcs));
833 ret = mbstowcs(wcs, mbs, 1);
834 ok(ret == 1, "mbstowcs returned %Id\n", ret);
835 ok(wcs[0] == 0xe9, "wcsstring[0] = %x\n", wcs[0]);
836 ok(wcs[1] == 0xfefe, "wcsstring[1] = %x\n", wcs[1]);
837 setlocale(LC_ALL, "C");
838}
839
841{
843 "Invalid parameter handler was already set\n");
844
845 test_strtod();
846 test_strtof();
851 test_mbsspn();
852 test_wcstok();
857 test_strcmp();
860}
int wint_t
Definition: _apple.h:38
static _invalid_parameter_handler invalid_parameter_handler
#define EINVAL
Definition: acclib.h:90
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int toupper(int c)
Definition: utclib.c:881
#define ERANGE
Definition: acclib.h:92
int tolower(int c)
Definition: utclib.c:902
#define __cdecl
Definition: accygwin.h:79
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define ARRAY_SIZE(A)
Definition: main.h:20
Definition: _locale.h:75
Definition: _set.h:50
wcscpy
_CRTIMP int __cdecl _getmbcp(void)
Definition: locale.c:1474
#define NULL
Definition: types.h:112
static const WCHAR empty[]
Definition: main.c:47
#define wcsnicmp
Definition: compat.h:14
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
_Check_return_ _CRTIMP wint_t __cdecl _towupper_l(_In_ wint_t c, _In_opt_ _locale_t locale)
Definition: stubs.c:614
_Must_inspect_result_ _CRTIMP int __cdecl _memicmp_l(_In_reads_bytes_opt_(size) const void *buf1, _In_reads_bytes_opt_(size) const void *buf2, _In_ size_t size, _In_opt_ _locale_t locale)
Definition: stubs.c:458
_Check_return_ _CRTIMP wint_t __cdecl _towlower_l(_In_ wint_t c, _In_opt_ _locale_t locale)
Definition: stubs.c:602
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint end
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
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 token
Definition: glfuncs.h:210
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 _tolower(_Char)
Definition: ctype.h:654
#define _toupper(_Char)
Definition: ctype.h:655
_Check_return_opt_ _locale_t __cdecl _create_locale(_In_ int _Category, _In_z_ const char *_Locale)
#define LC_ALL
Definition: locale.h:17
void __cdecl _free_locale(_In_opt_ _locale_t _Locale)
#define INFINITY
Definition: math.h:56
_Check_return_ _CRTIMP size_t __cdecl _mbsspn(_In_z_ const unsigned char *_Str, _In_z_ const unsigned char *_Control)
_Check_return_ _CRTIMP int __cdecl _mbbtype(_In_ unsigned char _Ch, _In_ int _CType)
_Check_return_ _CRTIMP int __cdecl _mbbtype_l(_In_ unsigned char _Ch, _In_ int _CType, _In_opt_ _locale_t _Locale)
_invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_In_opt_ _invalid_parameter_handler _Handler)
_Check_return_ double __cdecl strtod(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr)
float __cdecl strtof(const char *nptr, char **endptr)
Definition: strtod.cpp:55
_CRTIMP size_t __cdecl __strncnt(const char *_Str, size_t _Cnt)
Definition: strncnt.cpp:13
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
mbstowcs
Definition: stdlib.h:925
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
#define c
Definition: ke_i.h:80
POINT cp
Definition: magnifier.c:59
struct S1 s1
struct S2 s2
unsigned int uintptr_t
Definition: intrin.h:47
char string[160]
Definition: util.h:11
static struct test_info tests[]
BOOL expected
Definition: store.c:2063
#define NAN
Definition: mesh.c:39
int __cdecl _setmbcp(int)
Definition: _setmbcp.c:218
#define _MB_CP_LOCALE
Definition: msvcrt.h:831
static void test_C_locale(void)
Definition: string.c:4537
static void test_SpecialCasing(void)
Definition: string.c:4726
static void test___strncnt(void)
Definition: string.c:4502
#define expect_bin(buf, value, len)
Definition: string.c:57
static void test_strcmp(void)
Definition: string.c:717
static void test__memicmp(void)
Definition: string.c:4116
static void test_mbsspn(void)
Definition: string.c:612
static char int
Definition: string.c:79
static void test__memicmp_l(void)
Definition: string.c:4151
static void test_mbstowcs(void)
Definition: string.c:2183
static void test_invalid_parameter_handler(void)
Definition: misc.c:384
_ACRTIMP int __cdecl _o_tolower(int)
#define SET_EXPECT(func)
Definition: string.c:37
static void _test_strtod_str(int line, const char *string, double value, int length, int err)
Definition: string.c:82
static void test_wcstok(void)
Definition: string.c:432
#define test_strtod_str(string, value, length)
Definition: string.c:81
static void test__strnicmp(void)
Definition: string.c:477
static void test_strtof(void)
Definition: string.c:155
#define CHECK_EXPECT(func)
Definition: string.c:46
#define DEFINE_EXPECT(func)
Definition: string.c:34
_ACRTIMP int __cdecl _o_toupper(int)
#define test_strtod_str_errno(string, value, length, err)
Definition: string.c:80
static void test_wcsnicmp(void)
Definition: string.c:512
static void test__mbbtype_l(void)
Definition: string.c:605
#define CHECK_CALLED(func)
Definition: string.c:52
static void test_strtod(void)
Definition: string.c:99
static void test__mbsncpy_s(void)
Definition: string.c:658
static BOOL local_isnan(double d)
Definition: string.c:75
DWORD exp
Definition: msg.c:16058
#define L(x)
Definition: ntvdm.h:50
static unsigned __int64 next
Definition: rand_nt.c:6
#define err(...)
#define test
Definition: rosglue.h:37
const WCHAR * str
#define STRUNCATE
Definition: errno.h:110
#define errno
Definition: errno.h:18
#define EILSEQ
Definition: errno.h:109
_Check_return_ _CRTIMP int __cdecl _memicmp(_In_reads_bytes_opt_(_Size) const void *_Buf1, _In_reads_bytes_opt_(_Size) const void *_Buf2, _In_ size_t _Size)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define _NLSCMPERROR
Definition: string.h:19
_CRT_RESTORE_GCC_WARNINGS _Check_return_ _CRTIMP wchar_t *__cdecl wcstok(_Inout_opt_z_ wchar_t *_Str, _In_z_ const wchar_t *_Delim)
#define win_skip
Definition: test.h:164
#define memset(x, y, z)
Definition: compat.h:39
Definition: fci.c:127
Definition: parser.c:49
#define setlocale(n, s)
Definition: locale.h:46
#define towlower(c)
Definition: wctype.h:97
#define towupper(c)
Definition: wctype.h:99
int errno_t
Definition: corecrt.h:615
#define _TRUNCATE
Definition: corecrt.h:278
#define _ACRTIMP
Definition: corecrt.h:138
Definition: pdh_main.c:96
static const WCHAR lang[]
Definition: wbemdisp.c:287
char mbs[5]
int ret
wchar_t wcs[5]
__wchar_t WCHAR
Definition: xmlstorage.h:180