blob: 728b7908209461e578292416d0608eb9d6b8a79a [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001From 244b9d1b5cc6d5382935192998531ee70afb262d Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Fri, 29 Mar 2013 08:46:58 +0400
4Subject: [PATCH 07/35] uclibc-locale-update
5
6Signed-off-by: Khem Raj <raj.khem@gmail.com>
7
8Upstream-Status: Pending
9---
10 .../config/locale/uclibc/c++locale_internal.h | 3 +
11 libstdc++-v3/config/locale/uclibc/c_locale.cc | 74 ++++++++++------------
12 libstdc++-v3/config/locale/uclibc/c_locale.h | 42 ++++++------
13 libstdc++-v3/config/locale/uclibc/ctype_members.cc | 51 +++++++++++----
14 .../config/locale/uclibc/messages_members.h | 12 ++--
15 .../config/locale/uclibc/monetary_members.cc | 34 ++++++----
16 .../config/locale/uclibc/numeric_members.cc | 5 ++
17 libstdc++-v3/config/locale/uclibc/time_members.cc | 18 ++++--
18 libstdc++-v3/config/locale/uclibc/time_members.h | 17 +++--
19 9 files changed, 158 insertions(+), 98 deletions(-)
20
21diff --git a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
22index e74fddf..971a6b4 100644
23--- a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
24+++ b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
25@@ -31,6 +31,9 @@
26
27 #include <bits/c++config.h>
28 #include <clocale>
29+#include <cstdlib>
30+#include <cstring>
31+#include <cstddef>
32
33 #ifdef __UCLIBC_MJN3_ONLY__
34 #warning clean this up
35diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.cc b/libstdc++-v3/config/locale/uclibc/c_locale.cc
36index 21430d0..1b9d8e1 100644
37--- a/libstdc++-v3/config/locale/uclibc/c_locale.cc
38+++ b/libstdc++-v3/config/locale/uclibc/c_locale.cc
39@@ -39,23 +39,20 @@
40 #include <langinfo.h>
41 #include <bits/c++locale_internal.h>
42
43-namespace std
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& __cloc)
51 {
52- if (!(__err & ios_base::failbit))
53- {
54- char* __sanity;
55- errno = 0;
56- float __f = __strtof_l(__s, &__sanity, __cloc);
57- if (__sanity != __s && errno != ERANGE)
58- __v = __f;
59- else
60- __err |= ios_base::failbit;
61- }
62+ char* __sanity;
63+ errno = 0;
64+ float __f = __strtof_l(__s, &__sanity, __cloc);
65+ if (__sanity != __s && errno != ERANGE)
66+ __v = __f;
67+ else
68+ __err |= ios_base::failbit;
69 }
70
71 template<>
72@@ -63,16 +60,13 @@ namespace std
73 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
74 const __c_locale& __cloc)
75 {
76- if (!(__err & ios_base::failbit))
77- {
78- char* __sanity;
79- errno = 0;
80- double __d = __strtod_l(__s, &__sanity, __cloc);
81- if (__sanity != __s && errno != ERANGE)
82- __v = __d;
83- else
84- __err |= ios_base::failbit;
85- }
86+ char* __sanity;
87+ errno = 0;
88+ double __d = __strtod_l(__s, &__sanity, __cloc);
89+ if (__sanity != __s && errno != ERANGE)
90+ __v = __d;
91+ else
92+ __err |= ios_base::failbit;
93 }
94
95 template<>
96@@ -80,16 +74,13 @@ namespace std
97 __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
98 const __c_locale& __cloc)
99 {
100- if (!(__err & ios_base::failbit))
101- {
102- char* __sanity;
103- errno = 0;
104- long double __ld = __strtold_l(__s, &__sanity, __cloc);
105- if (__sanity != __s && errno != ERANGE)
106- __v = __ld;
107- else
108- __err |= ios_base::failbit;
109- }
110+ char* __sanity;
111+ errno = 0;
112+ long double __ld = __strtold_l(__s, &__sanity, __cloc);
113+ if (__sanity != __s && errno != ERANGE)
114+ __v = __ld;
115+ else
116+ __err |= ios_base::failbit;
117 }
118
119 void
120@@ -110,17 +101,18 @@ namespace std
121 void
122 locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
123 {
124- if (_S_get_c_locale() != __cloc)
125+ if (__cloc && _S_get_c_locale() != __cloc)
126 __freelocale(__cloc);
127 }
128
129 __c_locale
130 locale::facet::_S_clone_c_locale(__c_locale& __cloc)
131 { return __duplocale(__cloc); }
132-} // namespace std
133
134-namespace __gnu_cxx
135-{
136+_GLIBCXX_END_NAMESPACE
137+
138+_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
139+
140 const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
141 {
142 "LC_CTYPE",
143@@ -138,9 +130,11 @@ namespace __gnu_cxx
144 "LC_IDENTIFICATION"
145 #endif
146 };
147-}
148
149-namespace std
150-{
151+_GLIBCXX_END_NAMESPACE
152+
153+_GLIBCXX_BEGIN_NAMESPACE(std)
154+
155 const char* const* const locale::_S_categories = __gnu_cxx::category_names;
156-} // namespace std
157+
158+_GLIBCXX_END_NAMESPACE
159diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.h b/libstdc++-v3/config/locale/uclibc/c_locale.h
160index 4bca5f1..64a6d46 100644
161--- a/libstdc++-v3/config/locale/uclibc/c_locale.h
162+++ b/libstdc++-v3/config/locale/uclibc/c_locale.h
163@@ -39,21 +39,23 @@
164 #pragma GCC system_header
165
166 #include <cstring> // get std::strlen
167-#include <cstdio> // get std::snprintf or std::sprintf
168+#include <cstdio> // get std::vsnprintf or std::vsprintf
169 #include <clocale>
170 #include <langinfo.h> // For codecvt
171 #ifdef __UCLIBC_MJN3_ONLY__
172 #warning fix this
173 #endif
174-#ifdef __UCLIBC_HAS_LOCALE__
175+#ifdef _GLIBCXX_USE_ICONV
176 #include <iconv.h> // For codecvt using iconv, iconv_t
177 #endif
178-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
179-#include <libintl.h> // For messages
180+#ifdef HAVE_LIBINTL_H
181+#include <libintl.h> // For messages
182 #endif
183+#include <cstdarg>
184
185 #ifdef __UCLIBC_MJN3_ONLY__
186 #warning what is _GLIBCXX_C_LOCALE_GNU for
187+// psm: used in os/gnu-linux/ctype_noninline.h
188 #endif
189 #define _GLIBCXX_C_LOCALE_GNU 1
190
191@@ -78,23 +80,25 @@ namespace std
192 #else
193 typedef int* __c_locale;
194 #endif
195-
196- // Convert numeric value of type _Tv to string and return length of
197- // string. If snprintf is available use it, otherwise fall back to
198- // the unsafe sprintf which, in general, can be dangerous and should
199+ // Convert numeric value of type double to string and return length of
200+ // string. If vsnprintf is available use it, otherwise fall back to
201+ // the unsafe vsprintf which, in general, can be dangerous and should
202 // be avoided.
203- template<typename _Tv>
204- int
205- __convert_from_v(char* __out,
206- const int __size __attribute__ ((__unused__)),
207- const char* __fmt,
208-#ifdef __UCLIBC_HAS_XCLOCALE__
209- _Tv __v, const __c_locale& __cloc, int __prec)
210+ inline int
211+ __convert_from_v(const __c_locale&
212+#ifndef __UCLIBC_HAS_XCLOCALE__
213+ __cloc __attribute__ ((__unused__))
214+#endif
215+ ,
216+ char* __out,
217+ const int __size,
218+ const char* __fmt, ...)
219 {
220+ va_list __args;
221+#ifdef __UCLIBC_HAS_XCLOCALE__
222+
223 __c_locale __old = __gnu_cxx::__uselocale(__cloc);
224 #else
225- _Tv __v, const __c_locale&, int __prec)
226- {
227 # ifdef __UCLIBC_HAS_LOCALE__
228 char* __old = std::setlocale(LC_ALL, NULL);
229 char* __sav = new char[std::strlen(__old) + 1];
230@@ -103,7 +107,9 @@ namespace std
231 # endif
232 #endif
233
234- const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
235+ va_start(__args, __fmt);
236+ const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
237+ va_end(__args);
238
239 #ifdef __UCLIBC_HAS_XCLOCALE__
240 __gnu_cxx::__uselocale(__old);
241diff --git a/libstdc++-v3/config/locale/uclibc/ctype_members.cc b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
242index 7b12861..13e011d 100644
243--- a/libstdc++-v3/config/locale/uclibc/ctype_members.cc
244+++ b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
245@@ -33,16 +33,20 @@
246
247 // Written by Benjamin Kosnik <bkoz@redhat.com>
248
249+#include <features.h>
250+#ifdef __UCLIBC_HAS_LOCALE__
251 #define _LIBC
252 #include <locale>
253 #undef _LIBC
254+#else
255+#include <locale>
256+#endif
257 #include <bits/c++locale_internal.h>
258
259-namespace std
260-{
261+_GLIBCXX_BEGIN_NAMESPACE(std)
262+
263 // NB: The other ctype<char> specializations are in src/locale.cc and
264 // various /config/os/* files.
265- template<>
266 ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
267 : ctype<char>(0, false, __refs)
268 {
269@@ -57,6 +61,8 @@ namespace std
270 #endif
271 }
272 }
273+ ctype_byname<char>::~ctype_byname()
274+ { }
275
276 #ifdef _GLIBCXX_USE_WCHAR_T
277 ctype<wchar_t>::__wmask_type
278@@ -138,17 +144,33 @@ namespace std
279 ctype<wchar_t>::
280 do_is(mask __m, wchar_t __c) const
281 {
282- // Highest bitmask in ctype_base == 10, but extra in "C"
283- // library for blank.
284+ // The case of __m == ctype_base::space is particularly important,
285+ // due to its use in many istream functions. Therefore we deal with
286+ // it first, exploiting the knowledge that on GNU systems _M_bit[5]
287+ // is the mask corresponding to ctype_base::space. NB: an encoding
288+ // change would not affect correctness!
289+
290 bool __ret = false;
291- const size_t __bitmasksize = 11;
292- for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
293- if (__m & _M_bit[__bitcur]
294- && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
295- {
296- __ret = true;
297- break;
298- }
299+ if (__m == _M_bit[5])
300+ __ret = __iswctype_l(__c, _M_wmask[5], _M_c_locale_ctype);
301+ else
302+ {
303+ // Highest bitmask in ctype_base == 10, but extra in "C"
304+ // library for blank.
305+ const size_t __bitmasksize = 11;
306+ for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
307+ if (__m & _M_bit[__bitcur])
308+ {
309+ if (__iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
310+ {
311+ __ret = true;
312+ break;
313+ }
314+ else if (__m == _M_bit[__bitcur])
315+ break;
316+ }
317+ }
318+
319 return __ret;
320 }
321
322@@ -290,4 +312,5 @@ namespace std
323 #endif
324 }
325 #endif // _GLIBCXX_USE_WCHAR_T
326-}
327+
328+_GLIBCXX_END_NAMESPACE
329diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.h b/libstdc++-v3/config/locale/uclibc/messages_members.h
330index d89da33..067657a 100644
331--- a/libstdc++-v3/config/locale/uclibc/messages_members.h
332+++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
333@@ -53,12 +53,16 @@
334 template<typename _CharT>
335 messages<_CharT>::messages(__c_locale __cloc, const char* __s,
336 size_t __refs)
337- : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
338- _M_name_messages(__s)
339+ : facet(__refs), _M_c_locale_messages(NULL),
340+ _M_name_messages(NULL)
341 {
342- char* __tmp = new char[std::strlen(__s) + 1];
343- std::strcpy(__tmp, __s);
344+ const size_t __len = std::strlen(__s) + 1;
345+ char* __tmp = new char[__len];
346+ std::memcpy(__tmp, __s, __len);
347 _M_name_messages = __tmp;
348+
349+ // Last to avoid leaking memory if new throws.
350+ _M_c_locale_messages = _S_clone_c_locale(__cloc);
351 }
352
353 template<typename _CharT>
354diff --git a/libstdc++-v3/config/locale/uclibc/monetary_members.cc b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
355index 31ebb9f..7679b9c 100644
356--- a/libstdc++-v3/config/locale/uclibc/monetary_members.cc
357+++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
358@@ -33,9 +33,14 @@
359
360 // Written by Benjamin Kosnik <bkoz@redhat.com>
361
362+#include <features.h>
363+#ifdef __UCLIBC_HAS_LOCALE__
364 #define _LIBC
365 #include <locale>
366 #undef _LIBC
367+#else
368+#include <locale>
369+#endif
370 #include <bits/c++locale_internal.h>
371
372 #ifdef __UCLIBC_MJN3_ONLY__
373@@ -206,7 +211,7 @@ namespace std
374 }
375 break;
376 default:
377- ;
378+ __ret = pattern();
379 }
380 return __ret;
381 }
382@@ -390,7 +395,9 @@ namespace std
383 __c_locale __old = __uselocale(__cloc);
384 #else
385 // Switch to named locale so that mbsrtowcs will work.
386- char* __old = strdup(setlocale(LC_ALL, NULL));
387+ char* __old = setlocale(LC_ALL, NULL);
388+ const size_t __llen = strlen(__old) + 1;
389+ char* __sav = new char[__llen];
390 setlocale(LC_ALL, __name);
391 #endif
392
393@@ -477,8 +484,8 @@ namespace std
394 #ifdef __UCLIBC_HAS_XLOCALE__
395 __uselocale(__old);
396 #else
397- setlocale(LC_ALL, __old);
398- free(__old);
399+ setlocale(LC_ALL, __sav);
400+ delete [] __sav;
401 #endif
402 __throw_exception_again;
403 }
404@@ -498,8 +505,8 @@ namespace std
405 #ifdef __UCLIBC_HAS_XLOCALE__
406 __uselocale(__old);
407 #else
408- setlocale(LC_ALL, __old);
409- free(__old);
410+ setlocale(LC_ALL, __sav);
411+ delete [] __sav;
412 #endif
413 }
414 }
415@@ -545,8 +552,11 @@ namespace std
416 __c_locale __old = __uselocale(__cloc);
417 #else
418 // Switch to named locale so that mbsrtowcs will work.
419- char* __old = strdup(setlocale(LC_ALL, NULL));
420- setlocale(LC_ALL, __name);
421+ char* __old = setlocale(LC_ALL, NULL);
422+ const size_t __llen = strlen(__old) + 1;
423+ char* __sav = new char[__llen];
424+ memcpy(__sav, __old, __llen);
425+ setlocale(LC_ALL, __name);
426 #endif
427
428 #ifdef __UCLIBC_MJN3_ONLY__
429@@ -633,8 +643,8 @@ namespace std
430 #ifdef __UCLIBC_HAS_XLOCALE__
431 __uselocale(__old);
432 #else
433- setlocale(LC_ALL, __old);
434- free(__old);
435+ setlocale(LC_ALL, __sav);
436+ delete [] __sav;
437 #endif
438 __throw_exception_again;
439 }
440@@ -653,8 +663,8 @@ namespace std
441 #ifdef __UCLIBC_HAS_XLOCALE__
442 __uselocale(__old);
443 #else
444- setlocale(LC_ALL, __old);
445- free(__old);
446+ setlocale(LC_ALL, __sav);
447+ delete [] __sav;
448 #endif
449 }
450 }
451diff --git a/libstdc++-v3/config/locale/uclibc/numeric_members.cc b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
452index d5c8961..8ae8969 100644
453--- a/libstdc++-v3/config/locale/uclibc/numeric_members.cc
454+++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
455@@ -33,9 +33,14 @@
456
457 // Written by Benjamin Kosnik <bkoz@redhat.com>
458
459+#include <features.h>
460+#ifdef __UCLIBC_HAS_LOCALE__
461 #define _LIBC
462 #include <locale>
463 #undef _LIBC
464+#else
465+#include <locale>
466+#endif
467 #include <bits/c++locale_internal.h>
468
469 #ifdef __UCLIBC_MJN3_ONLY__
470diff --git a/libstdc++-v3/config/locale/uclibc/time_members.cc b/libstdc++-v3/config/locale/uclibc/time_members.cc
471index d848ed5..f24d53e 100644
472--- a/libstdc++-v3/config/locale/uclibc/time_members.cc
473+++ b/libstdc++-v3/config/locale/uclibc/time_members.cc
474@@ -53,11 +53,14 @@ namespace std
475 const size_t __len = __strftime_l(__s, __maxlen, __format, __tm,
476 _M_c_locale_timepunct);
477 #else
478- char* __old = strdup(setlocale(LC_ALL, NULL));
479+ char* __old = setlocale(LC_ALL, NULL);
480+ const size_t __llen = strlen(__old) + 1;
481+ char* __sav = new char[__llen];
482+ memcpy(__sav, __old, __llen);
483 setlocale(LC_ALL, _M_name_timepunct);
484 const size_t __len = strftime(__s, __maxlen, __format, __tm);
485- setlocale(LC_ALL, __old);
486- free(__old);
487+ setlocale(LC_ALL, __sav);
488+ delete [] __sav;
489 #endif
490 // Make sure __s is null terminated.
491 if (__len == 0)
492@@ -207,11 +210,14 @@ namespace std
493 const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm,
494 _M_c_locale_timepunct);
495 #else
496- char* __old = strdup(setlocale(LC_ALL, NULL));
497+ char* __old = setlocale(LC_ALL, NULL);
498+ const size_t __llen = strlen(__old) + 1;
499+ char* __sav = new char[__llen];
500+ memcpy(__sav, __old, __llen);
501 setlocale(LC_ALL, _M_name_timepunct);
502 const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
503- setlocale(LC_ALL, __old);
504- free(__old);
505+ setlocale(LC_ALL, __sav);
506+ delete [] __sav;
507 #endif
508 // Make sure __s is null terminated.
509 if (__len == 0)
510diff --git a/libstdc++-v3/config/locale/uclibc/time_members.h b/libstdc++-v3/config/locale/uclibc/time_members.h
511index ba8e858..1665dde 100644
512--- a/libstdc++-v3/config/locale/uclibc/time_members.h
513+++ b/libstdc++-v3/config/locale/uclibc/time_members.h
514@@ -50,12 +50,21 @@
515 __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
516 size_t __refs)
517 : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
518- _M_name_timepunct(__s)
519+ _M_name_timepunct(NULL)
520 {
521- char* __tmp = new char[std::strlen(__s) + 1];
522- std::strcpy(__tmp, __s);
523+ const size_t __len = std::strlen(__s) + 1;
524+ char* __tmp = new char[__len];
525+ std::memcpy(__tmp, __s, __len);
526 _M_name_timepunct = __tmp;
527- _M_initialize_timepunct(__cloc);
528+
529+ try
530+ { _M_initialize_timepunct(__cloc); }
531+ catch(...)
532+ {
533+ delete [] _M_name_timepunct;
534+ __throw_exception_again;
535+ }
536+
537 }
538
539 template<typename _CharT>
540--
5412.1.4
542