OSDN Git Service

2002-01-22 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / config / locale / c_locale_generic.cc
1 // Wrapper for underlying C-language localization -*- C++ -*-
2
3 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 //
31 // ISO C++ 14882: 22.8  Standard locale categories.
32 //
33
34 // Written by Benjamin Kosnik <bkoz@redhat.com>
35
36 #include <locale>
37
38 namespace std 
39 {
40   // Specializations for all types used in num_get.
41   template<>
42     void
43     __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 
44                    const __c_locale&, int __base)
45     {
46       if (!(__err & ios_base::failbit))
47       {
48         char* __sanity;
49         errno = 0;
50         long __l = strtol(__s, &__sanity, __base);
51         if (__sanity != __s && *__sanity == '\0' && errno == 0)
52           __v = __l;
53         else
54           __err |= ios_base::failbit;
55       }
56     }
57
58   template<>
59     void
60     __convert_to_v(const char* __s, unsigned long& __v, 
61                    ios_base::iostate& __err, const __c_locale&, int __base)
62     {
63       if (!(__err & ios_base::failbit))
64         {
65           char* __sanity;
66           errno = 0;
67           unsigned long __ul = strtoul(__s, &__sanity, __base);
68           if (__sanity != __s && *__sanity == '\0' && errno == 0)
69             __v = __ul;
70           else
71             __err |= ios_base::failbit;
72         }
73     }
74
75 #ifdef _GLIBCPP_USE_LONG_LONG
76   template<>
77     void
78     __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 
79                    const __c_locale&, int __base)
80     {
81       if (!(__err & ios_base::failbit))
82         {
83           char* __sanity;
84           errno = 0;
85           long long __ll = strtoll(__s, &__sanity, __base);
86           if (__sanity != __s && *__sanity == '\0' && errno == 0)
87             __v = __ll;
88           else
89             __err |= ios_base::failbit;
90         }
91     }
92
93   template<>
94     void
95     __convert_to_v(const char* __s, unsigned long long& __v, 
96                    ios_base::iostate& __err, const __c_locale&, int __base)
97     {
98       if (!(__err & ios_base::failbit))
99         {      
100           char* __sanity;
101           errno = 0;
102           unsigned long long __ull = strtoull(__s, &__sanity, __base);
103           if (__sanity != __s && *__sanity == '\0' && errno == 0)
104             __v = __ull;
105           else
106             __err |= ios_base::failbit;
107         }  
108     }
109 #endif
110
111   template<>
112     void
113     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
114                    const __c_locale&, int)            
115     {
116       if (!(__err & ios_base::failbit))
117         {
118           // Assumes __s formatted for "C" locale.
119           const char* __old = setlocale(LC_ALL, "C");
120           char* __sanity;
121           errno = 0;
122 #ifdef _GLIBCPP_USE_C99
123           float __f = strtof(__s, &__sanity);
124 #else
125           float __f = static_cast<float>(strtod(__s, &__sanity));
126 #endif
127           if (__sanity != __s && *__sanity == '\0' && errno == 0)
128             __v = __f;
129           else
130             __err |= ios_base::failbit;
131           setlocale(LC_ALL, __old);
132         }
133     }
134
135   template<>
136     void
137     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
138                    const __c_locale&, int) 
139     {
140       if (!(__err & ios_base::failbit))
141         {
142           // Assumes __s formatted for "C" locale.
143           const char* __old = setlocale(LC_ALL, "C");
144           char* __sanity;
145           errno = 0;
146           double __d = strtod(__s, &__sanity);
147           if (__sanity != __s && *__sanity == '\0' && errno == 0)
148             __v = __d;
149           else
150             __err |= ios_base::failbit;
151           setlocale(LC_ALL, __old);
152         }
153     }
154
155   template<>
156     void
157     __convert_to_v(const char* __s, long double& __v, 
158                    ios_base::iostate& __err, const __c_locale&, int) 
159     {
160       if (!(__err & ios_base::failbit))
161         {
162           // Assumes __s formatted for "C" locale.
163           const char* __old = setlocale(LC_ALL, "C");
164 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
165           char* __sanity;
166           errno = 0;
167           long double __ld = strtold(__s, &__sanity);
168           if (__sanity != __s && *__sanity == '\0' && errno == 0)
169             __v = __ld;
170 #else
171           typedef typename char_traits<char>::int_type int_type;
172           long double __ld;
173           int __p = sscanf(__s, "%Lf", &__ld);
174           if (__p && static_cast<int_type>(__p) != char_traits<char>::eof())
175             __v = __ld;
176 #endif
177           else
178             __err |= ios_base::failbit;
179           setlocale(LC_ALL, __old);
180         }
181     }
182
183   void
184   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*)
185   { __cloc = NULL; }
186
187   void
188   locale::facet::_S_destroy_c_locale(__c_locale&)
189   { }
190
191   __c_locale
192   locale::facet::_S_clone_c_locale(__c_locale&)
193   { return __c_locale(); }
194 }  // namespace std