• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "utils.h"
24 
25 class UtfLocale {
26  public:
UtfLocale()27   UtfLocale() : l(newlocale(LC_ALL, "C.UTF-8", nullptr)) {}
~UtfLocale()28   ~UtfLocale() { freelocale(l); }
29   locale_t l;
30 };
31 
TestIsWideFn(int fn (wint_t),int fn_l (wint_t,locale_t),const wchar_t * trues,const wchar_t * falses)32 static void TestIsWideFn(int fn(wint_t),
33                          int fn_l(wint_t, locale_t),
34                          const wchar_t* trues,
35                          const wchar_t* falses) {
36   UtfLocale l;
37   for (const wchar_t* p = trues; *p; ++p) {
38     const wchar_t val_ch = *p;
39     const int val_int = static_cast<int>(val_ch);
40 
41     EXPECT_TRUE(fn(val_ch)) << val_int;
42     EXPECT_TRUE(fn_l(val_ch, l.l)) << val_int;
43   }
44   for (const wchar_t* p = falses; *p; ++p) {
45     const wchar_t val_ch = *p;
46     const int val_int = static_cast<int>(val_ch);
47 
48     EXPECT_FALSE(fn(val_ch)) << val_int;
49     EXPECT_FALSE(fn_l(val_ch, l.l)) << val_int;
50   }
51 }
52 
TEST(wctype,iswalnum)53 TEST(wctype, iswalnum) {
54   TestIsWideFn(iswalnum, iswalnum_l, L"1aAÇçΔδ", L"! \b");
55 }
56 
TEST(wctype,iswalpha)57 TEST(wctype, iswalpha) {
58   TestIsWideFn(iswalpha, iswalpha_l, L"aAÇçΔδ", L"1! \b");
59 }
60 
TEST(wctype,iswblank)61 TEST(wctype, iswblank) {
62   TestIsWideFn(iswblank, iswblank_l, L" \t", L"1aA!\bÇçΔδ");
63 }
64 
TEST(wctype,iswcntrl)65 TEST(wctype, iswcntrl) {
66   TestIsWideFn(iswcntrl, iswcntrl_l, L"\b\u009f", L"1aA! ÇçΔδ");
67 }
68 
TEST(wctype,iswdigit)69 TEST(wctype, iswdigit) {
70   TestIsWideFn(iswdigit, iswdigit_l, L"1", L"aA! \bÇçΔδ");
71 }
72 
TEST(wctype,iswgraph)73 TEST(wctype, iswgraph) {
74   TestIsWideFn(iswgraph, iswgraph_l, L"1aA!ÇçΔδ", L" \b");
75 }
76 
TEST(wctype,iswlower)77 TEST(wctype, iswlower) {
78   TestIsWideFn(iswlower, iswlower_l, L"açδ", L"1A! \bÇΔ");
79 }
80 
TEST(wctype,iswprint)81 TEST(wctype, iswprint) {
82   TestIsWideFn(iswprint, iswprint_l, L"1aA! ÇçΔδ", L"\b");
83 }
84 
TEST(wctype,iswpunct)85 TEST(wctype, iswpunct) {
86   TestIsWideFn(iswpunct, iswpunct_l, L"!", L"1aA \bÇçΔδ");
87 }
88 
TEST(wctype,iswspace)89 TEST(wctype, iswspace) {
90   TestIsWideFn(iswspace, iswspace_l, L" \f\t", L"1aA!\bÇçΔδ");
91 }
92 
TEST(wctype,iswupper)93 TEST(wctype, iswupper) {
94   TestIsWideFn(iswupper, iswupper_l, L"AÇΔ", L"1a! \bçδ");
95 }
96 
TEST(wctype,iswxdigit)97 TEST(wctype, iswxdigit) {
98   TestIsWideFn(iswxdigit, iswxdigit_l, L"01aA", L"xg! \b");
99 }
100 
TEST(wctype,towlower)101 TEST(wctype, towlower) {
102   EXPECT_EQ(WEOF, towlower(WEOF));
103   EXPECT_EQ(wint_t('!'), towlower(L'!'));
104   EXPECT_EQ(wint_t('a'), towlower(L'a'));
105   EXPECT_EQ(wint_t('a'), towlower(L'A'));
106   EXPECT_EQ(wint_t('z'), towlower(L'z'));
107   EXPECT_EQ(wint_t('z'), towlower(L'Z'));
108   EXPECT_EQ(wint_t(L'ç'), towlower(L'ç'));
109   EXPECT_EQ(wint_t(L'ç'), towlower(L'Ç'));
110   EXPECT_EQ(wint_t(L'δ'), towlower(L'δ'));
111   EXPECT_EQ(wint_t(L'δ'), towlower(L'Δ'));
112 }
113 
TEST(wctype,towlower_l)114 TEST(wctype, towlower_l) {
115   UtfLocale l;
116   EXPECT_EQ(WEOF, towlower(WEOF));
117   EXPECT_EQ(wint_t('!'), towlower_l(L'!', l.l));
118   EXPECT_EQ(wint_t('a'), towlower_l(L'a', l.l));
119   EXPECT_EQ(wint_t('a'), towlower_l(L'A', l.l));
120   EXPECT_EQ(wint_t('z'), towlower_l(L'z', l.l));
121   EXPECT_EQ(wint_t('z'), towlower_l(L'Z', l.l));
122   EXPECT_EQ(wint_t(L'ç'), towlower_l(L'ç', l.l));
123   EXPECT_EQ(wint_t(L'ç'), towlower_l(L'Ç', l.l));
124   EXPECT_EQ(wint_t(L'δ'), towlower_l(L'δ', l.l));
125   EXPECT_EQ(wint_t(L'δ'), towlower_l(L'Δ', l.l));
126 }
127 
TEST(wctype,towupper)128 TEST(wctype, towupper) {
129   EXPECT_EQ(WEOF, towupper(WEOF));
130   EXPECT_EQ(wint_t('!'), towupper(L'!'));
131   EXPECT_EQ(wint_t('A'), towupper(L'a'));
132   EXPECT_EQ(wint_t('A'), towupper(L'A'));
133   EXPECT_EQ(wint_t('Z'), towupper(L'z'));
134   EXPECT_EQ(wint_t('Z'), towupper(L'Z'));
135   EXPECT_EQ(wint_t(L'Ç'), towupper(L'ç'));
136   EXPECT_EQ(wint_t(L'Ç'), towupper(L'Ç'));
137   EXPECT_EQ(wint_t(L'Δ'), towupper(L'δ'));
138   EXPECT_EQ(wint_t(L'Δ'), towupper(L'Δ'));
139 }
140 
TEST(wctype,towupper_l)141 TEST(wctype, towupper_l) {
142   UtfLocale l;
143   EXPECT_EQ(WEOF, towupper_l(WEOF, l.l));
144   EXPECT_EQ(wint_t('!'), towupper_l(L'!', l.l));
145   EXPECT_EQ(wint_t('A'), towupper_l(L'a', l.l));
146   EXPECT_EQ(wint_t('A'), towupper_l(L'A', l.l));
147   EXPECT_EQ(wint_t('Z'), towupper_l(L'z', l.l));
148   EXPECT_EQ(wint_t('Z'), towupper_l(L'Z', l.l));
149   EXPECT_EQ(wint_t(L'Ç'), towupper_l(L'ç', l.l));
150   EXPECT_EQ(wint_t(L'Ç'), towupper_l(L'Ç', l.l));
151   EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'δ', l.l));
152   EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'Δ', l.l));
153 }
154 
TEST(wctype,wctype)155 TEST(wctype, wctype) {
156   EXPECT_TRUE(wctype("alnum") != 0);
157   EXPECT_TRUE(wctype("alpha") != 0);
158   EXPECT_TRUE(wctype("blank") != 0);
159   EXPECT_TRUE(wctype("cntrl") != 0);
160   EXPECT_TRUE(wctype("digit") != 0);
161   EXPECT_TRUE(wctype("graph") != 0);
162   EXPECT_TRUE(wctype("lower") != 0);
163   EXPECT_TRUE(wctype("print") != 0);
164   EXPECT_TRUE(wctype("punct") != 0);
165   EXPECT_TRUE(wctype("space") != 0);
166   EXPECT_TRUE(wctype("upper") != 0);
167   EXPECT_TRUE(wctype("xdigit") != 0);
168 
169   EXPECT_TRUE(wctype("monkeys") == 0);
170 }
171 
TEST(wctype,wctype_l)172 TEST(wctype, wctype_l) {
173   UtfLocale l;
174   EXPECT_TRUE(wctype_l("alnum", l.l) != 0);
175   EXPECT_TRUE(wctype_l("alpha", l.l) != 0);
176   EXPECT_TRUE(wctype_l("blank", l.l) != 0);
177   EXPECT_TRUE(wctype_l("cntrl", l.l) != 0);
178   EXPECT_TRUE(wctype_l("digit", l.l) != 0);
179   EXPECT_TRUE(wctype_l("graph", l.l) != 0);
180   EXPECT_TRUE(wctype_l("lower", l.l) != 0);
181   EXPECT_TRUE(wctype_l("print", l.l) != 0);
182   EXPECT_TRUE(wctype_l("punct", l.l) != 0);
183   EXPECT_TRUE(wctype_l("space", l.l) != 0);
184   EXPECT_TRUE(wctype_l("upper", l.l) != 0);
185   EXPECT_TRUE(wctype_l("xdigit", l.l) != 0);
186 
187   EXPECT_TRUE(wctype_l("monkeys", l.l) == 0);
188 }
189 
TEST(wctype,iswctype)190 TEST(wctype, iswctype) {
191   EXPECT_TRUE(iswctype(L'a', wctype("alnum")));
192   EXPECT_TRUE(iswctype(L'1', wctype("alnum")));
193   EXPECT_FALSE(iswctype(L' ', wctype("alnum")));
194 
195   EXPECT_EQ(0, iswctype(WEOF, wctype("alnum")));
196 }
197 
TEST(wctype,iswctype_l)198 TEST(wctype, iswctype_l) {
199   UtfLocale l;
200   EXPECT_TRUE(iswctype_l(L'a', wctype_l("alnum", l.l), l.l));
201   EXPECT_TRUE(iswctype_l(L'1', wctype_l("alnum", l.l), l.l));
202   EXPECT_FALSE(iswctype_l(L' ', wctype_l("alnum", l.l), l.l));
203 
204   EXPECT_EQ(0, iswctype_l(WEOF, wctype_l("alnum", l.l), l.l));
205 }
206 
TEST(wctype,wctrans)207 TEST(wctype, wctrans) {
208   EXPECT_TRUE(wctrans("tolower") != nullptr);
209   EXPECT_TRUE(wctrans("toupper") != nullptr);
210 
211   errno = 0;
212   EXPECT_TRUE(wctrans("monkeys") == nullptr);
213   #if defined(__BIONIC__)
214   // Android/FreeBSD/iOS set errno, but musl/glibc don't.
215   EXPECT_ERRNO(EINVAL);
216   #endif
217 }
218 
TEST(wctype,wctrans_l)219 TEST(wctype, wctrans_l) {
220   UtfLocale l;
221   EXPECT_TRUE(wctrans_l("tolower", l.l) != nullptr);
222   EXPECT_TRUE(wctrans_l("toupper", l.l) != nullptr);
223 
224   errno = 0;
225   EXPECT_TRUE(wctrans_l("monkeys", l.l) == nullptr);
226   #if defined(__BIONIC__)
227   // Android/FreeBSD/iOS set errno, but musl/glibc don't.
228   EXPECT_ERRNO(EINVAL);
229   #endif
230 }
231 
TEST(wctype,towctrans)232 TEST(wctype, towctrans) {
233   wctrans_t lower = wctrans("tolower");
234   EXPECT_EQ(wint_t('a'), towctrans(L'A', lower));
235   EXPECT_EQ(WEOF, towctrans(WEOF, lower));
236 
237   wctrans_t upper = wctrans("toupper");
238   EXPECT_EQ(wint_t('A'), towctrans(L'a', upper));
239   EXPECT_EQ(WEOF, towctrans(WEOF, upper));
240 
241   wctrans_t invalid = wctrans("monkeys");
242   errno = 0;
243   EXPECT_EQ(wint_t('a'), towctrans(L'a', invalid));
244   #if defined(__BIONIC__)
245   // Android/FreeBSD/iOS set errno, but musl/glibc don't.
246   EXPECT_ERRNO(EINVAL);
247   #endif
248 }
249 
TEST(wctype,towctrans_l)250 TEST(wctype, towctrans_l) {
251   UtfLocale l;
252   wctrans_t lower = wctrans_l("tolower", l.l);
253   EXPECT_EQ(wint_t('a'), towctrans_l(L'A', lower, l.l));
254   EXPECT_EQ(WEOF, towctrans_l(WEOF, lower, l.l));
255 
256   wctrans_t upper = wctrans_l("toupper", l.l);
257   EXPECT_EQ(wint_t('A'), towctrans_l(L'a', upper, l.l));
258   EXPECT_EQ(WEOF, towctrans_l(WEOF, upper, l.l));
259 
260   wctrans_t invalid = wctrans_l("monkeys", l.l);
261   errno = 0;
262   EXPECT_EQ(wint_t('a'), towctrans_l(L'a', invalid, l.l));
263   #if defined(__BIONIC__)
264   // Android/FreeBSD/iOS set errno, but musl/glibc don't.
265   EXPECT_ERRNO(EINVAL);
266   #endif
267 }
268