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_GLIBCXX_BEGIN_NAMESPACE(std) 38 39 // NB: The other ctype<char> specializations are in src/locale.cc and 40 // various /config/os/* files. 41 ctype_byname<char>::ctype_byname(const char* __s, size_t __refs) 42 : ctype<char>(0, false, __refs) 43 { 44 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 45 { 46 this->_S_destroy_c_locale(this->_M_c_locale_ctype); 47 this->_S_create_c_locale(this->_M_c_locale_ctype, __s); 48 } 49 } 50 51 ctype_byname<char>::~ctype_byname() 52 { } 53 54#ifdef _GLIBCXX_USE_WCHAR_T 55 ctype<wchar_t>::__wmask_type 56 ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw() 57 { 58 __wmask_type __ret; 59 switch (__m) 60 { 61 case space: 62 __ret = wctype("space"); 63 break; 64 case print: 65 __ret = wctype("print"); 66 break; 67 case cntrl: 68 __ret = wctype("cntrl"); 69 break; 70 case upper: 71 __ret = wctype("upper"); 72 break; 73 case lower: 74 __ret = wctype("lower"); 75 break; 76 case alpha: 77 __ret = wctype("alpha"); 78 break; 79 case digit: 80 __ret = wctype("digit"); 81 break; 82 case punct: 83 __ret = wctype("punct"); 84 break; 85 case xdigit: 86 __ret = wctype("xdigit"); 87 break; 88 case alnum: 89 __ret = wctype("alnum"); 90 break; 91 case graph: 92 __ret = wctype("graph"); 93 break; 94 default: 95 __ret = __wmask_type(); 96 } 97 return __ret; 98 }; 99 100 wchar_t 101 ctype<wchar_t>::do_toupper(wchar_t __c) const 102 { return towupper(__c); } 103 104 const wchar_t* 105 ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const 106 { 107 while (__lo < __hi) 108 { 109 *__lo = towupper(*__lo); 110 ++__lo; 111 } 112 return __hi; 113 } 114 115 wchar_t 116 ctype<wchar_t>::do_tolower(wchar_t __c) const 117 { return towlower(__c); } 118 119 const wchar_t* 120 ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const 121 { 122 while (__lo < __hi) 123 { 124 *__lo = towlower(*__lo); 125 ++__lo; 126 } 127 return __hi; 128 } 129 130 bool 131 ctype<wchar_t>:: 132 do_is(mask __m, char_type __c) const 133 { 134 bool __ret = false; 135 // Generically, 15 (instead of 10) since we don't know the numerical 136 // encoding of the various categories in /usr/include/ctype.h. 137 const size_t __bitmasksize = 15; 138 for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) 139 if (__m & _M_bit[__bitcur] 140 && iswctype(__c, _M_wmask[__bitcur])) 141 { 142 __ret = true; 143 break; 144 } 145 return __ret; 146 } 147 148 const wchar_t* 149 ctype<wchar_t>:: 150 do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const 151 { 152 for (;__lo < __hi; ++__vec, ++__lo) 153 { 154 // Generically, 15 (instead of 10) since we don't know the numerical 155 // encoding of the various categories in /usr/include/ctype.h. 156 const size_t __bitmasksize = 15; 157 mask __m = 0; 158 for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) 159 if (iswctype(*__lo, _M_wmask[__bitcur])) 160 __m |= _M_bit[__bitcur]; 161 *__vec = __m; 162 } 163 return __hi; 164 } 165 166 const wchar_t* 167 ctype<wchar_t>:: 168 do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const 169 { 170 while (__lo < __hi && !this->do_is(__m, *__lo)) 171 ++__lo; 172 return __lo; 173 } 174 175 const wchar_t* 176 ctype<wchar_t>:: 177 do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const 178 { 179 while (__lo < __hi && this->do_is(__m, *__lo) != 0) 180 ++__lo; 181 return __lo; 182 } 183 184 wchar_t 185 ctype<wchar_t>:: 186 do_widen(char __c) const 187 { return _M_widen[static_cast<unsigned char>(__c)]; } 188 189 const char* 190 ctype<wchar_t>:: 191 do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const 192 { 193 while (__lo < __hi) 194 { 195 *__dest = _M_widen[static_cast<unsigned char>(*__lo)]; 196 ++__lo; 197 ++__dest; 198 } 199 return __hi; 200 } 201 202 char 203 ctype<wchar_t>:: 204 do_narrow(wchar_t __wc, char __dfault) const 205 { 206 if (__wc >= 0 && __wc < 128 && _M_narrow_ok) 207 return _M_narrow[__wc]; 208 const int __c = wctob(__wc); 209 return (__c == EOF ? __dfault : static_cast<char>(__c)); 210 } 211 212 const wchar_t* 213 ctype<wchar_t>:: 214 do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 215 char* __dest) const 216 { 217 if (_M_narrow_ok) 218 while (__lo < __hi) 219 { 220 if (*__lo >= 0 && *__lo < 128) 221 *__dest = _M_narrow[*__lo]; 222 else 223 { 224 const int __c = wctob(*__lo); 225 *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); 226 } 227 ++__lo; 228 ++__dest; 229 } 230 else 231 while (__lo < __hi) 232 { 233 const int __c = wctob(*__lo); 234 *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); 235 ++__lo; 236 ++__dest; 237 } 238 return __hi; 239 } 240 241 void 242 ctype<wchar_t>::_M_initialize_ctype() throw() 243 { 244 wint_t __i; 245 for (__i = 0; __i < 128; ++__i) 246 { 247 const int __c = wctob(__i); 248 if (__c == EOF) 249 break; 250 else 251 _M_narrow[__i] = static_cast<char>(__c); 252 } 253 if (__i == 128) 254 _M_narrow_ok = true; 255 else 256 _M_narrow_ok = false; 257 for (size_t __i = 0; 258 __i < sizeof(_M_widen) / sizeof(wint_t); ++__i) 259 _M_widen[__i] = btowc(__i); 260 261 for (size_t __i = 0; __i <= 15; ++__i) 262 { 263 _M_bit[__i] = static_cast<mask>(1 << __i); 264 _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]); 265 } 266 } 267#endif // _GLIBCXX_USE_WCHAR_T 268 269_GLIBCXX_END_NAMESPACE 270