diff mbox

[libstdc++] Provide nearly complete locale support for DragonFly

Message ID 55BB9D15.8080202@marino.st
State New
Headers show

Commit Message

John Marino July 31, 2015, 4:06 p.m. UTC
So far, DragonFly only handles the C/POSIX locale through the "generic"
locale support files, similar to FreeBSD and Darwin.  The following
patchset enables nearly complete support for named locales.  The except
is for std:messages which requires gettext support in libc which is not
present in any *BSD.  For that category, I have left generic support in
place at Jonathan's recommendation.

The support was made by talking the GNU version and adapting it to work
on DragonFly.

Testing has shown these patches to be working.  A "before" test results:
  https://gcc.gnu.org/ml/gcc-testresults/2015-07/msg01678.html
    PASS: 9883
    FAIL: 89
    XSUCC: 1
    XFAIL: 66
    UNSUP: 465
The most recent test:
  https://gcc.gnu.org/ml/gcc-testresults/2015-07/msg03024.html
    PASS:  10074
    FAIL:  32
    XFAIL: 68
    UNSUP: 401

For full disclosure, a number of improvements were made to the OS in the
area of locales, such as DragonFly being the first BSD to acquire full
collation support.

Most of the remaining failures are due to differences in locale
definitions between linux and DragonFly (DragonFly now uses CLDR POSIX
definitions, v2.0.1 currently)

Attachments:
  1. combined diff
  2. diff between gnu and dragonfly version (FYI)
  3. Suggested Changelog entry

This work should be highly interesting for FreeBSD and perhaps darwin as
well.  FreeBSD may be able to switch to it directly without any required
modifications, but of course that must be tested.

There is no risk to approving this patchset because it affects only
DragonFly.  Please consider approving this for incorporating into trunk
(also recall that my FSF copyright assignment is filed and in order.)

Regards,
John
2015-08-xx  John Marino  <gnugcc@marino.st>

	* acinclude.m4 (*-*-dragonfly*): Change 7 locale support files
        from generic to new DragonFly versions.
	* configure: Regenerate.
	* config/locale/dragonfly/c_locale.cc: Improve locale support.
	* config/locale/dragonfly/ctype_members.cc: likewise.
	* config/os/bsd/dragonfly/ctype_configure_char.cc: Likewise.
	* config/locale/dragonfly/c_locale.h: New.
	* config/locale/dragonfly/codecvt_members.cc: New.
	* config/locale/dragonfly/collate_members.cc: New.
	* config/locale/dragonfly/monetary_members.cc: New.
	* config/locale/dragonfly/numeric_members.cc: New.
	* config/locale/dragonfly/time_members.cc: New.
	* config/locale/dragonfly/time_members.h: New.

Index: libstdc++-v3/acinclude.m4
===================================================================
--- libstdc++-v3/acinclude.m4	(revision 226444)
+++ libstdc++-v3/acinclude.m4	(working copy)
@@ -2087,17 +2087,17 @@
     dragonfly)
       AC_MSG_RESULT(dragonfly)
 
-      CLOCALE_H=config/locale/generic/c_locale.h
+      CLOCALE_H=config/locale/dragonfly/c_locale.h
       CLOCALE_CC=config/locale/dragonfly/c_locale.cc
-      CCODECVT_CC=config/locale/generic/codecvt_members.cc
-      CCOLLATE_CC=config/locale/generic/collate_members.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/generic/monetary_members.cc
-      CNUMERIC_CC=config/locale/generic/numeric_members.cc
-      CTIME_H=config/locale/generic/time_members.h
-      CTIME_CC=config/locale/generic/time_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
       ;;
 
Index: libstdc++-v3/config/locale/dragonfly/c_locale.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/c_locale.cc	(revision 226444)
+++ libstdc++-v3/config/locale/dragonfly/c_locale.cc	(working copy)
@@ -1,4 +1,4 @@
-// Wrapper for underlying C-language localization -*- C++ -*-
+// localization implementation details, DragonFly version -*- C++ -*-
 
 // Copyright (C) 2014-2015 Free Software Foundation, Inc.
 //
@@ -27,19 +27,15 @@
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
-#include <cerrno>  // For errno
-#include <cmath>  // For isinf, finite, finitef, fabs
-#include <cstdlib>  // For strof, strtold
-#include <cstring>
-#include <cstdio>
+#include <cstdlib>
 #include <locale>
+#include <stdexcept>
 #include <limits>
+#include <langinfo.h>
+#include <xlocale.h>
 
-#ifdef _GLIBCXX_HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -47,41 +43,11 @@
   template<>
     void
     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
-		   const __c_locale&) throw()
+		   const __c_locale& __cloc) throw()
     {
-      // Assumes __s formatted for "C" locale.
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __len = strlen(__old) + 1;
-      char* __sav = new char[__len];
-      memcpy(__sav, __old, __len);
-      setlocale(LC_ALL, "C");
       char* __sanity;
-      bool __overflow = false;
+      __v = strtof_l(__s, &__sanity, (locale_t)__cloc);
 
-#if !__FLT_HAS_INFINITY__
-      errno = 0;
-#endif
-
-#ifdef _GLIBCXX_HAVE_STRTOF
-      __v = strtof(__s, &__sanity);
-#else
-      double __d = strtod(__s, &__sanity);
-      __v = static_cast<float>(__d);
-#ifdef _GLIBCXX_HAVE_FINITEF
-      if (!finitef (__v))
-	__overflow = true;
-#elif defined (_GLIBCXX_HAVE_FINITE)
-      if (!finite (static_cast<double> (__v)))
-	__overflow = true;
-#elif defined (_GLIBCXX_HAVE_ISINF)
-      if (isinf (static_cast<double> (__v)))
-	__overflow = true;
-#else
-      if (fabs(__d) > numeric_limits<float>::max())
-	__overflow = true;
-#endif
-#endif // _GLIBCXX_HAVE_STRTOF
-
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 23. Num_get overflow result.
       if (__sanity == __s || *__sanity != '\0')
@@ -89,45 +55,26 @@
 	  __v = 0.0f;
 	  __err = ios_base::failbit;
 	}
