diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.tcc | 16 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/22_locale/money_put_members_char.cc | 30 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc | 30 |
4 files changed, 80 insertions, 9 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 92dfd01..0377185 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2002-03-18 Paolo Carlini <pcarlini@unitus.it> + + * include/bits/locale_facets.tcc + (money_put::do_put(long double)): Fix dimensioning of + temporary buffers to avoid risk of overruns. + (money_put::do_put(string)): Same for the buffer used to + add the grouping chars. + * testsuite/22_locale/money_put_members_char.cc: Add test06. + * testsuite/22_locale/money_put_members_wchar_t.cc: Ditto. + + * include/bits/locale_facets.tcc + (collate::do_transform): Simplify. + 2002-03-18 Phil Edwards <pme@gcc.gnu.org> * acinclude.m4 (GLIBCPP_CONFIGURE): Make indentation/spacing uniform. diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 37ad6b3..f2a1789 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -1110,8 +1110,10 @@ namespace std long double __units) const { const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - const int __n = numeric_limits<long double>::digits10; + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point, + // decimal digit, '\0'. + const int __n = numeric_limits<long double>::max_exponent10 + 5; char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n)); _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale); @@ -1206,8 +1208,9 @@ namespace std : __mpf.thousands_sep(); const char* __gbeg = __grouping.c_str(); const char* __gend = __gbeg + __grouping.size(); - const int __n = numeric_limits<long double>::digits10 * 2; - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); + const int __n = (__end - __beg) * 2; + _CharT* __ws2 = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, __gend, __beg, __end); __value.insert(0, __ws2, __ws_end - __ws2); @@ -1863,10 +1866,9 @@ namespace std // If the buffer was not large enough, try again with the correct size. if (__res >= __len) { - _CharT* __c2 = + __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1))); - _M_transform_helper(__c2, __lo, __res + 1); - return string_type(__c2); + _M_transform_helper(__c, __lo, __res + 1); } return string_type(__c); } diff --git a/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc b/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc index c894b18..a97f78f 100644 --- a/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc +++ b/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc @@ -226,7 +226,7 @@ void test02() oss.setf(ios_base::showbase); oss.str(empty); - iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); + iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); string result3 = oss.str(); VERIFY( result3 == "7.200.000.000,00 DEM "); @@ -341,6 +341,33 @@ void test05() VERIFY( fmt.str() == "*(1,234.56)" ); } +struct My_money_io_2 : public std::moneypunct<char,false> +{ + char_type do_thousands_sep() const { return ','; } + std::string do_grouping() const { return "\001"; } +}; + +// Make sure we can output a very big amount of money (with grouping too). +void test06() +{ + using namespace std; + typedef ostreambuf_iterator<char> OutIt; + + locale loc(locale::classic(), new My_money_io_2); + + bool intl = false; + + long double val = 1e50L; + const money_put<char,OutIt>& mp = + use_facet<money_put<char, OutIt> >(loc); + + ostringstream fmt; + fmt.imbue(loc); + OutIt out(fmt); + mp.put(out,intl,fmt,'*',val); + VERIFY( fmt ); +} + int main() { test01(); @@ -348,5 +375,6 @@ int main() test03(); test04(); test05(); + test06(); return 0; } diff --git a/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc b/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc index 09feadd..dc77d0a 100644 --- a/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc +++ b/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc @@ -226,7 +226,7 @@ void test02() oss.setf(ios_base::showbase); oss.str(empty); - iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); + iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); wstring result3 = oss.str(); VERIFY( result3 == L"7.200.000.000,00 DEM "); @@ -340,6 +340,33 @@ void test05() mp.put(out,intl,fmt,L'*',val); VERIFY( fmt.str() == L"*(1,234.56)" ); } + +struct My_money_io_2 : public std::moneypunct<wchar_t,false> +{ + char_type do_thousands_sep() const { return L','; } + std::string do_grouping() const { return "\001"; } +}; + +// Make sure we can output a very big amount of money (with grouping too). +void test06() +{ + using namespace std; + typedef ostreambuf_iterator<wchar_t> OutIt; + + locale loc(locale::classic(), new My_money_io_2); + + bool intl = false; + + long double val = 1e50L; + const money_put<wchar_t,OutIt>& mp = + use_facet<money_put<wchar_t, OutIt> >(loc); + + wostringstream fmt; + fmt.imbue(loc); + OutIt out(fmt); + mp.put(out,intl,fmt,'*',val); + VERIFY( fmt ); +} #endif int main() @@ -350,6 +377,7 @@ int main() test03(); test04(); test05(); + test06(); #endif return 0; } |