197403Sobrien// Wrapper for underlying C-language localization -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
4169691Skan// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
31169691Skan/** @file c++locale.h
32169691Skan *  This is an internal header file, included by other library headers.
33169691Skan *  You should not attempt to use it directly.
34169691Skan */
35169691Skan
3697403Sobrien//
3797403Sobrien// ISO C++ 14882: 22.8  Standard locale categories.
3897403Sobrien//
3997403Sobrien
4097403Sobrien// Written by Benjamin Kosnik <bkoz@redhat.com>
4197403Sobrien
42132720Skan#ifndef _C_LOCALE_H
43132720Skan#define _C_LOCALE_H 1
44117397Skan
45117397Skan#pragma GCC system_header
46117397Skan
47132720Skan#include <cstring>              // get std::strlen
48169691Skan#include <cstdio>               // get std::vsnprintf or std::vsprintf
4997403Sobrien#include <clocale>
5097403Sobrien#include <langinfo.h>		// For codecvt
5197403Sobrien#include <iconv.h>		// For codecvt using iconv, iconv_t
5297403Sobrien#include <libintl.h> 		// For messages
53169691Skan#include <cstdarg>
5497403Sobrien
55132720Skan#define _GLIBCXX_C_LOCALE_GNU 1
5697403Sobrien
57132720Skan#define _GLIBCXX_NUM_CATEGORIES 6
58107606Sobrien
59103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
60169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
61169691Skan
62103447Skan  extern "C" __typeof(uselocale) __uselocale;
63169691Skan
64169691Skan_GLIBCXX_END_NAMESPACE
65103447Skan#endif
66103447Skan
67169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
68169691Skan
6997403Sobrien  typedef __locale_t		__c_locale;
70103447Skan
71169691Skan  // Convert numeric value of type double and long double to string and
72169691Skan  // return length of string.  If vsnprintf is available use it, otherwise
73169691Skan  // fall back to the unsafe vsprintf which, in general, can be dangerous
74169691Skan  // and should be avoided.
75169691Skan  inline int
76169691Skan  __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)),
77169691Skan		   char* __out,
78169691Skan		   const int __size __attribute__ ((__unused__)),
79169691Skan		   const char* __fmt, ...)
80169691Skan  {
81103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
82169691Skan    __c_locale __old = __gnu_cxx::__uselocale(__cloc);
83103447Skan#else
84169691Skan    char* __old = std::setlocale(LC_ALL, NULL);
85169691Skan    char* __sav = new char[std::strlen(__old) + 1];
86169691Skan    std::strcpy(__sav, __old);
87169691Skan    std::setlocale(LC_ALL, "C");
88103447Skan#endif
89103447Skan
90169691Skan    va_list __args;
91169691Skan    va_start(__args, __fmt);
92169691Skan
93132720Skan#ifdef _GLIBCXX_USE_C99
94169691Skan    const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
95103447Skan#else
96169691Skan    const int __ret = std::vsprintf(__out, __fmt, __args);
97103447Skan#endif
98103447Skan
99169691Skan    va_end(__args);
100169691Skan
101103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
102169691Skan    __gnu_cxx::__uselocale(__old);
103103447Skan#else
104169691Skan    std::setlocale(LC_ALL, __sav);
105169691Skan    delete [] __sav;
106103447Skan#endif
107169691Skan    return __ret;
108169691Skan  }
109117397Skan
110169691Skan_GLIBCXX_END_NAMESPACE
111169691Skan
112117397Skan#endif
113