-      else if (__overflow
-#if __FLT_HAS_INFINITY__
-	       || __v == numeric_limits<float>::infinity()
-	       || __v == -numeric_limits<float>::infinity()
-#else
-	       || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
-#endif
-	      )
+      else if (__v == numeric_limits<float>::infinity())
 	{
-	  if (__v > 0.0f)
-	    __v = numeric_limits<float>::max();
-	  else
-	    __v = -numeric_limits<float>::max();
+	  __v = numeric_limits<float>::max();
 	  __err = ios_base::failbit;
 	}
-
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
+      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&) throw()
+		   const __c_locale& __cloc) throw()
     {
-      // Assumes __s formatted for "C" locale.
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __len = strlen(__old) + 1;
-      char* __sav = new char[__len];
-      memcpy(__sav, __old, __len);
-      setlocale(LC_ALL, "C");
       char* __sanity;
+      __v = strtod_l(__s, &__sanity, (locale_t)__cloc);
 
-#if !__DBL_HAS_INFINITY__
-      errno = 0;
-#endif
-
-      __v = strtod(__s, &__sanity);
-
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 23. Num_get overflow result.
       if (__sanity == __s || *__sanity != '\0')
@@ -135,132 +82,86 @@
 	  __v = 0.0;
 	  __err = ios_base::failbit;
 	}
-      else if (
-#if __DBL_HAS_INFINITY__
-	       __v == numeric_limits<double>::infinity()
-	       || __v == -numeric_limits<double>::infinity())
-#else
-	       (__v > 1.0 || __v < -1.0) && errno == ERANGE)
-#endif
+      else if (__v == numeric_limits<double>::infinity())
 	{
-	  if (__v > 0.0)
-	    __v = numeric_limits<double>::max();
-	  else
-	    __v = -numeric_limits<double>::max();
+	  __v = numeric_limits<double>::max();
 	  __err = ios_base::failbit;
 	}
-
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
+      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&) throw()
+    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
     {
-      // Assumes __s formatted for "C" locale.
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __len = strlen(__old) + 1;
-      char* __sav = new char[__len];
-      memcpy(__sav, __old, __len);
-      setlocale(LC_ALL, "C");
-
-#if !__LDBL_HAS_INFINITY__
-      errno = 0;
-#endif
-
-#if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
       char* __sanity;
-      __v = strtold(__s, &__sanity);
+      __v = strtold_l(__s, &__sanity, (locale_t)__cloc);
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 23. Num_get overflow result.
       if (__sanity == __s || *__sanity != '\0')
-#else
-      typedef char_traits<char>::int_type int_type;
-      int __p = sscanf(__s, "%Lf", &__v);
-
-      if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
-#endif
 	{
 	  __v = 0.0l;
 	  __err = ios_base::failbit;
 	}
-       else if (
-#if __LDBL_HAS_INFINITY__
-		__v == numeric_limits<long double>::infinity()
-		|| __v == -numeric_limits<long double>::infinity())
-#else
-		(__v > 1.0l || __v < -1.0l) && errno == ERANGE)
-#endif
+      else if (__v == numeric_limits<long double>::infinity())
 	{
-	  if (__v > 0.0l)
-	    __v = numeric_limits<long double>::max();
-	  else
-	    __v = -numeric_limits<long double>::max();
+	  __v = numeric_limits<long double>::max();
 	  __err = ios_base::failbit;
 	}
-
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
+      else if (__v == -numeric_limits<long double>::infinity())
+	{
+	  __v = -numeric_limits<long double>::max();
+	  __err = ios_base::failbit;
+	}
     }
 
-
-  /*  DragonFly's implementation of setlocale won't accept something like
-      "de_DE".  According to nls manpage, the expected format is:
-      language[_territory][.codeset][@modifier], but it seems that both
-      the _territory and .codeset components are required.
-      
-      As an attempt to correct for this, we'll tack on ".UTF-8" if 
-      a period is not detected in the locale string.  
-
-      There are no locales with modifiers on DragonFly so if found, they
-      will just be stripped off silently.  e.g "de_DE@euro" will be reduced
-      to "de_DE".  The UTF-8 default would be added after that.
-  */
-
   void
   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
-				    __c_locale)
+				    __c_locale __old)
   {
-    const size_t size__s = (__s == NULL) ? 1 : strlen (__s);
-    const char UTF8[] = ".UTF-8";
-    char localspec[size__s + 6 + 1];
-    
-    if (__s == NULL) {
-       localspec[0] = '\0';
-    } else {
-       strcpy (localspec, __s);
-       char * pch = strchr (localspec, '@');
-       if (pch != NULL)
-          *pch = 0;
-
-       if (  (strchr (__s, '.') == NULL)
-          && (strcmp (__s, "C") != 0)
-          && (strcmp (__s, "POSIX") != 0))
-          strncat (localspec, UTF8, 6);
-    }
-
-    const char * result = std::setlocale(LC_ALL, localspec);
-    
-    if ((strcmp(result, "C") != 0) && (strcmp (result, localspec) != 0))
-      __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
-			    "name not valid"));
-    __cloc = 0;
+    __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)
-  { __cloc = 0; }
+  {
+    if (__cloc && _S_get_c_locale() != __cloc)
+      freelocale((locale_t)__cloc);
+  }
 
   __c_locale
