gcc/libstdc++-v3/src/localename.cc
Benjamin Kosnik 7be50fd30f [multiple changes]
2000-07-20  Benjamin Kosnik  <bkoz@cygnus.com>

	* bits/std_streambuf.h: Add bits for pback buffers here, so that
	in_avail, etc can use them.
	* bits/std_fstream.h: Ditto.
	* bits/fstream.tcc: Ditto.
	* testsuite/27_io/filebuf.cc: Tweaks.
	* testsuite/27_io/filebuf-3.tst: Correct for pbackfail bits.

2000-07-19  Benjamin Kosnik  <bkoz@cygnus.com>

	* src/localename.cc: Same.
	* src/locale.cc: Same.
	* bits/localefwd.h: _M_init_facet to _M_facet_init.

	* bits/locale_facets.h: _M_init_boolnames to _M_boolnames_init.

	* bits/std_sstream.h: Change _M_init_stringbuf to _M_stringbuf_init.

	* bits/fstream.tcc: Change _M_init_filebuf to _M_filebuf_init.
	* bits/std_fstream.h: Same.

	* bits/basic_string.h: Tweaks.

From-SVN: r35157
2000-07-21 00:06:51 +00:00

251 lines
7.8 KiB
C++

// Copyright (C) 1997-1999 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/std_clocale.h>
#include <bits/std_locale.h>
#include <bits/std_cstring.h>
#include <bits/std_cassert.h>
#include <bits/std_vector.h>
namespace std {
/////////////////////////////
// locale::_Impl constructors
/////////////////////////////
// construct specific categories, leaving unselected ones alone
//////////
locale::_Impl::_Impl(const _Impl& other,const string& name, category cats,
size_t refs)
: _M_num_references(refs)
// , _M_facets(other._M_facets)
// , _M_category_names(other._M_category_names)
, _M_has_name(other._M_has_name), _M_cached_name_ok(false)
{
#if 1
typedef vector<facet*, allocator<facet*> > __vec_facet;
typedef vector<string, allocator<string> > __vec_string;
try {
_M_facets = new __vec_facet(*(other._M_facets));
}
catch (...) {
delete _M_facets;
throw;
}
try {
_M_category_names = new __vec_string(*(other._M_category_names));
}
catch (...) {
delete _M_category_names;
throw;
}
#endif
// XXX Nathan what are you doing here? Is this supposed to be const?
// static void(_Impl::* const ctors[]) (const char*) =
static void(_Impl::* ctors[]) (const char*) =
{
// NB: order must match the decl order in class locale.
&locale::_Impl::_M_construct_collate,
&locale::_Impl::_M_construct_ctype,
&locale::_Impl::_M_construct_monetary,
&locale::_Impl::_M_construct_numeric,
&locale::_Impl::_M_construct_time,
&locale::_Impl::_M_construct_messages,
0
};
_S_initialize();
std::vector<facet*>::iterator it = _M_facets->begin();
for (; it != _M_facets->end(); ++it)
(*it)->_M_add_reference();
try {
category classix = _S_normalize_category(cats); // might throw
_M_normalize_category_names(name, classix);
unsigned mask = (locale::all & -(unsigned)locale::all);
for (unsigned ix = 0; (-mask & cats) != 0; ++ix, (mask <<= 1))
{
if (!(mask & cats))
continue;
if (mask & classix)
_M_replace_category(_S_classic, _S_facet_categories[ix]);
else
(this->*ctors[ix]) (name.c_str());
}
}
catch (...) {
it = _M_facets->begin();
for (; it != _M_facets->end(); ++it)
(*it)->_M_remove_reference();
throw;
}
}
//////////
locale::category
locale::_Impl::_M_normalize_category_names(const string&,
locale::category cats)
{
// The problem to be solved here is that locale names
// generally have one of two forms: they might have
// only one component, such as "en_US"; or they might
// have six, such as "en_US fr_FR en_US C C C", where
// each component names a category. Each vendor has
// a different order of categories. Each vendor uses
// a different format:
// AIX uses "C C C C C C"
// Sun uses "/C/C/C/C/C/C"
// HP uses "/0:C;1:C;2:C;3:C;4:C;5:C;6:C;/"
// (where the 0th element is for LC_ALL.)
// Most systems (except AIX) permit the long form only for
// setlocale(LC_ALL,...), and require the short form for
// other calls. All this matters because locale names are
// supposed to be compatible between locale("") and
// setlocale(..., "") constructors.
return cats;
#if 0 /* XXX not done */
unsigned mask = (locale::all & -(unsigned)locale::all);
for (unsigned ix = 0; (-mask & cats) != 0; ++ix, (mask <<= 1))
{
}
#endif
}
//////////
void
locale::_Impl::_M_construct_collate(const char* /*name*/)
{
#if 0
_M_facet_init(new std::collate_byname<char>(name));
_M_facet_init(new std::collate_byname<wchar_t>(name));
#endif
}
void
locale::_Impl::_M_construct_ctype(const char* /*name*/)
{
#if 0
_M_facet_init(new std::ctype_byname<char>(name));
_M_facet_init(new std::ctype_byname<wchar_t>(name));
_M_facet_init(new std::codecvt_byname<char,char,mbstate_t>(name));
_M_facet_init(new std::codecvt_byname<wchar_t,char,mbstate_t>(name));
#endif
}
void
locale::_Impl::_M_construct_monetary(const char* /*name*/)
{
#if 0
_M_facet_init(new std::moneypunct_byname<char,false>(name));
_M_facet_init(new std::moneypunct_byname<wchar_t,false>(name));
_M_facet_init(new std::moneypunct_byname<char,true >(name));
_M_facet_init(new std::moneypunct_byname<wchar_t,true >(name));
locale::_M_initialize();
_M_replace_facet(locale::_S_classic, &std::money_get<char>(name)::id);
_M_replace_facet(locale::_S_classic, &std::money_get<wchar_t>(name)::id);
_M_replace_facet(locale::_S_classic, &std::money_put<char>(name)::id);
_M_replace_facet(locale::_S_classic, &std::money_put<wchar_t>(name)::id);
#endif
}
void
locale::_Impl::_M_construct_numeric(const char* /*name*/)
{
#if 0
_M_facet_init(new std::numpunct_byname<char>(name));
_M_facet_init(new std::numpunct_byname<wchar_t>(name));
locale::_M_initialize();
_M_replace_facet(locale::_S_classic, &std::num_get<char>::id);
_M_replace_facet(locale::_S_classic, &std::num_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &std::num_put<char>::id);
_M_replace_facet(locale::_S_classic, &std::num_put<wchar_t>::id);
#endif
}
void
locale::_Impl::_M_construct_time(const char* /*name*/)
{
#if 0
_M_facet_init(new std::time_get_byname<char>(name));
_M_facet_init(new std::time_get_byname<wchar_t>(name));
_M_facet_init(new std::time_put_byname<char>(name));
_M_facet_init(new std::time_put_byname<wchar_t>(name));
#endif
}
void
locale::_Impl::_M_construct_messages(const char* /*name*/)
{
#if 0
_M_facet_init(new std::messages_byname<char>(name));
_M_facet_init(new std::messages_byname<wchar_t>(name));
#endif
}
//////////////////////
// locale constructors
//////////////////////
////////
locale::locale(const char* std_name)
{
_S_initialize();
if (strcmp(std_name, "C") == 0 || strcmp(std_name, "POSIX"))
(_M_impl = _S_classic)->_M_add_reference();
else
{
// might throw:
_M_impl = new _Impl(*_S_classic, string(std_name), all, 1);
_M_impl->_M_has_name = true;
}
}
/////////
locale::locale(const locale& other, const char* std_name, category cats)
: _M_impl(new _Impl(*other._M_impl, string(std_name),
_S_normalize_category(cats), 1)) // might throw
{ }
///////
bool
locale::operator==(const locale& __rhs) const throw()
{
return(_M_impl == __rhs._M_impl
|| (this->name() != "*" && this->name() == __rhs.name()));
}
}