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