diff options
Diffstat (limited to 'contrib/libstdc++/src')
| -rw-r--r-- | contrib/libstdc++/src/codecvt.cc | 2 | ||||
| -rw-r--r-- | contrib/libstdc++/src/ctype.cc | 11 | ||||
| -rw-r--r-- | contrib/libstdc++/src/globals.cc | 129 | ||||
| -rw-r--r-- | contrib/libstdc++/src/ios.cc | 26 | ||||
| -rw-r--r-- | contrib/libstdc++/src/locale-inst.cc | 4 | ||||
| -rw-r--r-- | contrib/libstdc++/src/locale.cc | 207 | ||||
| -rw-r--r-- | contrib/libstdc++/src/localename.cc | 157 | ||||
| -rw-r--r-- | contrib/libstdc++/src/string-inst.cc | 4 | 
8 files changed, 384 insertions, 156 deletions
diff --git a/contrib/libstdc++/src/codecvt.cc b/contrib/libstdc++/src/codecvt.cc index a2fb42d96919..1fe6b97bc6d0 100644 --- a/contrib/libstdc++/src/codecvt.cc +++ b/contrib/libstdc++/src/codecvt.cc @@ -50,7 +50,7 @@ namespace std    codecvt<char, char, mbstate_t>::    ~codecvt() -   { } +  { }    codecvt_base::result    codecvt<char, char, mbstate_t>:: diff --git a/contrib/libstdc++/src/ctype.cc b/contrib/libstdc++/src/ctype.cc index 7ca934eb379c..3d5ee618c53e 100644 --- a/contrib/libstdc++/src/ctype.cc +++ b/contrib/libstdc++/src/ctype.cc @@ -79,8 +79,7 @@ namespace std    ctype<char>::~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<wchar_t>::~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<wchar_t>::ctype_byname(const char* __s, size_t __refs)      : ctype<wchar_t>(__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 36d193fb406b..c6ff69c5e811 100644 --- a/contrib/libstdc++/src/globals.cc +++ b/contrib/libstdc++/src/globals.cc @@ -44,163 +44,209 @@  // Because <iostream> 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<char>)]    __attribute__ ((aligned(__alignof__(std::ctype<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(std::collate<char>))));    fake_collate_c collate_c; +  _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9collate_cE, _ZSt9collate_c, GLIBCPP_3.2)    typedef char fake_numpunct_c[sizeof(numpunct<char>)]    __attribute__ ((aligned(__alignof__(numpunct<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(num_get<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(num_put<char>))));    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<char, char, mbstate_t>)]    __attribute__ ((aligned(__alignof__(codecvt<char, char, mbstate_t>))));    fake_codecvt_c codecvt_c; +  _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9codecvt_cE, _ZSt9codecvt_c, GLIBCPP_3.2)    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; +  _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<char>)]    __attribute__ ((aligned(__alignof__(money_get<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(money_put<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(__timepunct<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(time_get<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(time_put<char>))));    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<char>)]    __attribute__ ((aligned(__alignof__(messages<char>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(std::ctype<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(std::collate<wchar_t>))));    fake_wollate_w collate_w; +  _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9collate_wE, _ZSt9collate_w, GLIBCPP_3.2)    typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)]    __attribute__ ((aligned(__alignof__(numpunct<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(num_get<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(num_put<wchar_t>))));    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<wchar_t, char, mbstate_t>)]    __attribute__ ((aligned(__alignof__(codecvt<wchar_t, char, mbstate_t>))));    fake_wodecvt_w codecvt_w; +  _GLIBCPP_ASM_SYMVER(_ZN9__gnu_cxx9codecvt_wE, _ZSt9codecvt_w, GLIBCPP_3.2)    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; +  _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<wchar_t>)]    __attribute__ ((aligned(__alignof__(money_get<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(money_put<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(__timepunct<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(time_get<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(time_put<wchar_t>))));    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<wchar_t>)]    __attribute__ ((aligned(__alignof__(messages<wchar_t>))));    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<char>)] -  __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf<char>)))); +  typedef char fake_filebuf[sizeof(stdio_filebuf<char>)] +  __attribute__ ((aligned(__alignof__(stdio_filebuf<char>))));    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<wchar_t>)] -  __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf<wchar_t>)))); +  typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)] +  __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>))));    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 c1167f8c15cf..7bfdc5b4bb40 100644 --- a/contrib/libstdc++/src/ios.cc +++ b/contrib/libstdc++/src/ios.cc @@ -39,28 +39,34 @@  #include <bits/atomicity.h>  #include <ext/stdio_filebuf.h> -namespace std  +namespace __gnu_cxx  {    // Extern declarations for global objects in src/globals.cc. +  extern stdio_filebuf<char> buf_cout; +  extern stdio_filebuf<char> buf_cin; +  extern stdio_filebuf<char> buf_cerr; + +#ifdef _GLIBCPP_USE_WCHAR_T +  extern stdio_filebuf<wchar_t> buf_wcout; +  extern stdio_filebuf<wchar_t> buf_wcin; +  extern stdio_filebuf<wchar_t> 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<char> buf_cout; -  extern stdio_filebuf<char> buf_cin; -  extern stdio_filebuf<char> buf_cerr; -  #ifdef _GLIBCPP_USE_WCHAR_T    extern wistream wcin;    extern wostream wcout;    extern wostream wcerr;    extern wostream wclog; - -  extern stdio_filebuf<wchar_t> buf_wcout; -  extern stdio_filebuf<wchar_t> buf_wcin; -  extern stdio_filebuf<wchar_t> 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 5e6c6751bc44..8f2c86381779 100644 --- a/contrib/libstdc++/src/locale-inst.cc +++ b/contrib/libstdc++/src/locale-inst.cc @@ -35,11 +35,7 @@  #include <clocale>  #include <cstring>  #include <cassert> -#include <limits> -#include <exception>  #include <locale> -#include <istream> -#include <ostream>  namespace std  { diff --git a/contrib/libstdc++/src/locale.cc b/contrib/libstdc++/src/locale.cc index 6314ba6a7a57..127197d0138f 100644 --- a/contrib/libstdc++/src/locale.cc +++ b/contrib/libstdc++/src/locale.cc @@ -31,19 +31,19 @@  #include <cassert>  #include <cctype>  #include <cwctype>     // For towupper, etc. -#include <limits> -#include <exception>  #include <locale> -#include <istream> -#include <ostream>  #include <bits/atomicity.h> -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 8fa911891705..61aa952e6ad2 100644 --- a/contrib/libstdc++/src/localename.cc +++ b/contrib/libstdc++/src/localename.cc @@ -30,9 +30,14 @@  #include <cstring>  #include <locale> -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<char>			ctype_c;    extern std::collate<char> 			collate_c;    extern numpunct<char> 			numpunct_c; @@ -63,6 +68,11 @@ namespace std    extern time_put<wchar_t> 			time_put_w;    extern std::messages<wchar_t> 		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<char>(__cloc)); +	free(__tmp); +      } +       +    // Construct all standard facets and add them to _M_facets.   +    _M_init_facet(new std::ctype<char>(__cloc, 0, false));      _M_init_facet(new codecvt<char, char, mbstate_t>);      _M_init_facet(new numpunct<char>(__cloc));      _M_init_facet(new num_get<char>); @@ -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<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>);	 +    // 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<char>(0, false, 1)); +    _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1)); +    _M_init_facet(new (&numpunct_c) numpunct<char>(1)); +    _M_init_facet(new (&num_get_c) num_get<char>(1)); +    _M_init_facet(new (&num_put_c) num_put<char>(1)); +    _M_init_facet(new (&collate_c) std::collate<char>(1)); +    _M_init_facet(new (&moneypunct_fc) moneypunct<char, false>(1)); +    _M_init_facet(new (&moneypunct_tc) moneypunct<char, true>(1)); +    _M_init_facet(new (&money_get_c) money_get<char>(1)); +    _M_init_facet(new (&money_put_c) money_put<char>(1)); +    _M_init_facet(new (&timepunct_c) __timepunct<char>(1)); +    _M_init_facet(new (&time_get_c) time_get<char>(1)); +    _M_init_facet(new (&time_put_c) time_put<char>(1)); +    _M_init_facet(new (&messages_c) std::messages<char>(1));	  #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	   +    _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1)); +    _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1)); +    _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(1)); +    _M_init_facet(new (&num_get_w) num_get<wchar_t>(1)); +    _M_init_facet(new (&num_put_w) num_put<wchar_t>(1)); +    _M_init_facet(new (&collate_w) std::collate<wchar_t>(1)); +    _M_init_facet(new (&moneypunct_fw) moneypunct<wchar_t, false>(1)); +    _M_init_facet(new (&moneypunct_tw) moneypunct<wchar_t, true>(1)); +    _M_init_facet(new (&money_get_w) money_get<wchar_t>(1)); +    _M_init_facet(new (&money_put_w) money_put<wchar_t>(1)); +    _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(1)); +    _M_init_facet(new (&time_get_w) time_get<wchar_t>(1)); +    _M_init_facet(new (&time_put_w) time_put<wchar_t>(1)); +    _M_init_facet(new (&messages_w) std::messages<wchar_t>(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 e812aa0cfc28..3fcaf5132e71 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<C>;    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  | 
