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: 25 UtfLocale() : l(newlocale(LC_ALL, "C.UTF-8", 0)) {} 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. 32 static bool have_dl() { 33 return (dlopen("libc.so", 0) != nullptr); 34 } 35 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 59 TEST(wctype, iswalnum) { 60 TestIsWideFn(iswalnum, iswalnum_l, L"1aA", L"! \b"); 61 } 62 63 TEST(wctype, iswalpha) { 64 TestIsWideFn(iswalpha, iswalpha_l, L"aA", L"1! \b"); 65 } 66 67 TEST(wctype, iswblank) { 68 TestIsWideFn(iswblank, iswblank_l, L" \t", L"1aA!\b"); 69 } 70 71 TEST(wctype, iswcntrl) { 72 TestIsWideFn(iswcntrl, iswcntrl_l, L"\b\u009f", L"1aA! "); 73 } 74 75 TEST(wctype, iswdigit) { 76 TestIsWideFn(iswdigit, iswdigit_l, L"1", L"aA! \b"); 77 } 78 79 TEST(wctype, iswgraph) { 80 TestIsWideFn(iswgraph, iswgraph_l, L"1aA!", L" \b"); 81 } 82 83 TEST(wctype, iswlower) { 84 TestIsWideFn(iswlower, iswlower_l, L"a", L"1A! \b"); 85 } 86 87 TEST(wctype, iswprint) { 88 TestIsWideFn(iswprint, iswprint_l, L"1aA! ", L"\b"); 89 } 90 91 TEST(wctype, iswpunct) { 92 TestIsWideFn(iswpunct, iswpunct_l, L"!", L"1aA \b"); 93 } 94 95 TEST(wctype, iswspace) { 96 TestIsWideFn(iswspace, iswspace_l, L" \f\t", L"1aA!\b"); 97 } 98 99 TEST(wctype, iswupper) { 100 TestIsWideFn(iswupper, iswupper_l, L"A", L"1a! \b"); 101 } 102 103 TEST(wctype, iswxdigit) { 104 TestIsWideFn(iswxdigit, iswxdigit_l, L"01aA", L"xg! \b"); 105 } 106 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 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 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 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 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 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 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 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 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 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 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 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