From 3d18d5a27ca0c2e8b966c527ce568f64389d1975 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <clement.chigot@atos.net>
Date: Tue, 29 Dec 2020 11:08:33 +0100
Subject: [PATCH 1/2] libstdc++: implement locale support for XPG7
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Create a new locale model for POSIX operating systems.
The implementation is based on dragonfly one.

There are few known limitations.
std::messages isn't implemented.
Creation std::locale with a string describing each LC_* category
isn't possible (eg std::locale("LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;...")

TODO: fix ctype_configure_char.c

libstdc++-v3/ChangeLog:
2020-01-25  Clément Chigot  <clement.chigot@atos.net>

	* acinclude.m4: Add XPG7 model.
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* config/locale/dragonfly/c_locale.cc: Rename to ...
	* config/locale/xpg7/c_locale.cc: ... here.
	* config/locale/dragonfly/c_locale.h: Rename to ...
	* config/locale/xpg7/c_locale.h: ... here.
	(_GLIBCXX_C_LOCALE_XPG7): New define.
	(strtof_l): New function if not provided by the system.
	(strtod_l): Likewise.
	(strtold_l): Likewise.
	* config/locale/dragonfly/ctype_members.cc: Rename to ...
	* config/locale/xpg7/ctype_members.cc: ... here.
	* config/locale/dragonfly/monetary_members.cc: Rename to ...
	* config/locale/xpg7/monetary_members.cc: ... here.
	* config/locale/dragonfly/numeric_members.cc: Rename to ...
	* config/locale/xpg7/numeric_members.cc: ... here.
	* config/locale/dragonfly/time_members.cc: Rename to ...
	* config/locale/xpg7/time_members.cc: ... here.
	* config/os/aix/ctype_configure_char.cc (ctype<char>::ctype):
	Add support for XPG7 model.
	* config/os/gnu-linux/ctype_configure_char.cc: Likewise.
	* src/c++98/locale_init.cc (locale::global): Call setlocale
	for each category instead of once when not using gnu model.
	* testsuite/22_locale/codecvt/in/wchar_t/2.cc: Add xfail for
	wchar_t on 16bit.
	* testsuite/22_locale/codecvt/in/wchar_t/3.cc: Likewise.
	* testsuite/22_locale/codecvt/in/wchar_t/4.cc: Likewise.
	* testsuite/22_locale/codecvt/in/wchar_t/7.cc: Likewise.
	* testsuite/22_locale/codecvt/in/wchar_t/8.cc: Likewise.
	* testsuite/22_locale/codecvt/in/wchar_t/9.cc: Likewise.
	* testsuite/22_locale/codecvt/length/wchar_t/4.cc: Likewise.
	* testsuite/22_locale/codecvt/out/wchar_t/4.cc: Likewise.
	* testsuite/22_locale/codecvt/unshift/wchar_t/4.cc: Likewise.
	* testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-1.cc:
	Likewise.
	* testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-2.cc:
	Likewise.
	* testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-3.cc:
	Likewise.
	* testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-4.cc:
	Likewise.
	* testsuite/22_locale/ctype/is/wchar_t/2.cc: Remove xfail
	with xpg7 model.
	* testsuite/22_locale/locale/cons/29217.cc: Add skip when not
	using gnu model.
	* testsuite/22_locale/locale/cons/38368.cc: Likewise.
	* testsuite/22_locale/locale/cons/40184.cc: Likewise.
	* testsuite/22_locale/locale/cons/5.cc: Likewise.
	* testsuite/22_locale/locale/global_locale_objects/14071.cc:
	Likewise.
	* testsuite/22_locale/messages/13631.cc: Likewise.
	* testsuite/22_locale/messages/members/char/1.cc: Likewise.
	* testsuite/22_locale/messages/members/char/2.cc: Likewise.
	* testsuite/22_locale/messages/members/char/3.cc: Likewise.
	* testsuite/22_locale/messages/members/char/wrapped_env.cc:
	Likewise.
	* testsuite/22_locale/messages/members/char/wrapped_locale.cc:
	Likewise.
	* testsuite/22_locale/messages_byname/named_equivalence.cc:
	Likewise.
	* testsuite/lib/dg-options.exp (dg-require-localemodel): New.
	* testsuite/lib/libstdc++.exp (check_v3_target_namedlocale): Add
	AIX support.
	(check_v3_target_localemodel): New.
	* testsuite/util/testsuite_hooks.h (ISO_8859): Add AIX support.
---
 libstdc++-v3/acinclude.m4                     |  47 +-
 libstdc++-v3/config.h.in                      |  15 +
 .../config/locale/dragonfly/c_locale.cc       | 200 ----
 .../config/locale/dragonfly/c_locale.h        |  82 --
 .../locale/dragonfly/codecvt_members.cc       | 288 ------
 .../locale/dragonfly/collate_members.cc       |  74 --
 .../config/locale/dragonfly/ctype_members.cc  | 230 -----
 .../locale/dragonfly/monetary_members.cc      | 903 -----------------
 .../locale/dragonfly/numeric_members.cc       | 235 -----
 .../config/locale/dragonfly/time_members.cc   | 404 --------
 .../config/locale/dragonfly/time_members.h    |  95 --
 libstdc++-v3/config/locale/xpg7/c_locale.cc   | 204 ++++
 libstdc++-v3/config/locale/xpg7/c_locale.h    | 126 +++
 .../config/locale/xpg7/codecvt_members.cc     | 288 ++++++
 .../config/locale/xpg7/collate_members.cc     |  74 ++
 .../config/locale/xpg7/ctype_members.cc       | 287 ++++++
 .../config/locale/xpg7/monetary_members.cc    | 942 ++++++++++++++++++
 .../config/locale/xpg7/numeric_members.cc     | 261 +++++
 .../config/locale/xpg7/time_members.cc        | 434 ++++++++
 .../config/locale/xpg7/time_members.h         |  95 ++
 .../config/os/aix/ctype_configure_char.cc     |  71 +-
 .../os/gnu-linux/ctype_configure_char.cc      |   6 +-
 libstdc++-v3/src/c++98/locale_init.cc         |  12 +
 .../22_locale/codecvt/in/wchar_t/2.cc         |   1 +
 .../22_locale/codecvt/in/wchar_t/3.cc         |   1 +
 .../22_locale/codecvt/in/wchar_t/4.cc         |   1 +
 .../22_locale/codecvt/in/wchar_t/7.cc         |   1 +
 .../22_locale/codecvt/in/wchar_t/8.cc         |   1 +
 .../22_locale/codecvt/in/wchar_t/9.cc         |   1 +
 .../22_locale/codecvt/length/wchar_t/4.cc     |   1 +
 .../22_locale/codecvt/out/wchar_t/4.cc        |   1 +
 .../22_locale/codecvt/unshift/wchar_t/4.cc    |   1 +
 .../testsuite/22_locale/ctype/is/wchar_t/2.cc |   2 +-
 .../testsuite/22_locale/locale/cons/29217.cc  |   1 +
 .../testsuite/22_locale/locale/cons/38368.cc  |   1 +
 .../testsuite/22_locale/locale/cons/40184.cc  |   1 +
 .../testsuite/22_locale/locale/cons/5.cc      |   1 +
 .../locale/global_locale_objects/14071.cc     |   1 +
 .../testsuite/22_locale/messages/13631.cc     |   1 +
 .../22_locale/messages/members/char/1.cc      |   1 +
 .../22_locale/messages/members/char/2.cc      |   1 +
 .../22_locale/messages/members/char/3.cc      |   1 +
 .../messages/members/char/wrapped_env.cc      |   1 +
 .../messages/members/char/wrapped_locale.cc   |   1 +
 .../messages_byname/named_equivalence.cc      |   1 +
 .../basic_filebuf/overflow/wchar_t/11305-1.cc |   1 +
 .../basic_filebuf/overflow/wchar_t/11305-2.cc |   1 +
 .../basic_filebuf/overflow/wchar_t/11305-3.cc |   1 +
 .../basic_filebuf/overflow/wchar_t/11305-4.cc |   1 +
 libstdc++-v3/testsuite/lib/dg-options.exp     |   9 +
 libstdc++-v3/testsuite/lib/libstdc++.exp      |  31 +
 libstdc++-v3/testsuite/util/testsuite_hooks.h |   3 +
 52 files changed, 2900 insertions(+), 2543 deletions(-)
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/c_locale.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/c_locale.h
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/codecvt_members.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/collate_members.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/ctype_members.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/monetary_members.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/numeric_members.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/time_members.cc
 delete mode 100644 libstdc++-v3/config/locale/dragonfly/time_members.h
 create mode 100644 libstdc++-v3/config/locale/xpg7/c_locale.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/c_locale.h
 create mode 100644 libstdc++-v3/config/locale/xpg7/codecvt_members.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/collate_members.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/ctype_members.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/monetary_members.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/numeric_members.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/time_members.cc
 create mode 100644 libstdc++-v3/config/locale/xpg7/time_members.h

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 1c0a4c13052..bb165d18f00 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2388,7 +2388,7 @@
 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|newlib|xpg7|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
@@ -2418,8 +2418,8 @@
       vxworks*)
 	enable_clocale_flag=vxworks
 	;;
-      dragonfly* | freebsd*)
-	enable_clocale_flag=dragonfly
+      aix* | dragonfly* | freebsd*)
+	enable_clocale_flag=xpg7
 	;;
       openbsd*)
 	enable_clocale_flag=newlib
@@ -2528,22 +2528,6 @@
       CTIME_CC=config/locale/generic/time_members.cc
       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)
@@ -2595,6 +2579,24 @@
       CTIME_CC=config/locale/generic/time_members.cc
       CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
       ;;
+
+    xpg7)
+      AC_MSG_RESULT(xpg7)
+
+      CLOCALE_H=config/locale/xpg7/c_locale.h
+      CLOCALE_CC=config/locale/xpg7/c_locale.cc
+      CCODECVT_CC=config/locale/xpg7/codecvt_members.cc
+      CCOLLATE_CC=config/locale/xpg7/collate_members.cc
+      CCTYPE_CC=config/locale/xpg7/ctype_members.cc
+      CMESSAGES_H=config/locale/generic/messages_members.h
+      CMESSAGES_CC=config/locale/generic/messages_members.cc
+      CMONEY_CC=config/locale/xpg7/monetary_members.cc
+      CNUMERIC_CC=config/locale/xpg7/numeric_members.cc
+      CTIME_H=config/locale/xpg7/time_members.h
+      CTIME_CC=config/locale/xpg7/time_members.cc
+      CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
+      ;;
+
     newlib)
       AC_MSG_RESULT(newlib)

@@ -2641,6 +2643,12 @@
   AC_SUBST(CTIME_CC)
   AC_SUBST(CLOCALE_CC)
   AC_SUBST(CLOCALE_INTERNAL_H)
+
+  if test $enable_clocale_flag = xpg7; then
+     AC_CHECK_HEADERS(xlocale.h)
+
+     AC_CHECK_FUNCS([strtof_l localeconv_l mbstowcs_l wcsftime_l strftime_l])
+  fi
 ])


diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 37b56b82b0e..2598a2a7634 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -225,6 +225,9 @@
 /* Define to 1 if you have the <linux/types.h> header file. */
 #undef HAVE_LINUX_TYPES_H
 
+/* Define to 1 if you have the `localeconv_l' function. */
+#undef HAVE_LOCALECONV_L
+
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
@@ -249,6 +252,9 @@
 /* Define if mbstate_t exists in wchar.h. */
 #undef HAVE_MBSTATE_T
 
+/* Define to 1 if you have the `mbstowcs_l' function. */
+#undef HAVE_MBSTOWCS_L
+
 /* Define to 1 if you have the `memalign' function. */
 #undef HAVE_MEMALIGN
 
@@ -364,6 +370,9 @@
 /* Define if strerror_r is available in <string.h>. */
 #undef HAVE_STRERROR_R
 
+/* Define to 1 if you have the `strftime_l' function. */
+#undef HAVE_STRFTIME_L
+
 /* Define to 1 if you have the <strings.h> header file. */
 #undef HAVE_STRINGS_H
 
@@ -373,6 +382,9 @@
 /* Define to 1 if you have the `strtof' function. */
 #undef HAVE_STRTOF
 
+/* Define to 1 if you have the `strtof_l' function. */
+#undef HAVE_STRTOF_L
+
 /* Define to 1 if you have the `strtold' function. */
 #undef HAVE_STRTOLD
 
@@ -494,6 +506,9 @@
 /* Define to 1 if you have the <wchar.h> header file. */
 #undef HAVE_WCHAR_H
 
+/* Define to 1 if you have the `wcsftime_l' function. */
+#undef HAVE_WCSFTIME_L
+
 /* Defined if wcstof exists. */
 #undef HAVE_WCSTOF
 
