Makefile.am: Add new files.

2003-10-17  Benjamin Kosnik  <bkoz@redhat.com>

	* src/Makefile.am: Add new files.
	* src/Makefile.in: Regenerate.
	* src/globals.cc: Split into..
	* src/globals_io.cc: New.
	* src/globals_locale.cc: New.
	* src/ios.cc: Split into...
	* src/ios_init.cc: New.
	* src/ios_locale.cc: New.
	* src/locale-inst.cc: Split into..
	* src/wlocale-inst.cc: New.
	* src/locale-misc-inst.cc: New.
	* src/locale.cc, src/localename: Split into...
	* src/locale_facets.cc: New.
	* src/locale_init.cc: New.
	* src/wstring-inst.cc: Add copyright info.

From-SVN: r72607
This commit is contained in:
Benjamin Kosnik 2003-10-17 14:47:30 +00:00 committed by Benjamin Kosnik
parent efc2515b49
commit c755e77d63
16 changed files with 1444 additions and 1315 deletions

View File

@ -1,3 +1,21 @@
2003-10-17 Benjamin Kosnik <bkoz@redhat.com>
* src/Makefile.am: Add new files.
* src/Makefile.in: Regenerate.
* src/globals.cc: Split into..
* src/globals_io.cc: New.
* src/globals_locale.cc: New.
* src/ios.cc: Split into...
* src/ios_init.cc: New.
* src/ios_locale.cc: New.
* src/locale-inst.cc: Split into..
* src/wlocale-inst.cc: New.
* src/locale-misc-inst.cc: New.
* src/locale.cc, src/localename: Split into...
* src/locale_facets.cc: New.
* src/locale_init.cc: New.
* src/wstring-inst.cc: Add copyright info.
2003-10-16 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/11450

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 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<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) 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&);
has_facet<ctype<C> >(const locale&);
template
bool
has_facet<codecvt<char, char, mbstate_t> >(const locale&);
has_facet<codecvt<C, char, mbstate_t> >(const locale&);
template
bool
has_facet<collate<char> >(const locale&);
has_facet<collate<C> >(const locale&);
template
bool
has_facet<numpunct<char> >(const locale&);
has_facet<numpunct<C> >(const locale&);
template
bool
has_facet<num_put<char> >(const locale&);
has_facet<num_put<C> >(const locale&);
template
bool
has_facet<num_get<char> >(const locale&);
has_facet<num_get<C> >(const locale&);
template
bool
has_facet<moneypunct<char> >(const locale&);
has_facet<moneypunct<C> >(const locale&);
template
bool
has_facet<money_put<char> >(const locale&);
has_facet<money_put<C> >(const locale&);
template
bool
has_facet<money_get<char> >(const locale&);
has_facet<money_get<C> >(const locale&);
template
bool
has_facet<__timepunct<char> >(const locale&);
has_facet<__timepunct<C> >(const locale&);
template
bool
has_facet<time_put<char> >(const locale&);
has_facet<time_put<C> >(const locale&);
template
bool
has_facet<time_get<char> >(const locale&);
has_facet<time_get<C> >(const locale&);
template
bool
has_facet<messages<char> >(const locale&);
has_facet<messages<C> >(const locale&);
#ifdef _GLIBCXX_USE_WCHAR_T
template
bool
has_facet<ctype<wchar_t> >(const locale&);
template
bool
has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
template
bool
has_facet<collate<wchar_t> >(const locale&);
template
bool
has_facet<numpunct<wchar_t> >(const locale&);
template
bool
has_facet<num_put<wchar_t> >(const locale&);
template
bool
has_facet<num_get<wchar_t> >(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> >;
#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 class __pad<C, char_traits<C> >;
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);
__int_to_char(C*, const int, unsigned long, const C*,
ios_base::fmtflags, bool);
#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*,
__int_to_char(C*, const int, unsigned long long, const C*,
ios_base::fmtflags, bool);
#ifdef _GLIBCXX_USE_WCHAR_T
template
int
__int_to_char(wchar_t*, const int, unsigned long, const wchar_t*,
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*,
ios_base::fmtflags, bool);
#endif
#endif
} // namespace std

View File

@ -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

View File

@ -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} };
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)
// locale::_Impl
locale::_Impl::
~_Impl() throw()
{
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++ = '#';
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;
// As per DR 231: _always_, not only when
// __flags & ios_base::fixed || __prec > 0
*__fptr++ = '.';
*__fptr++ = '*';
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 (__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';
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)
{
_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;
}
}
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)
{
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

View File

@ -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

View File

@ -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

View File

@ -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()
locale::locale(const char* __s)
{
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)
{
_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)
_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
{
_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;
// 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

View File

@ -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

View File

@ -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