c_locale.cc revision 132720
197403Sobrien// Wrapper for underlying C-language localization -*- C++ -*-
297403Sobrien
3117397Skan// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
497403Sobrien//
597403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
697403Sobrien// software; you can redistribute it and/or modify it under the
797403Sobrien// terms of the GNU General Public License as published by the
897403Sobrien// Free Software Foundation; either version 2, or (at your option)
997403Sobrien// any later version.
1097403Sobrien
1197403Sobrien// This library is distributed in the hope that it will be useful,
1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1497403Sobrien// GNU General Public License for more details.
1597403Sobrien
1697403Sobrien// You should have received a copy of the GNU General Public License along
1797403Sobrien// with this library; see the file COPYING.  If not, write to the Free
1897403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
1997403Sobrien// USA.
2097403Sobrien
2197403Sobrien// As a special exception, you may use this file as part of a free software
2297403Sobrien// library without restriction.  Specifically, if other files instantiate
2397403Sobrien// templates or use macros or inline functions from this file, or you compile
2497403Sobrien// this file and link it with other files to produce an executable, this
2597403Sobrien// file does not by itself cause the resulting executable to be covered by
2697403Sobrien// the GNU General Public License.  This exception does not however
2797403Sobrien// invalidate any other reasons why the executable file might be covered by
2897403Sobrien// the GNU General Public License.
2997403Sobrien
3097403Sobrien//
3197403Sobrien// ISO C++ 14882: 22.8  Standard locale categories.
3297403Sobrien//
3397403Sobrien
3497403Sobrien// Written by Benjamin Kosnik <bkoz@redhat.com>
3597403Sobrien
36132720Skan#include <cerrno>  // For errno
3797403Sobrien#include <locale>
3897403Sobrien#include <stdexcept>
3997403Sobrien#include <langinfo.h>
40117397Skan#include <bits/c++locale_internal.h>
4197403Sobrien
4297403Sobriennamespace std
4397403Sobrien{
4497403Sobrien  template<>
4597403Sobrien    void
4697403Sobrien    __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
47132720Skan		   const __c_locale& __cloc)
4897403Sobrien    {
4997403Sobrien      if (!(__err & ios_base::failbit))
5097403Sobrien	{
5197403Sobrien	  char* __sanity;
5297403Sobrien	  errno = 0;
5397403Sobrien	  float __f = __strtof_l(__s, &__sanity, __cloc);
54132720Skan          if (__sanity != __s && errno != ERANGE)
5597403Sobrien	    __v = __f;
5697403Sobrien	  else
5797403Sobrien	    __err |= ios_base::failbit;
5897403Sobrien	}
5997403Sobrien    }
6097403Sobrien
6197403Sobrien  template<>
6297403Sobrien    void
6397403Sobrien    __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
64132720Skan		   const __c_locale& __cloc)
6597403Sobrien    {
6697403Sobrien      if (!(__err & ios_base::failbit))
6797403Sobrien	{
6897403Sobrien	  char* __sanity;
6997403Sobrien	  errno = 0;
7097403Sobrien	  double __d = __strtod_l(__s, &__sanity, __cloc);
71132720Skan          if (__sanity != __s && errno != ERANGE)
7297403Sobrien	    __v = __d;
7397403Sobrien	  else
7497403Sobrien	    __err |= ios_base::failbit;
7597403Sobrien	}
7697403Sobrien    }
7797403Sobrien
7897403Sobrien  template<>
7997403Sobrien    void
8097403Sobrien    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
81132720Skan		   const __c_locale& __cloc)
8297403Sobrien    {
8397403Sobrien      if (!(__err & ios_base::failbit))
8497403Sobrien	{
8597403Sobrien	  char* __sanity;
8697403Sobrien	  errno = 0;
8797403Sobrien	  long double __ld = __strtold_l(__s, &__sanity, __cloc);
88132720Skan          if (__sanity != __s && errno != ERANGE)
8997403Sobrien	    __v = __ld;
9097403Sobrien	  else
9197403Sobrien	    __err |= ios_base::failbit;
9297403Sobrien	}
9397403Sobrien    }
9497403Sobrien
9597403Sobrien  void
9697403Sobrien  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
9797403Sobrien				    __c_locale __old)
9897403Sobrien  {
9997403Sobrien    __cloc = __newlocale(1 << LC_ALL, __s, __old);
10097403Sobrien    if (!__cloc)
10197403Sobrien      {
10297403Sobrien	// This named locale is not supported by the underlying OS.
103132720Skan	__throw_runtime_error(__N("locale::facet::_S_create_c_locale "
104132720Skan			      "name not valid"));
10597403Sobrien      }
10697403Sobrien  }
10797403Sobrien
10897403Sobrien  void
10997403Sobrien  locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
110107606Sobrien  {
111132720Skan    if (_S_get_c_locale() != __cloc)
112107606Sobrien      __freelocale(__cloc);
113107606Sobrien  }
11497403Sobrien
11597403Sobrien  __c_locale
11697403Sobrien  locale::facet::_S_clone_c_locale(__c_locale& __cloc)
11797403Sobrien  { return __duplocale(__cloc); }
118132720Skan} // namespace std
119107606Sobrien
120132720Skannamespace __gnu_cxx
121132720Skan{
122132720Skan  const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
123107606Sobrien    {
124107606Sobrien      "LC_CTYPE",
125117397Skan      "LC_NUMERIC",
126117397Skan      "LC_TIME",
127107606Sobrien      "LC_COLLATE",
128107606Sobrien      "LC_MONETARY",
129107606Sobrien      "LC_MESSAGES",
130107606Sobrien      "LC_PAPER",
131107606Sobrien      "LC_NAME",
132107606Sobrien      "LC_ADDRESS",
133107606Sobrien      "LC_TELEPHONE",
134107606Sobrien      "LC_MEASUREMENT",
135107606Sobrien      "LC_IDENTIFICATION"
136107606Sobrien    };
137132720Skan}
138132720Skan
139132720Skannamespace std
140132720Skan{
141132720Skan  const char* const* const locale::_S_categories = __gnu_cxx::category_names;
14297403Sobrien}  // namespace std
143