--- ./libstdc++-v3/config/locale/dragonfly/c_locale.cc_orig 2023-06-03 11:33:19 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/c_locale.cc  2023-06-03 11:33:33 +0000
@@ -1,200 +0,0 @@
-// localization implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2014-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.8  Standard locale categories.
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <cstdlib>
-#include <locale>
-#include <stdexcept>
-#include <limits>
-#include <langinfo.h>
-#include <xlocale.h>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<>
-    void
-    __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
-		   const __c_locale& __cloc) throw()
-    {
-      char* __sanity;
-      __v = strtof_l(__s, &__sanity, (locale_t)__cloc);
-
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 23. Num_get overflow result.
-      if (__sanity == __s || *__sanity != '\0')
-	{
-	  __v = 0.0f;
-	  __err = ios_base::failbit;
-	}
-      else if (__v == numeric_limits<float>::infinity())
-	{
-	  __v = numeric_limits<float>::max();
-	  __err = ios_base::failbit;
-	}
-      else if (__v == -numeric_limits<float>::infinity())
-	{
-	  __v = -numeric_limits<float>::max();
-	  __err = ios_base::failbit;
-	}
-    }
-
-  template<>
-    void
-    __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
-		   const __c_locale& __cloc) throw()
-    {
-      char* __sanity;
-      __v = strtod_l(__s, &__sanity, (locale_t)__cloc);
-
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 23. Num_get overflow result.
-      if (__sanity == __s || *__sanity != '\0')
-	{
-	  __v = 0.0;
-	  __err = ios_base::failbit;
-	}
-      else if (__v == numeric_limits<double>::infinity())
-	{
-	  __v = numeric_limits<double>::max();
-	  __err = ios_base::failbit;
-	}
-      else if (__v == -numeric_limits<double>::infinity())
-	{
-	  __v = -numeric_limits<double>::max();
-	  __err = ios_base::failbit;
-	}
-    }
-
-  template<>
-    void
-    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
-		   const __c_locale& __cloc) throw()
-    {
-      char* __sanity;
-      __v = strtold_l(__s, &__sanity, (locale_t)__cloc);
-
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 23. Num_get overflow result.
-      if (__sanity == __s || *__sanity != '\0')
-	{
-	  __v = 0.0l;
-	  __err = ios_base::failbit;
-	}
-      else if (__v == numeric_limits<long double>::infinity())
-	{
-	  __v = numeric_limits<long double>::max();
-	  __err = ios_base::failbit;
-	}
-      else if (__v == -numeric_limits<long double>::infinity())
-	{
-	  __v = -numeric_limits<long double>::max();
-	  __err = ios_base::failbit;
-	}
-    }
-
-  void
-  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
-				    __c_locale __old)
-  {
-    __cloc = (__c_locale)newlocale(LC_ALL_MASK, __s, (locale_t)__old);
-    if (!__cloc)
-      {
-	// This named locale is not supported by the underlying OS.
-	__throw_runtime_error(__N("locale::facet::_S_create_c_locale "
-				  "name not valid"));
-      }
-  }
-
-  void
-  locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
-  {
-    if (__cloc && _S_get_c_locale() != __cloc)
-      freelocale((locale_t)__cloc);
-  }
-
-  __c_locale
-  locale::facet::_S_clone_c_locale(__c_locale& __cloc) throw()
-  { return (__c_locale)duplocale((locale_t)__cloc); }
-
-  __c_locale
-  locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s)
-  {
-    __c_locale __dup = (__c_locale)duplocale((locale_t)__cloc);
-    if (__dup == __c_locale(0))
-      __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
-				"duplocale error"));
-    __c_locale __changed = (__c_locale)newlocale(LC_CTYPE_MASK, __s,
-						 (locale_t)__dup);
-    if (__changed == __c_locale(0))
-      {
-	freelocale((locale_t)__dup);
-	__throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
-				  "newlocale error"));
-      }
-    return __changed;
-  }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
-    {
-      "LC_CTYPE",
-      "LC_NUMERIC",
-      "LC_TIME",
-      "LC_COLLATE",
-      "LC_MONETARY",
-      "LC_MESSAGES"
-    };
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  const char* const* const locale::_S_categories = __gnu_cxx::category_names;
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-// XXX GLIBCXX_ABI Deprecated
-#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
-  extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
-_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct);
-#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
--- ./libstdc++-v3/config/locale/dragonfly/c_locale.h_orig	2023-06-03 11:48:50 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/c_locale.h	2023-06-03 11:48:56 +0000
@@ -1,82 +0,0 @@
-// localization implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2001-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-/** @file bits/c++locale.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{locale}
- */
-
-//
-// ISO C++ 14882: 22.8  Standard locale categories.
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#ifndef _GLIBCXX_CXX_LOCALE_H
-#define _GLIBCXX_CXX_LOCALE_H 1
-
-#pragma GCC system_header
-
-#include <clocale>
-#include <xlocale.h>
-
-#define _GLIBCXX_NUM_CATEGORIES 0
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  typedef int*			__c_locale;
-
-  // Convert numeric value of type double and long double to string and
-  // return length of string.  If vsnprintf is available use it, otherwise
-  // fall back to the unsafe vsprintf which, in general, can be dangerous
-  // and should be avoided.
-  inline int
-  __convert_from_v(const __c_locale& __cloc, char* __out,
-		   const int __size __attribute__ ((__unused__)),
-		   const char* __fmt, ...)
-  {
-    __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
-
-    __builtin_va_list __args;
-    __builtin_va_start(__args, __fmt);
-
-#if _GLIBCXX_USE_C99_STDIO
-    const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
-#else
-    const int __ret = __builtin_vsprintf(__out, __fmt, __args);
-#endif
-
-    __builtin_va_end(__args);
-
-    uselocale((locale_t)__old);
-    return __ret;
-  }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-#endif
--- ./libstdc++-v3/config/locale/dragonfly/codecvt_members.cc_orig	2023-06-03 11:52:51 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/codecvt_members.cc	2023-06-03 11:53:06 +0000
@@ -1,288 +0,0 @@
-// std::codecvt implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2015-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.2.1.5 - Template class codecvt
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <locale>
-#include <cstring>
-#include <cstdlib>  // For MB_CUR_MAX
-#include <climits>  // For MB_LEN_MAX
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  // Specializations.
-#ifdef _GLIBCXX_USE_WCHAR_T
-  codecvt_base::result
-  codecvt<wchar_t, char, mbstate_t>::
-  do_out(state_type& __state, const intern_type* __from,
-	 const intern_type* __from_end, const intern_type*& __from_next,
-	 extern_type* __to, extern_type* __to_end,
-	 extern_type*& __to_next) const
-  {
-    result __ret = ok;
-    state_type __tmp_state(__state);
-
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
-
-    // wcsnrtombs is *very* fast but stops if encounters NUL characters:
-    // in case we fall back to wcrtomb and then continue, in a loop.
-    // NB: wcsnrtombs is a GNU extension
-    for (__from_next = __from, __to_next = __to;
-	 __from_next < __from_end && __to_next < __to_end
-	 && __ret == ok;)
-      {
-	const intern_type* __from_chunk_end = wmemchr(__from_next, L'\0',
-						      __from_end - __from_next);
-	if (!__from_chunk_end)
-	  __from_chunk_end = __from_end;
-
-	__from = __from_next;
-	const size_t __conv = wcsnrtombs(__to_next, &__from_next,
-					 __from_chunk_end - __from_next,
-					 __to_end - __to_next, &__state);
-	if (__conv == static_cast<size_t>(-1))
-	  {
-	    // In case of error, in order to stop at the exact place we
-	    // have to start again from the beginning with a series of
-	    // wcrtomb.
-	    for (; __from < __from_next; ++__from)
-	      __to_next += wcrtomb(__to_next, *__from, &__tmp_state);
-	    __state = __tmp_state;
-	    __ret = error;
-	  }
-	else if (__from_next && __from_next < __from_chunk_end)
-	  {
-	    __to_next += __conv;
-	    __ret = partial;
-	  }
-	else
-	  {
-	    __from_next = __from_chunk_end;
-	    __to_next += __conv;
-	  }
-
-	if (__from_next < __from_end && __ret == ok)
-	  {
-	    extern_type __buf[MB_LEN_MAX];
-	    __tmp_state = __state;
-	    const size_t __conv2 = wcrtomb(__buf, *__from_next, &__tmp_state);
-	    if (__conv2 > static_cast<size_t>(__to_end - __to_next))
-	      __ret = partial;
-	    else
-	      {
-		memcpy(__to_next, __buf, __conv2);
-		__state = __tmp_state;
-		__to_next += __conv2;
-		++__from_next;
-	      }
-	  }
-      }
-
-    uselocale((locale_t)__old);
-
-    return __ret;
-  }
-
-  codecvt_base::result
-  codecvt<wchar_t, char, mbstate_t>::
-  do_in(state_type& __state, const extern_type* __from,
-	const extern_type* __from_end, const extern_type*& __from_next,
-	intern_type* __to, intern_type* __to_end,
-	intern_type*& __to_next) const
-  {
-    result __ret = ok;
-    state_type __tmp_state(__state);
-
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
-
-    // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
-    // in case we store a L'\0' and then continue, in a loop.
-    // NB: mbsnrtowcs is a GNU extension
-    for (__from_next = __from, __to_next = __to;
-	 __from_next < __from_end && __to_next < __to_end
-	 && __ret == ok;)
-      {
-	const extern_type* __from_chunk_end;
-	__from_chunk_end = static_cast<const extern_type*>(memchr(__from_next, '\0',
-								  __from_end
-								  - __from_next));
-	if (!__from_chunk_end)
-	  __from_chunk_end = __from_end;
-
-	__from = __from_next;
-	size_t __conv = mbsnrtowcs(__to_next, &__from_next,
-				   __from_chunk_end - __from_next,
-				   __to_end - __to_next, &__state);
-	if (__conv == static_cast<size_t>(-1))
-	  {
-	    // In case of error, in order to stop at the exact place we
-	    // have to start again from the beginning with a series of
-	    // mbrtowc.
-	    for (;; ++__to_next, __from += __conv)
-	      {
-		__conv = mbrtowc(__to_next, __from, __from_end - __from,
-				 &__tmp_state);
-		if (__conv == static_cast<size_t>(-1)
-		    || __conv == static_cast<size_t>(-2))
-		  break;
-	      }
-	    __from_next = __from;
-	    __state = __tmp_state;
-	    __ret = error;
-	  }
-	else if (__from_next && __from_next < __from_chunk_end)
-	  {
-	    // It is unclear what to return in this case (see DR 382).
-	    __to_next += __conv;
-	    __ret = partial;
-	  }
-	else
-	  {
-	    __from_next = __from_chunk_end;
-	    __to_next += __conv;
-	  }
-
-	if (__from_next < __from_end && __ret == ok)
-	  {
-	    if (__to_next < __to_end)
-	      {
-		// XXX Probably wrong for stateful encodings
-		__tmp_state = __state;
-		++__from_next;
-		*__to_next++ = L'\0';
-	      }
-	    else
-	      __ret = partial;
-	  }
-      }
-
-    uselocale((locale_t)__old);
-
-    return __ret;
-  }
-
-  int
-  codecvt<wchar_t, char, mbstate_t>::
-  do_encoding() const throw()
-  {
-    // XXX This implementation assumes that the encoding is
-    // stateless and is either single-byte or variable-width.
-    int __ret = 0;
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
-    if (MB_CUR_MAX == 1)
-      __ret = 1;
-    uselocale((locale_t)__old);
-    return __ret;
-  }
-
-  int
-  codecvt<wchar_t, char, mbstate_t>::
-  do_max_length() const throw()
-  {
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
-    // XXX Probably wrong for stateful encodings.
-    int __ret = MB_CUR_MAX;
-    uselocale((locale_t)__old);
-    return __ret;
-  }
-
-  int
-  codecvt<wchar_t, char, mbstate_t>::
-  do_length(state_type& __state, const extern_type* __from,
-	    const extern_type* __end, size_t __max) const
-  {
-    int __ret = 0;
-    state_type __tmp_state(__state);
-
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
-
-    // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
-    // in case we advance past it and then continue, in a loop.
-    // NB: mbsnrtowcs is a GNU extension
-
-    // A dummy internal buffer is needed in order for mbsnrtocws to consider
-    // its fourth parameter (it wouldn't with NULL as first parameter).
-    wchar_t* __to = static_cast<wchar_t*>(__builtin_alloca(sizeof(wchar_t)
-							   * __max));
-    while (__from < __end && __max)
-      {
-	const extern_type* __from_chunk_end;
-	__from_chunk_end = static_cast<const extern_type*>(memchr(__from, '\0',
-								  __end
-								  - __from));
-	if (!__from_chunk_end)
-	  __from_chunk_end = __end;
-
-	const extern_type* __tmp_from = __from;
-	size_t __conv = mbsnrtowcs(__to, &__from,
-				   __from_chunk_end - __from,
-				   __max, &__state);
-	if (__conv == static_cast<size_t>(-1))
-	  {
-	    // In case of error, in order to stop at the exact place we
-	    // have to start again from the beginning with a series of
-	    // mbrtowc.
-	    for (__from = __tmp_from;; __from += __conv)
-	      {
-		__conv = mbrtowc(0, __from, __end - __from,
-				 &__tmp_state);
-		if (__conv == static_cast<size_t>(-1)
-		    || __conv == static_cast<size_t>(-2))
-		  break;
-	      }
-	    __state = __tmp_state;
-	    __ret += __from - __tmp_from;
-	    break;
-	  }
-	if (!__from)
-	  __from = __from_chunk_end;
-
-	__ret += __from - __tmp_from;
-	__max -= __conv;
-
-	if (__from < __end && __max)
-	  {
-	    // XXX Probably wrong for stateful encodings
-	    __tmp_state = __state;
-	    ++__from;
-	    ++__ret;
-	    --__max;
-	  }
-      }
-
-    uselocale((locale_t)__old);
-
-    return __ret;
-  }
-#endif
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
--- ./libstdc++-v3/config/locale/dragonfly/collate_members.cc_orig	2023-06-03 11:56:57 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/collate_members.cc	2023-06-03 11:57:02 +0000
@@ -1,74 +0,0 @@
-// std::collate implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2015-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.2.4.1.2  collate virtual functions
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <locale>
-#include <cstring>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  // These are basically extensions to char_traits, and perhaps should
-  // be put there instead of here.
-  template<>
-    int
-    collate<char>::_M_compare(const char* __one,
-			      const char* __two) const throw()
-    {
-      int __cmp = strcoll_l(__one, __two, (locale_t)_M_c_locale_collate);
-      return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
-    }
-
-  template<>
-    size_t
-    collate<char>::_M_transform(char* __to, const char* __from,
-				size_t __n) const throw()
-    { return strxfrm_l(__to, __from, __n, (locale_t)_M_c_locale_collate); }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    int
-    collate<wchar_t>::_M_compare(const wchar_t* __one,
-				 const wchar_t* __two) const throw()
-    {
-      int __cmp = wcscoll_l(__one, __two, (locale_t)_M_c_locale_collate);
-      return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
-    }
-
-  template<>
-    size_t
-    collate<wchar_t>::_M_transform(wchar_t* __to, const wchar_t* __from,
-				   size_t __n) const throw()
-    { return wcsxfrm_l(__to, __from, __n, (locale_t)_M_c_locale_collate); }
-#endif
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
--- ./libstdc++-v3/config/locale/dragonfly/ctype_members.cc_orig	2023-06-03 11:59:18 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/ctype_members.cc	2023-06-03 12:01:54 +0000
@@ -1,230 +0,0 @@
-// std::ctype implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2014-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.2.1.1.2  ctype virtual functions.
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <locale>
-#include <cstring>
-#include <cstdio>
-
-#ifndef _ISbit
-#define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
-#endif
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  // NB: The other ctype<char> specializations are in src/locale.cc and
-  // various /config/os/* files.
-  ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
-  : ctype<char>(0, false, __refs)
-  {
-    if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
-      {
-	this->_S_destroy_c_locale(this->_M_c_locale_ctype);
-	this->_S_create_c_locale(this->_M_c_locale_ctype, __s);
-      }
-  }
-
-  ctype_byname<char>::~ctype_byname()
-  { }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  ctype<wchar_t>::__wmask_type
-  ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw()
-  {
-    __wmask_type __ret;
-    switch (__m)
-      {
-      case space:
-	__ret = wctype_l("space", (locale_t)_M_c_locale_ctype);
-	break;
-      case print:
-	__ret = wctype_l("print", (locale_t)_M_c_locale_ctype);
-	break;
-      case cntrl:
-	__ret = wctype_l("cntrl", (locale_t)_M_c_locale_ctype);
-	break;
-      case upper:
-	__ret = wctype_l("upper", (locale_t)_M_c_locale_ctype);
-	break;
-      case lower:
-	__ret = wctype_l("lower", (locale_t)_M_c_locale_ctype);
-	break;
-      case alpha:
-	__ret = wctype_l("alpha", (locale_t)_M_c_locale_ctype);
-	break;
-      case digit:
-	__ret = wctype_l("digit", (locale_t)_M_c_locale_ctype);
-	break;
-      case punct:
-	__ret = wctype_l("punct", (locale_t)_M_c_locale_ctype);
-	break;
-      case xdigit:
-	__ret = wctype_l("xdigit", (locale_t)_M_c_locale_ctype);
-	break;
-      case alnum:
-	__ret = wctype_l("alnum", (locale_t)_M_c_locale_ctype);
-	break;
-      case graph:
-	__ret = wctype_l("graph", (locale_t)_M_c_locale_ctype);
-	break;
-      case blank:
-	__ret = wctype_l("blank", (locale_t)_M_c_locale_ctype);
-	break;
-      default:
-	__ret = __wmask_type();
-      }
-    return __ret;
-  }
-
-  wchar_t
-  ctype<wchar_t>::do_toupper(wchar_t __c) const
-  { return towupper_l(__c, (locale_t)_M_c_locale_ctype); }
-
-  const wchar_t*
-  ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
-  {
-    while (__lo < __hi)
-      {
-        *__lo = towupper_l(*__lo, (locale_t)_M_c_locale_ctype);
-        ++__lo;
-      }
-    return __hi;
-  }
-
-  wchar_t
-  ctype<wchar_t>::do_tolower(wchar_t __c) const
-  { return towlower_l(__c, (locale_t)_M_c_locale_ctype); }
-
-  const wchar_t*
-  ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
-  {
-    while (__lo < __hi)
-      {
-        *__lo = towlower_l(*__lo, (locale_t)_M_c_locale_ctype);
-        ++__lo;
-      }
-    return __hi;
-  }
-
-  wchar_t
-  ctype<wchar_t>::
-  do_widen(char __c) const
-  { return _M_widen[static_cast<unsigned char>(__c)]; }
-
-  const char*
-  ctype<wchar_t>::
-  do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
-  {
-    while (__lo < __hi)
-      {
-	*__dest = _M_widen[static_cast<unsigned char>(*__lo)];
-	++__lo;
-	++__dest;
-      }
-    return __hi;
-  }
-
-  char
-  ctype<wchar_t>::
-  do_narrow(wchar_t __wc, char __dfault) const
-  {
-    if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
-      return _M_narrow[__wc];
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_ctype);
-    const int __c = wctob(__wc);
-    uselocale((locale_t)__old);
-    return (__c == EOF ? __dfault : static_cast<char>(__c));
-  }
-
-  const wchar_t*
-  ctype<wchar_t>::
-  do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
-	    char* __dest) const
-  {
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_ctype);
-    if (_M_narrow_ok)
-      while (__lo < __hi)
-	{
-	  if (*__lo >= 0 && *__lo < 128)
-	    *__dest = _M_narrow[*__lo];
-	  else
-	    {
-	      const int __c = wctob(*__lo);
-	      *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
-	    }
-	  ++__lo;
-	  ++__dest;
-	}
-    else
-      while (__lo < __hi)
-	{
-	  const int __c = wctob(*__lo);
-	  *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
-	  ++__lo;
-	  ++__dest;
-	}
-    uselocale((locale_t)__old);
-    return __hi;
-  }
-
-  void
-  ctype<wchar_t>::_M_initialize_ctype() throw()
-  {
-    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_ctype);
-    wint_t __i;
-    for (__i = 0; __i < 128; ++__i)
-      {
-	const int __c = wctob(__i);
-	if (__c == EOF)
-	  break;
-	else
-	  _M_narrow[__i] = static_cast<char>(__c);
-      }
-    if (__i == 128)
-      _M_narrow_ok = true;
-    else
-      _M_narrow_ok = false;
-    for (size_t __j = 0;
-	 __j < sizeof(_M_widen) / sizeof(wint_t); ++__j)
-      _M_widen[__j] = btowc(__j);
-
-    for (size_t __k = 0; __k <= 11; ++__k)
-      {
-	_M_bit[__k] = static_cast<mask>(_ISbit(__k));
-	_M_wmask[__k] = _M_convert_to_wmask(_M_bit[__k]);
-      }
-    uselocale((locale_t)__old);
-  }
-#endif //  _GLIBCXX_USE_WCHAR_T
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
--- ./libstdc++-v3/config/locale/dragonfly/monetary_members.cc_orig	2023-06-03 12:04:42 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/monetary_members.cc	2023-06-03 12:04:51 +0000
@@ -1,903 +0,0 @@
-// std::moneypunct implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2015-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.2.6.3.2  moneypunct virtual functions
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <locale>
-#include <cstring>
-#include <xlocale.h>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-// This file might be compiled twice, but we only want to define the members
-// of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
-
-  // Construct and return valid pattern consisting of some combination of:
-  // space none symbol sign value
-  money_base::pattern
-  money_base::_S_construct_pattern(char __precedes, char __space,
-				   char __posn) throw()
-  {
-    pattern __ret;
-
-    // This insanely complicated routine attempts to construct a valid
-    // pattern for use with moneypunct. A couple of invariants:
-
-    // if (__precedes) symbol -> value
-    // else value -> symbol
-
-    // if (__space) space
-    // else none
-
-    // none == never first
-    // space never first or last
-
-    // Any elegant implementations of this are welcome.
-    switch (__posn)
-      {
-      case 0:
-      case 1:
-	// 1 The sign precedes the value and symbol.
-	__ret.field[0] = sign;
-	if (__space)
-	  {
-	    // Pattern starts with sign.
-	    if (__precedes)
-	      {
-		__ret.field[1] = symbol;
-		__ret.field[3] = value;
-	      }
-	    else
-	      {
-		__ret.field[1] = value;
-		__ret.field[3] = symbol;
-	      }
-	    __ret.field[2] = space;
-	  }
-	else
-	  {
-	    // Pattern starts with sign and ends with none.
-	    if (__precedes)
-	      {
-		__ret.field[1] = symbol;
-		__ret.field[2] = value;
-	      }
-	    else
-	      {
-		__ret.field[1] = value;
-		__ret.field[2] = symbol;
-	      }
-	    __ret.field[3] = none;
-	  }
-	break;
-      case 2:
-	// 2 The sign follows the value and symbol.
-	if (__space)
-	  {
-	    // Pattern either ends with sign.
-	    if (__precedes)
-	      {
-		__ret.field[0] = symbol;
-		__ret.field[2] = value;
-	      }
-	    else
-	      {
-		__ret.field[0] = value;
-		__ret.field[2] = symbol;
-	      }
-	    __ret.field[1] = space;
-	    __ret.field[3] = sign;
-	  }
-	else
-	  {
-	    // Pattern ends with sign then none.
-	    if (__precedes)
-	      {
-		__ret.field[0] = symbol;
-		__ret.field[1] = value;
-	      }
-	    else
-	      {
-		__ret.field[0] = value;
-		__ret.field[1] = symbol;
-	      }
-	    __ret.field[2] = sign;
-	    __ret.field[3] = none;
-	  }
-	break;
-      case 3:
-	// 3 The sign immediately precedes the symbol.
-	if (__precedes)
-	  {
-	    __ret.field[0] = sign;
-	    __ret.field[1] = symbol;
-	    if (__space)
-	      {
-		__ret.field[2] = space;
-		__ret.field[3] = value;
-	      }
-	    else
-	      {
-		__ret.field[2] = value;
-		__ret.field[3] = none;
-	      }
-	  }
-	else
-	  {
-	    __ret.field[0] = value;
-	    if (__space)
-	      {
-		__ret.field[1] = space;
-		__ret.field[2] = sign;
-		__ret.field[3] = symbol;
-	      }
-	    else
-	      {
-		__ret.field[1] = sign;
-		__ret.field[2] = symbol;
-		__ret.field[3] = none;
-	      }
-	  }
-	break;
-      case 4:
-	// 4 The sign immediately follows the symbol.
-	if (__precedes)
-	  {
-	    __ret.field[0] = symbol;
-	    __ret.field[1] = sign;
-	    if (__space)
-	      {
-		__ret.field[2] = space;
-		__ret.field[3] = value;
-	      }
-	    else
-	      {
-		__ret.field[2] = value;
-		__ret.field[3] = none;
-	      }
-	  }
-	else
-	  {
-	    __ret.field[0] = value;
-	    if (__space)
-	      {
-		__ret.field[1] = space;
-		__ret.field[2] = symbol;
-		__ret.field[3] = sign;
-	      }
-	    else
-	      {
-		__ret.field[1] = symbol;
-		__ret.field[2] = sign;
-		__ret.field[3] = none;
-	      }
-	  }
-	break;
-      default:
-	__ret = pattern();
-      }
-    return __ret;
-  }
-#endif
-
-  template<>
-    void
-    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
-						     const char*)
-    {
-      if (!_M_data)
-	_M_data = new __moneypunct_cache<char, true>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_data->_M_decimal_point = '.';
-	  _M_data->_M_thousands_sep = ',';
-	  _M_data->_M_grouping = "";
-	  _M_data->_M_grouping_size = 0;
-	  _M_data->_M_use_grouping = false;
-	  _M_data->_M_curr_symbol = "";
-	  _M_data->_M_curr_symbol_size = 0;
-	  _M_data->_M_positive_sign = "";
-	  _M_data->_M_positive_sign_size = 0;
-	  _M_data->_M_negative_sign = "";
-	  _M_data->_M_negative_sign_size = 0;
-	  _M_data->_M_frac_digits = 0;
-	  _M_data->_M_pos_format = money_base::_S_default_pattern;
-	  _M_data->_M_neg_format = money_base::_S_default_pattern;
-
-	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
-	    _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
-	}
-      else
-	{
-	  // Named locale.
-	  lconv* lc = localeconv_l((locale_t) __cloc);
-
-	  // Check for NULL, which implies no fractional digits.
-	  if (lc->mon_decimal_point == NULL ||
-	      lc->mon_decimal_point[0] == '\0')
-	    {
-	      // Like in "C" locale.
-	      _M_data->_M_frac_digits = 0;
-	      _M_data->_M_decimal_point = '.';
-	    }
-	  else
-	    {
-	      _M_data->_M_decimal_point = lc->mon_decimal_point[0];
-	      _M_data->_M_frac_digits = lc->int_frac_digits;
-	    }
-
-	  const char* __cgroup = lc->mon_grouping;
-	  const char* __cpossign = lc->positive_sign;
-	  const char* __cnegsign = lc->negative_sign;
-	  // _Intl == true
-	  const char* __ccurr = lc->int_curr_symbol;
-
-	  char* __group = 0;
-	  char* __ps = 0;
-	  char* __ns = 0;
-	  const char __nposn = lc->int_n_sign_posn;
-	  __try
-	    {
-	      size_t __len;
-
-	      // Check for NULL, which implies no grouping.
-	      if (lc->mon_thousands_sep == NULL ||
-	          lc->mon_thousands_sep[0] == '\0')
-		{
-		  // Like in "C" locale.
-		  _M_data->_M_grouping = "";
-		  _M_data->_M_grouping_size = 0;
-		  _M_data->_M_use_grouping = false;
-		  _M_data->_M_thousands_sep = ',';
-		}
-	      else
-		{
-	          _M_data->_M_thousands_sep = lc->mon_thousands_sep[0];
-
-		  __len = strlen(__cgroup);
-		  if (__len)
-		    {
-		      __group = new char[__len + 1];
-		      memcpy(__group, __cgroup, __len + 1);
-		      _M_data->_M_grouping = __group;
-		    }
-		  else
-		    {
-		      _M_data->_M_grouping = "";
-		      _M_data->_M_use_grouping = false;
-		    }
-		  _M_data->_M_grouping_size = __len;
-		}
-
-	      __len = strlen(__cpossign);
-	      if (__len)
-		{
-		  __ps = new char[__len + 1];
-		  memcpy(__ps, __cpossign, __len + 1);
-		  _M_data->_M_positive_sign = __ps;
-		}
-	      else
-		_M_data->_M_positive_sign = "";
-	      _M_data->_M_positive_sign_size = __len;
-
-	      if (!__nposn)
-		{
-		  _M_data->_M_negative_sign = "()";
-		  _M_data->_M_negative_sign_size = 2;
-		}
-	      else
-		{
-		  __len = strlen(__cnegsign);
-		  if (__len)
-		    {
-		      __ns = new char[__len + 1];
-		      memcpy(__ns, __cnegsign, __len + 1);
-		      _M_data->_M_negative_sign = __ns;
-		    }
-		  else
-		    _M_data->_M_negative_sign = "";
-		  _M_data->_M_negative_sign_size = __len;
-		}
-
-	      __len = strlen(__ccurr);
-	      if (__len)
-		{
-		  char* __curr = new char[__len + 1];
-		  memcpy(__curr, __ccurr, __len + 1);
-		  _M_data->_M_curr_symbol = __curr;
-		}
-	      else
-		_M_data->_M_curr_symbol = "";
-	      _M_data->_M_curr_symbol_size = __len;
-	    }
-	  __catch(...)
-	    {
-	      delete _M_data;
-	      _M_data = 0;
-	      delete [] __group;
-	      delete [] __ps;
-	      delete [] __ns;
-	      __throw_exception_again;
-	    }
-
-	  char __pprecedes = lc->int_p_cs_precedes;
-	  char __pspace = lc->int_p_sep_by_space;
-	  char __pposn = lc->int_p_sign_posn;
-	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
-							__pposn);
-	  char __nprecedes = lc->int_n_cs_precedes;
-	  char __nspace = lc->int_n_sep_by_space;
-	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
-							__nposn);
-	}
-    }
-
-  template<>
-    void
-    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
-						      const char*)
-    {
-      if (!_M_data)
-	_M_data = new __moneypunct_cache<char, false>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_data->_M_decimal_point = '.';
-	  _M_data->_M_thousands_sep = ',';
-	  _M_data->_M_grouping = "";
-	  _M_data->_M_grouping_size = 0;
-	  _M_data->_M_use_grouping = false;
-	  _M_data->_M_curr_symbol = "";
-	  _M_data->_M_curr_symbol_size = 0;
-	  _M_data->_M_positive_sign = "";
-	  _M_data->_M_positive_sign_size = 0;
-	  _M_data->_M_negative_sign = "";
-	  _M_data->_M_negative_sign_size = 0;
-	  _M_data->_M_frac_digits = 0;
-	  _M_data->_M_pos_format = money_base::_S_default_pattern;
-	  _M_data->_M_neg_format = money_base::_S_default_pattern;
-
-	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
-	    _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
-	}
-      else
-	{
-	  // Named locale.
-	  lconv* lc = localeconv_l((locale_t) __cloc);
-
-	  // Check for NULL, which implies no fractional digits.
-	  if (lc->mon_decimal_point == NULL ||
-	      lc->mon_decimal_point[0] == '\0')
-	    {
-	      // Like in "C" locale.
-	      _M_data->_M_frac_digits = 0;
-	      _M_data->_M_decimal_point = '.';
-	    }
-	  else
-	    {
-	      _M_data->_M_decimal_point = lc->mon_decimal_point[0];
-	      _M_data->_M_frac_digits = lc->frac_digits;
-            }
-
-	  const char* __cgroup = lc->mon_grouping;
-	  const char* __cpossign = lc->positive_sign;
-	  const char* __cnegsign = lc->negative_sign;
-	  // _Intl == false
-	  const char* __ccurr = lc->currency_symbol;
-
-	  char* __group = 0;
-	  char* __ps = 0;
-	  char* __ns = 0;
-	  const char __nposn = lc->n_sign_posn;
-	  __try
-	    {
-	      size_t __len;
-
-	      // Check for NULL, which implies no grouping.
-	      if (lc->mon_thousands_sep == NULL ||
-	          lc->mon_thousands_sep[0] == '\0')
-		{
-		  // Like in "C" locale.
-		  _M_data->_M_grouping = "";
-		  _M_data->_M_grouping_size = 0;
-		  _M_data->_M_use_grouping = false;
-		  _M_data->_M_thousands_sep = ',';
-		}
-	      else
-		{
-	          _M_data->_M_thousands_sep = lc->mon_thousands_sep[0];
-
-		  __len = strlen(__cgroup);
-		  if (__len)
-		    {
-		      __group = new char[__len + 1];
-		      memcpy(__group, __cgroup, __len + 1);
-		      _M_data->_M_grouping = __group;
-		    }
-		  else
-		    {
-		      _M_data->_M_grouping = "";
-		      _M_data->_M_use_grouping = false;
-		    }
-		  _M_data->_M_grouping_size = __len;
-		}
-
-	      __len = strlen(__cpossign);
-	      if (__len)
-		{
-		  __ps = new char[__len + 1];
-		  memcpy(__ps, __cpossign, __len + 1);
-		  _M_data->_M_positive_sign = __ps;
-		}
-	      else
-		_M_data->_M_positive_sign = "";
-	      _M_data->_M_positive_sign_size = __len;
-
-	      if (!__nposn)
-		{
-		  _M_data->_M_negative_sign = "()";
-		  _M_data->_M_negative_sign_size = 2;
-		}
-	      else
-		{
-		  __len = strlen(__cnegsign);
-		  if (__len)
-		    {
-		      __ns = new char[__len + 1];
-		      memcpy(__ns, __cnegsign, __len + 1);
-		      _M_data->_M_negative_sign = __ns;
-		    }
-		  else
-		    _M_data->_M_negative_sign = "";
-		  _M_data->_M_negative_sign_size = __len;
-		}
-
-	      __len = strlen(__ccurr);
-	      if (__len)
-		{
-		  char* __curr = new char[__len + 1];
-		  memcpy(__curr, __ccurr, __len + 1);
-		  _M_data->_M_curr_symbol = __curr;
-		}
-	      else
-		_M_data->_M_curr_symbol = "";
-	      _M_data->_M_curr_symbol_size = __len;
-	    }
-	  __catch(...)
-	    {
-	      delete _M_data;
-	      _M_data = 0;
-	      delete [] __group;
-	      delete [] __ps;
-	      delete [] __ns;
-	      __throw_exception_again;
-	    }
-
-	  char __pprecedes = lc->p_cs_precedes;
-	  char __pspace = lc->p_sep_by_space;
-	  char __pposn = lc->p_sign_posn;
-	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
-							__pposn);
-	  char __nprecedes = lc->n_cs_precedes;
-	  char __nspace = lc->n_sep_by_space;
-	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
-							__nposn);
-	}
-    }
-
-  template<>
-    moneypunct<char, true>::~moneypunct()
-    {
-      if (_M_data->_M_grouping_size)
-	delete [] _M_data->_M_grouping;
-      if (_M_data->_M_positive_sign_size)
-	delete [] _M_data->_M_positive_sign;
-      if (_M_data->_M_negative_sign_size
-          && strcmp(_M_data->_M_negative_sign, "()") != 0)
-	delete [] _M_data->_M_negative_sign;
-      if (_M_data->_M_curr_symbol_size)
-	delete [] _M_data->_M_curr_symbol;
-      delete _M_data;
-    }
-
-  template<>
-    moneypunct<char, false>::~moneypunct()
-    {
-      if (_M_data->_M_grouping_size)
-	delete [] _M_data->_M_grouping;
-      if (_M_data->_M_positive_sign_size)
-	delete [] _M_data->_M_positive_sign;
-      if (_M_data->_M_negative_sign_size
-          && strcmp(_M_data->_M_negative_sign, "()") != 0)
-	delete [] _M_data->_M_negative_sign;
-      if (_M_data->_M_curr_symbol_size)
-	delete [] _M_data->_M_curr_symbol;
-      delete _M_data;
-    }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    void
-    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
-							const char*)
-    {
-      if (!_M_data)
-	_M_data = new __moneypunct_cache<wchar_t, true>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_data->_M_decimal_point = L'.';
-	  _M_data->_M_thousands_sep = L',';
-	  _M_data->_M_grouping = "";
-	  _M_data->_M_grouping_size = 0;
-	  _M_data->_M_use_grouping = false;
-	  _M_data->_M_curr_symbol = L"";
-	  _M_data->_M_curr_symbol_size = 0;
-	  _M_data->_M_positive_sign = L"";
-	  _M_data->_M_positive_sign_size = 0;
-	  _M_data->_M_negative_sign = L"";
-	  _M_data->_M_negative_sign_size = 0;
-	  _M_data->_M_frac_digits = 0;
-	  _M_data->_M_pos_format = money_base::_S_default_pattern;
-	  _M_data->_M_neg_format = money_base::_S_default_pattern;
-
-	  // Use ctype::widen code without the facet...
-	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
-	    _M_data->_M_atoms[__i] =
-	      static_cast<wchar_t>(money_base::_S_atoms[__i]);
-	}
-      else
-	{
-	  __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
-	  // Named locale.
-	  lconv* lc = localeconv_l((locale_t) __cloc);
-
-	  // Check for NULL, which implies no fractional digits.
-	  if (lc->mon_decimal_point == NULL ||
-	      lc->mon_decimal_point[0] == '\0')
-	    {
-	      // Like in "C" locale.
-	      _M_data->_M_frac_digits = 0;
-	      _M_data->_M_decimal_point = L'.';
-	    }
-	  else
-	    {
-	      _M_data->_M_frac_digits = lc->int_frac_digits;
-	      _M_data->_M_decimal_point = (wchar_t)lc->mon_decimal_point[0];
-            }
-
-	  const char* __cgroup = lc->mon_grouping;
-	  const char* __cpossign = lc->positive_sign;
-	  const char* __cnegsign = lc->negative_sign;
-	  const char* __ccurr = lc->int_curr_symbol;
-
-	  char* __group = 0;
-	  wchar_t* __wcs_ps = 0;
-	  wchar_t* __wcs_ns = 0;
-	  const char __nposn = lc->int_n_sign_posn;
-	  __try
-	    {
-	      size_t __len;
-
-	      // Check for NULL, which implies no grouping.
-	      if (lc->mon_thousands_sep == NULL ||
-	          lc->mon_thousands_sep[0] == '\0')
-		{
-		  // Like in "C" locale.
-		  _M_data->_M_grouping = "";
-		  _M_data->_M_grouping_size = 0;
-		  _M_data->_M_use_grouping = false;
-		  _M_data->_M_thousands_sep = L',';
-		}
-	      else
-		{
-		  _M_data->_M_thousands_sep =
-			(wchar_t)lc->mon_thousands_sep[0];
-		  __len = strlen(__cgroup);
-		  if (__len)
-		    {
-		      __group = new char[__len + 1];
-		      memcpy(__group, __cgroup, __len + 1);
-		      _M_data->_M_grouping = __group;
-		    }
-		  else
-		    {
-		      _M_data->_M_grouping = "";
-		      _M_data->_M_use_grouping = false;
-		    }
-		  _M_data->_M_grouping_size = __len;
-		}
-
-	      mbstate_t __state;
-	      __len = strlen(__cpossign);
-	      if (__len)
-		{
-		  memset(&__state, 0, sizeof(mbstate_t));
-		  __wcs_ps = new wchar_t[__len + 1];
-		  mbsrtowcs(__wcs_ps, &__cpossign, __len + 1, &__state);
-		  _M_data->_M_positive_sign = __wcs_ps;
-		}
-	      else
-		_M_data->_M_positive_sign = L"";
-	      _M_data->_M_positive_sign_size =
-		wcslen(_M_data->_M_positive_sign);
-
-	      __len = strlen(__cnegsign);
-	      if (!__nposn)
-		_M_data->_M_negative_sign = L"()";
-	      else if (__len)
-		{
-		  memset(&__state, 0, sizeof(mbstate_t));
-		  __wcs_ns = new wchar_t[__len + 1];
-		  mbsrtowcs(__wcs_ns, &__cnegsign, __len + 1, &__state);
-		  _M_data->_M_negative_sign = __wcs_ns;
-		}
-	      else
-		_M_data->_M_negative_sign = L"";
-	      _M_data->_M_negative_sign_size =
-		wcslen(_M_data->_M_negative_sign);
-
-	      // _Intl == true.
-	      __len = strlen(__ccurr);
-	      if (__len)
-		{
-		  memset(&__state, 0, sizeof(mbstate_t));
-		  wchar_t* __wcs = new wchar_t[__len + 1];
-		  mbsrtowcs(__wcs, &__ccurr, __len + 1, &__state);
-		  _M_data->_M_curr_symbol = __wcs;
-		}
-	      else
-		_M_data->_M_curr_symbol = L"";
-	      _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
-	    }
-	  __catch(...)
-	    {
-	      delete _M_data;
-	      _M_data = 0;
-	      delete [] __group;
-	      delete [] __wcs_ps;
-	      delete [] __wcs_ns;
-	      uselocale((locale_t)__old);
-	      __throw_exception_again;
-	    }
-
-	  char __pprecedes = lc->int_p_cs_precedes;
-	  char __pspace = lc->int_p_sep_by_space;
-	  char __pposn = lc->int_p_sign_posn;
-	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
-							__pposn);
-	  char __nprecedes = lc->int_n_cs_precedes;
-	  char __nspace = lc->int_n_sep_by_space;
-	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
-							__nposn);
-
-	  uselocale((locale_t)__old);
-	}
-    }
-
-  template<>
-  void
-  moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
-						       const char*)
-  {
-    if (!_M_data)
-      _M_data = new __moneypunct_cache<wchar_t, false>;
-
-    if (!__cloc)
-	{
-	  // "C" locale
-	  _M_data->_M_decimal_point = L'.';
-	  _M_data->_M_thousands_sep = L',';
-	  _M_data->_M_grouping = "";
-          _M_data->_M_grouping_size = 0;
-	  _M_data->_M_use_grouping = false;
-	  _M_data->_M_curr_symbol = L"";
-	  _M_data->_M_curr_symbol_size = 0;
-	  _M_data->_M_positive_sign = L"";
-	  _M_data->_M_positive_sign_size = 0;
-	  _M_data->_M_negative_sign = L"";
-	  _M_data->_M_negative_sign_size = 0;
-	  _M_data->_M_frac_digits = 0;
-	  _M_data->_M_pos_format = money_base::_S_default_pattern;
-	  _M_data->_M_neg_format = money_base::_S_default_pattern;
-
-	  // Use ctype::widen code without the facet...
-	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
-	    _M_data->_M_atoms[__i] =
-	      static_cast<wchar_t>(money_base::_S_atoms[__i]);
-	}
-      else
-	{
-	  __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
-	  // Named locale.
-	  lconv* lc = localeconv_l((locale_t) __cloc);
-
-	  // Check for NULL, which implies no fractional digits.
-	  if (lc->mon_decimal_point == NULL ||
-	      lc->mon_decimal_point[0] == '\0')
-	    {
-	      // Like in "C" locale.
-	      _M_data->_M_frac_digits = 0;
-	      _M_data->_M_decimal_point = L'.';
-	    }
-	  else
-	    {
-	      _M_data->_M_frac_digits = lc->frac_digits;
-	      _M_data->_M_decimal_point = (wchar_t)lc->mon_decimal_point[0];
-            }
-
-	  const char* __cgroup = lc->mon_grouping;
-	  const char* __cpossign = lc->positive_sign;
-	  const char* __cnegsign = lc->negative_sign;
-	  const char* __ccurr = lc->currency_symbol;
-
-	  char* __group = 0;
-	  wchar_t* __wcs_ps = 0;
-	  wchar_t* __wcs_ns = 0;
-	  const char __nposn = lc->n_sign_posn;
-	  __try
-            {
-	      size_t __len;
-
-	      // Check for NULL, which implies no grouping.
-	      if (lc->mon_thousands_sep == NULL ||
-	          lc->mon_thousands_sep[0] == '\0')
-		{
-		  // Like in "C" locale.
-		  _M_data->_M_grouping = "";
-		  _M_data->_M_grouping_size = 0;
-		  _M_data->_M_use_grouping = false;
-		  _M_data->_M_thousands_sep = L',';
-		}
-	      else
-		{
-		  _M_data->_M_thousands_sep =
-			(wchar_t)lc->mon_thousands_sep[0];
-		  __len = strlen(__cgroup);
-		  if (__len)
-		    {
-		      __group = new char[__len + 1];
-		      memcpy(__group, __cgroup, __len + 1);
-		      _M_data->_M_grouping = __group;
-		    }
-		  else
-		    {
-		      _M_data->_M_grouping = "";
-		      _M_data->_M_use_grouping = false;
-		    }
-		  _M_data->_M_grouping_size = __len;
-		}
-
-              mbstate_t __state;
-              __len = strlen(__cpossign);
-              if (__len)
-                {
-		  memset(&__state, 0, sizeof(mbstate_t));
-		  __wcs_ps = new wchar_t[__len + 1];
-		  mbsrtowcs(__wcs_ps, &__cpossign, __len + 1, &__state);
-		  _M_data->_M_positive_sign = __wcs_ps;
-		}
-	      else
-		_M_data->_M_positive_sign = L"";
-              _M_data->_M_positive_sign_size =
-		wcslen(_M_data->_M_positive_sign);
-
-	      __len = strlen(__cnegsign);
-	      if (!__nposn)
-		_M_data->_M_negative_sign = L"()";
-	      else if (__len)
-		{
-		  memset(&__state, 0, sizeof(mbstate_t));
-		  __wcs_ns = new wchar_t[__len + 1];
-		  mbsrtowcs(__wcs_ns, &__cnegsign, __len + 1, &__state);
-		  _M_data->_M_negative_sign = __wcs_ns;
-		}
-	      else
-		_M_data->_M_negative_sign = L"";
-              _M_data->_M_negative_sign_size =
-		wcslen(_M_data->_M_negative_sign);
-
-	      // _Intl == true.
-	      __len = strlen(__ccurr);
-	      if (__len)
-		{
-		  memset(&__state, 0, sizeof(mbstate_t));
-		  wchar_t* __wcs = new wchar_t[__len + 1];
-		  mbsrtowcs(__wcs, &__ccurr, __len + 1, &__state);
-		  _M_data->_M_curr_symbol = __wcs;
-		}
-	      else
-		_M_data->_M_curr_symbol = L"";
-              _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
-	    }
-          __catch(...)
-	    {
-	      delete _M_data;
-              _M_data = 0;
-	      delete [] __group;
-	      delete [] __wcs_ps;
-	      delete [] __wcs_ns;
-	      uselocale((locale_t)__old);
-              __throw_exception_again;
-	    }
-
-	  char __pprecedes = lc->p_cs_precedes;
-	  char __pspace = lc->p_sep_by_space;
-	  char __pposn = lc->p_sign_posn;
-	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
-	                                                __pposn);
-	  char __nprecedes = lc->n_cs_precedes;
-	  char __nspace = lc->n_sep_by_space;
-	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
-	                                                __nposn);
-
-	  uselocale((locale_t)__old);
-	}
-    }
-
-  template<>
-    moneypunct<wchar_t, true>::~moneypunct()
-    {
-      if (_M_data->_M_grouping_size)
-	delete [] _M_data->_M_grouping;
-      if (_M_data->_M_positive_sign_size)
-	delete [] _M_data->_M_positive_sign;
-      if (_M_data->_M_negative_sign_size
-          && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
-	delete [] _M_data->_M_negative_sign;
-      if (_M_data->_M_curr_symbol_size)
-	delete [] _M_data->_M_curr_symbol;
-      delete _M_data;
-    }
-
-  template<>
-    moneypunct<wchar_t, false>::~moneypunct()
-    {
-      if (_M_data->_M_grouping_size)
-	delete [] _M_data->_M_grouping;
-      if (_M_data->_M_positive_sign_size)
-	delete [] _M_data->_M_positive_sign;
-      if (_M_data->_M_negative_sign_size
-          && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
-	delete [] _M_data->_M_negative_sign;
-      if (_M_data->_M_curr_symbol_size)
-	delete [] _M_data->_M_curr_symbol;
-      delete _M_data;
-    }
-#endif
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
--- ./libstdc++-v3/config/locale/dragonfly/numeric_members.cc_orig	2023-06-03 12:09:45 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/numeric_members.cc	2023-06-03 12:09:51 +0000
@@ -1,235 +0,0 @@
-// std::numpunct implementation details, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2015-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.2.3.1.2  numpunct virtual functions
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <locale>
-#include <cstring>
-#include <xlocale.h>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<>
-    void
-    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
-    {
-      if (!_M_data)
-	_M_data = new __numpunct_cache<char>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_data->_M_grouping = "";
-	  _M_data->_M_grouping_size = 0;
-	  _M_data->_M_use_grouping = false;
-
-	  _M_data->_M_decimal_point = '.';
-	  _M_data->_M_thousands_sep = ',';
-
-	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
-	    _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
-
-	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
-	    _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
-	}
-      else
-	{
-	  // Named locale.
-	  lconv* lc = localeconv_l((locale_t) __cloc);
-
-	  // Decimal point should always be defined, but check null anyway
-	  if (lc->decimal_point == NULL)
-	    {
-	      // Not defined, so use "C" locale default
-	      _M_data->_M_decimal_point = '.';
-	    }
-	  else
-	    {
-	      _M_data->_M_decimal_point = lc->decimal_point[0];
-	    }
-	  // Check for NULL, which implies no grouping.
-	  if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0')
-	    {
-	      // Like in "C" locale.
-	      _M_data->_M_grouping = "";
-	      _M_data->_M_grouping_size = 0;
-	      _M_data->_M_use_grouping = false;
-	      _M_data->_M_thousands_sep = ',';
-	    }
-	  else
-	    {
-	      _M_data->_M_thousands_sep = lc->thousands_sep[0];
-
-	      const char* __src = lc->grouping;
-	      const size_t __len = strlen(__src);
-	      if (__len)
-		{
-		  __try
-		    {
-		      char* __dst = new char[__len + 1];
-		      memcpy(__dst, __src, __len + 1);
-		      _M_data->_M_grouping = __dst;
-		      _M_data->_M_use_grouping = true;
-		    }
-		  __catch(...)
-		    {
-		      delete _M_data;
-		      _M_data = 0;
-		      __throw_exception_again;
-		    }
-		}
-	      else
-		{
-		  _M_data->_M_grouping = "";
-		  _M_data->_M_use_grouping = false;
-		}
-	      _M_data->_M_grouping_size = __len;
-	    }
-	}
-
-      // NB: There is no way to extact this info from posix locales.
-      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
-      _M_data->_M_truename = "true";
-      _M_data->_M_truename_size = 4;
-      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
-      _M_data->_M_falsename = "false";
-      _M_data->_M_falsename_size = 5;
-    }
-
-  template<>
-    numpunct<char>::~numpunct()
-    {
-      if (_M_data->_M_grouping_size)
-	delete [] _M_data->_M_grouping;
-      delete _M_data;
-    }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    void
-    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
-    {
-      if (!_M_data)
-	_M_data = new __numpunct_cache<wchar_t>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_data->_M_grouping = "";
-	  _M_data->_M_grouping_size = 0;
-	  _M_data->_M_use_grouping = false;
-
-	  _M_data->_M_decimal_point = L'.';
-	  _M_data->_M_thousands_sep = L',';
-
-	  // Use ctype::widen code without the facet...
-	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
-	    _M_data->_M_atoms_out[__i] =
-	      static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
-
-	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
-	    _M_data->_M_atoms_in[__j] =
-	      static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
-	}
-      else
-	{
-	  // Named locale.
-	  lconv* lc = localeconv_l((locale_t) __cloc);
-
-	  // Decimal point should always be defined, but check null anyway
-	  if (lc->decimal_point == NULL)
-	    {
-	      // Not defined, so use "C" locale default
-	      _M_data->_M_decimal_point = L'.';
-	    }
-	  else
-	    {
-	      _M_data->_M_decimal_point = (wchar_t)lc->decimal_point[0];
-	    }
-	  // Check for NULL, which implies no grouping.
-	  if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0')
-	    {
-	      // Like in "C" locale.
-	      _M_data->_M_grouping = "";
-	      _M_data->_M_grouping_size = 0;
-	      _M_data->_M_use_grouping = false;
-	      _M_data->_M_thousands_sep = L',';
-	    }
-	  else
-	    {
-	      _M_data->_M_thousands_sep = (wchar_t)lc->thousands_sep[0];
-
-  	      const char* __src = lc->grouping;
-	      const size_t __len = strlen(__src);
-	      if (__len)
-		{
-		  __try
-		    {
-		      char* __dst = new char[__len + 1];
-		      memcpy(__dst, __src, __len + 1);
-		      _M_data->_M_grouping = __dst;
-		    }
-		  __catch(...)
-		    {
-		      delete _M_data;
-		      _M_data = 0;
-		      __throw_exception_again;
-		    }
-		}
-	      else
-		{
-		  _M_data->_M_grouping = "";
-		  _M_data->_M_use_grouping = false;
-		}
-	      _M_data->_M_grouping_size = __len;
-	    }
-	}
-
-      // NB: There is no way to extact this info from posix locales.
-      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
-      _M_data->_M_truename = L"true";
-      _M_data->_M_truename_size = 4;
-      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
-      _M_data->_M_falsename = L"false";
-      _M_data->_M_falsename_size = 5;
-    }
-
-  template<>
-    numpunct<wchar_t>::~numpunct()
-    {
-      if (_M_data->_M_grouping_size)
-	delete [] _M_data->_M_grouping;
-      delete _M_data;
-    }
- #endif
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
--- ./libstdc++-v3/config/locale/dragonfly/time_members.cc_orig	2023-06-03 12:12:24 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/time_members.cc	2023-06-03 12:12:31 +0000
@@ -1,404 +0,0 @@
-// std::time_get, std::time_put implementation, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2001-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-//
-// ISO C++ 14882: 22.2.5.1.2 - time_get virtual functions
-// ISO C++ 14882: 22.2.5.3.2 - time_put virtual functions
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-#include <locale>
-#include <ctime>
-#include <cwchar>
-#include <stdlib.h>
-#include <langinfo.h>
-#include <xlocale.h>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<>
-    void
-    __timepunct<char>::
-    _M_put(char* __s, size_t __maxlen, const char* __format,
-	   const tm* __tm) const throw()
-    {
-      const size_t __len = strftime_l(__s, __maxlen, __format, __tm,
-				      (locale_t)_M_c_locale_timepunct);
-      // Make sure __s is null terminated.
-      if (__len == 0)
-	__s[0] = '\0';
-    }
-
-  template<>
-    void
-    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc)
-    {
-      if (!_M_data)
-	_M_data = new __timepunct_cache<char>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_c_locale_timepunct = _S_get_c_locale();
-
-	  _M_data->_M_date_format = "%m/%d/%y";
-	  _M_data->_M_date_era_format = "%m/%d/%y";
-	  _M_data->_M_time_format = "%H:%M:%S";
-	  _M_data->_M_time_era_format = "%H:%M:%S";
-	  _M_data->_M_date_time_format = "";
-	  _M_data->_M_date_time_era_format = "";
-	  _M_data->_M_am = "AM";
-	  _M_data->_M_pm = "PM";
-	  _M_data->_M_am_pm_format = "%I:%M:%S %p";
-
-	  // Day names, starting with "C"'s Sunday.
-	  _M_data->_M_day1 = "Sunday";
-	  _M_data->_M_day2 = "Monday";
-	  _M_data->_M_day3 = "Tuesday";
-	  _M_data->_M_day4 = "Wednesday";
-	  _M_data->_M_day5 = "Thursday";
-	  _M_data->_M_day6 = "Friday";
-	  _M_data->_M_day7 = "Saturday";
-
-	  // Abbreviated day names, starting with "C"'s Sun.
-	  _M_data->_M_aday1 = "Sun";
-	  _M_data->_M_aday2 = "Mon";
-	  _M_data->_M_aday3 = "Tue";
-	  _M_data->_M_aday4 = "Wed";
-	  _M_data->_M_aday5 = "Thu";
-	  _M_data->_M_aday6 = "Fri";
-	  _M_data->_M_aday7 = "Sat";
-
-	  // Month names, starting with "C"'s January.
-	  _M_data->_M_month01 = "January";
-	  _M_data->_M_month02 = "February";
-	  _M_data->_M_month03 = "March";
-	  _M_data->_M_month04 = "April";
-	  _M_data->_M_month05 = "May";
-	  _M_data->_M_month06 = "June";
-	  _M_data->_M_month07 = "July";
-	  _M_data->_M_month08 = "August";
-	  _M_data->_M_month09 = "September";
-	  _M_data->_M_month10 = "October";
-	  _M_data->_M_month11 = "November";
-	  _M_data->_M_month12 = "December";
-
-	  // Abbreviated month names, starting with "C"'s Jan.
-	  _M_data->_M_amonth01 = "Jan";
-	  _M_data->_M_amonth02 = "Feb";
-	  _M_data->_M_amonth03 = "Mar";
-	  _M_data->_M_amonth04 = "Apr";
-	  _M_data->_M_amonth05 = "May";
-	  _M_data->_M_amonth06 = "Jun";
-	  _M_data->_M_amonth07 = "Jul";
-	  _M_data->_M_amonth08 = "Aug";
-	  _M_data->_M_amonth09 = "Sep";
-	  _M_data->_M_amonth10 = "Oct";
-	  _M_data->_M_amonth11 = "Nov";
-	  _M_data->_M_amonth12 = "Dec";
-	}
-      else
-	{
-	  _M_c_locale_timepunct = _S_clone_c_locale(__cloc);
-
-	  _M_data->_M_date_format = nl_langinfo_l(D_FMT, (locale_t)__cloc);
-	  _M_data->_M_date_era_format = nl_langinfo_l(ERA_D_FMT,
-	  					      (locale_t)__cloc);
-	  _M_data->_M_time_format = nl_langinfo_l(T_FMT, (locale_t)__cloc);
-	  _M_data->_M_time_era_format = nl_langinfo_l(ERA_T_FMT,
-						      (locale_t)__cloc);
-	  _M_data->_M_date_time_format = nl_langinfo_l(D_T_FMT,
-						       (locale_t)__cloc);
-	  _M_data->_M_date_time_era_format = nl_langinfo_l(ERA_D_T_FMT,
-	  						   (locale_t)__cloc);
-	  _M_data->_M_am = nl_langinfo_l(AM_STR, (locale_t)__cloc);
-	  _M_data->_M_pm = nl_langinfo_l(PM_STR, (locale_t)__cloc);
-	  _M_data->_M_am_pm_format = nl_langinfo_l(T_FMT_AMPM,
-	  					   (locale_t)__cloc);
-
-	  // Day names, starting with "C"'s Sunday.
-	  _M_data->_M_day1 = nl_langinfo_l(DAY_1, (locale_t)__cloc);
-	  _M_data->_M_day2 = nl_langinfo_l(DAY_2, (locale_t)__cloc);
-	  _M_data->_M_day3 = nl_langinfo_l(DAY_3, (locale_t)__cloc);
-	  _M_data->_M_day4 = nl_langinfo_l(DAY_4, (locale_t)__cloc);
-	  _M_data->_M_day5 = nl_langinfo_l(DAY_5, (locale_t)__cloc);
-	  _M_data->_M_day6 = nl_langinfo_l(DAY_6, (locale_t)__cloc);
-	  _M_data->_M_day7 = nl_langinfo_l(DAY_7, (locale_t)__cloc);
-
-	  // Abbreviated day names, starting with "C"'s Sun.
-	  _M_data->_M_aday1 = nl_langinfo_l(ABDAY_1, (locale_t)__cloc);
-	  _M_data->_M_aday2 = nl_langinfo_l(ABDAY_2, (locale_t)__cloc);
-	  _M_data->_M_aday3 = nl_langinfo_l(ABDAY_3, (locale_t)__cloc);
-	  _M_data->_M_aday4 = nl_langinfo_l(ABDAY_4, (locale_t)__cloc);
-	  _M_data->_M_aday5 = nl_langinfo_l(ABDAY_5, (locale_t)__cloc);
-	  _M_data->_M_aday6 = nl_langinfo_l(ABDAY_6, (locale_t)__cloc);
-	  _M_data->_M_aday7 = nl_langinfo_l(ABDAY_7, (locale_t)__cloc);
-
-	  // Month names, starting with "C"'s January.
-	  _M_data->_M_month01 = nl_langinfo_l(MON_1, (locale_t)__cloc);
-	  _M_data->_M_month02 = nl_langinfo_l(MON_2, (locale_t)__cloc);
-	  _M_data->_M_month03 = nl_langinfo_l(MON_3, (locale_t)__cloc);
-	  _M_data->_M_month04 = nl_langinfo_l(MON_4, (locale_t)__cloc);
-	  _M_data->_M_month05 = nl_langinfo_l(MON_5, (locale_t)__cloc);
-	  _M_data->_M_month06 = nl_langinfo_l(MON_6, (locale_t)__cloc);
-	  _M_data->_M_month07 = nl_langinfo_l(MON_7, (locale_t)__cloc);
-	  _M_data->_M_month08 = nl_langinfo_l(MON_8, (locale_t)__cloc);
-	  _M_data->_M_month09 = nl_langinfo_l(MON_9, (locale_t)__cloc);
-	  _M_data->_M_month10 = nl_langinfo_l(MON_10, (locale_t)__cloc);
-	  _M_data->_M_month11 = nl_langinfo_l(MON_11, (locale_t)__cloc);
-	  _M_data->_M_month12 = nl_langinfo_l(MON_12, (locale_t)__cloc);
-
-	  // Abbreviated month names, starting with "C"'s Jan.
-	  _M_data->_M_amonth01 = nl_langinfo_l(ABMON_1, (locale_t)__cloc);
-	  _M_data->_M_amonth02 = nl_langinfo_l(ABMON_2, (locale_t)__cloc);
-	  _M_data->_M_amonth03 = nl_langinfo_l(ABMON_3, (locale_t)__cloc);
-	  _M_data->_M_amonth04 = nl_langinfo_l(ABMON_4, (locale_t)__cloc);
-	  _M_data->_M_amonth05 = nl_langinfo_l(ABMON_5, (locale_t)__cloc);
-	  _M_data->_M_amonth06 = nl_langinfo_l(ABMON_6, (locale_t)__cloc);
-	  _M_data->_M_amonth07 = nl_langinfo_l(ABMON_7, (locale_t)__cloc);
-	  _M_data->_M_amonth08 = nl_langinfo_l(ABMON_8, (locale_t)__cloc);
-	  _M_data->_M_amonth09 = nl_langinfo_l(ABMON_9, (locale_t)__cloc);
-	  _M_data->_M_amonth10 = nl_langinfo_l(ABMON_10, (locale_t)__cloc);
-	  _M_data->_M_amonth11 = nl_langinfo_l(ABMON_11, (locale_t)__cloc);
-	  _M_data->_M_amonth12 = nl_langinfo_l(ABMON_12, (locale_t)__cloc);
-	}
-    }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    void
-    __timepunct<wchar_t>::
-    _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format,
-	   const tm* __tm) const throw()
-    {
-      const size_t __len = wcsftime_l(__s, __maxlen, __format, __tm,
-				      (locale_t)_M_c_locale_timepunct);
-      // Make sure __s is null terminated.
-      if (__len == 0)
-	__s[0] = L'\0';
-    }
-
-#define WIDE_LANGINFO(M,FMT) \
-	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); \
-	langstring[fmtlen] = L'\0'; \
-	_M_data->M = langstring;
-
-  template<>
-    void
-    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc)
-    {
-      if (!_M_data)
-	_M_data = new __timepunct_cache<wchar_t>;
-
-      if (!__cloc)
-	{
-	  // "C" locale
-	  _M_c_locale_timepunct = _S_get_c_locale();
-
-	  _M_data->_M_date_format = L"%m/%d/%y";
-	  _M_data->_M_date_era_format = L"%m/%d/%y";
-	  _M_data->_M_time_format = L"%H:%M:%S";
-	  _M_data->_M_time_era_format = L"%H:%M:%S";
-	  _M_data->_M_date_time_format = L"";
-	  _M_data->_M_date_time_era_format = L"";
-	  _M_data->_M_am = L"AM";
-	  _M_data->_M_pm = L"PM";
-	  _M_data->_M_am_pm_format = L"%I:%M:%S %p";
-
-	  // Day names, starting with "C"'s Sunday.
-	  _M_data->_M_day1 = L"Sunday";
-	  _M_data->_M_day2 = L"Monday";
-	  _M_data->_M_day3 = L"Tuesday";
-	  _M_data->_M_day4 = L"Wednesday";
-	  _M_data->_M_day5 = L"Thursday";
-	  _M_data->_M_day6 = L"Friday";
-	  _M_data->_M_day7 = L"Saturday";
-
-	  // Abbreviated day names, starting with "C"'s Sun.
-	  _M_data->_M_aday1 = L"Sun";
-	  _M_data->_M_aday2 = L"Mon";
-	  _M_data->_M_aday3 = L"Tue";
-	  _M_data->_M_aday4 = L"Wed";
-	  _M_data->_M_aday5 = L"Thu";
-	  _M_data->_M_aday6 = L"Fri";
-	  _M_data->_M_aday7 = L"Sat";
-
-	  // Month names, starting with "C"'s January.
-	  _M_data->_M_month01 = L"January";
-	  _M_data->_M_month02 = L"February";
-	  _M_data->_M_month03 = L"March";
-	  _M_data->_M_month04 = L"April";
-	  _M_data->_M_month05 = L"May";
-	  _M_data->_M_month06 = L"June";
-	  _M_data->_M_month07 = L"July";
-	  _M_data->_M_month08 = L"August";
-	  _M_data->_M_month09 = L"September";
-	  _M_data->_M_month10 = L"October";
-	  _M_data->_M_month11 = L"November";
-	  _M_data->_M_month12 = L"December";
-
-	  // Abbreviated month names, starting with "C"'s Jan.
-	  _M_data->_M_amonth01 = L"Jan";
-	  _M_data->_M_amonth02 = L"Feb";
-	  _M_data->_M_amonth03 = L"Mar";
-	  _M_data->_M_amonth04 = L"Apr";
-	  _M_data->_M_amonth05 = L"May";
-	  _M_data->_M_amonth06 = L"Jun";
-	  _M_data->_M_amonth07 = L"Jul";
-	  _M_data->_M_amonth08 = L"Aug";
-	  _M_data->_M_amonth09 = L"Sep";
-	  _M_data->_M_amonth10 = L"Oct";
-	  _M_data->_M_amonth11 = L"Nov";
-	  _M_data->_M_amonth12 = L"Dec";
-	}
-      else
-	{
-	  wchar_t *langstring = 0;
-	  wchar_t holder[128];
-	  size_t fmtlen;
-
-	  _M_c_locale_timepunct = _S_clone_c_locale(__cloc);
-
-	  WIDE_LANGINFO(_M_date_format, D_FMT)
-	  WIDE_LANGINFO(_M_date_era_format, ERA_D_FMT)
-	  WIDE_LANGINFO(_M_time_format, T_FMT)
-	  WIDE_LANGINFO(_M_time_era_format, ERA_T_FMT)
-	  WIDE_LANGINFO(_M_date_time_format, D_T_FMT)
-	  WIDE_LANGINFO(_M_date_time_era_format, ERA_D_T_FMT)
-	  WIDE_LANGINFO(_M_am, AM_STR)
-	  WIDE_LANGINFO(_M_pm, PM_STR)
-	  WIDE_LANGINFO(_M_am_pm_format, T_FMT_AMPM)
-
-	  // Day names, starting with "C"'s Sunday.
-	  WIDE_LANGINFO(_M_day1, DAY_1)
-	  WIDE_LANGINFO(_M_day2, DAY_2)
-	  WIDE_LANGINFO(_M_day3, DAY_3)
-	  WIDE_LANGINFO(_M_day4, DAY_4)
-	  WIDE_LANGINFO(_M_day5, DAY_5)
-	  WIDE_LANGINFO(_M_day6, DAY_6)
-	  WIDE_LANGINFO(_M_day7, DAY_7)
-
-	  // Abbreviated day names, starting with "C"'s Sun.
-	  WIDE_LANGINFO(_M_aday1, ABDAY_1)
-	  WIDE_LANGINFO(_M_aday2, ABDAY_2)
-	  WIDE_LANGINFO(_M_aday3, ABDAY_3)
-	  WIDE_LANGINFO(_M_aday4, ABDAY_4)
-	  WIDE_LANGINFO(_M_aday5, ABDAY_5)
-	  WIDE_LANGINFO(_M_aday6, ABDAY_6)
-	  WIDE_LANGINFO(_M_aday7, ABDAY_7)
-
-	  // Month names, starting with "C"'s January.
-	  WIDE_LANGINFO(_M_month01, MON_1)
-	  WIDE_LANGINFO(_M_month02, MON_2)
-	  WIDE_LANGINFO(_M_month03, MON_3)
-	  WIDE_LANGINFO(_M_month04, MON_4)
-	  WIDE_LANGINFO(_M_month05, MON_5)
-	  WIDE_LANGINFO(_M_month06, MON_6)
-	  WIDE_LANGINFO(_M_month07, MON_7)
-	  WIDE_LANGINFO(_M_month08, MON_8)
-	  WIDE_LANGINFO(_M_month09, MON_9)
-	  WIDE_LANGINFO(_M_month10, MON_10)
-	  WIDE_LANGINFO(_M_month11, MON_11)
-	  WIDE_LANGINFO(_M_month12, MON_12)
-
-	  // Abbreviated month names, starting with "C"'s Jan.
-	  WIDE_LANGINFO(_M_amonth01, ABMON_1)
-	  WIDE_LANGINFO(_M_amonth02, ABMON_2)
-	  WIDE_LANGINFO(_M_amonth03, ABMON_3)
-	  WIDE_LANGINFO(_M_amonth04, ABMON_4)
-	  WIDE_LANGINFO(_M_amonth05, ABMON_5)
-	  WIDE_LANGINFO(_M_amonth06, ABMON_6)
-	  WIDE_LANGINFO(_M_amonth07, ABMON_7)
-	  WIDE_LANGINFO(_M_amonth08, ABMON_8)
-	  WIDE_LANGINFO(_M_amonth09, ABMON_9)
-	  WIDE_LANGINFO(_M_amonth10, ABMON_10)
-	  WIDE_LANGINFO(_M_amonth11, ABMON_11)
-	  WIDE_LANGINFO(_M_amonth12, ABMON_12)
-	}
-    }
-
-  template<>
-    __timepunct<wchar_t>::~__timepunct()
-    {
-      delete [] _M_data->_M_date_format;
-      delete [] _M_data->_M_date_era_format;
-      delete [] _M_data->_M_time_format;
-      delete [] _M_data->_M_time_era_format;
-      delete [] _M_data->_M_date_time_format;
-      delete [] _M_data->_M_date_time_era_format;
-      delete [] _M_data->_M_am;
-      delete [] _M_data->_M_pm;
-      delete [] _M_data->_M_am_pm_format;
-      delete [] _M_data->_M_day1;
-      delete [] _M_data->_M_day2;
-      delete [] _M_data->_M_day3;
-      delete [] _M_data->_M_day4;
-      delete [] _M_data->_M_day5;
-      delete [] _M_data->_M_day6;
-      delete [] _M_data->_M_day7;
-      delete [] _M_data->_M_aday1;
-      delete [] _M_data->_M_aday2;
-      delete [] _M_data->_M_aday3;
-      delete [] _M_data->_M_aday4;
-      delete [] _M_data->_M_aday5;
-      delete [] _M_data->_M_aday6;
-      delete [] _M_data->_M_aday7;
-      delete [] _M_data->_M_month01;
-      delete [] _M_data->_M_month02;
-      delete [] _M_data->_M_month03;
-      delete [] _M_data->_M_month04;
-      delete [] _M_data->_M_month05;
-      delete [] _M_data->_M_month06;
-      delete [] _M_data->_M_month07;
-      delete [] _M_data->_M_month08;
-      delete [] _M_data->_M_month09;
-      delete [] _M_data->_M_month10;
-      delete [] _M_data->_M_month11;
-      delete [] _M_data->_M_month12;
-      delete [] _M_data->_M_amonth01;
-      delete [] _M_data->_M_amonth02;
-      delete [] _M_data->_M_amonth03;
-      delete [] _M_data->_M_amonth04;
-      delete [] _M_data->_M_amonth05;
-      delete [] _M_data->_M_amonth06;
-      delete [] _M_data->_M_amonth07;
-      delete [] _M_data->_M_amonth08;
-      delete [] _M_data->_M_amonth09;
-      delete [] _M_data->_M_amonth10;
-      delete [] _M_data->_M_amonth11;
-      delete [] _M_data->_M_amonth12;
-      delete _M_data;
-    }
-
-#endif
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
--- ./libstdc++-v3/config/locale/dragonfly/time_members.h_orig	2023-06-03 12:15:33 +0000
+++ ./libstdc++-v3/config/locale/dragonfly/time_members.h	2023-06-03 12:15:43 +0000
@@ -1,95 +0,0 @@
-// std::time_get, std::time_put implementation, DragonFly version -*- C++ -*-
-
-// Copyright (C) 2015-2022 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-/** @file bits/time_members.h
- *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{locale}
- */
-
-//
-// ISO C++ 14882: 22.2.5.1.2 - time_get functions
-// ISO C++ 14882: 22.2.5.3.2 - time_put functions
-//
-
-// Written by Benjamin Kosnik <bkoz@redhat.com>
-// Modified for DragonFly by John Marino <gnugcc@marino.st>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _CharT>
-    __timepunct<_CharT>::__timepunct(size_t __refs)
-    : facet(__refs), _M_data(0), _M_c_locale_timepunct(0),
-      _M_name_timepunct(_S_get_c_name())
-    { _M_initialize_timepunct(); }
-
-  template<typename _CharT>
-    __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs)
-    : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(0),
-      _M_name_timepunct(_S_get_c_name())
-    { _M_initialize_timepunct(); }
-
-  template<typename _CharT>
-    __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
-				     size_t __refs)
-    : facet(__refs), _M_data(0), _M_c_locale_timepunct(0),
-      _M_name_timepunct(0)
-    {
-      if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
-	{
-	  const size_t __len = __builtin_strlen(__s) + 1;
-	  char* __tmp = new char[__len];
-	  __builtin_memcpy(__tmp, __s, __len);
-	  _M_name_timepunct = __tmp;
-	}
-      else
-	_M_name_timepunct = _S_get_c_name();
-
-      __try
-	{ _M_initialize_timepunct(__cloc); }
-      __catch(...)
-	{
-	  if (_M_name_timepunct != _S_get_c_name())
-	    delete [] _M_name_timepunct;
-	  __throw_exception_again;
-	}
-    }
-
-  template<typename _CharT>
-    __timepunct<_CharT>::~__timepunct()
-    {
-      if (_M_name_timepunct != _S_get_c_name())
-	delete [] _M_name_timepunct;
-      delete _M_data;
-      _S_destroy_c_locale(_M_c_locale_timepunct);
-    }
-
-  // specialization
-  template<>
-    __timepunct<wchar_t>::~__timepunct();
-
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/c_locale.cc b/libstdc++-v3/config/locale/xpg7/c_locale.cc
new file mode 100644
index 00000000000..39ef58ea0a9
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/c_locale.cc
@@ -0,0 +1,204 @@
+// localization implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2014-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.8  Standard locale categories.
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+// Modified for XPG7 by Clément Chigot <clement.chigot@atos.net>
+
+#include <cstdlib>
+#include <locale>
+#include <stdexcept>
+#include <limits>
+
+#include <langinfo.h>
+#ifdef _GLIBCXX_HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<>
+    void
+    __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
+    {
+      char* __sanity;
+      __v = strtof_l(__s, &__sanity, (locale_t)__cloc);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 23. Num_get overflow result.
+      if (__sanity == __s || *__sanity != '\0')
+	{
+	  __v = 0.0f;
+	  __err = ios_base::failbit;
+	}
+      else if (__v == numeric_limits<float>::infinity())
+	{
+	  __v = numeric_limits<float>::max();
+	  __err = ios_base::failbit;
+	}
+      else if (__v == -numeric_limits<float>::infinity())
+	{
+	  __v = -numeric_limits<float>::max();
+	  __err = ios_base::failbit;
+	}
+    }
+
+  template<>
+    void
+    __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
+    {
+      char* __sanity;
+      __v = strtod_l(__s, &__sanity, (locale_t)__cloc);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 23. Num_get overflow result.
+      if (__sanity == __s || *__sanity != '\0')
+	{
+	  __v = 0.0;
+	  __err = ios_base::failbit;
+	}
+      else if (__v == numeric_limits<double>::infinity())
+	{
+	  __v = numeric_limits<double>::max();
+	  __err = ios_base::failbit;
+	}
+      else if (__v == -numeric_limits<double>::infinity())
+	{
+	  __v = -numeric_limits<double>::max();
+	  __err = ios_base::failbit;
+	}
+    }
+
+  template<>
+    void
+    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
+    {
+      char* __sanity;
+      __v = strtold_l(__s, &__sanity, (locale_t)__cloc);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 23. Num_get overflow result.
+      if (__sanity == __s || *__sanity != '\0')
+	{
+	  __v = 0.0l;
+	  __err = ios_base::failbit;
+	}
+      else if (__v == numeric_limits<long double>::infinity())
+	{
+	  __v = numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
+      else if (__v == -numeric_limits<long double>::infinity())
+	{
+	  __v = -numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
+    }
+
+  void
+  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
+				    __c_locale __old)
+  {
+    __cloc = (__c_locale)newlocale(LC_ALL_MASK, __s, (locale_t)__old);
+    if (!__cloc)
+      {
+	// This named locale is not supported by the underlying OS.
+	__throw_runtime_error(__N("locale::facet::_S_create_c_locale "
+				  "name not valid"));
+      }
+  }
+
+  void
+  locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
+  {
+    if (__cloc && _S_get_c_locale() != __cloc)
+      freelocale((locale_t)__cloc);
+  }
+
+  __c_locale
+  locale::facet::_S_clone_c_locale(__c_locale& __cloc) throw()
+  { return (__c_locale)duplocale((locale_t)__cloc); }
+
+  __c_locale
+  locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s)
+  {
+    __c_locale __dup = (__c_locale)duplocale((locale_t)__cloc);
+    if (__dup == __c_locale(0))
+      __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
+				"duplocale error"));
+    __c_locale __changed = (__c_locale)newlocale(LC_CTYPE_MASK, __s,
+						 (locale_t)__dup);
+    if (__changed == __c_locale(0))
+      {
+	freelocale((locale_t)__dup);
+	__throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
+				  "newlocale error"));
+      }
+    return __changed;
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
+    {
+      "LC_CTYPE",
+      "LC_NUMERIC",
+      "LC_TIME",
+      "LC_COLLATE",
+      "LC_MONETARY",
+      "LC_MESSAGES"
+    };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  const char* const* const locale::_S_categories = __gnu_cxx::category_names;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+// XXX GLIBCXX_ABI Deprecated
+#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
+#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
+  extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
+_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct);
+#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
diff --git a/libstdc++-v3/config/locale/xpg7/c_locale.h b/libstdc++-v3/config/locale/xpg7/c_locale.h
new file mode 100644
index 00000000000..e030a3368d1
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/c_locale.h
@@ -0,0 +1,126 @@
+// localization implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2001-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/c++locale.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{locale}
+ */
+
+//
+// ISO C++ 14882: 22.8  Standard locale categories.
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+// Modified for XPG7 by Clément Chigot <clement.chigot@atos.net>
+
+#ifndef _GLIBCXX_CXX_LOCALE_H
+#define _GLIBCXX_CXX_LOCALE_H 1
+
+#pragma GCC system_header
+
+#include <clocale>
+#include <cstdlib>
+#ifdef _GLIBCXX_HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+#define _GLIBCXX_C_LOCALE_XPG7 1
+
+// Assume that if strtof_l is missing then strtod_l and strold_l
+// are missing too.
+#ifndef _GLIBCXX_HAVE_STRTOF_L
+extern "C" inline
+float strtof_l (const char *__nptr, char **__endptr,
+		locale_t locale)
+{
+  locale_t __old = uselocale(locale);
+  float __res = strtof(__nptr, __endptr);
+  uselocale(__old);
+  return __res;
+}
+
+extern "C" inline
+double strtod_l (const char *__nptr, char **__endptr,
+		 locale_t locale)
+{
+  locale_t __old = uselocale(locale);
+  double __res = strtod(__nptr, __endptr);
+  uselocale(__old);
+  return __res;
+}
+
+extern "C" inline
+long double strtold_l (const char *__nptr, char **__endptr,
+		       locale_t locale)
+{
+  locale_t __old = uselocale(locale);
+  long double __res = strtold(__nptr, __endptr);
+  uselocale(__old);
+  return __res;
+}
+#endif
+
+#define _GLIBCXX_NUM_CATEGORIES 0
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if defined(__DragonFly__) || defined(__FreeBSD__)
+  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
+  // fall back to the unsafe vsprintf which, in general, can be dangerous
+  // and should be avoided.
+  inline int
+  __convert_from_v(const __c_locale& __cloc, char* __out,
+		   const int __size __attribute__ ((__unused__)),
+		   const char* __fmt, ...)
+  {
+    __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
+
+    __builtin_va_list __args;
+    __builtin_va_start(__args, __fmt);
+
+#if _GLIBCXX_USE_C99_STDIO
+    const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
+#else
+    const int __ret = __builtin_vsprintf(__out, __fmt, __args);
+#endif
+
+    __builtin_va_end(__args);
+
+    uselocale((locale_t)__old);
+    return __ret;
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif
diff --git a/libstdc++-v3/config/locale/xpg7/codecvt_members.cc b/libstdc++-v3/config/locale/xpg7/codecvt_members.cc
new file mode 100644
index 00000000000..3ce047a0851
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/codecvt_members.cc
@@ -0,0 +1,288 @@
+// std::codecvt implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2015-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.2.1.5 - Template class codecvt
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+
+#include <locale>
+#include <cstring>
+#include <cstdlib>  // For MB_CUR_MAX
+#include <climits>  // For MB_LEN_MAX
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // Specializations.
+#ifdef _GLIBCXX_USE_WCHAR_T
+  codecvt_base::result
+  codecvt<wchar_t, char, mbstate_t>::
+  do_out(state_type& __state, const intern_type* __from,
+	 const intern_type* __from_end, const intern_type*& __from_next,
+	 extern_type* __to, extern_type* __to_end,
+	 extern_type*& __to_next) const
+  {
+    result __ret = ok;
+    state_type __tmp_state(__state);
+
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
+
+    // wcsnrtombs is *very* fast but stops if encounters NUL characters:
+    // in case we fall back to wcrtomb and then continue, in a loop.
+    // NB: wcsnrtombs is a GNU extension
+    for (__from_next = __from, __to_next = __to;
+	 __from_next < __from_end && __to_next < __to_end
+	 && __ret == ok;)
+      {
+	const intern_type* __from_chunk_end = wmemchr(__from_next, L'\0',
+						      __from_end - __from_next);
+	if (!__from_chunk_end)
+	  __from_chunk_end = __from_end;
+
+	__from = __from_next;
+	const size_t __conv = wcsnrtombs(__to_next, &__from_next,
+					 __from_chunk_end - __from_next,
+					 __to_end - __to_next, &__state);
+	if (__conv == static_cast<size_t>(-1))
+	  {
+	    // In case of error, in order to stop at the exact place we
+	    // have to start again from the beginning with a series of
+	    // wcrtomb.
+	    for (; __from < __from_next; ++__from)
+	      __to_next += wcrtomb(__to_next, *__from, &__tmp_state);
+	    __state = __tmp_state;
+	    __ret = error;
+	  }
+	else if (__from_next && __from_next < __from_chunk_end)
+	  {
+	    __to_next += __conv;
+	    __ret = partial;
+	  }
+	else
+	  {
+	    __from_next = __from_chunk_end;
+	    __to_next += __conv;
+	  }
+
+	if (__from_next < __from_end && __ret == ok)
+	  {
+	    extern_type __buf[MB_LEN_MAX];
+	    __tmp_state = __state;
+	    const size_t __conv2 = wcrtomb(__buf, *__from_next, &__tmp_state);
+	    if (__conv2 > static_cast<size_t>(__to_end - __to_next))
+	      __ret = partial;
+	    else
+	      {
+		memcpy(__to_next, __buf, __conv2);
+		__state = __tmp_state;
+		__to_next += __conv2;
+		++__from_next;
+	      }
+	  }
+      }
+
+    uselocale((locale_t)__old);
+
+    return __ret;
+  }
+
+  codecvt_base::result
+  codecvt<wchar_t, char, mbstate_t>::
+  do_in(state_type& __state, const extern_type* __from,
+	const extern_type* __from_end, const extern_type*& __from_next,
+	intern_type* __to, intern_type* __to_end,
+	intern_type*& __to_next) const
+  {
+    result __ret = ok;
+    state_type __tmp_state(__state);
+
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
+
+    // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
+    // in case we store a L'\0' and then continue, in a loop.
+    // NB: mbsnrtowcs is a GNU extension
+    for (__from_next = __from, __to_next = __to;
+	 __from_next < __from_end && __to_next < __to_end
+	 && __ret == ok;)
+      {
+	const extern_type* __from_chunk_end;
+	__from_chunk_end = static_cast<const extern_type*>(memchr(__from_next, '\0',
+								  __from_end
+								  - __from_next));
+	if (!__from_chunk_end)
+	  __from_chunk_end = __from_end;
+
+	__from = __from_next;
+	size_t __conv = mbsnrtowcs(__to_next, &__from_next,
+				   __from_chunk_end - __from_next,
+				   __to_end - __to_next, &__state);
+	if (__conv == static_cast<size_t>(-1))
+	  {
+	    // In case of error, in order to stop at the exact place we
+	    // have to start again from the beginning with a series of
+	    // mbrtowc.
+	    for (;; ++__to_next, __from += __conv)
+	      {
+		__conv = mbrtowc(__to_next, __from, __from_end - __from,
+				 &__tmp_state);
+		if (__conv == static_cast<size_t>(-1)
+		    || __conv == static_cast<size_t>(-2))
+		  break;
+	      }
+	    __from_next = __from;
+	    __state = __tmp_state;
+	    __ret = error;
+	  }
+	else if (__from_next && __from_next < __from_chunk_end)
+	  {
+	    // It is unclear what to return in this case (see DR 382).
+	    __to_next += __conv;
+	    __ret = partial;
+	  }
+	else
+	  {
+	    __from_next = __from_chunk_end;
+	    __to_next += __conv;
+	  }
+
+	if (__from_next < __from_end && __ret == ok)
+	  {
+	    if (__to_next < __to_end)
+	      {
+		// XXX Probably wrong for stateful encodings
+		__tmp_state = __state;
+		++__from_next;
+		*__to_next++ = L'\0';
+	      }
+	    else
+	      __ret = partial;
+	  }
+      }
+
+    uselocale((locale_t)__old);
+
+    return __ret;
+  }
+
+  int
+  codecvt<wchar_t, char, mbstate_t>::
+  do_encoding() const throw()
+  {
+    // XXX This implementation assumes that the encoding is
+    // stateless and is either single-byte or variable-width.
+    int __ret = 0;
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
+    if (MB_CUR_MAX == 1)
+      __ret = 1;
+    uselocale((locale_t)__old);
+    return __ret;
+  }
+
+  int
+  codecvt<wchar_t, char, mbstate_t>::
+  do_max_length() const throw()
+  {
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
+    // XXX Probably wrong for stateful encodings.
+    int __ret = MB_CUR_MAX;
+    uselocale((locale_t)__old);
+    return __ret;
+  }
+
+  int
+  codecvt<wchar_t, char, mbstate_t>::
+  do_length(state_type& __state, const extern_type* __from,
+	    const extern_type* __end, size_t __max) const
+  {
+    int __ret = 0;
+    state_type __tmp_state(__state);
+
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_codecvt);
+
+    // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
+    // in case we advance past it and then continue, in a loop.
+    // NB: mbsnrtowcs is a GNU extension
+
+    // A dummy internal buffer is needed in order for mbsnrtocws to consider
+    // its fourth parameter (it wouldn't with NULL as first parameter).
+    wchar_t* __to = static_cast<wchar_t*>(__builtin_alloca(sizeof(wchar_t)
+							   * __max));
+    while (__from < __end && __max)
+      {
+	const extern_type* __from_chunk_end;
+	__from_chunk_end = static_cast<const extern_type*>(memchr(__from, '\0',
+								  __end
+								  - __from));
+	if (!__from_chunk_end)
+	  __from_chunk_end = __end;
+
+	const extern_type* __tmp_from = __from;
+	size_t __conv = mbsnrtowcs(__to, &__from,
+				   __from_chunk_end - __from,
+				   __max, &__state);
+	if (__conv == static_cast<size_t>(-1))
+	  {
+	    // In case of error, in order to stop at the exact place we
+	    // have to start again from the beginning with a series of
+	    // mbrtowc.
+	    for (__from = __tmp_from;; __from += __conv)
+	      {
+		__conv = mbrtowc(0, __from, __end - __from,
+				 &__tmp_state);
+		if (__conv == static_cast<size_t>(-1)
+		    || __conv == static_cast<size_t>(-2))
+		  break;
+	      }
+	    __state = __tmp_state;
+	    __ret += __from - __tmp_from;
+	    break;
+	  }
+	if (!__from)
+	  __from = __from_chunk_end;
+
+	__ret += __from - __tmp_from;
+	__max -= __conv;
+
+	if (__from < __end && __max)
+	  {
+	    // XXX Probably wrong for stateful encodings
+	    __tmp_state = __state;
+	    ++__from;
+	    ++__ret;
+	    --__max;
+	  }
+      }
+
+    uselocale((locale_t)__old);
+
+    return __ret;
+  }
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/collate_members.cc b/libstdc++-v3/config/locale/xpg7/collate_members.cc
new file mode 100644
index 00000000000..9a586ce7599
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/collate_members.cc
@@ -0,0 +1,74 @@
+// std::collate implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2015-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.2.4.1.2  collate virtual functions
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+
+#include <locale>
+#include <cstring>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // These are basically extensions to char_traits, and perhaps should
+  // be put there instead of here.
+  template<>
+    int
+    collate<char>::_M_compare(const char* __one,
+			      const char* __two) const throw()
+    {
+      int __cmp = strcoll_l(__one, __two, (locale_t)_M_c_locale_collate);
+      return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
+    }
+
+  template<>
+    size_t
+    collate<char>::_M_transform(char* __to, const char* __from,
+				size_t __n) const throw()
+    { return strxfrm_l(__to, __from, __n, (locale_t)_M_c_locale_collate); }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template<>
+    int
+    collate<wchar_t>::_M_compare(const wchar_t* __one,
+				 const wchar_t* __two) const throw()
+    {
+      int __cmp = wcscoll_l(__one, __two, (locale_t)_M_c_locale_collate);
+      return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
+    }
+
+  template<>
+    size_t
+    collate<wchar_t>::_M_transform(wchar_t* __to, const wchar_t* __from,
+				   size_t __n) const throw()
+    { return wcsxfrm_l(__to, __from, __n, (locale_t)_M_c_locale_collate); }
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/ctype_members.cc b/libstdc++-v3/config/locale/xpg7/ctype_members.cc
new file mode 100644
index 00000000000..a87a603fa27
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/ctype_members.cc
@@ -0,0 +1,287 @@
+// std::ctype implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2014-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.2.1.1.2  ctype virtual functions.
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+// Modified for XPG7 by Clément Chigot <clement.chigot@atos.net>
+
+#include <locale>
+#include <cstring>
+#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)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // NB: The other ctype<char> specializations are in src/locale.cc and
+  // various /config/os/* files.
+  ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
+  : ctype<char>(0, false, __refs)
+  {
+    if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
+      {
+	this->_S_destroy_c_locale(this->_M_c_locale_ctype);
+	this->_S_create_c_locale(this->_M_c_locale_ctype, __s);
+      }
+  }
+
+  ctype_byname<char>::~ctype_byname()
+  { }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  ctype<wchar_t>::__wmask_type
+  ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw()
+  {
+    __wmask_type __ret;
+    switch (__m)
+      {
+      case space:
+	__ret = wctype_l("space", (locale_t)_M_c_locale_ctype);
+	break;
+      case print:
+	__ret = wctype_l("print", (locale_t)_M_c_locale_ctype);
+	break;
+      case cntrl:
+	__ret = wctype_l("cntrl", (locale_t)_M_c_locale_ctype);
+	break;
+      case upper:
+	__ret = wctype_l("upper", (locale_t)_M_c_locale_ctype);
+	break;
+      case lower:
+	__ret = wctype_l("lower", (locale_t)_M_c_locale_ctype);
+	break;
+      case alpha:
+	__ret = wctype_l("alpha", (locale_t)_M_c_locale_ctype);
+	break;
+      case digit:
+	__ret = wctype_l("digit", (locale_t)_M_c_locale_ctype);
+	break;
+      case punct:
+	__ret = wctype_l("punct", (locale_t)_M_c_locale_ctype);
+	break;
+      case xdigit:
+	__ret = wctype_l("xdigit", (locale_t)_M_c_locale_ctype);
+	break;
+      case alnum:
+	__ret = wctype_l("alnum", (locale_t)_M_c_locale_ctype);
+	break;
+      case graph:
+	__ret = wctype_l("graph", (locale_t)_M_c_locale_ctype);
+	break;
+      case blank:
+	__ret = wctype_l("blank", (locale_t)_M_c_locale_ctype);
+	break;
+      default:
+	__ret = __wmask_type();
+      }
+    return __ret;
+  }
+
+  wchar_t
+  ctype<wchar_t>::do_toupper(wchar_t __c) const
+  { return towupper_l(__c, (locale_t)_M_c_locale_ctype); }
+
+  const wchar_t*
+  ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
+  {
+    while (__lo < __hi)
+      {
+	*__lo = towupper_l(*__lo, (locale_t)_M_c_locale_ctype);
+	++__lo;
+      }
+    return __hi;
+  }
+
+  wchar_t
+  ctype<wchar_t>::do_tolower(wchar_t __c) const
+  { return towlower_l(__c, (locale_t)_M_c_locale_ctype); }
+
+  const wchar_t*
+  ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
+  {
+    while (__lo < __hi)
+      {
+	*__lo = towlower_l(*__lo, (locale_t)_M_c_locale_ctype);
+	++__lo;
+      }
+    return __hi;
+  }
+
+#if !defined(__DragonFly__) && !defined(__FreeBSD__)
+  bool
+  ctype<wchar_t>::
+  do_is(mask __m, char_type __c) const
+  {
+    bool __ret = false;
+    const size_t __bitmasksize = 15;
+    for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
+      if (__m & _M_bit[__bitcur]
+	  && iswctype_l(__c, _M_wmask[__bitcur], (locale_t)_M_c_locale_ctype))
+	{
+	  __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)
+      {
+	const size_t __bitmasksize = 15;
+	mask __m = 0;
+	for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
+	  if (iswctype_l(*__lo, _M_wmask[__bitcur], (locale_t)_M_c_locale_ctype))
+	    __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
+  { return _M_widen[static_cast<unsigned char>(__c)]; }
+
+  const char*
+  ctype<wchar_t>::
+  do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
+  {
+    while (__lo < __hi)
+      {
+	*__dest = _M_widen[static_cast<unsigned char>(*__lo)];
+	++__lo;
+	++__dest;
+      }
+    return __hi;
+  }
+
+  char
+  ctype<wchar_t>::
+  do_narrow(wchar_t __wc, char __dfault) const
+  {
+    if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
+      return _M_narrow[__wc];
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_ctype);
+    const int __c = wctob(__wc);
+    uselocale((locale_t)__old);
+    return (__c == EOF ? __dfault : static_cast<char>(__c));
+  }
+
+  const wchar_t*
+  ctype<wchar_t>::
+  do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
+	    char* __dest) const
+  {
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_ctype);
+    if (_M_narrow_ok)
+      while (__lo < __hi)
+	{
+	  if (*__lo >= 0 && *__lo < 128)
+	    *__dest = _M_narrow[*__lo];
+	  else
+	    {
+	      const int __c = wctob(*__lo);
+	      *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
+	    }
+	  ++__lo;
+	  ++__dest;
+	}
+    else
+      while (__lo < __hi)
+	{
+	  const int __c = wctob(*__lo);
+	  *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
+	  ++__lo;
+	  ++__dest;
+	}
+    uselocale((locale_t)__old);
+    return __hi;
+  }
+
+  void
+  ctype<wchar_t>::_M_initialize_ctype() throw()
+  {
+    __c_locale __old = (__c_locale)uselocale((locale_t)_M_c_locale_ctype);
+    wint_t __i;
+    for (__i = 0; __i < 128; ++__i)
+      {
+	const int __c = wctob(__i);
+	if (__c == EOF)
+	  break;
+	else
+	  _M_narrow[__i] = static_cast<char>(__c);
+      }
+    if (__i == 128)
+      _M_narrow_ok = true;
+    else
+      _M_narrow_ok = false;
+    for (size_t __j = 0;
+	 __j < sizeof(_M_widen) / sizeof(wint_t); ++__j)
+      _M_widen[__j] = btowc(__j);
+
+    for (size_t __k = 0; __k <= 15; ++__k)
+      {
+	_M_bit[__k] = static_cast<mask>(_ISbit(__k));
+	_M_wmask[__k] = _M_convert_to_wmask(_M_bit[__k]);
+      }
+    uselocale((locale_t)__old);
+  }
+#endif //  _GLIBCXX_USE_WCHAR_T
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/monetary_members.cc b/libstdc++-v3/config/locale/xpg7/monetary_members.cc
new file mode 100644
index 00000000000..4dc35633fd2
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/monetary_members.cc
@@ -0,0 +1,942 @@
+// std::moneypunct implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2015-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.2.6.3.2  moneypunct virtual functions
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+// Modified for XPG7 by Clément Chigot <clement.chigot@atos.net>
+
+// Solaris 11.4 doesn't make C99 members of struct lconv visible for C++11
+// without this.
+#define _LCONV_C99
+#include <locale>
+#include <cstring>
+
+#ifdef _GLIBCXX_HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+// This file might be compiled twice, but we only want to define the members
+// of money_base once.
+#if ! _GLIBCXX_USE_CXX11_ABI
+
+  // Construct and return valid pattern consisting of some combination of:
+  // space none symbol sign value
+  money_base::pattern
+  money_base::_S_construct_pattern(char __precedes, char __space,
+				   char __posn) throw()
+  {
+    pattern __ret;
+
+    // This insanely complicated routine attempts to construct a valid
+    // pattern for use with moneypunct. A couple of invariants:
+
+    // if (__precedes) symbol -> value
+    // else value -> symbol
+
+    // if (__space) space
+    // else none
+
+    // none == never first
+    // space never first or last
+
+    // Any elegant implementations of this are welcome.
+    switch (__posn)
+      {
+      case 0:
+      case 1:
+	// 1 The sign precedes the value and symbol.
+	__ret.field[0] = sign;
+	if (__space)
+	  {
+	    // Pattern starts with sign.
+	    if (__precedes)
+	      {
+		__ret.field[1] = symbol;
+		__ret.field[3] = value;
+	      }
+	    else
+	      {
+		__ret.field[1] = value;
+		__ret.field[3] = symbol;
+	      }
+	    __ret.field[2] = space;
+	  }
+	else
+	  {
+	    // Pattern starts with sign and ends with none.
+	    if (__precedes)
+	      {
+		__ret.field[1] = symbol;
+		__ret.field[2] = value;
+	      }
+	    else
+	      {
+		__ret.field[1] = value;
+		__ret.field[2] = symbol;
+	      }
+	    __ret.field[3] = none;
+	  }
+	break;
+      case 2:
+	// 2 The sign follows the value and symbol.
+	if (__space)
+	  {
+	    // Pattern either ends with sign.
+	    if (__precedes)
+	      {
+		__ret.field[0] = symbol;
+		__ret.field[2] = value;
+	      }
+	    else
+	      {
+		__ret.field[0] = value;
+		__ret.field[2] = symbol;
+	      }
+	    __ret.field[1] = space;
+	    __ret.field[3] = sign;
+	  }
+	else
+	  {
+	    // Pattern ends with sign then none.
+	    if (__precedes)
+	      {
+		__ret.field[0] = symbol;
+		__ret.field[1] = value;
+	      }
+	    else
+	      {
+		__ret.field[0] = value;
+		__ret.field[1] = symbol;
+	      }
+	    __ret.field[2] = sign;
+	    __ret.field[3] = none;
+	  }
+	break;
+      case 3:
+	// 3 The sign immediately precedes the symbol.
+	if (__precedes)
+	  {
+	    __ret.field[0] = sign;
+	    __ret.field[1] = symbol;
+	    if (__space)
+	      {
+		__ret.field[2] = space;
+		__ret.field[3] = value;
+	      }
+	    else
+	      {
+		__ret.field[2] = value;
+		__ret.field[3] = none;
+	      }
+	  }
+	else
+	  {
+	    __ret.field[0] = value;
+	    if (__space)
+	      {
+		__ret.field[1] = space;
+		__ret.field[2] = sign;
+		__ret.field[3] = symbol;
+	      }
+	    else
+	      {
+		__ret.field[1] = sign;
+		__ret.field[2] = symbol;
+		__ret.field[3] = none;
+	      }
+	  }
+	break;
+      case 4:
+	// 4 The sign immediately follows the symbol.
+	if (__precedes)
+	  {
+	    __ret.field[0] = symbol;
+	    __ret.field[1] = sign;
+	    if (__space)
+	      {
+		__ret.field[2] = space;
+		__ret.field[3] = value;
+	      }
+	    else
+	      {
+		__ret.field[2] = value;
+		__ret.field[3] = none;
+	      }
+	  }
+	else
+	  {
+	    __ret.field[0] = value;
+	    if (__space)
+	      {
+		__ret.field[1] = space;
+		__ret.field[2] = symbol;
+		__ret.field[3] = sign;
+	      }
+	    else
+	      {
+		__ret.field[1] = symbol;
+		__ret.field[2] = sign;
+		__ret.field[3] = none;
+	      }
+	  }
+	break;
+      default:
+	__ret = pattern();
+      }
+    return __ret;
+  }
+#endif
+
+  template<>
+    void
+    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
+						     const char*)
+    {
+      if (!_M_data)
+	_M_data = new __moneypunct_cache<char, true>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_data->_M_decimal_point = '.';
+	  _M_data->_M_thousands_sep = ',';
+	  _M_data->_M_grouping = "";
+	  _M_data->_M_grouping_size = 0;
+	  _M_data->_M_use_grouping = false;
+	  _M_data->_M_curr_symbol = "";
+	  _M_data->_M_curr_symbol_size = 0;
+	  _M_data->_M_positive_sign = "";
+	  _M_data->_M_positive_sign_size = 0;
+	  _M_data->_M_negative_sign = "";
+	  _M_data->_M_negative_sign_size = 0;
+	  _M_data->_M_frac_digits = 0;
+	  _M_data->_M_pos_format = money_base::_S_default_pattern;
+	  _M_data->_M_neg_format = money_base::_S_default_pattern;
+
+	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
+	    _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
+	}
+      else
+	{
+	  // Named locale.
+#ifdef _GLIBCXX_HAVE_LOCALECONV_L
+	  lconv* lc = localeconv_l((locale_t) __cloc);
+#else
+	  __c_locale __old = uselocale(__cloc);
+	  lconv* lc = localeconv();
+#endif
+
+	  // Check for NULL, which implies no fractional digits.
+	  if (lc->mon_decimal_point == NULL ||
+	      lc->mon_decimal_point[0] == '\0')
+	    {
+	      // Like in "C" locale.
+	      _M_data->_M_frac_digits = 0;
+	      _M_data->_M_decimal_point = '.';
+	    }
+	  else
+	    {
+	      _M_data->_M_decimal_point = lc->mon_decimal_point[0];
+	      _M_data->_M_frac_digits = lc->int_frac_digits;
+	    }
+
+	  const char* __cgroup = lc->mon_grouping;
+	  const char* __cpossign = lc->positive_sign;
+	  const char* __cnegsign = lc->negative_sign;
+	  // _Intl == true
+	  const char* __ccurr = lc->int_curr_symbol;
+
+	  char* __group = 0;
+	  char* __ps = 0;
+	  char* __ns = 0;
+	  const char __nposn = lc->int_n_sign_posn;
+	  __try
+	    {
+	      size_t __len;
+
+	      // Check for NULL, which implies no grouping.
+	      if (lc->mon_thousands_sep == NULL ||
+	          lc->mon_thousands_sep[0] == '\0')
+		{
+		  // Like in "C" locale.
+		  _M_data->_M_grouping = "";
+		  _M_data->_M_grouping_size = 0;
+		  _M_data->_M_use_grouping = false;
+		  _M_data->_M_thousands_sep = ',';
+		}
+	      else
+		{
+	          _M_data->_M_thousands_sep = lc->mon_thousands_sep[0];
+
+		  __len = strlen(__cgroup);
+		  if (__len)
+		    {
+		      __group = new char[__len + 1];
+		      memcpy(__group, __cgroup, __len + 1);
+		      _M_data->_M_grouping = __group;
+		    }
+		  else
+		    {
+		      _M_data->_M_grouping = "";
+		      _M_data->_M_use_grouping = false;
+		    }
+		  _M_data->_M_grouping_size = __len;
+		}
+
+	      __len = strlen(__cpossign);
+	      if (__len)
+		{
+		  __ps = new char[__len + 1];
+		  memcpy(__ps, __cpossign, __len + 1);
+		  _M_data->_M_positive_sign = __ps;
+		}
+	      else
+		_M_data->_M_positive_sign = "";
+	      _M_data->_M_positive_sign_size = __len;
+
+	      if (!__nposn)
+		{
+		  _M_data->_M_negative_sign = "()";
+		  _M_data->_M_negative_sign_size = 2;
+		}
+	      else
+		{
+		  __len = strlen(__cnegsign);
+		  if (__len)
+		    {
+		      __ns = new char[__len + 1];
+		      memcpy(__ns, __cnegsign, __len + 1);
+		      _M_data->_M_negative_sign = __ns;
+		    }
+		  else
+		    _M_data->_M_negative_sign = "";
+		  _M_data->_M_negative_sign_size = __len;
+		}
+
+	      __len = strlen(__ccurr);
+	      if (__len)
+		{
+		  char* __curr = new char[__len + 1];
+		  memcpy(__curr, __ccurr, __len + 1);
+		  _M_data->_M_curr_symbol = __curr;
+		}
+	      else
+		_M_data->_M_curr_symbol = "";
+	      _M_data->_M_curr_symbol_size = __len;
+	    }
+	  __catch(...)
+	    {
+	      delete _M_data;
+	      _M_data = 0;
+	      delete [] __group;
+	      delete [] __ps;
+	      delete [] __ns;
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+	      uselocale(__old);
+#endif
+	      __throw_exception_again;
+	    }
+
+	  char __pprecedes = lc->int_p_cs_precedes;
+	  char __pspace = lc->int_p_sep_by_space;
+	  char __pposn = lc->int_p_sign_posn;
+	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
+							__pposn);
+	  char __nprecedes = lc->int_n_cs_precedes;
+	  char __nspace = lc->int_n_sep_by_space;
+	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
+							__nposn);
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+	  uselocale(__old);
+#endif
+	}
+    }
+
+  template<>
+    void
+    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
+						      const char*)
+    {
+      if (!_M_data)
+	_M_data = new __moneypunct_cache<char, false>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_data->_M_decimal_point = '.';
+	  _M_data->_M_thousands_sep = ',';
+	  _M_data->_M_grouping = "";
+	  _M_data->_M_grouping_size = 0;
+	  _M_data->_M_use_grouping = false;
+	  _M_data->_M_curr_symbol = "";
+	  _M_data->_M_curr_symbol_size = 0;
+	  _M_data->_M_positive_sign = "";
+	  _M_data->_M_positive_sign_size = 0;
+	  _M_data->_M_negative_sign = "";
+	  _M_data->_M_negative_sign_size = 0;
+	  _M_data->_M_frac_digits = 0;
+	  _M_data->_M_pos_format = money_base::_S_default_pattern;
+	  _M_data->_M_neg_format = money_base::_S_default_pattern;
+
+	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
+	    _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
+	}
+      else
+	{
+	  // Named locale.
+#ifdef _GLIBCXX_HAVE_LOCALECONV_L
+	  lconv* lc = localeconv_l((locale_t) __cloc);
+#else
+	  __c_locale __old = uselocale(__cloc);
+	  lconv* lc = localeconv();
+#endif
+
+	  // Check for NULL, which implies no fractional digits.
+	  if (lc->mon_decimal_point == NULL ||
+	      lc->mon_decimal_point[0] == '\0')
+	    {
+	      // Like in "C" locale.
+	      _M_data->_M_frac_digits = 0;
+	      _M_data->_M_decimal_point = '.';
+	    }
+	  else
+	    {
+	      _M_data->_M_decimal_point = lc->mon_decimal_point[0];
+	      _M_data->_M_frac_digits = lc->frac_digits;
+            }
+
+	  const char* __cgroup = lc->mon_grouping;
+	  const char* __cpossign = lc->positive_sign;
+	  const char* __cnegsign = lc->negative_sign;
+	  // _Intl == false
+	  const char* __ccurr = lc->currency_symbol;
+
+	  char* __group = 0;
+	  char* __ps = 0;
+	  char* __ns = 0;
+	  const char __nposn = lc->n_sign_posn;
+	  __try
+	    {
+	      size_t __len;
+
+	      // Check for NULL, which implies no grouping.
+	      if (lc->mon_thousands_sep == NULL ||
+	          lc->mon_thousands_sep[0] == '\0')
+		{
+		  // Like in "C" locale.
+		  _M_data->_M_grouping = "";
+		  _M_data->_M_grouping_size = 0;
+		  _M_data->_M_use_grouping = false;
+		  _M_data->_M_thousands_sep = ',';
+		}
+	      else
+		{
+	          _M_data->_M_thousands_sep = lc->mon_thousands_sep[0];
+
+		  __len = strlen(__cgroup);
+		  if (__len)
+		    {
+		      __group = new char[__len + 1];
+		      memcpy(__group, __cgroup, __len + 1);
+		      _M_data->_M_grouping = __group;
+		    }
+		  else
+		    {
+		      _M_data->_M_grouping = "";
+		      _M_data->_M_use_grouping = false;
+		    }
+		  _M_data->_M_grouping_size = __len;
+		}
+
+	      __len = strlen(__cpossign);
+	      if (__len)
+		{
+		  __ps = new char[__len + 1];
+		  memcpy(__ps, __cpossign, __len + 1);
+		  _M_data->_M_positive_sign = __ps;
+		}
+	      else
+		_M_data->_M_positive_sign = "";
+	      _M_data->_M_positive_sign_size = __len;
+
+	      if (!__nposn)
+		{
+		  _M_data->_M_negative_sign = "()";
+		  _M_data->_M_negative_sign_size = 2;
+		}
+	      else
+		{
+		  __len = strlen(__cnegsign);
+		  if (__len)
+		    {
+		      __ns = new char[__len + 1];
+		      memcpy(__ns, __cnegsign, __len + 1);
+		      _M_data->_M_negative_sign = __ns;
+		    }
+		  else
+		    _M_data->_M_negative_sign = "";
+		  _M_data->_M_negative_sign_size = __len;
+		}
+
+	      __len = strlen(__ccurr);
+	      if (__len)
+		{
+		  char* __curr = new char[__len + 1];
+		  memcpy(__curr, __ccurr, __len + 1);
+		  _M_data->_M_curr_symbol = __curr;
+		}
+	      else
+		_M_data->_M_curr_symbol = "";
+	      _M_data->_M_curr_symbol_size = __len;
+	    }
+	  __catch(...)
+	    {
+	      delete _M_data;
+	      _M_data = 0;
+	      delete [] __group;
+	      delete [] __ps;
+	      delete [] __ns;
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+	      uselocale(__old);
+#endif
+	      __throw_exception_again;
+	    }
+
+	  char __pprecedes = lc->p_cs_precedes;
+	  char __pspace = lc->p_sep_by_space;
+	  char __pposn = lc->p_sign_posn;
+	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
+							__pposn);
+	  char __nprecedes = lc->n_cs_precedes;
+	  char __nspace = lc->n_sep_by_space;
+	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
+							__nposn);
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+	  uselocale(__old);
+#endif
+	}
+    }
+
+  template<>
+    moneypunct<char, true>::~moneypunct()
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      if (_M_data->_M_positive_sign_size)
+	delete [] _M_data->_M_positive_sign;
+      if (_M_data->_M_negative_sign_size
+          && strcmp(_M_data->_M_negative_sign, "()") != 0)
+	delete [] _M_data->_M_negative_sign;
+      if (_M_data->_M_curr_symbol_size)
+	delete [] _M_data->_M_curr_symbol;
+      delete _M_data;
+    }
+
+  template<>
+    moneypunct<char, false>::~moneypunct()
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      if (_M_data->_M_positive_sign_size)
+	delete [] _M_data->_M_positive_sign;
+      if (_M_data->_M_negative_sign_size
+          && strcmp(_M_data->_M_negative_sign, "()") != 0)
+	delete [] _M_data->_M_negative_sign;
+      if (_M_data->_M_curr_symbol_size)
+	delete [] _M_data->_M_curr_symbol;
+      delete _M_data;
+    }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template<>
+    void
+    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
+							const char*)
+    {
+      if (!_M_data)
+	_M_data = new __moneypunct_cache<wchar_t, true>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_data->_M_decimal_point = L'.';
+	  _M_data->_M_thousands_sep = L',';
+	  _M_data->_M_grouping = "";
+	  _M_data->_M_grouping_size = 0;
+	  _M_data->_M_use_grouping = false;
+	  _M_data->_M_curr_symbol = L"";
+	  _M_data->_M_curr_symbol_size = 0;
+	  _M_data->_M_positive_sign = L"";
+	  _M_data->_M_positive_sign_size = 0;
+	  _M_data->_M_negative_sign = L"";
+	  _M_data->_M_negative_sign_size = 0;
+	  _M_data->_M_frac_digits = 0;
+	  _M_data->_M_pos_format = money_base::_S_default_pattern;
+	  _M_data->_M_neg_format = money_base::_S_default_pattern;
+
+	  // Use ctype::widen code without the facet...
+	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
+	    _M_data->_M_atoms[__i] =
+	      static_cast<wchar_t>(money_base::_S_atoms[__i]);
+	}
+      else
+	{
+	  // Named locale.
+	  // uselocale is needed for mbsrtowcs.
+	  __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
+#ifdef _GLIBCXX_HAVE_LOCALECONV_L
+	  lconv* lc = localeconv_l((locale_t) __cloc);
+#else
+	  lconv* lc = localeconv();
+#endif
+
+	  // Check for NULL, which implies no fractional digits.
+	  if (lc->mon_decimal_point == NULL ||
+	      lc->mon_decimal_point[0] == '\0')
+	    {
+	      // Like in "C" locale.
+	      _M_data->_M_frac_digits = 0;
+	      _M_data->_M_decimal_point = L'.';
+	    }
+	  else
+	    {
+	      _M_data->_M_frac_digits = lc->int_frac_digits;
+	      _M_data->_M_decimal_point = (wchar_t)lc->mon_decimal_point[0];
+            }
+
+	  const char* __cgroup = lc->mon_grouping;
+	  const char* __cpossign = lc->positive_sign;
+	  const char* __cnegsign = lc->negative_sign;
+	  const char* __ccurr = lc->int_curr_symbol;
+
+	  char* __group = 0;
+	  wchar_t* __wcs_ps = 0;
+	  wchar_t* __wcs_ns = 0;
+	  const char __nposn = lc->int_n_sign_posn;
+	  __try
+	    {
+	      size_t __len;
+
+	      // Check for NULL, which implies no grouping.
+	      if (lc->mon_thousands_sep == NULL ||
+	          lc->mon_thousands_sep[0] == '\0')
+		{
+		  // Like in "C" locale.
+		  _M_data->_M_grouping = "";
+		  _M_data->_M_grouping_size = 0;
+		  _M_data->_M_use_grouping = false;
+		  _M_data->_M_thousands_sep = L',';
+		}
+	      else
+		{
+		  _M_data->_M_thousands_sep =
+			(wchar_t)lc->mon_thousands_sep[0];
+		  __len = strlen(__cgroup);
+		  if (__len)
+		    {
+		      __group = new char[__len + 1];
+		      memcpy(__group, __cgroup, __len + 1);
+		      _M_data->_M_grouping = __group;
+		    }
+		  else
+		    {
+		      _M_data->_M_grouping = "";
+		      _M_data->_M_use_grouping = false;
+		    }
+		  _M_data->_M_grouping_size = __len;
+		}
+
+	      mbstate_t __state;
+	      __len = strlen(__cpossign);
+	      if (__len)
+		{
+		  memset(&__state, 0, sizeof(mbstate_t));
+		  __wcs_ps = new wchar_t[__len + 1];
+		  mbsrtowcs(__wcs_ps, &__cpossign, __len + 1, &__state);
+		  _M_data->_M_positive_sign = __wcs_ps;
+		}
+	      else
+		_M_data->_M_positive_sign = L"";
+	      _M_data->_M_positive_sign_size =
+		wcslen(_M_data->_M_positive_sign);
+
+	      __len = strlen(__cnegsign);
+	      if (!__nposn)
+		_M_data->_M_negative_sign = L"()";
+	      else if (__len)
+		{
+		  memset(&__state, 0, sizeof(mbstate_t));
+		  __wcs_ns = new wchar_t[__len + 1];
+		  mbsrtowcs(__wcs_ns, &__cnegsign, __len + 1, &__state);
+		  _M_data->_M_negative_sign = __wcs_ns;
+		}
+	      else
+		_M_data->_M_negative_sign = L"";
+	      _M_data->_M_negative_sign_size =
+		wcslen(_M_data->_M_negative_sign);
+
+	      // _Intl == true.
+	      __len = strlen(__ccurr);
+	      if (__len)
+		{
+		  memset(&__state, 0, sizeof(mbstate_t));
+		  wchar_t* __wcs = new wchar_t[__len + 1];
+		  mbsrtowcs(__wcs, &__ccurr, __len + 1, &__state);
+		  _M_data->_M_curr_symbol = __wcs;
+		}
+	      else
+		_M_data->_M_curr_symbol = L"";
+	      _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
+	    }
+	  __catch(...)
+	    {
+	      delete _M_data;
+	      _M_data = 0;
+	      delete [] __group;
+	      delete [] __wcs_ps;
+	      delete [] __wcs_ns;
+	      uselocale((locale_t)__old);
+	      __throw_exception_again;
+	    }
+
+	  char __pprecedes = lc->int_p_cs_precedes;
+	  char __pspace = lc->int_p_sep_by_space;
+	  char __pposn = lc->int_p_sign_posn;
+	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
+							__pposn);
+	  char __nprecedes = lc->int_n_cs_precedes;
+	  char __nspace = lc->int_n_sep_by_space;
+	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
+							__nposn);
+
+	  uselocale((locale_t)__old);
+	}
+    }
+
+  template<>
+  void
+  moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
+						       const char*)
+  {
+    if (!_M_data)
+      _M_data = new __moneypunct_cache<wchar_t, false>;
+
+    if (!__cloc)
+	{
+	  // "C" locale
+	  _M_data->_M_decimal_point = L'.';
+	  _M_data->_M_thousands_sep = L',';
+	  _M_data->_M_grouping = "";
+          _M_data->_M_grouping_size = 0;
+	  _M_data->_M_use_grouping = false;
+	  _M_data->_M_curr_symbol = L"";
+	  _M_data->_M_curr_symbol_size = 0;
+	  _M_data->_M_positive_sign = L"";
+	  _M_data->_M_positive_sign_size = 0;
+	  _M_data->_M_negative_sign = L"";
+	  _M_data->_M_negative_sign_size = 0;
+	  _M_data->_M_frac_digits = 0;
+	  _M_data->_M_pos_format = money_base::_S_default_pattern;
+	  _M_data->_M_neg_format = money_base::_S_default_pattern;
+
+	  // Use ctype::widen code without the facet...
+	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
+	    _M_data->_M_atoms[__i] =
+	      static_cast<wchar_t>(money_base::_S_atoms[__i]);
+	}
+      else
+	{
+	  // Named locale.
+	  // uselocale is needed for mbsrtowcs.
+	  __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
+#ifdef _GLIBCXX_HAVE_LOCALECONV_L
+	  lconv* lc = localeconv_l((locale_t) __cloc);
+#else
+	  lconv* lc = localeconv();
+#endif
+
+	  // Check for NULL, which implies no fractional digits.
+	  if (lc->mon_decimal_point == NULL ||
+	      lc->mon_decimal_point[0] == '\0')
+	    {
+	      // Like in "C" locale.
+	      _M_data->_M_frac_digits = 0;
+	      _M_data->_M_decimal_point = L'.';
+	    }
+	  else
+	    {
+	      _M_data->_M_frac_digits = lc->frac_digits;
+	      _M_data->_M_decimal_point = (wchar_t)lc->mon_decimal_point[0];
+            }
+
+	  const char* __cgroup = lc->mon_grouping;
+	  const char* __cpossign = lc->positive_sign;
+	  const char* __cnegsign = lc->negative_sign;
+	  const char* __ccurr = lc->currency_symbol;
+
+	  char* __group = 0;
+	  wchar_t* __wcs_ps = 0;
+	  wchar_t* __wcs_ns = 0;
+	  const char __nposn = lc->n_sign_posn;
+	  __try
+            {
+	      size_t __len;
+
+	      // Check for NULL, which implies no grouping.
+	      if (lc->mon_thousands_sep == NULL ||
+	          lc->mon_thousands_sep[0] == '\0')
+		{
+		  // Like in "C" locale.
+		  _M_data->_M_grouping = "";
+		  _M_data->_M_grouping_size = 0;
+		  _M_data->_M_use_grouping = false;
+		  _M_data->_M_thousands_sep = L',';
+		}
+	      else
+		{
+		  _M_data->_M_thousands_sep =
+			(wchar_t)lc->mon_thousands_sep[0];
+		  __len = strlen(__cgroup);
+		  if (__len)
+		    {
+		      __group = new char[__len + 1];
+		      memcpy(__group, __cgroup, __len + 1);
+		      _M_data->_M_grouping = __group;
+		    }
+		  else
+		    {
+		      _M_data->_M_grouping = "";
+		      _M_data->_M_use_grouping = false;
+		    }
+		  _M_data->_M_grouping_size = __len;
+		}
+
+              mbstate_t __state;
+              __len = strlen(__cpossign);
+              if (__len)
+                {
+		  memset(&__state, 0, sizeof(mbstate_t));
+		  __wcs_ps = new wchar_t[__len + 1];
+		  mbsrtowcs(__wcs_ps, &__cpossign, __len + 1, &__state);
+		  _M_data->_M_positive_sign = __wcs_ps;
+		}
+	      else
+		_M_data->_M_positive_sign = L"";
+              _M_data->_M_positive_sign_size =
+		wcslen(_M_data->_M_positive_sign);
+
+	      __len = strlen(__cnegsign);
+	      if (!__nposn)
+		_M_data->_M_negative_sign = L"()";
+	      else if (__len)
+		{
+		  memset(&__state, 0, sizeof(mbstate_t));
+		  __wcs_ns = new wchar_t[__len + 1];
+		  mbsrtowcs(__wcs_ns, &__cnegsign, __len + 1, &__state);
+		  _M_data->_M_negative_sign = __wcs_ns;
+		}
+	      else
+		_M_data->_M_negative_sign = L"";
+              _M_data->_M_negative_sign_size =
+		wcslen(_M_data->_M_negative_sign);
+
+	      // _Intl == true.
+	      __len = strlen(__ccurr);
+	      if (__len)
+		{
+		  memset(&__state, 0, sizeof(mbstate_t));
+		  wchar_t* __wcs = new wchar_t[__len + 1];
+		  mbsrtowcs(__wcs, &__ccurr, __len + 1, &__state);
+		  _M_data->_M_curr_symbol = __wcs;
+		}
+	      else
+		_M_data->_M_curr_symbol = L"";
+              _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
+	    }
+          __catch(...)
+	    {
+	      delete _M_data;
+              _M_data = 0;
+	      delete [] __group;
+	      delete [] __wcs_ps;
+	      delete [] __wcs_ns;
+	      uselocale((locale_t)__old);
+              __throw_exception_again;
+	    }
+
+	  char __pprecedes = lc->p_cs_precedes;
+	  char __pspace = lc->p_sep_by_space;
+	  char __pposn = lc->p_sign_posn;
+	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
+	                                                __pposn);
+	  char __nprecedes = lc->n_cs_precedes;
+	  char __nspace = lc->n_sep_by_space;
+	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
+	                                                __nposn);
+
+	  uselocale((locale_t)__old);
+	}
+    }
+
+  template<>
+    moneypunct<wchar_t, true>::~moneypunct()
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      if (_M_data->_M_positive_sign_size)
+	delete [] _M_data->_M_positive_sign;
+      if (_M_data->_M_negative_sign_size
+          && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
+	delete [] _M_data->_M_negative_sign;
+      if (_M_data->_M_curr_symbol_size)
+	delete [] _M_data->_M_curr_symbol;
+      delete _M_data;
+    }
+
+  template<>
+    moneypunct<wchar_t, false>::~moneypunct()
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      if (_M_data->_M_positive_sign_size)
+	delete [] _M_data->_M_positive_sign;
+      if (_M_data->_M_negative_sign_size
+          && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
+	delete [] _M_data->_M_negative_sign;
+      if (_M_data->_M_curr_symbol_size)
+	delete [] _M_data->_M_curr_symbol;
+      delete _M_data;
+    }
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/numeric_members.cc b/libstdc++-v3/config/locale/xpg7/numeric_members.cc
new file mode 100644
index 00000000000..5ee61f0fbb4
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/numeric_members.cc
@@ -0,0 +1,261 @@
+// std::numpunct implementation details, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2015-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.2.3.1.2  numpunct virtual functions
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+// Modified for XPG7 by Clément Chigot <clement.chigot@atos.net>
+
+#include <locale>
+#include <cstring>
+
+#ifdef _GLIBCXX_HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<>
+    void
+    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
+    {
+      if (!_M_data)
+	_M_data = new __numpunct_cache<char>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_data->_M_grouping = "";
+	  _M_data->_M_grouping_size = 0;
+	  _M_data->_M_use_grouping = false;
+
+	  _M_data->_M_decimal_point = '.';
+	  _M_data->_M_thousands_sep = ',';
+
+	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
+	    _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
+
+	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
+	    _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
+	}
+      else
+	{
+	  // Named locale.
+#ifdef _GLIBCXX_HAVE_LOCALECONV_L
+	  lconv* lc = localeconv_l((locale_t) __cloc);
+#else
+	  __c_locale __old = uselocale(__cloc);
+	  lconv* lc = localeconv();
+#endif
+
+	  // Decimal point should always be defined, but check null anyway
+	  if (lc->decimal_point == NULL)
+	    {
+	      // Not defined, so use "C" locale default
+	      _M_data->_M_decimal_point = '.';
+	    }
+	  else
+	    {
+	      _M_data->_M_decimal_point = lc->decimal_point[0];
+	    }
+	  // Check for NULL, which implies no grouping.
+	  if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0')
+	    {
+	      // Like in "C" locale.
+	      _M_data->_M_grouping = "";
+	      _M_data->_M_grouping_size = 0;
+	      _M_data->_M_use_grouping = false;
+	      _M_data->_M_thousands_sep = ',';
+	    }
+	  else
+	    {
+	      _M_data->_M_thousands_sep = lc->thousands_sep[0];
+
+	      const char* __src = lc->grouping;
+	      const size_t __len = strlen(__src);
+	      if (__len)
+		{
+		  __try
+		    {
+		      char* __dst = new char[__len + 1];
+		      memcpy(__dst, __src, __len + 1);
+		      _M_data->_M_grouping = __dst;
+		      _M_data->_M_use_grouping = true;
+		    }
+		  __catch(...)
+		    {
+		      delete _M_data;
+		      _M_data = 0;
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+		      uselocale(__old);
+#endif
+		      __throw_exception_again;
+		    }
+		}
+	      else
+		{
+		  _M_data->_M_grouping = "";
+		  _M_data->_M_use_grouping = false;
+		}
+	      _M_data->_M_grouping_size = __len;
+	    }
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+	  uselocale(__old);
+#endif
+	}
+
+      // NB: There is no way to extact this info from posix locales.
+      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
+      _M_data->_M_truename = "true";
+      _M_data->_M_truename_size = 4;
+      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
+      _M_data->_M_falsename = "false";
+      _M_data->_M_falsename_size = 5;
+    }
+
+  template<>
+    numpunct<char>::~numpunct()
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      delete _M_data;
+    }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template<>
+    void
+    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
+    {
+      if (!_M_data)
+	_M_data = new __numpunct_cache<wchar_t>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_data->_M_grouping = "";
+	  _M_data->_M_grouping_size = 0;
+	  _M_data->_M_use_grouping = false;
+
+	  _M_data->_M_decimal_point = L'.';
+	  _M_data->_M_thousands_sep = L',';
+
+	  // Use ctype::widen code without the facet...
+	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
+	    _M_data->_M_atoms_out[__i] =
+	      static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
+
+	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
+	    _M_data->_M_atoms_in[__j] =
+	      static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
+	}
+      else
+	{
+	  // Named locale.
+#ifdef _GLIBCXX_HAVE_LOCALECONV_L
+	  lconv* lc = localeconv_l((locale_t) __cloc);
+#else
+	  __c_locale __old = uselocale(__cloc);
+	  lconv* lc = localeconv();
+#endif
+
+	  // Decimal point should always be defined, but check null anyway
+	  if (lc->decimal_point == NULL)
+	    {
+	      // Not defined, so use "C" locale default
+	      _M_data->_M_decimal_point = L'.';
+	    }
+	  else
+	    {
+	      _M_data->_M_decimal_point = (wchar_t)lc->decimal_point[0];
+	    }
+	  // Check for NULL, which implies no grouping.
+	  if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0')
+	    {
+	      // Like in "C" locale.
+	      _M_data->_M_grouping = "";
+	      _M_data->_M_grouping_size = 0;
+	      _M_data->_M_use_grouping = false;
+	      _M_data->_M_thousands_sep = L',';
+	    }
+	  else
+	    {
+	      _M_data->_M_thousands_sep = (wchar_t)lc->thousands_sep[0];
+
+  	      const char* __src = lc->grouping;
+	      const size_t __len = strlen(__src);
+	      if (__len)
+		{
+		  __try
+		    {
+		      char* __dst = new char[__len + 1];
+		      memcpy(__dst, __src, __len + 1);
+		      _M_data->_M_grouping = __dst;
+		    }
+		  __catch(...)
+		    {
+		      delete _M_data;
+		      _M_data = 0;
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+		      uselocale(__old);
+#endif
+		      __throw_exception_again;
+		    }
+		}
+	      else
+		{
+		  _M_data->_M_grouping = "";
+		  _M_data->_M_use_grouping = false;
+		}
+	      _M_data->_M_grouping_size = __len;
+	    }
+#ifndef _GLIBCXX_HAVE_LOCALECONV_L
+	  uselocale(__old);
+#endif
+	}
+
+      // NB: There is no way to extact this info from posix locales.
+      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
+      _M_data->_M_truename = L"true";
+      _M_data->_M_truename_size = 4;
+      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
+      _M_data->_M_falsename = L"false";
+      _M_data->_M_falsename_size = 5;
+    }
+
+  template<>
+    numpunct<wchar_t>::~numpunct()
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      delete _M_data;
+    }
+ #endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/time_members.cc b/libstdc++-v3/config/locale/xpg7/time_members.cc
new file mode 100644
index 00000000000..fb287332c44
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/time_members.cc
@@ -0,0 +1,434 @@
+// std::time_get, std::time_put implementation, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2001-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.2.5.1.2 - time_get virtual functions
+// ISO C++ 14882: 22.2.5.3.2 - time_put virtual functions
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+// Modified for XPG7 by Clément Chigot <clement.chigot@atos.net>
+
+#include <locale>
+#include <ctime>
+#include <cwchar>
+#include <stdlib.h>
+#include <langinfo.h>
+
+#ifdef _GLIBCXX_HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<>
+    void
+    __timepunct<char>::
+    _M_put(char* __s, size_t __maxlen, const char* __format,
+	   const tm* __tm) const throw()
+    {
+#ifdef _GLIBCXX_HAVE_STRFTIME_L
+      const size_t __len = strftime_l(__s, __maxlen, __format, __tm,
+				      (locale_t)_M_c_locale_timepunct);
+#else
+      __c_locale __old = uselocale(_M_c_locale_timepunct);
+      const size_t __len = strftime(__s, __maxlen, __format, __tm);
+      uselocale(__old);
+#endif
+      // Make sure __s is null terminated.
+      if (__len == 0)
+	__s[0] = '\0';
+    }
+
+  template<>
+    void
+    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc)
+    {
+      if (!_M_data)
+	_M_data = new __timepunct_cache<char>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_c_locale_timepunct = _S_get_c_locale();
+
+	  _M_data->_M_date_format = "%m/%d/%y";
+	  _M_data->_M_date_era_format = "%m/%d/%y";
+	  _M_data->_M_time_format = "%H:%M:%S";
+	  _M_data->_M_time_era_format = "%H:%M:%S";
+	  _M_data->_M_date_time_format = "";
+	  _M_data->_M_date_time_era_format = "";
+	  _M_data->_M_am = "AM";
+	  _M_data->_M_pm = "PM";
+	  _M_data->_M_am_pm_format = "";
+
+	  // Day names, starting with "C"'s Sunday.
+	  _M_data->_M_day1 = "Sunday";
+	  _M_data->_M_day2 = "Monday";
+	  _M_data->_M_day3 = "Tuesday";
+	  _M_data->_M_day4 = "Wednesday";
+	  _M_data->_M_day5 = "Thursday";
+	  _M_data->_M_day6 = "Friday";
+	  _M_data->_M_day7 = "Saturday";
+
+	  // Abbreviated day names, starting with "C"'s Sun.
+	  _M_data->_M_aday1 = "Sun";
+	  _M_data->_M_aday2 = "Mon";
+	  _M_data->_M_aday3 = "Tue";
+	  _M_data->_M_aday4 = "Wed";
+	  _M_data->_M_aday5 = "Thu";
+	  _M_data->_M_aday6 = "Fri";
+	  _M_data->_M_aday7 = "Sat";
+
+	  // Month names, starting with "C"'s January.
+	  _M_data->_M_month01 = "January";
+	  _M_data->_M_month02 = "February";
+	  _M_data->_M_month03 = "March";
+	  _M_data->_M_month04 = "April";
+	  _M_data->_M_month05 = "May";
+	  _M_data->_M_month06 = "June";
+	  _M_data->_M_month07 = "July";
+	  _M_data->_M_month08 = "August";
+	  _M_data->_M_month09 = "September";
+	  _M_data->_M_month10 = "October";
+	  _M_data->_M_month11 = "November";
+	  _M_data->_M_month12 = "December";
+
+	  // Abbreviated month names, starting with "C"'s Jan.
+	  _M_data->_M_amonth01 = "Jan";
+	  _M_data->_M_amonth02 = "Feb";
+	  _M_data->_M_amonth03 = "Mar";
+	  _M_data->_M_amonth04 = "Apr";
+	  _M_data->_M_amonth05 = "May";
+	  _M_data->_M_amonth06 = "Jun";
+	  _M_data->_M_amonth07 = "Jul";
+	  _M_data->_M_amonth08 = "Aug";
+	  _M_data->_M_amonth09 = "Sep";
+	  _M_data->_M_amonth10 = "Oct";
+	  _M_data->_M_amonth11 = "Nov";
+	  _M_data->_M_amonth12 = "Dec";
+	}
+      else
+	{
+	  _M_c_locale_timepunct = _S_clone_c_locale(__cloc);
+
+	  _M_data->_M_date_format = nl_langinfo_l(D_FMT, (locale_t)__cloc);
+	  _M_data->_M_date_era_format = nl_langinfo_l(ERA_D_FMT,
+	  					      (locale_t)__cloc);
+	  _M_data->_M_time_format = nl_langinfo_l(T_FMT, (locale_t)__cloc);
+	  _M_data->_M_time_era_format = nl_langinfo_l(ERA_T_FMT,
+						      (locale_t)__cloc);
+	  _M_data->_M_date_time_format = nl_langinfo_l(D_T_FMT,
+						       (locale_t)__cloc);
+	  _M_data->_M_date_time_era_format = nl_langinfo_l(ERA_D_T_FMT,
+	  						   (locale_t)__cloc);
+	  _M_data->_M_am = nl_langinfo_l(AM_STR, (locale_t)__cloc);
+	  _M_data->_M_pm = nl_langinfo_l(PM_STR, (locale_t)__cloc);
+	  _M_data->_M_am_pm_format = nl_langinfo_l(T_FMT_AMPM,
+	  					   (locale_t)__cloc);
+
+	  // Day names, starting with "C"'s Sunday.
+	  _M_data->_M_day1 = nl_langinfo_l(DAY_1, (locale_t)__cloc);
+	  _M_data->_M_day2 = nl_langinfo_l(DAY_2, (locale_t)__cloc);
+	  _M_data->_M_day3 = nl_langinfo_l(DAY_3, (locale_t)__cloc);
+	  _M_data->_M_day4 = nl_langinfo_l(DAY_4, (locale_t)__cloc);
+	  _M_data->_M_day5 = nl_langinfo_l(DAY_5, (locale_t)__cloc);
+	  _M_data->_M_day6 = nl_langinfo_l(DAY_6, (locale_t)__cloc);
+	  _M_data->_M_day7 = nl_langinfo_l(DAY_7, (locale_t)__cloc);
+
+	  // Abbreviated day names, starting with "C"'s Sun.
+	  _M_data->_M_aday1 = nl_langinfo_l(ABDAY_1, (locale_t)__cloc);
+	  _M_data->_M_aday2 = nl_langinfo_l(ABDAY_2, (locale_t)__cloc);
+	  _M_data->_M_aday3 = nl_langinfo_l(ABDAY_3, (locale_t)__cloc);
+	  _M_data->_M_aday4 = nl_langinfo_l(ABDAY_4, (locale_t)__cloc);
+	  _M_data->_M_aday5 = nl_langinfo_l(ABDAY_5, (locale_t)__cloc);
+	  _M_data->_M_aday6 = nl_langinfo_l(ABDAY_6, (locale_t)__cloc);
+	  _M_data->_M_aday7 = nl_langinfo_l(ABDAY_7, (locale_t)__cloc);
+
+	  // Month names, starting with "C"'s January.
+	  _M_data->_M_month01 = nl_langinfo_l(MON_1, (locale_t)__cloc);
+	  _M_data->_M_month02 = nl_langinfo_l(MON_2, (locale_t)__cloc);
+	  _M_data->_M_month03 = nl_langinfo_l(MON_3, (locale_t)__cloc);
+	  _M_data->_M_month04 = nl_langinfo_l(MON_4, (locale_t)__cloc);
+	  _M_data->_M_month05 = nl_langinfo_l(MON_5, (locale_t)__cloc);
+	  _M_data->_M_month06 = nl_langinfo_l(MON_6, (locale_t)__cloc);
+	  _M_data->_M_month07 = nl_langinfo_l(MON_7, (locale_t)__cloc);
+	  _M_data->_M_month08 = nl_langinfo_l(MON_8, (locale_t)__cloc);
+	  _M_data->_M_month09 = nl_langinfo_l(MON_9, (locale_t)__cloc);
+	  _M_data->_M_month10 = nl_langinfo_l(MON_10, (locale_t)__cloc);
+	  _M_data->_M_month11 = nl_langinfo_l(MON_11, (locale_t)__cloc);
+	  _M_data->_M_month12 = nl_langinfo_l(MON_12, (locale_t)__cloc);
+
+	  // Abbreviated month names, starting with "C"'s Jan.
+	  _M_data->_M_amonth01 = nl_langinfo_l(ABMON_1, (locale_t)__cloc);
+	  _M_data->_M_amonth02 = nl_langinfo_l(ABMON_2, (locale_t)__cloc);
+	  _M_data->_M_amonth03 = nl_langinfo_l(ABMON_3, (locale_t)__cloc);
+	  _M_data->_M_amonth04 = nl_langinfo_l(ABMON_4, (locale_t)__cloc);
+	  _M_data->_M_amonth05 = nl_langinfo_l(ABMON_5, (locale_t)__cloc);
+	  _M_data->_M_amonth06 = nl_langinfo_l(ABMON_6, (locale_t)__cloc);
+	  _M_data->_M_amonth07 = nl_langinfo_l(ABMON_7, (locale_t)__cloc);
+	  _M_data->_M_amonth08 = nl_langinfo_l(ABMON_8, (locale_t)__cloc);
+	  _M_data->_M_amonth09 = nl_langinfo_l(ABMON_9, (locale_t)__cloc);
+	  _M_data->_M_amonth10 = nl_langinfo_l(ABMON_10, (locale_t)__cloc);
+	  _M_data->_M_amonth11 = nl_langinfo_l(ABMON_11, (locale_t)__cloc);
+	  _M_data->_M_amonth12 = nl_langinfo_l(ABMON_12, (locale_t)__cloc);
+	}
+    }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template<>
+    void
+    __timepunct<wchar_t>::
+    _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format,
+	   const tm* __tm) const throw()
+    {
+#ifdef _GLIBCXX_HAVE_WCSFTIME_L
+      const size_t __len = wcsftime_l(__s, __maxlen, __format, __tm,
+				      (locale_t)_M_c_locale_timepunct);
+#else
+      __c_locale __old = uselocale(_M_c_locale_timepunct);
+      const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
+      uselocale(__old);
+#endif
+      // Make sure __s is null terminated.
+      if (__len == 0)
+	__s[0] = L'\0';
+    }
+
+#ifdef _GLIBCXX_HAVE_MBSTOWCS_L
+#define MBSTOWCS_L(WCSTRING, STRING, NUMBER, LOCALE)	\
+  mbstowcs_l (WCSTRING, STRING, NUMBER, LOCALE);
+#else
+  // "uselocale" must be called before using this macro.
+#define MBSTOWCS_L(WCSTRING, STRING, NUMBER, LOCALE)	\
+  mbstowcs (WCSTRING, STRING, NUMBER);
+#endif
+#define WIDE_LANGINFO(M,FMT) \
+	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); \
+	langstring[fmtlen] = L'\0'; \
+	_M_data->M = langstring;
+
+  template<>
+    void
+    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc)
+    {
+      if (!_M_data)
+	_M_data = new __timepunct_cache<wchar_t>;
+
+      if (!__cloc)
+	{
+	  // "C" locale
+	  _M_c_locale_timepunct = _S_get_c_locale();
+
+	  _M_data->_M_date_format = L"%m/%d/%y";
+	  _M_data->_M_date_era_format = L"%m/%d/%y";
+	  _M_data->_M_time_format = L"%H:%M:%S";
+	  _M_data->_M_time_era_format = L"%H:%M:%S";
+	  _M_data->_M_date_time_format = L"";
+	  _M_data->_M_date_time_era_format = L"";
+	  _M_data->_M_am = L"AM";
+	  _M_data->_M_pm = L"PM";
+	  _M_data->_M_am_pm_format = L"";
+
+	  // Day names, starting with "C"'s Sunday.
+	  _M_data->_M_day1 = L"Sunday";
+	  _M_data->_M_day2 = L"Monday";
+	  _M_data->_M_day3 = L"Tuesday";
+	  _M_data->_M_day4 = L"Wednesday";
+	  _M_data->_M_day5 = L"Thursday";
+	  _M_data->_M_day6 = L"Friday";
+	  _M_data->_M_day7 = L"Saturday";
+
+	  // Abbreviated day names, starting with "C"'s Sun.
+	  _M_data->_M_aday1 = L"Sun";
+	  _M_data->_M_aday2 = L"Mon";
+	  _M_data->_M_aday3 = L"Tue";
+	  _M_data->_M_aday4 = L"Wed";
+	  _M_data->_M_aday5 = L"Thu";
+	  _M_data->_M_aday6 = L"Fri";
+	  _M_data->_M_aday7 = L"Sat";
+
+	  // Month names, starting with "C"'s January.
+	  _M_data->_M_month01 = L"January";
+	  _M_data->_M_month02 = L"February";
+	  _M_data->_M_month03 = L"March";
+	  _M_data->_M_month04 = L"April";
+	  _M_data->_M_month05 = L"May";
+	  _M_data->_M_month06 = L"June";
+	  _M_data->_M_month07 = L"July";
+	  _M_data->_M_month08 = L"August";
+	  _M_data->_M_month09 = L"September";
+	  _M_data->_M_month10 = L"October";
+	  _M_data->_M_month11 = L"November";
+	  _M_data->_M_month12 = L"December";
+
+	  // Abbreviated month names, starting with "C"'s Jan.
+	  _M_data->_M_amonth01 = L"Jan";
+	  _M_data->_M_amonth02 = L"Feb";
+	  _M_data->_M_amonth03 = L"Mar";
+	  _M_data->_M_amonth04 = L"Apr";
+	  _M_data->_M_amonth05 = L"May";
+	  _M_data->_M_amonth06 = L"Jun";
+	  _M_data->_M_amonth07 = L"Jul";
+	  _M_data->_M_amonth08 = L"Aug";
+	  _M_data->_M_amonth09 = L"Sep";
+	  _M_data->_M_amonth10 = L"Oct";
+	  _M_data->_M_amonth11 = L"Nov";
+	  _M_data->_M_amonth12 = L"Dec";
+	}
+      else
+	{
+#ifndef _GLIBCXX_HAVE_MBSTOWCS_L
+	  __c_locale __old = uselocale(__cloc);
+#endif
+	  wchar_t *langstring = 0;
+	  wchar_t holder[128];
+	  size_t fmtlen;
+
+	  _M_c_locale_timepunct = _S_clone_c_locale(__cloc);
+
+	  WIDE_LANGINFO(_M_date_format, D_FMT)
+	  WIDE_LANGINFO(_M_date_era_format, ERA_D_FMT)
+	  WIDE_LANGINFO(_M_time_format, T_FMT)
+	  WIDE_LANGINFO(_M_time_era_format, ERA_T_FMT)
+	  WIDE_LANGINFO(_M_date_time_format, D_T_FMT)
+	  WIDE_LANGINFO(_M_date_time_era_format, ERA_D_T_FMT)
+	  WIDE_LANGINFO(_M_am, AM_STR)
+	  WIDE_LANGINFO(_M_pm, PM_STR)
+	  WIDE_LANGINFO(_M_am_pm_format, T_FMT_AMPM)
+
+	  // Day names, starting with "C"'s Sunday.
+	  WIDE_LANGINFO(_M_day1, DAY_1)
+	  WIDE_LANGINFO(_M_day2, DAY_2)
+	  WIDE_LANGINFO(_M_day3, DAY_3)
+	  WIDE_LANGINFO(_M_day4, DAY_4)
+	  WIDE_LANGINFO(_M_day5, DAY_5)
+	  WIDE_LANGINFO(_M_day6, DAY_6)
+	  WIDE_LANGINFO(_M_day7, DAY_7)
+
+	  // Abbreviated day names, starting with "C"'s Sun.
+	  WIDE_LANGINFO(_M_aday1, ABDAY_1)
+	  WIDE_LANGINFO(_M_aday2, ABDAY_2)
+	  WIDE_LANGINFO(_M_aday3, ABDAY_3)
+	  WIDE_LANGINFO(_M_aday4, ABDAY_4)
+	  WIDE_LANGINFO(_M_aday5, ABDAY_5)
+	  WIDE_LANGINFO(_M_aday6, ABDAY_6)
+	  WIDE_LANGINFO(_M_aday7, ABDAY_7)
+
+	  // Month names, starting with "C"'s January.
+	  WIDE_LANGINFO(_M_month01, MON_1)
+	  WIDE_LANGINFO(_M_month02, MON_2)
+	  WIDE_LANGINFO(_M_month03, MON_3)
+	  WIDE_LANGINFO(_M_month04, MON_4)
+	  WIDE_LANGINFO(_M_month05, MON_5)
+	  WIDE_LANGINFO(_M_month06, MON_6)
+	  WIDE_LANGINFO(_M_month07, MON_7)
+	  WIDE_LANGINFO(_M_month08, MON_8)
+	  WIDE_LANGINFO(_M_month09, MON_9)
+	  WIDE_LANGINFO(_M_month10, MON_10)
+	  WIDE_LANGINFO(_M_month11, MON_11)
+	  WIDE_LANGINFO(_M_month12, MON_12)
+
+	  // Abbreviated month names, starting with "C"'s Jan.
+	  WIDE_LANGINFO(_M_amonth01, ABMON_1)
+	  WIDE_LANGINFO(_M_amonth02, ABMON_2)
+	  WIDE_LANGINFO(_M_amonth03, ABMON_3)
+	  WIDE_LANGINFO(_M_amonth04, ABMON_4)
+	  WIDE_LANGINFO(_M_amonth05, ABMON_5)
+	  WIDE_LANGINFO(_M_amonth06, ABMON_6)
+	  WIDE_LANGINFO(_M_amonth07, ABMON_7)
+	  WIDE_LANGINFO(_M_amonth08, ABMON_8)
+	  WIDE_LANGINFO(_M_amonth09, ABMON_9)
+	  WIDE_LANGINFO(_M_amonth10, ABMON_10)
+	  WIDE_LANGINFO(_M_amonth11, ABMON_11)
+	  WIDE_LANGINFO(_M_amonth12, ABMON_12)
+#ifndef _GLIBCXX_HAVE_MBSTOWCS_L
+	  uselocale(__old);
+#endif
+	}
+    }
+
+  template<>
+    __timepunct<wchar_t>::~__timepunct()
+    {
+      delete [] _M_data->_M_date_format;
+      delete [] _M_data->_M_date_era_format;
+      delete [] _M_data->_M_time_format;
+      delete [] _M_data->_M_time_era_format;
+      delete [] _M_data->_M_date_time_format;
+      delete [] _M_data->_M_date_time_era_format;
+      delete [] _M_data->_M_am;
+      delete [] _M_data->_M_pm;
+      delete [] _M_data->_M_am_pm_format;
+      delete [] _M_data->_M_day1;
+      delete [] _M_data->_M_day2;
+      delete [] _M_data->_M_day3;
+      delete [] _M_data->_M_day4;
+      delete [] _M_data->_M_day5;
+      delete [] _M_data->_M_day6;
+      delete [] _M_data->_M_day7;
+      delete [] _M_data->_M_aday1;
+      delete [] _M_data->_M_aday2;
+      delete [] _M_data->_M_aday3;
+      delete [] _M_data->_M_aday4;
+      delete [] _M_data->_M_aday5;
+      delete [] _M_data->_M_aday6;
+      delete [] _M_data->_M_aday7;
+      delete [] _M_data->_M_month01;
+      delete [] _M_data->_M_month02;
+      delete [] _M_data->_M_month03;
+      delete [] _M_data->_M_month04;
+      delete [] _M_data->_M_month05;
+      delete [] _M_data->_M_month06;
+      delete [] _M_data->_M_month07;
+      delete [] _M_data->_M_month08;
+      delete [] _M_data->_M_month09;
+      delete [] _M_data->_M_month10;
+      delete [] _M_data->_M_month11;
+      delete [] _M_data->_M_month12;
+      delete [] _M_data->_M_amonth01;
+      delete [] _M_data->_M_amonth02;
+      delete [] _M_data->_M_amonth03;
+      delete [] _M_data->_M_amonth04;
+      delete [] _M_data->_M_amonth05;
+      delete [] _M_data->_M_amonth06;
+      delete [] _M_data->_M_amonth07;
+      delete [] _M_data->_M_amonth08;
+      delete [] _M_data->_M_amonth09;
+      delete [] _M_data->_M_amonth10;
+      delete [] _M_data->_M_amonth11;
+      delete [] _M_data->_M_amonth12;
+      delete _M_data;
+    }
+
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/locale/xpg7/time_members.h b/libstdc++-v3/config/locale/xpg7/time_members.h
new file mode 100644
index 00000000000..1457d4cce32
--- /dev/null
+++ b/libstdc++-v3/config/locale/xpg7/time_members.h
@@ -0,0 +1,95 @@
+// std::time_get, std::time_put implementation, XPG7 version -*- C++ -*-
+
+// Copyright (C) 2015-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/time_members.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{locale}
+ */
+
+//
+// ISO C++ 14882: 22.2.5.1.2 - time_get functions
+// ISO C++ 14882: 22.2.5.3.2 - time_put functions
+//
+
+// Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _CharT>
+    __timepunct<_CharT>::__timepunct(size_t __refs)
+    : facet(__refs), _M_data(0), _M_c_locale_timepunct(0),
+      _M_name_timepunct(_S_get_c_name())
+    { _M_initialize_timepunct(); }
+
+  template<typename _CharT>
+    __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs)
+    : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(0),
+      _M_name_timepunct(_S_get_c_name())
+    { _M_initialize_timepunct(); }
+
+  template<typename _CharT>
+    __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
+				     size_t __refs)
+    : facet(__refs), _M_data(0), _M_c_locale_timepunct(0),
+      _M_name_timepunct(0)
+    {
+      if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
+	{
+	  const size_t __len = __builtin_strlen(__s) + 1;
+	  char* __tmp = new char[__len];
+	  __builtin_memcpy(__tmp, __s, __len);
+	  _M_name_timepunct = __tmp;
+	}
+      else
+	_M_name_timepunct = _S_get_c_name();
+
+      __try
+	{ _M_initialize_timepunct(__cloc); }
+      __catch(...)
+	{
+	  if (_M_name_timepunct != _S_get_c_name())
+	    delete [] _M_name_timepunct;
+	  __throw_exception_again;
+	}
+    }
+
+  template<typename _CharT>
+    __timepunct<_CharT>::~__timepunct()
+    {
+      if (_M_name_timepunct != _S_get_c_name())
+	delete [] _M_name_timepunct;
+      delete _M_data;
+      _S_destroy_c_locale(_M_c_locale_timepunct);
+    }
+
+  // specialization
+  template<>
+    __timepunct<wchar_t>::~__timepunct();
+
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/os/aix/ctype_configure_char.cc b/libstdc++-v3/config/os/aix/ctype_configure_char.cc
index b12c0bd435c..67ceb800b4f 100644
--- a/libstdc++-v3/config/os/aix/ctype_configure_char.cc
+++ b/libstdc++-v3/config/os/aix/ctype_configure_char.cc
@@ -42,28 +42,83 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ctype<char>::classic_table() throw()
   { return 0; }
 