-  locale::facet::_S_clone_c_locale(__c_locale&) throw()
-  { return __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, const char*)
-  { return __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
@@ -295,5 +196,5 @@
 #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_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
+_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
Index: libstdc++-v3/config/locale/dragonfly/c_locale.h
===================================================================
--- libstdc++-v3/config/locale/dragonfly/c_locale.h	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/c_locale.h	(working copy)
@@ -0,0 +1,81 @@
+// localization implementation details, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2001-2015 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>
+
+#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);
+
+#ifdef _GLIBCXX_USE_C99
+    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
Index: libstdc++-v3/config/locale/dragonfly/codecvt_members.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/codecvt_members.cc	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/codecvt_members.cc	(working copy)
@@ -0,0 +1,288 @@
+// std::codecvt implementation details, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2015 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
Index: libstdc++-v3/config/locale/dragonfly/collate_members.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/collate_members.cc	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/collate_members.cc	(working copy)
@@ -0,0 +1,74 @@
+// std::collate implementation details, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2015 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
Index: libstdc++-v3/config/locale/dragonfly/ctype_members.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/ctype_members.cc	(revision 226444)
+++ libstdc++-v3/config/locale/dragonfly/ctype_members.cc	(working copy)
@@ -1,4 +1,4 @@
-// std::ctype implementation details, GNU version -*- C++ -*-
+// std::ctype implementation details, DragonFly version -*- C++ -*-
 
 // Copyright (C) 2014-2015 Free Software Foundation, Inc.
 //
@@ -27,18 +27,22 @@
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
 #include <locale>
-#include <bits/c++locale_internal.h>
-#include <cstdlib>
 #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) 
   { 		
@@ -54,17 +58,56 @@
 
 #ifdef _GLIBCXX_USE_WCHAR_T  
   ctype<wchar_t>::__wmask_type
-  ctype<wchar_t>::_M_convert_to_wmask(
-    const mask __attribute__((__unused__)) __m) const throw()
+  ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw()
   {
-    // DragonFly uses the same codes for 'char' as 'wchar_t', so this routine
-    // never gets called.
-    return __wmask_type();
-  };
+    __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(__c); }
+  { 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
@@ -71,7 +114,7 @@
   {
     while (__lo < __hi)
       {
-        *__lo = towupper(*__lo);
+        *__lo = towupper_l(*__lo, (locale_t)_M_c_locale_ctype);
         ++__lo;
       }
     return __hi;
@@ -79,7 +122,7 @@
   
   wchar_t
   ctype<wchar_t>::do_tolower(wchar_t __c) const
-  { return towlower(__c); }
+  { 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
@@ -86,7 +129,7 @@
   {
     while (__lo < __hi)
       {
-        *__lo = towlower(*__lo);
+        *__lo = towlower_l(*__lo, (locale_t)_M_c_locale_ctype);
         ++__lo;
       }
     return __hi;
@@ -113,10 +156,12 @@
   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)); 
   }
 
@@ -125,6 +170,7 @@
   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)
 	{
@@ -146,6 +192,7 @@
 	  ++__lo;
 	  ++__dest;
 	}
+    uselocale((locale_t)__old);
     return __hi;
   }
 
@@ -152,6 +199,7 @@
   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)
       {
@@ -165,9 +213,18 @@
       _M_narrow_ok = true;
     else
       _M_narrow_ok = false;
-    for (size_t __i = 0;
-	 __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
-      _M_widen[__i] = btowc(__i);
+    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
Index: libstdc++-v3/config/locale/dragonfly/monetary_members.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/monetary_members.cc	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/monetary_members.cc	(working copy)
@@ -0,0 +1,903 @@
+// std::moneypunct implementation details, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2015 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
Index: libstdc++-v3/config/locale/dragonfly/numeric_members.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/numeric_members.cc	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/numeric_members.cc	(working copy)
@@ -0,0 +1,235 @@
+// std::numpunct implementation details, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2015 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
Index: libstdc++-v3/config/locale/dragonfly/time_members.cc
===================================================================
--- libstdc++-v3/config/locale/dragonfly/time_members.cc	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/time_members.cc	(working copy)
@@ -0,0 +1,404 @@
+// std::time_get, std::time_put implementation, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2001-2015 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 = "";
+
+	  // 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"";
+
+	  // 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
Index: libstdc++-v3/config/locale/dragonfly/time_members.h
===================================================================
--- libstdc++-v3/config/locale/dragonfly/time_members.h	(revision 0)
+++ libstdc++-v3/config/locale/dragonfly/time_members.h	(working copy)
@@ -0,0 +1,95 @@
+// std::time_get, std::time_put implementation, DragonFly version -*- C++ -*-
+
+// Copyright (C) 2015 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
Index: libstdc++-v3/config/os/bsd/dragonfly/ctype_configure_char.cc
===================================================================
--- libstdc++-v3/config/os/bsd/dragonfly/ctype_configure_char.cc	(revision 226444)
+++ libstdc++-v3/config/os/bsd/dragonfly/ctype_configure_char.cc	(working copy)
@@ -40,29 +40,57 @@
   
   const ctype_base::mask*
   ctype<char>::classic_table() throw()
-  { return 0; }
+  { return NULL; }
 
   ctype<char>::ctype(__c_locale, const mask* __table, bool __del, 
 		     size_t __refs) 
-  : facet(__refs), _M_del(__table != 0 && __del), 
-  _M_toupper(NULL), _M_tolower(NULL), 
-  _M_table(__table ? __table : classic_table()) 
-  { 
+  : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
+  _M_del(__table != 0 && __del), _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");
+      }
+    _M_toupper = NULL;
+    _M_tolower = NULL;
+    _M_table = __table ? __table : classic_table();
+    if (__sav)
+      {
+	setlocale(LC_CTYPE, __sav);
+	delete [] __sav;
+      }
     memset(_M_widen, 0, sizeof(_M_widen));
-    _M_widen_ok = 0;
     memset(_M_narrow, 0, sizeof(_M_narrow));
-    _M_narrow_ok = 0;
   }
 
   ctype<char>::ctype(const mask* __table, bool __del, size_t __refs) 
-  : facet(__refs), _M_del(__table != 0 && __del), 
-  _M_toupper(NULL), _M_tolower(NULL), 
-  _M_table(__table ? __table : classic_table()) 
-  { 
+  : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
+  _M_del(__table != 0 && __del), _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");
+      }
+    _M_toupper = NULL;
+    _M_tolower = NULL;
+    _M_table = __table ? __table : classic_table();
+    if (__sav)
+      {
+	setlocale(LC_CTYPE, __sav);
+	delete [] __sav;
+      }
     memset(_M_widen, 0, sizeof(_M_widen));
-    _M_widen_ok = 0;
     memset(_M_narrow, 0, sizeof(_M_narrow));
-    _M_narrow_ok = 0;
   }
 
   char
