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
4797403Sobrien#include <clocale>
48132720Skan#include <cstring>   // get std::strlen
49169691Skan#include <cstdio>    // get std::vsnprintf or std::vsprintf
50169691Skan#include <cstdarg>
5197403Sobrien
52132720Skan#define _GLIBCXX_NUM_CATEGORIES 0
53107606Sobrien
54169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
55169691Skan
5697403Sobrien  typedef int*			__c_locale;
57103447Skan
58169691Skan  // Convert numeric value of type double and long double to string and
59169691Skan  // return length of string.  If vsnprintf is available use it, otherwise
60169691Skan  // fall back to the unsafe vsprintf which, in general, can be dangerous
61169691Skan  // and should be avoided.
62169691Skan  inline int
63169691Skan  __convert_from_v(const __c_locale&, char* __out,
64169691Skan		   const int __size __attribute__((__unused__)),
65169691Skan		   const char* __fmt, ...)
66169691Skan  {
67169691Skan    char* __old = std::setlocale(LC_NUMERIC, NULL);
68169691Skan    char* __sav = NULL;
69169691Skan    if (std::strcmp(__old, "C"))
70169691Skan      {
71169691Skan	__sav = new char[std::strlen(__old) + 1];
72169691Skan	std::strcpy(__sav, __old);
73169691Skan	std::setlocale(LC_NUMERIC, "C");
74169691Skan      }
75103447Skan
76169691Skan    va_list __args;
77169691Skan    va_start(__args, __fmt);
78169691Skan
79132720Skan#ifdef _GLIBCXX_USE_C99
80169691Skan    const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
81103447Skan#else
82169691Skan    const int __ret = std::vsprintf(__out, __fmt, __args);
83103447Skan#endif
84169691Skan
85169691Skan    va_end(__args);
86146897Skan
87169691Skan    if (__sav)
88169691Skan      {
89169691Skan	std::setlocale(LC_NUMERIC, __sav);
90169691Skan	delete [] __sav;
91169691Skan      }
92169691Skan    return __ret;
93169691Skan  }
94117397Skan
95169691Skan_GLIBCXX_END_NAMESPACE
96169691Skan
97117397Skan#endif
98