From d3a193e36cdf55fbff3bd0f244bc36bc09871ee1 Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Tue, 16 Apr 2002 00:45:36 +0000 Subject: [PATCH] re PR libstdc++/4164 (33 Memory Leak when using iostream) 2002-04-15 Benjamin Kosnik PR libstdc++/4164 Valgrind fixes. * config/io/basic_file_stdio.cc (__basic_file::~__basic_file): Call close. (__basic_file::close): Call fflush. Correct return if fclose ok. (__basic_file::is_open): Make const. Change __c_file_type to __c_file. * config/io/basic_file_stdio.h: Change __c_file_type to __c_file. (__basic_file::is_open): Make const. * config/io/c_io_stdio.h: Change __c_file_type to __c_file. * include/std/std_fstream.h (filebuf::_M_allocate_file): Remove. (filebuf::_M_unbuf): Add. (filebuf::_M_file): Change to non-pointer. (filebuf::_M_allocate_pback_buffer): Remove. * include/bits/fstream.tcc (filebuf::_M_allocate_file): Remove. (filebuf::_M_allocate_internal_buffer): Use _M_unbuf. Change initialization list for _M_file change. (filebuf::_M_allocate_pback_buffer): Remove. Change _M_file usage to reflect non-pointer data member. * config/locale/generic/c_locale.cc (locale::facet::_S_create_c_locale): Add parameter. * config/locale/generic/collate_members.cc: Change _M_compare_helper to _M_compare. Change _M_transform_helper to _M_transform. * config/locale/generic/monetary_members.cc: Changeup data types. Add dtors. * config/locale/generic/numeric_members.cc: Add dtors. * config/locale/generic/time_members.cc: Add dtors. * config/locale/gnu/c_locale.cc: Add parameter. * config/locale/gnu/collate_members.cc:Change _M_compare_helper to _M_compare. Change _M_transform_helper to _M_transform. * config/locale/gnu/ctype_members.cc: Better error checking. * config/os/gnu-linux/bits/ctype_noninline.h: Better error checking. * config/locale/gnu/messages_members.cc: Tweak comment. * config/locale/gnu/monetary_members.cc: Change data types. Add dtors. * config/locale/gnu/numeric_members.cc: Add dtors, better error checking. * config/locale/gnu/time_members.cc: Same. * config/locale/ieee_1003.1-2001/c_locale.cc (locale::facet::_S_create_c_locale): Add parameter. * config/locale/ieee_1003.1-2001/c_locale.h: Correct typedef. * config/locale/ieee_1003.1-2001/codecvt_specializations.h: Remove bogus ctor. * include/bits/locale_facets.h (moneypunct): Use string literals. Don't define dtor. (numpunct): Same. (__timepunct): Same. (locale::_Impl::_M_facets): Change from vector to array. (locale::_Impl::_M_names): Change from array of strings to array of string literals. (locale::facet::_S_create_c_locale): Add parameter. (locale::locale::_S_num_facets): Move to... (locale::_Impl::_M_facets_size): Here. * include/bits/locale_facets.tcc: Fixups for _M_facets, _M_name changes. * include/bits/localefwd.h: (locale::id::_M_id): Add member function. (locale::_Impl::_Impl(facet**, size_t, bool)): Add. (locale::_Impl::_Impl(string, size_t)): Change to (locale::_Impl::_Impl(const char*, size_t)): This. * include/bits/streambuf.tcc (streambuf::_S_pback_size): Define. * include/std/std_streambuf.h (streambuf::_M_pback_size): Change to (streambuf::_S_pback_size): This. * src/globals.cc: Add pre-allocations for "C" facets. * src/locale-inst.cc: Remove vector instantiations. * src/locale.cc: Remove vector include. Fixups for _M_names, _M_facets changes. * src/localename.cc: Same. * include/bits/stl_vector.h: Fix odd formatting. * include/bits/basic_string.tcc: Tweak comment. * libsupc++/new: Make sure parameters are uglified. * libsupc++/typeinfo: Same. * testsuite/22_locale/num_get_members_char.cc: Fixup. * testsuite/22_locale/num_get_members_wchar_t.cc: Same. * testsuite/27_io/filebuf_members.cc: Same. From-SVN: r52345 --- libstdc++-v3/ChangeLog | 87 +++++++++ libstdc++-v3/config/io/basic_file_stdio.cc | 23 +-- libstdc++-v3/config/io/basic_file_stdio.h | 6 +- libstdc++-v3/config/io/c_io_stdio.h | 2 +- libstdc++-v3/config/locale/generic/c_locale.cc | 7 +- .../config/locale/generic/collate_members.cc | 17 +- .../config/locale/generic/monetary_members.cc | 42 ++-- .../config/locale/generic/numeric_members.cc | 8 + libstdc++-v3/config/locale/generic/time_members.cc | 22 ++- libstdc++-v3/config/locale/gnu/c_locale.cc | 9 +- libstdc++-v3/config/locale/gnu/collate_members.cc | 15 +- libstdc++-v3/config/locale/gnu/ctype_members.cc | 10 +- libstdc++-v3/config/locale/gnu/messages_members.cc | 2 +- libstdc++-v3/config/locale/gnu/monetary_members.cc | 192 ++++++++++-------- libstdc++-v3/config/locale/gnu/numeric_members.cc | 16 +- libstdc++-v3/config/locale/gnu/time_members.cc | 36 ++-- .../config/locale/ieee_1003.1-2001/c_locale.cc | 4 +- .../config/locale/ieee_1003.1-2001/c_locale.h | 9 +- .../ieee_1003.1-2001/codecvt_specializations.h | 21 -- .../config/os/gnu-linux/bits/ctype_noninline.h | 4 +- libstdc++-v3/include/bits/basic_string.tcc | 2 +- libstdc++-v3/include/bits/fstream.tcc | 127 +++++------- libstdc++-v3/include/bits/locale_facets.h | 127 +++++++----- libstdc++-v3/include/bits/locale_facets.tcc | 105 +++++----- libstdc++-v3/include/bits/localefwd.h | 56 +++--- libstdc++-v3/include/bits/stl_vector.h | 26 +-- libstdc++-v3/include/bits/streambuf.tcc | 4 + libstdc++-v3/include/std/std_fstream.h | 28 ++- libstdc++-v3/include/std/std_streambuf.h | 10 +- libstdc++-v3/libsupc++/new | 20 +- libstdc++-v3/libsupc++/typeinfo | 2 +- libstdc++-v3/src/globals.cc | 122 +++++++++++- libstdc++-v3/src/locale-inst.cc | 23 --- libstdc++-v3/src/locale.cc | 59 +++--- libstdc++-v3/src/localename.cc | 217 +++++++++++++++------ .../testsuite/22_locale/num_get_members_char.cc | 3 +- .../testsuite/22_locale/num_get_members_wchar_t.cc | 3 +- libstdc++-v3/testsuite/27_io/filebuf_members.cc | 4 +- 38 files changed, 915 insertions(+), 555 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1611797..0bf364c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,90 @@ +2002-04-15 Benjamin Kosnik + + PR libstdc++/4164 + Valgrind fixes. + * config/io/basic_file_stdio.cc (__basic_file::~__basic_file): + Call close. + (__basic_file::close): Call fflush. Correct return if fclose ok. + (__basic_file::is_open): Make const. + Change __c_file_type to __c_file. + * config/io/basic_file_stdio.h: Change __c_file_type to __c_file. + (__basic_file::is_open): Make const. + * config/io/c_io_stdio.h: Change __c_file_type to __c_file. + * include/std/std_fstream.h (filebuf::_M_allocate_file): Remove. + (filebuf::_M_unbuf): Add. + (filebuf::_M_file): Change to non-pointer. + (filebuf::_M_allocate_pback_buffer): Remove. + * include/bits/fstream.tcc (filebuf::_M_allocate_file): Remove. + (filebuf::_M_allocate_internal_buffer): Use _M_unbuf. + Change initialization list for _M_file change. + (filebuf::_M_allocate_pback_buffer): Remove. + Change _M_file usage to reflect non-pointer data member. + + * config/locale/generic/c_locale.cc + (locale::facet::_S_create_c_locale): Add parameter. + * config/locale/generic/collate_members.cc: Change + _M_compare_helper to _M_compare. + Change _M_transform_helper to _M_transform. + * config/locale/generic/monetary_members.cc: Changeup data types. + Add dtors. + * config/locale/generic/numeric_members.cc: Add dtors. + * config/locale/generic/time_members.cc: Add dtors. + * config/locale/gnu/c_locale.cc: Add parameter. + * config/locale/gnu/collate_members.cc:Change + _M_compare_helper to _M_compare. + Change _M_transform_helper to _M_transform. + * config/locale/gnu/ctype_members.cc: Better error checking. + * config/os/gnu-linux/bits/ctype_noninline.h: Better error checking. + * config/locale/gnu/messages_members.cc: Tweak comment. + * config/locale/gnu/monetary_members.cc: Change data types. + Add dtors. + * config/locale/gnu/numeric_members.cc: Add dtors, better error + checking. + * config/locale/gnu/time_members.cc: Same. + * config/locale/ieee_1003.1-2001/c_locale.cc + (locale::facet::_S_create_c_locale): Add parameter. + * config/locale/ieee_1003.1-2001/c_locale.h: Correct typedef. + * config/locale/ieee_1003.1-2001/codecvt_specializations.h: Remove + bogus ctor. + + * include/bits/locale_facets.h (moneypunct): Use string literals. + Don't define dtor. + (numpunct): Same. + (__timepunct): Same. + (locale::_Impl::_M_facets): Change from vector to array. + (locale::_Impl::_M_names): Change from array of strings to array + of string literals. + (locale::facet::_S_create_c_locale): Add parameter. + (locale::locale::_S_num_facets): Move to... + (locale::_Impl::_M_facets_size): Here. + * include/bits/locale_facets.tcc: Fixups for _M_facets, _M_name + changes. + * include/bits/localefwd.h: (locale::id::_M_id): Add member function. + (locale::_Impl::_Impl(facet**, size_t, bool)): Add. + (locale::_Impl::_Impl(string, size_t)): Change to + (locale::_Impl::_Impl(const char*, size_t)): This. + + * include/bits/streambuf.tcc (streambuf::_S_pback_size): Define. + * include/std/std_streambuf.h (streambuf::_M_pback_size): Change to + (streambuf::_S_pback_size): This. + + * src/globals.cc: Add pre-allocations for "C" facets. + * src/locale-inst.cc: Remove vector instantiations. + * src/locale.cc: Remove vector include. Fixups for _M_names, + _M_facets changes. + * src/localename.cc: Same. + + * include/bits/stl_vector.h: Fix odd formatting. + + * include/bits/basic_string.tcc: Tweak comment. + + * libsupc++/new: Make sure parameters are uglified. + * libsupc++/typeinfo: Same. + + * testsuite/22_locale/num_get_members_char.cc: Fixup. + * testsuite/22_locale/num_get_members_wchar_t.cc: Same. + * testsuite/27_io/filebuf_members.cc: Same. + 2002-04-12 Steve Ellcey * gcc/libstdc++-v3/config/os/hpux/bits/os_defines.h diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc index 50da49e..eaebdf2 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.cc +++ b/libstdc++-v3/config/io/basic_file_stdio.cc @@ -40,13 +40,7 @@ namespace std : _M_cfile(NULL), _M_cfile_created(false) { } __basic_file::~__basic_file() - { - if (this->is_open()) - { - fflush(_M_cfile); - this->close(); - } - } + { this->close(); } void __basic_file::_M_open_mode(ios_base::openmode __mode, int&, int&, @@ -75,7 +69,7 @@ namespace std } __basic_file* - __basic_file::sys_open(__c_file_type* __file, ios_base::openmode) + __basic_file::sys_open(__c_file* __file, ios_base::openmode) { __basic_file* __ret = NULL; if (!this->is_open() && __file) @@ -116,7 +110,7 @@ namespace std } bool - __basic_file::is_open() { return _M_cfile != 0; } + __basic_file::is_open() const { return _M_cfile != 0; } int __basic_file::fd() { return fileno(_M_cfile) ; } @@ -125,8 +119,15 @@ namespace std __basic_file::close() { __basic_file* __retval = static_cast<__basic_file*>(NULL); - if (_M_cfile_created && fclose(_M_cfile)) - __retval = this; + if (this->is_open()) + { + fflush(_M_cfile); + if ((_M_cfile_created && fclose(_M_cfile) == 0) || !_M_cfile_created) + { + _M_cfile = 0; + __retval = this; + } + } return __retval; } diff --git a/libstdc++-v3/config/io/basic_file_stdio.h b/libstdc++-v3/config/io/basic_file_stdio.h index cfc0b46..ca81d6d 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.h +++ b/libstdc++-v3/config/io/basic_file_stdio.h @@ -55,7 +55,7 @@ namespace std class __basic_file { // Underlying data source/sink. - __c_file_type* _M_cfile; + __c_file* _M_cfile; // True iff we opened _M_cfile, and thus must close it ourselves. bool _M_cfile_created; @@ -70,7 +70,7 @@ namespace std open(const char* __name, ios_base::openmode __mode, int __prot = 0664); __basic_file* - sys_open(__c_file_type* __file, ios_base::openmode __mode); + sys_open(__c_file* __file, ios_base::openmode __mode); char sys_getc(); @@ -82,7 +82,7 @@ namespace std close(); bool - is_open(); + is_open() const; int fd(); diff --git a/libstdc++-v3/config/io/c_io_stdio.h b/libstdc++-v3/config/io/c_io_stdio.h index de61da4..0d11d14 100644 --- a/libstdc++-v3/config/io/c_io_stdio.h +++ b/libstdc++-v3/config/io/c_io_stdio.h @@ -49,7 +49,7 @@ namespace std typedef __gthread_mutex_t __c_lock; // for basic_file.h - typedef FILE __c_file_type; + typedef FILE __c_file; // for ios_base.h struct __ios_flags diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc index 245b5b2..8ede46e 100644 --- a/libstdc++-v3/config/locale/generic/c_locale.cc +++ b/libstdc++-v3/config/locale/generic/c_locale.cc @@ -206,12 +206,13 @@ namespace std } void - locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*) + locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*, + __c_locale) { __cloc = NULL; } void - locale::facet::_S_destroy_c_locale(__c_locale&) - { } + locale::facet::_S_destroy_c_locale(__c_locale& __cloc) + { __cloc = NULL; } __c_locale locale::facet::_S_clone_c_locale(__c_locale&) diff --git a/libstdc++-v3/config/locale/generic/collate_members.cc b/libstdc++-v3/config/locale/generic/collate_members.cc index 085f766..93767d9 100644 --- a/libstdc++-v3/config/locale/generic/collate_members.cc +++ b/libstdc++-v3/config/locale/generic/collate_members.cc @@ -1,6 +1,6 @@ // std::collate implementation details, generic version -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -41,8 +41,7 @@ namespace std // be put there instead of here. template<> int - collate::_M_compare_helper(const char* __one, - const char* __two) const + collate::_M_compare(const char* __one, const char* __two) const { int __cmp = strcoll(__one, __two); return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0); @@ -50,15 +49,15 @@ namespace std template<> size_t - collate::_M_transform_helper(char* __to, const char* __from, - size_t __n) const + collate::_M_transform(char* __to, const char* __from, + size_t __n) const { return strxfrm(__to, __from, __n); } #ifdef _GLIBCPP_USE_WCHAR_T template<> int - collate::_M_compare_helper(const wchar_t* __one, - const wchar_t* __two) const + collate::_M_compare(const wchar_t* __one, + const wchar_t* __two) const { int __cmp = wcscoll(__one, __two); return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0); @@ -66,8 +65,8 @@ namespace std template<> size_t - collate::_M_transform_helper(wchar_t* __to, const wchar_t* __from, - size_t __n) const + collate::_M_transform(wchar_t* __to, const wchar_t* __from, + size_t __n) const { return wcsxfrm(__to, __from, __n); } #endif } diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc index 7a31900..7c2e13b 100644 --- a/libstdc++-v3/config/locale/generic/monetary_members.cc +++ b/libstdc++-v3/config/locale/generic/monetary_members.cc @@ -1,6 +1,6 @@ // std::moneypunct implementation details, generic version -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -51,9 +51,9 @@ namespace std _M_decimal_point = '.'; _M_thousands_sep = ','; _M_grouping = ""; - _M_curr_symbol = string_type(); - _M_positive_sign = string_type(); - _M_negative_sign = string_type(); + _M_curr_symbol = ""; + _M_positive_sign = ""; + _M_negative_sign = ""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; @@ -67,14 +67,22 @@ namespace std _M_decimal_point = '.'; _M_thousands_sep = ','; _M_grouping = ""; - _M_curr_symbol = string_type(); - _M_positive_sign = string_type(); - _M_negative_sign = string_type(); + _M_curr_symbol = ""; + _M_positive_sign = ""; + _M_negative_sign = ""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; } + template<> + moneypunct::~moneypunct() + { } + + template<> + moneypunct::~moneypunct() + { } + #ifdef _GLIBCPP_USE_WCHAR_T template<> void @@ -84,9 +92,9 @@ namespace std _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_curr_symbol = L""; + _M_positive_sign = L""; + _M_negative_sign = L""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; @@ -100,12 +108,20 @@ namespace std _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_curr_symbol = L""; + _M_positive_sign = L""; + _M_negative_sign = L""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; } + + template<> + moneypunct::~moneypunct() + { } + + template<> + moneypunct::~moneypunct() + { } #endif } diff --git a/libstdc++-v3/config/locale/generic/numeric_members.cc b/libstdc++-v3/config/locale/generic/numeric_members.cc index 7a511e3..f942e04 100644 --- a/libstdc++-v3/config/locale/generic/numeric_members.cc +++ b/libstdc++-v3/config/locale/generic/numeric_members.cc @@ -48,6 +48,10 @@ namespace std _M_truename = "true"; _M_falsename = "false"; } + + template<> + numpunct::~numpunct() + { } #ifdef _GLIBCPP_USE_WCHAR_T template<> @@ -61,5 +65,9 @@ namespace std _M_truename = L"true"; _M_falsename = L"false"; } + + template<> + numpunct::~numpunct() + { } #endif } diff --git a/libstdc++-v3/config/locale/generic/time_members.cc b/libstdc++-v3/config/locale/generic/time_members.cc index e546f30..16a4998 100644 --- a/libstdc++-v3/config/locale/generic/time_members.cc +++ b/libstdc++-v3/config/locale/generic/time_members.cc @@ -39,10 +39,17 @@ namespace std { template<> + __timepunct::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct:: - _M_put_helper(char* __s, size_t __maxlen, const char* __format, - const tm* __tm) const + _M_put(char* __s, size_t __maxlen, const char* __format, + const tm* __tm) const { const char* __old = setlocale(LC_ALL, _M_name_timepunct); strftime(__s, __maxlen, __format, __tm); @@ -113,10 +120,17 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T template<> + __timepunct::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct:: - _M_put_helper(wchar_t* __s, size_t __maxlen, const wchar_t* __format, - const tm* __tm) const + _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format, + const tm* __tm) const { const char* __old = setlocale(LC_ALL, _M_name_timepunct); wcsftime(__s, __maxlen, __format, __tm); diff --git a/libstdc++-v3/config/locale/gnu/c_locale.cc b/libstdc++-v3/config/locale/gnu/c_locale.cc index 6229090..60ec54d 100644 --- a/libstdc++-v3/config/locale/gnu/c_locale.cc +++ b/libstdc++-v3/config/locale/gnu/c_locale.cc @@ -164,13 +164,10 @@ namespace std } void - locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s) + locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old) { - // XXX - // 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); + __cloc = __newlocale(1 << LC_ALL, __s, __old); if (!__cloc) { // This named locale is not supported by the underlying OS. diff --git a/libstdc++-v3/config/locale/gnu/collate_members.cc b/libstdc++-v3/config/locale/gnu/collate_members.cc index d023d53..3b55f69 100644 --- a/libstdc++-v3/config/locale/gnu/collate_members.cc +++ b/libstdc++-v3/config/locale/gnu/collate_members.cc @@ -41,8 +41,7 @@ namespace std // be put there instead of here. template<> int - collate::_M_compare_helper(const char* __one, - const char* __two) const + collate::_M_compare(const char* __one, const char* __two) const { int __cmp = __strcoll_l(__one, __two, _M_c_locale_collate); return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0); @@ -50,15 +49,15 @@ namespace std template<> size_t - collate::_M_transform_helper(char* __to, const char* __from, - size_t __n) const + collate::_M_transform(char* __to, const char* __from, + size_t __n) const { return __strxfrm_l(__to, __from, __n, _M_c_locale_collate); } #ifdef _GLIBCPP_USE_WCHAR_T template<> int - collate::_M_compare_helper(const wchar_t* __one, - const wchar_t* __two) const + collate::_M_compare(const wchar_t* __one, + const wchar_t* __two) const { int __cmp = __wcscoll_l(__one, __two, _M_c_locale_collate); return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0); @@ -66,8 +65,8 @@ namespace std template<> size_t - collate::_M_transform_helper(wchar_t* __to, const wchar_t* __from, - size_t __n) const + collate::_M_transform(wchar_t* __to, const wchar_t* __from, + size_t __n) const { return __wcsxfrm_l(__to, __from, __n, _M_c_locale_collate); } #endif } diff --git a/libstdc++-v3/config/locale/gnu/ctype_members.cc b/libstdc++-v3/config/locale/gnu/ctype_members.cc index 33540c9..090738b 100644 --- a/libstdc++-v3/config/locale/gnu/ctype_members.cc +++ b/libstdc++-v3/config/locale/gnu/ctype_members.cc @@ -1,6 +1,6 @@ // std::ctype implementation details, GNU version -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -43,7 +43,7 @@ namespace std ctype_byname::ctype_byname(const char* __s, size_t __refs) : ctype(0, false, __refs) { - if (_M_c_locale_ctype) + if (_M_c_locale_ctype != _S_c_locale) _S_destroy_c_locale(_M_c_locale_ctype); _S_create_c_locale(_M_c_locale_ctype, __s); _M_toupper = _M_c_locale_ctype->__ctype_toupper; @@ -130,8 +130,10 @@ namespace std bool ctype:: do_is(mask __m, char_type __c) const - { return static_cast(__iswctype_l(__c, _M_convert_to_wmask(__m), - _M_c_locale_ctype)); } + { + return static_cast(__iswctype_l(__c, _M_convert_to_wmask(__m), + _M_c_locale_ctype)); + } const wchar_t* ctype:: diff --git a/libstdc++-v3/config/locale/gnu/messages_members.cc b/libstdc++-v3/config/locale/gnu/messages_members.cc index 28702c2..f202003 100644 --- a/libstdc++-v3/config/locale/gnu/messages_members.cc +++ b/libstdc++-v3/config/locale/gnu/messages_members.cc @@ -37,7 +37,7 @@ namespace std { - // Specializations + // Specializations. template<> string messages::do_get(catalog, int, int, const string& __dfault) const diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc index 88a4f95..bf9b50c 100644 --- a/libstdc++-v3/config/locale/gnu/monetary_members.cc +++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc @@ -1,6 +1,6 @@ // std::moneypunct implementation details, GNU version -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -218,15 +218,15 @@ namespace std void moneypunct::_M_initialize_moneypunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "C" locale _M_decimal_point = '.'; _M_thousands_sep = ','; _M_grouping = ""; - _M_curr_symbol = string_type(); - _M_positive_sign = string_type(); - _M_negative_sign = string_type(); + _M_curr_symbol = ""; + _M_positive_sign = ""; + _M_negative_sign = ""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; @@ -238,7 +238,12 @@ namespace std _M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, __cloc)); _M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); _M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); - _M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); + + char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); + if (!__nposn) + _M_negative_sign = "()"; + else + _M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); // _Intl == true _M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); @@ -249,9 +254,6 @@ namespace std _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn); char __nprecedes = *(__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)); - if (!__nposn) - _M_negative_sign = "()"; _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn); } } @@ -260,15 +262,15 @@ namespace std void moneypunct::_M_initialize_moneypunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "C" locale _M_decimal_point = '.'; _M_thousands_sep = ','; _M_grouping = ""; - _M_curr_symbol = string_type(); - _M_positive_sign = string_type(); - _M_negative_sign = string_type(); + _M_curr_symbol = ""; + _M_positive_sign = ""; + _M_negative_sign = ""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; @@ -280,7 +282,12 @@ namespace std _M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, __cloc)); _M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); _M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); - _M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); + + char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); + if (!__nposn) + _M_negative_sign = "()"; + else + _M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); // _Intl == false _M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); @@ -291,27 +298,32 @@ namespace std _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn); char __nprecedes = *(__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)); - if (!__nposn) - _M_negative_sign = "()"; _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn); } } + template<> + moneypunct::~moneypunct() + { } + + template<> + moneypunct::~moneypunct() + { } + #ifdef _GLIBCPP_USE_WCHAR_T template<> void moneypunct::_M_initialize_moneypunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "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_curr_symbol = L""; + _M_positive_sign = L""; + _M_negative_sign = L""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; @@ -325,45 +337,51 @@ namespace std _M_grouping = __nl_langinfo_l(GROUPING, __cloc); mbstate_t __state; - const char* __cs; - string __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); - string __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); - string __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); - string::size_type __len = max(__cpossign.size(), __cnegsign.size()); - __len = max(__len, __ccurr.size()) + 1; - wchar_t* __ws = static_cast(__builtin_alloca(sizeof(wchar_t) * __len)); + size_t __len; + const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); + const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); + const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); // NB: Should swich to __cloc's ctype info first. - if (__cpossign.size()) + __len = strlen(__cpossign); + if (__len) { + ++__len; memset(&__state, 0, sizeof(mbstate_t)); - __cs = __cpossign.c_str(); - mbsrtowcs(__ws, &__cs, __cpossign.size() + 1, &__state); - _M_positive_sign = string_type(__ws); + wchar_t* __wcs = new wchar_t[__len]; + mbsrtowcs(__wcs, &__cpossign, __len, &__state); + _M_positive_sign = __wcs; } else - _M_positive_sign = string_type(); + _M_positive_sign = L""; - if (__cnegsign.size()) + char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); + __len = strlen(__cnegsign); + if (!__nposn) + _M_negative_sign = L"()"; + else if (__len) { + ++__len; memset(&__state, 0, sizeof(mbstate_t)); - __cs = __cnegsign.c_str(); - mbsrtowcs(__ws, &__cs, __cnegsign.size() + 1, &__state); - _M_negative_sign = string_type(__ws); + wchar_t* __wcs = new wchar_t[__len]; + mbsrtowcs(__wcs, &__cnegsign, __len, &__state); + _M_negative_sign = __wcs; } else - _M_negative_sign = string_type(); + _M_negative_sign = L""; // _Intl == true. - if (__ccurr.size()) + __len = strlen(__ccurr); + if (__len) { + ++__len; memset(&__state, 0, sizeof(mbstate_t)); - __cs = __ccurr.c_str(); - mbsrtowcs(__ws, &__cs, __ccurr.size() + 1, &__state); - _M_curr_symbol = string_type(__ws); + wchar_t* __wcs = new wchar_t[__len]; + mbsrtowcs(__wcs, &__ccurr, __len, &__state); + _M_curr_symbol = __wcs; } else - _M_curr_symbol = string_type(); + _M_curr_symbol = L""; _M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, __cloc)); char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); @@ -372,9 +390,6 @@ namespace std _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn); char __nprecedes = *(__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)); - if (!__nposn) - _M_negative_sign = L"()"; _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn); } } @@ -383,15 +398,15 @@ namespace std void moneypunct::_M_initialize_moneypunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "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_curr_symbol = L""; + _M_positive_sign = L""; + _M_negative_sign = L""; _M_frac_digits = 0; _M_pos_format = money_base::_S_default_pattern; _M_neg_format = money_base::_S_default_pattern; @@ -404,45 +419,51 @@ namespace std _M_grouping = __nl_langinfo_l(GROUPING, __cloc); mbstate_t __state; - const char* __cs; - string __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); - string __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); - string __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); - string::size_type __len = max(__cpossign.size(), __cnegsign.size()); - __len = max(__len, __ccurr.size()) + 1; - wchar_t* __ws = static_cast(__builtin_alloca(sizeof(wchar_t) * __len)); + size_t __len; + const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); + const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); + const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); // NB: Should swich to __cloc's ctype info first. - if (__cpossign.size()) + __len = strlen(__cpossign); + if (__len) { + ++__len; memset(&__state, 0, sizeof(mbstate_t)); - __cs = __cpossign.c_str(); - mbsrtowcs(__ws, &__cs, __cpossign.size() + 1, &__state); - _M_positive_sign = string_type(__ws); + wchar_t* __wcs = new wchar_t[__len]; + mbsrtowcs(__wcs, &__cpossign, __len, &__state); + _M_positive_sign = __wcs; } else - _M_positive_sign = string_type(); + _M_positive_sign = L""; - if (__cnegsign.size()) + char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); + __len = strlen(__cnegsign); + if (!__nposn) + _M_negative_sign = L"()"; + else if (__len) { + ++__len; memset(&__state, 0, sizeof(mbstate_t)); - __cs = __cnegsign.c_str(); - mbsrtowcs(__ws, &__cs, __cnegsign.size() + 1, &__state); - _M_negative_sign = string_type(__ws); + wchar_t* __wcs = new wchar_t[__len]; + mbsrtowcs(__wcs, &__cnegsign, __len, &__state); + _M_negative_sign = __wcs; } else - _M_negative_sign = string_type(); + _M_negative_sign = L""; - // _Intl == false. - if (__ccurr.size()) + // _Intl == true. + __len = strlen(__ccurr); + if (__len) { + ++__len; memset(&__state, 0, sizeof(mbstate_t)); - __cs = __ccurr.c_str(); - mbsrtowcs(__ws, &__cs, __ccurr.size() + 1, &__state); - _M_curr_symbol = string_type(__ws); + wchar_t* __wcs = new wchar_t[__len]; + mbsrtowcs(__wcs, &__ccurr, __len, &__state); + _M_curr_symbol = __wcs; } else - _M_curr_symbol = string_type(); + _M_curr_symbol = L""; _M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); @@ -451,11 +472,30 @@ namespace std _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn); char __nprecedes = *(__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)); - if (!__nposn) - _M_negative_sign = L"()"; _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn); } } + + template<> + moneypunct::~moneypunct() + { + if (wcslen(_M_positive_sign)) + delete [] _M_positive_sign; + if (wcslen(_M_negative_sign) && (wcscmp(_M_negative_sign, L"()") != 0)) + delete [] _M_negative_sign; + if (wcslen(_M_curr_symbol)) + delete [] _M_curr_symbol; + } + + template<> + moneypunct::~moneypunct() + { + if (wcslen(_M_positive_sign)) + delete [] _M_positive_sign; + if (wcslen(_M_negative_sign) && (wcscmp(_M_negative_sign, L"()") != 0)) + delete [] _M_negative_sign; + if (wcslen(_M_curr_symbol)) + delete [] _M_curr_symbol; + } #endif } diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc index 4284c7c..4806435 100644 --- a/libstdc++-v3/config/locale/gnu/numeric_members.cc +++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc @@ -41,7 +41,7 @@ namespace std void numpunct::_M_initialize_numpunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "C" locale _M_decimal_point = '.'; @@ -65,13 +65,17 @@ namespace std // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); _M_falsename = "false"; } - + + template<> + numpunct::~numpunct() + { } + #ifdef _GLIBCPP_USE_WCHAR_T template<> void numpunct::_M_initialize_numpunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "C" locale _M_decimal_point = L'.'; @@ -94,5 +98,9 @@ namespace std // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); _M_falsename = L"false"; } -#endif + + template<> + numpunct::~numpunct() + { } + #endif } diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc b/libstdc++-v3/config/locale/gnu/time_members.cc index 124a917..665ea02 100644 --- a/libstdc++-v3/config/locale/gnu/time_members.cc +++ b/libstdc++-v3/config/locale/gnu/time_members.cc @@ -39,16 +39,20 @@ namespace std { template<> + __timepunct::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct:: - _M_put_helper(char* __s, size_t __maxlen, const char* __format, - const tm* __tm) const + _M_put(char* __s, size_t __maxlen, const char* __format, + const tm* __tm) const { #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) - if (_M_c_locale_timepunct) - __strftime_l(__s, __maxlen, _M_c_locale_timepunct, __format, __tm); - else - strftime(__s, __maxlen, __format, __tm); + __strftime_l(__s, __maxlen, _M_c_locale_timepunct, __format, __tm); #else const char* __old = setlocale(LC_ALL, _M_name_timepunct); strftime(__s, __maxlen, __format, __tm); @@ -60,7 +64,7 @@ namespace std void __timepunct::_M_initialize_timepunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "C" locale _M_date_format = "%m/%d/%y"; @@ -183,16 +187,20 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T template<> + __timepunct::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct:: - _M_put_helper(wchar_t* __s, size_t __maxlen, const wchar_t* __format, - const tm* __tm) const + _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format, + const tm* __tm) const { #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) - if (_M_c_locale_timepunct) - __wcsftime_l(__s, __maxlen, _M_c_locale_timepunct, __format, __tm); - else - wcsftime(__s, __maxlen, __format, __tm); + __wcsftime_l(__s, __maxlen, _M_c_locale_timepunct, __format, __tm); #else const char* __old = setlocale(LC_ALL, _M_name_timepunct); wcsftime(__s, __maxlen, __format, __tm); @@ -204,7 +212,7 @@ namespace std void __timepunct::_M_initialize_timepunct(__c_locale __cloc) { - if (!__cloc) + if (__cloc == _S_c_locale) { // "C" locale _M_date_format = L"%m/%d/%y"; diff --git a/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.cc b/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.cc index 493ac01..0a89aee 100644 --- a/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.cc +++ b/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.cc @@ -1,6 +1,6 @@ // Wrapper for underlying C-language localization -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -38,7 +38,7 @@ namespace std { void - locale::facet::_S_create_c_locale(__c_locale&, const char*) + locale::facet::_S_create_c_locale(__c_locale&, const char*, __c_locale*) { } void diff --git a/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.h b/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.h index bbfb85e..4c68f27 100644 --- a/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.h +++ b/libstdc++-v3/config/locale/ieee_1003.1-2001/c_locale.h @@ -1,6 +1,6 @@ // Wrapper for underlying C-language localization -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -40,10 +40,5 @@ namespace std { - typedef __locale_t __c_locale; + typedef int* __c_locale; } - - - - - diff --git a/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h b/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h index 891c66b..139e6c9 100644 --- a/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h +++ b/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h @@ -39,10 +39,6 @@ // Define this here to codecvt.cc can have _S_max_size definition. #define _GLIBCPP_USE___ENC_TRAITS 1 -#if _GLIBCPP_USE_SHADOW_HEADERS - using _C_legacy::CODESET; -#endif - // Extension to use icov for dealing with character encodings, // including conversions and comparisons between various character // sets. This object encapsulates data that may need to be shared between @@ -83,23 +79,6 @@ memset(_M_ext_enc, 0, _S_max_size); } - explicit __enc_traits(const locale& __loc) - : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0) - { - // __intc_end = whatever we are using internally, which is - // UCS4 (linux, solaris) - // UCS2 == UNICODE (microsoft, java, aix, whatever...) - // XXX Currently don't know how to get this data from target system... - strcpy(_M_int_enc, "UCS4"); - - // __extc_end = external codeset in current locale - // XXX There has got to be a better way to do this. - __c_locale __cloc; - locale::facet::_S_create_c_locale(__cloc, __loc.name().c_str()); - strcpy(_M_ext_enc, __nl_langinfo_l(CODESET, __cloc)); - locale::facet::_S_destroy_c_locale(__cloc); - } - explicit __enc_traits(const char* __int, const char* __ext, int __ibom = 0, int __ebom = 0) : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0) diff --git a/libstdc++-v3/config/os/gnu-linux/bits/ctype_noninline.h b/libstdc++-v3/config/os/gnu-linux/bits/ctype_noninline.h index 18324d1..ee70ab4 100644 --- a/libstdc++-v3/config/os/gnu-linux/bits/ctype_noninline.h +++ b/libstdc++-v3/config/os/gnu-linux/bits/ctype_noninline.h @@ -60,14 +60,14 @@ : __ctype_abstract_base(__refs), _M_del(__table != 0 && __del), _M_toupper(__ctype_toupper), _M_tolower(__ctype_tolower), _M_table(__table ? __table : classic_table()) - { _M_c_locale_ctype = NULL; } + { _M_c_locale_ctype = _S_c_locale; } #endif ctype::ctype(const mask* __table, bool __del, size_t __refs) : __ctype_abstract_base(__refs), _M_del(__table != 0 && __del), _M_toupper(__ctype_toupper), _M_tolower(__ctype_tolower), _M_table(__table ? __table : classic_table()) - { _M_c_locale_ctype = NULL; } + { _M_c_locale_ctype = _S_c_locale; } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 50818da..3f4b5fb 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -443,7 +443,7 @@ namespace std void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); _Rep *__p = new (__place) _Rep; __p->_M_capacity = __capacity; - __p->_M_set_sharable(); // one reference + __p->_M_set_sharable(); // One reference. __p->_M_length = 0; return __p; } diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 8514323..fb2f876 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -42,38 +42,25 @@ namespace std template void basic_filebuf<_CharT, _Traits>:: - _M_allocate_file() - { - if (!_M_file) - { - _M_buf_unified = true; // Tie input to output for basic_filebuf. - try - { _M_file = new __file_type(&_M_lock); } - catch(...) - { - delete _M_file; - __throw_exception_again; - } - } - } - - template - void - basic_filebuf<_CharT, _Traits>:: _M_allocate_internal_buffer() { if (!_M_buf && _M_buf_size_opt) { _M_buf_size = _M_buf_size_opt; - // Allocate internal buffer. - try { _M_buf = new char_type[_M_buf_size]; } - catch(...) + if (_M_buf_size != 1) { - delete [] _M_buf; - __throw_exception_again; + // Allocate internal buffer. + try { _M_buf = new char_type[_M_buf_size]; } + catch(...) + { + delete [] _M_buf; + __throw_exception_again; + } + _M_buf_allocated = true; } - _M_buf_allocated = true; + else + _M_buf = _M_unbuf; } } @@ -91,22 +78,13 @@ namespace std this->setg(NULL, NULL, NULL); this->setp(NULL, NULL); } - } - - template - void - basic_filebuf<_CharT, _Traits>:: - _M_allocate_pback_buffer() - { - if (!_M_pback && _M_pback_size) + else { - // Allocate pback buffer. - try - { _M_pback = new char_type[_M_pback_size]; } - catch(...) + if (_M_buf == _M_unbuf) { - delete [] _M_pback; - __throw_exception_again; + _M_buf = NULL; + this->setg(NULL, NULL, NULL); + this->setp(NULL, NULL); } } } @@ -114,20 +92,20 @@ namespace std template basic_filebuf<_CharT, _Traits>:: basic_filebuf() - : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), + : __streambuf_type(), _M_file(&_M_lock), _M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_buf_allocated(false), _M_last_overflowed(false) - { } + { _M_buf_unified = true; } template basic_filebuf<_CharT, _Traits>:: - basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s) - : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), + basic_filebuf(__c_file* __f, ios_base::openmode __mode, int_type __s) + : __streambuf_type(), _M_file(&_M_lock), _M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_buf_allocated(false), _M_last_overflowed(false) { - _M_allocate_file(); - _M_file->sys_open(__f, __mode); + _M_buf_unified = true; + _M_file.sys_open(__f, __mode); if (this->is_open()) { _M_mode = __mode; @@ -137,7 +115,6 @@ namespace std _M_allocate_internal_buffer(); _M_set_indeterminate(); } - _M_allocate_pback_buffer(); } } @@ -145,7 +122,7 @@ namespace std int basic_filebuf<_CharT, _Traits>:: fd() - { return _M_file->fd(); } + { return _M_file.fd(); } template typename basic_filebuf<_CharT, _Traits>::__filebuf_type* @@ -155,12 +132,10 @@ namespace std __filebuf_type *__ret = NULL; if (!this->is_open()) { - _M_allocate_file(); - _M_file->open(__s, __mode); + _M_file.open(__s, __mode); if (this->is_open()) { _M_allocate_internal_buffer(); - _M_allocate_pback_buffer(); _M_mode = __mode; // For time being, set both (in/out) sets of pointers. @@ -190,13 +165,7 @@ namespace std // NB: Do this here so that re-opened filebufs will be cool... _M_mode = ios_base::openmode(0); _M_destroy_internal_buffer(); - _M_pback_destroy(); - if (_M_pback) - { - delete [] _M_pback; - _M_pback = NULL; - } #if 0 // XXX not done @@ -206,16 +175,11 @@ namespace std _M_really_overflow(__eof); } #endif - __ret = this; - } - // Can actually allocate this file as part of an open and never - // have it be opened..... - if (_M_file) - { - delete _M_file; - _M_file = NULL; + if (_M_file.close()) + __ret = this; } + _M_last_overflowed = false; return __ret; } @@ -270,11 +234,11 @@ namespace std _M_really_overflow(); #if _GLIBCPP_AVOID_FSEEK else if ((_M_in_cur - _M_in_beg) == 1) - _M_file->sys_getc(); + _M_file.sys_getc(); #endif else - _M_file->seekoff(_M_in_cur - _M_in_beg, - ios_base::cur, ios_base::in); + _M_file.seekoff(_M_in_cur - _M_in_beg, + ios_base::cur, ios_base::in); } if (__testinit || __testget) @@ -286,14 +250,14 @@ namespace std streamsize __ilen = 0; if (__cvt.always_noconv()) { - __elen = _M_file->xsgetn(reinterpret_cast(_M_in_beg), - _M_buf_size); + __elen = _M_file.xsgetn(reinterpret_cast(_M_in_beg), + _M_buf_size); __ilen = __elen; } else { char* __buf = static_cast(__builtin_alloca(_M_buf_size)); - __elen = _M_file->xsgetn(__buf, _M_buf_size); + __elen = _M_file.xsgetn(__buf, _M_buf_size); const char* __eend; char_type* __iend; @@ -306,7 +270,7 @@ namespace std { // Unwind. __ilen = 0; - _M_file->seekoff(-__elen, ios_base::cur, ios_base::in); + _M_file.seekoff(-__elen, ios_base::cur, ios_base::in); } } @@ -318,11 +282,11 @@ namespace std __ret = traits_type::to_int_type(*_M_in_cur); #if _GLIBCPP_AVOID_FSEEK if (__elen == 1) - _M_file->sys_ungetc(*_M_in_cur); + _M_file.sys_ungetc(*_M_in_cur); else { #endif - _M_file->seekoff(-__elen, ios_base::cur, ios_base::in); + _M_file.seekoff(-__elen, ios_base::cur, ios_base::in); #if _GLIBCPP_AVOID_FSEEK } #endif @@ -437,7 +401,7 @@ namespace std if (__cvt.always_noconv() && __ilen) { - __elen += _M_file->xsputn(reinterpret_cast(__ibuf), __ilen); + __elen += _M_file.xsputn(reinterpret_cast(__ibuf), __ilen); __plen += __ilen; } else @@ -461,7 +425,7 @@ namespace std if (__blen) { - __elen += _M_file->xsputn(__buf, __blen); + __elen += _M_file.xsputn(__buf, __blen); __plen += __blen; } @@ -478,7 +442,7 @@ namespace std __rlen = 0; if (__rlen) { - __elen += _M_file->xsputn(__buf, __rlen); + __elen += _M_file.xsputn(__buf, __rlen); __plen += __rlen; } } @@ -492,7 +456,7 @@ namespace std { int_type __ret = traits_type::eof(); bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - bool __testunbuffered = _M_file && !_M_buf_size; + bool __testunbuffered = _M_file.is_open() && !_M_buf_size; if (__testput || __testunbuffered) { @@ -516,7 +480,7 @@ namespace std // Last, sync internal and external buffers. // NB: Need this so that external byte sequence reflects // internal buffer plus pending sequence. - if (__elen == __plen && !_M_file->sync()) + if (__elen == __plen && !_M_file.sync()) { _M_set_indeterminate(); __ret = traits_type::not_eof(__c); @@ -546,9 +510,6 @@ namespace std _M_buf = __s; _M_buf_size_opt = _M_buf_size = __n; _M_set_indeterminate(); - - // Step 3: Make sure a pback buffer is allocated. - _M_allocate_pback_buffer(); } _M_last_overflowed = false; return this; @@ -594,14 +555,14 @@ namespace std else if (__testget && __way == ios_base::cur) __computed_off += _M_in_cur - _M_in_beg; - __ret = _M_file->seekoff(__computed_off, __way, __mode); + __ret = _M_file.seekoff(__computed_off, __way, __mode); _M_set_indeterminate(); } // NB: Need to do this in case _M_file in indeterminate - // state, ie _M_file->_offset == -1 + // state, ie _M_file._offset == -1 else { - __ret = _M_file->seekoff(__off, ios_base::cur, __mode); + __ret = _M_file.seekoff(__off, ios_base::cur, __mode); __ret += max(_M_out_cur, _M_in_cur) - _M_buf; } } diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index a45023f..d63eb5d 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -43,13 +43,18 @@ #pragma GCC system_header #include // For struct tm -#ifdef _GLIBCPP_USE_WCHAR_T -# include // For wctype_t -#endif +#include // For wctype_t #include // For ios_base namespace std { + // NB: Don't instantiate required wchar_t facets if no wchar_t support. +#ifdef _GLIBCPP_USE_WCHAR_T +# define _GLIBCPP_NUM_FACETS 28 +#else +# define _GLIBCPP_NUM_FACETS 14 +#endif + // 22.2.1.1 Template class ctype // Include host and configuration specific ctype enums for ctype_base. #include @@ -169,11 +174,11 @@ namespace std typedef _CharT char_type; typedef typename ctype::mask mask; + static locale::id id; + explicit ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } - static locale::id id; - protected: virtual ~ctype(); @@ -458,9 +463,9 @@ namespace std private: char_type _M_decimal_point; char_type _M_thousands_sep; - string _M_grouping; - string_type _M_truename; - string_type _M_falsename; + const char* _M_grouping; + const char_type* _M_truename; + const char_type* _M_falsename; public: explicit @@ -493,7 +498,7 @@ namespace std protected: virtual - ~numpunct() { } + ~numpunct(); virtual char_type do_decimal_point() const @@ -517,18 +522,24 @@ namespace std // For use at construction time only. void - _M_initialize_numpunct(__c_locale __cloc = NULL); + _M_initialize_numpunct(__c_locale __cloc = _S_c_locale); }; template locale::id numpunct<_CharT>::id; template<> + numpunct::~numpunct(); + + template<> void numpunct::_M_initialize_numpunct(__c_locale __cloc); #ifdef _GLIBCPP_USE_WCHAR_T template<> + numpunct::~numpunct(); + + template<> void numpunct::_M_initialize_numpunct(__c_locale __cloc); #endif @@ -813,7 +824,7 @@ namespace std explicit collate(size_t __refs = 0) : locale::facet(__refs) - { _M_c_locale_collate = _S_clone_c_locale(_S_c_locale); } + { _M_c_locale_collate = _S_c_locale; } // Non-standard. explicit @@ -836,15 +847,18 @@ namespace std // Used to abstract out _CharT bits in virtual member functions, below. int - _M_compare_helper(const _CharT*, const _CharT*) const; + _M_compare(const _CharT*, const _CharT*) const; size_t - _M_transform_helper(_CharT*, const _CharT*, size_t) const; + _M_transform(_CharT*, const _CharT*, size_t) const; protected: virtual ~collate() - { _S_destroy_c_locale(_M_c_locale_collate); } + { + if (_M_c_locale_collate != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_collate); + } virtual int do_compare(const _CharT* __lo1, const _CharT* __hi1, @@ -863,21 +877,20 @@ namespace std // Specializations. template<> int - collate::_M_compare_helper(const char*, const char*) const; + collate::_M_compare(const char*, const char*) const; template<> size_t - collate::_M_transform_helper(char*, const char*, size_t) const; + collate::_M_transform(char*, const char*, size_t) const; #ifdef _GLIBCPP_USE_WCHAR_T template<> int - collate::_M_compare_helper(const wchar_t*, const wchar_t*) const; + collate::_M_compare(const wchar_t*, const wchar_t*) const; template<> size_t - collate::_M_transform_helper(wchar_t*, const wchar_t*, - size_t) const; + collate::_M_transform(wchar_t*, const wchar_t*, size_t) const; #endif template @@ -891,7 +904,8 @@ namespace std collate_byname(const char* __s, size_t __refs = 0) : collate<_CharT>(__refs) { - _S_destroy_c_locale(_M_c_locale_collate); + if (_M_c_locale_collate != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_collate); _S_create_c_locale(_M_c_locale_collate, __s); } @@ -991,8 +1005,8 @@ namespace std { _M_initialize_timepunct(__cloc); } void - _M_put_helper(_CharT* __s, size_t __maxlen, const _CharT* __format, - const tm* __tm) const; + _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, + const tm* __tm) const; void _M_date_formats(const _CharT** __date) const @@ -1085,21 +1099,20 @@ namespace std protected: virtual - ~__timepunct() - { - if (_M_c_locale_timepunct) - _S_destroy_c_locale(_M_c_locale_timepunct); - } + ~__timepunct(); // For use at construction time only. void - _M_initialize_timepunct(__c_locale __cloc = NULL); + _M_initialize_timepunct(__c_locale __cloc = _S_c_locale); }; template locale::id __timepunct<_CharT>::id; // Specializations. + template<> + __timepunct::~__timepunct(); + template<> const char* __timepunct::_S_timezones[14]; @@ -1110,10 +1123,12 @@ namespace std template<> void - __timepunct::_M_put_helper(char*, size_t, const char*, - const tm*) const; + __timepunct::_M_put(char*, size_t, const char*, const tm*) const; #ifdef _GLIBCPP_USE_WCHAR_T + template<> + __timepunct::~__timepunct(); + template<> const wchar_t* __timepunct::_S_timezones[14]; @@ -1124,8 +1139,8 @@ namespace std template<> void - __timepunct::_M_put_helper(wchar_t*, size_t, const wchar_t*, - const tm*) const; + __timepunct::_M_put(wchar_t*, size_t, const wchar_t*, + const tm*) const; #endif // Generic. @@ -1322,19 +1337,19 @@ namespace std typedef _CharT char_type; typedef basic_string<_CharT> string_type; - static const bool intl = _Intl; - static locale::id id; + static const bool intl = _Intl; + static locale::id id; private: - char_type _M_decimal_point; - char_type _M_thousands_sep; - string _M_grouping; - string_type _M_curr_symbol; - string_type _M_positive_sign; - string_type _M_negative_sign; - int _M_frac_digits; - pattern _M_pos_format; - pattern _M_neg_format; + const char* _M_grouping; + char_type _M_decimal_point; + char_type _M_thousands_sep; + const char_type* _M_curr_symbol; + const char_type* _M_positive_sign; + const char_type* _M_negative_sign; + int _M_frac_digits; + pattern _M_pos_format; + pattern _M_neg_format; public: explicit @@ -1383,7 +1398,7 @@ namespace std protected: virtual - ~moneypunct() { } + ~moneypunct(); virtual char_type do_decimal_point() const @@ -1423,7 +1438,7 @@ namespace std // For use at construction time only. void - _M_initialize_moneypunct(__c_locale __cloc = NULL); + _M_initialize_moneypunct(__c_locale __cloc = _S_c_locale); }; template @@ -1432,6 +1447,12 @@ namespace std template const bool moneypunct<_CharT, _Intl>::intl; + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + template<> void moneypunct::_M_initialize_moneypunct(__c_locale __cloc); @@ -1441,6 +1462,12 @@ namespace std moneypunct::_M_initialize_moneypunct(__c_locale __cloc); #ifdef _GLIBCPP_USE_WCHAR_T + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + template<> void moneypunct::_M_initialize_moneypunct(__c_locale __cloc); @@ -1586,7 +1613,7 @@ namespace std explicit messages(size_t __refs = 0) : locale::facet(__refs), _M_name_messages("C") - { _M_c_locale_messages = _S_clone_c_locale(_S_c_locale); } + { _M_c_locale_messages = _S_c_locale; } // Non-standard. explicit @@ -1616,7 +1643,10 @@ namespace std protected: virtual ~messages() - { _S_destroy_c_locale(_M_c_locale_messages); } + { + if (_M_c_locale_messages != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_messages); + } virtual catalog do_open(const basic_string&, const locale&) const; @@ -1699,7 +1729,8 @@ namespace std : messages<_CharT>(__refs) { _M_name_messages = __s; - _S_destroy_c_locale(_M_c_locale_messages); + if (_M_c_locale_messages != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_messages); _S_create_c_locale(_M_c_locale_messages, __s); } diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index d81406f..d362c33 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -70,21 +70,20 @@ namespace std const _Facet& use_facet(const locale& __loc) { - size_t __i = _Facet::id._M_index; - locale::_Impl::__vec_facet& __facet = __loc._M_impl->_M_facets; - const locale::facet* __fp = __facet[__i]; - if (__fp == 0 || __i >= __facet.size()) + size_t __i = _Facet::id._M_id(); + locale::facet** __facets = __loc._M_impl->_M_facets; + if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) __throw_bad_cast(); - return static_cast(*__fp); + return static_cast(*__facets[__i]); } template bool has_facet(const locale& __loc) throw() { - size_t __i = _Facet::id._M_index; - locale::_Impl::__vec_facet& __facet = __loc._M_impl->_M_facets; - return (__i < __facet.size() && __facet[__i] != 0); + size_t __i = _Facet::id._M_id(); + locale::facet** __facets = __loc._M_impl->_M_facets; + return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); } @@ -395,19 +394,21 @@ namespace std // Parse bool values as alphanumeric else { + typedef basic_string<_CharT> __string_type; locale __loc = __io.getloc(); const numpunct<_CharT>& __np = use_facet >(__loc); - const char_type* __true = __np.truename().c_str(); - const char_type* __false = __np.falsename().c_str(); - - const size_t __truen = __np.truename().size() - 1; - const size_t __falsen = __np.falsename().size() - 1; + const __string_type __true = __np.truename(); + const __string_type __false = __np.falsename(); + const char_type* __trues = __true.c_str(); + const char_type* __falses = __false.c_str(); + const size_t __truen = __true.size() - 1; + const size_t __falsen = __false.size() - 1; for (size_t __n = 0; __beg != __end; ++__n) { char_type __c = *__beg++; - bool __testf = __n <= __falsen ? __c == __false[__n] : false; - bool __testt = __n <= __truen ? __c == __true[__n] : false; + bool __testf = __n <= __falsen ? __c == __falses[__n] : false; + bool __testt = __n <= __truen ? __c == __trues[__n] : false; if (!(__testf || __testt)) { __err |= ios_base::failbit; @@ -628,7 +629,8 @@ namespace std const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec); if (__fp) - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale, __prec); + __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_c_locale, __prec); else __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); @@ -638,9 +640,11 @@ namespace std __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); if (__fp) - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale, __prec); + __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_c_locale, __prec); else - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); + __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_c_locale); } #else // Consider the possibility of long ios_base::fixed outputs @@ -679,13 +683,15 @@ namespace std // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); + int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_c_locale); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); + __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_c_locale); } #else // Leave room for "+/-," "0x," and commas. This size is @@ -791,7 +797,8 @@ namespace std *(__ws2 + 1) = *(__ws + 1); } _CharT* __p; - __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), __grouping.c_str(), + __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), + __grouping.c_str(), __grouping.c_str() + __grouping.size(), __ws + __off, __ws + __len); __len = __p - __ws2; @@ -842,21 +849,15 @@ namespace std } else { + typedef basic_string<_CharT> __string_type; locale __loc = __io.getloc(); const numpunct<_CharT>& __np = use_facet >(__loc); - const char_type* __ws; - int __len; + __string_type __name; if (__v) - { - __ws = __np.truename().c_str(); - __len = __np.truename().size(); - } + __name = __np.truename(); else - { - __ws = __np.falsename().c_str(); - __len = __np.falsename().size(); - } - __s = _M_insert(__s, __io, __fill, __ws, __len); + __name = __np.falsename(); + __s = _M_insert(__s, __io, __fill, __name.c_str(), __name.size()); } return __s; } @@ -999,15 +1000,16 @@ namespace std switch (__which) { case money_base::symbol: - if (__io.flags() & ios_base::showbase - || __i < 2 - || (__i == 2 && static_cast(__p.field[3]) != money_base::none) - || __sign.size() > 1) + if (__io.flags() & ios_base::showbase + || __i < 2 || __sign.size() > 1 + || ((static_cast(__p.field[3]) != money_base::none) + && __i == 2)) { - // According to 22.2.6.1.2.2, symbol is required if - // (__io.flags() & ios_base::showbase), otherwise is optional - // and consumed only if other characters are needed to complete - // the format. + // According to 22.2.6.1.2.2, symbol is required + // if (__io.flags() & ios_base::showbase), + // otherwise is optional and consumed only if + // other characters are needed to complete the + // format. const string_type __symbol = __intl ? __mpt.curr_symbol() : __mpf.curr_symbol(); size_type __len = __symbol.size(); @@ -1018,7 +1020,8 @@ namespace std __c = *(++__beg); ++__j; } - // When (__io.flags() & ios_base::showbase) symbol is required. + // When (__io.flags() & ios_base::showbase) + // symbol is required. if (__j != __len && (__io.flags() & ios_base::showbase)) __testvalid = false; } @@ -1152,13 +1155,15 @@ namespace std // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, _S_c_locale); + int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, + _S_c_locale); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, _S_c_locale); + __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, + _S_c_locale); } #else // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point, @@ -1871,7 +1876,7 @@ namespace std __fmt[3] = char_type(); } - __tp._M_put_helper(__res, __maxlen, __fmt, __tm); + __tp._M_put(__res, __maxlen, __fmt, __tm); // Write resulting, fully-formatted string to output iterator. size_t __len = char_traits::length(__res); @@ -1884,13 +1889,13 @@ namespace std // Generic version does nothing. template int - collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const + collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const { return 0; } // Generic version does nothing. template size_t - collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const + collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const { return 0; } template @@ -1901,7 +1906,7 @@ namespace std { const string_type __one(__lo1, __hi1); const string_type __two(__lo2, __hi2); - return _M_compare_helper(__one.c_str(), __two.c_str()); + return _M_compare(__one.c_str(), __two.c_str()); } template @@ -1913,13 +1918,13 @@ namespace std // First try a buffer perhaps big enough. _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); - size_t __res = _M_transform_helper(__c, __lo, __len); + size_t __res = _M_transform(__c, __lo, __len); // If the buffer was not large enough, try again with the correct size. if (__res >= __len) { __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1))); - _M_transform_helper(__c, __lo, __res + 1); + _M_transform(__c, __lo, __res + 1); } return string_type(__c); } @@ -2138,8 +2143,6 @@ namespace std // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. - extern template class vector; - extern template class moneypunct; extern template class moneypunct; extern template class moneypunct_byname; diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h index c80da641..c6daeb6 100644 --- a/libstdc++-v3/include/bits/localefwd.h +++ b/libstdc++-v3/include/bits/localefwd.h @@ -47,20 +47,11 @@ #include // For CHAR_BIT #include // For isspace, etc. #include // For string. -#include // For vector. #include - #include namespace std { - // NB: Don't instantiate required wchar_t facets if no wchar_t support. -#ifdef _GLIBCPP_USE_WCHAR_T -# define _GLIBCPP_NUM_FACETS 28 -#else -# define _GLIBCPP_NUM_FACETS 14 -#endif - // 22.1.1 Locale class locale; @@ -225,7 +216,7 @@ namespace std locale(const locale& __other) throw(); explicit - locale(const char* __std_name); + locale(const char* __s); locale(const locale& __base, const char* __s, category __cat); @@ -277,7 +268,6 @@ namespace std static _Impl* _S_global; static const size_t _S_num_categories = 6; - static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS; explicit locale(_Impl*) throw(); @@ -301,9 +291,6 @@ namespace std class locale::_Impl { public: - // Types. - typedef vector > __vec_facet; - // Friends. friend class locale; friend class locale::facet; @@ -319,8 +306,9 @@ namespace std private: // Data Members. _Atomic_word _M_references; - __vec_facet _M_facets; - string _M_names[_S_num_categories]; + facet** _M_facets; + size_t _M_facets_size; + const char* _M_names[_S_num_categories]; static const locale::id* const _S_id_ctype[]; static const locale::id* const _S_id_numeric[]; static const locale::id* const _S_id_collate[]; @@ -346,15 +334,22 @@ namespace std } _Impl(const _Impl&, size_t); - _Impl(string __name, size_t); + _Impl(const char*, size_t); + _Impl(facet**, size_t, bool); + ~_Impl() throw(); + _Impl(const _Impl&); // Not defined. + + void + operator=(const _Impl&); // Not defined. + inline bool _M_check_same_name() { bool __ret = true; - for (size_t i = 0; i < _S_num_categories - 1; ++i) - __ret &= _M_names[i] == _M_names[i + 1]; + for (size_t i = 0; __ret && i < _S_num_categories - 1; ++i) + __ret &= (strcmp(_M_names[i], _M_names[i + 1]) == 0); return __ret; } @@ -388,11 +383,10 @@ namespace std // 22.1.1.1.2 Class locale::facet class locale::facet { + private: friend class locale; friend class locale::_Impl; - friend class __enc_traits; - private: _Atomic_word _M_references; protected: @@ -407,7 +401,8 @@ namespace std ~facet(); static void - _S_create_c_locale(__c_locale& __cloc, const char* __s); + _S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old = 0); static __c_locale _S_clone_c_locale(__c_locale& __cloc); @@ -447,18 +442,29 @@ namespace std // function (even an inline) would be undefined. mutable size_t _M_index; - // Last id number assigned + // Last id number assigned. static _Atomic_word _S_highwater; void - operator=(const id&); // not defined + operator=(const id&); // Not defined. - id(const id&); // not defined + id(const id&); // Not defined. public: // NB: This class is always a static data member, and thus can be // counted on to be zero-initialized. id(); + + size_t + _M_id() const + { + if (!_M_index) + { + __exchange_and_add(&_S_highwater, 1); + _M_index = _S_highwater; + } + return _M_index - 1; + } }; template diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 81bb975..b30ea09 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -422,32 +422,34 @@ public: template void - assign(_InputIterator __first, _InputIterator __last) - { + assign(_InputIterator __first, _InputIterator __last) + { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } template void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) - { _M_fill_assign((size_type) __n, (_Tp) __val); } + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } template void - _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) { - typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory; - _M_assign_aux(__first, __last, _IterCategory()); - } + typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } template - void _M_assign_aux(_InputIterator __first, _InputIterator __last, - input_iterator_tag); + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); template - void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag); + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); /** * Returns a read/write reference to the data at the first element of the diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index dc79215..607800e 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -40,6 +40,10 @@ namespace std { template + const typename basic_streambuf<_CharT, _Traits>::int_type + basic_streambuf<_CharT, _Traits>::_S_pback_size; + + template typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>:: sbumpc() diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h index c462e7b..4db2594 100644 --- a/libstdc++-v3/include/std/std_fstream.h +++ b/libstdc++-v3/include/std/std_fstream.h @@ -74,18 +74,21 @@ namespace std protected: // Data Members: + // MT lock inherited from libio or other low-level io library. + __c_lock _M_lock; + // External buffer. - __file_type* _M_file; + __file_type _M_file; // Current and beginning state type for codecvt. __state_type _M_state_cur; __state_type _M_state_beg; - // MT lock inherited from libio or other low-level io library. - __c_lock _M_lock; - // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.. bool _M_buf_allocated; + + // Stack-based buffer for unbuffered input. + char_type _M_unbuf[4]; // XXX Needed? bool _M_last_overflowed; @@ -95,7 +98,7 @@ namespace std basic_filebuf(); // Non-standard ctor: - basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, + basic_filebuf(__c_file* __f, ios_base::openmode __mode, int_type __s = static_cast(BUFSIZ)); // Non-standard member: @@ -111,7 +114,7 @@ namespace std // Members: bool - is_open() const { return _M_file ? _M_file->is_open() : false; } + is_open() const { return _M_file.is_open(); } __filebuf_type* open(const char* __s, ios_base::openmode __mode); @@ -126,13 +129,6 @@ namespace std void _M_destroy_internal_buffer(); - void - _M_allocate_pback_buffer(); - - // Create __file_type object and initialize it properly. - void - _M_allocate_file(); - // Overridden virtual functions: virtual streamsize showmanyc(); @@ -191,16 +187,16 @@ namespace std // Make sure that the internal buffer resyncs its idea of // the file position with the external file. - if (__testput && !_M_file->sync()) + if (__testput && !_M_file.sync()) { // Need to restore current position. This interpreted as // the position of the external byte sequence (_M_file) // plus the offset in the current internal buffer // (_M_out_beg - _M_out_cur) - streamoff __cur = _M_file->seekoff(0, ios_base::cur); + streamoff __cur = _M_file.seekoff(0, ios_base::cur); off_type __off = _M_out_cur - _M_out_beg; _M_really_overflow(); - _M_file->seekpos(__cur + __off); + _M_file.seekpos(__cur + __off); } _M_last_overflowed = false; return 0; diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h index 919c1db..53e1e08 100644 --- a/libstdc++-v3/include/std/std_streambuf.h +++ b/libstdc++-v3/include/std/std_streambuf.h @@ -126,8 +126,8 @@ namespace std // requirements. The only basic_streambuf member function that // needs access to these data members is in_avail... // NB: pbacks of over one character are not currently supported. - int_type _M_pback_size; - char_type* _M_pback; + static const int_type _S_pback_size = 1; + char_type _M_pback[_S_pback_size]; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; bool _M_pback_init; @@ -141,7 +141,7 @@ namespace std if (!_M_pback_init) { int_type __dist = _M_in_end - _M_in_cur; - int_type __len = min(_M_pback_size, __dist); + int_type __len = min(_S_pback_size, __dist); traits_type::copy(_M_pback, _M_in_cur, __len); _M_pback_cur_save = _M_in_cur; _M_pback_end_save = _M_in_end; @@ -388,8 +388,8 @@ namespace std _M_buf_size_opt(static_cast(BUFSIZ)), _M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), - _M_buf_locale_init(false), _M_pback_size(1), _M_pback(NULL), - _M_pback_cur_save(NULL), _M_pback_end_save(NULL), _M_pback_init(false) + _M_buf_locale_init(false), _M_pback_cur_save(0), _M_pback_end_save(0), + _M_pback_init(false) { } // Get area: diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new index 3a725a6..afa603a 100644 --- a/libstdc++-v3/libsupc++/new +++ b/libstdc++-v3/libsupc++/new @@ -76,18 +76,18 @@ namespace std * Placement new and delete signatures (take a memory address argument, * does nothing) may not be replaced by a user's program. */ -void *operator new(std::size_t) throw (std::bad_alloc); -void *operator new[](std::size_t) throw (std::bad_alloc); -void operator delete(void *) throw(); -void operator delete[](void *) throw(); -void *operator new(std::size_t, const std::nothrow_t&) throw(); -void *operator new[](std::size_t, const std::nothrow_t&) throw(); -void operator delete(void *, const std::nothrow_t&) throw(); -void operator delete[](void *, const std::nothrow_t&) throw(); +void* operator new(std::size_t) throw (std::bad_alloc); +void* operator new[](std::size_t) throw (std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); +void* operator new(std::size_t, const std::nothrow_t&) throw(); +void* operator new[](std::size_t, const std::nothrow_t&) throw(); +void operator delete(void*, const std::nothrow_t&) throw(); +void operator delete[](void*, const std::nothrow_t&) throw(); // Default placement versions of operator new. -inline void *operator new(std::size_t, void *place) throw() { return place; } -inline void *operator new[](std::size_t, void *place) throw() { return place; } +inline void* operator new(std::size_t, void* __p) throw() { return __p; } +inline void* operator new[](std::size_t, void* __p) throw() { return __p; } //@} } // extern "C++" diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo index c36984c..480dc4a 100644 --- a/libstdc++-v3/libsupc++/typeinfo +++ b/libstdc++-v3/libsupc++/typeinfo @@ -85,7 +85,7 @@ namespace std { return __name; } #if !__GXX_MERGED_TYPEINFO_NAMES - bool before(const type_info& arg) const; + bool before(const type_info& __arg) const; // In old abi, or when weak symbols are not supported, there can // be multiple instances of a type_info object for one // type. Uniqueness must use the _name value, not object address. diff --git a/libstdc++-v3/src/globals.cc b/libstdc++-v3/src/globals.cc index 2c80abd..cf9087f 100644 --- a/libstdc++-v3/src/globals.cc +++ b/libstdc++-v3/src/globals.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 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 @@ -30,6 +30,7 @@ #include #include #include +#include // On AIX, and perhaps other systems, library initialization order is // not guaranteed. For example, the static initializers for the main @@ -45,14 +46,125 @@ namespace std { // Standard "C" locale. + typedef char fake_locale[sizeof(locale)] + __attribute__ ((aligned(__alignof__(locale)))); + fake_locale c_locale; + typedef char fake_locale_Impl[sizeof(locale::_Impl)] __attribute__ ((aligned(__alignof__(locale::_Impl)))); - fake_locale_Impl locale_impl_c; + fake_locale_Impl c_locale_impl; + + typedef char fake_facet_vec[sizeof(locale::facet*)] + __attribute__ ((aligned(__alignof__(locale::facet*)))); + fake_facet_vec facet_vec[_GLIBCPP_NUM_FACETS]; - typedef char fake_locale[sizeof(locale)] - __attribute__ ((aligned(__alignof__(locale)))); - fake_locale locale_c; + typedef char fake_ctype_c[sizeof(std::ctype)] + __attribute__ ((aligned(__alignof__(std::ctype)))); + fake_ctype_c ctype_c; + + typedef char fake_collate_c[sizeof(std::collate)] + __attribute__ ((aligned(__alignof__(std::collate)))); + fake_collate_c collate_c; + + typedef char fake_numpunct_c[sizeof(numpunct)] + __attribute__ ((aligned(__alignof__(numpunct)))); + fake_numpunct_c numpunct_c; + + typedef char fake_num_get_c[sizeof(num_get)] + __attribute__ ((aligned(__alignof__(num_get)))); + fake_num_get_c num_get_c; + + typedef char fake_num_put_c[sizeof(num_put)] + __attribute__ ((aligned(__alignof__(num_put)))); + fake_num_put_c num_put_c; + + typedef char fake_codecvt_c[sizeof(codecvt)] + __attribute__ ((aligned(__alignof__(codecvt)))); + fake_codecvt_c codecvt_c; + + typedef char fake_moneypunct_c[sizeof(moneypunct)] + __attribute__ ((aligned(__alignof__(moneypunct)))); + fake_moneypunct_c moneypunct_tc; + fake_moneypunct_c moneypunct_fc; + + typedef char fake_money_get_c[sizeof(money_get)] + __attribute__ ((aligned(__alignof__(money_get)))); + fake_money_get_c money_get_c; + typedef char fake_money_put_c[sizeof(money_put)] + __attribute__ ((aligned(__alignof__(money_put)))); + fake_money_put_c money_put_c; + + typedef char fake_timepunct_c[sizeof(__timepunct)] + __attribute__ ((aligned(__alignof__(__timepunct)))); + fake_timepunct_c timepunct_c; + + typedef char fake_time_get_c[sizeof(time_get)] + __attribute__ ((aligned(__alignof__(time_get)))); + fake_time_get_c time_get_c; + + typedef char fake_time_put_c[sizeof(time_put)] + __attribute__ ((aligned(__alignof__(time_put)))); + fake_time_put_c time_put_c; + + typedef char fake_messages_c[sizeof(messages)] + __attribute__ ((aligned(__alignof__(messages)))); + fake_messages_c messages_c; + +#ifdef _GLIBCPP_USE_WCHAR_T + typedef char fake_wtype_w[sizeof(std::ctype)] + __attribute__ ((aligned(__alignof__(std::ctype)))); + fake_wtype_w ctype_w; + + typedef char fake_wollate_w[sizeof(std::collate)] + __attribute__ ((aligned(__alignof__(std::collate)))); + fake_wollate_w collate_w; + + typedef char fake_numpunct_w[sizeof(numpunct)] + __attribute__ ((aligned(__alignof__(numpunct)))); + fake_numpunct_w numpunct_w; + + typedef char fake_num_get_w[sizeof(num_get)] + __attribute__ ((aligned(__alignof__(num_get)))); + fake_num_get_w num_get_w; + + typedef char fake_num_put_w[sizeof(num_put)] + __attribute__ ((aligned(__alignof__(num_put)))); + fake_num_put_w num_put_w; + + typedef char fake_wodecvt_w[sizeof(codecvt)] + __attribute__ ((aligned(__alignof__(codecvt)))); + fake_wodecvt_w codecvt_w; + + typedef char fake_moneypunct_w[sizeof(moneypunct)] + __attribute__ ((aligned(__alignof__(moneypunct)))); + fake_moneypunct_w moneypunct_tw; + fake_moneypunct_w moneypunct_fw; + + typedef char fake_money_get_w[sizeof(money_get)] + __attribute__ ((aligned(__alignof__(money_get)))); + fake_money_get_w money_get_w; + + typedef char fake_money_put_w[sizeof(money_put)] + __attribute__ ((aligned(__alignof__(money_put)))); + fake_money_put_w money_put_w; + + typedef char fake_timepunct_w[sizeof(__timepunct)] + __attribute__ ((aligned(__alignof__(__timepunct)))); + fake_timepunct_w timepunct_w; + + typedef char fake_time_get_w[sizeof(time_get)] + __attribute__ ((aligned(__alignof__(time_get)))); + fake_time_get_w time_get_w; + + typedef char fake_time_put_w[sizeof(time_put)] + __attribute__ ((aligned(__alignof__(time_put)))); + fake_time_put_w time_put_w; + + typedef char fake_messages_w[sizeof(messages)] + __attribute__ ((aligned(__alignof__(messages)))); + fake_messages_w messages_w; +#endif // Standard stream objects. typedef char fake_istream[sizeof(istream)] diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index 8662c10..7ac147f 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -410,13 +410,6 @@ namespace std has_facet >(const locale&); #endif - // iterator - typedef vector vec_pfacet; - template class vector; - template class __normal_iterator >; - template class __normal_iterator >; - // locale template char* @@ -484,20 +477,4 @@ namespace std int __convert_from_v(char*, const int, const char*, unsigned long long, const __c_locale&, int); - - template - locale::facet** - fill_n - (locale::facet**, size_t, locale::facet* const&); - - template - __normal_iterator > - fill_n(__normal_iterator >, - size_t, locale::facet* const&); - - template - void - fill(__normal_iterator >, - __normal_iterator >, - locale::facet* const&); } // namespace std diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 0b1056c..54693cb 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -30,23 +30,20 @@ #include #include #include +#include // For towupper, etc. #include #include #include #include #include -#include -#ifdef _GLIBCPP_USE_WCHAR_T -# include // for towupper, etc. -#endif - #include namespace std { // Defined in globals.cc. - extern locale::_Impl locale_impl_c; - extern locale locale_c; + extern locale c_locale; + extern locale::_Impl c_locale_impl; + extern locale::facet** facet_vec; // Definitions for static const data members of locale. const locale::category locale::none; @@ -61,7 +58,6 @@ namespace std locale::_Impl* locale::_S_classic; locale::_Impl* locale::_S_global; const size_t locale::_S_num_categories; - const size_t locale::_S_num_facets; // Definitions for locale::id of standard facets that are specialized. locale::id ctype::id; @@ -159,8 +155,8 @@ namespace std locale::_Impl::_S_id_ctype, locale::_Impl::_S_id_numeric, locale::_Impl::_S_id_collate, - locale::_Impl::_S_id_time, locale::_Impl::_S_id_monetary, + locale::_Impl::_S_id_time, locale::_Impl::_S_id_messages, 0 }; @@ -230,8 +226,7 @@ namespace std locale::operator==(const locale& __rhs) const throw() { string __name = this->name(); - return (_M_impl == __rhs._M_impl - || (__name != "*" && __name == __rhs.name())); + return (_M_impl == __rhs._M_impl || (__name != "*" && __name == __rhs.name())); } const locale& @@ -251,7 +246,8 @@ namespace std _Impl* __old = _S_global; __other._M_impl->_M_add_reference(); _S_global = __other._M_impl; - if (_S_global->_M_check_same_name() && _S_global->_M_names[0] != "*") + if (_S_global->_M_check_same_name() + && (strcmp(_S_global->_M_names[0], "*") != 0)) setlocale(LC_ALL, __other.name().c_str()); // Reference count sanity check: one reference removed for the @@ -265,23 +261,26 @@ namespace std string locale::name() const { - string __ret; // Need some kind of separator character. This one was pretty much // arbitrarily chosen as to not conflict with glibc locales: the // exact formatting is not set in stone. const char __separator = '|'; + string __ret; if (_M_impl->_M_check_same_name()) __ret = _M_impl->_M_names[0]; else { for (size_t i = 0; i < _S_num_categories; ++i) - __ret += __separator + _M_impl->_M_names[i]; + { + __ret += __separator; + __ret += _M_impl->_M_names[i]; + } } return __ret; } - locale const& + const locale& locale::classic() { static _STL_mutex_lock __lock __STL_MUTEX_INITIALIZER; @@ -293,9 +292,13 @@ namespace std { // 26 Standard facets, 2 references. // One reference for _M_classic, one for _M_global - _S_classic = new (&locale_impl_c) _Impl("C", 2); + facet** f = new(&facet_vec) facet*[_GLIBCPP_NUM_FACETS]; + for (size_t __i = 0; __i < _GLIBCPP_NUM_FACETS; ++__i) + f[__i] = 0; + + _S_classic = new (&c_locale_impl) _Impl(f, 2, true); _S_global = _S_classic; - new (&locale_c) locale(_S_classic); + new (&c_locale) locale(_S_classic); } catch(...) { @@ -307,7 +310,7 @@ namespace std __throw_exception_again; } } - return locale_c; + return c_locale; } locale::category @@ -382,7 +385,8 @@ namespace std } } - locale::id::id() { } + locale::id::id() + { } // Definitions for static const data members of ctype_base. const ctype_base::mask ctype_base::space; @@ -404,7 +408,7 @@ namespace std ctype::~ctype() { - if (_M_c_locale_ctype) + if (_M_c_locale_ctype != _S_c_locale) _S_destroy_c_locale(_M_c_locale_ctype); if (_M_del) delete[] this->table(); @@ -453,20 +457,24 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T ctype::ctype(size_t __refs) : __ctype_abstract_base(__refs) - { _M_c_locale_ctype = _S_clone_c_locale(_S_c_locale); } + { _M_c_locale_ctype = _S_c_locale; } ctype::ctype(__c_locale __cloc, size_t __refs) : __ctype_abstract_base(__refs) { _M_c_locale_ctype = _S_clone_c_locale(__cloc); } ctype::~ctype() - { _S_destroy_c_locale(_M_c_locale_ctype); } + { + if (_M_c_locale_ctype != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_ctype); + } template<> ctype_byname::ctype_byname(const char* __s, size_t __refs) : ctype(__refs) { - _S_destroy_c_locale(_M_c_locale_ctype); + if (_M_c_locale_ctype != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_ctype); _S_create_c_locale(_M_c_locale_ctype, __s); } #endif @@ -498,7 +506,7 @@ namespace std const ctype& use_facet >(const locale& __loc) { - size_t __i = ctype::id._M_index; + size_t __i = ctype::id._M_id(); const locale::_Impl* __tmp = __loc._M_impl; return static_cast&>(*(__tmp->_M_facets[__i])); } @@ -508,7 +516,7 @@ namespace std const ctype& use_facet >(const locale& __loc) { - size_t __i = ctype::id._M_index; + size_t __i = ctype::id._M_id(); const locale::_Impl* __tmp = __loc._M_impl; return static_cast&>(*(__tmp->_M_facets[__i])); } @@ -576,3 +584,4 @@ namespace std *__fptr = '\0'; } } // namespace std + diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc index 53c9e8a..1b40e0c 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -29,98 +29,186 @@ #include #include #include -#include namespace std { + // Defined in globals.cc. + extern std::ctype ctype_c; + extern std::collate collate_c; + extern numpunct numpunct_c; + extern num_get num_get_c; + extern num_put num_put_c; + extern codecvt codecvt_c; + extern moneypunct moneypunct_fc; + extern moneypunct moneypunct_tc; + extern money_get money_get_c; + extern money_put money_put_c; + extern __timepunct timepunct_c; + extern time_get time_get_c; + extern time_put time_put_c; + extern std::messages messages_c; +#ifdef _GLIBCPP_USE_WCHAR_T + extern std::ctype ctype_w; + extern std::collate collate_w; + extern numpunct numpunct_w; + extern num_get num_get_w; + extern num_put num_put_w; + extern codecvt codecvt_w; + extern moneypunct moneypunct_fw; + extern moneypunct moneypunct_tw; + extern money_get money_get_w; + extern money_put money_put_w; + extern __timepunct timepunct_w; + extern time_get time_get_w; + extern time_put time_put_w; + extern std::messages messages_w; +#endif + locale::_Impl:: ~_Impl() throw() { - __vec_facet::iterator __it = _M_facets.begin(); - __vec_facet::iterator __end = _M_facets.end(); - for (; __it != __end; ++__it) - if (*__it) - (*__it)->_M_remove_reference(); + for (size_t __i = 0; __i < _M_facets_size; ++__i) + if (_M_facets[__i]) + _M_facets[__i]->_M_remove_reference(); + delete [] _M_facets; } // Clone existing _Impl object. locale::_Impl:: _Impl(const _Impl& __imp, size_t __refs) - : _M_references(__refs) // XXX + : _M_references(__refs), _M_facets_size(__imp._M_facets_size) // XXX { - _M_facets = __imp._M_facets; + try + { + _M_facets = new facet*[_M_facets_size]; + for (size_t __i = 0; __i < _M_facets_size; ++__i) + _M_facets[__i] = 0; + } + catch(...) + { + delete [] _M_facets; + __throw_exception_again; + } + for (size_t __i = 0; __i < _M_facets_size; ++__i) + { + _M_facets[__i] = __imp._M_facets[__i]; + if (_M_facets[__i]) + _M_facets[__i]->_M_add_reference(); + } for (size_t __i = 0; __i < _S_num_categories; ++__i) _M_names[__i] = __imp._M_names[__i]; - - __vec_facet::iterator __it = _M_facets.begin(); - __vec_facet::iterator __end = _M_facets.end(); - for (; __it != __end; ++__it) - if (*__it) - (*__it)->_M_add_reference(); } - // Construct named _Impl, including the standard "C" locale. + // Construct named _Impl. locale::_Impl:: - _Impl(string __str, size_t __refs) - : _M_references(__refs) + _Impl(const char* __s, size_t __refs) + : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS) // XXX { - // Initialize the underlying locale model, which also checks to - // see if the given name is valid. + // Initialize the underlying locale model, which also checks + // to see if the given name is valid. __c_locale __cloc; - locale::facet::_S_create_c_locale(__cloc, __str.c_str()); + locale::facet::_S_create_c_locale(__cloc, __s); - // This is needed as presently "C" locales != required data in - // __timepunct, numpunct, and moneypunct. - __c_locale __cloc_c = NULL; - if (__str != "C" && __str != "POSIX") - __cloc_c = __cloc; - - _M_facets = __vec_facet(_S_num_facets, NULL); + try + { + _M_facets = new facet*[_M_facets_size]; + for (size_t __i = 0; __i < _M_facets_size; ++__i) + _M_facets[__i] = 0; + } + catch(...) + { + delete [] _M_facets; + __throw_exception_again; + } // Name all the categories. for (size_t i = 0; i < _S_num_categories; ++i) - _M_names[i] = __str; + _M_names[i] = __s; // Construct all standard facets and add them to _M_facets. - _M_init_facet(new std::collate(__cloc)); _M_init_facet(new std::ctype(__cloc)); _M_init_facet(new codecvt); - _M_init_facet(new moneypunct(__cloc_c)); - _M_init_facet(new moneypunct(__cloc_c)); - _M_init_facet(new money_get); - _M_init_facet(new money_put); - _M_init_facet(new numpunct(__cloc_c)); + _M_init_facet(new numpunct(__cloc)); _M_init_facet(new num_get); _M_init_facet(new num_put); - _M_init_facet(new __timepunct(__cloc_c, __str.c_str())); + _M_init_facet(new std::collate(__cloc)); + _M_init_facet(new moneypunct(__cloc)); + _M_init_facet(new moneypunct(__cloc)); + _M_init_facet(new money_get); + _M_init_facet(new money_put); + _M_init_facet(new __timepunct(__cloc, __s)); _M_init_facet(new time_get); _M_init_facet(new time_put); - _M_init_facet(new std::messages(__cloc, __str.c_str())); - + _M_init_facet(new std::messages(__cloc, __s)); + #ifdef _GLIBCPP_USE_WCHAR_T - _M_init_facet(new std::collate(__cloc)); _M_init_facet(new std::ctype(__cloc)); _M_init_facet(new codecvt); - _M_init_facet(new moneypunct(__cloc_c)); - _M_init_facet(new moneypunct(__cloc_c)); - _M_init_facet(new money_get); - _M_init_facet(new money_put); - _M_init_facet(new numpunct(__cloc_c)); + _M_init_facet(new numpunct(__cloc)); _M_init_facet(new num_get); _M_init_facet(new num_put); - _M_init_facet(new __timepunct(__cloc_c, __str.c_str())); + _M_init_facet(new std::collate(__cloc)); + _M_init_facet(new moneypunct(__cloc)); + _M_init_facet(new moneypunct(__cloc)); + _M_init_facet(new money_get); + _M_init_facet(new money_put); + _M_init_facet(new __timepunct(__cloc, __s)); _M_init_facet(new time_get); _M_init_facet(new time_put); - _M_init_facet(new std::messages(__cloc, __str.c_str())); + _M_init_facet(new std::messages(__cloc, __s)); #endif locale::facet::_S_destroy_c_locale(__cloc); } + + // Construct "C" _Impl. + locale::_Impl:: + _Impl(facet** __f, size_t __refs, bool) + : _M_references(__refs), _M_facets(__f), _M_facets_size(_GLIBCPP_NUM_FACETS) + { + // Name all the categories. + for (size_t i = 0; i < _S_num_categories; ++i) + _M_names[i] = "C"; + + // This is needed as presently the C++ version of "C" locales + // != data in the underlying locale model for __timepunct, + // numpunct, and moneypunct. Also, the "C" locales must be + // constructed in a way such that they are pre-allocated. + _M_init_facet(new (&ctype_c) std::ctype); + _M_init_facet(new (&codecvt_c) codecvt); + _M_init_facet(new (&numpunct_c) numpunct); + _M_init_facet(new (&num_get_c) num_get); + _M_init_facet(new (&num_put_c) num_put); + _M_init_facet(new (&collate_c) std::collate); + _M_init_facet(new (&moneypunct_fc) moneypunct); + _M_init_facet(new (&moneypunct_tc) moneypunct); + _M_init_facet(new (&money_get_c) money_get); + _M_init_facet(new (&money_put_c) money_put); + _M_init_facet(new (&timepunct_c) __timepunct); + _M_init_facet(new (&time_get_c) time_get); + _M_init_facet(new (&time_put_c) time_put); + _M_init_facet(new (&messages_c) std::messages); +#ifdef _GLIBCPP_USE_WCHAR_T + _M_init_facet(new (&ctype_w) std::ctype); + _M_init_facet(new (&codecvt_w) codecvt); + _M_init_facet(new (&numpunct_w) numpunct); + _M_init_facet(new (&num_get_w) num_get); + _M_init_facet(new (&num_put_w) num_put); + _M_init_facet(new (&collate_w) std::collate); + _M_init_facet(new (&moneypunct_fw) moneypunct); + _M_init_facet(new (&moneypunct_tw) moneypunct); + _M_init_facet(new (&money_get_w) money_get); + _M_init_facet(new (&money_put_w) money_put); + _M_init_facet(new (&timepunct_w) __timepunct); + _M_init_facet(new (&time_get_w) time_get); + _M_init_facet(new (&time_put_w) time_put); + _M_init_facet(new (&messages_w) std::messages); +#endif + } void locale::_Impl:: _M_replace_categories(const _Impl* __imp, category __cat) { - const string __none("*"); category __mask; for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix) { @@ -130,7 +218,8 @@ namespace std // Need to replace entry in _M_facets with other locale's info. _M_replace_category(__imp, _S_facet_categories[__ix]); // If both have names, go ahead and mangle. - if (_M_names[__ix] != __none && __imp->_M_names[__ix] != __none) + if (strcmp(_M_names[__ix], "*") != 0 + && strcmp(__imp->_M_names[__ix], "*") != 0) _M_names[__ix] = __imp->_M_names[__ix]; } } @@ -148,11 +237,9 @@ namespace std locale::_Impl:: _M_replace_facet(const _Impl* __imp, const locale::id* __idp) { - size_t __index = __idp->_M_index; - if (__index == 0 || __imp->_M_facets.size() <= __index - || __imp->_M_facets[__index] == 0) + size_t __index = __idp->_M_id(); + if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index]) __throw_runtime_error("no locale facet"); - _M_install_facet(__idp, __imp->_M_facets[__index]); } @@ -162,12 +249,28 @@ namespace std { if (__fp) { - size_t& __index = __idp->_M_index; - if (!__index) - __index = 1 + __exchange_and_add(&locale::id::_S_highwater, 1); - - if (__index >= _M_facets.size()) - _M_facets.resize(__index + 1, 0); // might throw + size_t __index = __idp->_M_id(); + if (__index > _M_facets_size - 1) + { + facet** __old = _M_facets; + facet** __new; + const size_t __new_size = __index + 4; + try + { __new = new facet*[__new_size]; } + catch(...) + { + delete [] __new; + __throw_exception_again; + } + for (size_t __i = 0; __i < _M_facets_size; ++__i) + __new[__i] = _M_facets[__i]; + for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) + __new[__i2] = 0; + + _M_facets_size = __new_size; + _M_facets = __new; + delete [] __old; + } facet*& __fpr = _M_facets[__index]; if (__fpr) diff --git a/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc b/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc index 5630351..7bf1e69 100644 --- a/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc +++ b/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc @@ -394,7 +394,8 @@ void test04() void test05() { using namespace std; - + bool test = true; + double d = 0.0; istringstream iss; diff --git a/libstdc++-v3/testsuite/22_locale/num_get_members_wchar_t.cc b/libstdc++-v3/testsuite/22_locale/num_get_members_wchar_t.cc index c4927e1..2efbe5c 100644 --- a/libstdc++-v3/testsuite/22_locale/num_get_members_wchar_t.cc +++ b/libstdc++-v3/testsuite/22_locale/num_get_members_wchar_t.cc @@ -396,7 +396,8 @@ void test04() void test05() { using namespace std; - + bool test = true; + double d = 0.0; wistringstream iss; diff --git a/libstdc++-v3/testsuite/27_io/filebuf_members.cc b/libstdc++-v3/testsuite/27_io/filebuf_members.cc index eed4ff6..f8153c4 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf_members.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf_members.cc @@ -185,9 +185,9 @@ void test_05() scratch_file.close(); scratch_file.open("SCRATCH", std::ios::in); + if (!scratch_file) + VERIFY( false ); scratch_file.close(); - - VERIFY(scratch_file); } int -- 2.7.4