Index: libstdc++-v3/configure
===================================================================
--- libstdc++-v3/configure	(revision 226444)
+++ libstdc++-v3/configure	(working copy)
@@ -15986,17 +15986,17 @@
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: dragonfly" >&5
 $as_echo "dragonfly" >&6; }
 
-      CLOCALE_H=config/locale/generic/c_locale.h
+      CLOCALE_H=config/locale/dragonfly/c_locale.h
       CLOCALE_CC=config/locale/dragonfly/c_locale.cc
-      CCODECVT_CC=config/locale/generic/codecvt_members.cc
-      CCOLLATE_CC=config/locale/generic/collate_members.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/generic/monetary_members.cc
-      CNUMERIC_CC=config/locale/generic/numeric_members.cc
-      CTIME_H=config/locale/generic/time_members.h
-      CTIME_CC=config/locale/generic/time_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
       ;;
diff mbox

Patch

diff -ur generic/c_locale.cc dragonfly/c_locale.cc
--- generic/c_locale.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/c_locale.cc	2015-07-31 17:10:46.000000000 +0200
@@ -1,6 +1,6 @@ 
-// Wrapper for underlying C-language localization -*- C++ -*-
+// localization implementation details, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2001-2015 Free Software Foundation, Inc.
+// Copyright (C) 2014-2015 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
@@ -27,18 +27,14 @@ 
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
-#include <cerrno>  // For errno
-#include <cmath>  // For isinf, finite, finitef, fabs
-#include <cstdlib>  // For strof, strtold
-#include <cstring>
-#include <cstdio>
+#include <cstdlib>
 #include <locale>
+#include <stdexcept>
 #include <limits>
-
-#ifdef _GLIBCXX_HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
+#include <langinfo.h>
+#include <xlocale.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -47,40 +43,10 @@ 
   template<>
     void
     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
-		   const __c_locale&) throw()
+		   const __c_locale& __cloc) throw()
     {
-      // Assumes __s formatted for "C" locale.
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __len = strlen(__old) + 1;
-      char* __sav = new char[__len];
-      memcpy(__sav, __old, __len);
-      setlocale(LC_ALL, "C");
       char* __sanity;
-      bool __overflow = false;
-
-#if !__FLT_HAS_INFINITY__
-      errno = 0;
-#endif
-
-#ifdef _GLIBCXX_HAVE_STRTOF
-      __v = strtof(__s, &__sanity);
-#else
-      double __d = strtod(__s, &__sanity);
-      __v = static_cast<float>(__d);
-#ifdef _GLIBCXX_HAVE_FINITEF
-      if (!finitef (__v))
-	__overflow = true;
-#elif defined (_GLIBCXX_HAVE_FINITE)
-      if (!finite (static_cast<double> (__v)))
-	__overflow = true;
-#elif defined (_GLIBCXX_HAVE_ISINF)
-      if (isinf (static_cast<double> (__v)))
-	__overflow = true;
-#else
-      if (fabs(__d) > numeric_limits<float>::max())
-	__overflow = true;
-#endif
-#endif // _GLIBCXX_HAVE_STRTOF
+      __v = strtof_l(__s, &__sanity, (locale_t)__cloc);
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 23. Num_get overflow result.
@@ -89,44 +55,25 @@ 
 	  __v = 0.0f;
 	  __err = ios_base::failbit;
 	}
-      else if (__overflow
-#if __FLT_HAS_INFINITY__
-	       || __v == numeric_limits<float>::infinity()
-	       || __v == -numeric_limits<float>::infinity()
-#else
-	       || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
-#endif
-	      )
+      else if (__v == numeric_limits<float>::infinity())
 	{
-	  if (__v > 0.0f)
-	    __v = numeric_limits<float>::max();
-	  else
-	    __v = -numeric_limits<float>::max();
+	  __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;
 	}
-
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
     }
 
   template<>
     void
     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
-		   const __c_locale&) throw()
+		   const __c_locale& __cloc) throw()
     {
-      // Assumes __s formatted for "C" locale.
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __len = strlen(__old) + 1;
-      char* __sav = new char[__len];
-      memcpy(__sav, __old, __len);
-      setlocale(LC_ALL, "C");
       char* __sanity;
-
-#if !__DBL_HAS_INFINITY__
-      errno = 0;
-#endif
-
-      __v = strtod(__s, &__sanity);
+      __v = strtod_l(__s, &__sanity, (locale_t)__cloc);
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 23. Num_get overflow result.
@@ -135,100 +82,86 @@ 
 	  __v = 0.0;
 	  __err = ios_base::failbit;
 	}
-      else if (
-#if __DBL_HAS_INFINITY__
-	       __v == numeric_limits<double>::infinity()
-	       || __v == -numeric_limits<double>::infinity())
-#else
-	       (__v > 1.0 || __v < -1.0) && errno == ERANGE)
-#endif
+      else if (__v == numeric_limits<double>::infinity())
 	{
-	  if (__v > 0.0)
-	    __v = numeric_limits<double>::max();
-	  else
-	    __v = -numeric_limits<double>::max();
+	  __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;
 	}
-
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
     }
 
   template<>
     void
