1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <wctype.h>
18
19 #include <dlfcn.h>
20
21 #include <gtest/gtest.h>
22
23 class UtfLocale {
24 public:
UtfLocale()25 UtfLocale() : l(newlocale(LC_ALL, "C.UTF-8", 0)) {}
~UtfLocale()26 ~UtfLocale() { freelocale(l); }
27 locale_t l;
28 };
29
30 // bionic's dlsym doesn't work in static binaries, so we can't access icu,
31 // so any unicode test case will fail.
have_dl()32 static bool have_dl() {
33 return (dlopen("libc.so", 0) != nullptr);
34 }
35
TestIsWideFn(int fn (wint_t),int fn_l (wint_t,locale_t),const wchar_t * trues,const wchar_t * falses)36 static void TestIsWideFn(int fn(wint_t),
37 int fn_l(wint_t, locale_t),
38 const wchar_t* trues,
39 const wchar_t* falses) {
40 UtfLocale l;
41 for (const wchar_t* p = trues; *p; ++p) {
42 if (!have_dl() && *p > 0x7f) {
43 GTEST_LOG_(INFO) << "skipping unicode test " << *p;
44 continue;
45 }
46 EXPECT_TRUE(fn(*p)) << *p;
47 EXPECT_TRUE(fn_l(*p, l.l)) << *p;
48 }
49 for (const wchar_t* p = falses; *p; ++p) {
50 if (!have_dl() && *p > 0x7f) {
51 GTEST_LOG_(INFO) << "skipping unicode test " << *p;
52 continue;
53 }
54 EXPECT_FALSE(fn(*p)) << *p;
55 EXPECT_FALSE(fn_l(*p, l.l)) << *p;
56 }
57 }
58
TEST(wctype,iswalnum)59 TEST(wctype, iswalnum) {
60 TestIsWideFn(iswalnum, iswalnum_l, L"1aAÇçΔδ", L"! \b");
61 }
62
TEST(wctype,iswalpha)63 TEST(wctype, iswalpha) {
64 TestIsWideFn(iswalpha, iswalpha_l, L"aAÇçΔδ", L"1! \b");
65 }
66
TEST(wctype,iswblank)67 TEST(wctype, iswblank) {
68 TestIsWideFn(iswblank, iswblank_l, L" \t", L"1aA!\bÇçΔδ");
69 }
70
TEST(wctype,iswcntrl)71 TEST(wctype, iswcntrl) {
72 TestIsWideFn(iswcntrl, iswcntrl_l, L"\b\u009f", L"1aA! ÇçΔδ");
73 }
74
TEST(wctype,iswdigit)75 TEST(wctype, iswdigit) {
76 TestIsWideFn(iswdigit, iswdigit_l, L"1", L"aA! \bÇçΔδ");
77 }
78
TEST(wctype,iswgraph)79 TEST(wctype, iswgraph) {
80 TestIsWideFn(iswgraph, iswgraph_l, L"1aA!ÇçΔδ", L" \b");
81 }
82
TEST(wctype,iswlower)83 TEST(wctype, iswlower) {
84 TestIsWideFn(iswlower, iswlower_l, L"açδ", L"1A! \bÇΔ");
85 }
86
TEST(wctype,iswprint)87 TEST(wctype, iswprint) {
88 TestIsWideFn(iswprint, iswprint_l, L"1aA! ÇçΔδ", L"\b");
89 }
90
TEST(wctype,iswpunct)91 TEST(wctype, iswpunct) {
92 TestIsWideFn(iswpunct, iswpunct_l, L"!", L"1aA \bÇçΔδ");
93 }
94
TEST(wctype,iswspace)95 TEST(wctype, iswspace) {
96 TestIsWideFn(iswspace, iswspace_l, L" \f\t", L"1aA!\bÇçΔδ");
97 }
98
TEST(wctype,iswupper)99 TEST(wctype, iswupper) {
100 TestIsWideFn(iswupper, iswupper_l, L"AÇΔ", L"1a! \bçδ");
101 }
102
TEST(wctype,iswxdigit)103 TEST(wctype, iswxdigit) {
104 TestIsWideFn(iswxdigit, iswxdigit_l, L"01aA", L"xg! \b");
105 }
106
TEST(wctype,towlower)107 TEST(wctype, towlower) {
108 EXPECT_EQ(WEOF, towlower(WEOF));
109 EXPECT_EQ(wint_t('!'), towlower(L'!'));
110 EXPECT_EQ(wint_t('a'), towlower(L'a'));
111 EXPECT_EQ(wint_t('a'), towlower(L'A'));
112 if (have_dl()) {
113 EXPECT_EQ(wint_t(L'ç'), towlower(L'ç'));
114 EXPECT_EQ(wint_t(L'ç'), towlower(L'Ç'));
115 EXPECT_EQ(wint_t(L'δ'), towlower(L'δ'));
116 EXPECT_EQ(wint_t(L'δ'), towlower(L'Δ'));
117 } else {
118 GTEST_LOG_(INFO) << "skipping unicode towlower tests";
119 }
120 }
121
TEST(wctype,towlower_l)122 TEST(wctype, towlower_l) {
123 UtfLocale l;
124 EXPECT_EQ(WEOF, towlower(WEOF));
125 EXPECT_EQ(wint_t('!'), towlower_l(L'!', l.l));
126 EXPECT_EQ(wint_t('a'), towlower_l(L'a', l.l));
127 EXPECT_EQ(wint_t('a'), towlower_l(L'A', l.l));
128 if (have_dl()) {
129 EXPECT_EQ(wint_t(L'ç'), towlower_l(L'ç', l.l));
130 EXPECT_EQ(wint_t(L'ç'), towlower_l(L'Ç', l.l));
131 EXPECT_EQ(wint_t(L'δ'), towlower_l(L'δ', l.l));
132 EXPECT_EQ(wint_t(L'δ'), towlower_l(L'Δ', l.l));
133 } else {
134 GTEST_LOG_(INFO) << "skipping unicode towlower_l tests";
135 }
136 }
137
TEST(wctype,towupper)138 TEST(wctype, towupper) {
139 EXPECT_EQ(WEOF, towupper(WEOF));
140 EXPECT_EQ(wint_t('!'), towupper(L'!'));
141 EXPECT_EQ(wint_t('A'), towupper(L'a'));
142 EXPECT_EQ(wint_t('A'), towupper(L'A'));
143 if (have_dl()) {
144 EXPECT_EQ(wint_t(L'Ç'), towupper(L'ç'));
145 EXPECT_EQ(wint_t(L'Ç'), towupper(L'Ç'));
146 EXPECT_EQ(wint_t(L'Δ'), towupper(L'δ'));
147 EXPECT_EQ(wint_t(L'Δ'), towupper(L'Δ'));
148 } else {
149 GTEST_LOG_(INFO) << "skipping unicode towupper tests";
150 }
151 }
152
TEST(wctype,towupper_l)153 TEST(wctype, towupper_l) {
154 UtfLocale l;
155 EXPECT_EQ(WEOF, towupper_l(WEOF, l.l));
156 EXPECT_EQ(wint_t('!'), towupper_l(L'!', l.l));
157 EXPECT_EQ(wint_t('A'), towupper_l(L'a', l.l));
158 EXPECT_EQ(wint_t('A'), towupper_l(L'A', l.l));
159 if (have_dl()) {
160 EXPECT_EQ(wint_t(L'Ç'), towupper_l(L'ç', l.l));
161 EXPECT_EQ(wint_t(L'Ç'), towupper_l(L'Ç', l.l));
162 EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'δ', l.l));
163 EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'Δ', l.l));
164 } else {
165 GTEST_LOG_(INFO) << "skipping unicode towupper_l tests";
166 }
167 }
168
TEST(wctype,wctype)169 TEST(wctype, wctype) {
170 EXPECT_TRUE(wctype("alnum") != 0);
171 EXPECT_TRUE(wctype("alpha") != 0);
172 EXPECT_TRUE(wctype("blank") != 0);
173 EXPECT_TRUE(wctype("cntrl") != 0);
174 EXPECT_TRUE(wctype("digit") != 0);
175 EXPECT_TRUE(wctype("graph") != 0);
176 EXPECT_TRUE(wctype("lower") != 0);
177 EXPECT_TRUE(wctype("print") != 0);
178 EXPECT_TRUE(wctype("punct") != 0);
179 EXPECT_TRUE(wctype("space") != 0);
180 EXPECT_TRUE(wctype("upper") != 0);
181 EXPECT_TRUE(wctype("xdigit") != 0);
182
183 EXPECT_TRUE(wctype("monkeys") == 0);
184 }
185
TEST(wctype,wctype_l)186 TEST(wctype, wctype_l) {
187 UtfLocale l;
188 EXPECT_TRUE(wctype_l("alnum", l.l) != 0);
189 EXPECT_TRUE(wctype_l("alpha", l.l) != 0);
190 EXPECT_TRUE(wctype_l("blank", l.l) != 0);
191 EXPECT_TRUE(wctype_l("cntrl", l.l) != 0);
192 EXPECT_TRUE(wctype_l("digit", l.l) != 0);
193 EXPECT_TRUE(wctype_l("graph", l.l) != 0);
194 EXPECT_TRUE(wctype_l("lower", l.l) != 0);
195 EXPECT_TRUE(wctype_l("print", l.l) != 0);
196 EXPECT_TRUE(wctype_l("punct", l.l) != 0);
197 EXPECT_TRUE(wctype_l("space", l.l) != 0);
198 EXPECT_TRUE(wctype_l("upper", l.l) != 0);
199 EXPECT_TRUE(wctype_l("xdigit", l.l) != 0);
200
201 EXPECT_TRUE(wctype_l("monkeys", l.l) == 0);
202 }
203
TEST(wctype,iswctype)204 TEST(wctype, iswctype) {
205 EXPECT_TRUE(iswctype(L'a', wctype("alnum")));
206 EXPECT_TRUE(iswctype(L'1', wctype("alnum")));
207 EXPECT_FALSE(iswctype(L' ', wctype("alnum")));
208
209 EXPECT_EQ(0, iswctype(WEOF, wctype("alnum")));
210 }
211
TEST(wctype,iswctype_l)212 TEST(wctype, iswctype_l) {
213 UtfLocale l;
214 EXPECT_TRUE(iswctype_l(L'a', wctype_l("alnum", l.l), l.l));
215 EXPECT_TRUE(iswctype_l(L'1', wctype_l("alnum", l.l), l.l));
216 EXPECT_FALSE(iswctype_l(L' ', wctype_l("alnum", l.l), l.l));
217
218 EXPECT_EQ(0, iswctype_l(WEOF, wctype_l("alnum", l.l), l.l));
219 }
220
TEST(wctype,towctrans)221 TEST(wctype, towctrans) {
222 EXPECT_TRUE(wctrans("tolower") != 0);
223 EXPECT_TRUE(wctrans("toupper") != 0);
224
225 EXPECT_TRUE(wctrans("monkeys") == 0);
226 }
227
TEST(wctype,towctrans_l)228 TEST(wctype, towctrans_l) {
229 UtfLocale l;
230 EXPECT_TRUE(wctrans_l("tolower", l.l) != 0);
231 EXPECT_TRUE(wctrans_l("toupper", l.l) != 0);
232
233 EXPECT_TRUE(wctrans_l("monkeys", l.l) == 0);
234 }
235
TEST(wctype,wctrans)236 TEST(wctype, wctrans) {
237 EXPECT_EQ(wint_t('a'), towctrans(L'A', wctrans("tolower")));
238 EXPECT_EQ(WEOF, towctrans(WEOF, wctrans("tolower")));
239
240 EXPECT_EQ(wint_t('A'), towctrans(L'a', wctrans("toupper")));
241 EXPECT_EQ(WEOF, towctrans(WEOF, wctrans("toupper")));
242 }
243
TEST(wctype,wctrans_l)244 TEST(wctype, wctrans_l) {
245 UtfLocale l;
246 EXPECT_EQ(wint_t('a'), towctrans_l(L'A', wctrans_l("tolower", l.l), l.l));
247 EXPECT_EQ(WEOF, towctrans_l(WEOF, wctrans_l("tolower", l.l), l.l));
248
249 EXPECT_EQ(wint_t('A'), towctrans_l(L'a', wctrans_l("toupper", l.l), l.l));
250 EXPECT_EQ(WEOF, towctrans_l(WEOF, wctrans_l("toupper", l.l), l.l));
251 }
252