Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Wrapper for underlying C-language localization -*- C++ -*-
  2.  
  3. // Copyright (C) 2001-2013 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.8  Standard locale categories.
  27. //
  28.  
  29. // Written by Benjamin Kosnik <bkoz@redhat.com>
  30.  
  31. #include <cerrno>  // For errno
  32. #include <cmath>  // For isinf, finite, finitef, fabs
  33. #include <cstdlib>  // For strof, strtold
  34. #include <cstring>
  35. #include <cstdio>
  36. #include <locale>
  37. #include <limits>
  38.  
  39. #ifdef _GLIBCXX_HAVE_IEEEFP_H
  40. #include <ieeefp.h>
  41. #endif
  42.  
  43. namespace std _GLIBCXX_VISIBILITY(default)
  44. {
  45. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  46.  
  47.   template<>
  48.     void
  49.     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
  50.                    const __c_locale&) throw()
  51.     {
  52.       // Assumes __s formatted for "C" locale.
  53.       char* __old = setlocale(LC_ALL, 0);
  54.       const size_t __len = strlen(__old) + 1;
  55.       char* __sav = new char[__len];
  56.       memcpy(__sav, __old, __len);
  57.       setlocale(LC_ALL, "C");
  58.       char* __sanity;
  59.       bool __overflow = false;
  60.  
  61. #if !__FLT_HAS_INFINITY__
  62.       errno = 0;
  63. #endif
  64.  
  65. #ifdef _GLIBCXX_HAVE_STRTOF
  66.       __v = strtof(__s, &__sanity);
  67. #else
  68.       double __d = strtod(__s, &__sanity);
  69.       __v = static_cast<float>(__d);
  70. #ifdef _GLIBCXX_HAVE_FINITEF
  71.       if (!finitef (__v))
  72.         __overflow = true;
  73. #elif defined (_GLIBCXX_HAVE_FINITE)
  74.       if (!finite (static_cast<double> (__v)))
  75.         __overflow = true;
  76. #elif defined (_GLIBCXX_HAVE_ISINF)
  77.       if (isinf (static_cast<double> (__v)))
  78.         __overflow = true;
  79. #else
  80.       if (fabs(__d) > numeric_limits<float>::max())
  81.         __overflow = true;
  82. #endif
  83. #endif // _GLIBCXX_HAVE_STRTOF
  84.  
  85.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  86.       // 23. Num_get overflow result.
  87.       if (__sanity == __s || *__sanity != '\0')
  88.         {
  89.           __v = 0.0f;
  90.           __err = ios_base::failbit;
  91.         }
  92.       else if (__overflow
  93. #if __FLT_HAS_INFINITY__
  94.                || __v == numeric_limits<float>::infinity()
  95.                || __v == -numeric_limits<float>::infinity()
  96. #else
  97.                || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
  98. #endif
  99.               )
  100.         {
  101.           if (__v > 0.0f)
  102.             __v = numeric_limits<float>::max();
  103.           else
  104.             __v = -numeric_limits<float>::max();
  105.           __err = ios_base::failbit;
  106.         }
  107.  
  108.       setlocale(LC_ALL, __sav);
  109.       delete [] __sav;
  110.     }
  111.  
  112.   template<>
  113.     void
  114.     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
  115.                    const __c_locale&) throw()
  116.     {
  117.       // Assumes __s formatted for "C" locale.
  118.       char* __old = setlocale(LC_ALL, 0);
  119.       const size_t __len = strlen(__old) + 1;
  120.       char* __sav = new char[__len];
  121.       memcpy(__sav, __old, __len);
  122.       setlocale(LC_ALL, "C");
  123.       char* __sanity;
  124.  
  125. #if !__DBL_HAS_INFINITY__
  126.       errno = 0;
  127. #endif
  128.  
  129.       __v = strtod(__s, &__sanity);
  130.  
  131.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  132.       // 23. Num_get overflow result.
  133.       if (__sanity == __s || *__sanity != '\0')
  134.         {
  135.           __v = 0.0;
  136.           __err = ios_base::failbit;
  137.         }
  138.       else if (
  139. #if __DBL_HAS_INFINITY__
  140.                __v == numeric_limits<double>::infinity()
  141.                || __v == -numeric_limits<double>::infinity())
  142. #else
  143.                (__v > 1.0 || __v < -1.0) && errno == ERANGE)
  144. #endif
  145.         {
  146.           if (__v > 0.0)
  147.             __v = numeric_limits<double>::max();
  148.           else
  149.             __v = -numeric_limits<double>::max();
  150.           __err = ios_base::failbit;
  151.         }
  152.  
  153.       setlocale(LC_ALL, __sav);
  154.       delete [] __sav;
  155.     }
  156.  
  157.   template<>
  158.     void
  159.     __convert_to_v(const char* __s, long double& __v,
  160.                    ios_base::iostate& __err, const __c_locale&) throw()
  161.     {
  162.       // Assumes __s formatted for "C" locale.
  163.       char* __old = setlocale(LC_ALL, 0);
  164.       const size_t __len = strlen(__old) + 1;
  165.       char* __sav = new char[__len];
  166.       memcpy(__sav, __old, __len);
  167.       setlocale(LC_ALL, "C");
  168.  
  169. #if !__LDBL_HAS_INFINITY__
  170.       errno = 0;
  171. #endif
  172.  
  173. #if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
  174.       char* __sanity;
  175.       __v = strtold(__s, &__sanity);
  176.  
  177.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  178.       // 23. Num_get overflow result.
  179.       if (__sanity == __s || *__sanity != '\0')
  180. #else
  181.       typedef char_traits<char>::int_type int_type;
  182.       int __p = sscanf(__s, "%Lf", &__v);
  183.  
  184.       if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
  185. #endif
  186.         {
  187.           __v = 0.0l;
  188.           __err = ios_base::failbit;
  189.         }
  190.        else if (
  191. #if __LDBL_HAS_INFINITY__
  192.                 __v == numeric_limits<long double>::infinity()
  193.                 || __v == -numeric_limits<long double>::infinity())
  194. #else
  195.                 (__v > 1.0l || __v < -1.0l) && errno == ERANGE)
  196. #endif
  197.         {
  198.           if (__v > 0.0l)
  199.             __v = numeric_limits<long double>::max();
  200.           else
  201.             __v = -numeric_limits<long double>::max();
  202.           __err = ios_base::failbit;
  203.         }
  204.  
  205.       setlocale(LC_ALL, __sav);
  206.       delete [] __sav;
  207.     }
  208.  
  209.   void
  210.   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
  211.                                     __c_locale)
  212.   {
  213.     // Currently, the generic model only supports the "C" locale.
  214.     // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html
  215.     __cloc = 0;
  216.     if (strcmp(__s, "C"))
  217.       __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
  218.                             "name not valid"));
  219.   }
  220.  
  221.   void
  222.   locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
  223.   { __cloc = 0; }
  224.  
  225.   __c_locale
  226.   locale::facet::_S_clone_c_locale(__c_locale&) throw()
  227.   { return __c_locale(); }
  228.  
  229.   __c_locale
  230.   locale::facet::_S_lc_ctype_c_locale(__c_locale, const char*)
  231.   { return __c_locale(); }
  232.  
  233. _GLIBCXX_END_NAMESPACE_VERSION
  234. } // namespace
  235.  
  236. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  237. {
  238. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  239.  
  240.   const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
  241.     {
  242.       "LC_CTYPE",
  243.       "LC_NUMERIC",
  244.       "LC_TIME",
  245.       "LC_COLLATE",
  246.       "LC_MONETARY",
  247.       "LC_MESSAGES"
  248.     };
  249.  
  250. _GLIBCXX_END_NAMESPACE_VERSION
  251. } // namespace
  252.  
  253. namespace std _GLIBCXX_VISIBILITY(default)
  254. {
  255. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  256.  
  257.   const char* const* const locale::_S_categories = __gnu_cxx::category_names;
  258.  
  259. _GLIBCXX_END_NAMESPACE_VERSION
  260. } // namespace
  261.  
  262. // XXX GLIBCXX_ABI Deprecated
  263. #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
  264. #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
  265.   extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
  266. _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
  267. #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
  268.