1 // Locale support -*- C++ -*- 2 3 // Copyright (C) 2011-2016 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file ctype_configure_char.cc */ 26 27 // 28 // ISO C++ 14882: 22.1 Locales 29 // 30 31 #include <locale> 32 #include <cstdlib> 33 #include <cstring> 34 35 namespace std _GLIBCXX_VISIBILITY(default) 36 { 37 _GLIBCXX_BEGIN_NAMESPACE_VERSION 38 39 // Information as gleaned from /usr/include/ctype.h 40 41 #if _GLIBCXX_C_LOCALE_GNU 42 const ctype_base::mask* classic_table()43 ctype<char>::classic_table() throw() 44 { return _S_get_c_locale()->__ctype_b; } 45 #else 46 const ctype_base::mask* 47 ctype<char>::classic_table() throw() 48 { 49 const ctype_base::mask* __ret; 50 char* __old = setlocale(LC_CTYPE, NULL); 51 char* __sav = NULL; 52 if (__builtin_strcmp(__old, "C")) 53 { 54 const size_t __len = __builtin_strlen(__old) + 1; 55 __sav = new char[__len]; 56 __builtin_memcpy(__sav, __old, __len); 57 setlocale(LC_CTYPE, "C"); 58 } 59 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 60 __ret = *__ctype_b_loc(); 61 #else 62 __ret = __ctype_b; 63 #endif 64 if (__sav) 65 { 66 setlocale(LC_CTYPE, __sav); 67 delete [] __sav; 68 } 69 return __ret; 70 } 71 #endif 72 73 #if _GLIBCXX_C_LOCALE_GNU ctype(__c_locale __cloc,const mask * __table,bool __del,size_t __refs)74 ctype<char>::ctype(__c_locale __cloc, const mask* __table, bool __del, 75 size_t __refs) 76 : facet(__refs), _M_c_locale_ctype(_S_clone_c_locale(__cloc)), 77 _M_del(__table != 0 && __del), 78 _M_toupper(_M_c_locale_ctype->__ctype_toupper), 79 _M_tolower(_M_c_locale_ctype->__ctype_tolower), 80 _M_table(__table ? __table : _M_c_locale_ctype->__ctype_b), 81 _M_widen_ok(0), _M_narrow_ok(0) 82 { 83 __builtin_memset(_M_widen, 0, sizeof(_M_widen)); 84 __builtin_memset(_M_narrow, 0, sizeof(_M_narrow)); 85 } 86 #else ctype(__c_locale,const mask * __table,bool __del,size_t __refs)87 ctype<char>::ctype(__c_locale, const mask* __table, bool __del, 88 size_t __refs) 89 : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), 90 _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0) 91 { 92 char* __old = setlocale(LC_CTYPE, NULL); 93 char* __sav = NULL; 94 if (__builtin_strcmp(__old, "C")) 95 { 96 const size_t __len = __builtin_strlen(__old) + 1; 97 __sav = new char[__len]; 98 __builtin_memcpy(__sav, __old, __len); 99 setlocale(LC_CTYPE, "C"); 100 } 101 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 102 _M_toupper = *__ctype_toupper_loc(); 103 _M_tolower = *__ctype_tolower_loc(); 104 _M_table = __table ? __table : *__ctype_b_loc(); 105 #else 106 _M_toupper = __ctype_toupper; 107 _M_tolower = __ctype_tolower; 108 _M_table = __table ? __table : __ctype_b; 109 #endif 110 if (__sav) 111 { 112 setlocale(LC_CTYPE, __sav); 113 delete [] __sav; 114 } 115 __builtin_memset(_M_widen, 0, sizeof(_M_widen)); 116 __builtin_memset(_M_narrow, 0, sizeof(_M_narrow)); 117 } 118 #endif 119 120 #if _GLIBCXX_C_LOCALE_GNU ctype(const mask * __table,bool __del,size_t __refs)121 ctype<char>::ctype(const mask* __table, bool __del, size_t __refs) 122 : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), 123 _M_del(__table != 0 && __del), 124 _M_toupper(_M_c_locale_ctype->__ctype_toupper), 125 _M_tolower(_M_c_locale_ctype->__ctype_tolower), 126 _M_table(__table ? __table : _M_c_locale_ctype->__ctype_b), 127 _M_widen_ok(0), _M_narrow_ok(0) 128 { 129 __builtin_memset(_M_widen, 0, sizeof(_M_widen)); 130 __builtin_memset(_M_narrow, 0, sizeof(_M_narrow)); 131 } 132 #else ctype(const mask * __table,bool __del,size_t __refs)133 ctype<char>::ctype(const mask* __table, bool __del, size_t __refs) 134 : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), 135 _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0) 136 { 137 char* __old = setlocale(LC_CTYPE, NULL); 138 char* __sav = NULL; 139 if (__builtin_strcmp(__old, "C")) 140 { 141 const size_t __len = __builtin_strlen(__old) + 1; 142 __sav = new char[__len]; 143 __builtin_memcpy(__sav, __old, __len); 144 setlocale(LC_CTYPE, "C"); 145 } 146 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 147 _M_toupper = *__ctype_toupper_loc(); 148 _M_tolower = *__ctype_tolower_loc(); 149 _M_table = __table ? __table : *__ctype_b_loc(); 150 #else 151 _M_toupper = __ctype_toupper; 152 _M_tolower = __ctype_tolower; 153 _M_table = __table ? __table : __ctype_b; 154 #endif 155 if (__sav) 156 { 157 setlocale(LC_CTYPE, __sav); 158 delete [] __sav; 159 } 160 __builtin_memset(_M_widen, 0, sizeof(_M_widen)); 161 __builtin_memset(_M_narrow, 0, sizeof(_M_narrow)); 162 } 163 #endif 164 165 char do_toupper(char __c) const166 ctype<char>::do_toupper(char __c) const 167 { return _M_toupper[static_cast<unsigned char>(__c)]; } 168 169 const char* do_toupper(char * __low,const char * __high) const170 ctype<char>::do_toupper(char* __low, const char* __high) const 171 { 172 while (__low < __high) 173 { 174 *__low = _M_toupper[static_cast<unsigned char>(*__low)]; 175 ++__low; 176 } 177 return __high; 178 } 179 180 char do_tolower(char __c) const181 ctype<char>::do_tolower(char __c) const 182 { return _M_tolower[static_cast<unsigned char>(__c)]; } 183 184 const char* do_tolower(char * __low,const char * __high) const185 ctype<char>::do_tolower(char* __low, const char* __high) const 186 { 187 while (__low < __high) 188 { 189 *__low = _M_tolower[static_cast<unsigned char>(*__low)]; 190 ++__low; 191 } 192 return __high; 193 } 194 195 _GLIBCXX_END_NAMESPACE_VERSION 196 } // namespace 197