163d1a8abSmrg // Wrapper for underlying C-language localization -*- C++ -*-
263d1a8abSmrg 
3*ec02198aSmrg // Copyright (C) 2001-2020 Free Software Foundation, Inc.
463d1a8abSmrg //
563d1a8abSmrg // This file is part of the GNU ISO C++ Library.  This library is free
663d1a8abSmrg // software; you can redistribute it and/or modify it under the
763d1a8abSmrg // terms of the GNU General Public License as published by the
863d1a8abSmrg // Free Software Foundation; either version 3, or (at your option)
963d1a8abSmrg // any later version.
1063d1a8abSmrg 
1163d1a8abSmrg // This library is distributed in the hope that it will be useful,
1263d1a8abSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
1363d1a8abSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1463d1a8abSmrg // GNU General Public License for more details.
1563d1a8abSmrg 
1663d1a8abSmrg // Under Section 7 of GPL version 3, you are granted additional
1763d1a8abSmrg // permissions described in the GCC Runtime Library Exception, version
1863d1a8abSmrg // 3.1, as published by the Free Software Foundation.
1963d1a8abSmrg 
2063d1a8abSmrg // You should have received a copy of the GNU General Public License and
2163d1a8abSmrg // a copy of the GCC Runtime Library Exception along with this program;
2263d1a8abSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2363d1a8abSmrg // <http://www.gnu.org/licenses/>.
2463d1a8abSmrg 
2563d1a8abSmrg /** @file bits/c++locale.h
2663d1a8abSmrg  *  This is an internal header file, included by other library headers.
2763d1a8abSmrg  *  Do not attempt to use it directly. @headername{locale}
2863d1a8abSmrg  */
2963d1a8abSmrg 
3063d1a8abSmrg //
3163d1a8abSmrg // ISO C++ 14882: 22.8  Standard locale categories.
3263d1a8abSmrg //
3363d1a8abSmrg 
3463d1a8abSmrg // Written by Benjamin Kosnik <bkoz@redhat.com>
3563d1a8abSmrg 
3663d1a8abSmrg #ifndef _GLIBCXX_CXX_LOCALE_H
3763d1a8abSmrg #define _GLIBCXX_CXX_LOCALE_H 1
3863d1a8abSmrg 
3963d1a8abSmrg #pragma GCC system_header
4063d1a8abSmrg 
4163d1a8abSmrg #include <clocale>
4263d1a8abSmrg 
4363d1a8abSmrg #define _GLIBCXX_C_LOCALE_GNU 1
4463d1a8abSmrg 
4563d1a8abSmrg #define _GLIBCXX_NUM_CATEGORIES 6
4663d1a8abSmrg 
4763d1a8abSmrg #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
_GLIBCXX_VISIBILITY(default)4863d1a8abSmrg namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
4963d1a8abSmrg {
5063d1a8abSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
5163d1a8abSmrg 
5263d1a8abSmrg   extern "C" __typeof(uselocale) __uselocale;
5363d1a8abSmrg 
5463d1a8abSmrg _GLIBCXX_END_NAMESPACE_VERSION
5563d1a8abSmrg } // namespace
5663d1a8abSmrg #endif
5763d1a8abSmrg 
_GLIBCXX_VISIBILITY(default)5863d1a8abSmrg namespace std _GLIBCXX_VISIBILITY(default)
5963d1a8abSmrg {
6063d1a8abSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
6163d1a8abSmrg 
6263d1a8abSmrg   typedef __locale_t		__c_locale;
6363d1a8abSmrg 
6463d1a8abSmrg   // Convert numeric value of type double and long double to string and
6563d1a8abSmrg   // return length of string.  If vsnprintf is available use it, otherwise
6663d1a8abSmrg   // fall back to the unsafe vsprintf which, in general, can be dangerous
6763d1a8abSmrg   // and should be avoided.
6863d1a8abSmrg   inline int
6963d1a8abSmrg   __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)),
7063d1a8abSmrg 		   char* __out,
7163d1a8abSmrg 		   const int __size __attribute__ ((__unused__)),
7263d1a8abSmrg 		   const char* __fmt, ...)
7363d1a8abSmrg   {
7463d1a8abSmrg #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
7563d1a8abSmrg     __c_locale __old = __gnu_cxx::__uselocale(__cloc);
7663d1a8abSmrg #else
7763d1a8abSmrg     char* __old = std::setlocale(LC_NUMERIC, 0);
7863d1a8abSmrg     char* __sav = 0;
7963d1a8abSmrg     if (__builtin_strcmp(__old, "C"))
8063d1a8abSmrg       {
8163d1a8abSmrg 	const size_t __len = __builtin_strlen(__old) + 1;
8263d1a8abSmrg 	__sav = new char[__len];
8363d1a8abSmrg 	__builtin_memcpy(__sav, __old, __len);
8463d1a8abSmrg 	std::setlocale(LC_NUMERIC, "C");
8563d1a8abSmrg       }
8663d1a8abSmrg #endif
8763d1a8abSmrg 
8863d1a8abSmrg     __builtin_va_list __args;
8963d1a8abSmrg     __builtin_va_start(__args, __fmt);
9063d1a8abSmrg 
9163d1a8abSmrg #if _GLIBCXX_USE_C99_STDIO
9263d1a8abSmrg     const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
9363d1a8abSmrg #else
9463d1a8abSmrg     const int __ret = __builtin_vsprintf(__out, __fmt, __args);
9563d1a8abSmrg #endif
9663d1a8abSmrg 
9763d1a8abSmrg     __builtin_va_end(__args);
9863d1a8abSmrg 
9963d1a8abSmrg #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
10063d1a8abSmrg     __gnu_cxx::__uselocale(__old);
10163d1a8abSmrg #else
10263d1a8abSmrg     if (__sav)
10363d1a8abSmrg       {
10463d1a8abSmrg 	std::setlocale(LC_NUMERIC, __sav);
10563d1a8abSmrg 	delete [] __sav;
10663d1a8abSmrg       }
10763d1a8abSmrg #endif
10863d1a8abSmrg     return __ret;
10963d1a8abSmrg   }
11063d1a8abSmrg 
11163d1a8abSmrg _GLIBCXX_END_NAMESPACE_VERSION
11263d1a8abSmrg } // namespace
11363d1a8abSmrg 
11463d1a8abSmrg #endif
115