-    __convert_to_v(const char* __s, long double& __v,
-		   ios_base::iostate& __err, const __c_locale&) throw()
+    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+		   const __c_locale& __cloc) throw()
     {
-      // Assumes __s formatted for "C" locale.
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __len = strlen(__old) + 1;
-      char* __sav = new char[__len];
-      memcpy(__sav, __old, __len);
-      setlocale(LC_ALL, "C");
-
-#if !__LDBL_HAS_INFINITY__
-      errno = 0;
-#endif
-
-#if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
       char* __sanity;
-      __v = strtold(__s, &__sanity);
+      __v = strtold_l(__s, &__sanity, (locale_t)__cloc);
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 23. Num_get overflow result.
       if (__sanity == __s || *__sanity != '\0')
-#else
-      typedef char_traits<char>::int_type int_type;
-      int __p = sscanf(__s, "%Lf", &__v);
-
-      if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
-#endif
 	{
 	  __v = 0.0l;
 	  __err = ios_base::failbit;
 	}
-       else if (
-#if __LDBL_HAS_INFINITY__
-		__v == numeric_limits<long double>::infinity()
-		|| __v == -numeric_limits<long double>::infinity())
-#else
-		(__v > 1.0l || __v < -1.0l) && errno == ERANGE)
-#endif
+      else if (__v == numeric_limits<long double>::infinity())
 	{
-	  if (__v > 0.0l)
-	    __v = numeric_limits<long double>::max();
-	  else
-	    __v = -numeric_limits<long double>::max();
+	  __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;
 	}
-
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
     }
 
   void
   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
-				    __c_locale)
+				    __c_locale __old)
   {
-    // Currently, the generic model only supports the "C" locale.
-    // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html
-    __cloc = 0;
-    if (strcmp(__s, "C"))
-      __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
-			    "name not valid"));
+    __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)
-  { __cloc = 0; }
+  {
+    if (__cloc && _S_get_c_locale() != __cloc)
+      freelocale((locale_t)__cloc);
+  }
 
   __c_locale
-  locale::facet::_S_clone_c_locale(__c_locale&) throw()
-  { return __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, const char*)
-  { return __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
@@ -263,5 +196,5 @@ 
 #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_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
+_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 -ur generic/c_locale.h dragonfly/c_locale.h
--- generic/c_locale.h	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/c_locale.h	2015-07-31 17:10:45.000000000 +0200
@@ -1,4 +1,4 @@ 
-// Wrapper for underlying C-language localization -*- C++ -*-
+// localization implementation details, DragonFly version -*- C++ -*-
 
 // Copyright (C) 2001-2015 Free Software Foundation, Inc.
 //
@@ -32,6 +32,7 @@ 
 //
 
 // 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
@@ -53,19 +54,11 @@ 
   // fall back to the unsafe vsprintf which, in general, can be dangerous
   // and should be avoided.
   inline int
-  __convert_from_v(const __c_locale&, char* __out, 
-		   const int __size __attribute__((__unused__)),
+  __convert_from_v(const __c_locale& __cloc, char* __out,
+		   const int __size __attribute__ ((__unused__)),
 		   const char* __fmt, ...)
   {
-    char* __old = std::setlocale(LC_NUMERIC, 0);
-    char* __sav = 0;
-    if (__builtin_strcmp(__old, "C"))
-      {
-	const size_t __len = __builtin_strlen(__old) + 1;
-	__sav = new char[__len];
-	__builtin_memcpy(__sav, __old, __len);
-	std::setlocale(LC_NUMERIC, "C");
-      }
+    __c_locale __old = (__c_locale)uselocale((locale_t)__cloc);
 
     __builtin_va_list __args;
     __builtin_va_start(__args, __fmt);
@@ -78,11 +71,7 @@ 
 
     __builtin_va_end(__args);
 
-    if (__sav)
-      {
-	std::setlocale(LC_NUMERIC, __sav);
-	delete [] __sav;
-      }
+    uselocale((locale_t)__old);
     return __ret;
   }
 
Only in generic: c++locale_internal.h
diff -ur generic/codecvt_members.cc dragonfly/codecvt_members.cc
--- generic/codecvt_members.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/codecvt_members.cc	2015-07-31 17:10:45.000000000 +0200
@@ -1,6 +1,6 @@ 
-// std::codecvt implementation details, generic version -*- C++ -*-
+// std::codecvt implementation details, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2002-2015 Free Software Foundation, Inc.
+// Copyright (C) 2015 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
@@ -27,11 +27,12 @@ 
 //
 
 // 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
-#include <cstring>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -47,60 +48,66 @@ 
 	 extern_type*& __to_next) const
   {
     result __ret = ok;
-    // The conversion must be done using a temporary destination buffer
-    // since it is not possible to pass the size of the buffer to wcrtomb
     state_type __tmp_state(__state);
 
-    // The conversion must be done by calling wcrtomb in a loop rather
-    // than using wcsrtombs because wcsrtombs assumes that the input is
-    // zero-terminated.
-
-    // Either we can upper bound the total number of external characters to
-    // something smaller than __to_end - __to or the conversion must be done
-    // using a temporary destination buffer since it is not possible to
-    // pass the size of the buffer to wcrtomb
-    if (MB_CUR_MAX * (__from_end - __from) - (__to_end - __to) <= 0)
-      while (__from < __from_end)
-	{
-	  const size_t __conv = wcrtomb(__to, *__from, &__tmp_state);
-	  if (__conv == static_cast<size_t>(-1))
-	    {
-	      __ret = error;
-	      break;
-	    }
-	  __state = __tmp_state;
-	  __to += __conv;
-	  __from++;
-	}
-    else
+    __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;)
       {
-	extern_type __buf[MB_LEN_MAX];
-	while (__from < __from_end && __to < __to_end)
+	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))
 	  {
-	    const size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
-	    if (__conv == static_cast<size_t>(-1))
-	      {
-		__ret = error;
-		break;
-	      }
-	    else if (__conv > static_cast<size_t>(__to_end - __to))
+	    // 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
 	      {
-		__ret = partial;
-		break;
+		memcpy(__to_next, __buf, __conv2);
+		__state = __tmp_state;
+		__to_next += __conv2;
+		++__from_next;
 	      }
-	    
-	    memcpy(__to, __buf, __conv);
-	    __state = __tmp_state;
-	    __to += __conv;
-	    __from++;
 	  }
       }
 
-    if (__ret == ok && __from < __from_end)
-      __ret = partial;
+    uselocale((locale_t)__old);
 
-    __from_next = __from;
-    __to_next = __to;
     return __ret; 
   }
   
@@ -112,47 +119,73 @@ 
 	intern_type*& __to_next) const
   {
     result __ret = ok;
-    // This temporary state object is necessary so __state won't be modified
-    // if [__from, __from_end) is a partial multibyte character.
     state_type __tmp_state(__state);
 
-    // Conversion must be done by calling mbrtowc in a loop rather than
-    // by calling mbsrtowcs because mbsrtowcs assumes that the input
-    // sequence is zero-terminated.
-    while (__from < __from_end && __to < __to_end)
+    __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;)
       {
-	size_t __conv = mbrtowc(__to, __from, __from_end - __from,
-				&__tmp_state);
+	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;
-	    break;
 	  }
-	else if (__conv == static_cast<size_t>(-2))
+	else if (__from_next && __from_next < __from_chunk_end)
 	  {
-	    // It is unclear what to return in this case (see DR 382).
+	    // It is unclear what to return in this case (see DR 382). 
+	    __to_next += __conv;
 	    __ret = partial;
-	    break;
 	  }
-	else if (__conv == 0)
+	else
 	  {
-	    // XXX Probably wrong for stateful encodings
-	    __conv = 1;
-	    *__to = L'\0';
+	    __from_next = __from_chunk_end;
+	    __to_next += __conv;
 	  }
 
-	__state = __tmp_state;
-	__to++;
-	__from += __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;
+	  }
       }
 
-    // It is not clear that __from < __from_end implies __ret != ok
-    // (see DR 382).
-    if (__ret == ok && __from < __from_end)
-      __ret = partial;
+    uselocale((locale_t)__old);
 
-    __from_next = __from;
-    __to_next = __to;
     return __ret; 
   }
 
@@ -163,8 +196,10 @@ 
     // 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;
   }  
 
@@ -172,8 +207,10 @@ 
   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;
   }
   
@@ -185,32 +222,64 @@ 
     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)
       {
-	size_t __conv = mbrtowc(0, __from, __end - __from, &__tmp_state);
+	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))
 	  {
-	    // Invalid source character
-	    break;
-	  }
-	else if (__conv == static_cast<size_t>(-2))
-	  {
-	    // Remainder of input does not form a complete destination
-	    // character.
+	    // 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;
 	  }
-	else if (__conv == 0)
+	if (!__from)
+	  __from = __from_chunk_end;
+	
+	__ret += __from - __tmp_from;
+	__max -= __conv;
+
+	if (__from < __end && __max)
 	  {
 	    // XXX Probably wrong for stateful encodings
-	    __conv = 1;
+	    __tmp_state = __state;
+	    ++__from;
+	    ++__ret;
+	    --__max;
 	  }
-
-	__state = __tmp_state;
-	__from += __conv;
-	__ret += __conv;
-	__max--;
       }
 
+    uselocale((locale_t)__old);
+
     return __ret; 
   }
 #endif
diff -ur generic/collate_members.cc dragonfly/collate_members.cc
--- generic/collate_members.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/collate_members.cc	2015-07-31 17:10:45.000000000 +0200
@@ -1,6 +1,6 @@ 
-// std::collate implementation details, generic version -*- C++ -*-
+// std::collate implementation details, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2001-2015 Free Software Foundation, Inc.
+// Copyright (C) 2015 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
@@ -27,6 +27,7 @@ 
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
 #include <locale>
 #include <cstring>
@@ -42,7 +43,7 @@ 
     collate<char>::_M_compare(const char* __one, 
 			      const char* __two) const throw()
     { 
-      int __cmp = strcoll(__one, __two);
+      int __cmp = strcoll_l(__one, __two, (locale_t)_M_c_locale_collate);
       return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
     }
   
@@ -50,7 +51,7 @@ 
     size_t
     collate<char>::_M_transform(char* __to, const char* __from, 
 				size_t __n) const throw()
-    { return strxfrm(__to, __from, __n); }
+    { return strxfrm_l(__to, __from, __n, (locale_t)_M_c_locale_collate); }
 
 #ifdef _GLIBCXX_USE_WCHAR_T
   template<>
@@ -58,7 +59,7 @@ 
     collate<wchar_t>::_M_compare(const wchar_t* __one, 
 				 const wchar_t* __two) const throw()
     {
-      int __cmp = wcscoll(__one, __two);
+      int __cmp = wcscoll_l(__one, __two, (locale_t)_M_c_locale_collate);
       return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
     }
   
@@ -66,7 +67,7 @@ 
     size_t
     collate<wchar_t>::_M_transform(wchar_t* __to, const wchar_t* __from,
 				   size_t __n) const throw()
-    { return wcsxfrm(__to, __from, __n); }
+    { return wcsxfrm_l(__to, __from, __n, (locale_t)_M_c_locale_collate); }
 #endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff -ur generic/ctype_members.cc dragonfly/ctype_members.cc
--- generic/ctype_members.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/ctype_members.cc	2015-07-31 17:10:46.000000000 +0200
@@ -1,6 +1,6 @@ 
-// std::ctype implementation details, generic version -*- C++ -*-
+// std::ctype implementation details, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2001-2015 Free Software Foundation, Inc.
+// Copyright (C) 2014-2015 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
@@ -27,12 +27,16 @@ 
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
 #include <locale>
-#include <cstdlib>
 #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
@@ -41,7 +45,7 @@ 
   // 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);
@@ -60,59 +64,57 @@ 
     switch (__m)
       {
       case space:
-	__ret = wctype("space");
+	__ret = wctype_l("space", (locale_t)_M_c_locale_ctype);
 	break;
       case print:
-	__ret = wctype("print");
+	__ret = wctype_l("print", (locale_t)_M_c_locale_ctype);
 	break;
       case cntrl:
-	__ret = wctype("cntrl");
+	__ret = wctype_l("cntrl", (locale_t)_M_c_locale_ctype);
 	break;
       case upper:
-	__ret = wctype("upper");
+	__ret = wctype_l("upper", (locale_t)_M_c_locale_ctype);
 	break;
       case lower:
-	__ret = wctype("lower");
+	__ret = wctype_l("lower", (locale_t)_M_c_locale_ctype);
 	break;
       case alpha:
-	__ret = wctype("alpha");
+	__ret = wctype_l("alpha", (locale_t)_M_c_locale_ctype);
 	break;
       case digit:
-	__ret = wctype("digit");
+	__ret = wctype_l("digit", (locale_t)_M_c_locale_ctype);
 	break;
       case punct:
-	__ret = wctype("punct");
+	__ret = wctype_l("punct", (locale_t)_M_c_locale_ctype);
 	break;
       case xdigit:
-	__ret = wctype("xdigit");
+	__ret = wctype_l("xdigit", (locale_t)_M_c_locale_ctype);
 	break;
       case alnum:
-	__ret = wctype("alnum");
+	__ret = wctype_l("alnum", (locale_t)_M_c_locale_ctype);
 	break;
       case graph:
-	__ret = wctype("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:
-	// For some targets ctype_base::blank == ctype_base::space so check
-	// here to avoid a duplicate case error.
-	if (__m == blank)
-	  __ret = wctype("blank");
-	else
-	  __ret = __wmask_type();
+	__ret = __wmask_type();
       }
     return __ret;
-  };
+  }
   
   wchar_t
   ctype<wchar_t>::do_toupper(wchar_t __c) const
-  { return towupper(__c); }
+  { 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(*__lo);
+        *__lo = towupper_l(*__lo, (locale_t)_M_c_locale_ctype);
         ++__lo;
       }
     return __hi;
@@ -120,78 +122,24 @@ 
   
   wchar_t
   ctype<wchar_t>::do_tolower(wchar_t __c) const
-  { return towlower(__c); }
+  { 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(*__lo);
+        *__lo = towlower_l(*__lo, (locale_t)_M_c_locale_ctype);
         ++__lo;
       }
     return __hi;
   }
 
-  bool
-  ctype<wchar_t>::
-  do_is(mask __m, char_type __c) const
-  { 
-    bool __ret = false;
-    // Generically, 15 (instead of 11) since we don't know the numerical
-    // encoding of the various categories in /usr/include/ctype.h.
-    const size_t __bitmasksize = 15; 
-    for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
-      if (__m & _M_bit[__bitcur]
-	  && iswctype(__c, _M_wmask[__bitcur]))
-	{
-	  __ret = true;
-	  break;
-	}
-    return __ret;    
-  }
-  
-  const wchar_t* 
-  ctype<wchar_t>::
-  do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
-  {
-    for (;__lo < __hi; ++__vec, ++__lo)
-      {
-	// Generically, 15 (instead of 11) since we don't know the numerical
-	// encoding of the various categories in /usr/include/ctype.h.
-	const size_t __bitmasksize = 15; 
-	mask __m = 0;
-	for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
-	  if (iswctype(*__lo, _M_wmask[__bitcur]))
-	    __m |= _M_bit[__bitcur];
-	*__vec = __m;
-      }
-    return __hi;
-  }
-  
-  const wchar_t* 
-  ctype<wchar_t>::
-  do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
-  {
-    while (__lo < __hi && !this->do_is(__m, *__lo))
-      ++__lo;
-    return __lo;
-  }
-
-  const wchar_t*
-  ctype<wchar_t>::
-  do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
-  {
-    while (__lo < __hi && this->do_is(__m, *__lo) != 0)
-      ++__lo;
-    return __lo;
-  }
-
   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
@@ -208,10 +156,12 @@ 
   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)); 
   }
 
@@ -220,6 +170,7 @@ 
   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)
 	{
@@ -241,12 +192,14 @@ 
 	  ++__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)
       {
@@ -260,15 +213,16 @@ 
       _M_narrow_ok = true;
     else
       _M_narrow_ok = false;
-    for (size_t __i = 0;
-	 __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
-      _M_widen[__i] = btowc(__i);
-
-    for (size_t __i = 0; __i <= 15; ++__i)
-      { 
-	_M_bit[__i] = static_cast<mask>(1 << __i);
-	_M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
-      }  
+    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
 
Only in generic: messages_members.cc
Only in generic: messages_members.h
diff -ur generic/monetary_members.cc dragonfly/monetary_members.cc
--- generic/monetary_members.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/monetary_members.cc	2015-07-31 17:10:45.000000000 +0200
@@ -1,6 +1,6 @@ 
-// std::moneypunct implementation details, generic version -*- C++ -*-
+// std::moneypunct implementation details, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2001-2015 Free Software Foundation, Inc.
+// Copyright (C) 2015 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
@@ -27,8 +27,11 @@ 
 //
 
 // 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)
 {
@@ -41,134 +44,859 @@ 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
   money_base::pattern
-  money_base::_S_construct_pattern(char, char, char) throw()
-  { return _S_default_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, const char*)
+    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc, 
+						     const char*)
     {
-      // "C" locale.
       if (!_M_data)
 	_M_data = new __moneypunct_cache<char, true>;
 
-      _M_data->_M_decimal_point = '.';
-      _M_data->_M_thousands_sep = ',';
-      _M_data->_M_grouping = "";
-      _M_data->_M_grouping_size = 0;
-      _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];
+      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, const char*)
+    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc, 
+						      const char*)
     {
-      // "C" locale.
       if (!_M_data)
 	_M_data = new __moneypunct_cache<char, false>;
 
-      _M_data->_M_decimal_point = '.';
-      _M_data->_M_thousands_sep = ',';
-      _M_data->_M_grouping = "";
-      _M_data->_M_grouping_size = 0;
-      _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];
+      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()
-    { delete _M_data; }
+    {
+      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()
-    { delete _M_data; }
+    {
+      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,
+    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc, 
 							const char*)
     {
-      // "C" locale
       if (!_M_data)
 	_M_data = new __moneypunct_cache<wchar_t, true>;
 
-      _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_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;
-
-      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]);
+      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,
-							 const char*)
-    {
-      // "C" locale
-      if (!_M_data)
-	_M_data = new __moneypunct_cache<wchar_t, false>;
+  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);
 
