1// std::numpunct implementation details, GNU version -*- C++ -*- 2 3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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.3.1.2 numpunct virtual functions 28// 29 30// Written by Benjamin Kosnik <bkoz@redhat.com> 31 32#include <locale> 33#include <bits/c++locale_internal.h> 34 35_GLIBCXX_BEGIN_NAMESPACE(std) 36 37 template<> 38 void 39 numpunct<char>::_M_initialize_numpunct(__c_locale __cloc) 40 { 41 if (!_M_data) 42 _M_data = new __numpunct_cache<char>; 43 44 if (!__cloc) 45 { 46 // "C" locale 47 _M_data->_M_grouping = ""; 48 _M_data->_M_grouping_size = 0; 49 _M_data->_M_use_grouping = false; 50 51 _M_data->_M_decimal_point = '.'; 52 _M_data->_M_thousands_sep = ','; 53 54 for (size_t __i = 0; __i < __num_base::_S_oend; ++__i) 55 _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i]; 56 57 for (size_t __j = 0; __j < __num_base::_S_iend; ++__j) 58 _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j]; 59 } 60 else 61 { 62 // Named locale. 63 _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT, 64 __cloc)); 65 _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP, 66 __cloc)); 67 68 // Check for NULL, which implies no grouping. 69 if (_M_data->_M_thousands_sep == '\0') 70 { 71 // Like in "C" locale. 72 _M_data->_M_grouping = ""; 73 _M_data->_M_grouping_size = 0; 74 _M_data->_M_use_grouping = false; 75 _M_data->_M_thousands_sep = ','; 76 } 77 else 78 { 79 const char* __src = __nl_langinfo_l(GROUPING, __cloc); 80 const size_t __len = strlen(__src); 81 if (__len) 82 { 83 __try 84 { 85 char* __dst = new char[__len + 1]; 86 memcpy(__dst, __src, __len + 1); 87 _M_data->_M_grouping = __dst; 88 } 89 __catch(...) 90 { 91 delete _M_data; 92 _M_data = 0; 93 __throw_exception_again; 94 } 95 } 96 else 97 { 98 _M_data->_M_grouping = ""; 99 _M_data->_M_use_grouping = false; 100 } 101 _M_data->_M_grouping_size = __len; 102 } 103 } 104 105 // NB: There is no way to extact this info from posix locales. 106 // _M_truename = __nl_langinfo_l(YESSTR, __cloc); 107 _M_data->_M_truename = "true"; 108 _M_data->_M_truename_size = 4; 109 // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); 110 _M_data->_M_falsename = "false"; 111 _M_data->_M_falsename_size = 5; 112 } 113 114 template<> 115 numpunct<char>::~numpunct() 116 { 117 if (_M_data->_M_grouping_size) 118 delete [] _M_data->_M_grouping; 119 delete _M_data; 120 } 121 122#ifdef _GLIBCXX_USE_WCHAR_T 123 template<> 124 void 125 numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc) 126 { 127 if (!_M_data) 128 _M_data = new __numpunct_cache<wchar_t>; 129 130 if (!__cloc) 131 { 132 // "C" locale 133 _M_data->_M_grouping = ""; 134 _M_data->_M_grouping_size = 0; 135 _M_data->_M_use_grouping = false; 136 137 _M_data->_M_decimal_point = L'.'; 138 _M_data->_M_thousands_sep = L','; 139 140 // Use ctype::widen code without the facet... 141 for (size_t __i = 0; __i < __num_base::_S_oend; ++__i) 142 _M_data->_M_atoms_out[__i] = 143 static_cast<wchar_t>(__num_base::_S_atoms_out[__i]); 144 145 for (size_t __j = 0; __j < __num_base::_S_iend; ++__j) 146 _M_data->_M_atoms_in[__j] = 147 static_cast<wchar_t>(__num_base::_S_atoms_in[__j]); 148 } 149 else 150 { 151 // Named locale. 152 // NB: In the GNU model wchar_t is always 32 bit wide. 153 union { char *__s; wchar_t __w; } __u; 154 __u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc); 155 _M_data->_M_decimal_point = __u.__w; 156 157 __u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc); 158 _M_data->_M_thousands_sep = __u.__w; 159 160 // Check for NULL, which implies no grouping. 161 if (_M_data->_M_thousands_sep == L'\0') 162 { 163 // Like in "C" locale. 164 _M_data->_M_grouping = ""; 165 _M_data->_M_grouping_size = 0; 166 _M_data->_M_use_grouping = false; 167 _M_data->_M_thousands_sep = L','; 168 } 169 else 170 { 171 const char* __src = __nl_langinfo_l(GROUPING, __cloc); 172 const size_t __len = strlen(__src); 173 if (__len) 174 { 175 __try 176 { 177 char* __dst = new char[__len + 1]; 178 memcpy(__dst, __src, __len + 1); 179 _M_data->_M_grouping = __dst; 180 } 181 __catch(...) 182 { 183 delete _M_data; 184 _M_data = 0; 185 __throw_exception_again; 186 } 187 } 188 else 189 { 190 _M_data->_M_grouping = ""; 191 _M_data->_M_use_grouping = false; 192 } 193 _M_data->_M_grouping_size = __len; 194 } 195 } 196 197 // NB: There is no way to extact this info from posix locales. 198 // _M_truename = __nl_langinfo_l(YESSTR, __cloc); 199 _M_data->_M_truename = L"true"; 200 _M_data->_M_truename_size = 4; 201 // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); 202 _M_data->_M_falsename = L"false"; 203 _M_data->_M_falsename_size = 5; 204 } 205 206 template<> 207 numpunct<wchar_t>::~numpunct() 208 { 209 if (_M_data->_M_grouping_size) 210 delete [] _M_data->_M_grouping; 211 delete _M_data; 212 } 213 #endif 214 215_GLIBCXX_END_NAMESPACE 216