diff options
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/Makefile.am | 29 | ||||
-rw-r--r-- | libstdc++-v3/src/Makefile.in | 60 | ||||
-rw-r--r-- | libstdc++-v3/src/globals_io.cc | 128 | ||||
-rw-r--r-- | libstdc++-v3/src/globals_locale.cc (renamed from libstdc++-v3/src/globals.cc) | 80 | ||||
-rw-r--r-- | libstdc++-v3/src/ios.cc | 212 | ||||
-rw-r--r-- | libstdc++-v3/src/ios_init.cc | 191 | ||||
-rw-r--r-- | libstdc++-v3/src/ios_locale.cc | 60 | ||||
-rw-r--r-- | libstdc++-v3/src/locale-inst.cc | 439 | ||||
-rw-r--r-- | libstdc++-v3/src/locale-misc-inst.cc | 69 | ||||
-rw-r--r-- | libstdc++-v3/src/locale.cc | 534 | ||||
-rw-r--r-- | libstdc++-v3/src/locale_facets.cc | 91 | ||||
-rw-r--r-- | libstdc++-v3/src/locale_init.cc | 340 | ||||
-rw-r--r-- | libstdc++-v3/src/localename.cc | 434 | ||||
-rw-r--r-- | libstdc++-v3/src/wlocale-inst.cc | 39 | ||||
-rw-r--r-- | libstdc++-v3/src/wstring-inst.cc | 33 |
15 files changed, 1425 insertions, 1314 deletions
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index a79b6df0d2b..e3e04b52f12 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -91,33 +91,40 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC) # Sources present in the src directory. sources = \ - allocator-inst.cc \ codecvt.cc \ complex_io.cc \ - concept-inst.cc \ ctype.cc \ demangle.cc \ - ext-inst.cc \ - fstream-inst.cc \ functexcept.cc \ - globals.cc \ - io-inst.cc \ + globals_locale.cc \ + globals_io.cc \ ios.cc \ ios_failure.cc \ - istream-inst.cc \ + ios_init.cc \ + ios_locale.cc \ limits.cc \ locale.cc \ - locale-inst.cc \ + locale_init.cc \ + locale_facets.cc \ localename.cc \ + stdexcept.cc \ + stl_tree.cc \ + strstream.cc \ + allocator-inst.cc \ + concept-inst.cc \ + fstream-inst.cc \ + ext-inst.cc \ + io-inst.cc \ + istream-inst.cc \ + locale-inst.cc \ + locale-misc-inst.cc \ misc-inst.cc \ ostream-inst.cc \ sstream-inst.cc \ - stdexcept.cc \ - stl_tree.cc \ streambuf-inst.cc \ string-inst.cc \ - strstream.cc \ valarray-inst.cc \ + wlocale-inst.cc \ wstring-inst.cc \ ${host_sources} \ ${host_sources_extra} diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index 7a10f855352..40d6f8bc94a 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.7.6 from Makefile.am. +# Makefile.in generated by automake 1.7.8 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 @@ -81,8 +81,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@ -FPOS_H = @FPOS_H@ -FPOS_INC_SRCDIR = @FPOS_INC_SRCDIR@ GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@ GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@ GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@ @@ -250,33 +248,40 @@ host_sources_extra = \ # Sources present in the src directory. sources = \ - allocator-inst.cc \ codecvt.cc \ complex_io.cc \ - concept-inst.cc \ ctype.cc \ demangle.cc \ - ext-inst.cc \ - fstream-inst.cc \ functexcept.cc \ - globals.cc \ - io-inst.cc \ + globals_locale.cc \ + globals_io.cc \ ios.cc \ ios_failure.cc \ - istream-inst.cc \ + ios_init.cc \ + ios_locale.cc \ limits.cc \ locale.cc \ - locale-inst.cc \ + locale_init.cc \ + locale_facets.cc \ localename.cc \ + stdexcept.cc \ + stl_tree.cc \ + strstream.cc \ + allocator-inst.cc \ + concept-inst.cc \ + fstream-inst.cc \ + ext-inst.cc \ + io-inst.cc \ + istream-inst.cc \ + locale-inst.cc \ + locale-misc-inst.cc \ misc-inst.cc \ ostream-inst.cc \ sstream-inst.cc \ - stdexcept.cc \ - stl_tree.cc \ streambuf-inst.cc \ string-inst.cc \ - strstream.cc \ valarray-inst.cc \ + wlocale-inst.cc \ wstring-inst.cc \ ${host_sources} \ ${host_sources_extra} @@ -355,14 +360,16 @@ am__objects_1 = codecvt_members.lo collate_members.lo ctype_members.lo \ messages_members.lo monetary_members.lo numeric_members.lo \ time_members.lo am__objects_2 = basic_file.lo c++locale.lo -am__objects_3 = allocator-inst.lo codecvt.lo complex_io.lo \ - concept-inst.lo ctype.lo demangle.lo ext-inst.lo \ - fstream-inst.lo functexcept.lo globals.lo io-inst.lo ios.lo \ - ios_failure.lo istream-inst.lo limits.lo locale.lo locale-inst.lo \ - localename.lo misc-inst.lo ostream-inst.lo sstream-inst.lo \ - stdexcept.lo stl_tree.lo streambuf-inst.lo string-inst.lo \ - strstream.lo valarray-inst.lo wstring-inst.lo $(am__objects_1) \ - $(am__objects_2) +am__objects_3 = codecvt.lo complex_io.lo ctype.lo demangle.lo \ + functexcept.lo globals_locale.lo globals_io.lo ios.lo \ + ios_failure.lo ios_init.lo ios_locale.lo limits.lo locale.lo \ + locale_init.lo locale_facets.lo localename.lo stdexcept.lo \ + stl_tree.lo strstream.lo allocator-inst.lo concept-inst.lo \ + fstream-inst.lo ext-inst.lo io-inst.lo istream-inst.lo \ + locale-inst.lo locale-misc-inst.lo misc-inst.lo ostream-inst.lo \ + sstream-inst.lo streambuf-inst.lo string-inst.lo \ + valarray-inst.lo wlocale-inst.lo wstring-inst.lo \ + $(am__objects_1) $(am__objects_2) am_libstdc___la_OBJECTS = $(am__objects_3) libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS) @@ -373,7 +380,8 @@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) DIST_SOURCES = $(libstdc___la_SOURCES) -DIST_COMMON = $(top_srcdir)/fragment.am Makefile.am Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/fragment.am \ + Makefile.am SOURCES = $(libstdc___la_SOURCES) all: all-am @@ -552,7 +560,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -563,7 +571,7 @@ clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ mostlyclean-am distclean: distclean-am - + -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags @@ -586,7 +594,7 @@ install-man: installcheck-am: maintainer-clean: maintainer-clean-am - + -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am diff --git a/libstdc++-v3/src/globals_io.cc b/libstdc++-v3/src/globals_io.cc new file mode 100644 index 00000000000..7be53f2f30d --- /dev/null +++ b/libstdc++-v3/src/globals_io.cc @@ -0,0 +1,128 @@ +// Copyright (C) 2001, 2002, 2003 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +#include "bits/c++config.h" +#include "bits/gthr.h" +#include <fstream> +#include <istream> +#include <ostream> +#include <ext/stdio_filebuf.h> +#include <ext/stdio_sync_filebuf.h> + +// On AIX, and perhaps other systems, library initialization order is +// not guaranteed. For example, the static initializers for the main +// program might run before the static initializers for this library. +// That means that we cannot rely on static initialization in the +// library; there is no guarantee that things will get initialized in +// time. This file contains definitions of all global variables that +// require initialization as arrays of characters. + +// NB: asm directives can rename these non-exported, namespace +// __gnu_cxx symbols into exported, namespace std symbols with the +// appropriate symbol version name. +// The rename syntax is +// asm (".symver currentname,oldname@@GLIBCXX_3.2") +// In macro form: +// _GLIBCXX_ASM_SYMVER(currentname, oldname, GLIBCXX_3.2) + +namespace std +{ + // Standard stream objects. + // NB: Iff <iostream> is included, these definitions become wonky. + 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 _GLIBCXX_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 + +namespace __gnu_cxx +{ + using namespace std; + + // We use different stream buffer types depending on whether + // ios_base::sync_with_stdio(false) has been called. + typedef char fake_stdiobuf[sizeof(stdio_sync_filebuf<char>)] + __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<char>)))); + fake_stdiobuf buf_cout_sync; + fake_stdiobuf buf_cin_sync; + fake_stdiobuf buf_cerr_sync; + + 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; + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef char fake_wstdiobuf[sizeof(stdio_sync_filebuf<wchar_t>)] + __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<wchar_t>)))); + fake_wstdiobuf buf_wcout_sync; + fake_wstdiobuf buf_wcin_sync; + fake_wstdiobuf buf_wcerr_sync; + + 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; +#endif + + // 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. +#ifdef __GTHREAD_MUTEX_INIT +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) + __gthread_once_t _GLIBCXX_once = __GTHREAD_ONCE_INIT; + __gthread_mutex_t _GLIBCXX_mutex; + __gthread_mutex_t *_GLIBCXX_mutex_address; + + // Once-only initializer function for _GLIBCXX_mutex. + void + _GLIBCXX_mutex_init () + { __GTHREAD_MUTEX_INIT_FUNCTION (&_GLIBCXX_mutex); } + + // Once-only initializer function for _GLIBCXX_mutex_address. + void + _GLIBCXX_mutex_address_init () + { __GTHREAD_MUTEX_INIT_FUNCTION (_GLIBCXX_mutex_address); } +#endif +} // namespace __gnu_cxx diff --git a/libstdc++-v3/src/globals.cc b/libstdc++-v3/src/globals_locale.cc index e9e5814f6b5..c79a379ff1a 100644 --- a/libstdc++-v3/src/globals.cc +++ b/libstdc++-v3/src/globals_locale.cc @@ -25,14 +25,7 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "bits/c++config.h" -#include "bits/gthr.h" -#include <fstream> -#include <istream> -#include <ostream> #include <locale> -#include <ext/stdio_filebuf.h> -#include <ext/stdio_sync_filebuf.h> // On AIX, and perhaps other systems, library initialization order is // not guaranteed. For example, the static initializers for the main @@ -50,63 +43,10 @@ // In macro form: // _GLIBCXX_ASM_SYMVER(currentname, oldname, GLIBCXX_3.2) -namespace std -{ - // Standard stream objects. - // NB: Iff <iostream> is included, these definitions become wonky. - 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 _GLIBCXX_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 - namespace __gnu_cxx { using namespace std; - // We use different stream buffer types depending on whether - // ios_base::sync_with_stdio(false) has been called. - typedef char fake_stdiobuf[sizeof(stdio_sync_filebuf<char>)] - __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<char>)))); - fake_stdiobuf buf_cout_sync; - fake_stdiobuf buf_cin_sync; - fake_stdiobuf buf_cerr_sync; - - 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; - -#ifdef _GLIBCXX_USE_WCHAR_T - typedef char fake_wstdiobuf[sizeof(stdio_sync_filebuf<wchar_t>)] - __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<wchar_t>)))); - fake_wstdiobuf buf_wcout_sync; - fake_wstdiobuf buf_wcin_sync; - fake_wstdiobuf buf_wcerr_sync; - - 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; -#endif - typedef char fake_locale_Impl[sizeof(locale::_Impl)] __attribute__ ((aligned(__alignof__(locale::_Impl)))); fake_locale_Impl c_locale_impl; @@ -267,24 +207,4 @@ namespace __gnu_cxx __attribute__ ((aligned(__alignof__(std::__timepunct_cache<wchar_t>)))); fake_time_cache_w timepunct_cache_w; #endif - - // 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. -#ifdef __GTHREAD_MUTEX_INIT -#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) - __gthread_once_t _GLIBCXX_once = __GTHREAD_ONCE_INIT; - __gthread_mutex_t _GLIBCXX_mutex; - __gthread_mutex_t *_GLIBCXX_mutex_address; - - // Once-only initializer function for _GLIBCXX_mutex. - void - _GLIBCXX_mutex_init () - { __GTHREAD_MUTEX_INIT_FUNCTION (&_GLIBCXX_mutex); } - - // Once-only initializer function for _GLIBCXX_mutex_address. - void - _GLIBCXX_mutex_address_init () - { __GTHREAD_MUTEX_INIT_FUNCTION (_GLIBCXX_mutex_address); } -#endif } // namespace __gnu_cxx diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 616f4f5b196..fdc1f06c1cb 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -33,51 +33,11 @@ // #include <ios> -#include <ostream> -#include <istream> -#include <fstream> +#include <limits> #include <bits/atomicity.h> -#include <ext/stdio_filebuf.h> -#include <ext/stdio_sync_filebuf.h> - -namespace __gnu_cxx -{ - // Extern declarations for global objects in src/globals.cc. - extern stdio_sync_filebuf<char> buf_cout_sync; - extern stdio_sync_filebuf<char> buf_cin_sync; - extern stdio_sync_filebuf<char> buf_cerr_sync; - - extern stdio_filebuf<char> buf_cout; - extern stdio_filebuf<char> buf_cin; - extern stdio_filebuf<char> buf_cerr; - -#ifdef _GLIBCXX_USE_WCHAR_T - extern stdio_sync_filebuf<wchar_t> buf_wcout_sync; - extern stdio_sync_filebuf<wchar_t> buf_wcin_sync; - extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync; - - 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; - -#ifdef _GLIBCXX_USE_WCHAR_T - extern wistream wcin; - extern wostream wcout; - extern wostream wcerr; - extern wostream wclog; -#endif - // Definitions for static const data members of __ios_flags. const __ios_flags::__int_type __ios_flags::_S_boolalpha; const __ios_flags::__int_type __ios_flags::_S_dec; @@ -146,69 +106,30 @@ namespace std const ios_base::seekdir ios_base::end; const int ios_base::_S_local_word_size; + int ios_base::Init::_S_ios_base_init = 0; + bool ios_base::Init::_S_synced_with_stdio = true; - ios_base::Init::Init() + ios_base::ios_base() + : _M_callbacks(0), _M_word_size(_S_local_word_size), _M_word(_M_local_word) { - if (_S_ios_base_init == 0) - { - // Standard streams default to synced with "C" operations. - _S_synced_with_stdio = true; - - new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout); - new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin); - new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr); - - // The standard streams are constructed once only and never - // destroyed. - new (&cout) ostream(&buf_cout_sync); - new (&cin) istream(&buf_cin_sync); - new (&cerr) ostream(&buf_cerr_sync); - new (&clog) ostream(&buf_cerr_sync); - cin.tie(&cout); - cerr.flags(ios_base::unitbuf); - -#ifdef _GLIBCXX_USE_WCHAR_T - new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout); - new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin); - new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr); - - new (&wcout) wostream(&buf_wcout_sync); - new (&wcin) wistream(&buf_wcin_sync); - new (&wcerr) wostream(&buf_wcerr_sync); - new (&wclog) wostream(&buf_wcerr_sync); - wcin.tie(&wcout); - wcerr.flags(ios_base::unitbuf); -#endif - - _S_ios_base_init = 1; - } - ++_S_ios_base_init; + // Do nothing: basic_ios::init() does it. + // NB: _M_callbacks and _M_word must be zero for non-initialized + // ios_base to go through ~ios_base gracefully. } - - ios_base::Init::~Init() + + // 27.4.2.7 ios_base constructors/destructors + ios_base::~ios_base() { - if (--_S_ios_base_init == 1) + _M_call_callbacks(erase_event); + _M_dispose_callbacks(); + if (_M_word != _M_local_word) { - // Catch any exceptions thrown by basic_ostream::flush() - try - { - // Flush standard output streams as required by 27.4.2.1.6 - cout.flush(); - cerr.flush(); - clog.flush(); - -#ifdef _GLIBCXX_USE_WCHAR_T - wcout.flush(); - wcerr.flush(); - wclog.flush(); -#endif - } - catch (...) - { } + delete [] _M_word; + _M_word = 0; } - } + } // 27.4.2.5 ios_base storage functions int @@ -220,6 +141,10 @@ namespace std return __exchange_and_add(&_S_top, 1) + 4; } + void + ios_base::register_callback(event_callback __fn, int __index) + { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); } + // 27.4.2.5 iword/pword storage ios_base::_Words& ios_base::_M_grow_words(int ix) @@ -262,51 +187,6 @@ namespace std _M_word_size = newsize; return _M_word[ix]; } - - // Called only by basic_ios<>::init. - void - ios_base::_M_init() - { - // NB: May be called more than once - _M_precision = 6; - _M_width = 0; - _M_flags = skipws | dec; - _M_ios_locale = locale(); - } - - // 27.4.2.3 ios_base locale functions - locale - ios_base::imbue(const locale& __loc) - { - locale __old = _M_ios_locale; - _M_ios_locale = __loc; - _M_call_callbacks(imbue_event); - return __old; - } - - ios_base::ios_base() - : _M_callbacks(0), _M_word_size(_S_local_word_size), _M_word(_M_local_word) - { - // Do nothing: basic_ios::init() does it. - // NB: _M_callbacks and _M_word must be zero for non-initialized - // ios_base to go through ~ios_base gracefully. - } - - // 27.4.2.7 ios_base constructors/destructors - ios_base::~ios_base() - { - _M_call_callbacks(erase_event); - _M_dispose_callbacks(); - if (_M_word != _M_local_word) - { - delete [] _M_word; - _M_word = 0; - } - } - - void - ios_base::register_callback(event_callback __fn, int __index) - { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); } void ios_base::_M_call_callbacks(event __e) throw() @@ -334,54 +214,4 @@ namespace std } _M_callbacks = 0; } - - bool - ios_base::sync_with_stdio(bool __sync) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 49. Underspecification of ios_base::sync_with_stdio - bool __ret = ios_base::Init::_S_synced_with_stdio; - - // Turn off sync with C FILE* for cin, cout, cerr, clog iff - // currently synchronized. - if (!__sync && __ret) - { - ios_base::Init::_S_synced_with_stdio = __sync; - - // Explicitly call dtors to free any memory that is - // dynamically allocated by filebuf ctor or member functions, - // but don't deallocate all memory by calling operator delete. - buf_cout_sync.~stdio_sync_filebuf<char>(); - buf_cin_sync.~stdio_sync_filebuf<char>(); - buf_cerr_sync.~stdio_sync_filebuf<char>(); - -#ifdef _GLIBCXX_USE_WCHAR_T - buf_wcout_sync.~stdio_sync_filebuf<wchar_t>(); - buf_wcin_sync.~stdio_sync_filebuf<wchar_t>(); - buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>(); -#endif - - // Create stream buffers for the standard streams and use - // those buffers without destroying and recreating the - // streams. - new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out); - new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in); - new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out); - cout.rdbuf(&buf_cout); - cin.rdbuf(&buf_cin); - cerr.rdbuf(&buf_cerr); - clog.rdbuf(&buf_cerr); - -#ifdef _GLIBCXX_USE_WCHAR_T - new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out); - new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in); - new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out); - wcout.rdbuf(&buf_wcout); - wcin.rdbuf(&buf_wcin); - wcerr.rdbuf(&buf_wcerr); - wclog.rdbuf(&buf_wcerr); -#endif - } - return __ret; - } } // namespace std diff --git a/libstdc++-v3/src/ios_init.cc b/libstdc++-v3/src/ios_init.cc new file mode 100644 index 00000000000..1645ea7b381 --- /dev/null +++ b/libstdc++-v3/src/ios_init.cc @@ -0,0 +1,191 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +#include <ios> +#include <ostream> +#include <istream> +#include <fstream> +#include <bits/atomicity.h> +#include <ext/stdio_filebuf.h> +#include <ext/stdio_sync_filebuf.h> + +namespace __gnu_cxx +{ + // Extern declarations for global objects in src/globals.cc. + extern stdio_sync_filebuf<char> buf_cout_sync; + extern stdio_sync_filebuf<char> buf_cin_sync; + extern stdio_sync_filebuf<char> buf_cerr_sync; + + extern stdio_filebuf<char> buf_cout; + extern stdio_filebuf<char> buf_cin; + extern stdio_filebuf<char> buf_cerr; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern stdio_sync_filebuf<wchar_t> buf_wcout_sync; + extern stdio_sync_filebuf<wchar_t> buf_wcin_sync; + extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync; + + 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; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern wistream wcin; + extern wostream wcout; + extern wostream wcerr; + extern wostream wclog; +#endif + + ios_base::Init::Init() + { + if (_S_ios_base_init == 0) + { + // Standard streams default to synced with "C" operations. + _S_synced_with_stdio = true; + + new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout); + new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin); + new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr); + + // The standard streams are constructed once only and never + // destroyed. + new (&cout) ostream(&buf_cout_sync); + new (&cin) istream(&buf_cin_sync); + new (&cerr) ostream(&buf_cerr_sync); + new (&clog) ostream(&buf_cerr_sync); + cin.tie(&cout); + cerr.flags(ios_base::unitbuf); + +#ifdef _GLIBCXX_USE_WCHAR_T + new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout); + new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin); + new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr); + + new (&wcout) wostream(&buf_wcout_sync); + new (&wcin) wistream(&buf_wcin_sync); + new (&wcerr) wostream(&buf_wcerr_sync); + new (&wclog) wostream(&buf_wcerr_sync); + wcin.tie(&wcout); + wcerr.flags(ios_base::unitbuf); +#endif + + _S_ios_base_init = 1; + } + ++_S_ios_base_init; + } + + ios_base::Init::~Init() + { + if (--_S_ios_base_init == 1) + { + // Catch any exceptions thrown by basic_ostream::flush() + try + { + // Flush standard output streams as required by 27.4.2.1.6 + cout.flush(); + cerr.flush(); + clog.flush(); + +#ifdef _GLIBCXX_USE_WCHAR_T + wcout.flush(); + wcerr.flush(); + wclog.flush(); +#endif + } + catch (...) + { } + } + } + + bool + ios_base::sync_with_stdio(bool __sync) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 49. Underspecification of ios_base::sync_with_stdio + bool __ret = ios_base::Init::_S_synced_with_stdio; + + // Turn off sync with C FILE* for cin, cout, cerr, clog iff + // currently synchronized. + if (!__sync && __ret) + { + ios_base::Init::_S_synced_with_stdio = __sync; + + // Explicitly call dtors to free any memory that is + // dynamically allocated by filebuf ctor or member functions, + // but don't deallocate all memory by calling operator delete. + buf_cout_sync.~stdio_sync_filebuf<char>(); + buf_cin_sync.~stdio_sync_filebuf<char>(); + buf_cerr_sync.~stdio_sync_filebuf<char>(); + +#ifdef _GLIBCXX_USE_WCHAR_T + buf_wcout_sync.~stdio_sync_filebuf<wchar_t>(); + buf_wcin_sync.~stdio_sync_filebuf<wchar_t>(); + buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>(); +#endif + + // Create stream buffers for the standard streams and use + // those buffers without destroying and recreating the + // streams. + new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out); + new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in); + new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out); + cout.rdbuf(&buf_cout); + cin.rdbuf(&buf_cin); + cerr.rdbuf(&buf_cerr); + clog.rdbuf(&buf_cerr); + +#ifdef _GLIBCXX_USE_WCHAR_T + new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out); + new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in); + new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out); + wcout.rdbuf(&buf_wcout); + wcin.rdbuf(&buf_wcin); + wcerr.rdbuf(&buf_wcerr); + wclog.rdbuf(&buf_wcerr); +#endif + } + return __ret; + } +} // namespace std diff --git a/libstdc++-v3/src/ios_locale.cc b/libstdc++-v3/src/ios_locale.cc new file mode 100644 index 00000000000..008a4850d36 --- /dev/null +++ b/libstdc++-v3/src/ios_locale.cc @@ -0,0 +1,60 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +#include <ios> +#include <locale> + +namespace std +{ + // Called only by basic_ios<>::init. + void + ios_base::_M_init() + { + // NB: May be called more than once + _M_precision = 6; + _M_width = 0; + _M_flags = skipws | dec; + _M_ios_locale = locale(); + } + + // 27.4.2.3 ios_base locale functions + locale + ios_base::imbue(const locale& __loc) + { + locale __old = _M_ios_locale; + _M_ios_locale = __loc; + _M_call_callbacks(imbue_event); + return __old; + } +} // namespace std diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index 2a12a932206..27a51f04afb 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -31,466 +31,221 @@ // ISO C++ 14882: 22.1 Locales // -#include <cstdlib> -#include <clocale> -#include <cstring> #include <locale> +// Instantiation configuration. +#ifndef C +# define C char +#endif + namespace std { // moneypunct, money_get, and money_put - template class moneypunct<char, false>; - template class moneypunct<char, true>; - template struct __moneypunct_cache<char>; - template class moneypunct_byname<char, false>; - template class moneypunct_byname<char, true>; - template class money_get<char, istreambuf_iterator<char> >; - template class money_put<char, ostreambuf_iterator<char> >; - -#ifdef _GLIBCXX_USE_WCHAR_T - template class moneypunct<wchar_t, false>; - template class moneypunct<wchar_t, true>; - template struct __moneypunct_cache<wchar_t>; - template class moneypunct_byname<wchar_t, false>; - template class moneypunct_byname<wchar_t, true>; - template class money_get<wchar_t, istreambuf_iterator<wchar_t> >; - template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >; -#endif + template class moneypunct<C, false>; + template class moneypunct<C, true>; + template struct __moneypunct_cache<C>; + template class moneypunct_byname<C, false>; + template class moneypunct_byname<C, true>; + template class money_get<C, istreambuf_iterator<C> >; + template class money_put<C, ostreambuf_iterator<C> >; // numpunct, numpunct_byname, num_get, and num_put - template class numpunct<char>; - template struct __numpunct_cache<char>; - template class numpunct_byname<char>; - template class num_get<char, istreambuf_iterator<char> >; - template class num_put<char, ostreambuf_iterator<char> >; - template - ostreambuf_iterator<char> - num_put<char, ostreambuf_iterator<char> >:: - _M_insert_int(ostreambuf_iterator<char>, ios_base&, char, + template class numpunct<C>; + template struct __numpunct_cache<C>; + template class numpunct_byname<C>; + template class num_get<C, istreambuf_iterator<C> >; + template class num_put<C, ostreambuf_iterator<C> >; + template + ostreambuf_iterator<C> + num_put<C, ostreambuf_iterator<C> >:: + _M_insert_int(ostreambuf_iterator<C>, ios_base&, C, long) const; template - ostreambuf_iterator<char> - num_put<char, ostreambuf_iterator<char> >:: - _M_insert_int(ostreambuf_iterator<char>, ios_base&, char, + ostreambuf_iterator<C> + num_put<C, ostreambuf_iterator<C> >:: + _M_insert_int(ostreambuf_iterator<C>, ios_base&, C, unsigned long) const; #ifdef _GLIBCXX_USE_LONG_LONG template - ostreambuf_iterator<char> - num_put<char, ostreambuf_iterator<char> >:: - _M_insert_int(ostreambuf_iterator<char>, ios_base&, char, + ostreambuf_iterator<C> + num_put<C, ostreambuf_iterator<C> >:: + _M_insert_int(ostreambuf_iterator<C>, ios_base&, C, long long) const; template - ostreambuf_iterator<char> - num_put<char, ostreambuf_iterator<char> >:: - _M_insert_int(ostreambuf_iterator<char>, ios_base&, char, + ostreambuf_iterator<C> + num_put<C, ostreambuf_iterator<C> >:: + _M_insert_int(ostreambuf_iterator<C>, ios_base&, C, unsigned long long) const; #endif template - ostreambuf_iterator<char> - num_put<char, ostreambuf_iterator<char> >:: - _M_insert_float(ostreambuf_iterator<char>, ios_base&, char, char, + ostreambuf_iterator<C> + num_put<C, ostreambuf_iterator<C> >:: + _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char, double) const; template - ostreambuf_iterator<char> - num_put<char, ostreambuf_iterator<char> >:: - _M_insert_float(ostreambuf_iterator<char>, ios_base&, char, char, + ostreambuf_iterator<C> + num_put<C, ostreambuf_iterator<C> >:: + _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char, long double) const; -#ifdef _GLIBCXX_USE_WCHAR_T - template class numpunct<wchar_t>; - template struct __numpunct_cache<wchar_t>; - template class numpunct_byname<wchar_t>; - template class num_get<wchar_t, istreambuf_iterator<wchar_t> >; - template class num_put<wchar_t, ostreambuf_iterator<wchar_t> >; - - template - ostreambuf_iterator<wchar_t> - num_put<wchar_t, ostreambuf_iterator<wchar_t> >:: - _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, - long) const; - - template - ostreambuf_iterator<wchar_t> - num_put<wchar_t, ostreambuf_iterator<wchar_t> >:: - _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, - unsigned long) const; - -#ifdef _GLIBCXX_USE_LONG_LONG - template - ostreambuf_iterator<wchar_t> - num_put<wchar_t, ostreambuf_iterator<wchar_t> >:: - _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, - long long) const; - - template - ostreambuf_iterator<wchar_t> - num_put<wchar_t, ostreambuf_iterator<wchar_t> >:: - _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, - unsigned long long) const; -#endif - - template - ostreambuf_iterator<wchar_t> - num_put<wchar_t, ostreambuf_iterator<wchar_t> >:: - _M_insert_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, char, - double) const; - - template - ostreambuf_iterator<wchar_t> - num_put<wchar_t, ostreambuf_iterator<wchar_t> >:: - _M_insert_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, char, - long double) const; -#endif - // time_get and time_put - template class __timepunct<char>; - template struct __timepunct_cache<char>; - template class time_put<char, ostreambuf_iterator<char> >; - template class time_put_byname<char, ostreambuf_iterator<char> >; - template class time_get<char, istreambuf_iterator<char> >; - template class time_get_byname<char, istreambuf_iterator<char> >; - -#ifdef _GLIBCXX_USE_WCHAR_T - template class __timepunct<wchar_t>; - template struct __timepunct_cache<wchar_t>; - template class time_put<wchar_t, ostreambuf_iterator<wchar_t> >; - template class time_put_byname<wchar_t, ostreambuf_iterator<wchar_t> >; - template class time_get<wchar_t, istreambuf_iterator<wchar_t> >; - template class time_get_byname<wchar_t, istreambuf_iterator<wchar_t> >; -#endif + template class __timepunct<C>; + template struct __timepunct_cache<C>; + template class time_put<C, ostreambuf_iterator<C> >; + template class time_put_byname<C, ostreambuf_iterator<C> >; + template class time_get<C, istreambuf_iterator<C> >; + template class time_get_byname<C, istreambuf_iterator<C> >; // messages - template class messages<char>; - template class messages_byname<char>; -#ifdef _GLIBCXX_USE_WCHAR_T - template class messages<wchar_t>; - template class messages_byname<wchar_t>; -#endif + template class messages<C>; + template class messages_byname<C>; // ctype - inline template class __ctype_abstract_base<char>; - template class ctype_byname<char>; -#ifdef _GLIBCXX_USE_WCHAR_T - inline template class __ctype_abstract_base<wchar_t>; - template class ctype_byname<wchar_t>; -#endif + inline template class __ctype_abstract_base<C>; + template class ctype_byname<C>; // codecvt - inline template class __codecvt_abstract_base<char, char, mbstate_t>; - template class codecvt_byname<char, char, mbstate_t>; -#ifdef _GLIBCXX_USE_WCHAR_T - inline template class __codecvt_abstract_base<wchar_t, char, mbstate_t>; - template class codecvt_byname<wchar_t, char, mbstate_t>; -#endif + inline template class __codecvt_abstract_base<C, char, mbstate_t>; + template class codecvt_byname<C, char, mbstate_t>; // collate - template class collate<char>; - template class collate_byname<char>; -#ifdef _GLIBCXX_USE_WCHAR_T - template class collate<wchar_t>; - template class collate_byname<wchar_t>; -#endif + template class collate<C>; + template class collate_byname<C>; // use_facet // NB: use_facet<ctype> is specialized template - const codecvt<char, char, mbstate_t>& - use_facet<codecvt<char, char, mbstate_t> >(const locale&); + const codecvt<C, char, mbstate_t>& + use_facet<codecvt<C, char, mbstate_t> >(const locale&); template - const collate<char>& - use_facet<collate<char> >(const locale&); + const collate<C>& + use_facet<collate<C> >(const locale&); template - const numpunct<char>& - use_facet<numpunct<char> >(const locale&); + const numpunct<C>& + use_facet<numpunct<C> >(const locale&); template - const num_put<char>& - use_facet<num_put<char> >(const locale&); + const num_put<C>& + use_facet<num_put<C> >(const locale&); template - const num_get<char>& - use_facet<num_get<char> >(const locale&); + const num_get<C>& + use_facet<num_get<C> >(const locale&); template - const moneypunct<char, true>& - use_facet<moneypunct<char, true> >(const locale&); + const moneypunct<C, true>& + use_facet<moneypunct<C, true> >(const locale&); template - const moneypunct<char, false>& - use_facet<moneypunct<char, false> >(const locale&); + const moneypunct<C, false>& + use_facet<moneypunct<C, false> >(const locale&); template - const money_put<char>& - use_facet<money_put<char> >(const locale&); + const money_put<C>& + use_facet<money_put<C> >(const locale&); template - const money_get<char>& - use_facet<money_get<char> >(const locale&); + const money_get<C>& + use_facet<money_get<C> >(const locale&); template - const __timepunct<char>& - use_facet<__timepunct<char> >(const locale&); + const __timepunct<C>& + use_facet<__timepunct<C> >(const locale&); template - const time_put<char>& - use_facet<time_put<char> >(const locale&); + const time_put<C>& + use_facet<time_put<C> >(const locale&); template - const time_get<char>& - use_facet<time_get<char> >(const locale&); + const time_get<C>& + use_facet<time_get<C> >(const locale&); template - const messages<char>& - use_facet<messages<char> >(const locale&); - -#ifdef _GLIBCXX_USE_WCHAR_T - template - const codecvt<wchar_t, char, mbstate_t>& - use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&); - - template - const collate<wchar_t>& - use_facet<collate<wchar_t> >(const locale&); - - template - const numpunct<wchar_t>& - use_facet<numpunct<wchar_t> >(const locale&); - - template - const num_put<wchar_t>& - use_facet<num_put<wchar_t> >(const locale&); - - template - const num_get<wchar_t>& - use_facet<num_get<wchar_t> >(const locale&); - - template - const moneypunct<wchar_t, true>& - use_facet<moneypunct<wchar_t, true> >(const locale&); - - template - const moneypunct<wchar_t, false>& - use_facet<moneypunct<wchar_t, false> >(const locale&); - - template - const money_put<wchar_t>& - use_facet<money_put<wchar_t> >(const locale&); - - template - const money_get<wchar_t>& - use_facet<money_get<wchar_t> >(const locale&); - - template - const __timepunct<wchar_t>& - use_facet<__timepunct<wchar_t> >(const locale&); - - template - const time_put<wchar_t>& - use_facet<time_put<wchar_t> >(const locale&); - - template - const time_get<wchar_t>& - use_facet<time_get<wchar_t> >(const locale&); - - template - const messages<wchar_t>& - use_facet<messages<wchar_t> >(const locale&); -#endif + const messages<C>& + use_facet<messages<C> >(const locale&); // has_facet template bool - has_facet<ctype<char> >(const locale&); - - template - bool - has_facet<codecvt<char, char, mbstate_t> >(const locale&); - - template - bool - has_facet<collate<char> >(const locale&); - - template - bool - has_facet<numpunct<char> >(const locale&); + has_facet<ctype<C> >(const locale&); template bool - has_facet<num_put<char> >(const locale&); + has_facet<codecvt<C, char, mbstate_t> >(const locale&); template bool - has_facet<num_get<char> >(const locale&); + has_facet<collate<C> >(const locale&); template bool - has_facet<moneypunct<char> >(const locale&); + has_facet<numpunct<C> >(const locale&); template bool - has_facet<money_put<char> >(const locale&); + has_facet<num_put<C> >(const locale&); template bool - has_facet<money_get<char> >(const locale&); + has_facet<num_get<C> >(const locale&); template bool - has_facet<__timepunct<char> >(const locale&); + has_facet<moneypunct<C> >(const locale&); template bool - has_facet<time_put<char> >(const locale&); - - template - bool - has_facet<time_get<char> >(const locale&); - - template - bool - has_facet<messages<char> >(const locale&); - -#ifdef _GLIBCXX_USE_WCHAR_T - template - bool - has_facet<ctype<wchar_t> >(const locale&); + has_facet<money_put<C> >(const locale&); template bool - has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); + has_facet<money_get<C> >(const locale&); template bool - has_facet<collate<wchar_t> >(const locale&); + has_facet<__timepunct<C> >(const locale&); template bool - has_facet<numpunct<wchar_t> >(const locale&); + has_facet<time_put<C> >(const locale&); template bool - has_facet<num_put<wchar_t> >(const locale&); + has_facet<time_get<C> >(const locale&); template bool - has_facet<num_get<wchar_t> >(const locale&); + has_facet<messages<C> >(const locale&); - template - bool - has_facet<moneypunct<wchar_t> >(const locale&); - - template - bool - has_facet<money_put<wchar_t> >(const locale&); - - template - bool - has_facet<money_get<wchar_t> >(const locale&); - template - bool - has_facet<__timepunct<wchar_t> >(const locale&); - - template - bool - has_facet<time_put<wchar_t> >(const locale&); - - template - bool - has_facet<time_get<wchar_t> >(const locale&); - - template - bool - has_facet<messages<wchar_t> >(const locale&); -#endif - - // locale + // locale functions. template - char* - __add_grouping<char>(char*, char, char const*, char const*, - char const*, char const*); + C* + __add_grouping<C>(C*, C, char const*, char const*, + C const*, C const*); template bool - __verify_grouping<char>(const basic_string<char>&, basic_string<char>&); + __verify_grouping<C>(const basic_string<C>&, basic_string<C>&); - template class __pad<char, char_traits<char> >; + template class __pad<C, char_traits<C> >; -#ifdef _GLIBCXX_USE_WCHAR_T - template - wchar_t* - __add_grouping<wchar_t>(wchar_t*, wchar_t, char const*, char const*, - wchar_t const*, wchar_t const*); - template - bool - __verify_grouping<wchar_t>(const basic_string<wchar_t>&, - basic_string<wchar_t>&); - - template class __pad<wchar_t, char_traits<wchar_t> >; -#endif - - template - int - __convert_from_v(char*, const int, const char*, double, - const __c_locale&, int); - - template - int - __convert_from_v(char*, const int, const char*, long double, - const __c_locale&, int); - - template - int - __convert_from_v(char*, const int, const char*, long, - const __c_locale&, int); - - template - int - __convert_from_v(char*, const int, const char*, unsigned long, - const __c_locale&, int); - -#ifdef _GLIBCXX_USE_LONG_LONG - template - int - __convert_from_v(char*, const int, const char*, long long, - const __c_locale&, int); - - template - int - __convert_from_v(char*, const int, const char*, unsigned long long, - const __c_locale&, int); -#endif - - template - int - __int_to_char(char*, const int, unsigned long, const char*, - ios_base::fmtflags, bool); - -#ifdef _GLIBCXX_USE_WCHAR_T template int - __int_to_char(wchar_t*, const int, unsigned long, const wchar_t*, + __int_to_char(C*, const int, unsigned long, const C*, ios_base::fmtflags, bool); -#endif #ifdef _GLIBCXX_USE_LONG_LONG template int - __int_to_char(char*, const int, unsigned long long, const char*, - ios_base::fmtflags, bool); - -#ifdef _GLIBCXX_USE_WCHAR_T - template - int - __int_to_char(wchar_t*, const int, unsigned long long, const wchar_t*, + __int_to_char(C*, const int, unsigned long long, const C*, ios_base::fmtflags, bool); #endif -#endif } // namespace std diff --git a/libstdc++-v3/src/locale-misc-inst.cc b/libstdc++-v3/src/locale-misc-inst.cc new file mode 100644 index 00000000000..73169c19cdd --- /dev/null +++ b/libstdc++-v3/src/locale-misc-inst.cc @@ -0,0 +1,69 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2002, 2003 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +// +// ISO C++ 14882: 22.1 Locales +// + +#include <locale> + +namespace std +{ + template + int + __convert_from_v(char*, const int, const char*, double, + const __c_locale&, int); + + template + int + __convert_from_v(char*, const int, const char*, long double, + const __c_locale&, int); + + template + int + __convert_from_v(char*, const int, const char*, long, + const __c_locale&, int); + + template + int + __convert_from_v(char*, const int, const char*, unsigned long, + const __c_locale&, int); + +#ifdef _GLIBCXX_USE_LONG_LONG + template + int + __convert_from_v(char*, const int, const char*, long long, + const __c_locale&, int); + + template + int + __convert_from_v(char*, const int, const char*, unsigned long long, + const __c_locale&, int); +#endif +} // namespace std diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 80bce52b47d..78d0059e3ed 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -34,17 +34,8 @@ #include <locale> #include <bits/atomicity.h> -namespace __gnu_cxx -{ - // Defined in globals.cc. - 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; const locale::category locale::ctype; @@ -55,10 +46,6 @@ namespace std const locale::category locale::messages; const locale::category locale::all; - // In the future, GLIBCXX_ABI > 5 should remove all uses of - // _GLIBCXX_ASM_SYMVER in this file, and remove exports of any - // static data members of locale. - // These are no longer exported. locale::_Impl* locale::_S_classic; locale::_Impl* locale::_S_global; @@ -68,112 +55,6 @@ namespace std __gthread_once_t locale::_S_once = __GTHREAD_ONCE_INIT; #endif - size_t - locale::id::_M_id() const - { - if (!_M_index) - _M_index = 1 + __exchange_and_add(&_S_highwater, 1); - return _M_index - 1; - } - - // Definitions for static const data members of locale::id - _Atomic_word locale::id::_S_highwater; // init'd to 0 by linker - - // Definitions for static const data members of locale::_Impl - const locale::id* const - locale::_Impl::_S_id_ctype[] = - { - &std::ctype<char>::id, - &codecvt<char, char, mbstate_t>::id, -#ifdef _GLIBCXX_USE_WCHAR_T - &std::ctype<wchar_t>::id, - &codecvt<wchar_t, char, mbstate_t>::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_numeric[] = - { - &num_get<char>::id, - &num_put<char>::id, - &numpunct<char>::id, -#ifdef _GLIBCXX_USE_WCHAR_T - &num_get<wchar_t>::id, - &num_put<wchar_t>::id, - &numpunct<wchar_t>::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_collate[] = - { - &std::collate<char>::id, -#ifdef _GLIBCXX_USE_WCHAR_T - &std::collate<wchar_t>::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_time[] = - { - &__timepunct<char>::id, - &time_get<char>::id, - &time_put<char>::id, -#ifdef _GLIBCXX_USE_WCHAR_T - &__timepunct<wchar_t>::id, - &time_get<wchar_t>::id, - &time_put<wchar_t>::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_monetary[] = - { - &money_get<char>::id, - &money_put<char>::id, - &moneypunct<char, false>::id, - &moneypunct<char, true >::id, -#ifdef _GLIBCXX_USE_WCHAR_T - &money_get<wchar_t>::id, - &money_put<wchar_t>::id, - &moneypunct<wchar_t, false>::id, - &moneypunct<wchar_t, true >::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_messages[] = - { - &std::messages<char>::id, -#ifdef _GLIBCXX_USE_WCHAR_T - &std::messages<wchar_t>::id, -#endif - 0 - }; - - const locale::id* const* const - locale::_Impl::_S_facet_categories[] = - { - // Order must match the decl order in class locale. - 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_messages, - 0 - }; - - locale::locale() throw() - { - _S_initialize(); - (_M_impl = _S_global)->_M_add_reference(); - } locale::locale(const locale& __other) throw() { (_M_impl = __other._M_impl)->_M_add_reference(); } @@ -184,130 +65,6 @@ namespace std locale::locale(_Impl* __ip) throw() : _M_impl(__ip) { } - locale::locale(const char* __s) - { - if (__s) - { - _S_initialize(); - if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0) - (_M_impl = _S_classic)->_M_add_reference(); - else if (std::strcmp(__s, "") != 0) - _M_impl = new _Impl(__s, 1); - else - { - // Get it from the environment. - char* __env = std::getenv("LC_ALL"); - // If LC_ALL is set we are done. - if (__env && std::strcmp(__env, "") != 0) - { - if (std::strcmp(__env, "C") == 0 - || std::strcmp(__env, "POSIX") == 0) - (_M_impl = _S_classic)->_M_add_reference(); - else - _M_impl = new _Impl(__env, 1); - } - else - { - string __res; - // LANG may set a default different from "C". - char* __env = std::getenv("LANG"); - if (!__env || std::strcmp(__env, "") == 0 - || std::strcmp(__env, "C") == 0 - || std::strcmp(__env, "POSIX") == 0) - __res = "C"; - else - __res = __env; - - // Scan the categories looking for the first one - // different from LANG. - size_t __i = 0; - if (__res == "C") - for (; __i < _S_categories_size; ++__i) - { - __env = std::getenv(_S_categories[__i]); - if (__env && std::strcmp(__env, "") != 0 - && std::strcmp(__env, "C") != 0 - && std::strcmp(__env, "POSIX") != 0) - break; - } - else - for (; __i < _S_categories_size; ++__i) - { - __env = std::getenv(_S_categories[__i]); - if (__env && std::strcmp(__env, "") != 0 - && __res != __env) - 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) - { - 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; ++__i) - { - __env = std::getenv(_S_categories[__i]); - if (!__env || std::strcmp(__env, "") == 0) - { - __str += _S_categories[__i]; - __str += '='; - __str += __res; - __str += ';'; - } - else if (std::strcmp(__env, "C") == 0 - || std::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 (__res == "C") - (_M_impl = _S_classic)->_M_add_reference(); - else - _M_impl = new _Impl(__res.c_str(), 1); - } - } - } - else - __throw_runtime_error("locale::locale NULL not valid"); - } - - locale::locale(const locale& __base, const char* __s, category __cat) - { - // NB: There are complicated, yet more efficient ways to do - // this. Building up locales on a per-category way is tedious, so - // let's do it this way until people complain. - locale __add(__s); - _M_coalesce(__base, __add, __cat); - } - - locale::locale(const locale& __base, const locale& __add, category __cat) - { _M_coalesce(__base, __add, __cat); } - locale::~locale() throw() { _M_impl->_M_remove_reference(); } @@ -328,27 +85,6 @@ namespace std return *this; } - locale - locale::global(const locale& __other) - { - _S_initialize(); - - // XXX MT - _Impl* __old = _S_global; - __other._M_impl->_M_add_reference(); - _S_global = __other._M_impl; - if (_S_global->_M_check_same_name() - && (std::strcmp(_S_global->_M_names[0], "*") != 0)) - setlocale(LC_ALL, __other.name().c_str()); - - // Reference count sanity check: one reference removed for the - // subsition of __other locale, one added by return-by-value. Net - // difference: zero. When the returned locale object's destrutor - // is called, then the reference count is decremented and possibly - // destroyed. - return locale(__old); - } - string locale::name() const { @@ -371,50 +107,6 @@ namespace std return __ret; } - const locale& - locale::classic() - { - _S_initialize(); - return c_locale; - } - - void - locale::_S_initialize_once() - { - // 2 references. - // One reference for _S_classic, one for _S_global - _S_classic = new (&c_locale_impl) _Impl(2); - _S_global = _S_classic; - new (&c_locale) locale(_S_classic); - } - - void - locale::_S_initialize() - { -#ifdef __GTHREADS - if (__gthread_active_p()) - __gthread_once(&_S_once, _S_initialize_once); -#endif - if (!_S_classic) - _S_initialize_once(); - } - - 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) { @@ -457,6 +149,7 @@ namespace std return __ret; } + // locale::facet __c_locale locale::facet::_S_c_locale; const char locale::facet::_S_c_name[2] = "C"; @@ -465,9 +158,6 @@ namespace std __gthread_once_t locale::facet::_S_once = __GTHREAD_ONCE_INIT; #endif - locale::facet:: - ~facet() { } - void locale::facet::_S_initialize_once() { @@ -494,62 +184,182 @@ namespace std locale::facet::_S_get_c_name() { return _S_c_name; } - // Definitions for static const data members of time_base. - template<> - const char* - __timepunct_cache<char>::_S_timezones[14] = - { - "GMT", "HST", "AKST", "PST", "MST", "CST", "EST", "AST", "NST", "CET", - "IST", "EET", "CST", "JST" - }; - -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - const wchar_t* - __timepunct_cache<wchar_t>::_S_timezones[14] = - { - L"GMT", L"HST", L"AKST", L"PST", L"MST", L"CST", L"EST", L"AST", - L"NST", L"CET", L"IST", L"EET", L"CST", L"JST" - }; -#endif + locale::facet:: + ~facet() { } - // Definitions for static const data members of money_base. - const money_base::pattern - money_base::_S_default_pattern = { {symbol, sign, none, value} }; + // locale::_Impl + locale::_Impl:: + ~_Impl() throw() + { + if (_M_facets) + for (size_t __i = 0; __i < _M_facets_size; ++__i) + if (_M_facets[__i]) + _M_facets[__i]->_M_remove_reference(); + delete [] _M_facets; + + if (_M_caches) + for (size_t __i = 0; __i < _M_facets_size; ++__i) + if (_M_caches[__i]) + _M_caches[__i]->_M_remove_reference(); + delete [] _M_caches; + + if (_M_names) + for (size_t __i = 0; __i < _S_categories_size; ++__i) + delete [] _M_names[__i]; + delete [] _M_names; + } - const char* __num_base::_S_atoms_in = "-+xX0123456789eEabcdfABCDF"; - const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF"; + // Clone existing _Impl object. + locale::_Impl:: + _Impl(const _Impl& __imp, size_t __refs) + : _M_references(__refs), _M_facets_size(__imp._M_facets_size) + { + _M_facets = _M_caches = 0; + _M_names = 0; + try + { + _M_facets = new const facet*[_M_facets_size]; + 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(); + } + _M_caches = new const facet*[_M_facets_size]; + for (size_t __i = 0; __i < _M_facets_size; ++__i) + { + _M_caches[__i] = __imp._M_caches[__i]; + if (_M_caches[__i]) + _M_caches[__i]->_M_add_reference(); + } + _M_names = new char*[_S_categories_size]; + for (size_t __i = 0; __i < _S_categories_size; ++__i) + _M_names[__i] = 0; + + // Name all the categories. + for (size_t __i = 0; __i < _S_categories_size; ++__i) + { + char* __new = new char[std::strlen(__imp._M_names[__i]) + 1]; + std::strcpy(__new, __imp._M_names[__i]); + _M_names[__i] = __new; + } + } + catch(...) + { + this->~_Impl(); + __throw_exception_again; + } + } - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // According to the resolution of DR 231, about 22.2.2.2.2, p11, - // "str.precision() is specified in the conversion specification". void - __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod) + locale::_Impl:: + _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp) { - ios_base::fmtflags __flags = __io.flags(); - *__fptr++ = '%'; - // [22.2.2.2.2] Table 60 - if (__flags & ios_base::showpos) - *__fptr++ = '+'; - if (__flags & ios_base::showpoint) - *__fptr++ = '#'; - - // As per DR 231: _always_, not only when - // __flags & ios_base::fixed || __prec > 0 - *__fptr++ = '.'; - *__fptr++ = '*'; - - if (__mod) - *__fptr++ = __mod; - ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; - // [22.2.2.2.2] Table 58 - if (__fltfield == ios_base::fixed) - *__fptr++ = 'f'; - else if (__fltfield == ios_base::scientific) - *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; - else - *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; - *__fptr = '\0'; + for (; *__idpp; ++__idpp) + _M_replace_facet(__imp, *__idpp); + } + + void + locale::_Impl:: + _M_replace_facet(const _Impl* __imp, const locale::id* __idp) + { + size_t __index = __idp->_M_id(); + if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index]) + __throw_runtime_error("locale::_Impl::_M_replace_facet"); + _M_install_facet(__idp, __imp->_M_facets[__index]); + } + + void + locale::_Impl:: + _M_install_facet(const locale::id* __idp, const facet* __fp) + { + if (__fp) + { + size_t __index = __idp->_M_id(); + + // Check size of facet vector to ensure adequate room. + if (__index > _M_facets_size - 1) + { + const size_t __new_size = __index + 4; + + // New facet array. + const facet** __oldf = _M_facets; + const facet** __newf; + __newf = new const facet*[__new_size]; + for (size_t __i = 0; __i < _M_facets_size; ++__i) + __newf[__i] = _M_facets[__i]; + for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) + __newf[__i2] = 0; + + // New cache array. + const facet** __oldc = _M_caches; + const facet** __newc; + try + { + __newc = new const facet*[__new_size]; + } + catch(...) + { + delete [] __newf; + __throw_exception_again; + } + for (size_t __i = 0; __i < _M_facets_size; ++__i) + __newc[__i] = _M_caches[__i]; + for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) + __newc[__i2] = 0; + + _M_facets_size = __new_size; + _M_facets = __newf; + _M_caches = __newc; + delete [] __oldf; + delete [] __oldc; + } + + __fp->_M_add_reference(); + const facet*& __fpr = _M_facets[__index]; + if (__fpr) + { + // Replacing an existing facet. Order matters. + __fpr->_M_remove_reference(); + __fpr = __fp; + } + else + { + // Installing a newly created facet into an empty + // _M_facets container, say a newly-constructed, + // swanky-fresh _Impl. + _M_facets[__index] = __fp; + } + + // Ideally, it would be nice to only remove the caches that + // are now incorrect. However, some of the caches depend on + // multiple facets, and we only know about one facet + // here. It's no great loss: the first use of the new facet + // will create a new, correctly cached facet anyway. + for (size_t __i = 0; __i < _M_facets_size; ++__i) + { + const facet* __cpr = _M_caches[__i]; + if (__cpr) + { + __cpr->_M_remove_reference(); + _M_caches[__i] = 0; + } + } + } + } + + + // locale::id + // Definitions for static const data members of locale::id + _Atomic_word locale::id::_S_highwater; // init'd to 0 by linker + + size_t + locale::id::_M_id() const + { + if (!_M_index) + _M_index = 1 + __exchange_and_add(&_S_highwater, 1); + return _M_index - 1; } } // namespace std + diff --git a/libstdc++-v3/src/locale_facets.cc b/libstdc++-v3/src/locale_facets.cc new file mode 100644 index 00000000000..6a0ccf21257 --- /dev/null +++ b/libstdc++-v3/src/locale_facets.cc @@ -0,0 +1,91 @@ +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +#include <locale> + +namespace std +{ + // Definitions for static const data members of time_base. + template<> + const char* + __timepunct_cache<char>::_S_timezones[14] = + { + "GMT", "HST", "AKST", "PST", "MST", "CST", "EST", "AST", "NST", "CET", + "IST", "EET", "CST", "JST" + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + const wchar_t* + __timepunct_cache<wchar_t>::_S_timezones[14] = + { + L"GMT", L"HST", L"AKST", L"PST", L"MST", L"CST", L"EST", L"AST", + L"NST", L"CET", L"IST", L"EET", L"CST", L"JST" + }; +#endif + + // Definitions for static const data members of money_base. + const money_base::pattern + money_base::_S_default_pattern = { {symbol, sign, none, value} }; + + const char* __num_base::_S_atoms_in = "-+xX0123456789eEabcdfABCDF"; + const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF"; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR 231, about 22.2.2.2.2, p11, + // "str.precision() is specified in the conversion specification". + void + __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod) + { + ios_base::fmtflags __flags = __io.flags(); + *__fptr++ = '%'; + // [22.2.2.2.2] Table 60 + if (__flags & ios_base::showpos) + *__fptr++ = '+'; + if (__flags & ios_base::showpoint) + *__fptr++ = '#'; + + // As per DR 231: _always_, not only when + // __flags & ios_base::fixed || __prec > 0 + *__fptr++ = '.'; + *__fptr++ = '*'; + + if (__mod) + *__fptr++ = __mod; + ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; + // [22.2.2.2.2] Table 58 + if (__fltfield == ios_base::fixed) + *__fptr++ = 'f'; + else if (__fltfield == ios_base::scientific) + *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; + else + *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; + *__fptr = '\0'; + } +} // namespace std + diff --git a/libstdc++-v3/src/locale_init.cc b/libstdc++-v3/src/locale_init.cc new file mode 100644 index 00000000000..1273b2a4422 --- /dev/null +++ b/libstdc++-v3/src/locale_init.cc @@ -0,0 +1,340 @@ +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +#include <clocale> +#include <cstring> +#include <cstdlib> // For getenv, free. +#include <cctype> +#include <cwctype> // For towupper, etc. +#include <locale> +#include <bits/atomicity.h> + +namespace __gnu_cxx +{ + // Defined in globals.cc. + extern std::locale c_locale; + extern std::locale::_Impl c_locale_impl; + + extern std::locale::facet* facet_vec[_GLIBCXX_NUM_FACETS]; + extern char* name_vec[6 + _GLIBCXX_NUM_CATEGORIES]; + extern char name_c[6 + _GLIBCXX_NUM_CATEGORIES][2]; + + extern std::ctype<char> ctype_c; + extern std::collate<char> collate_c; + extern std::numpunct<char> numpunct_c; + extern std::num_get<char> num_get_c; + extern std::num_put<char> num_put_c; + extern std::codecvt<char, char, mbstate_t> codecvt_c; + extern std::moneypunct<char, false> moneypunct_cf; + extern std::moneypunct<char, true> moneypunct_ct; + extern std::money_get<char> money_get_c; + extern std::money_put<char> money_put_c; + extern std::__timepunct<char> timepunct_c; + extern std::time_get<char> time_get_c; + extern std::time_put<char> time_put_c; + extern std::messages<char> messages_c; +#ifdef _GLIBCXX_USE_WCHAR_T + extern std::ctype<wchar_t> ctype_w; + extern std::collate<wchar_t> collate_w; + extern std::numpunct<wchar_t> numpunct_w; + extern std::num_get<wchar_t> num_get_w; + extern std::num_put<wchar_t> num_put_w; + extern std::codecvt<wchar_t, char, mbstate_t> codecvt_w; + extern std::moneypunct<wchar_t, false> moneypunct_wf; + extern std::moneypunct<wchar_t, true> moneypunct_wt; + extern std::money_get<wchar_t> money_get_w; + extern std::money_put<wchar_t> money_put_w; + extern std::__timepunct<wchar_t> timepunct_w; + extern std::time_get<wchar_t> time_get_w; + extern std::time_put<wchar_t> time_put_w; + extern std::messages<wchar_t> messages_w; +#endif + + // And the caches.... + extern std::locale::facet* cache_vec[_GLIBCXX_NUM_FACETS]; + extern std::__numpunct_cache<char> numpunct_cache_c; + extern std::__moneypunct_cache<char> moneypunct_cache_cf; + extern std::__moneypunct_cache<char> moneypunct_cache_ct; + extern std::__timepunct_cache<char> timepunct_cache_c; +#ifdef _GLIBCXX_USE_WCHAR_T + extern std::__numpunct_cache<wchar_t> numpunct_cache_w; + extern std::__moneypunct_cache<wchar_t> moneypunct_cache_wf; + extern std::__moneypunct_cache<wchar_t> moneypunct_cache_wt; + extern std::__timepunct_cache<wchar_t> timepunct_cache_w; +#endif +} // namespace __gnu_cxx + +namespace std +{ + using namespace __gnu_cxx; + + locale::locale() throw() + { + _S_initialize(); + (_M_impl = _S_global)->_M_add_reference(); + } + + locale + locale::global(const locale& __other) + { + _S_initialize(); + + // XXX MT + _Impl* __old = _S_global; + __other._M_impl->_M_add_reference(); + _S_global = __other._M_impl; + if (_S_global->_M_check_same_name() + && (std::strcmp(_S_global->_M_names[0], "*") != 0)) + setlocale(LC_ALL, __other.name().c_str()); + + // Reference count sanity check: one reference removed for the + // subsition of __other locale, one added by return-by-value. Net + // difference: zero. When the returned locale object's destrutor + // is called, then the reference count is decremented and possibly + // destroyed. + return locale(__old); + } + + const locale& + locale::classic() + { + _S_initialize(); + return c_locale; + } + + void + locale::_S_initialize_once() + { + // 2 references. + // One reference for _S_classic, one for _S_global + _S_classic = new (&c_locale_impl) _Impl(2); + _S_global = _S_classic; + new (&c_locale) locale(_S_classic); + } + + void + locale::_S_initialize() + { +#ifdef __GTHREADS + if (__gthread_active_p()) + __gthread_once(&_S_once, _S_initialize_once); + else +#endif + { + if (!_S_classic) + _S_initialize_once(); + } + } + + // Definitions for static const data members of locale::_Impl + const locale::id* const + locale::_Impl::_S_id_ctype[] = + { + &std::ctype<char>::id, + &codecvt<char, char, mbstate_t>::id, +#ifdef _GLIBCXX_USE_WCHAR_T + &std::ctype<wchar_t>::id, + &codecvt<wchar_t, char, mbstate_t>::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_numeric[] = + { + &num_get<char>::id, + &num_put<char>::id, + &numpunct<char>::id, +#ifdef _GLIBCXX_USE_WCHAR_T + &num_get<wchar_t>::id, + &num_put<wchar_t>::id, + &numpunct<wchar_t>::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_collate[] = + { + &std::collate<char>::id, +#ifdef _GLIBCXX_USE_WCHAR_T + &std::collate<wchar_t>::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_time[] = + { + &__timepunct<char>::id, + &time_get<char>::id, + &time_put<char>::id, +#ifdef _GLIBCXX_USE_WCHAR_T + &__timepunct<wchar_t>::id, + &time_get<wchar_t>::id, + &time_put<wchar_t>::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_monetary[] = + { + &money_get<char>::id, + &money_put<char>::id, + &moneypunct<char, false>::id, + &moneypunct<char, true >::id, +#ifdef _GLIBCXX_USE_WCHAR_T + &money_get<wchar_t>::id, + &money_put<wchar_t>::id, + &moneypunct<wchar_t, false>::id, + &moneypunct<wchar_t, true >::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_messages[] = + { + &std::messages<char>::id, +#ifdef _GLIBCXX_USE_WCHAR_T + &std::messages<wchar_t>::id, +#endif + 0 + }; + + const locale::id* const* const + locale::_Impl::_S_facet_categories[] = + { + // Order must match the decl order in class locale. + 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_messages, + 0 + }; + + // Construct "C" _Impl. + locale::_Impl:: + _Impl(size_t __refs) throw() + : _M_references(__refs), _M_facets_size(_GLIBCXX_NUM_FACETS) + { + _M_facets = new (&facet_vec) const facet*[_M_facets_size]; + _M_caches = new (&cache_vec) const facet*[_M_facets_size]; + for (size_t __i = 0; __i < _M_facets_size; ++__i) + _M_facets[__i] = _M_caches[__i] = 0; + + // Name all the categories. + _M_names = new (&name_vec) char*[_S_categories_size]; + for (size_t __i = 0; __i < _S_categories_size; ++__i) + { + _M_names[__i] = new (&name_c[__i]) char[2]; + std::strcpy(_M_names[__i], locale::facet::_S_get_c_name()); + } + + // 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. + // 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)); + + typedef __numpunct_cache<char> num_cache_c; + num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2); + _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 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)); + + typedef __moneypunct_cache<char> money_cache_c; + money_cache_c* __mpcf = new (&moneypunct_cache_cf) money_cache_c(2); + _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1)); + money_cache_c* __mpct = new (&moneypunct_cache_ct) money_cache_c(2); + _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1)); + + _M_init_facet(new (&money_get_c) money_get<char>(1)); + _M_init_facet(new (&money_put_c) money_put<char>(1)); + + typedef __timepunct_cache<char> time_cache_c; + time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2); + _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 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 _GLIBCXX_USE_WCHAR_T + _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1)); + _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1)); + + typedef __numpunct_cache<wchar_t> num_cache_w; + num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2); + _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 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)); + + typedef __moneypunct_cache<wchar_t> money_cache_w; + money_cache_w* __mpwf = new (&moneypunct_cache_wf) money_cache_w(2); + _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1)); + money_cache_w* __mpwt = new (&moneypunct_cache_wt) money_cache_w(2); + _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 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)); + + typedef __timepunct_cache<wchar_t> time_cache_w; + time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2); + _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 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 + + // This locale is safe to pre-cache, after all the facets have + // been created and installed. + _M_caches[numpunct<char>::id._M_id()] = __npc; + _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf; + _M_caches[moneypunct<char, true>::id._M_id()] = __mpct; + _M_caches[__timepunct<char>::id._M_id()] = __tpc; +#ifdef _GLIBCXX_USE_WCHAR_T + _M_caches[numpunct<wchar_t>::id._M_id()] = __npw; + _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf; + _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt; + _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw; +#endif + } +} // namespace std diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc index 56b2bdfe102..e14053c9580 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -30,123 +30,147 @@ #include <cstring> #include <locale> -namespace __gnu_cxx -{ - using namespace std; - - // Defined in globals.cc. - extern locale::facet* facet_vec[_GLIBCXX_NUM_FACETS]; - extern char* name_vec[6 + _GLIBCXX_NUM_CATEGORIES]; - extern char name_c[6 + _GLIBCXX_NUM_CATEGORIES][2]; - - 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_cf; - extern moneypunct<char, true> moneypunct_ct; - 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 _GLIBCXX_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_wf; - extern moneypunct<wchar_t, true> moneypunct_wt; - 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 - - // And the caches.... - extern locale::facet* cache_vec[_GLIBCXX_NUM_FACETS]; - extern __numpunct_cache<char> numpunct_cache_c; - extern __moneypunct_cache<char> moneypunct_cache_cf; - extern __moneypunct_cache<char> moneypunct_cache_ct; - extern __timepunct_cache<char> timepunct_cache_c; -#ifdef _GLIBCXX_USE_WCHAR_T - extern __numpunct_cache<wchar_t> numpunct_cache_w; - extern __moneypunct_cache<wchar_t> moneypunct_cache_wf; - extern __moneypunct_cache<wchar_t> moneypunct_cache_wt; - extern __timepunct_cache<wchar_t> timepunct_cache_w; -#endif -} // namespace __gnu_cxx - namespace std { using namespace __gnu_cxx; - locale::_Impl:: - ~_Impl() throw() - { - if (_M_facets) - for (size_t __i = 0; __i < _M_facets_size; ++__i) - if (_M_facets[__i]) - _M_facets[__i]->_M_remove_reference(); - delete [] _M_facets; - - if (_M_caches) - for (size_t __i = 0; __i < _M_facets_size; ++__i) - if (_M_caches[__i]) - _M_caches[__i]->_M_remove_reference(); - delete [] _M_caches; - - if (_M_names) - for (size_t __i = 0; __i < _S_categories_size; ++__i) - delete [] _M_names[__i]; - delete [] _M_names; - } - - // Clone existing _Impl object. - locale::_Impl:: - _Impl(const _Impl& __imp, size_t __refs) - : _M_references(__refs), _M_facets_size(__imp._M_facets_size) + + locale::locale(const char* __s) { - _M_facets = _M_caches = 0; - _M_names = 0; - try + if (__s) { - _M_facets = new const facet*[_M_facets_size]; - 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(); - } - _M_caches = new const facet*[_M_facets_size]; - for (size_t __i = 0; __i < _M_facets_size; ++__i) - { - _M_caches[__i] = __imp._M_caches[__i]; - if (_M_caches[__i]) - _M_caches[__i]->_M_add_reference(); - } - _M_names = new char*[_S_categories_size]; - for (size_t __i = 0; __i < _S_categories_size; ++__i) - _M_names[__i] = 0; - - // Name all the categories. - for (size_t __i = 0; __i < _S_categories_size; ++__i) + _S_initialize(); + if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0) + (_M_impl = _S_classic)->_M_add_reference(); + else if (std::strcmp(__s, "") != 0) + _M_impl = new _Impl(__s, 1); + else { - char* __new = new char[std::strlen(__imp._M_names[__i]) + 1]; - std::strcpy(__new, __imp._M_names[__i]); - _M_names[__i] = __new; + // Get it from the environment. + char* __env = std::getenv("LC_ALL"); + // If LC_ALL is set we are done. + if (__env && std::strcmp(__env, "") != 0) + { + if (std::strcmp(__env, "C") == 0 + || std::strcmp(__env, "POSIX") == 0) + (_M_impl = _S_classic)->_M_add_reference(); + else + _M_impl = new _Impl(__env, 1); + } + else + { + string __res; + // LANG may set a default different from "C". + char* __env = std::getenv("LANG"); + if (!__env || std::strcmp(__env, "") == 0 + || std::strcmp(__env, "C") == 0 + || std::strcmp(__env, "POSIX") == 0) + __res = "C"; + else + __res = __env; + + // Scan the categories looking for the first one + // different from LANG. + size_t __i = 0; + if (__res == "C") + for (; __i < _S_categories_size; ++__i) + { + __env = std::getenv(_S_categories[__i]); + if (__env && std::strcmp(__env, "") != 0 + && std::strcmp(__env, "C") != 0 + && std::strcmp(__env, "POSIX") != 0) + break; + } + else + for (; __i < _S_categories_size; ++__i) + { + __env = std::getenv(_S_categories[__i]); + if (__env && std::strcmp(__env, "") != 0 + && __res != __env) + 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) + { + 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; ++__i) + { + __env = std::getenv(_S_categories[__i]); + if (!__env || std::strcmp(__env, "") == 0) + { + __str += _S_categories[__i]; + __str += '='; + __str += __res; + __str += ';'; + } + else if (std::strcmp(__env, "C") == 0 + || std::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 (__res == "C") + (_M_impl = _S_classic)->_M_add_reference(); + else + _M_impl = new _Impl(__res.c_str(), 1); + } } } - catch(...) - { - this->~_Impl(); + else + __throw_runtime_error("locale::locale NULL not valid"); + } + + locale::locale(const locale& __base, const char* __s, category __cat) + { + // NB: There are complicated, yet more efficient ways to do + // this. Building up locales on a per-category way is tedious, so + // let's do it this way until people complain. + locale __add(__s); + _M_coalesce(__base, __add, __cat); + } + + locale::locale(const locale& __base, const locale& __add, category __cat) + { _M_coalesce(__base, __add, __cat); } + + 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; } } @@ -243,103 +267,6 @@ namespace std } } - // Construct "C" _Impl. - locale::_Impl:: - _Impl(size_t __refs) throw() - : _M_references(__refs), _M_facets_size(_GLIBCXX_NUM_FACETS) - { - _M_facets = new (&facet_vec) const facet*[_M_facets_size]; - _M_caches = new (&cache_vec) const facet*[_M_facets_size]; - for (size_t __i = 0; __i < _M_facets_size; ++__i) - _M_facets[__i] = _M_caches[__i] = 0; - - // Name all the categories. - _M_names = new (&name_vec) char*[_S_categories_size]; - for (size_t __i = 0; __i < _S_categories_size; ++__i) - { - _M_names[__i] = new (&name_c[__i]) char[2]; - std::strcpy(_M_names[__i], locale::facet::_S_get_c_name()); - } - - // 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. - // 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)); - - typedef __numpunct_cache<char> num_cache_c; - num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2); - _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 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)); - - typedef __moneypunct_cache<char> money_cache_c; - money_cache_c* __mpcf = new (&moneypunct_cache_cf) money_cache_c(2); - _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1)); - money_cache_c* __mpct = new (&moneypunct_cache_ct) money_cache_c(2); - _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1)); - - _M_init_facet(new (&money_get_c) money_get<char>(1)); - _M_init_facet(new (&money_put_c) money_put<char>(1)); - - typedef __timepunct_cache<char> time_cache_c; - time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2); - _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 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 _GLIBCXX_USE_WCHAR_T - _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1)); - _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1)); - - typedef __numpunct_cache<wchar_t> num_cache_w; - num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2); - _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 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)); - - typedef __moneypunct_cache<wchar_t> money_cache_w; - money_cache_w* __mpwf = new (&moneypunct_cache_wf) money_cache_w(2); - _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1)); - money_cache_w* __mpwt = new (&moneypunct_cache_wt) money_cache_w(2); - _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 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)); - - typedef __timepunct_cache<wchar_t> time_cache_w; - time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2); - _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 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 - - // This locale is safe to pre-cache, after all the facets have - // been created and installed. - _M_caches[numpunct<char>::id._M_id()] = __npc; - _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf; - _M_caches[moneypunct<char, true>::id._M_id()] = __mpct; - _M_caches[__timepunct<char>::id._M_id()] = __tpc; -#ifdef _GLIBCXX_USE_WCHAR_T - _M_caches[numpunct<wchar_t>::id._M_id()] = __npw; - _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf; - _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt; - _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw; -#endif - } - void locale::_Impl:: _M_replace_categories(const _Impl* __imp, category __cat) @@ -363,101 +290,4 @@ namespace std } } } - - void - locale::_Impl:: - _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp) - { - for (; *__idpp; ++__idpp) - _M_replace_facet(__imp, *__idpp); - } - - void - locale::_Impl:: - _M_replace_facet(const _Impl* __imp, const locale::id* __idp) - { - const size_t __index = __idp->_M_id(); - if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index]) - __throw_runtime_error("locale::_Impl::_M_replace_facet"); - _M_install_facet(__idp, __imp->_M_facets[__index]); - } - - void - locale::_Impl:: - _M_install_facet(const locale::id* __idp, const facet* __fp) - { - if (__fp) - { - size_t __index = __idp->_M_id(); - - // Check size of facet vector to ensure adequate room. - if (__index > _M_facets_size - 1) - { - const size_t __new_size = __index + 4; - - // New facet array. - const facet** __oldf = _M_facets; - const facet** __newf; - __newf = new const facet*[__new_size]; - for (size_t __i = 0; __i < _M_facets_size; ++__i) - __newf[__i] = _M_facets[__i]; - for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) - __newf[__i2] = 0; - - // New cache array. - const facet** __oldc = _M_caches; - const facet** __newc; - try - { - __newc = new const facet*[__new_size]; - } - catch(...) - { - delete [] __newf; - __throw_exception_again; - } - for (size_t __i = 0; __i < _M_facets_size; ++__i) - __newc[__i] = _M_caches[__i]; - for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) - __newc[__i2] = 0; - - _M_facets_size = __new_size; - _M_facets = __newf; - _M_caches = __newc; - delete [] __oldf; - delete [] __oldc; - } - - __fp->_M_add_reference(); - const facet*& __fpr = _M_facets[__index]; - if (__fpr) - { - // Replacing an existing facet. Order matters. - __fpr->_M_remove_reference(); - __fpr = __fp; - } - else - { - // Installing a newly created facet into an empty - // _M_facets container, say a newly-constructed, - // swanky-fresh _Impl. - _M_facets[__index] = __fp; - } - - // Ideally, it would be nice to only remove the caches that - // are now incorrect. However, some of the caches depend on - // multiple facets, and we only know about one facet - // here. It's no great loss: the first use of the new facet - // will create a new, correctly cached facet anyway. - for (size_t __i = 0; __i < _M_facets_size; ++__i) - { - const facet* __cpr = _M_caches[__i]; - if (__cpr) - { - __cpr->_M_remove_reference(); - _M_caches[__i] = 0; - } - } - } - } } // namespace std diff --git a/libstdc++-v3/src/wlocale-inst.cc b/libstdc++-v3/src/wlocale-inst.cc new file mode 100644 index 00000000000..fa5059dae92 --- /dev/null +++ b/libstdc++-v3/src/wlocale-inst.cc @@ -0,0 +1,39 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2002, 2003 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +// +// ISO C++ 14882: 22.1 Locales +// + +#include <bits/c++config.h> + +#ifdef _GLIBCXX_USE_WCHAR_T +#define C wchar_t +#include "locale-inst.cc" +#endif diff --git a/libstdc++-v3/src/wstring-inst.cc b/libstdc++-v3/src/wstring-inst.cc index bbfbe337eef..2bcdcfcd308 100644 --- a/libstdc++-v3/src/wstring-inst.cc +++ b/libstdc++-v3/src/wstring-inst.cc @@ -1,3 +1,36 @@ +// wide string support -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2002, 2003 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 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 +// 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. + +// +// ISO C++ 14882: 21 Strings library +// + #include <bits/c++config.h> #ifdef _GLIBCXX_USE_WCHAR_T |