ReactOS 0.4.15-dev-7958-gcd0bb1a
CharFuncs.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for Char* functions
5 * COPYRIGHT: Copyright 2022 Stanislav Motylkov <x86corez@gmail.com>
6 */
7
8#include "precomp.h"
9
10#include <winnls.h>
11#include <ndk/rtlfuncs.h>
12#include <pseh/pseh2.h>
13#include <strsafe.h>
14#include <versionhelpers.h>
15
16#define INVALID_PTR_OFF(x) ((PVOID)(ULONG_PTR)(0xdeadbeefdeadbeefULL + x))
17#define INVALID_PTR INVALID_PTR_OFF(0)
18
19/* Default code page to be tested */
20#define TEST_ACP 1252
21
22typedef enum
23{
27} TEST_TYPE;
28
29/* Dynamic allocation tests */
30typedef struct
31{
33 LPWSTR lpszStart; /* Specified string for szStart */
34 LPWSTR lpszCurrent; /* Specified string for szCurrent (only when testType == testBoth) */
35 INT iOffset; /* Specified offset to test (only when testType == testOffs) */
36 INT iResOffset; /* Expected offset when szCurrent >= szStart */
37 INT iResOffsetNeg; /* Expected offset when szCurrent < szStart */
38 BOOL bWithinStart; /* TRUE for pointer expected to be within szStart, FALSE for within szCurrent */
39 BOOL bWideOnly; /* Perform test only for Unicode case */
41
43{
44 {testLen, L"C:\\ReactOS", NULL, 0, 9, 9, TRUE, FALSE},
45 {testOffs, L"abcdefghijk", NULL, 11, 10, 10, TRUE, FALSE},
46 {testOffs, L"test a´^~¯", NULL, 10, 9, 9, TRUE, FALSE},
47 {testOffs, L"test å", NULL, 6, 5, 5, TRUE, FALSE},
48 {testBoth, L"C:\\ReactOS", L"", 0, -1, 0, FALSE, FALSE},
49 {testBoth, L"C:\\ReactOS\\", L"C:\\ReactOS", 0, -1, 0, FALSE, FALSE},
50 {testBoth, L"C:\\ReactOS\\", L"ReactOS", 0, -1, 0, FALSE, FALSE},
51};
52
54{
55 /* XP/2003 treat diacritics as normal characters */
56 {testOffs, L"test a\x030a", NULL, 7, 6, 6, TRUE, TRUE},
57 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 10, 9, 9, TRUE, TRUE},
58 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 9, 8, 8, TRUE, TRUE},
59 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 8, 7, 7, TRUE, TRUE},
60 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 7, 6, 6, TRUE, TRUE},
61};
62
64{
65 /* Vista+ does respect diacritics and skip them */
66 {testOffs, L"test a\x030a", NULL, 7, 5, 5, TRUE, TRUE},
67 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 10, 5, 5, TRUE, TRUE},
68 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 9, 5, 5, TRUE, TRUE},
69 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 8, 5, 5, TRUE, TRUE},
70 {testOffs, L"test a\x0301\x0302\x0303\x0304", NULL, 7, 5, 5, TRUE, TRUE},
71};
72
73/* Static tests */
74static const WCHAR wszReactOS[] = L"C:\\ReactOS";
75static const CHAR szReactOS[] = "C:\\ReactOS";
76static const WCHAR wszSpecial[] = L"test\0\0\0\0\0\0aa\t\t\t\r\n\r\n";
77static const CHAR szSpecial[] = "test\0\0\0\0\0\0aa\t\t\t\r\n\r\n";
78static const WCHAR wszMagic1[] = L"test a\x030a";
79static const WCHAR wszMagic2[] = L"test a\x0301\x0302\x0303\x0304";
80
81static const CHAR szUTF8Cyril[] = "test \xD1\x82\xD0\xB5\xD1\x81\xD1\x82"; /* UTF8(L"test тест") */
82static const CHAR szUTF8Greek[] = "test \xCF\x84\xCE\xB5\xCF\x83\xCF\x84"; /* UTF8(L"test τεστ") */
83static const CHAR szUTF8Japan[] = "test \xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88"; /* UTF8(L"test テスト") */
84static const CHAR szCP932Japan[] = "test \x83\x65\x83\x58\x83\x67"; /* CP932(L"test テスト") */
85
86typedef struct
87{
95
97{
103 szReactOS, szReactOS + 2, szReactOS + 1},
105 szReactOS, szReactOS + 3, szReactOS + 2},
106 {wszReactOS, wszReactOS + 10, wszReactOS + 9,
107 szReactOS, szReactOS + 10, szReactOS + 9},
108
111 {wszReactOS + 2, wszReactOS + 1, wszReactOS + 1,
112 szReactOS + 2, szReactOS + 1, szReactOS + 1},
113 {wszReactOS + 2, wszReactOS + 2, wszReactOS + 2,
114 szReactOS + 2, szReactOS + 2, szReactOS + 2},
115 {wszReactOS + 2, wszReactOS + 3, wszReactOS + 2,
116 szReactOS + 2, szReactOS + 3, szReactOS + 2},
117 {wszReactOS + 2, wszReactOS + 4, wszReactOS + 3,
118 szReactOS + 2, szReactOS + 4, szReactOS + 3},
119
120 /* Test null-terminators */
122 szSpecial, szSpecial + 8, szSpecial + 7},
123
124 /* Test tabulation */
125 {wszSpecial, wszSpecial + 13, wszSpecial + 12,
126 szSpecial, szSpecial + 13, szSpecial + 12},
127
128 /* Test linebreak */
129 {wszSpecial, wszSpecial + 17, wszSpecial + 16,
130 szSpecial, szSpecial + 17, szSpecial + 16},
131 {wszSpecial, wszSpecial + 18, wszSpecial + 17,
132 szSpecial, szSpecial + 18, szSpecial + 17},
133};
134
136{
137 /* XP/2003 treat diacritics as normal characters */
138 {wszMagic1, wszMagic1 + 7, wszMagic1 + 6,
139 NULL, NULL, NULL},
140 {wszMagic2, wszMagic2 + 10, wszMagic2 + 9,
141 NULL, NULL, NULL},
142 {wszMagic2, wszMagic2 + 9, wszMagic2 + 8,
143 NULL, NULL, NULL},
144 {wszMagic2, wszMagic2 + 8, wszMagic2 + 7,
145 NULL, NULL, NULL},
146 {wszMagic2, wszMagic2 + 7, wszMagic2 + 6,
147 NULL, NULL, NULL},
148};
149
151{
152 /* Vista+ does respect diacritics and skip them */
153 {wszMagic1, wszMagic1 + 7, wszMagic1 + 5,
154 NULL, NULL, NULL},
155 {wszMagic2, wszMagic2 + 10, wszMagic2 + 5,
156 NULL, NULL, NULL},
157 {wszMagic2, wszMagic2 + 9, wszMagic2 + 5,
158 NULL, NULL, NULL},
159 {wszMagic2, wszMagic2 + 8, wszMagic2 + 5,
160 NULL, NULL, NULL},
161 {wszMagic2, wszMagic2 + 7, wszMagic2 + 5,
162 NULL, NULL, NULL},
163};
164
165typedef struct
166{
172
174{
175 /* UTF-8 characters are not properly counted */
179
182
185
186 /* Code Page 932 / Shift-JIS characters are properly counted */
187 {932, szCP932Japan, szCP932Japan + 2, szCP932Japan + 1},
188 {932, szCP932Japan, szCP932Japan + 7, szCP932Japan + 5},
189 {932, szCP932Japan, szCP932Japan + 9, szCP932Japan + 7},
190};
191
192typedef struct
193{
199
201{
203 szReactOS, szReactOS + 1},
204 {wszReactOS + 1, wszReactOS + 2,
205 szReactOS + 1, szReactOS + 2},
206 {wszReactOS + 2, wszReactOS + 3,
207 szReactOS + 2, szReactOS + 3},
208 {wszReactOS + 9, wszReactOS + 10,
209 szReactOS + 9, szReactOS + 10},
210 {wszReactOS + 10, wszReactOS + 10,
211 szReactOS + 10, szReactOS + 10},
212
213 /* Test null-terminators */
214 {wszSpecial + 3, wszSpecial + 4,
215 szSpecial + 3, szSpecial + 4},
216 {wszSpecial + 4, wszSpecial + 4,
217 szSpecial + 4, szSpecial + 4},
218 {wszSpecial + 5, wszSpecial + 5,
219 szSpecial + 5, szSpecial + 5},
220
221 /* Test tabulation */
222 {wszSpecial + 12, wszSpecial + 13,
223 szSpecial + 12, szSpecial + 13},
224
225 /* Test linebreak */
226 {wszSpecial + 15, wszSpecial + 16,
227 szSpecial + 15, szSpecial + 16},
228 {wszSpecial + 16, wszSpecial + 17,
229 szSpecial + 16, szSpecial + 17},
230};
231
233{
234 /* XP/2003 treat diacritics as normal characters */
235 {wszMagic1 + 5, wszMagic1 + 6,
236 NULL, NULL},
237 {wszMagic2 + 5, wszMagic2 + 6,
238 NULL, NULL},
239 {wszMagic2 + 6, wszMagic2 + 7,
240 NULL, NULL},
241 {wszMagic2 + 7, wszMagic2 + 8,
242 NULL, NULL},
243 {wszMagic2 + 8, wszMagic2 + 9,
244 NULL, NULL},
245};
246
248{
249 /* Vista+ does respect diacritics and skip them */
250 {wszMagic1 + 5, wszMagic1 + 7,
251 NULL, NULL},
252 {wszMagic2 + 5, wszMagic2 + 10,
253 NULL, NULL},
254 {wszMagic2 + 6, wszMagic2 + 10,
255 NULL, NULL},
256 {wszMagic2 + 7, wszMagic2 + 10,
257 NULL, NULL},
258 {wszMagic2 + 8, wszMagic2 + 10,
259 NULL, NULL},
260};
261
262typedef struct
263{
268
270{
271 /* UTF-8 characters are not properly counted */
273 {CP_UTF8, szUTF8Cyril + 4, szUTF8Cyril + 5},
274 {CP_UTF8, szUTF8Cyril + 5, szUTF8Cyril + 6},
275 {CP_UTF8, szUTF8Cyril + 7, szUTF8Cyril + 8},
276
277 {CP_UTF8, szUTF8Greek + 5, szUTF8Greek + 6},
278 {CP_UTF8, szUTF8Greek + 7, szUTF8Greek + 8},
279
280 {CP_UTF8, szUTF8Japan + 5, szUTF8Japan + 6},
281 {CP_UTF8, szUTF8Japan + 8, szUTF8Japan + 9},
282
283 /* Code Page 932 / Shift-JIS characters are properly counted */
284 {932, szCP932Japan, szCP932Japan + 1},
285 {932, szCP932Japan + 5, szCP932Japan + 7},
286 {932, szCP932Japan + 7, szCP932Japan + 9},
287};
288
289/* Exception tests (corner cases) */
290typedef struct
291{
301
303{
307 {NULL, NULL, NULL,
308 NULL, NULL, NULL, NULL,
313
317 {NULL, NULL, NULL,
318 NULL, NULL, NULL, NULL,
321 NULL, INVALID_PTR, INVALID_PTR_OFF(-1) /* NULL on Win7 with updates */, NULL,
323
325 szReactOS, INVALID_PTR, INVALID_PTR_OFF(-1) /* NULL on Win7 with updates */, NULL,
333
335 INVALID_PTR_OFF(-2), INVALID_PTR, INVALID_PTR_OFF(-1) /* NULL on Win7 with updates */, NULL,
338 INVALID_PTR, INVALID_PTR_OFF(2), INVALID_PTR_OFF(1) /* NULL on Win7 with updates */, NULL,
346};
347
348typedef struct
349{
356
358{
360 szReactOS, szReactOS + 1,
362 {NULL, NULL,
363 NULL, NULL,
368
369 {INVALID_PTR_OFF(-2), NULL,
375};
376
378{
379 LPWSTR str;
380 SIZE_T sz;
381
382 if (!lpszStr)
383 return NULL;
384
385 sz = (len + 1) * sizeof(lpszStr[0]);
387 if (!str)
388 {
389 trace("HeapAlloc failed (error %ld)\n", GetLastError());
390 goto Skip;
391 }
392 StringCbCopyW(str, sz, lpszStr);
393Skip:
394 return str;
395}
396
398{
399 LPSTR str;
400 SIZE_T sz, mbs;
401
402 if (!lpszStr)
403 return NULL;
404
405 sz = len + 1;
407 if (!str)
408 {
409 trace("HeapAlloc failed (error %ld)\n", GetLastError());
410 goto Skip;
411 }
412
413 mbs = WideCharToMultiByte(TEST_ACP, 0, lpszStr, -1, NULL, 0, NULL, NULL);
414 if (!mbs || mbs > sz)
415 {
417 str = NULL;
418 trace("WideCharToMultiByte returned %lu (error %ld)\n", mbs, GetLastError());
419 goto Skip;
420 }
421
422 WideCharToMultiByte(TEST_ACP, 0, lpszStr, -1, str, mbs, NULL, NULL);
423Skip:
424 return str;
425}
426
428{
429 LPWSTR wszStart, wszCurrent;
430 LPWSTR pchW;
431 INT iRealOffset;
432 BOOL b;
433
434 wszStart = AllocStringW(pEntry->lpszStart, len);
435 if (!wszStart && pEntry->lpszStart)
436 {
437 skip("[%u] AllocStringW for wszStart failed\n", i);
438 goto Cleanup;
439 }
440 if (pEntry->testType == testLen)
441 wszCurrent = wszStart + len;
442 else if (pEntry->testType == testOffs)
443 wszCurrent = wszStart + pEntry->iOffset;
444 else
445 {
446 wszCurrent = AllocStringW(pEntry->lpszCurrent, wcslen(pEntry->lpszCurrent));
447 if (!wszCurrent && pEntry->lpszCurrent)
448 {
449 skip("[%u] AllocStringW for wszCurrent failed\n", i);
450 goto Cleanup;
451 }
452 }
453 pchW = CharPrevW(wszStart, wszCurrent);
454 if (wszCurrent - wszStart >= 0)
455 iRealOffset = pEntry->iResOffset;
456 else
457 iRealOffset = pEntry->iResOffsetNeg;
458 if (pEntry->bWithinStart)
459 {
460 b = pchW >= wszStart && pchW <= wszStart + len;
461 if (iRealOffset >= 0)
462 ok(b, "[%u] CharPrevW: pchW (0x%p) is expected to be within wszStart (0x%p)\n", i, pchW, wszStart);
463 else
464 ok(!b, "[%u] CharPrevW: pchW (0x%p) is expected to be outside wszStart (0x%p)\n", i, pchW, wszStart);
465 ok(pchW == wszStart + iRealOffset, "[%u] CharPrevW: pchW is 0x%p (offset %d)\n", i, pchW, pchW - wszStart);
466 }
467 else
468 {
469 b = pchW >= wszCurrent && pchW <= wszCurrent + wcslen(pEntry->lpszCurrent);
470 if (iRealOffset >= 0)
471 ok(b, "[%u] CharPrevW: pchW (0x%p) is expected to be within wszCurrent (0x%p)\n", i, pchW, wszCurrent);
472 else
473 ok(!b, "[%u] CharPrevW: pchW (0x%p) is expected to be outside wszCurrent (0x%p)\n", i, pchW, wszCurrent);
474 ok(pchW == wszCurrent + iRealOffset, "[%u] CharPrevW: pchW is 0x%p (offset %d)\n", i, pchW, pchW - wszCurrent);
475 }
476
477Cleanup:
478 if (pEntry->testType != testBoth)
479 wszCurrent = NULL;
480 HeapFree(GetProcessHeap(), 0, wszStart);
481 HeapFree(GetProcessHeap(), 0, wszCurrent);
482}
483
485{
486 LPSTR szStart, szCurrent;
487 LPSTR pchA, pchEx;
488 INT iRealOffset;
489 BOOL b;
490
491 szStart = AllocStringA(pEntry->lpszStart, len);
492 if (!szStart && pEntry->lpszStart)
493 {
494 skip("[%u] AllocStringA for szStart failed\n", i);
495 goto Cleanup;
496 }
497 if (pEntry->testType == testLen)
498 szCurrent = szStart + len;
499 else if (pEntry->testType == testOffs)
500 szCurrent = szStart + pEntry->iOffset;
501 else
502 {
503 szCurrent = AllocStringA(pEntry->lpszCurrent, wcslen(pEntry->lpszCurrent));
504 if (!szCurrent && pEntry->lpszCurrent)
505 {
506 skip("[%u] AllocStringA for szCurrent failed\n", i);
507 goto Cleanup;
508 }
509 }
510 pchA = CharPrevA(szStart, szCurrent);
511 pchEx = CharPrevExA(TEST_ACP, szStart, szCurrent, 0);
512 if (szCurrent - szStart >= 0)
513 iRealOffset = pEntry->iResOffset;
514 else
515 iRealOffset = pEntry->iResOffsetNeg;
516 if (pEntry->bWithinStart)
517 {
518 b = pchA >= szStart && pchA <= szStart + len;
519 if (iRealOffset >= 0)
520 ok(b, "[%u] CharPrevA: pchA (0x%p) is expected to be within szStart (0x%p)\n", i, pchA, szStart);
521 else
522 ok(!b, "[%u] CharPrevA: pchA (0x%p) is expected to be outside szStart (0x%p)\n", i, pchA, szStart);
523 ok(pchA == szStart + iRealOffset, "[%u] CharPrevA: pchA is 0x%p (offset %d)\n", i, pchA, pchA - szStart);
524 }
525 else
526 {
527 b = pchA >= szCurrent && pchA <= szCurrent + wcslen(pEntry->lpszCurrent);
528 if (iRealOffset >= 0)
529 ok(b, "[%u] CharPrevA: pchA (0x%p) is expected to be within szCurrent (0x%p)\n", i, pchA, szCurrent);
530 else
531 ok(!b, "[%u] CharPrevA: pchA (0x%p) is expected to be outside szCurrent (0x%p)\n", i, pchA, szCurrent);
532 ok(pchA == szCurrent + iRealOffset, "[%u] CharPrevA: pchA is 0x%p (offset %d)\n", i, pchA, pchA - szCurrent);
533 }
534 ok(pchA == pchEx, "[%u] CharPrevExA: pchA (0x%p) is not equal to pchEx (0x%p)\n", i, pchA, pchEx);
535
536Cleanup:
537 if (pEntry->testType != testBoth)
538 szCurrent = NULL;
539 HeapFree(GetProcessHeap(), 0, szStart);
540 HeapFree(GetProcessHeap(), 0, szCurrent);
541}
542
544{
545 SIZE_T len;
546
547 len = wcslen(pEntry->lpszStart);
549
550 if (pEntry->bWideOnly)
551 return;
552
554}
555
557{
558 LPWSTR pchW;
559 LPSTR pchA;
560
561 pchW = CharPrevW(pEntry->wszStart, pEntry->wszCurrent);
562 ok(pchW == pEntry->wszResult, "[%u] CharPrevW: pchW is 0x%p (expected 0x%p)\n", i, pchW, pEntry->wszResult);
563
564 if (!pEntry->szStart)
565 return;
566
567 pchA = CharPrevA(pEntry->szStart, pEntry->szCurrent);
568 ok(pchA == pEntry->szResult, "[%u] CharPrevA: pchA is 0x%p (expected 0x%p)\n", i, pchA, pEntry->szResult);
569
570 pchA = CharPrevExA(TEST_ACP, pEntry->szStart, pEntry->szCurrent, 0);
571 ok(pchA == pEntry->szResult, "[%u] CharPrevExA: pchA is 0x%p (expected 0x%p)\n", i, pchA, pEntry->szResult);
572}
573
575{
576 LPSTR pchA;
577
578 pchA = CharPrevExA(pEntry->uCodePage, pEntry->szStart, pEntry->szCurrent, 0);
579 ok(pchA == pEntry->szResult, "[%u] CharPrevExA(%u): pchA is 0x%p (expected 0x%p)\n", i, pEntry->uCodePage, pchA, pEntry->szResult);
580}
581
583{
584 LPWSTR pchW;
585 LPSTR pchA;
586
587 pchW = CharNextW(pEntry->wszString);
588 ok(pchW == pEntry->wszResult, "[%u] CharNextW: pchW is 0x%p (expected 0x%p)\n", i, pchW, pEntry->wszResult);
589
590 if (!pEntry->szString)
591 return;
592
593 pchA = CharNextA(pEntry->szString);
594 ok(pchA == pEntry->szResult, "[%u] CharNextA: pchA is 0x%p (expected 0x%p)\n", i, pchA, pEntry->szResult);
595
596 pchA = CharNextExA(TEST_ACP, pEntry->szString, 0);
597 ok(pchA == pEntry->szResult, "[%u] CharNextExA: pchA is 0x%p (expected 0x%p)\n", i, pchA, pEntry->szResult);
598}
599
601{
602 LPSTR pchA;
603
604 pchA = CharNextExA(pEntry->uCodePage, pEntry->szString, 0);
605 ok(pchA == pEntry->szResult, "[%u] CharNextExA(%u): pchA is 0x%p (expected 0x%p)\n", i, pEntry->uCodePage, pchA, pEntry->szResult);
606}
607
608static void testCharPrev(void)
609{
610 UINT i;
611
612 /* Perform dynamic allocation tests */
613 for (i = 0; i < _countof(TestCharPrev); i++)
614 {
616 }
617
619 {
620 for (i = 0; i < _countof(TestCharPrev_XP); i++)
621 {
623 }
624 }
625 else
626 {
627 for (i = 0; i < _countof(TestCharPrev_Vista); i++)
628 {
630 }
631 }
632
633 /* Perform static tests */
634 for (i = 0; i < _countof(TestStaticCharPrev); i++)
635 {
637 }
638
640 {
641 for (i = 0; i < _countof(TestStaticCharPrev_XP); i++)
642 {
644 }
645 }
646 else
647 {
648 for (i = 0; i < _countof(TestStaticCharPrev_Vista); i++)
649 {
651 }
652 }
653
654 for (i = 0; i < _countof(TestStaticCodePageCharPrev); i++)
655 {
657 }
658
659 /* Perform exception tests (check corner cases) */
661 {
662 ok(FALSE, "testCharPrev: unexpected INVALID PTR < wszReactOS\n");
663 return;
664 }
666 {
667 ok(FALSE, "testCharPrev: unexpected INVALID PTR < szReactOS\n");
668 return;
669 }
670
671 for (i = 0; i < _countof(TestExceptionCharPrev); i++)
672 {
673 LPWSTR pchW;
674 LPSTR pchA;
677
678 //trace("0x%p 0x%p\n", pEntry->wszStart, pEntry->wszCurrent);
679 pchW = NULL;
681 {
682 pchW = CharPrevW(pEntry->wszStart, pEntry->wszCurrent);
683 }
685 {
687 }
688 _SEH2_END;
689 ok(Status == pEntry->resStatus, "[%u] CharPrevW: Status is 0x%lX, expected 0x%lX\n", i, Status, pEntry->resStatus);
690 ok(pchW == pEntry->wszResult, "[%u] CharPrevW: pchW is 0x%p, expected 0x%p\n", i, pchW, pEntry->wszResult);
691
692 //trace("0x%p 0x%p\n", pEntry->szStart, pEntry->szCurrent);
693 pchA = NULL;
695 {
696 pchA = CharPrevA(pEntry->szStart, pEntry->szCurrent);
697 }
699 {
701 }
702 _SEH2_END;
703 ok(Status == pEntry->resStatus, "[%u] CharPrevA: Status is 0x%lX, expected 0x%lX\n", i, Status, pEntry->resStatus);
704 ok(pchA == pEntry->szResult, "[%u] CharPrevA: pchA is 0x%p, expected 0x%p\n", i, pchA, pEntry->szResult);
705
706 pchA = NULL;
708 {
709 pchA = CharPrevExA(TEST_ACP, pEntry->szStart, pEntry->szCurrent, 0);
710 }
712 {
714 }
715 _SEH2_END;
716 ok(Status == pEntry->resStatus, "[%u] CharPrevExA: Status is 0x%lX, expected 0x%lX\n", i, Status, pEntry->resStatus);
717 ok(pchA == pEntry->szExResult, "[%u] CharPrevExA: pchA is 0x%p, expected 0x%p\n", i, pchA, pEntry->szExResult);
718 }
719}
720
721static void testCharNext(void)
722{
723 UINT i;
724
725 /* Perform static tests */
726 for (i = 0; i < _countof(TestStaticCharNext); i++)
727 {
729 }
730
732 {
733 for (i = 0; i < _countof(TestStaticCharNext_XP); i++)
734 {
736 }
737 }
738 else
739 {
740 for (i = 0; i < _countof(TestStaticCharNext_Vista); i++)
741 {
743 }
744 }
745
746 for (i = 0; i < _countof(TestStaticCodePageCharNext); i++)
747 {
749 }
750
751 /* Perform exception tests (check corner cases) */
753 {
754 ok(FALSE, "testCharNext: unexpected INVALID PTR < wszReactOS\n");
755 return;
756 }
758 {
759 ok(FALSE, "testCharNext: unexpected INVALID PTR < szReactOS\n");
760 return;
761 }
762
763 for (i = 0; i < _countof(TestExceptionCharNext); i++)
764 {
765 LPWSTR pchW;
766 LPSTR pchA;
769
770 //trace("0x%p\n", pEntry->wszString);
771 pchW = NULL;
773 {
774 pchW = CharNextW(pEntry->wszString);
775 }
777 {
779 }
780 _SEH2_END;
781 ok(Status == pEntry->resStatus, "[%u] CharNextW: Status is 0x%lX, expected 0x%lX\n", i, Status, pEntry->resStatus);
782 ok(pchW == pEntry->wszResult, "[%u] CharNextW: pchW is 0x%p, expected 0x%p\n", i, pchW, pEntry->wszResult);
783
784 //trace("0x%p 0x%p\n", pEntry->szString);
785 pchA = NULL;
787 {
788 pchA = CharNextA(pEntry->szString);
789 }
791 {
793 }
794 _SEH2_END;
795 ok(Status == pEntry->resStatus, "[%u] CharNextA: Status is 0x%lX, expected 0x%lX\n", i, Status, pEntry->resStatus);
796 ok(pchA == pEntry->szResult, "[%u] CharNextA: pchA is 0x%p, expected 0x%p\n", i, pchA, pEntry->szResult);
797
798 pchA = NULL;
800 {
801 pchA = CharNextExA(TEST_ACP, pEntry->szString, 0);
802 }
804 {
806 }
807 _SEH2_END;
808 ok(Status == pEntry->resStatus, "[%u] CharNextExA: Status is 0x%lX, expected 0x%lX\n", i, Status, pEntry->resStatus);
809 ok(pchA == pEntry->szResult, "[%u] CharNextExA: pchA is 0x%p, expected 0x%p\n", i, pchA, pEntry->szResult);
810 }
811}
812
813START_TEST(CharFuncs)
814{
815 testCharPrev();
816 testCharNext();
817}
static LPWSTR AllocStringW(LPWSTR lpszStr, SIZE_T len)
Definition: CharFuncs.c:377
TESTS_CHARPREV TestCharPrev[]
Definition: CharFuncs.c:42
static const WCHAR wszSpecial[]
Definition: CharFuncs.c:76
TEST_TYPE
Definition: CharFuncs.c:23
@ testLen
Definition: CharFuncs.c:24
@ testBoth
Definition: CharFuncs.c:26
@ testOffs
Definition: CharFuncs.c:25
ST_TESTS_CHARPREV TestStaticCharPrev_Vista[]
Definition: CharFuncs.c:150
static const CHAR szSpecial[]
Definition: CharFuncs.c:77
EX_TESTS_CHARPREV TestExceptionCharPrev[]
Definition: CharFuncs.c:302
ST_TESTS_CHARPREV TestStaticCharPrev_XP[]
Definition: CharFuncs.c:135
static void testStatCodePageCharPrev(const ST_CODEPAGE_TESTS_CHARPREV *pEntry, UINT i)
Definition: CharFuncs.c:574
TESTS_CHARPREV TestCharPrev_Vista[]
Definition: CharFuncs.c:63
ST_TESTS_CHARNEXT TestStaticCharNext[]
Definition: CharFuncs.c:200
ST_TESTS_CHARNEXT TestStaticCharNext_Vista[]
Definition: CharFuncs.c:247
static void testCharNext(void)
Definition: CharFuncs.c:721
static const CHAR szReactOS[]
Definition: CharFuncs.c:75
static const WCHAR wszReactOS[]
Definition: CharFuncs.c:74
static const WCHAR wszMagic1[]
Definition: CharFuncs.c:78
TESTS_CHARPREV TestCharPrev_XP[]
Definition: CharFuncs.c:53
ST_CODEPAGE_TESTS_CHARNEXT TestStaticCodePageCharNext[]
Definition: CharFuncs.c:269
#define TEST_ACP
Definition: CharFuncs.c:20
ST_TESTS_CHARPREV TestStaticCharPrev[]
Definition: CharFuncs.c:96
#define INVALID_PTR_OFF(x)
Definition: CharFuncs.c:16
ST_CODEPAGE_TESTS_CHARPREV TestStaticCodePageCharPrev[]
Definition: CharFuncs.c:173
static void testCharPrevA(const TESTS_CHARPREV *pEntry, SIZE_T len, UINT i)
Definition: CharFuncs.c:484
EX_TESTS_CHARNEXT TestExceptionCharNext[]
Definition: CharFuncs.c:357
ST_TESTS_CHARNEXT TestStaticCharNext_XP[]
Definition: CharFuncs.c:232
static void testStatCodePageCharNext(const ST_CODEPAGE_TESTS_CHARNEXT *pEntry, UINT i)
Definition: CharFuncs.c:600
static void testCharPrev(void)
Definition: CharFuncs.c:608
static const CHAR szUTF8Greek[]
Definition: CharFuncs.c:82
static const CHAR szUTF8Cyril[]
Definition: CharFuncs.c:81
static void testStatCharNext(const ST_TESTS_CHARNEXT *pEntry, UINT i)
Definition: CharFuncs.c:582
static const CHAR szCP932Japan[]
Definition: CharFuncs.c:84
#define INVALID_PTR
Definition: CharFuncs.c:17
static LPSTR AllocStringA(LPWSTR lpszStr, SIZE_T len)
Definition: CharFuncs.c:397
static const WCHAR wszMagic2[]
Definition: CharFuncs.c:79
static void testDynCharPrev(const TESTS_CHARPREV *pEntry, UINT i)
Definition: CharFuncs.c:543
static const CHAR szUTF8Japan[]
Definition: CharFuncs.c:83
static void testStatCharPrev(const ST_TESTS_CHARPREV *pEntry, UINT i)
Definition: CharFuncs.c:556
static void testCharPrevW(const TESTS_CHARPREV *pEntry, SIZE_T len, UINT i)
Definition: CharFuncs.c:427
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Cleanup[]
Definition: register.c:80
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
Status
Definition: gdiplustypes.h:25
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLsizei len
Definition: glext.h:6722
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
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define b
Definition: ke_i.h:79
unsigned int UINT
Definition: ndis.h:50
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define L(x)
Definition: ntvdm.h:50
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
const WCHAR * str
#define CP_UTF8
Definition: nls.h:20
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _countof(array)
Definition: sndvol32.h:68
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
NTSTATUS resStatus
Definition: CharFuncs.c:354
LPCWSTR wszString
Definition: CharFuncs.c:350
LPCWSTR wszResult
Definition: CharFuncs.c:351
LPCWSTR wszResult
Definition: CharFuncs.c:294
LPCWSTR wszCurrent
Definition: CharFuncs.c:293
LPCWSTR wszStart
Definition: CharFuncs.c:292
NTSTATUS resStatus
Definition: CharFuncs.c:299
LPCWSTR wszResult
Definition: CharFuncs.c:195
LPCWSTR wszString
Definition: CharFuncs.c:194
LPCWSTR wszStart
Definition: CharFuncs.c:88
LPCWSTR wszCurrent
Definition: CharFuncs.c:89
LPCSTR szCurrent
Definition: CharFuncs.c:92
LPCWSTR wszResult
Definition: CharFuncs.c:90
BOOL bWideOnly
Definition: CharFuncs.c:39
TEST_TYPE testType
Definition: CharFuncs.c:32
INT iResOffsetNeg
Definition: CharFuncs.c:37
LPWSTR lpszStart
Definition: CharFuncs.c:33
BOOL bWithinStart
Definition: CharFuncs.c:38
LPWSTR lpszCurrent
Definition: CharFuncs.c:34
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
VERSIONHELPERAPI IsWindowsVistaOrGreater()
char mbs[5]
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
LPSTR WINAPI CharPrevA(_In_ LPCSTR, _In_ LPCSTR)
LPSTR WINAPI CharNextExA(_In_ WORD, _In_ LPCSTR, _In_ DWORD)
LPSTR WINAPI CharNextA(_In_ LPCSTR)
LPSTR WINAPI CharPrevExA(_In_ WORD, _In_ LPCSTR, _In_ LPCSTR, _In_ DWORD)
LPWSTR WINAPI CharPrevW(_In_ LPCWSTR, _In_ LPCWSTR)
LPWSTR WINAPI CharNextW(_In_ LPCWSTR)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175