diff options
author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-04-16 00:45:36 +0000 |
---|---|---|
committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-04-16 00:45:36 +0000 |
commit | 5f8a31fe840b65eb67326eb59debe7279bf1354c (patch) | |
tree | b099d8807cf3e64edeb22eeaae55f91bee6e0c39 | |
parent | 9a3d0fc8ef6accf6cd6def570239b53e611845bb (diff) | |
download | gcc-5f8a31fe840b65eb67326eb59debe7279bf1354c.tar.gz |
2002-04-15 Benjamin Kosnik <bkoz@redhat.com>
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52345 138bc75d-0d04-0410-961f-82ee72b054a4
38 files changed, 915 insertions, 555 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1611797b14a..0bf364cb16c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,90 @@ +2002-04-15 Benjamin Kosnik <bkoz@redhat.com> + + 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 <sje@cup.hp.com> * 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 50da49e1cba..eaebdf25ad9 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<char>::~__basic_file() - { - if (this->is_open()) - { - fflush(_M_cfile); - this->close(); - } - } + { this->close(); } void __basic_file<char>::_M_open_mode(ios_base::openmode __mode, int&, int&, @@ -75,7 +69,7 @@ namespace std } __basic_file<char>* - __basic_file<char>::sys_open(__c_file_type* __file, ios_base::openmode) + __basic_file<char>::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<char>::is_open() { return _M_cfile != 0; } + __basic_file<char>::is_open() const { return _M_cfile != 0; } int __basic_file<char>::fd() { return fileno(_M_cfile) ; } @@ -125,8 +119,15 @@ namespace std __basic_file<char>::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 cfc0b4622ad..ca81d6d168f 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<char> { // 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 de61da4de7e..0d11d14d3f9 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 245b5b23f80..8ede46ec2dd 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 085f7668bde..93767d93e3b 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<char>::_M_compare_helper(const char* __one, - const char* __two) const + collate<char>::_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<char>::_M_transform_helper(char* __to, const char* __from, - size_t __n) const + collate<char>::_M_transform(char* __to, const char* __from, + size_t __n) const { return strxfrm(__to, __from, __n); } #ifdef _GLIBCPP_USE_WCHAR_T template<> int - collate<wchar_t>::_M_compare_helper(const wchar_t* __one, - const wchar_t* __two) const + collate<wchar_t>::_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<wchar_t>::_M_transform_helper(wchar_t* __to, const wchar_t* __from, - size_t __n) const + collate<wchar_t>::_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 7a31900a8e6..7c2e13b62df 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<char, true>::~moneypunct() + { } + + template<> + moneypunct<char, false>::~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<wchar_t, true>::~moneypunct() + { } + + template<> + moneypunct<wchar_t, false>::~moneypunct() + { } #endif } diff --git a/libstdc++-v3/config/locale/generic/numeric_members.cc b/libstdc++-v3/config/locale/generic/numeric_members.cc index 7a511e3a36a..f942e0415b0 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<char>::~numpunct() + { } #ifdef _GLIBCPP_USE_WCHAR_T template<> @@ -61,5 +65,9 @@ namespace std _M_truename = L"true"; _M_falsename = L"false"; } + + template<> + numpunct<wchar_t>::~numpunct() + { } #endif } diff --git a/libstdc++-v3/config/locale/generic/time_members.cc b/libstdc++-v3/config/locale/generic/time_members.cc index e546f30a0db..16a4998cead 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<char>::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct<char>:: - _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<wchar_t>::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct<wchar_t>:: - _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 62290901141..60ec54d76db 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 d023d53468a..3b55f6985c6 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<char>::_M_compare_helper(const char* __one, - const char* __two) const + collate<char>::_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<char>::_M_transform_helper(char* __to, const char* __from, - size_t __n) const + collate<char>::_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<wchar_t>::_M_compare_helper(const wchar_t* __one, - const wchar_t* __two) const + collate<wchar_t>::_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<wchar_t>::_M_transform_helper(wchar_t* __to, const wchar_t* __from, - size_t __n) const + collate<wchar_t>::_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 33540c948f2..090738bf5b6 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<char>::ctype_byname(const char* __s, size_t __refs) : ctype<char>(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<wchar_t>:: do_is(mask __m, char_type __c) const - { return static_cast<bool>(__iswctype_l(__c, _M_convert_to_wmask(__m), - _M_c_locale_ctype)); } + { + return static_cast<bool>(__iswctype_l(__c, _M_convert_to_wmask(__m), + _M_c_locale_ctype)); + } const wchar_t* ctype<wchar_t>:: diff --git a/libstdc++-v3/config/locale/gnu/messages_members.cc b/libstdc++-v3/config/locale/gnu/messages_members.cc index 28702c2bc79..f2020032fc2 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<char>::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 88a4f95a24a..bf9b50cbb95 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<char, true>::_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<char, false>::_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<char, true>::~moneypunct() + { } + + template<> + moneypunct<char, false>::~moneypunct() + { } + #ifdef _GLIBCPP_USE_WCHAR_T template<> void moneypunct<wchar_t, true>::_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<wchar_t*>(__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<wchar_t, false>::_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<wchar_t*>(__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<wchar_t, true>::~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<wchar_t, false>::~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 4284c7c07b3..4806435a50f 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<char>::_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<char>::~numpunct() + { } + #ifdef _GLIBCPP_USE_WCHAR_T template<> void numpunct<wchar_t>::_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<wchar_t>::~numpunct() + { } + #endif } diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc b/libstdc++-v3/config/locale/gnu/time_members.cc index 124a91787c1..665ea0245be 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<char>::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct<char>:: - _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<char>::_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<wchar_t>::~__timepunct() + { + if (_M_c_locale_timepunct != _S_c_locale) + _S_destroy_c_locale(_M_c_locale_timepunct); + } + + template<> void __timepunct<wchar_t>:: - _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<wchar_t>::_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 493ac014208..0a89aeea034 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 bbfb85eb9e6..4c68f2758ea 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 891c66b2844..139e6c9ca35 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 18324d167dd..ee70ab46c3b 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<char>(__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<char>::ctype(const mask* __table, bool __del, size_t __refs) : __ctype_abstract_base<char>(__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<char>::do_toupper(char __c) const diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 50818da602b..3f4b5fb73ca 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 85143235436..fb2f87672ac 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -42,38 +42,25 @@ namespace std template<typename _CharT, typename _Traits> 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<typename _CharT, typename _Traits> - 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<typename _CharT, typename _Traits> - 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<typename _CharT, typename _Traits> 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<typename _CharT, typename _Traits> 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 _CharT, typename _Traits> 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<char*>(_M_in_beg), - _M_buf_size); + __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), + _M_buf_size); __ilen = __elen; } else { char* __buf = static_cast<char*>(__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<char*>(__ibuf), __ilen); + __elen += _M_file.xsputn(reinterpret_cast<char*>(__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 a45023f8cb6..d63eb5dd2d5 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 <ctime> // For struct tm -#ifdef _GLIBCPP_USE_WCHAR_T -# include <cwctype> // For wctype_t -#endif +#include <cwctype> // For wctype_t #include <ios> // 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 <bits/ctype_base.h> @@ -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<typename _CharT> locale::id numpunct<_CharT>::id; template<> + numpunct<char>::~numpunct(); + + template<> void numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); #ifdef _GLIBCPP_USE_WCHAR_T template<> + numpunct<wchar_t>::~numpunct(); + + template<> void numpunct<wchar_t>::_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<char>::_M_compare_helper(const char*, const char*) const; + collate<char>::_M_compare(const char*, const char*) const; template<> size_t - collate<char>::_M_transform_helper(char*, const char*, size_t) const; + collate<char>::_M_transform(char*, const char*, size_t) const; #ifdef _GLIBCPP_USE_WCHAR_T template<> int - collate<wchar_t>::_M_compare_helper(const wchar_t*, const wchar_t*) const; + collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const; template<> size_t - collate<wchar_t>::_M_transform_helper(wchar_t*, const wchar_t*, - size_t) const; + collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const; #endif template<typename _CharT> @@ -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<typename _CharT> locale::id __timepunct<_CharT>::id; // Specializations. + template<> + __timepunct<char>::~__timepunct(); + template<> const char* __timepunct<char>::_S_timezones[14]; @@ -1110,10 +1123,12 @@ namespace std template<> void - __timepunct<char>::_M_put_helper(char*, size_t, const char*, - const tm*) const; + __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const; #ifdef _GLIBCPP_USE_WCHAR_T + template<> + __timepunct<wchar_t>::~__timepunct(); + template<> const wchar_t* __timepunct<wchar_t>::_S_timezones[14]; @@ -1124,8 +1139,8 @@ namespace std template<> void - __timepunct<wchar_t>::_M_put_helper(wchar_t*, size_t, const wchar_t*, - const tm*) const; + __timepunct<wchar_t>::_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<typename _CharT, bool _Intl> @@ -1432,6 +1447,12 @@ namespace std template<typename _CharT, bool _Intl> const bool moneypunct<_CharT, _Intl>::intl; + template<> + moneypunct<char, true>::~moneypunct(); + + template<> + moneypunct<char, false>::~moneypunct(); + template<> void moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc); @@ -1441,6 +1462,12 @@ namespace std moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc); #ifdef _GLIBCPP_USE_WCHAR_T + template<> + moneypunct<wchar_t, true>::~moneypunct(); + + template<> + moneypunct<wchar_t, false>::~moneypunct(); + template<> void moneypunct<wchar_t, true>::_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<char>&, 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 d81406ff4b1..d362c33f87f 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<const _Facet&>(*__fp); + return static_cast<const _Facet&>(*__facets[__i]); } template<typename _Facet> 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<numpunct<_CharT> >(__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<char*>(__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<char*>(__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<char*>(__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<numpunct<_CharT> >(__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<part>(__p.field[3]) != money_base::none) - || __sign.size() > 1) + if (__io.flags() & ios_base::showbase + || __i < 2 || __sign.size() > 1 + || ((static_cast<part>(__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<char*>(__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<char*>(__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<char_type>::length(__res); @@ -1884,13 +1889,13 @@ namespace std // Generic version does nothing. template<typename _CharT> 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<typename _CharT> 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<typename _CharT> @@ -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<typename _CharT> @@ -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<locale::facet*>; - extern template class moneypunct<char, false>; extern template class moneypunct<char, true>; extern template class moneypunct_byname<char, false>; diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h index c80da641490..c6daeb69014 100644 --- a/libstdc++-v3/include/bits/localefwd.h +++ b/libstdc++-v3/include/bits/localefwd.h @@ -47,20 +47,11 @@ #include <climits> // For CHAR_BIT #include <cctype> // For isspace, etc. #include <string> // For string. -#include <vector> // For vector. #include <bits/functexcept.h> - #include <bits/atomicity.h> 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<facet*, allocator<facet*> > __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<typename _Facet> diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 81bb9752453..b30ea09a1f8 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -422,32 +422,34 @@ public: template<class _InputIterator> 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<class _Integer> 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<class _InputIter> 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 <class _InputIterator> - void _M_assign_aux(_InputIterator __first, _InputIterator __last, - input_iterator_tag); + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); template <class _ForwardIterator> - 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 dc7921527d9..607800e19e0 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -40,6 +40,10 @@ namespace std { template<typename _CharT, typename _Traits> + const typename basic_streambuf<_CharT, _Traits>::int_type + basic_streambuf<_CharT, _Traits>::_S_pback_size; + + template<typename _CharT, typename _Traits> 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 c462e7bd188..4db259438aa 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<int_type>(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 919c1db022f..53e1e08b231 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<int_type>(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 3a725a6c933..afa603a786d 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 c36984cf8f3..480dc4a21a1 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 2c80abd6937..cf9087f9e08 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 <fstream> #include <istream> #include <ostream> +#include <locale> // 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<char>)] + __attribute__ ((aligned(__alignof__(std::ctype<char>)))); + fake_ctype_c ctype_c; + + typedef char fake_collate_c[sizeof(std::collate<char>)] + __attribute__ ((aligned(__alignof__(std::collate<char>)))); + fake_collate_c collate_c; + + typedef char fake_numpunct_c[sizeof(numpunct<char>)] + __attribute__ ((aligned(__alignof__(numpunct<char>)))); + fake_numpunct_c numpunct_c; + + typedef char fake_num_get_c[sizeof(num_get<char>)] + __attribute__ ((aligned(__alignof__(num_get<char>)))); + fake_num_get_c num_get_c; + + typedef char fake_num_put_c[sizeof(num_put<char>)] + __attribute__ ((aligned(__alignof__(num_put<char>)))); + fake_num_put_c num_put_c; + + typedef char fake_codecvt_c[sizeof(codecvt<char, char, mbstate_t>)] + __attribute__ ((aligned(__alignof__(codecvt<char, char, mbstate_t>)))); + fake_codecvt_c codecvt_c; + + typedef char fake_moneypunct_c[sizeof(moneypunct<char, true>)] + __attribute__ ((aligned(__alignof__(moneypunct<char, true>)))); + fake_moneypunct_c moneypunct_tc; + fake_moneypunct_c moneypunct_fc; + + typedef char fake_money_get_c[sizeof(money_get<char>)] + __attribute__ ((aligned(__alignof__(money_get<char>)))); + fake_money_get_c money_get_c; + typedef char fake_money_put_c[sizeof(money_put<char>)] + __attribute__ ((aligned(__alignof__(money_put<char>)))); + fake_money_put_c money_put_c; + + typedef char fake_timepunct_c[sizeof(__timepunct<char>)] + __attribute__ ((aligned(__alignof__(__timepunct<char>)))); + fake_timepunct_c timepunct_c; + + typedef char fake_time_get_c[sizeof(time_get<char>)] + __attribute__ ((aligned(__alignof__(time_get<char>)))); + fake_time_get_c time_get_c; + + typedef char fake_time_put_c[sizeof(time_put<char>)] + __attribute__ ((aligned(__alignof__(time_put<char>)))); + fake_time_put_c time_put_c; + + typedef char fake_messages_c[sizeof(messages<char>)] + __attribute__ ((aligned(__alignof__(messages<char>)))); + fake_messages_c messages_c; + +#ifdef _GLIBCPP_USE_WCHAR_T + typedef char fake_wtype_w[sizeof(std::ctype<wchar_t>)] + __attribute__ ((aligned(__alignof__(std::ctype<wchar_t>)))); + fake_wtype_w ctype_w; + + typedef char fake_wollate_w[sizeof(std::collate<wchar_t>)] + __attribute__ ((aligned(__alignof__(std::collate<wchar_t>)))); + fake_wollate_w collate_w; + + typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)] + __attribute__ ((aligned(__alignof__(numpunct<wchar_t>)))); + fake_numpunct_w numpunct_w; + + typedef char fake_num_get_w[sizeof(num_get<wchar_t>)] + __attribute__ ((aligned(__alignof__(num_get<wchar_t>)))); + fake_num_get_w num_get_w; + + typedef char fake_num_put_w[sizeof(num_put<wchar_t>)] + __attribute__ ((aligned(__alignof__(num_put<wchar_t>)))); + fake_num_put_w num_put_w; + + typedef char fake_wodecvt_w[sizeof(codecvt<wchar_t, char, mbstate_t>)] + __attribute__ ((aligned(__alignof__(codecvt<wchar_t, char, mbstate_t>)))); + fake_wodecvt_w codecvt_w; + + typedef char fake_moneypunct_w[sizeof(moneypunct<wchar_t, true>)] + __attribute__ ((aligned(__alignof__(moneypunct<wchar_t, true>)))); + fake_moneypunct_w moneypunct_tw; + fake_moneypunct_w moneypunct_fw; + + typedef char fake_money_get_w[sizeof(money_get<wchar_t>)] + __attribute__ ((aligned(__alignof__(money_get<wchar_t>)))); + fake_money_get_w money_get_w; + + typedef char fake_money_put_w[sizeof(money_put<wchar_t>)] + __attribute__ ((aligned(__alignof__(money_put<wchar_t>)))); + fake_money_put_w money_put_w; + + typedef char fake_timepunct_w[sizeof(__timepunct<wchar_t>)] + __attribute__ ((aligned(__alignof__(__timepunct<wchar_t>)))); + fake_timepunct_w timepunct_w; + + typedef char fake_time_get_w[sizeof(time_get<wchar_t>)] + __attribute__ ((aligned(__alignof__(time_get<wchar_t>)))); + fake_time_get_w time_get_w; + + typedef char fake_time_put_w[sizeof(time_put<wchar_t>)] + __attribute__ ((aligned(__alignof__(time_put<wchar_t>)))); + fake_time_put_w time_put_w; + + typedef char fake_messages_w[sizeof(messages<wchar_t>)] + __attribute__ ((aligned(__alignof__(messages<wchar_t>)))); + 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 8662c106528..7ac147f9fa0 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -410,13 +410,6 @@ namespace std has_facet<messages<wchar_t> >(const locale&); #endif - // iterator - typedef vector<locale::facet*> vec_pfacet; - template class vector<locale::facet*>; - template class __normal_iterator<locale::facet**, vector<locale::facet*> >; - template class __normal_iterator<locale::facet* const*, - vector<locale::facet*> >; - // 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*> - (locale::facet**, size_t, locale::facet* const&); - - template - __normal_iterator<locale::facet**, vector<locale::facet*> > - fill_n(__normal_iterator<locale::facet**, vector<locale::facet*> >, - size_t, locale::facet* const&); - - template - void - fill(__normal_iterator<locale::facet**, vector<locale::facet*> >, - __normal_iterator<locale::facet**, vector<locale::facet*> >, - locale::facet* const&); } // namespace std diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 0b1056c045d..54693cb2059 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -30,23 +30,20 @@ #include <cstring> #include <cassert> #include <cctype> +#include <cwctype> // For towupper, etc. #include <limits> #include <exception> #include <locale> #include <istream> #include <ostream> -#include <vector> -#ifdef _GLIBCPP_USE_WCHAR_T -# include <cwctype> // for towupper, etc. -#endif - #include <bits/atomicity.h> 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<char>::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<char>::~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<wchar_t>::ctype(size_t __refs) : __ctype_abstract_base<wchar_t>(__refs) - { _M_c_locale_ctype = _S_clone_c_locale(_S_c_locale); } + { _M_c_locale_ctype = _S_c_locale; } ctype<wchar_t>::ctype(__c_locale __cloc, size_t __refs) : __ctype_abstract_base<wchar_t>(__refs) { _M_c_locale_ctype = _S_clone_c_locale(__cloc); } ctype<wchar_t>::~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<wchar_t>::ctype_byname(const char* __s, size_t __refs) : ctype<wchar_t>(__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<char>& use_facet<ctype<char> >(const locale& __loc) { - size_t __i = ctype<char>::id._M_index; + size_t __i = ctype<char>::id._M_id(); const locale::_Impl* __tmp = __loc._M_impl; return static_cast<const ctype<char>&>(*(__tmp->_M_facets[__i])); } @@ -508,7 +516,7 @@ namespace std const ctype<wchar_t>& use_facet<ctype<wchar_t> >(const locale& __loc) { - size_t __i = ctype<wchar_t>::id._M_index; + size_t __i = ctype<wchar_t>::id._M_id(); const locale::_Impl* __tmp = __loc._M_impl; return static_cast<const ctype<wchar_t>&>(*(__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 53c9e8a0347..1b40e0c3db6 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -29,98 +29,186 @@ #include <clocale> #include <cstring> #include <locale> -#include <vector> namespace std { + // Defined in globals.cc. + extern std::ctype<char> ctype_c; + extern std::collate<char> collate_c; + extern numpunct<char> numpunct_c; + extern num_get<char> num_get_c; + extern num_put<char> num_put_c; + extern codecvt<char, char, mbstate_t> codecvt_c; + extern moneypunct<char, false> moneypunct_fc; + extern moneypunct<char, true> moneypunct_tc; + extern money_get<char> money_get_c; + extern money_put<char> money_put_c; + extern __timepunct<char> timepunct_c; + extern time_get<char> time_get_c; + extern time_put<char> time_put_c; + extern std::messages<char> messages_c; +#ifdef _GLIBCPP_USE_WCHAR_T + extern std::ctype<wchar_t> ctype_w; + extern std::collate<wchar_t> collate_w; + extern numpunct<wchar_t> numpunct_w; + extern num_get<wchar_t> num_get_w; + extern num_put<wchar_t> num_put_w; + extern codecvt<wchar_t, char, mbstate_t> codecvt_w; + extern moneypunct<wchar_t, false> moneypunct_fw; + extern moneypunct<wchar_t, true> moneypunct_tw; + extern money_get<wchar_t> money_get_w; + extern money_put<wchar_t> money_put_w; + extern __timepunct<wchar_t> timepunct_w; + extern time_get<wchar_t> time_get_w; + extern time_put<wchar_t> time_put_w; + extern std::messages<wchar_t> 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<char>(__cloc)); _M_init_facet(new std::ctype<char>(__cloc)); _M_init_facet(new codecvt<char, char, mbstate_t>); - _M_init_facet(new moneypunct<char, false>(__cloc_c)); - _M_init_facet(new moneypunct<char, true>(__cloc_c)); - _M_init_facet(new money_get<char>); - _M_init_facet(new money_put<char>); - _M_init_facet(new numpunct<char>(__cloc_c)); + _M_init_facet(new numpunct<char>(__cloc)); _M_init_facet(new num_get<char>); _M_init_facet(new num_put<char>); - _M_init_facet(new __timepunct<char>(__cloc_c, __str.c_str())); + _M_init_facet(new std::collate<char>(__cloc)); + _M_init_facet(new moneypunct<char, false>(__cloc)); + _M_init_facet(new moneypunct<char, true>(__cloc)); + _M_init_facet(new money_get<char>); + _M_init_facet(new money_put<char>); + _M_init_facet(new __timepunct<char>(__cloc, __s)); _M_init_facet(new time_get<char>); _M_init_facet(new time_put<char>); - _M_init_facet(new std::messages<char>(__cloc, __str.c_str())); - + _M_init_facet(new std::messages<char>(__cloc, __s)); + #ifdef _GLIBCPP_USE_WCHAR_T - _M_init_facet(new std::collate<wchar_t>(__cloc)); _M_init_facet(new std::ctype<wchar_t>(__cloc)); _M_init_facet(new codecvt<wchar_t, char, mbstate_t>); - _M_init_facet(new moneypunct<wchar_t, false>(__cloc_c)); - _M_init_facet(new moneypunct<wchar_t, true>(__cloc_c)); - _M_init_facet(new money_get<wchar_t>); - _M_init_facet(new money_put<wchar_t>); - _M_init_facet(new numpunct<wchar_t>(__cloc_c)); + _M_init_facet(new numpunct<wchar_t>(__cloc)); _M_init_facet(new num_get<wchar_t>); _M_init_facet(new num_put<wchar_t>); - _M_init_facet(new __timepunct<wchar_t>(__cloc_c, __str.c_str())); + _M_init_facet(new std::collate<wchar_t>(__cloc)); + _M_init_facet(new moneypunct<wchar_t, false>(__cloc)); + _M_init_facet(new moneypunct<wchar_t, true>(__cloc)); + _M_init_facet(new money_get<wchar_t>); + _M_init_facet(new money_put<wchar_t>); + _M_init_facet(new __timepunct<wchar_t>(__cloc, __s)); _M_init_facet(new time_get<wchar_t>); _M_init_facet(new time_put<wchar_t>); - _M_init_facet(new std::messages<wchar_t>(__cloc, __str.c_str())); + _M_init_facet(new std::messages<wchar_t>(__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<char>); + _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>); + _M_init_facet(new (&numpunct_c) numpunct<char>); + _M_init_facet(new (&num_get_c) num_get<char>); + _M_init_facet(new (&num_put_c) num_put<char>); + _M_init_facet(new (&collate_c) std::collate<char>); + _M_init_facet(new (&moneypunct_fc) moneypunct<char, false>); + _M_init_facet(new (&moneypunct_tc) moneypunct<char, true>); + _M_init_facet(new (&money_get_c) money_get<char>); + _M_init_facet(new (&money_put_c) money_put<char>); + _M_init_facet(new (&timepunct_c) __timepunct<char>); + _M_init_facet(new (&time_get_c) time_get<char>); + _M_init_facet(new (&time_put_c) time_put<char>); + _M_init_facet(new (&messages_c) std::messages<char>); +#ifdef _GLIBCPP_USE_WCHAR_T + _M_init_facet(new (&ctype_w) std::ctype<wchar_t>); + _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>); + _M_init_facet(new (&numpunct_w) numpunct<wchar_t>); + _M_init_facet(new (&num_get_w) num_get<wchar_t>); + _M_init_facet(new (&num_put_w) num_put<wchar_t>); + _M_init_facet(new (&collate_w) std::collate<wchar_t>); + _M_init_facet(new (&moneypunct_fw) moneypunct<wchar_t, false>); + _M_init_facet(new (&moneypunct_tw) moneypunct<wchar_t, true>); + _M_init_facet(new (&money_get_w) money_get<wchar_t>); + _M_init_facet(new (&money_put_w) money_put<wchar_t>); + _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>); + _M_init_facet(new (&time_get_w) time_get<wchar_t>); + _M_init_facet(new (&time_put_w) time_put<wchar_t>); + _M_init_facet(new (&messages_w) std::messages<wchar_t>); +#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 5630351e2d5..7bf1e6956e7 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 c4927e18fb7..2efbe5c5aff 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 eed4ff6fc77..f8153c42e39 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 |