+#if _GLIBCXX_C_LOCALE_XPG7
+  ctype<char>::ctype(__c_locale __cloc, const mask* __table, bool __del,
+		     size_t __refs)
+    : facet(__refs), _M_c_locale_ctype(_S_clone_c_locale(__cloc)),
+    _M_del(__table != 0 && __del),
+    _M_toupper(NULL), _M_tolower(NULL),
+    _M_table(__table ? __table : classic_table()),
+    _M_widen_ok(0), _M_narrow_ok(0)
+    {
+      memset(_M_widen, 0, sizeof(_M_widen));
+      memset(_M_narrow, 0, sizeof(_M_narrow));
+    }
+#else
   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;
   }
+#endif
 
+#if _GLIBCXX_C_LOCALE_XPG7
   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_widen_ok(0), _M_narrow_ok(0)
+    {
+      memset(_M_widen, 0, sizeof(_M_widen));
+      memset(_M_narrow, 0, sizeof(_M_narrow));
+    }
+#else
+  ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
+  : 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;
   }
+#endif
 
   char
   ctype<char>::do_toupper(char __c) const
diff --git a/libstdc++-v3/config/os/gnu-linux/ctype_configure_char.cc b/libstdc++-v3/config/os/gnu-linux/ctype_configure_char.cc
index d6ab73175b8..d909feefca3 100644
--- a/libstdc++-v3/config/os/gnu-linux/ctype_configure_char.cc
+++ b/libstdc++-v3/config/os/gnu-linux/ctype_configure_char.cc
@@ -38,7 +38,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // Information as gleaned from /usr/include/ctype.h
 
