c_locale.cc revision 103447
1223695Sdfr// Wrapper for underlying C-language localization -*- C++ -*-
2223695Sdfr
3239058Sae// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
4223695Sdfr//
5223695Sdfr// This file is part of the GNU ISO C++ Library.  This library is free
6223695Sdfr// software; you can redistribute it and/or modify it under the
7223695Sdfr// terms of the GNU General Public License as published by the
8223695Sdfr// Free Software Foundation; either version 2, or (at your option)
9223695Sdfr// any later version.
10223695Sdfr
11223695Sdfr// This library is distributed in the hope that it will be useful,
12223695Sdfr// but WITHOUT ANY WARRANTY; without even the implied warranty of
13223695Sdfr// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14223695Sdfr// GNU General Public License for more details.
15223695Sdfr
16223695Sdfr// You should have received a copy of the GNU General Public License along
17223695Sdfr// with this library; see the file COPYING.  If not, write to the Free
18223695Sdfr// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19223695Sdfr// USA.
20223695Sdfr
21223695Sdfr// As a special exception, you may use this file as part of a free software
22223695Sdfr// library without restriction.  Specifically, if other files instantiate
23223695Sdfr// templates or use macros or inline functions from this file, or you compile
24223695Sdfr// this file and link it with other files to produce an executable, this
25223695Sdfr// file does not by itself cause the resulting executable to be covered by
26223695Sdfr// the GNU General Public License.  This exception does not however
27223695Sdfr// invalidate any other reasons why the executable file might be covered by
28223695Sdfr// the GNU General Public License.
29223695Sdfr
30223695Sdfr//
31239058Sae// ISO C++ 14882: 22.8  Standard locale categories.
32241053Sae//
33223695Sdfr
34223695Sdfr// Written by Benjamin Kosnik <bkoz@redhat.com>
35223695Sdfr
36239058Sae#include <locale>
37223695Sdfr#include <stdexcept>
38223695Sdfr#include <langinfo.h>
39223695Sdfr#include "c++locale_internal.h"
40223695Sdfr
41223695Sdfrnamespace std
42223695Sdfr{
43223695Sdfr  template<>
44223695Sdfr    void
45223695Sdfr    __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err,
46239058Sae		   const __c_locale& __cloc, int __base)
47239058Sae    {
48329099Skevans      if (!(__err & ios_base::failbit))
49329099Skevans      {
50239058Sae	char* __sanity;
51239058Sae	errno = 0;
52223695Sdfr	long __l = __strtol_l(__s, &__sanity, __base, __cloc);
53239058Sae	if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
54239058Sae	  __v = __l;
55239058Sae	else
56239058Sae	  __err |= ios_base::failbit;
57223695Sdfr      }
58223695Sdfr    }
59239058Sae
60223695Sdfr  template<>
61239058Sae    void
62223695Sdfr    __convert_to_v(const char* __s, unsigned long& __v,
63223695Sdfr		   ios_base::iostate& __err, const __c_locale& __cloc,
64223695Sdfr		   int __base)
65223695Sdfr    {
66239058Sae      if (!(__err & ios_base::failbit))
67223695Sdfr	{
68223695Sdfr	  char* __sanity;
69223695Sdfr	  errno = 0;
70223695Sdfr	  unsigned long __ul = __strtoul_l(__s, &__sanity, __base, __cloc);
71223695Sdfr          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
72223695Sdfr	    __v = __ul;
73223695Sdfr	  else
74223695Sdfr	    __err |= ios_base::failbit;
75223695Sdfr	}
76223695Sdfr    }
77223695Sdfr
78239058Sae#ifdef _GLIBCPP_USE_LONG_LONG
79223695Sdfr  template<>
80223695Sdfr    void
81223695Sdfr    __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err,
82296963Sallanjude		   const __c_locale& __cloc, int __base)
83329099Skevans    {
84223695Sdfr      if (!(__err & ios_base::failbit))
85239058Sae	{
86239058Sae	  char* __sanity;
87223695Sdfr	  errno = 0;
88239058Sae	  long long __ll = __strtoll_l(__s, &__sanity, __base, __cloc);
89239058Sae          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
90313355Stsoome	    __v = __ll;
91239058Sae	  else
92223695Sdfr	    __err |= ios_base::failbit;
93223695Sdfr	}
94239058Sae    }
95300117Simp
96239058Sae  template<>
97223695Sdfr    void
98329099Skevans    __convert_to_v(const char* __s, unsigned long long& __v,
99239058Sae		   ios_base::iostate& __err, const __c_locale& __cloc,
100239058Sae		   int __base)
101239058Sae    {
102239058Sae      if (!(__err & ios_base::failbit))
103300117Simp	{
104223695Sdfr	  char* __sanity;
105239058Sae	  errno = 0;
106239058Sae	  unsigned long long __ull = __strtoull_l(__s, &__sanity, __base,
107239058Sae						  __cloc);
108239058Sae          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
109239058Sae	    __v = __ull;
110239058Sae	  else
111239058Sae	    __err |= ios_base::failbit;
112239058Sae	}
113239058Sae    }
114300117Simp#endif
115300117Simp
116300117Simp  template<>
117239058Sae    void
118239058Sae    __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
119329099Skevans		   const __c_locale& __cloc, int)
120329099Skevans    {
121329099Skevans      if (!(__err & ios_base::failbit))
122329099Skevans	{
123329099Skevans	  char* __sanity;
124329099Skevans	  errno = 0;
125329099Skevans	  float __f = __strtof_l(__s, &__sanity, __cloc);
126329099Skevans          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
127329099Skevans	    __v = __f;
128329099Skevans	  else
129329099Skevans	    __err |= ios_base::failbit;
130329099Skevans	}
131329099Skevans    }
132329099Skevans
133329099Skevans  template<>
134329099Skevans    void
135329099Skevans    __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
136329099Skevans		   const __c_locale& __cloc, int)
137223695Sdfr    {
138300117Simp      if (!(__err & ios_base::failbit))
139300117Simp	{
140223695Sdfr	  char* __sanity;
141239058Sae	  errno = 0;
142223695Sdfr	  double __d = __strtod_l(__s, &__sanity, __cloc);
143300117Simp          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
144239058Sae	    __v = __d;
145223695Sdfr	  else
146239058Sae	    __err |= ios_base::failbit;
147239058Sae	}
148223695Sdfr    }
149239058Sae
150239058Sae  template<>
151239058Sae    void
152239058Sae    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
153239058Sae		   const __c_locale& __cloc, int)
154300117Simp    {
155223695Sdfr      if (!(__err & ios_base::failbit))
156223695Sdfr	{
157239058Sae	  char* __sanity;
158329099Skevans	  errno = 0;
159291402Szbb	  long double __ld = __strtold_l(__s, &__sanity, __cloc);
160291402Szbb          if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
161291402Szbb	    __v = __ld;
162291402Szbb	  else
163291402Szbb	    __err |= ios_base::failbit;
164313355Stsoome	}
165291402Szbb    }
166291402Szbb
167291402Szbb  void
168291402Szbb  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
169291402Szbb				    __c_locale __old)
170291402Szbb  {
171329099Skevans    __cloc = __newlocale(1 << LC_ALL, __s, __old);
172291402Szbb    if (!__cloc)
173291402Szbb      {
174291402Szbb	// This named locale is not supported by the underlying OS.
175291402Szbb	__throw_runtime_error("attempt to create locale from unknown name");
176291402Szbb      }
177313355Stsoome  }
178291402Szbb
179291402Szbb  void
180291402Szbb  locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
181291402Szbb  { __freelocale(__cloc); }
182291402Szbb
183291402Szbb  __c_locale
184329099Skevans  locale::facet::_S_clone_c_locale(__c_locale& __cloc)
185291402Szbb  { return __duplocale(__cloc); }
186329099Skevans}  // namespace std
187291402Szbb