1 // std::ctype implementation details, generic version -*- C++ -*- 2 3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 // 27 // ISO C++ 14882: 22.2.1.1.2 ctype virtual functions. 28 // 29 30 // Written by Benjamin Kosnik <bkoz@redhat.com> 31 32 #include <locale> 33 #include <cstdlib> 34 #include <cstring> 35 #include <cstdio> 36 37 namespace std _GLIBCXX_VISIBILITY(default) 38 { 39 _GLIBCXX_BEGIN_NAMESPACE_VERSION 40 41 // NB: The other ctype<char> specializations are in src/locale.cc and 42 // various /config/os/* files. 43 ctype_byname<char>::ctype_byname(const char* __s, size_t __refs) 44 : ctype<char>(0, false, __refs) 45 { 46 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 47 { 48 this->_S_destroy_c_locale(this->_M_c_locale_ctype); 49 this->_S_create_c_locale(this->_M_c_locale_ctype, __s); 50 } 51 } 52 53 ctype_byname<char>::~ctype_byname() 54 { } 55 56 #ifdef _GLIBCXX_USE_WCHAR_T 57 ctype<wchar_t>::__wmask_type 58 ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw() 59 { 60 __wmask_type __ret; 61 switch (__m) 62 { 63 case space: 64 __ret = wctype("space"); 65 break; 66 case print: 67 __ret = wctype("print"); 68 break; 69 case cntrl: 70 __ret = wctype("cntrl"); 71 break; 72 case upper: 73 __ret = wctype("upper"); 74 break; 75 case lower: 76 __ret = wctype("lower"); 77 break; 78 case alpha: 79 __ret = wctype("alpha"); 80 break; 81 case digit: 82 __ret = wctype("digit"); 83 break; 84 case punct: 85 __ret = wctype("punct"); 86 break; 87 case xdigit: 88 __ret = wctype("xdigit"); 89 break; 90 case alnum: 91 __ret = wctype("alnum"); 92 break; 93 case graph: 94 __ret = wctype("graph"); 95 break; 96 default: 97 __ret = __wmask_type(); 98 } 99 return __ret; 100 }; 101 102 wchar_t 103 ctype<wchar_t>::do_toupper(wchar_t __c) const 104 { return towupper(__c); } 105 106 const wchar_t* 107 ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const 108 { 109 while (__lo < __hi) 110 { 111 *__lo = towupper(*__lo); 112 ++__lo; 113 } 114 return __hi; 115 } 116 117 wchar_t 118 ctype<wchar_t>::do_tolower(wchar_t __c) const 119 { return towlower(__c); } 120 121 const wchar_t* 122 ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const 123 { 124 while (__lo < __hi) 125 { 126 *__lo = towlower(*__lo); 127 ++__lo; 128 } 129 return __hi; 130 } 131 132 bool 133 ctype<wchar_t>:: 134 do_is(mask __m, char_type __c) const 135 { 136 bool __ret = false; 137 // Generically, 15 (instead of 10) since we don't know the numerical 138 // encoding of the various categories in /usr/include/ctype.h. 139 const size_t __bitmasksize = 15; 140 for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) 141 if (__m & _M_bit[__bitcur] 142 && iswctype(__c, _M_wmask[__bitcur])) 143 { 144 __ret = true; 145 break; 146 } 147 return __ret; 148 } 149 150 const wchar_t* 151 ctype<wchar_t>:: 152 do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const 153 { 154 for (;__lo < __hi; ++__vec, ++__lo) 155 { 156 // Generically, 15 (instead of 10) since we don't know the numerical 157 // encoding of the various categories in /usr/include/ctype.h. 158 const size_t __bitmasksize = 15; 159 mask __m = 0; 160 for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) 161 if (iswctype(*__lo, _M_wmask[__bitcur])) 162 __m |= _M_bit[__bitcur]; 163 *__vec = __m; 164 } 165 return __hi; 166 } 167 168 const wchar_t* 169 ctype<wchar_t>:: 170 do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const 171 { 172 while (__lo < __hi && !this->do_is(__m, *__lo)) 173 ++__lo; 174 return __lo; 175 } 176 177 const wchar_t* 178 ctype<wchar_t>:: 179 do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const 180 { 181 while (__lo < __hi && this->do_is(__m, *__lo) != 0) 182 ++__lo; 183 return __lo; 184 } 185 186 wchar_t 187 ctype<wchar_t>:: 188 do_widen(char __c) const 189 { return _M_widen[static_cast<unsigned char>(__c)]; } 190 191 const char* 192 ctype<wchar_t>:: 193 do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const 194 { 195 while (__lo < __hi) 196 { 197 *__dest = _M_widen[static_cast<unsigned char>(*__lo)]; 198 ++__lo; 199 ++__dest; 200 } 201 return __hi; 202 } 203 204 char 205 ctype<wchar_t>:: 206 do_narrow(wchar_t __wc, char __dfault) const 207 { 208 if (__wc >= 0 && __wc < 128 && _M_narrow_ok) 209 return _M_narrow[__wc]; 210 const int __c = wctob(__wc); 211 return (__c == EOF ? __dfault : static_cast<char>(__c)); 212 } 213 214 const wchar_t* 215 ctype<wchar_t>:: 216 do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 217 char* __dest) const 218 { 219 if (_M_narrow_ok) 220 while (__lo < __hi) 221 { 222 if (*__lo >= 0 && *__lo < 128) 223 *__dest = _M_narrow[*__lo]; 224 else 225 { 226 const int __c = wctob(*__lo); 227 *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); 228 } 229 ++__lo; 230 ++__dest; 231 } 232 else 233 while (__lo < __hi) 234 { 235 const int __c = wctob(*__lo); 236 *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); 237 ++__lo; 238 ++__dest; 239 } 240 return __hi; 241 } 242 243 void 244 ctype<wchar_t>::_M_initialize_ctype() throw() 245 { 246 wint_t __i; 247 for (__i = 0; __i < 128; ++__i) 248 { 249 const int __c = wctob(__i); 250 if (__c == EOF) 251 break; 252 else 253 _M_narrow[__i] = static_cast<char>(__c); 254 } 255 if (__i == 128) 256 _M_narrow_ok = true; 257 else 258 _M_narrow_ok = false; 259 for (size_t __i = 0; 260 __i < sizeof(_M_widen) / sizeof(wint_t); ++__i) 261 _M_widen[__i] = btowc(__i); 262 263 for (size_t __i = 0; __i <= 15; ++__i) 264 { 265 _M_bit[__i] = static_cast<mask>(1 << __i); 266 _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]); 267 } 268 } 269 #endif // _GLIBCXX_USE_WCHAR_T 270 271 _GLIBCXX_END_NAMESPACE_VERSION 272 } // namespace 273