From 75978a60ac0c368617f1b03b972f9480660cc282 Mon Sep 17 00:00:00 2001 From: John Marino Date: Sun, 19 Jul 2015 00:22:03 +0200 Subject: [PATCH] gcc50: Change c++ locale handling The biggest change is removing the modification of the specified locale. Before locales without extensions were appended with ".UTF-8" and modifiers (e.g. @euro) were silently stripped off. The latter is probably a bad idea, and even if we want to continue doing this (modifiers are not supported), it should be done at the library level, not at c++ on gcc level. The no-extension problem has been solved today by creating symlinks at /usr/share/locale. The logic of the "gnu" support was mimicked by using newlocale, duplocale, and freelocale. The generic version uses setlocale only. This patch will be pushed upstream most likely. --- contrib/gcc-5.0/README.DRAGONFLY | 1 + .../config/locale/dragonfly/c_locale.cc | 67 +++++++------------ 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/contrib/gcc-5.0/README.DRAGONFLY b/contrib/gcc-5.0/README.DRAGONFLY index 415cca68ca..241d0e0dbc 100644 --- a/contrib/gcc-5.0/README.DRAGONFLY +++ b/contrib/gcc-5.0/README.DRAGONFLY @@ -23,3 +23,4 @@ The following files have been patched (* planned) gcc/ginclude/stddef.h * gcc/tree-inline.c libstdc++-v3/config/os/bsd/dragonfly/os_defines.h + libstdc++-v3/config/locale/dragonfly/c_locale.cc diff --git a/contrib/gcc-5.0/libstdc++-v3/config/locale/dragonfly/c_locale.cc b/contrib/gcc-5.0/libstdc++-v3/config/locale/dragonfly/c_locale.cc index dea7a391c7..18c6ad7112 100644 --- a/contrib/gcc-5.0/libstdc++-v3/config/locale/dragonfly/c_locale.cc +++ b/contrib/gcc-5.0/libstdc++-v3/config/locale/dragonfly/c_locale.cc @@ -36,6 +36,7 @@ #include #include +#include #ifdef _GLIBCXX_HAVE_IEEEFP_H #include #endif @@ -206,61 +207,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION delete [] __sav; } - - /* 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); + __cloc = (__c_locale)newlocale(LC_ALL_MASK, __s, (locale_t)__old); - if ((strcmp(result, "C") != 0) && (strcmp (result, localspec) != 0)) + if (!__cloc) __throw_runtime_error(__N("locale::facet::_S_create_c_locale " "name not valid")); - __cloc = 0; } 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 -- 2.41.0