-#if _GLIBCXX_C_LOCALE_GNU
+#if _GLIBCXX_C_LOCALE_GNU || _GLIBCXX_C_LOCALE_XPG7
   const ctype_base::mask*
   ctype<char>::classic_table() throw()
   { return _S_get_c_locale()->__ctype_b; }
@@ -70,7 +70,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif
 
-#if _GLIBCXX_C_LOCALE_GNU
+#if _GLIBCXX_C_LOCALE_GNU || _GLIBCXX_C_LOCALE_XPG7
   ctype<char>::ctype(__c_locale __cloc, const mask* __table, bool __del,
 		     size_t __refs)
   : facet(__refs), _M_c_locale_ctype(_S_clone_c_locale(__cloc)),
@@ -117,7 +117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif
 
-#if _GLIBCXX_C_LOCALE_GNU
+#if _GLIBCXX_C_LOCALE_GNU || _GLIBCXX_C_LOCALE_XPG7
   ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
   : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
   _M_del(__table != 0 && __del),
diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc
index 4bec50bf595..dcea799aeaf 100644
--- a/libstdc++-v3/src/c++98/locale_init.cc
+++ b/libstdc++-v3/src/c++98/locale_init.cc
@@ -296,7 +296,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _S_global = __other._M_impl;
       const string __other_name = __other.name();
       if (__other_name != "*")
+#ifdef _GLIBCXX_C_LOCALE_GNU
 	setlocale(LC_ALL, __other_name.c_str());
+#else
+        {
+	  // In general, passing "LC_CTYPE=C;LC_NUMERIQUE=C;..." as
+	  // argument to setlocale isn't allowed.
+	  if (__other._M_impl->_M_check_same_name())
+	    setlocale(LC_ALL, __other_name.c_str());
+	  else
+	    for (size_t __i = 0; __i < __other._S_categories_size; ++__i)
+	      setlocale(__i, __other._M_impl->_M_names[__i]);
+	}
+#endif
     }
 
     // Reference count sanity check: one reference removed for the
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/2.cc b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/2.cc
index ea0c43a20fc..71e198843d2 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/2.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/2.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.ISO8859-1" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/3.cc b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/3.cc
index 54206f8000a..ffde94108a1 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/3.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/3.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.ISO-8859-15" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/4.cc
index f27d667daf5..9193b598162 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/4.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/7.cc b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/7.cc
index b5383af657c..e4b428c9fc6 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/7.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/7.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/8.cc b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/8.cc
index 1d40a1723a4..ffbd856640b 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/8.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/8.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/9.cc b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/9.cc
index 9801e085683..5e42a373547 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/9.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/in/wchar_t/9.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/length/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/codecvt/length/wchar_t/4.cc
index f70d0fc6c58..01bf1a57917 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/length/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/length/wchar_t/4.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/out/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/codecvt/out/wchar_t/4.cc
index 5cde0b66331..25dfa02b99d 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/out/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/out/wchar_t/4.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/unshift/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/codecvt/unshift/wchar_t/4.cc
index 1e4ce5a8e3e..5d00a62c9a9 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/unshift/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/unshift/wchar_t/4.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // 2003-02-06  Petur Runolfsson  <peturr02@ru.is>
 
--- ./libstdc++-v3/testsuite/22_locale/ctype/is/wchar_t/2.cc_orig	2023-06-03 12:18:20 +0000
+++ ./libstdc++-v3/testsuite/22_locale/ctype/is/wchar_t/2.cc	2023-06-03 12:21:37 +0000
@@ -1,5 +1,5 @@
-// { dg-do run { xfail { ! { *-*-linux* *-*-gnu* } } } }
 // { dg-require-namedlocale "de_DE.ISO8859-15" }
+// { dg-require-localemodel "gnu xpg7" }
 
 // Copyright (C) 2000-2022 Free Software Foundation, Inc.
 //
--- ./libstdc++-v3/testsuite/22_locale/locale/cons/29217.cc_orig	2023-06-03 13:43:26 +0000
+++ ./libstdc++-v3/testsuite/22_locale/locale/cons/29217.cc	2023-06-03 13:45:06 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-require-localemodel "gnu" }
 
 // Copyright (C) 2006-2022 Free Software Foundation, Inc.
 //
--- ./libstdc++-v3/testsuite/22_locale/locale/cons/38368.cc_orig	2023-06-03 13:47:25 +0000
+++ ./libstdc++-v3/testsuite/22_locale/locale/cons/38368.cc	2023-06-03 13:47:44 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.ISO8859-1" }
+// { dg-require-localemodel "gnu" }
 
 // Copyright (C) 2008-2022 Free Software Foundation, Inc.
 //
--- ./libstdc++-v3/testsuite/22_locale/locale/cons/40184.cc_orig	2023-06-03 13:49:40 +0000
+++ ./libstdc++-v3/testsuite/22_locale/locale/cons/40184.cc	2023-06-03 13:49:55 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "ja_JP.eucJP" }
+// { dg-require-localemodel "gnu" }
 
 // Copyright (C) 2009-2022 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/5.cc b/libstdc++-v3/testsuite/22_locale/locale/cons/5.cc
index 66b939e2228..99abf566b81 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/cons/5.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/5.cc
@@ -3,6 +3,7 @@
 // { dg-require-namedlocale "es_MX" }
 // { dg-require-namedlocale "fr_FR" }
 // { dg-require-namedlocale "it_IT" }
+// { dg-require-localemodel "gnu" }
 
 // 2000-09-13 Benjamin Kosnik <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/testsuite/22_locale/locale/global_locale_objects/14071.cc b/libstdc++-v3/testsuite/22_locale/locale/global_locale_objects/14071.cc
index ea3992b03f6..30d4a31a64c 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/global_locale_objects/14071.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/global_locale_objects/14071.cc
@@ -1,5 +1,6 @@
 // { dg-require-namedlocale "is_IS.ISO8859-1" }
 // { dg-require-namedlocale "en_US.ISO8859-1" }
