gcc50/csu: Skip depends step to avoid possible race
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / config / locale / dragonfly / c_locale.cc
1 // Wrapper for underlying C-language localization -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 //
27 // ISO C++ 14882: 22.8  Standard locale categories.
28 //
29
30 // Written by Benjamin Kosnik <bkoz@redhat.com>
31
32 #include <cerrno>  // For errno
33 #include <cmath>  // For isinf, finite, finitef, fabs
34 #include <cstdlib>  // For strof, strtold
35 #include <cstring>
36 #include <cstdio>
37 #include <locale>
38 #include <limits>
39 #include <cstddef>
40
41 #ifdef _GLIBCXX_HAVE_IEEEFP_H
42 #include <ieeefp.h>
43 #endif
44
45 _GLIBCXX_BEGIN_NAMESPACE(std)
46
47   template<>
48     void
49     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
50                    const __c_locale&)         
51     {
52       // Assumes __s formatted for "C" locale.
53       char* __old = setlocale(LC_ALL, NULL);
54       const size_t __len = strlen(__old) + 1;
55       char* __sav = new char[__len];
56       memcpy(__sav, __old, __len);
57       setlocale(LC_ALL, "C");
58       char* __sanity;
59       bool __overflow = false;
60
61 #if !__FLT_HAS_INFINITY__
62       errno = 0;
63 #endif
64
65 #ifdef _GLIBCXX_HAVE_STRTOF
66       __v = strtof(__s, &__sanity);
67 #else
68       double __d = strtod(__s, &__sanity);
69       __v = static_cast<float>(__d);
70 #ifdef _GLIBCXX_HAVE_FINITEF
71       if (!finitef (__v))
72         __overflow = true;
73 #elif defined (_GLIBCXX_HAVE_FINITE)
74       if (!finite (static_cast<double> (__v)))
75         __overflow = true;
76 #elif defined (_GLIBCXX_HAVE_ISINF)
77       if (isinf (static_cast<double> (__v)))
78         __overflow = true;
79 #else
80       if (fabs(__d) > numeric_limits<float>::max())
81         __overflow = true;
82 #endif
83 #endif // _GLIBCXX_HAVE_STRTOF
84
85       // _GLIBCXX_RESOLVE_LIB_DEFECTS
86       // 23. Num_get overflow result.
87       if (__sanity == __s || *__sanity != '\0')
88         {
89           __v = 0.0f;
90           __err = ios_base::failbit;
91         }
92       else if (__overflow
93 #if __FLT_HAS_INFINITY__
94                || __v == numeric_limits<float>::infinity()
95                || __v == -numeric_limits<float>::infinity()
96 #else
97                || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
98 #endif
99               )
100         {
101           if (__v > 0.0f)
102             __v = numeric_limits<float>::max();
103           else
104             __v = -numeric_limits<float>::max();
105           __err = ios_base::failbit;
106         }
107
108       setlocale(LC_ALL, __sav);
109       delete [] __sav;
110     }
111
112   template<>
113     void
114     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
115                    const __c_locale&) 
116     {
117       // Assumes __s formatted for "C" locale.
118       char* __old = setlocale(LC_ALL, NULL);
119       const size_t __len = strlen(__old) + 1;
120       char* __sav = new char[__len];
121       memcpy(__sav, __old, __len);
122       setlocale(LC_ALL, "C");
123       char* __sanity;
124
125 #if !__DBL_HAS_INFINITY__
126       errno = 0;
127 #endif
128
129       __v = strtod(__s, &__sanity);
130
131       // _GLIBCXX_RESOLVE_LIB_DEFECTS
132       // 23. Num_get overflow result.
133       if (__sanity == __s || *__sanity != '\0')
134         {
135           __v = 0.0;
136           __err = ios_base::failbit;
137         }
138       else if (
139 #if __DBL_HAS_INFINITY__
140                __v == numeric_limits<double>::infinity()
141                || __v == -numeric_limits<double>::infinity())
142 #else          
143                (__v > 1.0 || __v < -1.0) && errno == ERANGE)
144 #endif
145         {
146           if (__v > 0.0)
147             __v = numeric_limits<double>::max();
148           else
149             __v = -numeric_limits<double>::max();
150           __err = ios_base::failbit;
151         }
152
153       setlocale(LC_ALL, __sav);
154       delete [] __sav;
155     }
156
157   template<>
158     void
159     __convert_to_v(const char* __s, long double& __v, 
160                    ios_base::iostate& __err, const __c_locale&) 
161     {
162       // Assumes __s formatted for "C" locale.
163       char* __old = setlocale(LC_ALL, NULL);
164       const size_t __len = strlen(__old) + 1;
165       char* __sav = new char[__len];
166       memcpy(__sav, __old, __len);
167       setlocale(LC_ALL, "C");
168
169 #if !__LDBL_HAS_INFINITY__
170       errno = 0;
171 #endif
172
173 #if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
174       char* __sanity;
175       __v = strtold(__s, &__sanity);
176
177       // _GLIBCXX_RESOLVE_LIB_DEFECTS
178       // 23. Num_get overflow result.
179       if (__sanity == __s || *__sanity != '\0')
180 #else
181       typedef char_traits<char>::int_type int_type;
182       int __p = sscanf(__s, "%Lf", &__v);
183
184       if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
185 #endif
186         {
187           __v = 0.0l;
188           __err = ios_base::failbit;
189         }
190        else if (
191 #if __LDBL_HAS_INFINITY__
192                 __v == numeric_limits<long double>::infinity()
193                 || __v == -numeric_limits<long double>::infinity())
194 #else
195                 (__v > 1.0l || __v < -1.0l) && errno == ERANGE)
196 #endif
197         {
198           if (__v > 0.0l)
199             __v = numeric_limits<long double>::max();
200           else
201             __v = -numeric_limits<long double>::max();
202           __err = ios_base::failbit;
203         }
204
205       setlocale(LC_ALL, __sav);
206       delete [] __sav;
207     }
208
209   /*  DragonFly's implemenation of setlocale won't accept something like
210       "de_DE".  According to nls manpage, the expected format is:
211       language[_territory][.codeset][@modifier], but it seems that both
212       the _territory and .codeset components are required.
213       
214       As an attempt to correct for this, we'll tack on ".UTF-8" if 
215       a period is not detected in the locale string.  
216
217       There are no locales with modifiers on DragonFly so if found, they
218       will just be stripped off silently.  e.g "de_DE@euro" will be reduced
219       to "de_DE".  The UTF-8 default would be added after that.
220   */
221
222   void
223   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
224                                     __c_locale)
225   {
226     const size_t size__s = (__s == NULL) ? 1 : strlen (__s);
227     const char UTF8[] = ".UTF-8";
228     char localspec[size__s + 6 + 1];
229     
230     if (__s == NULL) {
231        localspec[0] = NULL;
232     } else {
233        strcpy (localspec, __s);
234        char * pch = strchr (localspec, '@');
235        if (pch != NULL)
236           *pch = 0;
237
238        if (  (strchr (__s, '.') == NULL)
239           && (strcmp (__s, "C") != 0)
240           && (strcmp (__s, "POSIX") != 0))
241           strncat (localspec, UTF8, 6);
242     }
243
244     const char * result = std::setlocale(LC_ALL, localspec);
245     
246     if ((strcmp(result, "C") != 0) && (strcmp (result, localspec) != 0))
247       __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
248                             "name not valid"));
249     __cloc = 0;
250   }
251
252   void
253   locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
254   { __cloc = NULL; }
255
256   __c_locale
257   locale::facet::_S_clone_c_locale(__c_locale&)
258   { return __c_locale(); }
259
260 _GLIBCXX_END_NAMESPACE
261
262 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
263
264   const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
265     {
266       "LC_CTYPE", 
267       "LC_NUMERIC",
268       "LC_TIME",   
269       "LC_COLLATE", 
270       "LC_MONETARY",
271       "LC_MESSAGES"
272     };
273
274 _GLIBCXX_END_NAMESPACE
275
276 _GLIBCXX_BEGIN_NAMESPACE(std)
277
278   const char* const* const locale::_S_categories = __gnu_cxx::category_names;
279
280 _GLIBCXX_END_NAMESPACE
281
282 // XXX GLIBCXX_ABI Deprecated
283 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
284 #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
285   extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
286 _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
287 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT