X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Fconfig%2Flocale%2Fgeneric%2Fc_locale.cc;h=3b9f1bd42a51670c73ef0a4cbe17a566b42de51f;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=689bbf592b930651027d844e08e1d8c0d60e6673;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc index 689bbf59..3b9f1bd4 100644 --- a/libstdc++-v3/config/locale/generic/c_locale.cc +++ b/libstdc++-v3/config/locale/generic/c_locale.cc @@ -1,11 +1,12 @@ // Wrapper for underlying C-language localization -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) +// Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, @@ -13,19 +14,14 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . // // ISO C++ 14882: 22.8 Standard locale categories. @@ -33,188 +29,194 @@ // Written by Benjamin Kosnik +#include // For errno +#include // For isinf, finite, finitef, fabs +#include // For strof, strtold +#include +#include #include +#include +#include -#ifdef _GLIBCPP_HAVE_IEEEFP_H +#ifdef _GLIBCXX_HAVE_IEEEFP_H #include #endif -namespace std -{ - // Specializations for all types used in num_get. - template<> - void - __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, - const __c_locale&, int __base) - { - if (!(__err & ios_base::failbit)) - { - char* __sanity; - errno = 0; - long __l = strtol(__s, &__sanity, __base); - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __l; - else - __err |= ios_base::failbit; - } - } +_GLIBCXX_BEGIN_NAMESPACE(std) template<> void - __convert_to_v(const char* __s, unsigned long& __v, - ios_base::iostate& __err, const __c_locale&, int __base) - { - if (!(__err & ios_base::failbit)) - { - char* __sanity; - errno = 0; - unsigned long __ul = strtoul(__s, &__sanity, __base); - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __ul; - else - __err |= ios_base::failbit; - } - } - -#ifdef _GLIBCPP_USE_LONG_LONG - template<> - void - __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, - const __c_locale&, int __base) + __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, + const __c_locale&) { - if (!(__err & ios_base::failbit)) - { - char* __sanity; - errno = 0; - long long __ll = strtoll(__s, &__sanity, __base); - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __ll; - else - __err |= ios_base::failbit; - } - } + // Assumes __s formatted for "C" locale. + char* __old = setlocale(LC_ALL, NULL); + const size_t __len = strlen(__old) + 1; + char* __sav = new char[__len]; + memcpy(__sav, __old, __len); + setlocale(LC_ALL, "C"); + char* __sanity; + bool __overflow = false; - template<> - void - __convert_to_v(const char* __s, unsigned long long& __v, - ios_base::iostate& __err, const __c_locale&, int __base) - { - if (!(__err & ios_base::failbit)) - { - char* __sanity; - errno = 0; - unsigned long long __ull = strtoull(__s, &__sanity, __base); - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __ull; - else - __err |= ios_base::failbit; - } - } +#if !__FLT_HAS_INFINITY__ + errno = 0; #endif - template<> - void - __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, - const __c_locale&, int) - { - if (!(__err & ios_base::failbit)) - { - // Assumes __s formatted for "C" locale. - char* __old = strdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); - char* __sanity; - errno = 0; -#if defined(_GLIBCPP_USE_C99) - float __f = strtof(__s, &__sanity); +#ifdef _GLIBCXX_HAVE_STRTOF + __v = strtof(__s, &__sanity); #else - double __d = strtod(__s, &__sanity); - float __f = static_cast(__d); -#ifdef _GLIBCPP_HAVE_FINITEF - if (!finitef (__f)) - errno = ERANGE; -#elif defined (_GLIBCPP_HAVE_FINITE) - if (!finite (static_cast (__f))) - errno = ERANGE; -#elif defined (_GLIBCPP_HAVE_ISINF) - if (isinf (static_cast (__f))) - errno = ERANGE; + double __d = strtod(__s, &__sanity); + __v = static_cast(__d); +#ifdef _GLIBCXX_HAVE_FINITEF + if (!finitef (__v)) + __overflow = true; +#elif defined (_GLIBCXX_HAVE_FINITE) + if (!finite (static_cast (__v))) + __overflow = true; +#elif defined (_GLIBCXX_HAVE_ISINF) + if (isinf (static_cast (__v))) + __overflow = true; #else - if (fabs(__d) > numeric_limits::max()) - errno = ERANGE; + if (fabs(__d) > numeric_limits::max()) + __overflow = true; #endif +#endif // _GLIBCXX_HAVE_STRTOF + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 23. Num_get overflow result. + if (__sanity == __s || *__sanity != '\0') + { + __v = 0.0f; + __err = ios_base::failbit; + } + else if (__overflow +#if __FLT_HAS_INFINITY__ + || __v == numeric_limits::infinity() + || __v == -numeric_limits::infinity() +#else + || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE) #endif - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __f; + ) + { + if (__v > 0.0f) + __v = numeric_limits::max(); else - __err |= ios_base::failbit; - setlocale(LC_ALL, __old); - free(__old); + __v = -numeric_limits::max(); + __err = ios_base::failbit; } + + setlocale(LC_ALL, __sav); + delete [] __sav; } template<> void __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, - const __c_locale&, int) + const __c_locale&) { - if (!(__err & ios_base::failbit)) + // Assumes __s formatted for "C" locale. + char* __old = setlocale(LC_ALL, NULL); + const size_t __len = strlen(__old) + 1; + char* __sav = new char[__len]; + memcpy(__sav, __old, __len); + setlocale(LC_ALL, "C"); + char* __sanity; + +#if !__DBL_HAS_INFINITY__ + errno = 0; +#endif + + __v = strtod(__s, &__sanity); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 23. Num_get overflow result. + if (__sanity == __s || *__sanity != '\0') { - // Assumes __s formatted for "C" locale. - char* __old = strdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); - char* __sanity; - errno = 0; - double __d = strtod(__s, &__sanity); - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __d; + __v = 0.0; + __err = ios_base::failbit; + } + else if ( +#if __DBL_HAS_INFINITY__ + __v == numeric_limits::infinity() + || __v == -numeric_limits::infinity()) +#else + (__v > 1.0 || __v < -1.0) && errno == ERANGE) +#endif + { + if (__v > 0.0) + __v = numeric_limits::max(); else - __err |= ios_base::failbit; - setlocale(LC_ALL, __old); - free(__old); + __v = -numeric_limits::max(); + __err = ios_base::failbit; } + + setlocale(LC_ALL, __sav); + delete [] __sav; } template<> void __convert_to_v(const char* __s, long double& __v, - ios_base::iostate& __err, const __c_locale&, int) + ios_base::iostate& __err, const __c_locale&) { - if (!(__err & ios_base::failbit)) - { - // Assumes __s formatted for "C" locale. - char* __old = strdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); -#if defined(_GLIBCPP_USE_C99) - char* __sanity; - errno = 0; - long double __ld = strtold(__s, &__sanity); - if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) - __v = __ld; + // Assumes __s formatted for "C" locale. + char* __old = setlocale(LC_ALL, NULL); + const size_t __len = strlen(__old) + 1; + char* __sav = new char[__len]; + memcpy(__sav, __old, __len); + setlocale(LC_ALL, "C"); + +#if !__LDBL_HAS_INFINITY__ + errno = 0; +#endif + +#if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD) + char* __sanity; + __v = strtold(__s, &__sanity); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 23. Num_get overflow result. + if (__sanity == __s || *__sanity != '\0') #else - typedef char_traits::int_type int_type; - long double __ld; - errno = 0; - int __p = sscanf(__s, "%Lf", &__ld); - if (errno == ERANGE) - __p = 0; -#ifdef _GLIBCPP_HAVE_FINITEL - if ((__p == 1) && !finitel (__ld)) - __p = 0; + typedef char_traits::int_type int_type; + int __p = sscanf(__s, "%Lf", &__v); + + if (!__p || static_cast(__p) == char_traits::eof()) #endif - if (__p && static_cast(__p) != char_traits::eof()) - __v = __ld; + { + __v = 0.0l; + __err = ios_base::failbit; + } + else if ( +#if __LDBL_HAS_INFINITY__ + __v == numeric_limits::infinity() + || __v == -numeric_limits::infinity()) +#else + (__v > 1.0l || __v < -1.0l) && errno == ERANGE) #endif + { + if (__v > 0.0l) + __v = numeric_limits::max(); else - __err |= ios_base::failbit; - setlocale(LC_ALL, __old); - free(__old); + __v = -numeric_limits::max(); + __err = ios_base::failbit; } + + setlocale(LC_ALL, __sav); + delete [] __sav; } void - locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*, + locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, __c_locale) - { __cloc = NULL; } + { + // Currently, the generic model only supports the "C" locale. + // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html + __cloc = NULL; + if (strcmp(__s, "C")) + __throw_runtime_error(__N("locale::facet::_S_create_c_locale " + "name not valid")); + } void locale::facet::_S_destroy_c_locale(__c_locale& __cloc) @@ -224,14 +226,31 @@ namespace std locale::facet::_S_clone_c_locale(__c_locale&) { return __c_locale(); } - const char* locale::_S_categories[_S_categories_size - + _S_extra_categories_size] = +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] = { "LC_CTYPE", - "LC_NUMERIC", + "LC_NUMERIC", + "LC_TIME", "LC_COLLATE", - "LC_TIME", "LC_MONETARY", "LC_MESSAGES" }; -} // namespace std + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + const char* const* const locale::_S_categories = __gnu_cxx::category_names; + +_GLIBCXX_END_NAMESPACE + +// XXX GLIBCXX_ABI Deprecated +#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT +#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ + extern "C" void ldbl (void) __attribute__ ((alias (#dbl))) +_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi); +#endif // _GLIBCXX_LONG_DOUBLE_COMPAT