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