From ee820e9f244fb13f3dd7773478f525ddcbeac501 Mon Sep 17 00:00:00 2001 From: obrien Date: Wed, 4 Dec 2002 16:53:59 +0000 Subject: Gcc 3.2.1 release virgin vendor import. (19-Nov-2002) --- contrib/libstdc++/src/codecvt.cc | 2 +- contrib/libstdc++/src/ctype.cc | 11 +- contrib/libstdc++/src/globals.cc | 129 ++++++++++++++++------ contrib/libstdc++/src/ios.cc | 26 +++-- contrib/libstdc++/src/locale-inst.cc | 4 - contrib/libstdc++/src/locale.cc | 207 +++++++++++++++++++++++++---------- contrib/libstdc++/src/localename.cc | 157 ++++++++++++++++++-------- contrib/libstdc++/src/string-inst.cc | 4 +- 8 files changed, 384 insertions(+), 156 deletions(-) (limited to 'contrib/libstdc++/src') diff --git a/contrib/libstdc++/src/codecvt.cc b/contrib/libstdc++/src/codecvt.cc index a2fb42d..1fe6b97 100644 --- a/contrib/libstdc++/src/codecvt.cc +++ b/contrib/libstdc++/src/codecvt.cc @@ -50,7 +50,7 @@ namespace std codecvt:: ~codecvt() - { } + { } codecvt_base::result codecvt:: diff --git a/contrib/libstdc++/src/ctype.cc b/contrib/libstdc++/src/ctype.cc index 7ca934e..3d5ee61 100644 --- a/contrib/libstdc++/src/ctype.cc +++ b/contrib/libstdc++/src/ctype.cc @@ -79,8 +79,7 @@ namespace std ctype::~ctype() { - if (_M_c_locale_ctype != _S_c_locale) - _S_destroy_c_locale(_M_c_locale_ctype); + _S_destroy_c_locale(_M_c_locale_ctype); if (_M_del) delete[] this->table(); } @@ -135,17 +134,13 @@ namespace std { _M_c_locale_ctype = _S_clone_c_locale(__cloc); } ctype::~ctype() - { - if (_M_c_locale_ctype != _S_c_locale) - _S_destroy_c_locale(_M_c_locale_ctype); - } + { _S_destroy_c_locale(_M_c_locale_ctype); } template<> ctype_byname::ctype_byname(const char* __s, size_t __refs) : ctype(__refs) { - if (_M_c_locale_ctype != _S_c_locale) - _S_destroy_c_locale(_M_c_locale_ctype); + _S_destroy_c_locale(_M_c_locale_ctype); _S_create_c_locale(_M_c_locale_ctype, __s); } #endif diff --git a/contrib/libstdc++/src/globals.cc b/contrib/libstdc++/src/globals.cc index 36d193f..c6ff69c 100644 --- a/contrib/libstdc++/src/globals.cc +++ b/contrib/libstdc++/src/globals.cc @@ -44,163 +44,209 @@ // Because declares the standard streams to be [io]stream // types instead of say [io]fstream types, it is also necessary to // allocate the actual file buffers in this file. -namespace std +namespace __gnu_cxx { - // Standard "C" locale. - typedef char fake_locale[sizeof(locale)] - __attribute__ ((aligned(__alignof__(locale)))); - fake_locale c_locale; + using namespace std; + + typedef char fake_facet_name[sizeof(char*)] + __attribute__ ((aligned(__alignof__(char*)))); + fake_facet_name facet_name[6 + _GLIBCPP_NUM_CATEGORIES]; typedef char fake_locale_Impl[sizeof(locale::_Impl)] __attribute__ ((aligned(__alignof__(locale::_Impl)))); fake_locale_Impl c_locale_impl; - + + + // NB: The asm directives renames these non-exported, namespace + // __gnu_cxx symbols into the mistakenly exported, namespace std + // symbols in GLIBCPP_3.2. + // The rename syntax is + // asm (".symver currentname,oldname@@GLIBCPP_3.2") + // At the same time, these new __gnu_cxx symbols are not exported. + // In the future, GLIBCXX_ABI > 5 should remove all uses of + // _GLIBCPP_ASM_SYMVER in this file. + typedef char fake_locale[sizeof(locale)] + __attribute__ ((aligned(__alignof__(locale)))); + fake_locale c_locale; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx8c_localeE, _ZSt8c_locale, GLIBCPP_3.2) + + // GLIBCXX_ABI > 5 will not need this symbol at all. + // It's here just as a placeholder, as the size of this exported + // object changed. The new symbol is not exported. + const int o = sizeof(locale::_Impl) - sizeof(char*[_GLIBCPP_NUM_CATEGORIES]); + typedef char fake_locale_Impl_compat[o] + __attribute__ ((aligned(__alignof__(o)))); + fake_locale_Impl_compat c_locale_impl_compat; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx20c_locale_impl_compatE, _ZSt13c_locale_impl, GLIBCPP_3.2) + typedef char fake_facet_vec[sizeof(locale::facet*)] __attribute__ ((aligned(__alignof__(locale::facet*)))); fake_facet_vec facet_vec[_GLIBCPP_NUM_FACETS]; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9facet_vecE, _ZSt9facet_vec, GLIBCPP_3.2) typedef char fake_ctype_c[sizeof(std::ctype)] __attribute__ ((aligned(__alignof__(std::ctype)))); fake_ctype_c ctype_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx7ctype_cE, _ZSt7ctype_c, GLIBCPP_3.2) typedef char fake_collate_c[sizeof(std::collate)] __attribute__ ((aligned(__alignof__(std::collate)))); fake_collate_c collate_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9collate_cE, _ZSt9collate_c, GLIBCPP_3.2) typedef char fake_numpunct_c[sizeof(numpunct)] __attribute__ ((aligned(__alignof__(numpunct)))); fake_numpunct_c numpunct_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10numpunct_cE, _ZSt10numpunct_c, GLIBCPP_3.2) typedef char fake_num_get_c[sizeof(num_get)] __attribute__ ((aligned(__alignof__(num_get)))); fake_num_get_c num_get_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9num_get_cE, _ZSt9num_get_c, GLIBCPP_3.2) typedef char fake_num_put_c[sizeof(num_put)] __attribute__ ((aligned(__alignof__(num_put)))); fake_num_put_c num_put_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9num_put_cE, _ZSt9num_put_c, GLIBCPP_3.2) typedef char fake_codecvt_c[sizeof(codecvt)] __attribute__ ((aligned(__alignof__(codecvt)))); fake_codecvt_c codecvt_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9codecvt_cE, _ZSt9codecvt_c, GLIBCPP_3.2) typedef char fake_moneypunct_c[sizeof(moneypunct)] __attribute__ ((aligned(__alignof__(moneypunct)))); fake_moneypunct_c moneypunct_tc; fake_moneypunct_c moneypunct_fc; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx13moneypunct_tcE,\ + _ZSt13moneypunct_tc, GLIBCPP_3.2) + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx13moneypunct_fcE,\ + _ZSt13moneypunct_fc, GLIBCPP_3.2) typedef char fake_money_get_c[sizeof(money_get)] __attribute__ ((aligned(__alignof__(money_get)))); fake_money_get_c money_get_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx11money_get_cE, _ZSt11money_get_c, GLIBCPP_3.2) typedef char fake_money_put_c[sizeof(money_put)] __attribute__ ((aligned(__alignof__(money_put)))); fake_money_put_c money_put_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx11money_put_cE, _ZSt11money_put_c, GLIBCPP_3.2) typedef char fake_timepunct_c[sizeof(__timepunct)] __attribute__ ((aligned(__alignof__(__timepunct)))); fake_timepunct_c timepunct_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx11timepunct_cE, _ZSt11timepunct_c, GLIBCPP_3.2) typedef char fake_time_get_c[sizeof(time_get)] __attribute__ ((aligned(__alignof__(time_get)))); fake_time_get_c time_get_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10time_get_cE, _ZSt10time_get_c, GLIBCPP_3.2) typedef char fake_time_put_c[sizeof(time_put)] __attribute__ ((aligned(__alignof__(time_put)))); fake_time_put_c time_put_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10time_put_cE, _ZSt10time_put_c, GLIBCPP_3.2) typedef char fake_messages_c[sizeof(messages)] __attribute__ ((aligned(__alignof__(messages)))); fake_messages_c messages_c; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10messages_cE, _ZSt10messages_c, GLIBCPP_3.2) #ifdef _GLIBCPP_USE_WCHAR_T typedef char fake_wtype_w[sizeof(std::ctype)] __attribute__ ((aligned(__alignof__(std::ctype)))); fake_wtype_w ctype_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx7ctype_wE, _ZSt7ctype_w, GLIBCPP_3.2) typedef char fake_wollate_w[sizeof(std::collate)] __attribute__ ((aligned(__alignof__(std::collate)))); fake_wollate_w collate_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9collate_wE, _ZSt9collate_w, GLIBCPP_3.2) typedef char fake_numpunct_w[sizeof(numpunct)] __attribute__ ((aligned(__alignof__(numpunct)))); fake_numpunct_w numpunct_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10numpunct_wE, _ZSt10numpunct_w, GLIBCPP_3.2) typedef char fake_num_get_w[sizeof(num_get)] __attribute__ ((aligned(__alignof__(num_get)))); fake_num_get_w num_get_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9num_get_wE, _ZSt9num_get_w, GLIBCPP_3.2) typedef char fake_num_put_w[sizeof(num_put)] __attribute__ ((aligned(__alignof__(num_put)))); fake_num_put_w num_put_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9num_put_wE, _ZSt9num_put_w, GLIBCPP_3.2) typedef char fake_wodecvt_w[sizeof(codecvt)] __attribute__ ((aligned(__alignof__(codecvt)))); fake_wodecvt_w codecvt_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9codecvt_wE, _ZSt9codecvt_w, GLIBCPP_3.2) typedef char fake_moneypunct_w[sizeof(moneypunct)] __attribute__ ((aligned(__alignof__(moneypunct)))); fake_moneypunct_w moneypunct_tw; fake_moneypunct_w moneypunct_fw; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx13moneypunct_twE,\ + _ZSt13moneypunct_tw, GLIBCPP_3.2) + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx13moneypunct_fwE,\ + _ZSt13moneypunct_fw, GLIBCPP_3.2) typedef char fake_money_get_w[sizeof(money_get)] __attribute__ ((aligned(__alignof__(money_get)))); fake_money_get_w money_get_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx11money_get_wE, _ZSt11money_get_w, GLIBCPP_3.2) typedef char fake_money_put_w[sizeof(money_put)] __attribute__ ((aligned(__alignof__(money_put)))); fake_money_put_w money_put_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx11money_put_wE, _ZSt11money_put_w, GLIBCPP_3.2) typedef char fake_timepunct_w[sizeof(__timepunct)] __attribute__ ((aligned(__alignof__(__timepunct)))); fake_timepunct_w timepunct_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx11timepunct_wE, _ZSt11timepunct_w, GLIBCPP_3.2) typedef char fake_time_get_w[sizeof(time_get)] __attribute__ ((aligned(__alignof__(time_get)))); fake_time_get_w time_get_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10time_get_wE, _ZSt10time_get_w, GLIBCPP_3.2) typedef char fake_time_put_w[sizeof(time_put)] __attribute__ ((aligned(__alignof__(time_put)))); fake_time_put_w time_put_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10time_put_wE, _ZSt10time_put_w, GLIBCPP_3.2) typedef char fake_messages_w[sizeof(messages)] __attribute__ ((aligned(__alignof__(messages)))); fake_messages_w messages_w; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx10messages_wE, _ZSt10messages_w, GLIBCPP_3.2) #endif - // Standard stream objects. - typedef char fake_istream[sizeof(istream)] - __attribute__ ((aligned(__alignof__(istream)))); - typedef char fake_ostream[sizeof(ostream)] - __attribute__ ((aligned(__alignof__(ostream)))); - fake_istream cin; - fake_ostream cout; - fake_ostream cerr; - fake_ostream clog; - - typedef char fake_filebuf[sizeof(__gnu_cxx::stdio_filebuf)] - __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf)))); + typedef char fake_filebuf[sizeof(stdio_filebuf)] + __attribute__ ((aligned(__alignof__(stdio_filebuf)))); fake_filebuf buf_cout; fake_filebuf buf_cin; fake_filebuf buf_cerr; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx8buf_coutE, _ZSt8buf_cout, GLIBCPP_3.2) + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx7buf_cinE, _ZSt7buf_cin, GLIBCPP_3.2) + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx8buf_cerrE, _ZSt8buf_cerr, GLIBCPP_3.2) #ifdef _GLIBCPP_USE_WCHAR_T - typedef char fake_wistream[sizeof(wistream)] - __attribute__ ((aligned(__alignof__(wistream)))); - typedef char fake_wostream[sizeof(wostream)] - __attribute__ ((aligned(__alignof__(wostream)))); - fake_wistream wcin; - fake_wostream wcout; - fake_wostream wcerr; - fake_wostream wclog; - - typedef char fake_wfilebuf[sizeof(__gnu_cxx::stdio_filebuf)] - __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf)))); + typedef char fake_wfilebuf[sizeof(stdio_filebuf)] + __attribute__ ((aligned(__alignof__(stdio_filebuf)))); fake_wfilebuf buf_wcout; fake_wfilebuf buf_wcin; fake_wfilebuf buf_wcerr; + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9buf_wcoutE, _ZSt9buf_wcout, GLIBCPP_3.2) + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx8buf_wcinE, _ZSt8buf_wcin, GLIBCPP_3.2) + _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9buf_wcerrE, _ZSt9buf_wcerr, GLIBCPP_3.2) #endif +} // namespace __gnu_cxx - +namespace std +{ // Globals for once-only runtime initialization of mutex objects. This // allows static initialization of these objects on systems that need a // function call to initialize a mutex. For example, see stl_threads.h. @@ -223,4 +269,25 @@ namespace std _GLIBCPP_mutex_address_init () { __GTHREAD_MUTEX_INIT_FUNCTION (_GLIBCPP_mutex_address); } #endif -} + + // Standard stream objects. + typedef char fake_istream[sizeof(istream)] + __attribute__ ((aligned(__alignof__(istream)))); + typedef char fake_ostream[sizeof(ostream)] + __attribute__ ((aligned(__alignof__(ostream)))); + fake_istream cin; + fake_ostream cout; + fake_ostream cerr; + fake_ostream clog; + +#ifdef _GLIBCPP_USE_WCHAR_T + typedef char fake_wistream[sizeof(wistream)] + __attribute__ ((aligned(__alignof__(wistream)))); + typedef char fake_wostream[sizeof(wostream)] + __attribute__ ((aligned(__alignof__(wostream)))); + fake_wistream wcin; + fake_wostream wcout; + fake_wostream wcerr; + fake_wostream wclog; +#endif +} // namespace std diff --git a/contrib/libstdc++/src/ios.cc b/contrib/libstdc++/src/ios.cc index c1167f8..7bfdc5b 100644 --- a/contrib/libstdc++/src/ios.cc +++ b/contrib/libstdc++/src/ios.cc @@ -39,28 +39,34 @@ #include #include -namespace std +namespace __gnu_cxx { // Extern declarations for global objects in src/globals.cc. + extern stdio_filebuf buf_cout; + extern stdio_filebuf buf_cin; + extern stdio_filebuf buf_cerr; + +#ifdef _GLIBCPP_USE_WCHAR_T + extern stdio_filebuf buf_wcout; + extern stdio_filebuf buf_wcin; + extern stdio_filebuf buf_wcerr; +#endif +} // namespace __gnu_cxx + +namespace std +{ + using namespace __gnu_cxx; + extern istream cin; extern ostream cout; extern ostream cerr; extern ostream clog; - using __gnu_cxx::stdio_filebuf; - extern stdio_filebuf buf_cout; - extern stdio_filebuf buf_cin; - extern stdio_filebuf buf_cerr; - #ifdef _GLIBCPP_USE_WCHAR_T extern wistream wcin; extern wostream wcout; extern wostream wcerr; extern wostream wclog; - - extern stdio_filebuf buf_wcout; - extern stdio_filebuf buf_wcin; - extern stdio_filebuf buf_wcerr; #endif // Definitions for static const data members of __ios_flags. diff --git a/contrib/libstdc++/src/locale-inst.cc b/contrib/libstdc++/src/locale-inst.cc index 5e6c675..8f2c863 100644 --- a/contrib/libstdc++/src/locale-inst.cc +++ b/contrib/libstdc++/src/locale-inst.cc @@ -35,11 +35,7 @@ #include #include #include -#include -#include #include -#include -#include namespace std { diff --git a/contrib/libstdc++/src/locale.cc b/contrib/libstdc++/src/locale.cc index 6314ba6..127197d 100644 --- a/contrib/libstdc++/src/locale.cc +++ b/contrib/libstdc++/src/locale.cc @@ -31,19 +31,19 @@ #include #include #include // For towupper, etc. -#include -#include #include -#include -#include #include -namespace std +namespace __gnu_cxx { // Defined in globals.cc. - extern locale c_locale; - extern locale::_Impl c_locale_impl; - extern locale::facet** facet_vec; + extern std::locale c_locale; + extern std::locale::_Impl c_locale_impl; +} // namespace __gnu_cxx + +namespace std +{ + using namespace __gnu_cxx; // Definitions for static const data members of locale. const locale::category locale::none; @@ -55,9 +55,14 @@ namespace std const locale::category locale::messages; const locale::category locale::all; + // In the future, GLIBCXX_ABI > 5 should remove all uses of + // _GLIBCPP_ASM_SYMVER in this file, and remove exports of any + // static data members of locale. locale::_Impl* locale::_S_classic; locale::_Impl* locale::_S_global; - const size_t locale::_S_num_categories; + const size_t locale::_S_categories_size; + _GLIBCPP_ASM_SYMVER(_ZNSt6locale18_S_categories_sizeE, _ZNSt6locale17_S_num_categoriesE, GLIBCPP_3.2) + const size_t locale::_S_extra_categories_size; // Definitions for static const data members of locale::id _Atomic_word locale::id::_S_highwater; // init'd to 0 by linker @@ -146,31 +151,12 @@ namespace std locale::_Impl::_S_id_ctype, locale::_Impl::_S_id_numeric, locale::_Impl::_S_id_collate, - locale::_Impl::_S_id_monetary, locale::_Impl::_S_id_time, + locale::_Impl::_S_id_monetary, locale::_Impl::_S_id_messages, 0 }; - locale::~locale() throw() - { _M_impl->_M_remove_reference(); } - - void - locale::_M_coalesce(const locale& __base, const locale& __add, - category __cat) - { - __cat = _S_normalize_category(__cat); - _M_impl = new _Impl(*__base._M_impl, 1); - - try - { _M_impl->_M_replace_categories(__add._M_impl, __cat); } - catch (...) - { - _M_impl->_M_remove_reference(); - __throw_exception_again; - } - } - locale::locale() throw() { _S_initialize(); @@ -182,6 +168,7 @@ namespace std // This is used to initialize global and classic locales, and // assumes that the _Impl objects are constructed correctly. + // The lack of a reference increment is intentional. locale::locale(_Impl* __ip) throw() : _M_impl(__ip) { } @@ -192,18 +179,110 @@ namespace std _S_initialize(); if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0) (_M_impl = _S_classic)->_M_add_reference(); - else if (strcmp(__s, "") == 0) + else if (strcmp(__s, "") != 0) + _M_impl = new _Impl(__s, 1); + else { + // Get it from the environment. char* __env = getenv("LC_ALL"); - if (__env) - _M_impl = new _Impl(__env, 1); - else if ((__env = getenv("LANG"))) - _M_impl = new _Impl(__env, 1); + // If LC_ALL is set we are done. + if (__env && strcmp(__env, "") != 0) + { + if (strcmp(__env, "C") == 0 || strcmp(__env, "POSIX") == 0) + (_M_impl = _S_classic)->_M_add_reference(); + else + _M_impl = new _Impl(__env, 1); + } else - (_M_impl = _S_classic)->_M_add_reference(); + { + char* __res; + // LANG may set a default different from "C". + char* __env = getenv("LANG"); + if (!__env || strcmp(__env, "") == 0 || strcmp(__env, "C") == 0 + || strcmp(__env, "POSIX") == 0) + __res = strdup("C"); + else + __res = strdup(__env); + + // Scan the categories looking for the first one + // different from LANG. + size_t __i = 0; + if (strcmp(__res, "C") == 0) + for (__i = 0; + __i < _S_categories_size + _S_extra_categories_size; + ++__i) + { + __env = getenv(_S_categories[__i]); + if (__env && strcmp(__env, "") != 0 + && strcmp(__env, "C") != 0 + && strcmp(__env, "POSIX") != 0) + break; + } + else + for (__i = 0; + __i < _S_categories_size + _S_extra_categories_size; + ++__i) + { + __env = getenv(_S_categories[__i]); + if (__env && strcmp(__env, "") != 0 + && strcmp(__env, __res) != 0) + break; + } + + // If one is found, build the complete string of + // the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on... + if (__i < _S_categories_size + _S_extra_categories_size) + { + string __str; + for (size_t __j = 0; __j < __i; ++__j) + { + __str += _S_categories[__j]; + __str += "="; + __str += __res; + __str += ";"; + } + __str += _S_categories[__i]; + __str += "="; + __str += __env; + __str += ";"; + __i++; + for (; __i < _S_categories_size + + _S_extra_categories_size; ++__i) + { + __env = getenv(_S_categories[__i]); + if (!__env || strcmp(__env, "") == 0) + { + __str += _S_categories[__i]; + __str += '='; + __str += __res; + __str += ';'; + } + else if (strcmp(__env, "C") == 0 + || strcmp(__env, "POSIX") == 0) + { + __str += _S_categories[__i]; + __str += "=C;"; + } + else + { + __str += _S_categories[__i]; + __str += "="; + __str += __env; + __str += ";"; + } + } + __str.erase(__str.end() - 1); + _M_impl = new _Impl(__str.c_str(), 1); + } + // ... otherwise either an additional instance of + // the "C" locale or LANG. + else if (strcmp(__res, "C") == 0) + (_M_impl = _S_classic)->_M_add_reference(); + else + _M_impl = new _Impl(__res, 1); + free(__res); + } } - else - _M_impl = new _Impl(__s, 1); } else __throw_runtime_error("attempt to create locale from NULL name"); @@ -221,6 +300,9 @@ namespace std locale::locale(const locale& __base, const locale& __add, category __cat) { _M_coalesce(__base, __add, __cat); } + locale::~locale() throw() + { _M_impl->_M_remove_reference(); } + bool locale::operator==(const locale& __rhs) const throw() { @@ -261,20 +343,22 @@ namespace std string locale::name() const { - // 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 += _S_categories[0]; + __ret += "="; + __ret += _M_impl->_M_names[0]; + for (size_t __i = 1; + __i < _S_categories_size + _S_extra_categories_size; + ++__i) { - __ret += __separator; - __ret += _M_impl->_M_names[i]; + __ret += ";"; + __ret += _S_categories[__i]; + __ret += "="; + __ret += _M_impl->_M_names[__i]; } } return __ret; @@ -291,12 +375,8 @@ namespace std try { // 26 Standard facets, 2 references. - // One reference for _M_classic, one for _M_global - 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); + // One reference for _S_classic, one for _S_global + _S_classic = new (&c_locale_impl) _Impl(0, 2, true); _S_global = _S_classic; new (&c_locale) locale(_S_classic); } @@ -313,6 +393,22 @@ namespace std return c_locale; } + void + locale::_M_coalesce(const locale& __base, const locale& __add, + category __cat) + { + __cat = _S_normalize_category(__cat); + _M_impl = new _Impl(*__base._M_impl, 1); + + try + { _M_impl->_M_replace_categories(__add._M_impl, __cat); } + catch (...) + { + _M_impl->_M_remove_reference(); + __throw_exception_again; + } + } + locale::category locale::_S_normalize_category(category __cat) { @@ -361,11 +457,8 @@ namespace std ~facet() { } locale::facet:: - facet(size_t __refs) throw() : _M_references(__refs) - { - if (!_S_c_locale) - _S_create_c_locale(_S_c_locale, "C"); - } + facet(size_t __refs) throw() : _M_references(__refs ? 1 : 0) + { } void locale::facet:: @@ -376,7 +469,7 @@ namespace std locale::facet:: _M_remove_reference() throw() { - if (__exchange_and_add(&_M_references, -1) == 0) + if (__exchange_and_add(&_M_references, -1) == 1) { try { delete this; } diff --git a/contrib/libstdc++/src/localename.cc b/contrib/libstdc++/src/localename.cc index 8fa9118..61aa952 100644 --- a/contrib/libstdc++/src/localename.cc +++ b/contrib/libstdc++/src/localename.cc @@ -30,9 +30,14 @@ #include #include -namespace std +namespace __gnu_cxx { + using namespace std; + // Defined in globals.cc. + extern locale::facet** facet_vec; + extern char* facet_name[6 + _GLIBCPP_NUM_CATEGORIES]; + extern std::ctype ctype_c; extern std::collate collate_c; extern numpunct numpunct_c; @@ -63,6 +68,11 @@ namespace std extern time_put time_put_w; extern std::messages messages_w; #endif +} // namespace __gnu_cxx + +namespace std +{ + using namespace __gnu_cxx; locale::_Impl:: ~_Impl() throw() @@ -71,6 +81,10 @@ namespace std if (_M_facets[__i]) _M_facets[__i]->_M_remove_reference(); delete [] _M_facets; + + for (size_t __i = 0; + __i < _S_categories_size + _S_extra_categories_size; ++__i) + delete [] _M_names[__i]; } // Clone existing _Impl object. @@ -95,14 +109,19 @@ namespace std 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]; + for (size_t __i = 0; + __i < _S_categories_size + _S_extra_categories_size; ++__i) + { + char* __new = new char[strlen(__imp._M_names[__i]) + 1]; + strcpy(__new, __imp._M_names[__i]); + _M_names[__i] = __new; + } } // Construct named _Impl. locale::_Impl:: _Impl(const char* __s, size_t __refs) - : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS) // XXX + : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS) { // Initialize the underlying locale model, which also checks // to see if the given name is valid. @@ -122,11 +141,40 @@ namespace std } // Name all the categories. - for (size_t i = 0; i < _S_num_categories; ++i) - _M_names[i] = __s; + if (!strchr(__s, ';')) + { + size_t __len = strlen(__s) + 1; + for (size_t __i = 0; + __i < _S_categories_size + _S_extra_categories_size; ++__i) + { + _M_names[__i] = new char[__len]; + strcpy(_M_names[__i], __s); + } + } + else + { + char* __tmp = strdup(__s); + __tmp[strlen(__tmp)] = ';'; + strtok(__tmp, "=;"); + for (size_t __i = 0; + __i < _S_categories_size + _S_extra_categories_size - 1; ++__i) + { + char* __src = strtok(NULL, "=;"); + char* __new = new char[strlen(__src) + 1]; + strcpy(__new, __src); + _M_names[__i] = __new; + strtok(NULL, "=;"); + } + char* __src = strtok(NULL, "=;"); + char* __new = new char[strlen(__src) + 1]; + strcpy(__new, __src); + _M_names[_S_categories_size + _S_extra_categories_size - 1] = __new; - // Construct all standard facets and add them to _M_facets. - _M_init_facet(new std::ctype(__cloc)); + free(__tmp); + } + + // Construct all standard facets and add them to _M_facets. + _M_init_facet(new std::ctype(__cloc, 0, false)); _M_init_facet(new codecvt); _M_init_facet(new numpunct(__cloc)); _M_init_facet(new num_get); @@ -162,47 +210,61 @@ namespace std // Construct "C" _Impl. locale::_Impl:: - _Impl(facet** __f, size_t __refs, bool) - : _M_references(__refs), _M_facets(__f), _M_facets_size(_GLIBCPP_NUM_FACETS) + _Impl(facet**, size_t __refs, bool) + : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS) { + // Initialize the underlying locale model. + locale::facet::_S_create_c_locale(locale::facet::_S_c_locale, "C"); + + _M_facets = new(&facet_vec) facet*[_M_facets_size]; + for (size_t __i = 0; __i < _M_facets_size; ++__i) + _M_facets[__i] = 0; + // Name all the categories. - for (size_t i = 0; i < _S_num_categories; ++i) - _M_names[i] = "C"; + for (size_t __i = 0; + __i < _S_categories_size + _S_extra_categories_size; ++__i) + { + _M_names[__i] = new (&facet_name[__i]) char[2]; + strcpy(_M_names[__i], "C"); + } // This is needed as presently the C++ version of "C" locales // != data in the underlying locale model for __timepunct, // numpunct, and moneypunct. Also, the "C" locales must be // constructed in a way such that they are pre-allocated. - _M_init_facet(new (&ctype_c) std::ctype); - _M_init_facet(new (&codecvt_c) codecvt); - _M_init_facet(new (&numpunct_c) numpunct); - _M_init_facet(new (&num_get_c) num_get); - _M_init_facet(new (&num_put_c) num_put); - _M_init_facet(new (&collate_c) std::collate); - _M_init_facet(new (&moneypunct_fc) moneypunct); - _M_init_facet(new (&moneypunct_tc) moneypunct); - _M_init_facet(new (&money_get_c) money_get); - _M_init_facet(new (&money_put_c) money_put); - _M_init_facet(new (&timepunct_c) __timepunct); - _M_init_facet(new (&time_get_c) time_get); - _M_init_facet(new (&time_put_c) time_put); - _M_init_facet(new (&messages_c) std::messages); + // NB: Set locale::facets(ref) count to one so that each individual + // facet is not destroyed when the locale (and thus locale::_Impl) is + // destroyed. + _M_init_facet(new (&ctype_c) std::ctype(0, false, 1)); + _M_init_facet(new (&codecvt_c) codecvt(1)); + _M_init_facet(new (&numpunct_c) numpunct(1)); + _M_init_facet(new (&num_get_c) num_get(1)); + _M_init_facet(new (&num_put_c) num_put(1)); + _M_init_facet(new (&collate_c) std::collate(1)); + _M_init_facet(new (&moneypunct_fc) moneypunct(1)); + _M_init_facet(new (&moneypunct_tc) moneypunct(1)); + _M_init_facet(new (&money_get_c) money_get(1)); + _M_init_facet(new (&money_put_c) money_put(1)); + _M_init_facet(new (&timepunct_c) __timepunct(1)); + _M_init_facet(new (&time_get_c) time_get(1)); + _M_init_facet(new (&time_put_c) time_put(1)); + _M_init_facet(new (&messages_c) std::messages(1)); #ifdef _GLIBCPP_USE_WCHAR_T - _M_init_facet(new (&ctype_w) std::ctype); - _M_init_facet(new (&codecvt_w) codecvt); - _M_init_facet(new (&numpunct_w) numpunct); - _M_init_facet(new (&num_get_w) num_get); - _M_init_facet(new (&num_put_w) num_put); - _M_init_facet(new (&collate_w) std::collate); - _M_init_facet(new (&moneypunct_fw) moneypunct); - _M_init_facet(new (&moneypunct_tw) moneypunct); - _M_init_facet(new (&money_get_w) money_get); - _M_init_facet(new (&money_put_w) money_put); - _M_init_facet(new (&timepunct_w) __timepunct); - _M_init_facet(new (&time_get_w) time_get); - _M_init_facet(new (&time_put_w) time_put); - _M_init_facet(new (&messages_w) std::messages); -#endif + _M_init_facet(new (&ctype_w) std::ctype(1)); + _M_init_facet(new (&codecvt_w) codecvt(1)); + _M_init_facet(new (&numpunct_w) numpunct(1)); + _M_init_facet(new (&num_get_w) num_get(1)); + _M_init_facet(new (&num_put_w) num_put(1)); + _M_init_facet(new (&collate_w) std::collate(1)); + _M_init_facet(new (&moneypunct_fw) moneypunct(1)); + _M_init_facet(new (&moneypunct_tw) moneypunct(1)); + _M_init_facet(new (&money_get_w) money_get(1)); + _M_init_facet(new (&money_put_w) money_put(1)); + _M_init_facet(new (&timepunct_w) __timepunct(1)); + _M_init_facet(new (&time_get_w) time_get(1)); + _M_init_facet(new (&time_put_w) time_put(1)); + _M_init_facet(new (&messages_w) std::messages(1)); +#endif } void @@ -210,7 +272,7 @@ namespace std _M_replace_categories(const _Impl* __imp, category __cat) { category __mask; - for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix) + for (size_t __ix = 0; __ix < _S_categories_size; ++__ix) { __mask = 1 << __ix; if (__mask & __cat) @@ -220,7 +282,12 @@ namespace std // If both have names, go ahead and mangle. if (strcmp(_M_names[__ix], "*") != 0 && strcmp(__imp->_M_names[__ix], "*") != 0) - _M_names[__ix] = __imp->_M_names[__ix]; + { + delete [] _M_names[__ix]; + char* __new = new char[strlen(__imp->_M_names[__ix]) + 1]; + strcpy(__new, __imp->_M_names[__ix]); + _M_names[__ix] = __new; + } } } } @@ -250,6 +317,8 @@ namespace std if (__fp) { size_t __index = __idp->_M_id(); + + // Check size of facet vector to ensure adequate room. if (__index > _M_facets_size - 1) { facet** __old = _M_facets; @@ -266,11 +335,11 @@ namespace std delete [] __old; } + __fp->_M_add_reference(); facet*& __fpr = _M_facets[__index]; if (__fpr) { // Replacing an existing facet. Order matters. - __fp->_M_add_reference(); __fpr->_M_remove_reference(); __fpr = __fp; } diff --git a/contrib/libstdc++/src/string-inst.cc b/contrib/libstdc++/src/string-inst.cc index e812aa0..3fcaf51 100644 --- a/contrib/libstdc++/src/string-inst.cc +++ b/contrib/libstdc++/src/string-inst.cc @@ -22,7 +22,8 @@ // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. @@ -48,6 +49,7 @@ namespace std template class basic_string; template S operator+(const C*, const S&); template S operator+(C, const S&); + template S operator+(const S&, const S&); } // namespace std namespace __gnu_cxx -- cgit v1.1