1// std::numpunct implementation details, DragonFly version -*- C++ -*- 2 3// Copyright (C) 2015-2022 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// 26// ISO C++ 14882: 22.2.3.1.2 numpunct virtual functions 27// 28 29// Written by Benjamin Kosnik <bkoz@redhat.com> 30// Modified for DragonFly by John Marino <gnugcc@marino.st> 31 32#include <locale> 33#include <cstring> 34 35#include "xlocale_port.h" 36 37namespace std _GLIBCXX_VISIBILITY(default) 38{ 39_GLIBCXX_BEGIN_NAMESPACE_VERSION 40 41 template<> 42 void 43 numpunct<char>::_M_initialize_numpunct(__c_locale __cloc) 44 { 45 if (!_M_data) 46 _M_data = new __numpunct_cache<char>; 47 48 if (!__cloc) 49 { 50 // "C" locale 51 _M_data->_M_grouping = ""; 52 _M_data->_M_grouping_size = 0; 53 _M_data->_M_use_grouping = false; 54 55 _M_data->_M_decimal_point = '.'; 56 _M_data->_M_thousands_sep = ','; 57 58 for (size_t __i = 0; __i < __num_base::_S_oend; ++__i) 59 _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i]; 60 61 for (size_t __j = 0; __j < __num_base::_S_iend; ++__j) 62 _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j]; 63 } 64 else 65 { 66 // Named locale. 67 lconv* lc = localeconv_l((locale_t) __cloc); 68 69 // Decimal point should always be defined, but check null anyway 70 if (lc->decimal_point == NULL) 71 { 72 // Not defined, so use "C" locale default 73 _M_data->_M_decimal_point = '.'; 74 } 75 else 76 { 77 _M_data->_M_decimal_point = lc->decimal_point[0]; 78 } 79 // Check for NULL, which implies no grouping. 80 if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0') 81 { 82 // Like in "C" locale. 83 _M_data->_M_grouping = ""; 84 _M_data->_M_grouping_size = 0; 85 _M_data->_M_use_grouping = false; 86 _M_data->_M_thousands_sep = ','; 87 } 88 else 89 { 90 _M_data->_M_thousands_sep = lc->thousands_sep[0]; 91 92 const char* __src = lc->grouping; 93 const size_t __len = strlen(__src); 94 if (__len) 95 { 96 __try 97 { 98 char* __dst = new char[__len + 1]; 99 memcpy(__dst, __src, __len + 1); 100 _M_data->_M_grouping = __dst; 101 _M_data->_M_use_grouping = true; 102 } 103 __catch(...) 104 { 105 delete _M_data; 106 _M_data = 0; 107 __throw_exception_again; 108 } 109 } 110 else 111 { 112 _M_data->_M_grouping = ""; 113 _M_data->_M_use_grouping = false; 114 } 115 _M_data->_M_grouping_size = __len; 116 } 117 } 118 119 // NB: There is no way to extact this info from posix locales. 120 // _M_truename = __nl_langinfo_l(YESSTR, __cloc); 121 _M_data->_M_truename = "true"; 122 _M_data->_M_truename_size = 4; 123 // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); 124 _M_data->_M_falsename = "false"; 125 _M_data->_M_falsename_size = 5; 126 } 127 128 template<> 129 numpunct<char>::~numpunct() 130 { 131 if (_M_data->_M_grouping_size) 132 delete [] _M_data->_M_grouping; 133 delete _M_data; 134 } 135 136#ifdef _GLIBCXX_USE_WCHAR_T 137 template<> 138 void 139 numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc) 140 { 141 if (!_M_data) 142 _M_data = new __numpunct_cache<wchar_t>; 143 144 if (!__cloc) 145 { 146 // "C" locale 147 _M_data->_M_grouping = ""; 148 _M_data->_M_grouping_size = 0; 149 _M_data->_M_use_grouping = false; 150 151 _M_data->_M_decimal_point = L'.'; 152 _M_data->_M_thousands_sep = L','; 153 154 // Use ctype::widen code without the facet... 155 for (size_t __i = 0; __i < __num_base::_S_oend; ++__i) 156 _M_data->_M_atoms_out[__i] = 157 static_cast<wchar_t>(__num_base::_S_atoms_out[__i]); 158 159 for (size_t __j = 0; __j < __num_base::_S_iend; ++__j) 160 _M_data->_M_atoms_in[__j] = 161 static_cast<wchar_t>(__num_base::_S_atoms_in[__j]); 162 } 163 else 164 { 165 // Named locale. 166 lconv* lc = localeconv_l((locale_t) __cloc); 167 168 // Decimal point should always be defined, but check null anyway 169 if (lc->decimal_point == NULL) 170 { 171 // Not defined, so use "C" locale default 172 _M_data->_M_decimal_point = L'.'; 173 } 174 else 175 { 176 _M_data->_M_decimal_point = (wchar_t)lc->decimal_point[0]; 177 } 178 // Check for NULL, which implies no grouping. 179 if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0') 180 { 181 // Like in "C" locale. 182 _M_data->_M_grouping = ""; 183 _M_data->_M_grouping_size = 0; 184 _M_data->_M_use_grouping = false; 185 _M_data->_M_thousands_sep = L','; 186 } 187 else 188 { 189 _M_data->_M_thousands_sep = (wchar_t)lc->thousands_sep[0]; 190 191 const char* __src = lc->grouping; 192 const size_t __len = strlen(__src); 193 if (__len) 194 { 195 __try 196 { 197 char* __dst = new char[__len + 1]; 198 memcpy(__dst, __src, __len + 1); 199 _M_data->_M_grouping = __dst; 200 } 201 __catch(...) 202 { 203 delete _M_data; 204 _M_data = 0; 205 __throw_exception_again; 206 } 207 } 208 else 209 { 210 _M_data->_M_grouping = ""; 211 _M_data->_M_use_grouping = false; 212 } 213 _M_data->_M_grouping_size = __len; 214 } 215 } 216 217 // NB: There is no way to extact this info from posix locales. 218 // _M_truename = __nl_langinfo_l(YESSTR, __cloc); 219 _M_data->_M_truename = L"true"; 220 _M_data->_M_truename_size = 4; 221 // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); 222 _M_data->_M_falsename = L"false"; 223 _M_data->_M_falsename_size = 5; 224 } 225 226 template<> 227 numpunct<wchar_t>::~numpunct() 228 { 229 if (_M_data->_M_grouping_size) 230 delete [] _M_data->_M_grouping; 231 delete _M_data; 232 } 233 #endif 234 235_GLIBCXX_END_NAMESPACE_VERSION 236} // namespace 237