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