From 575dd831c71130cb7fe25e8e99cae094227efaa2 Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Fri, 24 Aug 2001 04:11:23 +0000 Subject: [PATCH] c_locale_gnu.cc: Minor tweaks. 2001-08-23 Benjamin Kosnik * config/locale/c_locale_gnu.cc: Minor tweaks. (moneypunct): Implement. * include/bits/locale_facets.h: Same. * testsuite/22_locale/moneypunct.cc: New file. * testsuite/22_locale/moneypunct_byname.cc: New file. * testsuite/22_locale/moneypunct_char_members.cc: New file. From-SVN: r45142 --- libstdc++-v3/ChangeLog | 9 ++ libstdc++-v3/config/locale/c_locale_gnu.cc | 74 +++++++++--- libstdc++-v3/include/bits/locale_facets.h | 1 + .../testsuite/22_locale/moneypunct.cc | 52 +++++++++ .../testsuite/22_locale/moneypunct_byname.cc | 102 +++++++++++++++++ .../22_locale/moneypunct_char_members.cc | 108 ++++++++++++++++++ .../testsuite/22_locale/numpunct_byname.cc | 10 ++ 7 files changed, 340 insertions(+), 16 deletions(-) create mode 100644 libstdc++-v3/testsuite/22_locale/moneypunct.cc create mode 100644 libstdc++-v3/testsuite/22_locale/moneypunct_byname.cc create mode 100644 libstdc++-v3/testsuite/22_locale/moneypunct_char_members.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index aafc29d31734..672ed390434f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2001-08-23 Benjamin Kosnik + + * config/locale/c_locale_gnu.cc: Minor tweaks. + (moneypunct): Implement. + * include/bits/locale_facets.h: Same. + * testsuite/22_locale/moneypunct.cc: New file. + * testsuite/22_locale/moneypunct_byname.cc: New file. + * testsuite/22_locale/moneypunct_char_members.cc: New file. + 2001-08-23 David Edelsohn * config/os/gnu-linux/bits/os_defines.h: Correct __s390__ definitions. diff --git a/libstdc++-v3/config/locale/c_locale_gnu.cc b/libstdc++-v3/config/locale/c_locale_gnu.cc index e81a52c1750b..57c69e59951e 100644 --- a/libstdc++-v3/config/locale/c_locale_gnu.cc +++ b/libstdc++-v3/config/locale/c_locale_gnu.cc @@ -1,4 +1,3 @@ - // Wrapper for underlying C-language localization -*- C++ -*- // Copyright (C) 2001 Free Software Foundation, Inc. @@ -44,9 +43,9 @@ namespace std locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s) { // XXX - // perhaps locale::categories could be made equivalent to LC_*_MASK - // _M_c_locale = __newlocale(1 << LC_ALL, __str.c_str(), NULL); - // _M_c_locale = __newlocale(locale::all, __str.c_str(), NULL); + // Perhaps locale::categories could be made equivalent to LC_*_MASK ? + // _M_c_locale = __newlocale(1 << LC_ALL, __s, 0); + // _M_c_locale = __newlocale(locale::all, __s, 0); __cloc = __newlocale(1 << LC_ALL, __s, 0); if (!__cloc) { @@ -181,19 +180,62 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T template<> void - moneypunct::_M_initialize_moneypunct(__c_locale /*__cloc*/) + moneypunct::_M_initialize_moneypunct(__c_locale __cloc) { - // XXX implement - // "C" locale - _M_decimal_point = L'.'; - _M_thousands_sep = L','; - _M_grouping = ""; - _M_curr_symbol = string_type(); - _M_positive_sign = string_type(); - _M_negative_sign = string_type(); - _M_frac_digits = 0; - _M_pos_format = money_base::_S_default_pattern; - _M_neg_format = money_base::_S_default_pattern; + if (!__cloc) + { + // "C" locale + _M_decimal_point = L'.'; + _M_thousands_sep = L','; + _M_grouping = ""; + _M_curr_symbol = string_type(); + _M_positive_sign = string_type(); + _M_negative_sign = string_type(); + _M_frac_digits = 0; + _M_pos_format = money_base::_S_default_pattern; + _M_neg_format = money_base::_S_default_pattern; + } + else + { + // Named locale. + _M_decimal_point = reinterpret_cast(__nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)); + _M_thousands_sep = reinterpret_cast(__nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC,__cloc)); + _M_grouping = __nl_langinfo_l(GROUPING, __cloc); + _M_positive_sign = reinterpret_cast(__nl_langinfo_l(__POSITIVE_SIGN, __cloc)); + _M_negative_sign = reinterpret_cast(__nl_langinfo_l(__NEGATIVE_SIGN, __cloc)); + if (intl) + { + _M_curr_symbol = reinterpret_cast(__nl_langinfo_l(__INT_CURR_SYMBOL, __cloc)); + _M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, __cloc)); + char __ppreceeds = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, + __cloc)); + char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); + char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); + _M_pos_format = _S_construct_pattern(__ppreceeds, __pspace, + __pposn); + char __npreceeds = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, + __cloc)); + char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); + char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); + _M_neg_format = _S_construct_pattern(__npreceeds, __nspace, + __nposn); + } + else + { + _M_curr_symbol = reinterpret_cast(__nl_langinfo_l(__CURRENCY_SYMBOL, __cloc)); + _M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); + char __ppreceeds = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); + char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); + char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); + _M_pos_format = _S_construct_pattern(__ppreceeds, __pspace, + __pposn); + char __npreceeds = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); + char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); + char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); + _M_neg_format = _S_construct_pattern(__npreceeds, __nspace, + __nposn); + } + } } #endif } // namespace std diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 159becfa7e5d..ffef999ca05f 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -1448,6 +1448,7 @@ namespace std class moneypunct_byname : public moneypunct<_CharT, _Intl> { __c_locale _M_c_locale_moneypunct; + public: typedef _CharT char_type; typedef basic_string<_CharT> string_type; diff --git a/libstdc++-v3/testsuite/22_locale/moneypunct.cc b/libstdc++-v3/testsuite/22_locale/moneypunct.cc new file mode 100644 index 000000000000..256369a00935 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/moneypunct.cc @@ -0,0 +1,52 @@ +// 2001-08-23 Benjamin Kosnik + +// Copyright (C) 2001 Free Software Foundation +// +// 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 2, 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 22.2.6.3 Template class moneypunct + +#include + +void test01() +{ + // Check for required base class. + typedef std::moneypunct test_type; + typedef std::locale::facet base_type; + const test_type& obj = std::use_facet(std::locale()); + const base_type* base = &obj; + + // Check for required typedefs + typedef test_type::char_type char_type; + typedef test_type::string_type string_type; +} + +// Should be able to instantiate this for other types besides char, wchar_t +class gnu_moneypunct: public std::moneypunct +{ }; + +void test02() +{ + gnu_moneypunct facet01; +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/moneypunct_byname.cc b/libstdc++-v3/testsuite/22_locale/moneypunct_byname.cc new file mode 100644 index 000000000000..e86c80e7426f --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/moneypunct_byname.cc @@ -0,0 +1,102 @@ +// 2001-08-24 Benjamin Kosnik + +// Copyright (C) 2001 Free Software Foundation +// +// 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 2, 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 22.2.6.4 Template class moneypunct_byname + +#include +#include + +// XXX This test is not working for non-glibc locale models. +// { dg-do run { xfail *-*-* } } + +void test01() +{ + using namespace std; + typedef money_base::part part; + typedef money_base::pattern pattern; + + bool test = true; + string str; + + locale loc_byname(locale::classic(), new moneypunct_byname("de_DE")); + str = loc_byname.name(); + + locale loc_de("de_DE"); + str = loc_de.name(); + + locale loc_c = locale::classic(); + + VERIFY( loc_de != loc_byname ); + + // cache the moneypunct facets + const moneypunct& monp_c = use_facet >(loc_c); + const moneypunct& monp_byname = + use_facet >(loc_byname); + const moneypunct& monp_de = use_facet >(loc_de); + + // sanity check that the data match + char dp1 = monp_de.decimal_point(); + char th1 = monp_de.thousands_sep(); + string g1 = monp_de.grouping(); + string cs1 = monp_de.curr_symbol(); + string ps1 = monp_de.positive_sign(); + string ns1 = monp_de.negative_sign(); + int fd1 = monp_de.frac_digits(); + pattern pos1 = monp_de.pos_format(); + pattern neg1 = monp_de.neg_format(); + + char dp2 = monp_byname.decimal_point(); + char th2 = monp_byname.thousands_sep(); + string g2 = monp_byname.grouping(); + string cs2 = monp_byname.curr_symbol(); + string ps2 = monp_byname.positive_sign(); + string ns2 = monp_byname.negative_sign(); + int fd2 = monp_byname.frac_digits(); + pattern pos2 = monp_byname.pos_format(); + pattern neg2 = monp_byname.neg_format(); + + VERIFY( dp1 == dp2 ); + VERIFY( th1 == th2 ); + VERIFY( g1 == g2 ); + VERIFY( cs1 == cs2 ); + VERIFY( ps1 == ps2 ); + VERIFY( ns1 == ns2 ); + VERIFY( fd1 == fd2 ); + VERIFY(static_cast(pos1.field[0]) == static_cast(pos2.field[0])); + VERIFY(static_cast(pos1.field[1]) == static_cast(pos2.field[1])); + VERIFY(static_cast(pos1.field[2]) == static_cast(pos2.field[2])); + VERIFY(static_cast(pos1.field[3]) == static_cast(pos2.field[3])); + + VERIFY(static_cast(neg1.field[0]) == static_cast(neg2.field[0])); + VERIFY(static_cast(neg1.field[1]) == static_cast(neg2.field[1])); + VERIFY(static_cast(neg1.field[2]) == static_cast(neg2.field[2])); + VERIFY(static_cast(neg1.field[3]) == static_cast(neg2.field[3])); + + // ...and don't match "C" + char dp3 = monp_c.decimal_point(); + VERIFY( dp1 != dp3 ); +} + +int main() +{ + test01(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/moneypunct_char_members.cc b/libstdc++-v3/testsuite/22_locale/moneypunct_char_members.cc new file mode 100644 index 000000000000..1ddd4268c5ce --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/moneypunct_char_members.cc @@ -0,0 +1,108 @@ +// 2001-08-23 Benjamin Kosnik + +// Copyright (C) 2001 Free Software Foundation +// +// 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 2, 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 22.2.6.3.1 moneypunct members + +#include +#include + +// XXX This test is not working for non-glibc locale models. +// { dg-do run { xfail *-*-* } } + +void test01() +{ + using namespace std; + typedef money_base::part part; + typedef money_base::pattern pattern; + + bool test = true; + string str; + + // basic construction + locale loc_c = locale::classic(); + str = loc_c.name(); + + locale loc_us("en_US"); + str = loc_us.name(); + VERIFY( loc_c != loc_us ); + + locale loc_fr("fr_FR"); + str = loc_fr.name(); + VERIFY( loc_c != loc_fr ); + + locale loc_de("de_DE"); + str = loc_de.name(); + VERIFY( loc_c != loc_de ); + + VERIFY( loc_us != loc_fr ); + VERIFY( loc_us != loc_de ); + VERIFY( loc_de != loc_fr ); + + // cache the moneypunct facets + const moneypunct& monp_c = use_facet >(loc_c); + const moneypunct& monp_us = use_facet >(loc_us); + const moneypunct& monp_fr = use_facet >(loc_fr); + const moneypunct& monp_de = use_facet >(loc_de); + + // sanity check the data is correct. + char dp1 = monp_c.decimal_point(); + char th1 = monp_c.thousands_sep(); + string g1 = monp_c.grouping(); + string cs1 = monp_c.curr_symbol(); + string ps1 = monp_c.positive_sign(); + string ns1 = monp_c.negative_sign(); + int fd1 = monp_c.frac_digits(); + pattern pos1 = monp_c.pos_format(); + pattern neg1 = monp_c.neg_format(); + + char dp2 = monp_de.decimal_point(); + char th2 = monp_de.thousands_sep(); + string g2 = monp_de.grouping(); + string cs2 = monp_de.curr_symbol(); + string ps2 = monp_de.positive_sign(); + string ns2 = monp_de.negative_sign(); + int fd2 = monp_de.frac_digits(); + pattern pos2 = monp_de.pos_format(); + pattern neg2 = monp_de.neg_format(); + + VERIFY( dp1 != dp2 ); + VERIFY( th1 != th2 ); + VERIFY( g1 != g2 ); + VERIFY( cs1 != cs2 ); + // VERIFY( ps1 != ps2 ); + VERIFY( ns1 != ns2 ); + VERIFY( fd1 != fd2 ); + VERIFY(static_cast(pos1.field[0]) != static_cast(pos2.field[0])); + VERIFY(static_cast(pos1.field[1]) != static_cast(pos2.field[1])); + VERIFY(static_cast(pos1.field[2]) != static_cast(pos2.field[2])); + VERIFY(static_cast(pos1.field[3]) != static_cast(pos2.field[3])); + + VERIFY(static_cast(neg1.field[0]) != static_cast(neg2.field[0])); + VERIFY(static_cast(neg1.field[1]) != static_cast(neg2.field[1])); + VERIFY(static_cast(neg1.field[2]) != static_cast(neg2.field[2])); + VERIFY(static_cast(neg1.field[3]) != static_cast(neg2.field[3])); +} + +int main() +{ + test01(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/numpunct_byname.cc b/libstdc++-v3/testsuite/22_locale/numpunct_byname.cc index 5fbbcc251bef..6b6d7d80a0f3 100644 --- a/libstdc++-v3/testsuite/22_locale/numpunct_byname.cc +++ b/libstdc++-v3/testsuite/22_locale/numpunct_byname.cc @@ -23,6 +23,9 @@ #include #include +// XXX This test is not working for non-glibc locale models. +// { dg-do run { xfail *-*-* } } + void test01() { using namespace std; @@ -36,9 +39,12 @@ void test01() locale loc_de("de_DE"); str = loc_de.name(); + locale loc_c = locale::classic(); + VERIFY( loc_de != loc_byname ); // cache the numpunct facets + const numpunct& nump_c = use_facet >(loc_c); const numpunct& nump_byname = use_facet >(loc_byname); const numpunct& nump_de = use_facet >(loc_de); @@ -60,6 +66,10 @@ void test01() VERIFY( g1 == g2 ); VERIFY( t1 == t2 ); VERIFY( f1 == f2 ); + + // ...and don't match "C" + char dp3 = nump_c.decimal_point(); + VERIFY( dp1 != dp3 ); } int main()