c_locale.cc revision 107606
197403Sobrien// Wrapper for underlying C-language localization -*- C++ -*-
297403Sobrien
397403Sobrien// Copyright (C) 2001, 2002 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
3697403Sobrien#include <locale>
3797403Sobrien#include <stdexcept>
3897403Sobrien#include <langinfo.h>
39103447Skan#include "c++locale_internal.h"
4097403Sobrien
4197403Sobriennamespace std
4297403Sobrien{
4397403Sobrien  template<>
4497403Sobrien    void
4597403Sobrien    __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err,
4697403Sobrien		   const __c_locale& __cloc, int __base)
4797403Sobrien    {
4897403Sobrien      if (!(__err & ios_base::failbit))
4997403Sobrien      {
5097403Sobrien	char* __sanity;
5197403Sobrien	errno = 0;
5297403Sobrien	long __l = __strtol_l(__s, &__sanity, __base, __cloc);
5397403Sobrien	if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
5497403Sobrien	  __v = __l;
5597403Sobrien	else
5697403Sobrien	  __err |= ios_base::failbit;
5797403Sobrien      }
5897403Sobrien    }
5997403Sobrien
6097403Sobrien  template<>
6197403Sobrien    void
6297403Sobrien    __convert_to_v(const char* __s, unsigned long& __v,
6397403Sobrien		   ios_base::iostate& __err, const __c_locale& __cloc,
6497403Sobrien		   int __base)
6597403Sobrien    {
6697403Sobrien      if (!(__err & ios_base::failbit))
6797403Sobrien	{
6897403Sobrien	  char* __sanity;
6997403Sobrien	  errno = 0;
7097403Sobrien	  unsigned long __ul = __strtoul_l(__s, &__sanity, __base, __cloc);
7197403Sobrien          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
7297403Sobrien	    __v = __ul;
7397403Sobrien	  else
7497403Sobrien	    __err |= ios_base::failbit;
7597403Sobrien	}
7697403Sobrien    }
7797403Sobrien
7897403Sobrien#ifdef _GLIBCPP_USE_LONG_LONG
7997403Sobrien  template<>
8097403Sobrien    void
8197403Sobrien    __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err,
8297403Sobrien		   const __c_locale& __cloc, int __base)
8397403Sobrien    {
8497403Sobrien      if (!(__err & ios_base::failbit))
8597403Sobrien	{
8697403Sobrien	  char* __sanity;
8797403Sobrien	  errno = 0;
8897403Sobrien	  long long __ll = __strtoll_l(__s, &__sanity, __base, __cloc);
8997403Sobrien          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
9097403Sobrien	    __v = __ll;
9197403Sobrien	  else
9297403Sobrien	    __err |= ios_base::failbit;
9397403Sobrien	}
9497403Sobrien    }
9597403Sobrien
9697403Sobrien  template<>
9797403Sobrien    void
9897403Sobrien    __convert_to_v(const char* __s, unsigned long long& __v,
9997403Sobrien		   ios_base::iostate& __err, const __c_locale& __cloc,
10097403Sobrien		   int __base)
10197403Sobrien    {
10297403Sobrien      if (!(__err & ios_base::failbit))
10397403Sobrien	{
10497403Sobrien	  char* __sanity;
10597403Sobrien	  errno = 0;
10697403Sobrien	  unsigned long long __ull = __strtoull_l(__s, &__sanity, __base,
10797403Sobrien						  __cloc);
10897403Sobrien          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
10997403Sobrien	    __v = __ull;
11097403Sobrien	  else
11197403Sobrien	    __err |= ios_base::failbit;
11297403Sobrien	}
11397403Sobrien    }
11497403Sobrien#endif
11597403Sobrien
11697403Sobrien  template<>
11797403Sobrien    void
11897403Sobrien    __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
11997403Sobrien		   const __c_locale& __cloc, int)
12097403Sobrien    {
12197403Sobrien      if (!(__err & ios_base::failbit))
12297403Sobrien	{
12397403Sobrien	  char* __sanity;
12497403Sobrien	  errno = 0;
12597403Sobrien	  float __f = __strtof_l(__s, &__sanity, __cloc);
12697403Sobrien          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
12797403Sobrien	    __v = __f;
12897403Sobrien	  else
12997403Sobrien	    __err |= ios_base::failbit;
13097403Sobrien	}
13197403Sobrien    }
13297403Sobrien
13397403Sobrien  template<>
13497403Sobrien    void
13597403Sobrien    __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
13697403Sobrien		   const __c_locale& __cloc, int)
13797403Sobrien    {
13897403Sobrien      if (!(__err & ios_base::failbit))
13997403Sobrien	{
14097403Sobrien	  char* __sanity;
14197403Sobrien	  errno = 0;
14297403Sobrien	  double __d = __strtod_l(__s, &__sanity, __cloc);
14397403Sobrien          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
14497403Sobrien	    __v = __d;
14597403Sobrien	  else
14697403Sobrien	    __err |= ios_base::failbit;
14797403Sobrien	}
14897403Sobrien    }
14997403Sobrien
15097403Sobrien  template<>
15197403Sobrien    void
15297403Sobrien    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
15397403Sobrien		   const __c_locale& __cloc, int)
15497403Sobrien    {
15597403Sobrien      if (!(__err & ios_base::failbit))
15697403Sobrien	{
15797403Sobrien	  char* __sanity;
15897403Sobrien	  errno = 0;
15997403Sobrien	  long double __ld = __strtold_l(__s, &__sanity, __cloc);
16097403Sobrien          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
16197403Sobrien	    __v = __ld;
16297403Sobrien	  else
16397403Sobrien	    __err |= ios_base::failbit;
16497403Sobrien	}
16597403Sobrien    }
16697403Sobrien
16797403Sobrien  void
16897403Sobrien  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
16997403Sobrien				    __c_locale __old)
17097403Sobrien  {
17197403Sobrien    __cloc = __newlocale(1 << LC_ALL, __s, __old);
17297403Sobrien    if (!__cloc)
17397403Sobrien      {
17497403Sobrien	// This named locale is not supported by the underlying OS.
17597403Sobrien	__throw_runtime_error("attempt to create locale from unknown name");
17697403Sobrien      }
17797403Sobrien  }
17897403Sobrien
17997403Sobrien  void
18097403Sobrien  locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
181107606Sobrien  {
182107606Sobrien    if (_S_c_locale != __cloc)
183107606Sobrien      __freelocale(__cloc);
184107606Sobrien  }
18597403Sobrien
18697403Sobrien  __c_locale
18797403Sobrien  locale::facet::_S_clone_c_locale(__c_locale& __cloc)
18897403Sobrien  { return __duplocale(__cloc); }
189107606Sobrien
190107606Sobrien  const char* locale::_S_categories[_S_categories_size
191107606Sobrien				    + _S_extra_categories_size] =
192107606Sobrien    {
193107606Sobrien      "LC_CTYPE",
194107606Sobrien      "LC_NUMERIC",
195107606Sobrien      "LC_COLLATE",
196107606Sobrien      "LC_TIME",
197107606Sobrien      "LC_MONETARY",
198107606Sobrien      "LC_MESSAGES",
199107606Sobrien      "LC_PAPER",
200107606Sobrien      "LC_NAME",
201107606Sobrien      "LC_ADDRESS",
202107606Sobrien      "LC_TELEPHONE",
203107606Sobrien      "LC_MEASUREMENT",
204107606Sobrien      "LC_IDENTIFICATION"
205107606Sobrien    };
20697403Sobrien}  // namespace std
207