Hi everyone,
I've reworked the patch to merged dragonfly and AIX
models into the new one named "ieee_1003.1-2008".
It seems okay on the AIX part but if someone can test
on Dragonfly and Freebsd I would be glad. Configure
needs to be regenerated, first.
For now, I've used #ifdef inside the code for the few
differences. There are less than I thought. So, it seems
okay to me.
However, I haven't changed all the (locale_t) casts
made on Dragonfly when passing a locale object to
a syscall. On AIX, this is transparent, __c_locale being
locale_t.
I haven't updated tests failing on AIX yet.
And I don't know for the Changelog/Patch, how renamed
files must be handled ? I've retrieved my git commit with
"git format-patch --no-renames" and thus the Changelog
is made of "Removed" and "New File". Is it okay or is there
anything special to add ? I didn't find the answer quickly.
Thanks,
Clément
From d36a04c7d4eb390817d711dc59ad0e0759bccdce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <clement.chi...@atos.net>
Date: Tue, 29 Dec 2020 11:08:33 +0100
Subject: [PATCH] libstdc++: implement locale support for POSIX 2008
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The implementation is based on dragonfly one.
It also adds support for AIX with a few tweaks.
As of now, a few locale functions are missing on AIX.
For strftime_l, localeconv_l, mbstowcs_l and wcsftime_l,
uselocale must be set prior to use the version without _l.
For strtof_l, strtod_l, strtold_l, a wrapper simply calls
the default version.
libstdc++-v3/ChangeLog:
2021-01-12 Clément Chigot <clement.chi...@atos.net>
* acinclude.m4: Add ieee_1003.1-2008 locale model.
* configure: Regenerate.
* config/os/aix/ctype_configure_char.cc: Enable locale support.
* testsuite/lib/libstdc++.exp (check_v3_target_namedlocale):
Handle AIX locale names.
* testsuite/util/testsuite_hooks.h: Likewise.
* config/locale/dragonfly/c_locale.cc: Removed.
* config/locale/dragonfly/c_locale.h: Removed.
* config/locale/dragonfly/codecvt_members.cc: Removed.
* config/locale/dragonfly/collate_members.cc: Removed.
* config/locale/dragonfly/ctype_members.cc: Removed.
* config/locale/dragonfly/monetary_members.cc: Removed.
* config/locale/dragonfly/numeric_members.cc: Removed.
* config/locale/dragonfly/time_members.cc: Removed.
* config/locale/dragonfly/time_members.h: Removed.
* config/locale/ieee_1003.1-2008/c_locale.cc: New file.
* config/locale/ieee_1003.1-2008/c_locale.h: New file.
* config/locale/ieee_1003.1-2008/codecvt_members.cc: New file.
* config/locale/ieee_1003.1-2008/collate_members.cc: New file.
* config/locale/ieee_1003.1-2008/ctype_members.cc: New file.
* config/locale/ieee_1003.1-2008/monetary_members.cc: New file.
* config/locale/ieee_1003.1-2008/numeric_members.cc: New file.
* config/locale/ieee_1003.1-2008/time_members.cc: New file.
* config/locale/ieee_1003.1-2008/time_members.h: New file.
---
libstdc++-v3/acinclude.m4 | 41 ++++++-------
.../c_locale.cc | 3 +
.../c_locale.h | 31 ++++++++++
.../codecvt_members.cc | 0
.../collate_members.cc | 0
.../ctype_members.cc | 58 +++++++++++++++++++
.../monetary_members.cc | 39 ++++++++++++-
.../numeric_members.cc | 27 +++++++++
.../time_members.cc | 32 +++++++++-
.../time_members.h | 0
.../config/os/aix/ctype_configure_char.cc | 44 +++++++++++---
libstdc++-v3/testsuite/lib/libstdc++.exp | 5 ++
libstdc++-v3/testsuite/util/testsuite_hooks.h | 3 +
13 files changed, 252 insertions(+), 31 deletions(-)
rename libstdc++-v3/config/locale/{dragonfly => ieee_1003.1-2008}/c_locale.cc
(99%)
rename libstdc++-v3/config/locale/{dragonfly => ieee_1003.1-2008}/c_locale.h
(80%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/codecvt_members.cc (100%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/collate_members.cc (100%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/ctype_members.cc (82%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/monetary_members.cc (97%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/numeric_members.cc (93%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/time_members.cc (94%)
rename libstdc++-v3/config/locale/{dragonfly =>
ieee_1003.1-2008}/time_members.h (100%)
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index e4175ea3e64..64a91b72359 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2421,7 +2421,7 @@ dnl
AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
GLIBCXX_ENABLE(clocale,auto,[[[=MODEL]]],
[use MODEL for target locale package],
- [permit generic|gnu|ieee_1003.1-2001|newlib|yes|no|auto])
+ [permit generic|gnu|ieee_1003.1-2001|ieee_1003.1-2008|newlib|yes|no|auto])
# Deal with gettext issues. Default to not using it (=no) until we detect
# support for it later. Let the user turn it off via --e/d, but let that
@@ -2448,8 +2448,8 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
darwin*)
enable_clocale_flag=darwin
;;
- dragonfly* | freebsd*)
- enable_clocale_flag=dragonfly
+ aix* | dragonfly* | freebsd*)
+ enable_clocale_flag=ieee_1003.1-2008
;;
openbsd*)
enable_clocale_flag=newlib
@@ -2543,23 +2543,6 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
;;
- dragonfly)
- AC_MSG_RESULT(dragonfly or freebsd)
-
- CLOCALE_H=config/locale/dragonfly/c_locale.h
- CLOCALE_CC=config/locale/dragonfly/c_locale.cc
- CCODECVT_CC=config/locale/dragonfly/codecvt_members.cc
- CCOLLATE_CC=config/locale/dragonfly/collate_members.cc
- CCTYPE_CC=config/locale/dragonfly/ctype_members.cc
- CMESSAGES_H=config/locale/generic/messages_members.h
- CMESSAGES_CC=config/locale/generic/messages_members.cc
- CMONEY_CC=config/locale/dragonfly/monetary_members.cc
- CNUMERIC_CC=config/locale/dragonfly/numeric_members.cc
- CTIME_H=config/locale/dragonfly/time_members.h
- CTIME_CC=config/locale/dragonfly/time_members.cc
- CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
- ;;
-
gnu)
AC_MSG_RESULT(gnu)
@@ -2610,6 +2593,24 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
CTIME_CC=config/locale/generic/time_members.cc
CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
;;
+
+ ieee_1003.1-2008)
+ AC_MSG_RESULT(ieee_1003.1-2008)
+
+ CLOCALE_H=config/locale/ieee_1003.1-2008/c_locale.h
+ CLOCALE_CC=config/locale/ieee_1003.1-2008/c_locale.cc
+ CCODECVT_CC=config/locale/ieee_1003.1-2008/codecvt_members.cc
+ CCOLLATE_CC=config/locale/ieee_1003.1-2008/collate_members.cc
+ CCTYPE_CC=config/locale/ieee_1003.1-2008/ctype_members.cc
+ CMESSAGES_H=config/locale/generic/messages_members.h
+ CMESSAGES_CC=config/locale/generic/messages_members.cc
+ CMONEY_CC=config/locale/ieee_1003.1-2008/monetary_members.cc
+ CNUMERIC_CC=config/locale/ieee_1003.1-2008/numeric_members.cc
+ CTIME_H=config/locale/ieee_1003.1-2008/time_members.h
+ CTIME_CC=config/locale/ieee_1003.1-2008/time_members.cc
+ CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
+ ;;
+
newlib)
AC_MSG_RESULT(newlib)
diff --git a/libstdc++-v3/config/locale/dragonfly/c_locale.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/c_locale.cc
similarity index 99%
rename from libstdc++-v3/config/locale/dragonfly/c_locale.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/c_locale.cc
index 02df4605bb5..988f34ab6ed 100644
--- a/libstdc++-v3/config/locale/dragonfly/c_locale.cc
+++ b/libstdc++-v3/config/locale/ieee_1003.1-2008/c_locale.cc
@@ -33,8 +33,11 @@
#include <locale>
#include <stdexcept>
#include <limits>
+
+#ifdef __DragonFly__
#include <langinfo.h>
#include <xlocale.h>
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/config/locale/dragonfly/c_locale.h
b/libstdc++-v3/config/locale/ieee_1003.1-2008/c_locale.h
similarity index 80%
rename from libstdc++-v3/config/locale/dragonfly/c_locale.h
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/c_locale.h
index cf4281cebbf..f77f815c61b 100644
--- a/libstdc++-v3/config/locale/dragonfly/c_locale.h
+++ b/libstdc++-v3/config/locale/ieee_1003.1-2008/c_locale.h
@@ -40,7 +40,34 @@
#pragma GCC system_header
#include <clocale>
+#ifdef __DragonFly__
#include <xlocale.h>
+#endif
+
+#ifdef _AIX
+// The following are not POSIX routines. These are quick-and-dirty hacks
+// to make things pretend to work
+extern "C" inline
+float strtof_l (const char *__nptr, char **__endptr,
+ locale_t locale)
+{
+ return strtof(__nptr, __endptr);
+}
+
+extern "C" inline
+double strtod_l (const char *__nptr, char **__endptr,
+ locale_t locale)
+{
+ return strtod(__nptr, __endptr);
+}
+
+extern "C" inline
+long double strtold_l (const char *__nptr, char **__endptr,
+ locale_t locale)
+{
+ return strtold(__nptr, __endptr);
+}
+#endif
#define _GLIBCXX_NUM_CATEGORIES 0
@@ -48,7 +75,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+#ifdef __DragonFly__
typedef int* __c_locale;
+#else
+ typedef locale_t __c_locale;
+#endif
// Convert numeric value of type double and long double to string and
// return length of string. If vsnprintf is available use it, otherwise
diff --git a/libstdc++-v3/config/locale/dragonfly/codecvt_members.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/codecvt_members.cc
similarity index 100%
rename from libstdc++-v3/config/locale/dragonfly/codecvt_members.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/codecvt_members.cc
diff --git a/libstdc++-v3/config/locale/dragonfly/collate_members.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/collate_members.cc
similarity index 100%
rename from libstdc++-v3/config/locale/dragonfly/collate_members.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/collate_members.cc
diff --git a/libstdc++-v3/config/locale/dragonfly/ctype_members.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/ctype_members.cc
similarity index 82%
rename from libstdc++-v3/config/locale/dragonfly/ctype_members.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/ctype_members.cc
index 420cb51e07a..ad9d3a4709b 100644
--- a/libstdc++-v3/config/locale/dragonfly/ctype_members.cc
+++ b/libstdc++-v3/config/locale/ieee_1003.1-2008/ctype_members.cc
@@ -34,7 +34,11 @@
#include <cstdio>
#ifndef _ISbit
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
+#else
+#define _ISbit(bit) (1 << bit)
+#endif
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@@ -135,6 +139,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __hi;
}
+#ifndef __DragonFly__
+ bool
+ ctype<wchar_t>::
+ do_is(mask __m, char_type __c) const
+ {
+ bool __ret = false;
+ // Highest bitmask in ctype_base == 11
+ const size_t __bitmasksize = 11;
+ for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
+ if (__m & _M_bit[__bitcur]
+ && iswctype(__c, _M_wmask[__bitcur]))
+ {
+ __ret = true;
+ break;
+ }
+ return __ret;
+ }
+
+ const wchar_t*
+ ctype<wchar_t>::
+ do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
+ {
+ for (;__lo < __hi; ++__vec, ++__lo)
+ {
+ // Highest bitmask in ctype_base == 11
+ const size_t __bitmasksize = 11;
+ mask __m = 0;
+ for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
+ if (iswctype(*__lo, _M_wmask[__bitcur]))
+ __m |= _M_bit[__bitcur];
+ *__vec = __m;
+ }
+ return __hi;
+ }
+
+ const wchar_t*
+ ctype<wchar_t>::
+ do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
+ {
+ while (__lo < __hi && !this->do_is(__m, *__lo))
+ ++__lo;
+ return __lo;
+ }
+
+ const wchar_t*
+ ctype<wchar_t>::
+ do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
+ {
+ while (__lo < __hi && this->do_is(__m, *__lo) != 0)
+ ++__lo;
+ return __lo;
+ }
+#endif
+
wchar_t
ctype<wchar_t>::
do_widen(char __c) const
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/monetary_members.cc
similarity index 97%
rename from libstdc++-v3/config/locale/dragonfly/monetary_members.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/monetary_members.cc
index e1decc61cbf..7680a1a3916 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/ieee_1003.1-2008/monetary_members.cc
@@ -31,7 +31,10 @@
#include <locale>
#include <cstring>
+
+#ifdef __DragonFly__
#include <xlocale.h>
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -241,7 +244,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
{
// Named locale.
+#ifdef _AIX
+ __c_locale __old = uselocale(__cloc);
+ lconv* lc = localeconv();
+#else
lconv* lc = localeconv_l((locale_t) __cloc);
+#endif
// Check for NULL, which implies no fractional digits.
if (lc->mon_decimal_point == NULL ||
@@ -348,6 +356,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
delete [] __group;
delete [] __ps;
delete [] __ns;
+#ifdef _AIX
+ uselocale(__old);
+#endif
__throw_exception_again;
}
@@ -360,6 +371,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
char __nspace = lc->int_n_sep_by_space;
_M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
__nposn);
+#ifdef _AIX
+ uselocale(__old);
+#endif
}
}
@@ -395,7 +409,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
{
// Named locale.
+#ifdef _AIX
+ __c_locale __old = uselocale(__cloc);
+ lconv* lc = localeconv();
+#else
lconv* lc = localeconv_l((locale_t) __cloc);
+#endif
// Check for NULL, which implies no fractional digits.
if (lc->mon_decimal_point == NULL ||
@@ -502,6 +521,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
delete [] __group;
delete [] __ps;
delete [] __ns;
+#ifdef _AIX
+ uselocale(__old);
+#endif
__throw_exception_again;
}
@@ -514,6 +536,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
char __nspace = lc->n_sep_by_space;
_M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
__nposn);
+#ifdef _AIX
+ uselocale(__old);
+#endif
}
}
@@ -581,9 +606,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
else
{
- __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
// Named locale.
+ // uselocale is needed for mbsrtowcs
+ __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
+#ifdef _AIX
+ lconv* lc = localeconv();
+#else
lconv* lc = localeconv_l((locale_t) __cloc);
+#endif
// Check for NULL, which implies no fractional digits.
if (lc->mon_decimal_point == NULL ||
@@ -741,9 +771,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
else
{
- __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
// Named locale.
+ // uselocale is needed for mbsrtowcs
+ __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
+#ifdef _AIX
+ lconv* lc = localeconv();
+#else
lconv* lc = localeconv_l((locale_t) __cloc);
+#endif
// Check for NULL, which implies no fractional digits.
if (lc->mon_decimal_point == NULL ||
diff --git a/libstdc++-v3/config/locale/dragonfly/numeric_members.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/numeric_members.cc
similarity index 93%
rename from libstdc++-v3/config/locale/dragonfly/numeric_members.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/numeric_members.cc
index cac6fe8c710..eb460c94088 100644
--- a/libstdc++-v3/config/locale/dragonfly/numeric_members.cc
+++ b/libstdc++-v3/config/locale/ieee_1003.1-2008/numeric_members.cc
@@ -31,7 +31,10 @@
#include <locale>
#include <cstring>
+
+#ifdef __DragonFly__
#include <xlocale.h>
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -63,7 +66,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
{
// Named locale.
+#ifdef _AIX
+ // uselocale is needed for localeconv
+ __c_locale __old = uselocale(__cloc);
+ lconv* lc = localeconv();
+#else
lconv* lc = localeconv_l((locale_t) __cloc);
+#endif
// Decimal point should always be defined, but check null anyway
if (lc->decimal_point == NULL)
@@ -103,6 +112,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
delete _M_data;
_M_data = 0;
+#ifdef _AIX
+ uselocale(__old);
+#endif
__throw_exception_again;
}
}
@@ -113,6 +125,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
_M_data->_M_grouping_size = __len;
}
+#ifdef _AIX
+ uselocale(__old);
+#endif
}
// NB: There is no way to extact this info from posix locales.
@@ -162,7 +177,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
{
// Named locale.
+#ifdef _AIX
+ // uselocale is needed for localeconv
+ __c_locale __old = uselocale(__cloc);
+ lconv* lc = localeconv();
+#else
lconv* lc = localeconv_l((locale_t) __cloc);
+#endif
// Decimal point should always be defined, but check null anyway
if (lc->decimal_point == NULL)
@@ -201,6 +222,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
delete _M_data;
_M_data = 0;
+#ifdef _AIX
+ uselocale(__old);
+#endif
__throw_exception_again;
}
}
@@ -211,6 +235,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
_M_data->_M_grouping_size = __len;
}
+#ifdef _AIX
+ uselocale(__old);
+#endif
}
// NB: There is no way to extact this info from posix locales.
diff --git a/libstdc++-v3/config/locale/dragonfly/time_members.cc
b/libstdc++-v3/config/locale/ieee_1003.1-2008/time_members.cc
similarity index 94%
rename from libstdc++-v3/config/locale/dragonfly/time_members.cc
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/time_members.cc
index c8b621a323f..660fc26de1a 100644
--- a/libstdc++-v3/config/locale/dragonfly/time_members.cc
+++ b/libstdc++-v3/config/locale/ieee_1003.1-2008/time_members.cc
@@ -35,7 +35,10 @@
#include <cwchar>
#include <stdlib.h>
#include <langinfo.h>
+
+#ifdef __DragonFly__
#include <xlocale.h>
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -47,8 +50,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_put(char* __s, size_t __maxlen, const char* __format,
const tm* __tm) const throw()
{
+#ifdef _AIX
+ __c_locale __old = uselocale(_M_c_locale_timepunct);
+ const size_t __len = strftime(__s, __maxlen, __format, __tm);
+ uselocale(__old);
+#else
const size_t __len = strftime_l(__s, __maxlen, __format, __tm,
(locale_t)_M_c_locale_timepunct);
+#endif
// Make sure __s is null terminated.
if (__len == 0)
__s[0] = '\0';
@@ -196,15 +205,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format,
const tm* __tm) const throw()
{
+#ifdef _AIX
+ __c_locale __old = uselocale(_M_c_locale_timepunct);
+ const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
+ uselocale(__old);
+#else
const size_t __len = wcsftime_l(__s, __maxlen, __format, __tm,
(locale_t)_M_c_locale_timepunct);
+#endif
// Make sure __s is null terminated.
if (__len == 0)
__s[0] = L'\0';
}
+#ifdef _AIX
+ // mbstowcs_l deosn't exist on AIX. "uselocale" must
+ // be called before using this macro.
+#define MBSTOWCS_L(WCSTRING, STRING, NUMBER, LOCALE) \
+ mbstowcs (WCSTRING, STRING, NUMBER);
+#else
+#define MBSTOWCS_L(WCSTRING, STRING, NUMBER, LOCALE) \
+ mbstowcs_l (WCSTRING, STRING, NUMBER, LOCALE);
+#endif
#define WIDE_LANGINFO(M,FMT) \
- fmtlen = mbstowcs_l (holder, nl_langinfo_l(FMT, (locale_t)__cloc), \
+ fmtlen = MBSTOWCS_L (holder, nl_langinfo_l(FMT, (locale_t)__cloc), \
128, (locale_t)__cloc); \
langstring = new wchar_t[fmtlen + 1]; \
wcsncpy (langstring, holder, fmtlen); \
@@ -281,6 +305,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
else
{
+#ifdef _AIX
+ __c_locale __old = uselocale(__cloc);
+#endif
wchar_t *langstring = 0;
wchar_t holder[128];
size_t fmtlen;
@@ -342,6 +369,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
WIDE_LANGINFO(_M_amonth10, ABMON_10)
WIDE_LANGINFO(_M_amonth11, ABMON_11)
WIDE_LANGINFO(_M_amonth12, ABMON_12)
+#ifdef _AIX
+ uselocale(__old);
+#endif
}
}
diff --git a/libstdc++-v3/config/locale/dragonfly/time_members.h
b/libstdc++-v3/config/locale/ieee_1003.1-2008/time_members.h
similarity index 100%
rename from libstdc++-v3/config/locale/dragonfly/time_members.h
rename to libstdc++-v3/config/locale/ieee_1003.1-2008/time_members.h
diff --git a/libstdc++-v3/config/os/aix/ctype_configure_char.cc
b/libstdc++-v3/config/os/aix/ctype_configure_char.cc
index b12c0bd435c..3af3457ef41 100644
--- a/libstdc++-v3/config/os/aix/ctype_configure_char.cc
+++ b/libstdc++-v3/config/os/aix/ctype_configure_char.cc
@@ -44,25 +44,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
ctype<char>::ctype(__c_locale, const mask* __table, bool __del,
size_t __refs)
- : facet(__refs), _M_del(__table != 0 && __del),
+ : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
+ _M_del(__table != 0 && __del),
_M_toupper(NULL), _M_tolower(NULL),
- _M_table(__table ? __table : classic_table())
+ _M_table(__table ? __table : classic_table()),
+ _M_widen_ok(0), _M_narrow_ok(0)
{
+ char* __old = setlocale(LC_CTYPE, NULL);
+ char* __sav = NULL;
+ if (strcmp(__old, "C"))
+ {
+ const size_t __len = strlen(__old) + 1;
+ __sav = new char[__len];
+ memcpy(__sav, __old, __len);
+ setlocale(LC_CTYPE, "C");
+ }
+ if (__sav)
+ {
+ setlocale(LC_CTYPE, __sav);
+ delete [] __sav;
+ }
memset(_M_widen, 0, sizeof(_M_widen));
- _M_widen_ok = 0;
memset(_M_narrow, 0, sizeof(_M_narrow));
- _M_narrow_ok = 0;
}
ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
- : facet(__refs), _M_del(__table != 0 && __del),
+ : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
+ _M_del(__table != 0 && __del),
_M_toupper(NULL), _M_tolower(NULL),
- _M_table(__table ? __table : classic_table())
+ _M_table(__table ? __table : classic_table()),
+ _M_widen_ok(0), _M_narrow_ok(0)
{
+ char* __old = setlocale(LC_CTYPE, NULL);
+ char* __sav = NULL;
+ if (strcmp(__old, "C"))
+ {
+ const size_t __len = strlen(__old) + 1;
+ __sav = new char[__len];
+ memcpy(__sav, __old, __len);
+ setlocale(LC_CTYPE, "C");
+ }
+ if (__sav)
+ {
+ setlocale(LC_CTYPE, __sav);
+ delete [] __sav;
+ }
memset(_M_widen, 0, sizeof(_M_widen));
- _M_widen_ok = 0;
memset(_M_narrow, 0, sizeof(_M_narrow));
- _M_narrow_ok = 0;
}
char
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp
b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 30a4345b14f..200602d003e 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -904,6 +904,11 @@ proc check_v3_target_namedlocale { args } {
puts $f " strcpy(result, name);"
puts $f "#if defined __FreeBSD__ || defined __DragonFly__ || defined
__NetBSD__"
puts $f " /* fall-through */"
+ puts $f "#elif defined _AIX"
+ puts $f " char *p = strstr(result, \"ISO8859-15\");"
+ puts $f " if (p) {"
+ puts $f " strcpy(p, \"8859-15\");"
+ puts $f " }"
puts $f "#else"
puts $f " if (strstr(result, \"ISO8859-15\")) {"
puts $f " strcat(result, \"@euro\");"
diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h
b/libstdc++-v3/testsuite/util/testsuite_hooks.h
index b5e0767211a..a632f5f31f8 100644
--- a/libstdc++-v3/testsuite/util/testsuite_hooks.h
+++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h
@@ -77,6 +77,9 @@
#if defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__
# define ISO_8859(part,langTERR) #langTERR ".ISO8859-" #part
+#elif defined _AIX
+# define ISO_8859(part,langTERR) ((part) == 15 ?\
+ #langTERR ".8859-" #part : #langTERR ".ISO8859-" #part)
#else
# define ISO_8859(part,langTERR) ((part) == 15 ?\
#langTERR ".ISO8859-" #part "@euro" : #langTERR ".ISO8859-" #part)
--
2.25.0