+// { dg-require-localemodel "gnu" }
 
 // 2004-02-09  Petur Runolfsson  <peturr02@ru.is>
 
--- ./libstdc++-v3/testsuite/22_locale/messages/13631.cc_orig	2023-06-03 13:51:19 +0000
+++ ./libstdc++-v3/testsuite/22_locale/messages/13631.cc	2023-06-03 13:51:43 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-require-localemodel "gnu" }
 
 // Copyright (C) 2014-2022 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/22_locale/messages/members/char/1.cc b/libstdc++-v3/testsuite/22_locale/messages/members/char/1.cc
index c4d972124f0..fdf4a0af018 100644
--- a/libstdc++-v3/testsuite/22_locale/messages/members/char/1.cc
+++ b/libstdc++-v3/testsuite/22_locale/messages/members/char/1.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "de_DE.ISO8859-15" }
+// { dg-require-localemodel "gnu" }
 
 // 2001-07-17 Benjamin Kosnik  <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/testsuite/22_locale/messages/members/char/2.cc b/libstdc++-v3/testsuite/22_locale/messages/members/char/2.cc
index 81d914f5c37..3345f43b342 100644
--- a/libstdc++-v3/testsuite/22_locale/messages/members/char/2.cc
+++ b/libstdc++-v3/testsuite/22_locale/messages/members/char/2.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-require-localemodel "gnu" }
 
 // 2001-07-17 Benjamin Kosnik  <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/testsuite/22_locale/messages/members/char/3.cc b/libstdc++-v3/testsuite/22_locale/messages/members/char/3.cc
index 5a503ef2c49..1d2f7ad3162 100644
--- a/libstdc++-v3/testsuite/22_locale/messages/members/char/3.cc
+++ b/libstdc++-v3/testsuite/22_locale/messages/members/char/3.cc
@@ -1,5 +1,6 @@
 // { dg-require-namedlocale "en_US.ISO8859-1" }
 // { dg-require-namedlocale "fr_FR.ISO8859-15" }
+// { dg-require-localemodel "gnu" }
 
 // 2001-07-17 Benjamin Kosnik  <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_env.cc b/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_env.cc
index 35e7f6c740c..976b4d9fbf6 100644
--- a/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_env.cc
+++ b/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_env.cc
@@ -1,6 +1,7 @@
 // { dg-require-namedlocale "de_DE.ISO8859-15" }
 // { dg-require-namedlocale "fr_FR.ISO8859-15" }
 // { dg-require-namedlocale "en_US.ISO8859-1" }
+// { dg-require-localemodel "gnu" }
 
 // 2001-08-15 Benjamin Kosnik  <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_locale.cc b/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_locale.cc
index a44bf1476b2..b143d33a4cc 100644
--- a/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_locale.cc
+++ b/libstdc++-v3/testsuite/22_locale/messages/members/char/wrapped_locale.cc
@@ -2,6 +2,7 @@
 // { dg-require-namedlocale "de_DE.ISO8859-15" }
 // { dg-require-namedlocale "fr_FR.ISO8859-15" }
 // { dg-require-namedlocale "en_US.ISO8859-1" }
+// { dg-require-localemodel "gnu" }
 
 // 2001-08-15 Benjamin Kosnik  <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/testsuite/22_locale/messages_byname/named_equivalence.cc b/libstdc++-v3/testsuite/22_locale/messages_byname/named_equivalence.cc
index 1006f20c996..fabf281d3e6 100644
--- a/libstdc++-v3/testsuite/22_locale/messages_byname/named_equivalence.cc
+++ b/libstdc++-v3/testsuite/22_locale/messages_byname/named_equivalence.cc
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "de_DE.ISO8859-15" }
+// { dg-require-localemodel "gnu" }
 
 // 2001-07-17 Benjamin Kosnik  <bkoz@redhat.com>
 
--- ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-1.cc_orig	2023-06-03 13:53:13 +0000
+++ ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-1.cc	2023-06-03 13:53:41 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // Copyright (C) 2003-2022 Free Software Foundation, Inc.
 //
--- ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-2.cc_orig	2023-06-03 13:55:03 +0000
+++ ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-2.cc	2023-06-03 13:55:18 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // Copyright (C) 2003-2022 Free Software Foundation, Inc.
 //
--- ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-3.cc_orig	2023-06-03 13:56:38 +0000
+++ ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-3.cc	2023-06-03 13:56:48 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // Copyright (C) 2003-2022 Free Software Foundation, Inc.
 //
--- ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-4.cc_orig	2023-06-03 13:57:52 +0000
+++ ./libstdc++-v3/testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-4.cc	2023-06-03 13:58:03 +0000
@@ -1,4 +1,5 @@
 // { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-excess-errors "wchar_t overflow" { xfail { wchar_t_char16_t_compatible } } }
 
 // Copyright (C) 2003-2022 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp
index 7894973bcca..f380cb005b5 100644
--- a/libstdc++-v3/testsuite/lib/dg-options.exp
+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
@@ -88,6 +88,15 @@ proc dg-require-namedlocale { args } {
     return
 }
 
+proc dg-require-localemodel { args } {
+    if { ![ check_v3_target_localemodel [lindex $args 1] ] } {
+	upvar dg-do-what dg-do-what
+	set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+	return
+    }
+    return
+}
+
 proc dg-require-sharedlib { args } {
     if { ![ check_v3_target_sharedlib ] } {
 	upvar dg-do-what dg-do-what
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 30a4345b14f..0165c25673c 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\");"
@@ -954,6 +959,32 @@ proc check_v3_target_namedlocale { args } {
     }]
 }
 
+# Return 1 if the locale model is implemented.
+proc check_v3_target_localemodel { args } {
+    set key "et_locale $args"
+    return [check_v3_target_prop_cached $key {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
+
+	set cond "0"
+	if [string match "*gnu*" $args] {
+	    set cond " $cond || defined _GLIBCXX_C_LOCALE_GNU"
+	}
+	if [string match "*xpg7*" $args] {
+	    set cond " $cond || defined _GLIBCXX_C_LOCALE_XPG7"
+	}
+
+	set code "
+	#include <bits/c++locale.h>
+	#if ! ($cond)
+	#error '$cond' is false
+	#endif
+	"
+	set flags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
+	return [v3_try_preprocess name $code $flags]
+    }]
+}
+
 # Returns 1 if the tokens in CODE can be preprocessed successfully using FLAGS,
 # returns 0 otherwise.
 proc v3_try_preprocess { name code flags } {
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

