1 // std::ctype implementation details, GNU 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 // NB: The other ctype<char> specializations are in src/locale.cc and 40 // various /config/os/* files. 41 42 ctype_byname<char>::ctype_byname(const char* __s, size_t __refs) 43 : ctype<char>(0, false, __refs) 44 { 45 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 46 { 47 this->_S_destroy_c_locale(this->_M_c_locale_ctype); 48 this->_S_create_c_locale(this->_M_c_locale_ctype, __s); 49 } 50 } 51 52 ctype_byname<char>::~ctype_byname() 53 { } 54 55 #ifdef _GLIBCXX_USE_WCHAR_T 56 ctype<wchar_t>::__wmask_type 57 ctype<wchar_t>::_M_convert_to_wmask( 58 const mask __attribute__((__unused__)) __m) const throw() 59 { 60 // DragonFly uses the same codes for 'char' as 'wchar_t', so this routine 61 // never gets called. 62 return __wmask_type(); 63 }; 64 65 wchar_t 66 ctype<wchar_t>::do_toupper(wchar_t __c) const 67 { return towupper(__c); } 68 69 const wchar_t* 70 ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const 71 { 72 while (__lo < __hi) 73 { 74 *__lo = towupper(*__lo); 75 ++__lo; 76 } 77 return __hi; 78 } 79 80 wchar_t 81 ctype<wchar_t>::do_tolower(wchar_t __c) const 82 { return towlower(__c); } 83 84 const wchar_t* 85 ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const 86 { 87 while (__lo < __hi) 88 { 89 *__lo = towlower(*__lo); 90 ++__lo; 91 } 92 return __hi; 93 } 94 95 wchar_t 96 ctype<wchar_t>:: 97 do_widen(char __c) const 98 { return _M_widen[static_cast<unsigned char>(__c)]; } 99 100 const char* 101 ctype<wchar_t>:: 102 do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const 103 { 104 while (__lo < __hi) 105 { 106 *__dest = _M_widen[static_cast<unsigned char>(*__lo)]; 107 ++__lo; 108 ++__dest; 109 } 110 return __hi; 111 } 112 113 char 114 ctype<wchar_t>:: 115 do_narrow(wchar_t __wc, char __dfault) const 116 { 117 if (__wc >= 0 && __wc < 128 && _M_narrow_ok) 118 return _M_narrow[__wc]; 119 const int __c = wctob(__wc); 120 return (__c == EOF ? __dfault : static_cast<char>(__c)); 121 } 122 123 const wchar_t* 124 ctype<wchar_t>:: 125 do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 126 char* __dest) const 127 { 128 if (_M_narrow_ok) 129 while (__lo < __hi) 130 { 131 if (*__lo >= 0 && *__lo < 128) 132 *__dest = _M_narrow[*__lo]; 133 else 134 { 135 const int __c = wctob(*__lo); 136 *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); 137 } 138 ++__lo; 139 ++__dest; 140 } 141 else 142 while (__lo < __hi) 143 { 144 const int __c = wctob(*__lo); 145 *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); 146 ++__lo; 147 ++__dest; 148 } 149 return __hi; 150 } 151 152 void 153 ctype<wchar_t>::_M_initialize_ctype() throw() 154 { 155 wint_t __i; 156 for (__i = 0; __i < 128; ++__i) 157 { 158 const int __c = wctob(__i); 159 if (__c == EOF) 160 break; 161 else 162 _M_narrow[__i] = static_cast<char>(__c); 163 } 164 if (__i == 128) 165 _M_narrow_ok = true; 166 else 167 _M_narrow_ok = false; 168 for (size_t __i = 0; 169 __i < sizeof(_M_widen) / sizeof(wint_t); ++__i) 170 _M_widen[__i] = btowc(__i); 171 } 172 #endif // _GLIBCXX_USE_WCHAR_T 173 } 174