buildroot: allow specifying libc personality for external toolchains
[openwrt.git] / toolchain / gcc / patches / llvm / 205-uclibc-locale-update.patch
1 --- a/libstdc++-v3/config/locale/uclibc/c_locale.cc
2 +++ b/libstdc++-v3/config/locale/uclibc/c_locale.cc
3 @@ -46,16 +46,13 @@ namespace std 
4      __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
5                    const __c_locale& __cloc)
6      {
7 -      if (!(__err & ios_base::failbit))
8 -       {
9 -         char* __sanity;
10 -         errno = 0;
11 -         float __f = __strtof_l(__s, &__sanity, __cloc);
12 -          if (__sanity != __s && errno != ERANGE)
13 -           __v = __f;
14 -         else
15 -           __err |= ios_base::failbit;
16 -       }
17 +      char* __sanity;
18 +      errno = 0;
19 +      float __f = __strtof_l(__s, &__sanity, __cloc);
20 +      if (__sanity != __s && errno != ERANGE)
21 +       __v = __f;
22 +      else
23 +       __err |= ios_base::failbit;
24      }
25  
26    template<>
27 @@ -63,16 +60,13 @@ namespace std 
28      __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
29                    const __c_locale& __cloc)
30      {
31 -      if (!(__err & ios_base::failbit))
32 -       {
33 -         char* __sanity;
34 -         errno = 0;
35 -         double __d = __strtod_l(__s, &__sanity, __cloc);
36 -          if (__sanity != __s && errno != ERANGE)
37 -           __v = __d;
38 -         else
39 -           __err |= ios_base::failbit;
40 -       }
41 +      char* __sanity;
42 +      errno = 0;
43 +      double __d = __strtod_l(__s, &__sanity, __cloc);
44 +      if (__sanity != __s && errno != ERANGE)
45 +       __v = __d;
46 +      else
47 +       __err |= ios_base::failbit;
48      }
49  
50    template<>
51 @@ -80,16 +74,13 @@ namespace std 
52      __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
53                    const __c_locale& __cloc)
54      {
55 -      if (!(__err & ios_base::failbit))
56 -       {
57 -         char* __sanity;
58 -         errno = 0;
59 -         long double __ld = __strtold_l(__s, &__sanity, __cloc);
60 -          if (__sanity != __s && errno != ERANGE)
61 -           __v = __ld;
62 -         else
63 -           __err |= ios_base::failbit;
64 -       }
65 +      char* __sanity;
66 +      errno = 0;
67 +      long double __ld = __strtold_l(__s, &__sanity, __cloc);
68 +      if (__sanity != __s && errno != ERANGE)
69 +       __v = __ld;
70 +      else
71 +       __err |= ios_base::failbit;
72      }
73  
74    void
75 @@ -110,7 +101,7 @@ namespace std 
76    void
77    locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
78    {
79 -    if (_S_get_c_locale() != __cloc)
80 +    if (__cloc && _S_get_c_locale() != __cloc)
81        __freelocale(__cloc); 
82    }
83  
84 --- a/libstdc++-v3/config/locale/uclibc/ctype_members.cc
85 +++ b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
86 @@ -33,9 +33,14 @@
87  
88  // Written by Benjamin Kosnik <bkoz@redhat.com>
89  
90 +#include <features.h>
91 +#ifdef __UCLIBC_HAS_LOCALE__
92  #define _LIBC
93  #include <locale>
94  #undef _LIBC
95 +#else
96 +#include <locale>
97 +#endif
98  #include <bits/c++locale_internal.h>
99  
100  namespace std
101 @@ -138,20 +143,34 @@ namespace std
102    ctype<wchar_t>::
103    do_is(mask __m, wchar_t __c) const
104    { 
105 -    // Highest bitmask in ctype_base == 10, but extra in "C"
106 -    // library for blank.
107 +    // The case of __m == ctype_base::space is particularly important,
108 +    // due to its use in many istream functions.  Therefore we deal with
109 +    // it first, exploiting the knowledge that on GNU systems _M_bit[5]
110 +    // is the mask corresponding to ctype_base::space.  NB: an encoding
111 +    // change would not affect correctness!
112      bool __ret = false;
113 -    const size_t __bitmasksize = 11; 
114 -    for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
115 -      if (__m & _M_bit[__bitcur]
116 -         && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
117 -       {
118 -         __ret = true;
119 -         break;
120 -       }
121 +    if (__m == _M_bit[5])
122 +      __ret = __iswctype_l(__c, _M_wmask[5], _M_c_locale_ctype);
123 +    else
124 +      {
125 +       // Highest bitmask in ctype_base == 10, but extra in "C"
126 +       // library for blank.
127 +       const size_t __bitmasksize = 11;
128 +       for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
129 +         if (__m & _M_bit[__bitcur])
130 +           {
131 +             if (__iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
132 +               {
133 +                 __ret = true;
134 +                 break;
135 +               }
136 +             else if (__m == _M_bit[__bitcur])
137 +               break;
138 +           }
139 +      }
140      return __ret;    
141    }
142 -  
143 +
144    const wchar_t* 
145    ctype<wchar_t>::
146    do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
147 --- a/libstdc++-v3/config/locale/uclibc/messages_members.h
148 +++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
149 @@ -47,18 +47,21 @@
150    template<typename _CharT>
151       messages<_CharT>::messages(size_t __refs)
152       : facet(__refs), _M_c_locale_messages(_S_get_c_locale()), 
153 -     _M_name_messages(_S_get_c_name())
154 +       _M_name_messages(_S_get_c_name())
155       { }
156  
157    template<typename _CharT>
158       messages<_CharT>::messages(__c_locale __cloc, const char* __s, 
159                                 size_t __refs) 
160 -     : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
161 -     _M_name_messages(__s)
162 +     : facet(__refs), _M_c_locale_messages(NULL), _M_name_messages(NULL)
163       {
164 -       char* __tmp = new char[std::strlen(__s) + 1];
165 -       std::strcpy(__tmp, __s);
166 +       const size_t __len = std::strlen(__s) + 1;
167 +       char* __tmp = new char[__len];
168 +       std::memcpy(__tmp, __s, __len);
169         _M_name_messages = __tmp;
170 +
171 +       // Last to avoid leaking memory if new throws.
172 +       _M_c_locale_messages = _S_clone_c_locale(__cloc);
173       }
174  
175    template<typename _CharT>
176 --- a/libstdc++-v3/config/locale/uclibc/monetary_members.cc
177 +++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
178 @@ -33,9 +33,14 @@
179  
180  // Written by Benjamin Kosnik <bkoz@redhat.com>
181  
182 +#include <features.h>
183 +#ifdef __UCLIBC_HAS_LOCALE__
184  #define _LIBC
185  #include <locale>
186  #undef _LIBC
187 +#else
188 +#include <locale>
189 +#endif
190  #include <bits/c++locale_internal.h>
191  
192  #ifdef __UCLIBC_MJN3_ONLY__
193 @@ -206,7 +211,7 @@ namespace std
194           }
195         break;
196        default:
197 -       ;
198 +       __ret = pattern();
199        }
200      return __ret;
201    }
202 --- a/libstdc++-v3/config/locale/uclibc/numeric_members.cc
203 +++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
204 @@ -33,9 +33,14 @@
205  
206  // Written by Benjamin Kosnik <bkoz@redhat.com>
207  
208 +#include <features.h>
209 +#ifdef __UCLIBC_HAS_LOCALE__
210  #define _LIBC
211  #include <locale>
212  #undef _LIBC
213 +#else
214 +#include <locale>
215 +#endif
216  #include <bits/c++locale_internal.h>
217  
218  #ifdef __UCLIBC_MJN3_ONLY__
219 --- a/libstdc++-v3/config/locale/uclibc/time_members.h
220 +++ b/libstdc++-v3/config/locale/uclibc/time_members.h
221 @@ -37,25 +37,33 @@
222    template<typename _CharT>
223      __timepunct<_CharT>::__timepunct(size_t __refs) 
224      : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), 
225 -    _M_name_timepunct(_S_get_c_name())
226 +      _M_name_timepunct(_S_get_c_name())
227      { _M_initialize_timepunct(); }
228  
229    template<typename _CharT>
230      __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) 
231      : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(NULL), 
232 -    _M_name_timepunct(_S_get_c_name())
233 +      _M_name_timepunct(_S_get_c_name())
234      { _M_initialize_timepunct(); }
235  
236    template<typename _CharT>
237      __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
238                                      size_t __refs) 
239      : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), 
240 -    _M_name_timepunct(__s)
241 +      _M_name_timepunct(NULL)
242      { 
243 -      char* __tmp = new char[std::strlen(__s) + 1];
244 -      std::strcpy(__tmp, __s);
245 +      const size_t __len = std::strlen(__s) + 1;
246 +      char* __tmp = new char[__len];
247 +      std::memcpy(__tmp, __s, __len);
248        _M_name_timepunct = __tmp;
249 -      _M_initialize_timepunct(__cloc); 
250 +
251 +      try
252 +       { _M_initialize_timepunct(__cloc); }
253 +      catch(...)
254 +       {
255 +         delete [] _M_name_timepunct;
256 +         __throw_exception_again;
257 +       }
258      }
259  
260    template<typename _CharT>
261 --- a/libstdc++-v3/config/locale/uclibc/c_locale.h
262 +++ b/libstdc++-v3/config/locale/uclibc/c_locale.h
263 @@ -39,21 +39,23 @@
264  #pragma GCC system_header
265  
266  #include <cstring>              // get std::strlen
267 -#include <cstdio>               // get std::snprintf or std::sprintf
268 +#include <cstdio>               // get std::vsnprintf or std::vsprintf
269  #include <clocale>
270  #include <langinfo.h>          // For codecvt
271  #ifdef __UCLIBC_MJN3_ONLY__
272  #warning fix this
273  #endif
274 -#ifdef __UCLIBC_HAS_LOCALE__
275 +#ifdef _GLIBCXX_USE_ICONV
276  #include <iconv.h>             // For codecvt using iconv, iconv_t
277  #endif
278 -#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
279 -#include <libintl.h>           // For messages
280 +#ifdef HAVE_LIBINTL_H
281 +#include <libintl.h>           // For messages
282  #endif
283 +#include <cstdarg>
284  
285  #ifdef __UCLIBC_MJN3_ONLY__
286  #warning what is _GLIBCXX_C_LOCALE_GNU for
287 +// psm: used in os/gnu-linux/ctype_noninline.h
288  #endif
289  #define _GLIBCXX_C_LOCALE_GNU 1
290  
291 @@ -62,7 +64,7 @@
292  #endif
293  // #define _GLIBCXX_NUM_CATEGORIES 6
294  #define _GLIBCXX_NUM_CATEGORIES 0
295
296 +
297  #ifdef __UCLIBC_HAS_XLOCALE__
298  namespace __gnu_cxx
299  {
300 @@ -79,22 +81,24 @@ namespace std
301    typedef int*                 __c_locale;
302  #endif
303  
304 -  // Convert numeric value of type _Tv to string and return length of
305 -  // string.  If snprintf is available use it, otherwise fall back to
306 -  // the unsafe sprintf which, in general, can be dangerous and should
307 +  // Convert numeric value of type double to string and return length of
308 +  // string.  If vsnprintf is available use it, otherwise fall back to
309 +  // the unsafe vsprintf which, in general, can be dangerous and should
310    // be avoided.
311 -  template<typename _Tv>
312 -    int
313 -    __convert_from_v(char* __out, 
314 -                    const int __size __attribute__ ((__unused__)),
315 -                    const char* __fmt,
316 -#ifdef __UCLIBC_HAS_XCLOCALE__
317 -                    _Tv __v, const __c_locale& __cloc, int __prec)
318 +    inline int
319 +    __convert_from_v(const __c_locale&
320 +#ifndef __UCLIBC_HAS_XCLOCALE__
321 +                                       __cloc __attribute__ ((__unused__))
322 +#endif
323 +                    ,
324 +                    char* __out,
325 +                    const int __size,
326 +                    const char* __fmt, ...)
327      {
328 +      va_list __args;
329 +#ifdef __UCLIBC_HAS_XCLOCALE__
330        __c_locale __old = __gnu_cxx::__uselocale(__cloc);
331  #else
332 -                    _Tv __v, const __c_locale&, int __prec)
333 -    {
334  # ifdef __UCLIBC_HAS_LOCALE__
335        char* __old = std::setlocale(LC_ALL, NULL);
336        char* __sav = new char[std::strlen(__old) + 1];
337 @@ -103,7 +107,9 @@ namespace std
338  # endif
339  #endif
340  
341 -      const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
342 +      va_start(__args, __fmt);
343 +      const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
344 +      va_end(__args);
345  
346  #ifdef __UCLIBC_HAS_XCLOCALE__
347        __gnu_cxx::__uselocale(__old);