1 $NetBSD: patch-libstdc++-v3_config_locale_dragonfly_c__locale.cc,v 1.1 2012/06/23 22:13:02 marino Exp $
3 --- libstdc++-v3/config/locale/dragonfly/c_locale.cc.orig 2012-06-22 10:35:30.000000000 +0000
4 +++ libstdc++-v3/config/locale/dragonfly/c_locale.cc
6 +// Wrapper for underlying C-language localization -*- C++ -*-
8 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
9 +// Free Software Foundation, Inc.
11 +// This file is part of the GNU ISO C++ Library. This library is free
12 +// software; you can redistribute it and/or modify it under the
13 +// terms of the GNU General Public License as published by the
14 +// Free Software Foundation; either version 3, or (at your option)
15 +// any later version.
17 +// This library is distributed in the hope that it will be useful,
18 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 +// GNU General Public License for more details.
22 +// Under Section 7 of GPL version 3, you are granted additional
23 +// permissions described in the GCC Runtime Library Exception, version
24 +// 3.1, as published by the Free Software Foundation.
26 +// You should have received a copy of the GNU General Public License and
27 +// a copy of the GCC Runtime Library Exception along with this program;
28 +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
29 +// <http://www.gnu.org/licenses/>.
32 +// ISO C++ 14882: 22.8 Standard locale categories.
35 +// Written by Benjamin Kosnik <bkoz@redhat.com>
37 +#include <cerrno> // For errno
38 +#include <cmath> // For isinf, finite, finitef, fabs
39 +#include <cstdlib> // For strof, strtold
45 +#ifdef _GLIBCXX_HAVE_IEEEFP_H
49 +namespace std _GLIBCXX_VISIBILITY(default)
51 +_GLIBCXX_BEGIN_NAMESPACE_VERSION
55 + __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
56 + const __c_locale&) throw()
58 + // Assumes __s formatted for "C" locale.
59 + char* __old = setlocale(LC_ALL, 0);
60 + const size_t __len = strlen(__old) + 1;
61 + char* __sav = new char[__len];
62 + memcpy(__sav, __old, __len);
63 + setlocale(LC_ALL, "C");
65 + bool __overflow = false;
67 +#if !__FLT_HAS_INFINITY__
71 +#ifdef _GLIBCXX_HAVE_STRTOF
72 + __v = strtof(__s, &__sanity);
74 + double __d = strtod(__s, &__sanity);
75 + __v = static_cast<float>(__d);
76 +#ifdef _GLIBCXX_HAVE_FINITEF
79 +#elif defined (_GLIBCXX_HAVE_FINITE)
80 + if (!finite (static_cast<double> (__v)))
82 +#elif defined (_GLIBCXX_HAVE_ISINF)
83 + if (isinf (static_cast<double> (__v)))
86 + if (fabs(__d) > numeric_limits<float>::max())
89 +#endif // _GLIBCXX_HAVE_STRTOF
91 + // _GLIBCXX_RESOLVE_LIB_DEFECTS
92 + // 23. Num_get overflow result.
93 + if (__sanity == __s || *__sanity != '\0')
96 + __err = ios_base::failbit;
99 +#if __FLT_HAS_INFINITY__
100 + || __v == numeric_limits<float>::infinity()
101 + || __v == -numeric_limits<float>::infinity()
103 + || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
108 + __v = numeric_limits<float>::max();
110 + __v = -numeric_limits<float>::max();
111 + __err = ios_base::failbit;
114 + setlocale(LC_ALL, __sav);
120 + __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
121 + const __c_locale&) throw()
123 + // Assumes __s formatted for "C" locale.
124 + char* __old = setlocale(LC_ALL, 0);
125 + const size_t __len = strlen(__old) + 1;
126 + char* __sav = new char[__len];
127 + memcpy(__sav, __old, __len);
128 + setlocale(LC_ALL, "C");
131 +#if !__DBL_HAS_INFINITY__
135 + __v = strtod(__s, &__sanity);
137 + // _GLIBCXX_RESOLVE_LIB_DEFECTS
138 + // 23. Num_get overflow result.
139 + if (__sanity == __s || *__sanity != '\0')
142 + __err = ios_base::failbit;
145 +#if __DBL_HAS_INFINITY__
146 + __v == numeric_limits<double>::infinity()
147 + || __v == -numeric_limits<double>::infinity())
149 + (__v > 1.0 || __v < -1.0) && errno == ERANGE)
153 + __v = numeric_limits<double>::max();
155 + __v = -numeric_limits<double>::max();
156 + __err = ios_base::failbit;
159 + setlocale(LC_ALL, __sav);
165 + __convert_to_v(const char* __s, long double& __v,
166 + ios_base::iostate& __err, const __c_locale&) throw()
168 + // Assumes __s formatted for "C" locale.
169 + char* __old = setlocale(LC_ALL, 0);
170 + const size_t __len = strlen(__old) + 1;
171 + char* __sav = new char[__len];
172 + memcpy(__sav, __old, __len);
173 + setlocale(LC_ALL, "C");
175 +#if !__LDBL_HAS_INFINITY__
179 +#if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
181 + __v = strtold(__s, &__sanity);
183 + // _GLIBCXX_RESOLVE_LIB_DEFECTS
184 + // 23. Num_get overflow result.
185 + if (__sanity == __s || *__sanity != '\0')
187 + typedef char_traits<char>::int_type int_type;
188 + int __p = sscanf(__s, "%Lf", &__v);
190 + if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
194 + __err = ios_base::failbit;
197 +#if __LDBL_HAS_INFINITY__
198 + __v == numeric_limits<long double>::infinity()
199 + || __v == -numeric_limits<long double>::infinity())
201 + (__v > 1.0l || __v < -1.0l) && errno == ERANGE)
205 + __v = numeric_limits<long double>::max();
207 + __v = -numeric_limits<long double>::max();
208 + __err = ios_base::failbit;
211 + setlocale(LC_ALL, __sav);
216 + /* DragonFly's implementation of setlocale won't accept something like
217 + "de_DE". According to nls manpage, the expected format is:
218 + language[_territory][.codeset][@modifier], but it seems that both
219 + the _territory and .codeset components are required.
221 + As an attempt to correct for this, we'll tack on ".UTF-8" if
222 + a period is not detected in the locale string.
224 + There are no locales with modifiers on DragonFly so if found, they
225 + will just be stripped off silently. e.g "de_DE@euro" will be reduced
226 + to "de_DE". The UTF-8 default would be added after that.
230 + locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
233 + const size_t size__s = (__s == NULL) ? 1 : strlen (__s);
234 + const char UTF8[] = ".UTF-8";
235 + char localspec[size__s + 6 + 1];
238 + localspec[0] = NULL;
240 + strcpy (localspec, __s);
241 + char * pch = strchr (localspec, '@');
245 + if ( (strchr (__s, '.') == NULL)
246 + && (strcmp (__s, "C") != 0)
247 + && (strcmp (__s, "POSIX") != 0))
248 + strncat (localspec, UTF8, 6);
251 + const char * result = std::setlocale(LC_ALL, localspec);
253 + if ((strcmp(result, "C") != 0) && (strcmp (result, localspec) != 0))
254 + __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
255 + "name not valid"));
260 + locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
264 + locale::facet::_S_clone_c_locale(__c_locale&) throw()
265 + { return __c_locale(); }
268 + locale::facet::_S_lc_ctype_c_locale(__c_locale, const char*)
269 + { return __c_locale(); }
271 +_GLIBCXX_END_NAMESPACE_VERSION
274 +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
276 +_GLIBCXX_BEGIN_NAMESPACE_VERSION
278 + const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
288 +_GLIBCXX_END_NAMESPACE_VERSION
291 +namespace std _GLIBCXX_VISIBILITY(default)
293 +_GLIBCXX_BEGIN_NAMESPACE_VERSION
295 + const char* const* const locale::_S_categories = __gnu_cxx::category_names;
297 +_GLIBCXX_END_NAMESPACE_VERSION
300 +// XXX GLIBCXX_ABI Deprecated
301 +#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
302 +#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
303 + extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
304 +_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
305 +#endif // _GLIBCXX_LONG_DOUBLE_COMPAT