-      _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_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;
-
-      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]);
+	  uselocale((locale_t)__old);
+	}
     }
 
   template<>
     moneypunct<wchar_t, true>::~moneypunct()
-    { delete _M_data; }
+    {
+      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()
-    { delete _M_data; }
+    {
+      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
diff -ur generic/numeric_members.cc dragonfly/numeric_members.cc
--- generic/numeric_members.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/numeric_members.cc	2015-07-31 17:10:45.000000000 +0200
@@ -1,6 +1,6 @@ 
-// std::numpunct implementation details, generic version -*- C++ -*-
+// std::numpunct implementation details, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2001-2015 Free Software Foundation, Inc.
+// Copyright (C) 2015 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
@@ -27,8 +27,11 @@ 
 //
 
 // 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)
 {
@@ -36,71 +39,197 @@ 
 
   template<> 
     void
-    numpunct<char>::_M_initialize_numpunct(__c_locale)
+    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
     {
-      // "C" locale
       if (!_M_data)
 	_M_data = new __numpunct_cache<char>;
 
-      _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 __i = 0; __i < __num_base::_S_iend; ++__i)
-	_M_data->_M_atoms_in[__i] = __num_base::_S_atoms_in[__i];
+      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()
-    { delete _M_data; }
-      
+    {
+      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)
+    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
     {
-      // "C" locale
       if (!_M_data)
 	_M_data = new __numpunct_cache<wchar_t>;
 
-      _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 __i = 0; __i < __num_base::_S_iend; ++__i)
-	_M_data->_M_atoms_in[__i] =
-	  static_cast<wchar_t>(__num_base::_S_atoms_in[__i]);
+      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()
-    { delete _M_data; }
-#endif
+    {
+      if (_M_data->_M_grouping_size)
+	delete [] _M_data->_M_grouping;
+      delete _M_data;
+    }
+ #endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
-
diff -ur generic/time_members.cc dragonfly/time_members.cc
--- generic/time_members.cc	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/time_members.cc	2015-07-31 17:10:45.000000000 +0200
@@ -1,4 +1,4 @@ 
-// std::time_get, std::time_put implementation, generic version -*- C++ -*-
+// std::time_get, std::time_put implementation, DragonFly version -*- C++ -*-
 
 // Copyright (C) 2001-2015 Free Software Foundation, Inc.
 //
@@ -28,10 +28,14 @@ 
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
 #include <locale>
-#include <cstdlib>
-#include <cstring>
+#include <ctime>
+#include <cwchar>
+#include <stdlib.h>
+#include <langinfo.h>
+#include <xlocale.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -40,171 +44,360 @@ 
   template<>
     void
     __timepunct<char>::
-    _M_put(char* __s, size_t __maxlen, const char* __format,
+    _M_put(char* __s, size_t __maxlen, const char* __format, 
 	   const tm* __tm) const throw()
     {
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __llen = strlen(__old) + 1;
-      char* __sav = new char[__llen];
-      memcpy(__sav, __old, __llen);
-      setlocale(LC_ALL, _M_name_timepunct);
-      const size_t __len = strftime(__s, __maxlen, __format, __tm);
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
+      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<>
+  template<> 
     void
-    __timepunct<char>::_M_initialize_timepunct(__c_locale)
+    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc)
     {
-      // "C" locale.
       if (!_M_data)
 	_M_data = new __timepunct_cache<char>;
 
-      _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";
+      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,
+    _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format, 
 	   const tm* __tm) const throw()
     {
-      char* __old = setlocale(LC_ALL, 0);
-      const size_t __llen = strlen(__old) + 1;
-      char* __sav = new char[__llen];
-      memcpy(__sav, __old, __llen);
-      setlocale(LC_ALL, _M_name_timepunct);
-      const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
-      setlocale(LC_ALL, __sav);
-      delete [] __sav;
+      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';
     }
 
-  template<>
+#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)
+    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc)
     {
-      // "C" locale.
       if (!_M_data)
 	_M_data = new __timepunct_cache<wchar_t>;
 
-      _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";
+      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
+	{
+	  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
diff -ur generic/time_members.h dragonfly/time_members.h
--- generic/time_members.h	2015-02-13 08:19:54.000000000 +0100
+++ dragonfly/time_members.h	2015-07-31 17:10:45.000000000 +0200
@@ -1,6 +1,6 @@ 
-// std::time_get, std::time_put implementation, generic version -*- C++ -*-
+// std::time_get, std::time_put implementation, DragonFly version -*- C++ -*-
 
-// Copyright (C) 2001-2015 Free Software Foundation, Inc.
+// Copyright (C) 2015 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
@@ -33,6 +33,7 @@ 
 //
 
 // Written by Benjamin Kosnik <bkoz@redhat.com>
+// Modified for DragonFly by John Marino <gnugcc@marino.st>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -40,24 +41,21 @@ 
 
   template<typename _CharT>
     __timepunct<_CharT>::__timepunct(size_t __refs) 
-    : facet(__refs), _M_data(0)
-    { 
-      _M_name_timepunct = _S_get_c_name();
-      _M_initialize_timepunct(); 
-    }
+    : 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_name_timepunct = _S_get_c_name();
-      _M_initialize_timepunct(); 
-    }
+    : 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, 
+    __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
 				     size_t __refs) 
-    : facet(__refs), _M_data(0)
+    : facet(__refs), _M_data(0), _M_c_locale_timepunct(0), 
+      _M_name_timepunct(0)
     {
       if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
 	{
@@ -84,9 +82,14 @@ 
     { 
       if (_M_name_timepunct != _S_get_c_name())
 	delete [] _M_name_timepunct;
-      delete _M_data;
+      delete _M_data; 
       _S_destroy_c_locale(_M_c_locale_timepunct); 
     }
 
+  // specialization
+  template<>
+    __timepunct<wchar_t>::~__timepunct();
+
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace