Commit 0214010c by Benjamin Kosnik

Preliminary named locales.


2001-01-29  Benjamin Kosnik  <bkoz@redhat.com>

	Preliminary named locales.
	* acinclude.m4 (GLIBCPP_ENABLE_CLOCALE): New macro.
	* aclocal.m4: Regenerate.
	* configure.in: Use it.
	* configure: Regerate.
	* src/Makefile.am (sources): Add c++locale.cc.
	(build_headers): Add c++locale.h.
	* src/Makefile.in: Regenerate.
	* config/c_locale_gnu.h: New file.
	* config/c_locale_gnu.cc: New file. Non-inline member functions
	for named locales, gnu-specific.
	* config/c_locale_generic.h: New file.
	* config/c_locale_generic.cc: New file. Non-inline member
	functions for named locales, generic version.
	* docs/html/configopts.html: Add documentation on new options.

	* include/bits/locale_facets.h (class _Messages): Remove.
	(class _Moneypunct): Remove.
	* src/locale-inst.cc: Remove.

	* include/bits/locale_facets.h (class _Collate): Remove.
	* src/locale-inst.cc (std): Remove.
	* src/locale.cc: And here.

	* include/bits/localefwd.h (locale::_M_coalesce): New
	function. Correctly put together multi-name locales.
	(_Impl(const _Impl&, category, size_t)): Remove.

	* include/bits/localefwd.h (locale::_Impl): Remove _M_construct_*
	member functions.
	(_M_normalize_category_names): Remove.
	(_M_replace_categories): Fix.

	* src/localename.cc (locale::_Impl::_M_construct_collate): Remove.
	(locale::_Impl::_M_construct_ctype): Remove.
	(locale::_Impl::_M_construct_monetary): Remove.
	(locale::_Impl::_M_construct_numeric): Remove.
	(locale::_Impl::_M_construct_time): Remove.
	(locale::_Impl::_M_construct_messages): Remove.

	* include/bits/locale_facets.h (_Bad_use_facet): Remove.
	(_Use_facet_failure_handle): Remove.
	* src/locale.cc: Remove definitions.
	* src/locale-inst.cc: And here.

	* testsuite/22_locale/ctor_copy_dtor.cc (test01): Fixup. Add tests.

	* src/localename.cc (locale::facet::_S_create_c_locale): Properly
	create and error-check underlying locale object.
	(locale::facet::_S_destroy_c_locale): Add, take care of properly
	tearing down underlying locale object.
	* include/bits/localefwd.h (locale::facet): Declare.
	* testsuite/22_locale/members.cc: Don't test "fr_FR" locale for
	correctness, as glibc apparently has incorrect info in it. Test
	with it when it works again.....

	* include/bits/localefwd.h (locale::_Impl::__vec_string):
	Remove. Number of categories is fixed at six, so just simplify and
	make this an array of strings.
	(locale::_Impl::_M_has_name): Remove.
	(locale::_Impl::_M_name): Remove.
	(locale::_Impl::_M_category_names): Turns into...
	(locale::_Impl::_M_names): ...this.
	(locale::_Impl::_M_has_same_name()): New function.
	* src/localename.cc (locale::_Impl::~_Impl()): Remove here.
	(locale::_Impl::_Impl(size_t __refs, string __str)): Simplify
	signature.
	* src/locale.cc (locale::name()): Construct mangled name
	accurately reflecting combined locale categories.

	* src/locale.cc (locale::classic()): Don't initialize here.
	* src/localename.cc (locale::_Impl::_Impl(size_t __num, size_t
	__refs, bool __has_name, string __str): Do it here.

	* include/bits/localefwd.h: _S_categories_num to
	_S_num_categories. _S_facets_num to _S_num_facets.
	(locale::id::id()): Explicitly set _M_index to zero.
	* src/locale.cc: Same.

	* src/locale.cc: (locale::locale(const char*)): Construct named
	locales uniquely.

	* src/locale.cc: Remove numpunct_byname ctors.
	* testsuite/22_locale/numpunct_byname.cc: New file.
	* testsuite/22_locale/numpunct.cc: New file.

	* include/bits/localefwd.h (class locale): Change data members to
	protected, from private.
	(_Impl::_M_get_c_locale): Add member function.
	(locale::facet::_M_get_global_impl()): Add member function.
	* include/bits/locale_facets.h (numpunct::_M_init): Change to take
	a __c_locale pointer.
	(numpunct::numpunct( __c_locale*, size_t)): Add additonal ctor for
	named locales.
	* testsuite/22_locale/members.cc: New file, test name and combine.

	* include/bits/locale_facets.h (class numpunct): Remove class
	_Punct and _Numpunct. Rewrite class numpunct to be correct for
	named locales.
	* include/bits/localefwd.h (locale::_Imp::_M_c_locale): Add.
	* src/localename.cc (_Impl::~_Impl()): Call __frelocale.
	(_Imp::_Impl(size_t, size_t, bool, string)) Initialize _M_c_locale.
	* src/locale-inst.cc: Remove _Numpunct, _Punct instantiations.
	* testsuite/22_locale/numpunct_char_members.cc: New file.

From-SVN: r39347
parent f25561bb
2001-01-29 Benjamin Kosnik <bkoz@redhat.com>
Preliminary named locales.
* acinclude.m4 (GLIBCPP_ENABLE_CLOCALE): New macro.
* aclocal.m4: Regenerate.
* configure.in: Use it.
* configure: Regerate.
* src/Makefile.am (sources): Add c++locale.cc.
(build_headers): Add c++locale.h.
* src/Makefile.in: Regenerate.
* config/c_locale_gnu.h: New file.
* config/c_locale_gnu.cc: New file. Non-inline member functions
for named locales, gnu-specific.
* config/c_locale_generic.h: New file.
* config/c_locale_generic.cc: New file. Non-inline member
functions for named locales, generic version.
* docs/html/configopts.html: Add documentation on new options.
* include/bits/locale_facets.h (class _Messages): Remove.
(class _Moneypunct): Remove.
* src/locale-inst.cc: Remove.
* include/bits/locale_facets.h (class _Collate): Remove.
* src/locale-inst.cc (std): Remove.
* src/locale.cc: And here.
* include/bits/localefwd.h (locale::_M_coalesce): New
function. Correctly put together multi-name locales.
(_Impl(const _Impl&, category, size_t)): Remove.
* include/bits/localefwd.h (locale::_Impl): Remove _M_construct_*
member functions.
(_M_normalize_category_names): Remove.
(_M_replace_categories): Fix.
* src/localename.cc (locale::_Impl::_M_construct_collate): Remove.
(locale::_Impl::_M_construct_ctype): Remove.
(locale::_Impl::_M_construct_monetary): Remove.
(locale::_Impl::_M_construct_numeric): Remove.
(locale::_Impl::_M_construct_time): Remove.
(locale::_Impl::_M_construct_messages): Remove.
* include/bits/locale_facets.h (_Bad_use_facet): Remove.
(_Use_facet_failure_handle): Remove.
* src/locale.cc: Remove definitions.
* src/locale-inst.cc: And here.
* testsuite/22_locale/ctor_copy_dtor.cc (test01): Fixup. Add tests.
* src/localename.cc (locale::facet::_S_create_c_locale): Properly
create and error-check underlying locale object.
(locale::facet::_S_destroy_c_locale): Add, take care of properly
tearing down underlying locale object.
* include/bits/localefwd.h (locale::facet): Declare.
* testsuite/22_locale/members.cc: Don't test "fr_FR" locale for
correctness, as glibc apparently has incorrect info in it. Test
with it when it works again.....
* include/bits/localefwd.h (locale::_Impl::__vec_string):
Remove. Number of categories is fixed at six, so just simplify and
make this an array of strings.
(locale::_Impl::_M_has_name): Remove.
(locale::_Impl::_M_name): Remove.
(locale::_Impl::_M_category_names): Turns into...
(locale::_Impl::_M_names): ...this.
(locale::_Impl::_M_has_same_name()): New function.
* src/localename.cc (locale::_Impl::~_Impl()): Remove here.
(locale::_Impl::_Impl(size_t __refs, string __str)): Simplify
signature.
* src/locale.cc (locale::name()): Construct mangled name
accurately reflecting combined locale categories.
* src/locale.cc (locale::classic()): Don't initialize here.
* src/localename.cc (locale::_Impl::_Impl(size_t __num, size_t
__refs, bool __has_name, string __str): Do it here.
* include/bits/localefwd.h: _S_categories_num to
_S_num_categories. _S_facets_num to _S_num_facets.
(locale::id::id()): Explicitly set _M_index to zero.
* src/locale.cc: Same.
* src/locale.cc: (locale::locale(const char*)): Construct named
locales uniquely.
* src/locale.cc: Remove numpunct_byname ctors.
* testsuite/22_locale/numpunct_byname.cc: New file.
* testsuite/22_locale/numpunct.cc: New file.
* include/bits/localefwd.h (class locale): Change data members to
protected, from private.
(_Impl::_M_get_c_locale): Add member function.
(locale::facet::_M_get_global_impl()): Add member function.
* include/bits/locale_facets.h (numpunct::_M_init): Change to take
a __c_locale pointer.
(numpunct::numpunct( __c_locale*, size_t)): Add additonal ctor for
named locales.
* testsuite/22_locale/members.cc: New file, test name and combine.
* include/bits/locale_facets.h (class numpunct): Remove class
_Punct and _Numpunct. Rewrite class numpunct to be correct for
named locales.
* include/bits/localefwd.h (locale::_Imp::_M_c_locale): Add.
* src/localename.cc (_Impl::~_Impl()): Call __frelocale.
(_Imp::_Impl(size_t, size_t, bool, string)) Initialize _M_c_locale.
* src/locale-inst.cc: Remove _Numpunct, _Punct instantiations.
* testsuite/22_locale/numpunct_char_members.cc: New file.
2001-01-28 Gabriel Dos Reis <gdr@codesourcery.com> 2001-01-28 Gabriel Dos Reis <gdr@codesourcery.com>
* testsuite/README: Add more comment. * testsuite/README: Add more comment.
......
...@@ -1055,6 +1055,51 @@ AC_SUBST(EXTRA_CXX_FLAGS) ...@@ -1055,6 +1055,51 @@ AC_SUBST(EXTRA_CXX_FLAGS)
dnl dnl
dnl Check for which locale library to use: gnu or generic.
dnl
dnl GLIBCPP_ENABLE_CLOCALE
dnl --enable-clocale=gnu sets config/c_locale_gnu.cc and friends
dnl --enable-clocale=generic sets config/c_locale_generic.cc and friends
dnl
dnl default is generic
dnl
AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
AC_MSG_CHECKING([for clocale to use])
AC_ARG_ENABLE(clocale,
[ --enable-clocale enable model for target locale package.
--enable-clocale=MODEL use MODEL target-speific locale package. [default=generic]
],
if test x$enable_clocale = xno; then
enable_clocale=generic
fi,
enable_clocale=generic)
enable_clocale_flag=$enable_clocale
dnl Check if a valid locale package
case x${enable_clocale_flag} in
xgnu)
CLOCALE_H=config/c_locale_gnu.h
CLOCALE_CC=config/c_locale_gnu.cc
AC_MSG_RESULT(gnu)
;;
xgeneric)
CLOCALE_H=config/c_locale_generic.h
CLOCALE_CC=config/c_locale_generic.cc
AC_MSG_RESULT(generic)
;;
*)
echo "$enable_clocale is an unknown locale package" 1>&2
exit 1
;;
esac
AC_LINK_FILES($CLOCALE_H, include/bits/c++locale.h)
AC_LINK_FILES($CLOCALE_CC, src/c++locale.cc)
])
dnl
dnl Check for which I/O library to use: libio, or something specific. dnl Check for which I/O library to use: libio, or something specific.
dnl dnl
dnl GLIBCPP_ENABLE_CSTDIO dnl GLIBCPP_ENABLE_CSTDIO
......
...@@ -1067,6 +1067,51 @@ AC_SUBST(EXTRA_CXX_FLAGS) ...@@ -1067,6 +1067,51 @@ AC_SUBST(EXTRA_CXX_FLAGS)
dnl dnl
dnl Check for which locale library to use: gnu or generic.
dnl
dnl GLIBCPP_ENABLE_CLOCALE
dnl --enable-clocale=gnu sets config/c_locale_gnu.cc and friends
dnl --enable-clocale=generic sets config/c_locale_generic.cc and friends
dnl
dnl default is generic
dnl
AC_DEFUN(GLIBCPP_ENABLE_CLOCALE, [
AC_MSG_CHECKING([for clocale to use])
AC_ARG_ENABLE(clocale,
[ --enable-clocale enable model for target locale package.
--enable-clocale=MODEL use MODEL target-speific locale package. [default=generic]
],
if test x$enable_clocale = xno; then
enable_clocale=generic
fi,
enable_clocale=generic)
enable_clocale_flag=$enable_clocale
dnl Check if a valid locale package
case x${enable_clocale_flag} in
xgnu)
CLOCALE_H=config/c_locale_gnu.h
CLOCALE_CC=config/c_locale_gnu.cc
AC_MSG_RESULT(gnu)
;;
xgeneric)
CLOCALE_H=config/c_locale_generic.h
CLOCALE_CC=config/c_locale_generic.cc
AC_MSG_RESULT(generic)
;;
*)
echo "$enable_clocale is an unknown locale package" 1>&2
exit 1
;;
esac
AC_LINK_FILES($CLOCALE_H, include/bits/c++locale.h)
AC_LINK_FILES($CLOCALE_CC, src/c++locale.cc)
])
dnl
dnl Check for which I/O library to use: libio, or something specific. dnl Check for which I/O library to use: libio, or something specific.
dnl dnl
dnl GLIBCPP_ENABLE_CSTDIO dnl GLIBCPP_ENABLE_CSTDIO
......
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001 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.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#include <locale>
#include <langinfo.h>
namespace std
{
void
locale::facet::_S_create_c_locale(__c_locale& /*__cloc*/, const char*)
{ }
void
locale::facet::_S_destroy_c_locale(__c_locale& /*__cloc*/)
{ }
template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_truename = "true";
_M_falsename = "false";
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_truename = L"true";
_M_falsename = L"false";
}
#endif
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
#endif
} // namespace std
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001 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.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std
{
typedef int* __c_locale;
}
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001 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.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#include <locale>
#include <stdexcept>
#include <langinfo.h>
namespace std
{
void
locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s)
{
// XXX
// perhaps locale::categories could be made equivalent to LC_*_MASK
// _M_c_locale = __newlocale(1 << LC_ALL, __str.c_str(), NULL);
// _M_c_locale = __newlocale(locale::all, __str.c_str(), NULL);
__cloc = __newlocale(LC_ALL, __s, NULL);
if (!__cloc)
{
// This named locale is not supported by the underlying OS.
throw runtime_error("attempt to create locale from unknown name");
}
}
void
locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
{
if (__cloc)
__freelocale(__cloc);
}
template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
{
if (!__cloc)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
}
else
{
// Named locale.
_M_decimal_point = *(__nl_langinfo_l(RADIXCHAR, __cloc));
_M_thousands_sep = *(__nl_langinfo_l(THOUSEP, __cloc));
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
}
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_truename = "true";
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
_M_falsename = "false";
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
{
if (!__cloc)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
}
else
{
// Named locale.
_M_decimal_point = reinterpret_cast<wchar_t>(__nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc));
_M_thousands_sep = reinterpret_cast<wchar_t>(__nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC,__cloc));
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
}
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_truename = L"true";
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
_M_falsename = L"false";
}
#endif
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale __cloc)
{
if (!__cloc)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
else
{
// Named locale.
_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, __cloc));
_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, __cloc));
_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
if (intl)
{
_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, __cloc));
char __ppreceeds = *(__nl_langinfo_l(__INT_P_CS_PRECEDES,
__cloc));
char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
_M_pos_format = _S_construct_pattern(__ppreceeds, __pspace,
__pposn);
char __npreceeds = *(__nl_langinfo_l(__INT_N_CS_PRECEDES,
__cloc));
char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
_M_neg_format = _S_construct_pattern(__npreceeds, __nspace,
__nposn);
}
else
{
_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
char __ppreceeds = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
_M_pos_format = _S_construct_pattern(__ppreceeds, __pspace,
__pposn);
char __npreceeds = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
_M_neg_format = _S_construct_pattern(__npreceeds, __nspace,
__nposn);
}
}
}
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// XXX implement
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
#endif
} // namespace std
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001 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.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std
{
typedef __locale_t __c_locale;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -35,6 +35,7 @@ GLIBCPP_CHECK_COMPILER_VERSION ...@@ -35,6 +35,7 @@ GLIBCPP_CHECK_COMPILER_VERSION
# Enable all the crazy c++ stuff. C_MBCHAR must come early. # Enable all the crazy c++ stuff. C_MBCHAR must come early.
GLIBCPP_ENABLE_DEBUG($USE_MAINTAINER_MODE) GLIBCPP_ENABLE_DEBUG($USE_MAINTAINER_MODE)
GLIBCPP_ENABLE_CSTDIO GLIBCPP_ENABLE_CSTDIO
GLIBCPP_ENABLE_CLOCALE
GLIBCPP_ENABLE_C_MBCHAR([yes]) GLIBCPP_ENABLE_C_MBCHAR([yes])
GLIBCPP_ENABLE_LONG_LONG([no]) GLIBCPP_ENABLE_LONG_LONG([no])
GLIBCPP_ENABLE_CHEADERS([c_std]) GLIBCPP_ENABLE_CHEADERS([c_std])
......
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
</H1> </H1>
</HEAD> </HEAD>
<I> <I>
prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000 prepared by Benjamin Kosnik (bkoz@redhat.com) on January 24, 2001
</I> </I>
<P> <P>
<H2> <H2>
1. Abstract 1. Abstract Describes the basic locale object, including nested
classes id, facet, and the reference-counted implementation object,
class _Impl.
</H2> </H2>
<P> <P>
</P> </P>
...@@ -18,6 +20,7 @@ prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000 ...@@ -18,6 +20,7 @@ prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000
<P> <P>
<H2> <H2>
2. What the standard says 2. What the standard says
See Chapter 22 of the standard.
</H2> </H2>
...@@ -27,17 +30,44 @@ prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000 ...@@ -27,17 +30,44 @@ prepared by Benjamin Kosnik (bkoz@redhat.com) on September 15, 2000
</H2> </H2>
<P> <P>
For the required specialization codecvt&lt;wchar_t, char, mbstate_t&gt; , The major problem is fitting an object-orientated and non-global locale
conversions are made between the internal character set (always UCS4 design ontop of POSIX and other relevant stanards, which include the
on GNU/Linux) and whatever the currently selected locale for the Single Unix (nee X/Open.)
LC_CTYPE category implements.
Because POSIX falls down so completely, portibility is an issue.
<P> <P>
<H2> <H2>
4. Design 4. Design
</H2> </H2>
The two required specializations are implemented as follows: Class locale in non-templatized and has three distinct types nested
inside of it:
class facet
22.1.1.1.2 Class locale::facet
Facets actually implement locale functionality. For instance, a facet
called numpunct is the data objects that can be used to query for the
thousands seperator is in the German locale.
Literally, a facet is strictly defined:
- containing
public:
static locale::id id;
- or derived from another facet
The only other thing of interest in this class is the memory
management of facets. Each constructor of a facet class takes a
std::size_t __refs argument: if __refs == 0, the facet is deleted when
no longer used. if __refs == 1, the facet is not destroyed, even when
it is no longer reference.
class id
Provides an index for looking up specific facets.
class _Impl
<P> <P>
<H2> <H2>
...@@ -45,7 +75,7 @@ The two required specializations are implemented as follows: ...@@ -45,7 +75,7 @@ The two required specializations are implemented as follows:
</H2> </H2>
<pre> <pre>
typedef ctype<char> cctype; typedef __locale_t locale;
</pre> </pre>
More information can be found in the following testcases: More information can be found in the following testcases:
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<META NAME="GENERATOR" CONTENT="vi and eight fingers"> <META NAME="GENERATOR" CONTENT="vi and eight fingers">
<TITLE>libstdc++-v3 configure options</TITLE> <TITLE>libstdc++-v3 configure options</TITLE>
<LINK REL=StyleSheet HREF="lib3styles.css"> <LINK REL=StyleSheet HREF="lib3styles.css">
<!-- $Id: configopts.html,v 1.3 2001/01/03 15:53:27 bkoz Exp $ --> <!-- $Id: configopts.html,v 1.4 2001/01/21 09:36:09 pme Exp $ -->
</HEAD> </HEAD>
<BODY> <BODY>
...@@ -69,6 +69,21 @@ options</A></H1> ...@@ -69,6 +69,21 @@ options</A></H1>
abstraction. The default is 'stdio'. abstraction. The default is 'stdio'.
</P> </P>
<DT><TT>--enable-clocale </TT>
<DD><P>This is an abbreviated form of <TT>'--enable-clocale=generic'</TT>
(described next).
</P>
<DT><TT>--enable-clocale=MODEL </TT>
<DD><P>Select a target-specific underlying locale package. The
choices are 'gnu' to specify an X/Open (IEEE Std. 1003.1-200x)
model based on langinfo/iconv (from <A
HREF="http://sources.redhat.com/glibc/">glibc</A>, the GNU C
library), or 'generic' to use a generic &quot;C&quot;
abstraction which consists of "C" locale info. The default is
'generic'.
</P>
<DT><TT>--enable-long-long </TT> <DT><TT>--enable-long-long </TT>
<DD><P>The &quot;long long&quot; type was introduced in C99. It is <DD><P>The &quot;long long&quot; type was introduced in C99. It is
provided as a GNU extension to C++98 in g++. This flag builds provided as a GNU extension to C++98 in g++. This flag builds
...@@ -178,7 +193,7 @@ options</A></H1> ...@@ -178,7 +193,7 @@ options</A></H1>
<HR> <HR>
<P CLASS="fineprint"><EM> <P CLASS="fineprint"><EM>
$Id: configopts.html,v 1.3 2001/01/03 15:53:27 bkoz Exp $ $Id: configopts.html,v 1.4 2001/01/21 09:36:09 pme Exp $
</EM></P> </EM></P>
......
// Locale support -*- C++ -*- // Locale support -*- C++ -*-
// Copyright (C) 1997-2000 Free Software Foundation, Inc. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -37,49 +37,15 @@ ...@@ -37,49 +37,15 @@
#define _CPP_BITS_LOCFACETS_H 1 #define _CPP_BITS_LOCFACETS_H 1
#include <bits/std_ctime.h> // For struct tm #include <bits/std_ctime.h> // For struct tm
#include <typeinfo> // For bad_cast, which shouldn't be here.
#include <bits/std_ios.h> // For ios_base #include <bits/std_ios.h> // For ios_base
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
# include <langinfo.h> // For codecvt
# include <bits/std_cwctype.h> // For wctype_t # include <bits/std_cwctype.h> // For wctype_t
# include <iconv.h> // For codecvt using iconv, iconv_t # include <iconv.h> // For codecvt using iconv, iconv_t
# include <langinfo.h> // For codecvt using nl_langinfo
#endif #endif
namespace std namespace std
{ {
// XXX This function is to be specialized for the "required" facets to
// be constructed lazily. The specializations must be declared after
// the definitions of the facets themselves; but they shouldn't be
// inline. Corresponding new's in locale::classic() should then be
// eliminated. Note that ctype<> should not get this treatment;
// see the use_facet<> specializations below.
//
struct _Bad_use_facet : public bad_cast
{
_Bad_use_facet() throw() {}
_Bad_use_facet(_Bad_use_facet const& __b) throw()
: bad_cast(__b) { }
_Bad_use_facet&
operator=(_Bad_use_facet const& __b) throw()
{
static_cast<bad_cast*>(this)->operator=(__b);
return *this;
}
virtual char const*
what() const throw();
virtual
~_Bad_use_facet() throw();
};
template<typename _Facet>
const _Facet&
_Use_facet_failure_handler(const locale&)
{ throw _Bad_use_facet(); }
// 22.2.1.1 Template class ctype // 22.2.1.1 Template class ctype
// Include host-specific ctype enums for ctype_base. // Include host-specific ctype enums for ctype_base.
#include <bits/ctype_base.h> #include <bits/ctype_base.h>
...@@ -809,12 +775,30 @@ namespace std ...@@ -809,12 +775,30 @@ namespace std
locale::id num_put<_CharT, _OutIter>::id; locale::id num_put<_CharT, _OutIter>::id;
template<typename _CharT> template<typename _CharT>
class _Punct : public locale::facet class numpunct : public locale::facet
{ {
public: public:
// Types: // Types:
typedef _CharT char_type; typedef _CharT char_type;
typedef basic_string<_CharT> string_type; typedef basic_string<_CharT> string_type;
static locale::id id;
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
string _M_grouping;
string_type _M_truename;
string_type _M_falsename;
public:
explicit
numpunct(size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_numpunct(); }
explicit
numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_numpunct(__cloc); }
char_type char_type
decimal_point() const decimal_point() const
...@@ -827,13 +811,18 @@ namespace std ...@@ -827,13 +811,18 @@ namespace std
string string
grouping() const grouping() const
{ return do_grouping(); } { return do_grouping(); }
protected:
explicit string_type
_Punct(size_t __refs = 0) : locale::facet(__refs) { } truename() const
{ return do_truename(); }
string_type
falsename() const
{ return do_falsename(); }
protected:
virtual virtual
~_Punct() { } ~numpunct() { }
virtual char_type virtual char_type
do_decimal_point() const do_decimal_point() const
...@@ -843,49 +832,10 @@ namespace std ...@@ -843,49 +832,10 @@ namespace std
do_thousands_sep() const do_thousands_sep() const
{ return _M_thousands_sep; } { return _M_thousands_sep; }
virtual string virtual string
do_grouping() const do_grouping() const
{ return _M_grouping; } { return _M_grouping; }
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
string _M_grouping;
protected:
// for use at construction time only:
void
_M_init(char_type __d, char_type __t, const string& __g)
{
_M_decimal_point = __d;
_M_thousands_sep = __t;
_M_grouping = __g;
}
};
template<typename _CharT>
class _Numpunct : public _Punct<_CharT>
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
string_type
truename() const
{ return do_truename(); }
string_type
falsename() const
{ return do_falsename(); }
protected:
explicit
_Numpunct(size_t __refs = 0) : _Punct<_CharT> (__refs) { }
virtual
~_Numpunct() { }
virtual string_type virtual string_type
do_truename() const do_truename() const
{ return _M_truename; } { return _M_truename; }
...@@ -894,86 +844,67 @@ namespace std ...@@ -894,86 +844,67 @@ namespace std
do_falsename() const do_falsename() const
{ return _M_falsename; } { return _M_falsename; }
private: // For use at construction time only.
string_type _M_truename;
string_type _M_falsename;
protected:
// For use only during construction
void void
_M_boolnames_init(const string_type& __t, const string_type& __f) _M_initialize_numpunct(__c_locale __cloc = NULL);
{
_M_truename = __t;
_M_falsename = __f;
}
};
template<typename _CharT>
class numpunct : public _Numpunct<_CharT>
{
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
numpunct(size_t __refs = 0) : _Numpunct<_CharT>(__refs) { }
protected:
virtual
~numpunct() { }
}; };
template<typename _CharT> template<typename _CharT>
locale::id numpunct<_CharT>::id; locale::id numpunct<_CharT>::id;
template<> template<typename _CharT>
numpunct<char>::numpunct(size_t __refs): _Numpunct<char>(__refs) void
{ numpunct<_CharT>::_M_initialize_numpunct(__c_locale /*__cloc*/)
_M_init('.', ',', ""); {
_M_boolnames_init("true", "false"); // NB: Cannot be made generic.
} }
template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template<> template<>
numpunct<wchar_t>::numpunct(size_t __refs): _Numpunct<wchar_t>(__refs) void
{ numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
_M_init(L'.', L',', "");
_M_boolnames_init(L"true", L"false");
}
#endif #endif
template<typename _CharT> template<typename _CharT>
class numpunct_byname : public numpunct<_CharT> class numpunct_byname : public numpunct<_CharT>
{ {
__c_locale _M_c_locale_numpunct;
public: public:
typedef _CharT char_type; typedef _CharT char_type;
typedef basic_string<_CharT> string_type; typedef basic_string<_CharT> string_type;
explicit explicit
numpunct_byname(const char*, size_t __refs = 0); numpunct_byname(const char* __s, size_t __refs = 0)
: numpunct<_CharT>(__refs)
{
_S_create_c_locale(_M_c_locale_numpunct, __s);
_M_initialize_numpunct(_M_c_locale_numpunct);
}
protected: protected:
virtual virtual
~numpunct_byname() { } ~numpunct_byname()
{ _S_destroy_c_locale(_M_c_locale_numpunct); }
}; };
template<>
numpunct_byname<char>::numpunct_byname(const char*, size_t __refs);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
numpunct_byname<wchar_t>::numpunct_byname(const char*, size_t __refs);
#endif
template<typename _CharT> template<typename _CharT>
class _Collate : public locale::facet class collate : public locale::facet
{ {
public: public:
// Types: // Types:
typedef _CharT char_type; typedef _CharT char_type;
typedef basic_string<_CharT> string_type; typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
collate(size_t __refs = 0) : locale::facet(__refs) { }
int int
compare(const _CharT* __lo1, const _CharT* __hi1, compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const const _CharT* __lo2, const _CharT* __hi2) const
...@@ -988,99 +919,50 @@ namespace std ...@@ -988,99 +919,50 @@ namespace std
{ return do_hash(__lo, __hi); } { return do_hash(__lo, __hi); }
protected: protected:
explicit ~collate() { } // virtual
_Collate(size_t __refs = 0) : locale::facet(__refs) { }
~_Collate() { } // virtual
virtual int virtual int
do_compare(const _CharT* __lo1, const _CharT* __hi1, do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const = 0; const _CharT* __lo2, const _CharT* __hi2) const;
virtual string_type virtual string_type
do_transform(const _CharT* __lo, const _CharT* __hi) const = 0; do_transform(const _CharT* __lo, const _CharT* __hi) const;
virtual long virtual long
do_hash(const _CharT* __lo, const _CharT* __hi) const = 0; do_hash(const _CharT* __lo, const _CharT* __hi) const;
};
template<typename _CharT>
class collate : public _Collate<_CharT>
{
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
explicit
collate(size_t __refs = 0) : _Collate<_CharT> (__refs) { }
static locale::id id;
protected:
virtual
~collate() { }
}; };
template<typename _CharT> template<typename _CharT>
locale::id collate<_CharT>::id; locale::id collate<_CharT>::id;
// Required specializations.
template<> template<>
class collate<char> : public _Collate<char> int
{ collate<char>::do_compare(const char* __lo1, const char* __hi1,
public: const char* __lo2, const char* __hi2) const;
// Types:
typedef char char_type;
typedef basic_string<char> string_type;
explicit
collate(size_t __refs = 0);
static locale::id id; template<>
string
protected: collate<char>::do_transform(const char* __lo, const char* __hi) const;
virtual
~collate();
virtual int
do_compare(const char* __lo1, const char* __hi1,
const char* __lo2, const char* __hi2) const;
virtual string_type
do_transform(const char* __lo, const char* __hi) const;
virtual long
do_hash(const char* __lo, const char* __hi) const;
};
template<>
long
collate<char>::do_hash(const char* __lo, const char* __hi) const;
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template<> template<>
class collate<wchar_t> : public _Collate<wchar_t> int
{ collate<wchar_t>::do_compare(const wchar_t* __lo1, const wchar_t* __hi1,
public: const wchar_t* __lo2,
// Types: const wchar_t* __hi2) const;
typedef wchar_t char_type;
typedef basic_string<wchar_t> string_type;
explicit
collate(size_t __refs = 0);
static locale::id id; template<>
wstring
protected: collate<wchar_t>::do_transform(const wchar_t* __lo,
virtual const wchar_t* __hi) const;
~collate();
virtual int
do_compare(const wchar_t* __lo1, const wchar_t* __hi1,
const wchar_t* __lo2, const wchar_t* __hi2) const;
virtual string_type
do_transform(const wchar_t* __lo, const wchar_t* __hi) const;
virtual long template<>
do_hash(const wchar_t* __lo, const wchar_t* __hi) const; long
}; collate<wchar_t>::do_hash(const wchar_t* __lo, const wchar_t* __hi) const;
#endif #endif
template<typename _CharT> template<typename _CharT>
...@@ -1356,17 +1238,58 @@ namespace std ...@@ -1356,17 +1238,58 @@ namespace std
struct pattern { char field[4]; }; struct pattern { char field[4]; };
static const pattern _S_default_pattern; static const pattern _S_default_pattern;
// Construct and return valid pattern consisting of some combination of:
// space none symbol sign value
static pattern
_S_construct_pattern(char __preceeds, char __space, char __posn);
}; };
template<typename _CharT> template<typename _CharT, bool _Intl>
class _Moneypunct : public _Punct<_CharT>, public money_base class moneypunct : public locale::facet, public money_base
{ {
public: public:
typedef _CharT char_type; // Types:
typedef basic_string<_CharT> string_type; typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static const bool intl = _Intl;
static locale::id id;
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
string _M_grouping;
string_type _M_curr_symbol;
string_type _M_positive_sign;
string_type _M_negative_sign;
int _M_frac_digits;
pattern _M_pos_format;
pattern _M_neg_format;
public:
explicit
moneypunct(size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_moneypunct(); }
explicit
moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
{ _M_initialize_moneypunct(__cloc); }
char_type
decimal_point() const
{ return decimal_point(); }
char_type
thousands_sep() const
{ return thousands_sep(); }
string
grouping() const
{ return grouping(); }
string_type string_type
curr_symbol() const curr_symbol() const
{ return do_curr_symbol(); } { return do_curr_symbol(); }
string_type string_type
...@@ -1378,66 +1301,60 @@ namespace std ...@@ -1378,66 +1301,60 @@ namespace std
{ return do_negative_sign(); } { return do_negative_sign(); }
int int
frac_digits() const frac_digits() const
{ return do_frac_digits(); } { return do_frac_digits(); }
pattern pattern
pos_format() const pos_format() const
{ return do_pos_format(); } { return do_pos_format(); }
pattern pattern
neg_format() const neg_format() const
{ return do_neg_format(); } { return do_neg_format(); }
protected: protected:
explicit
_Moneypunct(size_t __refs = 0) : _Punct<_CharT> (__refs) { }
virtual virtual
~_Moneypunct() { } ~moneypunct() { }
virtual char_type
do_decimal_point() const
{ return _M_decimal_point; }
virtual char_type
do_thousands_sep() const
{ return _M_thousands_sep; }
virtual string
do_grouping() const
{ return _M_grouping; }
virtual string_type virtual string_type
do_curr_symbol() const do_curr_symbol() const
{ return basic_string<_CharT>(); } { return _M_curr_symbol; }
virtual string_type virtual string_type
do_positive_sign() const do_positive_sign() const
{ return basic_string<_CharT>(); } { return _M_positive_sign; }
virtual string_type virtual string_type
do_negative_sign() const do_negative_sign() const
{ return basic_string<_CharT>(); } { return _M_negative_sign; }
virtual int virtual int
do_frac_digits() const do_frac_digits() const
{ return 0; } { return _M_frac_digits; }
virtual pattern virtual pattern
do_pos_format() const do_pos_format() const
{ return money_base::_S_default_pattern; } { return _M_pos_format; }
virtual pattern virtual pattern
do_neg_format() const do_neg_format() const
{ return money_base::_S_default_pattern; } { return _M_neg_format; }
};
template<typename _CharT, bool _Intl> // For use at construction time only.
class moneypunct : public _Moneypunct<_CharT> void
{ _M_initialize_moneypunct(__c_locale __cloc = NULL);
public:
// Types:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static const bool intl = _Intl;
static locale::id id;
explicit
moneypunct(size_t __refs = 0) : _Moneypunct<_CharT> (__refs) { }
protected:
virtual
~moneypunct() { }
}; };
template<typename _CharT, bool _Intl> template<typename _CharT, bool _Intl>
...@@ -1447,38 +1364,48 @@ namespace std ...@@ -1447,38 +1364,48 @@ namespace std
const bool moneypunct<_CharT, _Intl>::intl; const bool moneypunct<_CharT, _Intl>::intl;
template<typename _CharT, bool _Intl> template<typename _CharT, bool _Intl>
class moneypunct_byname : public moneypunct<_CharT,_Intl> void
moneypunct<_CharT, _Intl>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// NB: Cannot be made generic.
}
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale __cloc);
#endif
template<typename _CharT, bool _Intl>
class moneypunct_byname : public moneypunct<_CharT, _Intl>
{ {
__c_locale _M_c_locale_moneypunct;
public: public:
typedef _CharT char_type; typedef _CharT char_type;
typedef basic_string<_CharT> string_type; typedef basic_string<_CharT> string_type;
static const bool intl = _Intl; static const bool intl = _Intl;
explicit explicit
moneypunct_byname(const char*, size_t __refs = 0); moneypunct_byname(const char* __s, size_t __refs = 0)
: moneypunct<_CharT, _Intl>(__refs)
{
_S_create_c_locale(_M_c_locale_moneypunct, __s);
_M_initialize_moneypunct(_M_c_locale_moneypunct);
}
protected: protected:
virtual virtual
~moneypunct_byname() { } ~moneypunct_byname()
{ _S_destroy_c_locale(_M_c_locale_moneypunct); }
}; };
template<typename _CharT, bool _Intl> template<typename _CharT, bool _Intl>
const bool moneypunct_byname<_CharT, _Intl>::intl; const bool moneypunct_byname<_CharT, _Intl>::intl;
template<>
moneypunct_byname<char, false>::
moneypunct_byname(const char*, size_t __refs);
template<>
moneypunct_byname<char, true>::
moneypunct_byname(const char*, size_t __refs);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
moneypunct_byname<wchar_t,false>::
moneypunct_byname(const char*, size_t __refs);
template<>
moneypunct_byname<wchar_t,true>::
moneypunct_byname (const char*, size_t __refs);
#endif
struct messages_base struct messages_base
{ {
...@@ -1486,11 +1413,16 @@ namespace std ...@@ -1486,11 +1413,16 @@ namespace std
}; };
template<typename _CharT> template<typename _CharT>
class _Messages : public locale::facet, public messages_base class messages : public locale::facet, public messages_base
{ {
public: public:
typedef _CharT char_type; typedef _CharT char_type;
typedef basic_string<_CharT> string_type; typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
messages(size_t __refs = 0) : locale::facet(__refs) { }
catalog catalog
open(const basic_string<char>& __s, const locale& __loc) const open(const basic_string<char>& __s, const locale& __loc) const
...@@ -1505,11 +1437,8 @@ namespace std ...@@ -1505,11 +1437,8 @@ namespace std
{ return do_close(__c); } { return do_close(__c); }
protected: protected:
explicit
_Messages(size_t __refs = 0) : locale::facet(__refs) { }
virtual virtual
~_Messages() { } ~messages() { }
// NB: Probably these should be pure, and implemented only in // NB: Probably these should be pure, and implemented only in
// specializations of messages<>. But for now... // specializations of messages<>. But for now...
...@@ -1522,22 +1451,7 @@ namespace std ...@@ -1522,22 +1451,7 @@ namespace std
{ return __dfault; } { return __dfault; }
virtual void virtual void
do_close (catalog) const { } do_close(catalog) const { }
};
template<typename _CharT>
class messages : public _Messages<_CharT>
{
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
static locale::id id;
explicit
messages(size_t __refs = 0) : _Messages<_CharT> (__refs) { }
protected:
virtual
~messages() { }
}; };
template<typename _CharT> template<typename _CharT>
......
// Locale support -*- C++ -*- // Locale support -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -39,8 +39,10 @@ ...@@ -39,8 +39,10 @@
#include <bits/std_memory.h> // For auto_ptr #include <bits/std_memory.h> // For auto_ptr
#include <bits/sbuf_iter.h> // For streambuf_iterators #include <bits/sbuf_iter.h> // For streambuf_iterators
#include <bits/std_cctype.h> // For isspace #include <bits/std_cctype.h> // For isspace
#include <typeinfo> // For bad_cast
#include <bits/std_vector.h> #include <bits/std_vector.h>
namespace std namespace std
{ {
template<typename _Facet> template<typename _Facet>
...@@ -49,7 +51,6 @@ namespace std ...@@ -49,7 +51,6 @@ namespace std
{ {
locale __copy(*this); locale __copy(*this);
__copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id); __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id);
__copy._M_impl->_M_has_name = false;
return __copy; return __copy;
} }
...@@ -58,8 +59,6 @@ namespace std ...@@ -58,8 +59,6 @@ namespace std
locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
const basic_string<_CharT, _Traits, _Alloc>& __s2) const const basic_string<_CharT, _Traits, _Alloc>& __s2) const
{ {
// XXX should not need to qualify here.
// typedef collate<_CharT> __collate_type;
typedef std::collate<_CharT> __collate_type; typedef std::collate<_CharT> __collate_type;
const __collate_type* __fcoll = &use_facet<__collate_type>(*this); const __collate_type* __fcoll = &use_facet<__collate_type>(*this);
return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(), return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(),
...@@ -71,12 +70,12 @@ namespace std ...@@ -71,12 +70,12 @@ namespace std
use_facet(const locale& __loc) use_facet(const locale& __loc)
{ {
typedef locale::_Impl::__vec_facet __vec_facet; typedef locale::_Impl::__vec_facet __vec_facet;
locale::id& __id = _Facet::id; // check member id locale::id& __id = _Facet::id;
size_t __i = __id._M_index; size_t __i = __id._M_index;
__vec_facet* __facet = __loc._M_impl->_M_facets; __vec_facet* __facet = __loc._M_impl->_M_facets;
const locale::facet* __fp = (*__facet)[__i]; // check derivation const locale::facet* __fp = (*__facet)[__i];
if (__i >= __facet->size() || __fp == 0) if (__fp == 0 || __i >= __facet->size())
return _Use_facet_failure_handler<_Facet>(__loc); throw bad_cast();
return static_cast<const _Facet&>(*__fp); return static_cast<const _Facet&>(*__fp);
} }
...@@ -85,7 +84,7 @@ namespace std ...@@ -85,7 +84,7 @@ namespace std
has_facet(const locale& __loc) throw() has_facet(const locale& __loc) throw()
{ {
typedef locale::_Impl::__vec_facet __vec_facet; typedef locale::_Impl::__vec_facet __vec_facet;
locale::id& __id = _Facet::id; // check member id locale::id& __id = _Facet::id;
size_t __i = __id._M_index; size_t __i = __id._M_index;
__vec_facet* __facet = __loc._M_impl->_M_facets; __vec_facet* __facet = __loc._M_impl->_M_facets;
return (__i < __facet->size() && (*__facet)[__i] != 0); return (__i < __facet->size() && (*__facet)[__i] != 0);
......
// Locale support -*- C++ -*- // Locale support -*- C++ -*-
// Copyright (C) 1997-2000 Free Software Foundation, Inc. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -38,9 +38,16 @@ ...@@ -38,9 +38,16 @@
#include <bits/std_climits.h> // For CHAR_BIT #include <bits/std_climits.h> // For CHAR_BIT
#include <bits/std_string.h> // For string #include <bits/std_string.h> // For string
#include <bits/std_cctype.h> // For isspace, etc. #include <bits/std_cctype.h> // For isspace, etc.
#include <bits/c++locale.h> // Defines __c_locale.
namespace std namespace std
{ {
// NB: Don't instantiate required wchar_t facets if no wchar_t support.
#ifdef _GLIBCPP_USE_WCHAR_T
# define _GLIBCPP_NUM_FACETS 26
#else
# define _GLIBCPP_NUM_FACETS 13
#endif
// _Count_ones: compile-time computation of number of 1-bits in a value N // _Count_ones: compile-time computation of number of 1-bits in a value N
// This takes only 5 (or 6) instantiations, doing recursive descent // This takes only 5 (or 6) instantiations, doing recursive descent
...@@ -163,10 +170,6 @@ namespace std ...@@ -163,10 +170,6 @@ namespace std
// 22.2.4 collation // 22.2.4 collation
template<typename _CharT> template<typename _CharT>
class collate; class collate;
template<> class collate<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template<> class collate<wchar_t>;
#endif
template<typename _CharT> class template<typename _CharT> class
collate_byname; collate_byname;
...@@ -199,19 +202,19 @@ namespace std ...@@ -199,19 +202,19 @@ namespace std
template<typename _CharT> template<typename _CharT>
class messages_byname; class messages_byname;
// 22.1.1 Class locale // 22.1.1 Class locale
class locale class locale
{ {
public: public:
// Types: // Types:
typedef unsigned int category; typedef unsigned int category;
// Forward decls and friends: // Forward decls and friends:
class facet; class facet;
class id; class id;
class _Impl; class _Impl;
friend class facet;
friend class _Impl; friend class _Impl;
template<typename _Facet> template<typename _Facet>
...@@ -223,7 +226,7 @@ namespace std ...@@ -223,7 +226,7 @@ namespace std
has_facet(const locale&) throw(); has_facet(const locale&) throw();
// Category values: // Category values:
// NB much depends on the order in which these appear: // NB: Order must match _S_facet_categories definition in locale.cc
static const category none = 0; static const category none = 0;
static const category ctype = 1 << 0; static const category ctype = 1 << 0;
static const category numeric = 1 << 1; static const category numeric = 1 << 1;
...@@ -235,23 +238,20 @@ namespace std ...@@ -235,23 +238,20 @@ namespace std
numeric | time | messages); numeric | time | messages);
// Construct/copy/destroy: // Construct/copy/destroy:
inline
locale() throw(); locale() throw();
inline
locale(const locale& __other) throw(); locale(const locale& __other) throw();
explicit explicit
locale(const char* __std_name); locale(const char* __std_name);
locale(const locale& __other, const char* __std_name, category __cat); locale(const locale& __base, const char* __s, category __cat);
locale(const locale& __other, const locale& __one, category __cat); locale(const locale& __base, const locale& __add, category __cat);
template<typename _Facet> template<typename _Facet>
locale(const locale& __other, _Facet* __f); locale(const locale& __other, _Facet* __f);
inline
~locale() throw(); ~locale() throw();
const locale& const locale&
...@@ -294,8 +294,8 @@ namespace std ...@@ -294,8 +294,8 @@ namespace std
// Current global reference locale // Current global reference locale
static _Impl* _S_global; static _Impl* _S_global;
static const int _S_categories_num = _Count_ones<all>::_M_count; static const size_t _S_num_categories = _Count_ones<all>::_M_count;
static const int _S_facets_num = 26; static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
explicit explicit
locale(_Impl*) throw(); locale(_Impl*) throw();
...@@ -304,8 +304,11 @@ namespace std ...@@ -304,8 +304,11 @@ namespace std
_S_initialize() _S_initialize()
{ if (!_S_classic) classic(); } { if (!_S_classic) classic(); }
static int static category
_S_normalize_category(int); _S_normalize_category(category);
void
_M_coalesce(const locale& __base, const locale& __add, category __cat);
}; };
...@@ -314,8 +317,7 @@ namespace std ...@@ -314,8 +317,7 @@ namespace std
{ {
public: public:
// Types. // Types.
typedef vector<facet*, allocator<facet*> > __vec_facet; typedef vector<facet*, allocator<facet*> > __vec_facet;
typedef vector<string, allocator<string> > __vec_string;
// Friends. // Friends.
friend class locale; friend class locale;
...@@ -333,9 +335,8 @@ namespace std ...@@ -333,9 +335,8 @@ namespace std
// Data Members. // Data Members.
size_t _M_references; size_t _M_references;
__vec_facet* _M_facets; __vec_facet* _M_facets;
__vec_string* _M_category_names; string _M_names[_S_num_categories];
bool _M_has_name; __c_locale _M_c_locale;
string _M_name;
static const locale::id* const _S_id_ctype[]; static const locale::id* const _S_id_ctype[];
static const locale::id* const _S_id_numeric[]; static const locale::id* const _S_id_numeric[];
static const locale::id* const _S_id_collate[]; static const locale::id* const _S_id_collate[];
...@@ -353,19 +354,25 @@ namespace std ...@@ -353,19 +354,25 @@ namespace std
{ {
if (_M_references-- == 0) // XXX MT if (_M_references-- == 0) // XXX MT
{ {
try { try
delete this; { delete this; }
} catch(...)
catch(...) { { }
}
} }
} }
_Impl(const _Impl&, size_t); _Impl(const _Impl&, size_t);
_Impl(const _Impl&, const string&, category, size_t); _Impl(string __name, size_t);
_Impl(size_t, size_t, bool __has_name = false, string __name = "*");
~_Impl() throw(); ~_Impl() throw();
bool
_M_check_same_name()
{
bool __ret = true;
for (size_t i = 0; i < _S_num_categories - 1; ++i)
__ret &= _M_names[i] == _M_names[i + 1];
return __ret;
}
void void
_M_replace_categories(const _Impl*, category); _M_replace_categories(const _Impl*, category);
...@@ -380,53 +387,19 @@ namespace std ...@@ -380,53 +387,19 @@ namespace std
template<typename _Facet> template<typename _Facet>
inline void inline void
_M_facet_init(_Facet* __facet) _M_init_facet(_Facet* __facet)
{ _M_install_facet(&_Facet::id, __facet); } { _M_install_facet(&_Facet::id, __facet); }
void
_M_construct_collate(const char*);
void
_M_construct_ctype(const char*);
void
_M_construct_monetary(const char*);
void
_M_construct_numeric(const char*);
void
_M_construct_time(const char*);
void
_M_construct_messages(const char*);
category
_M_normalize_category_names(const string&, category __cat);
}; };
// class locale inlines, that need declaration of locale::_Imp
locale::locale() throw()
{
_S_initialize();
(_M_impl = _S_global)->_M_add_reference();
} // XXX MT
locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); }
template<typename _Facet> template<typename _Facet>
locale::locale(const locale& __other, _Facet* __f) locale::locale(const locale& __other, _Facet* __f)
{ {
_M_impl = new _Impl(*__other._M_impl, 1); _M_impl = new _Impl(*__other._M_impl, 1);
_M_impl->_M_install_facet(&_Facet::id, __f); _M_impl->_M_install_facet(&_Facet::id, __f);
_M_impl->_M_has_name = false; for (int __i = 0; __i < _S_num_categories; ++__i)
_M_impl->_M_name = "*"; _M_impl->_M_names[__i] = "*";
} }
locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }
// 22.1.1.1.2 Class locale::facet // 22.1.1.1.2 Class locale::facet
class locale::facet class locale::facet
{ {
...@@ -440,6 +413,12 @@ namespace std ...@@ -440,6 +413,12 @@ namespace std
virtual virtual
~facet() { }; ~facet() { };
static void
_S_create_c_locale(__c_locale& __cloc, const char* __s);
static void
_S_destroy_c_locale(__c_locale& __cloc);
private: private:
size_t _M_references; size_t _M_references;
...@@ -459,6 +438,7 @@ namespace std ...@@ -459,6 +438,7 @@ namespace std
// 22.1.1.1.3 Class locale::id // 22.1.1.1.3 Class locale::id
class locale::id class locale::id
{ {
private:
friend class locale; friend class locale;
friend class locale::_Impl; friend class locale::_Impl;
template<typename _Facet> template<typename _Facet>
...@@ -467,9 +447,7 @@ namespace std ...@@ -467,9 +447,7 @@ namespace std
template<typename _Facet> template<typename _Facet>
friend bool friend bool
has_facet(const locale&) throw (); has_facet(const locale&) throw ();
public:
id() { };
private:
// NB: There is no accessor for _M_index because it may be used // NB: There is no accessor for _M_index because it may be used
// before the constructor is run; the effect of calling a member // before the constructor is run; the effect of calling a member
// function (even an inline) would be undefined. // function (even an inline) would be undefined.
...@@ -482,6 +460,12 @@ namespace std ...@@ -482,6 +460,12 @@ namespace std
operator=(const id&); // not defined operator=(const id&); // not defined
id(const id&); // not defined id(const id&); // not defined
public:
// NB: This class is always a static data member, and thus can be
// counted on to be zero-initialized.
// XXX id() : _M_index(0) { }
id() { }
}; };
template<typename _Facet> template<typename _Facet>
...@@ -491,7 +475,6 @@ namespace std ...@@ -491,7 +475,6 @@ namespace std
template<typename _Facet> template<typename _Facet>
bool bool
has_facet(const locale& __loc) throw(); has_facet(const locale& __loc) throw();
} // namespace std } // namespace std
#endif /* _CPP_BITS_LOCCORE_H */ #endif /* _CPP_BITS_LOCCORE_H */
......
// -*- C++ -*- forwarding header. // -*- C++ -*- forwarding header.
// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#ifndef _CPP_CLOCALE #ifndef _CPP_CLOCALE
#define _CPP_CLOCALE 1 #define _CPP_CLOCALE 1
#include <bits/c++config.h>
#pragma GCC system_header #pragma GCC system_header
#include <locale.h> #include <locale.h>
......
2001-01-28 benjamin kosnik <bkoz@fillmore.constant.com>
* Makefile.am (LIBIO_SRCS): Remove stdio.c.
2000-10-29 Benjamin Kosnik <bkoz@gnu.org> 2000-10-29 Benjamin Kosnik <bkoz@gnu.org>
* Makefile.am (INCLUDES): Change to $(top_builddir)/include. * Makefile.am (INCLUDES): Change to $(top_builddir)/include.
......
...@@ -48,8 +48,8 @@ libio_headers = \ ...@@ -48,8 +48,8 @@ libio_headers = \
if GLIBCPP_NEED_LIBIO if GLIBCPP_NEED_LIBIO
LIBIO_SRCS = \ LIBIO_SRCS = \
filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c \ filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c \
iofopen.c stdio.c iofclose.c iofopen.c
else else
LIBIO_SRCS = LIBIO_SRCS =
endif endif
......
...@@ -129,7 +129,7 @@ INCLUDES = -nostdinc++ -I$(top_builddir)/include -I$(GLIBCPP_INCLUDE_DIR) $( ...@@ -129,7 +129,7 @@ INCLUDES = -nostdinc++ -I$(top_builddir)/include -I$(GLIBCPP_INCLUDE_DIR) $(
libio_headers = libio.h libioP.h iolibio.h libio_headers = libio.h libioP.h iolibio.h
@GLIBCPP_NEED_LIBIO_TRUE@LIBIO_SRCS = filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c iofopen.c stdio.c @GLIBCPP_NEED_LIBIO_TRUE@LIBIO_SRCS = filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c iofopen.c
@GLIBCPP_NEED_LIBIO_FALSE@LIBIO_SRCS = @GLIBCPP_NEED_LIBIO_FALSE@LIBIO_SRCS =
@GLIBCPP_NEED_WLIBIO_TRUE@LIBIO_WSRCS = wfiledoalloc.c wfileops.c wgenops.c iofwide.c @GLIBCPP_NEED_WLIBIO_TRUE@LIBIO_WSRCS = wfiledoalloc.c wfileops.c wgenops.c iofwide.c
@GLIBCPP_NEED_WLIBIO_FALSE@LIBIO_WSRCS = @GLIBCPP_NEED_WLIBIO_FALSE@LIBIO_WSRCS =
...@@ -157,7 +157,7 @@ libio_la_LIBADD = ...@@ -157,7 +157,7 @@ libio_la_LIBADD =
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@stdfiles.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@stdfiles.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@c_codecvt.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@c_codecvt.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofclose.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofclose.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo stdio.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wfiledoalloc.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wfiledoalloc.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wfileops.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wfileops.lo \
@GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wgenops.lo \ @GLIBCPP_NEED_WLIBIO_TRUE@@GLIBCPP_NEED_LIBIO_TRUE@wgenops.lo \
...@@ -174,7 +174,7 @@ libio_la_LIBADD = ...@@ -174,7 +174,7 @@ libio_la_LIBADD =
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@stdfiles.lo \ @GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@stdfiles.lo \
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@c_codecvt.lo \ @GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@c_codecvt.lo \
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofclose.lo \ @GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofclose.lo \
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo stdio.lo @GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_TRUE@iofopen.lo
@GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_FALSE@libio_la_OBJECTS = @GLIBCPP_NEED_WLIBIO_FALSE@@GLIBCPP_NEED_LIBIO_FALSE@libio_la_OBJECTS =
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
## Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
## USA. ## USA.
## $Id: Makefile.am,v 1.64 2001/01/11 07:27:49 bkoz Exp $ ## $Id: Makefile.am,v 1.65 2001/01/25 22:39:28 mmitchel Exp $
AUTOMAKE_OPTIONS = 1.3 gnits AUTOMAKE_OPTIONS = 1.3 gnits
MAINT_CHARSET = latin1 MAINT_CHARSET = latin1
...@@ -168,7 +168,8 @@ libio_headers = ...@@ -168,7 +168,8 @@ libio_headers =
endif endif
build_headers = \ build_headers = \
bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++threads.h \ bits/std_limits.h \
bits/c++config.h bits/c++io.h bits/c++locale.h bits/c++threads.h \
bits/atomicity.h bits/os_defines.h \ bits/atomicity.h bits/os_defines.h \
bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h
...@@ -178,7 +179,7 @@ sources = \ ...@@ -178,7 +179,7 @@ sources = \
stdexcept.cc bitset.cc \ stdexcept.cc bitset.cc \
globals.cc \ globals.cc \
c++io.cc ios.cc strstream.cc \ c++io.cc ios.cc strstream.cc \
locale.cc localename.cc codecvt.cc \ c++locale.cc locale.cc localename.cc codecvt.cc \
locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc
wstring_sources = \ wstring_sources = \
......
...@@ -167,10 +167,10 @@ std_headers = algorithm bitset complex deque fstream functional iomanip ios i ...@@ -167,10 +167,10 @@ std_headers = algorithm bitset complex deque fstream functional iomanip ios i
@GLIBCPP_NEED_LIBIO_TRUE@libio_headers = $(top_srcdir)/libio/_G_config.h $(top_srcdir)/libio/libio.h @GLIBCPP_NEED_LIBIO_TRUE@libio_headers = $(top_srcdir)/libio/_G_config.h $(top_srcdir)/libio/libio.h
@GLIBCPP_NEED_LIBIO_FALSE@libio_headers = @GLIBCPP_NEED_LIBIO_FALSE@libio_headers =
build_headers = bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++threads.h bits/atomicity.h bits/os_defines.h bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h build_headers = bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++locale.h bits/c++threads.h bits/atomicity.h bits/os_defines.h bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h
sources = limitsMEMBERS.cc complex_io.cc stdexcept.cc bitset.cc globals.cc c++io.cc ios.cc strstream.cc locale.cc localename.cc codecvt.cc locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc sources = limitsMEMBERS.cc complex_io.cc stdexcept.cc bitset.cc globals.cc c++io.cc ios.cc strstream.cc c++locale.cc locale.cc localename.cc codecvt.cc locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc
wstring_sources = wstring-inst.cc wstring_sources = wstring-inst.cc
...@@ -259,9 +259,9 @@ libinst_wstring_la_LDFLAGS = ...@@ -259,9 +259,9 @@ libinst_wstring_la_LDFLAGS =
libinst_wstring_la_LIBADD = libinst_wstring_la_LIBADD =
libinst_wstring_la_OBJECTS = wstring-inst.lo libinst_wstring_la_OBJECTS = wstring-inst.lo
libstdc___la_OBJECTS = limitsMEMBERS.lo complex_io.lo stdexcept.lo \ libstdc___la_OBJECTS = limitsMEMBERS.lo complex_io.lo stdexcept.lo \
bitset.lo globals.lo c++io.lo ios.lo strstream.lo locale.lo \ bitset.lo globals.lo c++io.lo ios.lo strstream.lo c++locale.lo \
localename.lo codecvt.lo locale-inst.lo stl-inst.lo misc-inst.lo \ locale.lo localename.lo codecvt.lo locale-inst.lo stl-inst.lo \
valarray-inst.lo string-inst.lo misc-inst.lo valarray-inst.lo string-inst.lo
CXXFLAGS = @CXXFLAGS@ CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX) CXXLD = $(CXX)
......
// Locale support -*- C++ -*- // Locale support -*- C++ -*-
// Copyright (C) 1999, 2000 Free Software Foundation, Inc. // Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -54,7 +54,6 @@ namespace std { ...@@ -54,7 +54,6 @@ namespace std {
template class moneypunct<char, true>; template class moneypunct<char, true>;
template class moneypunct_byname<char, false>; template class moneypunct_byname<char, false>;
template class moneypunct_byname<char, true>; template class moneypunct_byname<char, true>;
template class _Moneypunct<char>;
template class money_get<char, obuf_iterator>; template class money_get<char, obuf_iterator>;
template class money_put<char, obuf_iterator>; template class money_put<char, obuf_iterator>;
template class money_get<char, ibuf_iterator>; template class money_get<char, ibuf_iterator>;
...@@ -66,7 +65,6 @@ namespace std { ...@@ -66,7 +65,6 @@ namespace std {
template class moneypunct<wchar_t, true>; template class moneypunct<wchar_t, true>;
template class moneypunct_byname<wchar_t, false>; template class moneypunct_byname<wchar_t, false>;
template class moneypunct_byname<wchar_t, true>; template class moneypunct_byname<wchar_t, true>;
template class _Moneypunct<wchar_t>;
template class money_get<wchar_t, wobuf_iterator>; template class money_get<wchar_t, wobuf_iterator>;
template class money_put<wchar_t, wobuf_iterator>; template class money_put<wchar_t, wobuf_iterator>;
template class money_get<wchar_t, wibuf_iterator>; template class money_get<wchar_t, wibuf_iterator>;
...@@ -77,23 +75,15 @@ namespace std { ...@@ -77,23 +75,15 @@ namespace std {
// numpunct, numpunct_byname, num_get, and num_put // numpunct, numpunct_byname, num_get, and num_put
template class numpunct<char>; template class numpunct<char>;
template class numpunct_byname<char>; template class numpunct_byname<char>;
template class _Numpunct<char>;
template class num_get<char, ibuf_iterator>; template class num_get<char, ibuf_iterator>;
template class num_put<char, obuf_iterator>; template class num_put<char, obuf_iterator>;
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template class numpunct<wchar_t>; template class numpunct<wchar_t>;
template class numpunct_byname<wchar_t>; template class numpunct_byname<wchar_t>;
template class _Numpunct<wchar_t>;
template class num_get<wchar_t, wibuf_iterator>; template class num_get<wchar_t, wibuf_iterator>;
template class num_put<wchar_t, wobuf_iterator>; template class num_put<wchar_t, wobuf_iterator>;
#endif #endif
// _Punct
template class _Punct<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class _Punct<wchar_t>;
#endif
// time_get and time_put // time_get and time_put
template class time_put<char, obuf_iterator>; template class time_put<char, obuf_iterator>;
template class time_put_byname<char, obuf_iterator>; template class time_put_byname<char, obuf_iterator>;
...@@ -108,11 +98,9 @@ namespace std { ...@@ -108,11 +98,9 @@ namespace std {
#endif #endif
// messages // messages
template class _Messages<char>;
template class messages<char>; template class messages<char>;
template class messages_byname<char>; template class messages_byname<char>;
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template class _Messages<wchar_t>;
template class messages<wchar_t>; template class messages<wchar_t>;
template class messages_byname<wchar_t>; template class messages_byname<wchar_t>;
#endif #endif
...@@ -134,12 +122,12 @@ namespace std { ...@@ -134,12 +122,12 @@ namespace std {
#endif #endif
// collate // collate
template class _Collate<char>; template class collate<char>;
template class collate_byname<char>; template class collate_byname<char>;
template class _Weekdaynames<char, int>; template class _Weekdaynames<char, int>;
template class _Monthnames<char, int>; template class _Monthnames<char, int>;
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template class _Collate<wchar_t>; template class collate<wchar_t>;
template class collate_byname<wchar_t>; template class collate_byname<wchar_t>;
template class _Weekdaynames<wchar_t, int>; template class _Weekdaynames<wchar_t, int>;
template class _Monthnames<wchar_t, int>; template class _Monthnames<wchar_t, int>;
...@@ -155,10 +143,6 @@ namespace std { ...@@ -155,10 +143,6 @@ namespace std {
template template
const codecvt<char, char, mbstate_t>& const codecvt<char, char, mbstate_t>&
use_facet<codecvt<char, char, mbstate_t> >(const locale&); use_facet<codecvt<char, char, mbstate_t> >(const locale&);
template
const num_put<char, obuf_iterator>&
_Use_facet_failure_handler<num_put<char, obuf_iterator> >
(const locale &);
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
template template
const num_put<wchar_t, wobuf_iterator>& const num_put<wchar_t, wobuf_iterator>&
...@@ -169,10 +153,6 @@ namespace std { ...@@ -169,10 +153,6 @@ namespace std {
template template
const codecvt<wchar_t, char, mbstate_t>& const codecvt<wchar_t, char, mbstate_t>&
use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const &); use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const &);
template
const num_put<wchar_t, wobuf_iterator>&
_Use_facet_failure_handler<num_put<wchar_t, wobuf_iterator> >
(const locale &);
#endif #endif
// has_facet // has_facet
...@@ -296,12 +276,11 @@ namespace std { ...@@ -296,12 +276,11 @@ namespace std {
template template
locale::facet** locale::facet**
fill_n<locale::facet**, unsigned int, locale::facet*> fill_n<locale::facet**, unsigned int, locale::facet*>
(locale::facet**, unsigned int, locale::facet* const &); (locale::facet**, unsigned int, locale::facet* const&);
template template
locale::facet** locale::facet**
fill_n<locale::facet**, unsigned long, locale::facet*> fill_n<locale::facet**, unsigned long, locale::facet*>
(locale::facet**, unsigned long, locale::facet* const &); (locale::facet**, unsigned long, locale::facet* const&);
} //std } //std
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -55,8 +55,8 @@ namespace std ...@@ -55,8 +55,8 @@ namespace std
locale::_Impl* locale::_S_classic; locale::_Impl* locale::_S_classic;
locale::_Impl* locale::_S_global; locale::_Impl* locale::_S_global;
const int locale::_S_categories_num; const size_t locale::_S_num_categories;
const int locale::_S_facets_num; const size_t locale::_S_num_facets;
// Definitions for locale::id of standard facets. // Definitions for locale::id of standard facets.
locale::id ctype<char>::id; locale::id ctype<char>::id;
...@@ -180,9 +180,457 @@ namespace std ...@@ -180,9 +180,457 @@ namespace std
0 0
}; };
// Construct and return valid pattern consisting of some combination of:
// space none symbol sign value
money_base::pattern
money_base::_S_construct_pattern(char __preceeds, char __space, char __posn)
{
pattern __ret;
// This insanely complicated routine attempts to construct a valid
// pattern for use with monyepunct. A couple of invariants:
// if (__preceeds) symbol -> value
// else value -> symbol
// if (__space) space
// else none
// none == never first
// space never first or last
// Any elegant implementations of this are welcome.
switch (__posn)
{
case 1:
// 1 The sign precedes the value and symbol.
if (__space)
{
// Pattern starts with sign.
if (__preceeds)
{
__ret.field[1] = symbol;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[1] = value;
__ret.field[2] = space;
__ret.field[3] = symbol;
}
__ret.field[0] = sign;
}
else
{
// Pattern starts with sign and ends with none.
if (__preceeds)
{
__ret.field[1] = symbol;
__ret.field[2] = value;
}
else
{
__ret.field[1] = value;
__ret.field[2] = symbol;
}
__ret.field[0] = sign;
__ret.field[3] = none;
}
break;
case 2:
// 2 The sign follows the value and symbol.
if (__space)
{
// Pattern either ends with sign.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = space;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = symbol;
}
__ret.field[3] = sign;
}
else
{
// Pattern ends with sign then none.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = symbol;
}
__ret.field[2] = sign;
__ret.field[3] = none;
}
break;
case 3:
// 3 The sign immediately precedes the symbol.
if (__space)
{
// Have space.
if (__preceeds)
{
__ret.field[0] = sign;
__ret.field[1] = symbol;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = sign;
__ret.field[3] = symbol;
}
}
else
{
// Have none.
if (__preceeds)
{
__ret.field[0] = sign;
__ret.field[1] = symbol;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = sign;
__ret.field[2] = symbol;
}
__ret.field[3] = none;
}
break;
case 4:
// 4 The sign immediately follows the symbol.
if (__space)
{
// Have space.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = sign;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = symbol;
__ret.field[3] = sign;
}
}
else
{
// Have none.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = sign;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = symbol;
__ret.field[2] = sign;
}
__ret.field[3] = none;
}
break;
default:
;
}
return __ret;
}
locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }
void
locale::_M_coalesce(const locale& __base, const locale& __add,
category __cat)
{
__cat = _S_normalize_category(__cat);
_M_impl = new _Impl(*__base._M_impl, 1);
try
{ _M_impl->_M_replace_categories(__add._M_impl, __cat); }
catch (...)
{
_M_impl->_M_remove_reference();
throw;
}
}
locale::locale() throw()
{
_S_initialize();
(_M_impl = _S_global)->_M_add_reference();
} // XXX MT
locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); }
locale::locale(_Impl* __ip) throw()
: _M_impl(__ip)
{ __ip->_M_add_reference(); }
locale::locale(const char* __s)
{
if (__s)
{
if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0)
(_M_impl = _S_classic)->_M_add_reference();
else
_M_impl = new _Impl(__s, 1);
}
else
throw runtime_error("attempt to create locale from NULL name");
}
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); }
bool
locale::operator==(const locale& __rhs) const throw()
{
string __name = this->name();
return (_M_impl == __rhs._M_impl
|| (__name != "*" && __name == __rhs.name()));
}
const locale&
locale::operator=(const locale& __other) throw()
{
__other._M_impl->_M_add_reference();
_M_impl->_M_remove_reference();
_M_impl = __other._M_impl;
return *this;
}
locale
locale::global(const locale& __other)
{
// XXX MT
_S_initialize();
locale __old(_S_global);
__other._M_impl->_M_add_reference();
_S_global->_M_remove_reference();
_S_global = __other._M_impl;
if (_S_global->_M_check_same_name() && _S_global->_M_names[0] != "*")
setlocale(LC_ALL, __other.name().c_str());
return __old;
}
string
locale::name() const
{
string __ret;
// Need some kind of separator character. This one was pretty much
// arbitrarily chosen as to not conflict with glibc locales: the
// exact formatting is not set in stone.
const char __separator = '|';
if (_M_impl->_M_check_same_name())
__ret = _M_impl->_M_names[0];
else
{
for (size_t i = 0; i < _S_num_categories; ++i)
__ret += __separator + _M_impl->_M_names[i];
}
return __ret;
}
locale const&
locale::classic()
{
static locale* __classic_locale;
// XXX MT
if (!_S_classic)
{
try
{
// 26 Standard facets, 2 references.
// One reference for _M_classic, one for _M_global
_S_classic = new _Impl("C", 2);
_S_global = _S_classic;
// Finesse static init order hassles
__classic_locale = new locale(_S_classic);
}
catch(...)
{
delete __classic_locale;
if (_S_classic)
{
_S_classic->_M_remove_reference();
_S_global->_M_remove_reference();
}
_S_classic = _S_global = 0;
// XXX MT
throw;
}
}
return *__classic_locale;
}
locale::category
locale::_S_normalize_category(category __cat)
{
int __ret;
if (__cat == none || (__cat & all) && !(__cat & ~all))
__ret = __cat;
else
{
// NB: May be a C-style "LC_ALL" category; convert.
switch (__cat)
{
case LC_COLLATE:
__ret = collate;
break;
case LC_CTYPE:
__ret = ctype;
break;
case LC_MONETARY:
__ret = monetary;
break;
case LC_NUMERIC:
__ret = numeric;
break;
case LC_TIME:
__ret = time;
break;
#ifdef _GLIBCPP_HAVE_LC_MESSAGES
case LC_MESSAGES:
__ret = messages;
break;
#endif
case LC_ALL:
__ret = all;
break;
default:
throw runtime_error("bad locale category");
}
}
return __ret;
}
locale::facet::
facet(size_t __refs) throw()
: _M_references(__refs)
{ }
void
locale::facet::
_M_add_reference() throw()
{ ++_M_references; } // XXX MT
void
locale::facet::
_M_remove_reference() throw()
{
if (_M_references)
--_M_references;
else
{
try
{ delete this; } // XXX MT
catch (...)
{ }
}
}
// Definitions for static const data members of ctype_base.
const ctype_base::mask ctype_base::space;
const ctype_base::mask ctype_base::print;
const ctype_base::mask ctype_base::cntrl;
const ctype_base::mask ctype_base::upper;
const ctype_base::mask ctype_base::lower;
const ctype_base::mask ctype_base::alpha;
const ctype_base::mask ctype_base::digit;
const ctype_base::mask ctype_base::punct;
const ctype_base::mask ctype_base::xdigit;
const ctype_base::mask ctype_base::alnum;
const ctype_base::mask ctype_base::graph;
// Platform-specific initialization code for ctype tables.
#include <bits/ctype_noninline.h>
const size_t ctype<char>::table_size;
ctype<char>::~ctype()
{ if (_M_del) delete[] this->table(); }
// These are dummy placeholders as these virtual functions are never called.
bool
ctype<char>::do_is(mask, char_type) const
{ return false; }
const char*
ctype<char>::do_is(const char_type* __c, const char_type*, mask*) const
{ return __c; }
const char*
ctype<char>::do_scan_is(mask, const char_type* __c, const char_type*) const
{ return __c; }
const char*
ctype<char>::do_scan_not(mask, const char_type* __c, const char_type*) const
{ return __c; }
char
ctype<char>::do_widen(char __c) const
{ return __c; }
const char*
ctype<char>::do_widen(const char* __low, const char* __high,
char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
char
ctype<char>::do_narrow(char __c, char /*__dfault*/) const
{ return __c; }
const char*
ctype<char>::do_narrow(const char* __low, const char* __high,
char /*__dfault*/, char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
ctype_byname<char>::ctype_byname(const char* /*__s*/, size_t __refs)
: ctype<char>(new mask[table_size], true, __refs)
{ }
// Definitions for static const data members of money_base // Definitions for static const data members of money_base
const money_base::pattern const money_base::pattern
money_base::_S_default_pattern = {{symbol, sign, none, value}};; money_base::_S_default_pattern = {{symbol, sign, none, value}};
template<> template<>
_Format_cache<char>::_Format_cache() _Format_cache<char>::_Format_cache()
...@@ -565,300 +1013,8 @@ namespace std ...@@ -565,300 +1013,8 @@ namespace std
return __incl_prec; return __incl_prec;
} }
locale::locale(_Impl* __ip) throw()
: _M_impl(__ip)
{ __ip->_M_add_reference(); }
locale::locale(const char* __name)
{
if (__name)
{
if (strcmp(__name, "C") == 0 || strcmp(__name, "POSIX") == 0)
(_M_impl = _S_classic)->_M_add_reference();
// Might throw:
else
// XXX Named locale support not finished.
// _M_impl = new _Impl(_S_facets_num, 1, true, __name);
_M_impl = new _Impl(*_S_classic, __name, all, 1);
}
else
throw runtime_error("attempt to create named locale from NULL name");
}
locale::locale(const locale& __other, const char* __name, category __cat)
{
if (__name)
{
if (__other.name() == __name)
(_M_impl = __other._M_impl)->_M_add_reference();
// Might throw:
else
_M_impl = new _Impl(*__other._M_impl, __name, __cat, 1);
}
else
throw runtime_error("attempt to create locale from NULL named locale");
}
locale::locale(const locale& __other, const locale& __one, category __cat)
{
__cat = _S_normalize_category(__cat); // might throw
_M_impl = new _Impl(*__other._M_impl, 1); // might throw
try {
_M_impl->_M_replace_categories(__one._M_impl, __cat);
}
catch (...) {
_M_impl->_M_remove_reference();
throw;
}
// XXX
// _M_impl->_M_cached_name_ok = false;
if (!__other._M_impl->_M_has_name)
_M_impl->_M_has_name = false;
}
bool
locale::operator==(const locale& __rhs) const throw()
{
return (_M_impl == __rhs._M_impl
|| (this->name() != "*" && this->name() == __rhs.name()));
}
const locale&
locale::operator=(const locale& __other) throw()
{
__other._M_impl->_M_add_reference();
_M_impl->_M_remove_reference();
_M_impl = __other._M_impl;
return *this;
}
locale
locale::global(const locale& __other)
{
// XXX MT
_S_initialize();
locale __keep(_S_global);
__other._M_impl->_M_add_reference();
_S_global->_M_remove_reference();
_S_global = __other._M_impl;
if (_S_global->_M_has_name)
setlocale(LC_ALL, __other.name().c_str());
return __keep;
}
string
locale::name() const
{ return _M_impl->_M_name; }
locale const&
locale::classic()
{
static locale* __classic_locale;
// XXX MT
if (!_S_classic)
{
try {
// 26 Standard facets, 2 references.
// One reference for _M_classic, one for _M_global
_S_classic = new _Impl(_S_facets_num, 2, true, "C");
_S_global = _S_classic;
_S_classic->_M_facet_init(new std::collate<char>);
_S_classic->_M_facet_init(new std::ctype<char>);
_S_classic->_M_facet_init(new codecvt<char, char, mbstate_t>);
_S_classic->_M_facet_init(new moneypunct<char, false>);
_S_classic->_M_facet_init(new moneypunct<char,true >);
_S_classic->_M_facet_init(new money_get<char>);
_S_classic->_M_facet_init(new money_put<char>);
_S_classic->_M_facet_init(new numpunct<char>);
_S_classic->_M_facet_init(new num_get<char>);
_S_classic->_M_facet_init(new num_put<char>);
_S_classic->_M_facet_init(new time_get<char>);
_S_classic->_M_facet_init(new time_put<char>);
_S_classic->_M_facet_init(new std::messages<char>);
#ifdef _GLIBCPP_USE_WCHAR_T
_S_classic->_M_facet_init(new std::collate<wchar_t>);
_S_classic->_M_facet_init(new std::ctype<wchar_t>);
_S_classic->_M_facet_init(new codecvt<wchar_t, char, mbstate_t>);
_S_classic->_M_facet_init(new moneypunct<wchar_t, false>);
_S_classic->_M_facet_init(new moneypunct<wchar_t,true >);
_S_classic->_M_facet_init(new money_get<wchar_t>);
_S_classic->_M_facet_init(new money_put<wchar_t>);
_S_classic->_M_facet_init(new numpunct<wchar_t>);
_S_classic->_M_facet_init(new num_get<wchar_t>);
_S_classic->_M_facet_init(new num_put<wchar_t>);
_S_classic->_M_facet_init(new time_get<wchar_t>);
_S_classic->_M_facet_init(new time_put<wchar_t>);
_S_classic->_M_facet_init(new std::messages<wchar_t>);
#endif
// Finesse static init order hassles
__classic_locale = new locale(_S_classic);
}
catch(...) {
delete __classic_locale;
if (_S_classic)
{
_S_classic->_M_remove_reference();
_S_global->_M_remove_reference();
}
_S_classic = _S_global = 0;
// XXX MT
throw;
}
}
return *__classic_locale;
}
int
locale::_S_normalize_category(int __cat)
{
int __ret;
if ((__cat & all) && !(__cat & ~all))
__ret = __cat;
else
{
// NB: May be a C-style "LC_ALL" category; convert.
switch (__cat)
{
case LC_COLLATE:
__ret = collate;
break;
case LC_CTYPE:
__ret = ctype;
break;
case LC_MONETARY:
__ret = monetary;
break;
case LC_NUMERIC:
__ret = numeric;
break;
case LC_TIME:
__ret = time;
break;
#ifdef _GLIBCPP_HAVE_LC_MESSAGES
case LC_MESSAGES:
__ret = messages;
break;
#endif
case LC_ALL:
__ret = all;
break;
default:
throw runtime_error("bad locale category");
}
}
return __ret;
}
locale::facet::
facet(size_t __refs) throw()
: _M_references(__refs - 1)
{ }
void
locale::facet::
_M_add_reference() throw()
{
if (this)
++_M_references;
} // XXX MT
void
locale::facet::
_M_remove_reference() throw()
{
if (this && _M_references-- == 0)
{
try {
delete this;
} // XXX MT
catch (...) {
}
}
}
char const*
_Bad_use_facet::
what() const throw()
{ return "_Bad_use_facet thrown from use_facet"; }
_Bad_use_facet::
~_Bad_use_facet() throw() { }
// Definitions for static const data members of ctype_base.
const ctype_base::mask ctype_base::space;
const ctype_base::mask ctype_base::print;
const ctype_base::mask ctype_base::cntrl;
const ctype_base::mask ctype_base::upper;
const ctype_base::mask ctype_base::lower;
const ctype_base::mask ctype_base::alpha;
const ctype_base::mask ctype_base::digit;
const ctype_base::mask ctype_base::punct;
const ctype_base::mask ctype_base::xdigit;
const ctype_base::mask ctype_base::alnum;
const ctype_base::mask ctype_base::graph;
// Platform-specific initialization code for ctype tables.
#include <bits/ctype_noninline.h>
const size_t ctype<char>::table_size;
ctype<char>::~ctype()
{ if (_M_del) delete[] this->table(); }
// These are dummy placeholders as these virtual functions are never called.
bool
ctype<char>::do_is(mask, char_type) const
{ return false; }
const char*
ctype<char>::do_is(const char_type* __c, const char_type*, mask*) const
{ return __c; }
const char*
ctype<char>::do_scan_is(mask, const char_type* __c, const char_type*) const
{ return __c; }
const char*
ctype<char>::do_scan_not(mask, const char_type* __c, const char_type*) const
{ return __c; }
char
ctype<char>::do_widen(char __c) const
{ return __c; }
const char*
ctype<char>::do_widen(const char* __low, const char* __high,
char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
char
ctype<char>::do_narrow(char __c, char /*__dfault*/) const
{ return __c; }
const char*
ctype<char>::do_narrow(const char* __low, const char* __high,
char /*__dfault*/, char* __dest) const
{
memcpy(__dest, __low, __high - __low);
return __high;
}
ctype_byname<char>::ctype_byname(const char* /*__s*/, size_t __refs)
: ctype<char>(new mask[table_size], true, __refs)
{ }
collate<char>::collate(size_t __refs) collate<char>::collate(size_t __refs)
: _Collate<char>(__refs) { } : locale::facet(__refs) { }
collate<char>::~collate() { } collate<char>::~collate() { }
...@@ -896,9 +1052,6 @@ namespace std ...@@ -896,9 +1052,6 @@ namespace std
collate_byname<char>::collate_byname(const char* /*__s*/, size_t __refs) collate_byname<char>::collate_byname(const char* /*__s*/, size_t __refs)
: collate<char>(__refs) { } : collate<char>(__refs) { }
numpunct_byname<char>::numpunct_byname(const char* /*__s*/, size_t __refs)
: numpunct<char>(__refs) { }
moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/, moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/,
size_t __refs) size_t __refs)
: moneypunct<char, false>(__refs) { } : moneypunct<char, false>(__refs) { }
...@@ -1068,8 +1221,7 @@ namespace std ...@@ -1068,8 +1221,7 @@ namespace std
: ctype<wchar_t>(__refs) { } : ctype<wchar_t>(__refs) { }
collate<wchar_t>:: collate<wchar_t>::
collate(size_t __refs) collate(size_t __refs): locale::facet(__refs) { }
: _Collate<wchar_t> (__refs) { }
collate<wchar_t>:: collate<wchar_t>::
~collate() { } ~collate() { }
...@@ -1094,27 +1246,14 @@ namespace std ...@@ -1094,27 +1246,14 @@ namespace std
return 0; // XXX not done return 0; // XXX not done
} }
numpunct_byname<wchar_t>::
numpunct_byname(const char* /*__s*/, size_t __refs)
: numpunct<wchar_t> (__refs) { }
collate_byname<wchar_t>:: collate_byname<wchar_t>::
collate_byname(const char* /*__s*/, size_t __refs) collate_byname(const char* /*__s*/, size_t __refs)
: collate<wchar_t> (__refs) { } : collate<wchar_t> (__refs) { }
moneypunct_byname<wchar_t, false>::
moneypunct_byname(const char* /*__s*/, size_t __refs)
: moneypunct<wchar_t, false> (__refs) { }
moneypunct_byname<wchar_t, true>::
moneypunct_byname(const char* /*__s*/, size_t __refs)
: moneypunct<wchar_t, true> (__refs) { }
messages_byname<wchar_t>:: messages_byname<wchar_t>::
messages_byname(const char* /*__s*/, size_t __refs) messages_byname(const char* /*__s*/, size_t __refs)
: messages<wchar_t> (__refs) { } : messages<wchar_t> (__refs) { }
#endif // _GLIBCPP_USE_WCHAR_T #endif // _GLIBCPP_USE_WCHAR_T
} // namespace std } // namespace std
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
// invalidate any other reasons why the executable file might be covered by // invalidate any other reasons why the executable file might be covered by
// the GNU General Public License. // the GNU General Public License.
#include <bits/std_clocale.h> #include <bits/std_clocale.h>
#include <bits/std_locale.h> #include <bits/std_locale.h>
#include <bits/std_cstring.h> #include <bits/std_cstring.h>
...@@ -33,21 +32,21 @@ ...@@ -33,21 +32,21 @@
#include <bits/std_stdexcept.h> #include <bits/std_stdexcept.h>
namespace std { namespace std {
locale::_Impl:: locale::_Impl::
~_Impl() throw() ~_Impl() throw()
{ {
std::vector<facet*>::iterator it = _M_facets->begin(); __vec_facet::iterator it = _M_facets->begin();
for (; it != _M_facets->end(); ++it) for (; it != _M_facets->end(); ++it)
(*it)->_M_remove_reference(); if (*it)
(*it)->_M_remove_reference();
delete _M_facets; delete _M_facets;
delete _M_category_names; locale::facet::_S_destroy_c_locale(_M_c_locale);
} }
// Clone existing _Impl object.
locale::_Impl:: locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs) _Impl(const _Impl& __imp, size_t __refs)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0), : _M_references(__refs - 1), _M_facets(0), _M_c_locale(0) // XXX
_M_has_name(__imp._M_has_name), _M_name(__imp._M_name)
{ {
try try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); } { _M_facets = new __vec_facet(*(__imp._M_facets)); }
...@@ -57,121 +56,89 @@ namespace std { ...@@ -57,121 +56,89 @@ namespace std {
throw; throw;
} }
try for (size_t i = 0; i < _S_num_categories; ++i)
{ _M_category_names = new __vec_string(*(__imp._M_category_names)); } _M_names[i] = __imp._M_names[i];
catch(...)
{
delete _M_category_names;
throw;
}
std::vector<facet*>::iterator __it = _M_facets->begin(); __vec_facet::iterator __it = _M_facets->begin();
for (; __it != _M_facets->end(); ++__it) for (; __it != _M_facets->end(); ++__it)
(*__it)->_M_add_reference(); if (*__it)
(*__it)->_M_add_reference();
} }
// This constructor is used to correctly initialize named locales, // Construct named _Impl, including the standard "C" locale.
// including the standard "C" locale.
locale::_Impl:: locale::_Impl::
_Impl(size_t __num, size_t __refs, bool __has_name, string __str) _Impl(string __str, size_t __refs)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0), : _M_references(__refs - 1), _M_facets(0)
_M_has_name(__has_name), _M_name(__str)
{ {
// Initialize the underlying locale model, which also checks to
// see if the given name is valid.
if (__str != "C" && __str != "POSIX")
locale::facet::_S_create_c_locale(_M_c_locale, __str.c_str());
else
_M_c_locale = NULL;
// Allocate facet container.
try try
{ _M_facets = new __vec_facet(__num, NULL); } { _M_facets = new __vec_facet(_S_num_facets, NULL); }
catch(...) catch(...)
{ {
delete _M_facets; delete _M_facets;
throw; throw;
} }
try // Name all the categories.
{ _M_category_names = new __vec_string(_S_categories_num, _M_name); } for (size_t i = 0; i < _S_num_categories; ++i)
catch(...) _M_names[i] = __str;
{
delete _M_category_names; // Construct all standard facets and add them to _M_facets.
throw; // XXX Eventually, all should use __c_locale ctor like numpunct
} _M_init_facet(new std::collate<char>);
} _M_init_facet(new std::ctype<char>);
_M_init_facet(new codecvt<char, char, mbstate_t>);
// Construct specific categories, leaving unselected ones alone _M_init_facet(new moneypunct<char, false>(_M_c_locale));
locale::_Impl:: _M_init_facet(new moneypunct<char,true >);
_Impl(const _Impl& __imp, const string& __str, category __cat, size_t __refs) _M_init_facet(new money_get<char>);
: _M_references(__refs - 1) _M_init_facet(new money_put<char>);
{ _M_init_facet(new numpunct<char>(_M_c_locale));
__cat = _S_normalize_category(__cat); // might throw _M_init_facet(new num_get<char>);
_M_init_facet(new num_put<char>);
try _M_init_facet(new time_get<char>);
{ _M_facets = new __vec_facet(*(__imp._M_facets)); } _M_init_facet(new time_put<char>);
catch(...) _M_init_facet(new std::messages<char>);
{
delete _M_facets;
throw;
}
try
{ _M_category_names = new __vec_string(*(__imp._M_category_names)); }
catch(...)
{
delete _M_category_names;
throw;
}
static void(_Impl::* ctors[]) (const char*) =
{
// NB: Order must match the decl order in class locale.
&locale::_Impl::_M_construct_ctype,
&locale::_Impl::_M_construct_numeric,
&locale::_Impl::_M_construct_collate,
&locale::_Impl::_M_construct_time,
&locale::_Impl::_M_construct_monetary,
&locale::_Impl::_M_construct_messages,
0
};
__vec_facet::iterator __it = _M_facets->begin(); #ifdef _GLIBCPP_USE_WCHAR_T
for (; __it != _M_facets->end(); ++__it) _M_init_facet(new std::collate<wchar_t>);
(*__it)->_M_add_reference(); _M_init_facet(new std::ctype<wchar_t>);
_M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
try _M_init_facet(new moneypunct<wchar_t, false>(_M_c_locale));
{ _M_init_facet(new moneypunct<wchar_t,true >);
unsigned mask = (locale::all & -(unsigned)locale::all); _M_init_facet(new money_get<wchar_t>);
for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1)) _M_init_facet(new money_put<wchar_t>);
{ _M_init_facet(new numpunct<wchar_t>(_M_c_locale));
if (!(mask & __cat)) _M_init_facet(new num_get<wchar_t>);
continue; _M_init_facet(new num_put<wchar_t>);
_M_init_facet(new time_get<wchar_t>);
if (mask & __cat) _M_init_facet(new time_put<wchar_t>);
_M_replace_category(_S_classic, _S_facet_categories[ix]); _M_init_facet(new std::messages<wchar_t>);
else #endif
(this->*ctors[ix])(__str.c_str());
}
}
catch(...)
{
__it = _M_facets->begin();
for (; __it != _M_facets->end(); ++__it)
(*__it)->_M_remove_reference();
throw;
}
// XXX May need to be adjusted
if (__cat == all)
_M_name = __str;
_M_has_name = __str != "*";
} }
void void
locale::_Impl:: locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat) _M_replace_categories(const _Impl* __imp, category __cat)
{ {
category __mask = locale::all & -static_cast<unsigned int>(locale::all); const string __none("*");
for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1)) category __mask;
for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix)
{ {
__mask = 1 << __ix;
if (__mask & __cat) if (__mask & __cat)
{ {
// Need to replace entry in _M_facets with other locale's info.
_M_replace_category(__imp, _S_facet_categories[__ix]); _M_replace_category(__imp, _S_facet_categories[__ix]);
(*_M_category_names)[__ix] = (*(__imp->_M_category_names))[__ix]; // If both have names, go ahead and mangle.
if (_M_names[__ix] != __none && __imp->_M_names[__ix] != __none)
_M_names[__ix] = __imp->_M_names[__ix];
} }
} }
} }
...@@ -201,91 +168,36 @@ namespace std { ...@@ -201,91 +168,36 @@ namespace std {
locale::_Impl:: locale::_Impl::
_M_install_facet(const locale::id* __idp, facet* __fp) _M_install_facet(const locale::id* __idp, facet* __fp)
{ {
if (__fp == 0) if (__fp)
return; {
size_t& __index = __idp->_M_index;
size_t& __index = __idp->_M_index; if (!__index)
if (!__index) __index = ++locale::id::_S_highwater; // XXX MT
__index = ++locale::id::_S_highwater; // XXX MT
if (__index >= _M_facets->size())
if (__index >= _M_facets->size()) _M_facets->resize(__index + 1, 0); // might throw
_M_facets->resize(__index + 1, 0); // might throw
facet*& __fpr = (*_M_facets)[__index];
// Order matters, here:
__fp->_M_add_reference();
if (__fpr)
__fpr->_M_remove_reference();
__fpr = __fp;
}
void
locale::_Impl::_M_construct_collate(const char* __s)
{
_M_facet_init(new collate_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new collate_byname<wchar_t>(__s, 0));
#endif
}
void facet*& __fpr = (*_M_facets)[__index];
locale::_Impl::_M_construct_ctype(const char* __s) if (__fpr)
{ {
_M_facet_init(new ctype_byname<char>(__s, 0)); // Replacing an existing facet.
_M_facet_init(new codecvt_byname<char, char, mbstate_t>(__s)); // Order matters, here:
#ifdef _GLIBCPP_USE_WCHAR_T __fp->_M_add_reference();
_M_facet_init(new ctype_byname<wchar_t>(__s, 0)); if (__fpr)
_M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__s)); __fpr->_M_remove_reference();
#endif __fpr = __fp;
} }
else
void {
locale::_Impl::_M_construct_monetary(const char* __s) // Installing a newly created facet into an empty
{ // _M_facets container, say a newly-constructed,
_M_replace_facet(locale::_S_classic, &money_get<char>::id); // swanky-fresh _Impl.
_M_replace_facet(locale::_S_classic, &money_put<char>::id); (*_M_facets)[__index] = __fp;
_M_facet_init(new moneypunct_byname<char, false>(__s, 0)); }
_M_facet_init(new moneypunct_byname<char, true >(__s, 0)); }
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
_M_facet_init(new moneypunct_byname<wchar_t, false>(__s, 0));
_M_facet_init(new moneypunct_byname<wchar_t, true >(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_numeric(const char* __s)
{
_M_replace_facet(locale::_S_classic, &num_get<char>::id);
_M_replace_facet(locale::_S_classic, &num_put<char>::id);
_M_facet_init(new numpunct_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
_M_facet_init(new numpunct_byname<wchar_t>(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_time(const char* __s)
{
_M_facet_init(new time_get_byname<char>(__s, 0));
_M_facet_init(new time_put_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new time_get_byname<wchar_t>(__s, 0));
_M_facet_init(new time_put_byname<wchar_t>(__s, 0));
#endif
}
void
locale::_Impl::_M_construct_messages(const char* __s)
{
_M_facet_init(new messages_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_facet_init(new messages_byname<wchar_t>(__s, 0));
#endif
} }
} }
// 2000-09-13 Benjamin Kosnik <bkoz@redhat.com> // 2000-09-13 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2000 Free Software Foundation // Copyright (C) 2000, 2001 Free Software Foundation
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -33,6 +33,14 @@ typedef std::codecvt_byname<wchar_t, char, std::mbstate_t> w_codecvt_byname; ...@@ -33,6 +33,14 @@ typedef std::codecvt_byname<wchar_t, char, std::mbstate_t> w_codecvt_byname;
class gnu_codecvt: public c_codecvt { }; class gnu_codecvt: public c_codecvt { };
class gnu_facet: public std::locale::facet
{
public:
static std::locale::id id;
};
std::locale::id gnu_facet::id;
void test01() void test01()
{ {
using namespace std; using namespace std;
...@@ -65,14 +73,7 @@ void test01() ...@@ -65,14 +73,7 @@ void test01()
{ VERIFY( false ); } { VERIFY( false ); }
try try
{ VERIFY (has_facet<c_codecvt_byname>(loc02)); } { use_facet<gnu_facet>(loc02); }
catch(bad_cast& obj)
{ VERIFY( true ); }
catch(...)
{ VERIFY( false ); }
try
{ VERIFY (has_facet<w_codecvt_byname>(loc02)); }
catch(bad_cast& obj) catch(bad_cast& obj)
{ VERIFY( true ); } { VERIFY( true ); }
catch(...) catch(...)
...@@ -92,14 +93,7 @@ void test01() ...@@ -92,14 +93,7 @@ void test01()
{ VERIFY( false ); } { VERIFY( false ); }
try try
{ VERIFY (has_facet<c_codecvt_byname>(loc13)); } { use_facet<gnu_facet>(loc13); }
catch(bad_cast& obj)
{ VERIFY( true ); }
catch(...)
{ VERIFY( false ); }
try
{ VERIFY (has_facet<w_codecvt_byname>(loc13)); }
catch(bad_cast& obj) catch(bad_cast& obj)
{ VERIFY( true ); } { VERIFY( true ); }
catch(...) catch(...)
...@@ -134,32 +128,99 @@ void test01() ...@@ -134,32 +128,99 @@ void test01()
// 4 // 4
// locale(const locale& other, const char* std_name, category) // locale(const locale& other, const char* std_name, category)
locale loc09(loc06, "C", locale::ctype); {
VERIFY (loc09.name() != "fr_FR"); // This is the same as 5 only use "C" for loc("C")
VERIFY (loc09.name() != "C"); locale loc09(loc06, "C", locale::ctype);
VERIFY (loc09 != loc01); VERIFY (loc09.name() != "fr_FR");
VERIFY (loc09 != loc06); VERIFY (loc09.name() != "C");
// XXX somehow check that the ctype, codecvt facets have "C" locale bits... VERIFY (loc09.name() != "*");
VERIFY (loc09 != loc01);
locale loc10(loc02, "C", locale::ctype); VERIFY (loc09 != loc06);
VERIFY (loc10.name() == "*");
VERIFY (loc10 != loc01); // As not named, even tho facets same... locale loc10(loc02, "C", locale::ctype);
VERIFY (loc10 != loc02); VERIFY (loc10.name() == "*");
// XXX somehow check that the ctype, codecvt facets have "C" locale bits... VERIFY (loc10 != loc01); // As not named, even tho facets same...
VERIFY (loc10 != loc02);
locale loc11(loc01, "C", locale::ctype);
VERIFY (loc11.name() == "C"); locale loc11(loc01, "C", locale::ctype);
VERIFY (loc11 == loc01); VERIFY (loc11.name() == "C");
// XXX somehow check that the ctype, codecvt facets have "C" locale bits... VERIFY (loc11 == loc01);
try try
{ locale loc12(loc01, static_cast<const char*>(NULL), locale::ctype); } { locale loc12(loc01, static_cast<const char*>(NULL), locale::ctype); }
catch(runtime_error& obj) catch(runtime_error& obj)
{ VERIFY (true); } { VERIFY (true); }
catch(...) catch(...)
{ VERIFY (false); } { VERIFY (false); }
try
{ locale loc13(loc01, "localized by the wu-tang clan", locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
locale loc14(loc06, "C", locale::none);
VERIFY (loc14.name() == "fr_FR");
VERIFY (loc14 == loc06);
locale loc15(loc06, "C", locale::collate);
VERIFY (loc15.name() != "fr_FR");
VERIFY (loc15.name() != "C");
VERIFY (loc15.name() != "*");
VERIFY (loc15.name() != loc09.name());
VERIFY (loc15 != loc01);
VERIFY (loc15 != loc06);
VERIFY (loc15 != loc09);
}
// 5
// locale(const locale& other, const locale& one, category)
{
// This is the exact same as 4, with locale("C") for "C"
locale loc09(loc06, loc01, locale::ctype);
VERIFY (loc09.name() != "fr_FR");
VERIFY (loc09.name() != "C");
VERIFY (loc09.name() != "*");
VERIFY (loc09 != loc01);
VERIFY (loc09 != loc06);
locale loc10(loc02, loc01, locale::ctype);
VERIFY (loc10.name() == "*");
VERIFY (loc10 != loc01); // As not named, even tho facets same...
VERIFY (loc10 != loc02);
locale loc11(loc01, loc01, locale::ctype);
VERIFY (loc11.name() == "C");
VERIFY (loc11 == loc01);
try
{ locale loc12(loc01, static_cast<const char*>(NULL), locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
try
{ locale loc13(loc01, locale("wu-tang clan"), locale::ctype); }
catch(runtime_error& obj)
{ VERIFY (true); }
catch(...)
{ VERIFY (false); }
locale loc14(loc06, loc01, locale::none);
VERIFY (loc14.name() == "fr_FR");
VERIFY (loc14 == loc06);
locale loc15(loc06, loc01, locale::collate);
VERIFY (loc15.name() != "fr_FR");
VERIFY (loc15.name() != "C");
VERIFY (loc15.name() != "*");
VERIFY (loc15.name() != loc09.name());
VERIFY (loc15 != loc01);
VERIFY (loc15 != loc06);
VERIFY (loc15 != loc09);
}
} }
#endif /* !defined(_GLIBCPP_USE_WCHAR_T) */ #endif /* !defined(_GLIBCPP_USE_WCHAR_T) */
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <cwchar> // for mbstate_t #include <cwchar> // for mbstate_t
#include <locale> #include <locale>
#include <stdexcept>
#include <string>
#include <iterator> #include <iterator>
#include <debug_assert.h> #include <debug_assert.h>
...@@ -169,37 +171,66 @@ std::locale::id gnu_facet::id; ...@@ -169,37 +171,66 @@ std::locale::id gnu_facet::id;
void test01() void test01()
{ {
// 1 bool test = true;
gnu_collate obj01; const std::string name_no("*");
gnu_ctype obj02; const std::string name_c("C");
gnu_codecvt obj03;
gnu_moneypunct obj04; try
gnu_moneypunct_true obj05; {
gnu_money_get obj06; gnu_collate obj01;
gnu_money_put obj07; gnu_ctype obj02;
gnu_numpunct obj08; gnu_codecvt obj03;
gnu_num_get obj09; gnu_moneypunct obj04;
gnu_num_put obj10; gnu_moneypunct_true obj05;
gnu_time_get obj11; gnu_money_get obj06;
gnu_time_put obj12; gnu_money_put obj07;
gnu_messages obj13; gnu_numpunct obj08;
gnu_time_put_out obj14(0); gnu_num_get obj09;
gnu_time_put_byname obj15("gnu_message_byname", 0); gnu_num_put obj10;
gnu_time_get_in obj16(0); gnu_time_get obj11;
gnu_time_get_byname obj17("gnu_message_byname", 0); gnu_time_put obj12;
gnu_num_put_out obj18(0); gnu_messages obj13;
gnu_num_get_in obj19(0); gnu_time_put_out obj14(0);
gnu_numpunct_byname obj20("gnu_message_byname", 0); gnu_time_put_byname obj15("C", 0);
gnu_money_put_out obj21(0); gnu_time_get_in obj16(0);
gnu_money_get_in obj22(0); gnu_time_get_byname obj17("C", 0);
gnu_moneypunct_byname_false obj23("gnu_message_byname", 0); gnu_num_put_out obj18(0);
gnu_moneypunct_byname_true obj24("gnu_message_byname", 0); gnu_num_get_in obj19(0);
gnu_ctype_byname obj25("gnu_message_byname", 0); gnu_numpunct_byname obj20("C", 0);
gnu_collate_byname obj26("gnu_message_byname", 0); gnu_money_put_out obj21(0);
gnu_messages_byname obj27("gnu_message_byname", 0); gnu_money_get_in obj22(0);
gnu_moneypunct_byname_false obj23("C", 0);
gnu_moneypunct_byname_true obj24("C", 0);
gnu_ctype_byname obj25("C", 0);
gnu_collate_byname obj26("C", 0);
gnu_messages_byname obj27("C", 0);
}
catch (std::runtime_error& obj)
{
// named locale not valid
VERIFY( false );
}
catch (std::exception& obj)
{
// some other error
VERIFY( false );
}
// 2 // 2
gnu_facet obj28; try
{
gnu_facet obj28;
}
catch (std::runtime_error& obj)
{
// named locale not valid
VERIFY( false );
}
catch (std::exception& obj)
{
// some other error
VERIFY( false );
}
} }
int main () int main ()
......
// 2001-01-19 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// 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.
// 22.2.3.1.1 numpunct members
#include <locale>
#include <string>
#include <debug_assert.h>
// creating unnamed locales 1 using new + combine
void
test01()
{
using namespace std;
bool test = true;
const string name_c("C");
const string str_unnamed("*");
string str;
// construct a locale object with the specialized facet.
locale loc_c = locale::classic();
locale loc_1(locale::classic(), new numpunct<char>);
// check names
VERIFY( loc_c.name() == name_c );
VERIFY( loc_1.name() == str_unnamed );
// sanity check the constructed locale has the specialized facet.
VERIFY( has_facet<numpunct<char> >(loc_1) );
VERIFY( has_facet<numpunct<char> >(loc_c) );
// extract facet
const numpunct<char>& f_nump_1 = use_facet<numpunct<char> >(loc_1);
const numpunct<char>& f_nump_c = use_facet<numpunct<char> >(loc_c);
// attempt to re-synthesize classic locale
locale loc_2 = loc_1.combine<numpunct<char> >(loc_c);
VERIFY( loc_2.name() == str_unnamed );
VERIFY( loc_2 != loc_c );
}
void
test02()
{
using namespace std;
bool test = true;
const string name_c("C");
const string name_no("*");
string str;
// construct a locale object with the specialized facet.
locale loc_c = locale::classic();
locale loc_1(locale::classic(),
new numpunct_byname<char>("fr_FR"));
locale loc_fr("fr_FR");
// check names
VERIFY( loc_c.name() == name_c );
VERIFY( loc_1.name() == name_no );
// sanity check the constructed locale has the specialized facet.
VERIFY( has_facet<numpunct<char> >(loc_1) );
VERIFY( has_facet<numpunct<char> >(loc_c) );
// attempt to re-synthesize classic locale
locale loc_2 = loc_1.combine<numpunct<char> >(loc_c);
VERIFY( loc_2.name() == name_no );
VERIFY( loc_2 != loc_c );
// extract facet
const numpunct<char>& f_nump_1 = use_facet<numpunct<char> >(loc_1);
const numpunct<char>& f_nump_2 = use_facet<numpunct<char> >(loc_2);
const numpunct<char>& f_nump_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& f_nump_fr = use_facet<numpunct<char> >(loc_fr);
// sanity check the data is correct.
char dp1 = f_nump_c.decimal_point();
char th1 = f_nump_c.thousands_sep();
string g1 = f_nump_c.grouping();
string t1 = f_nump_c.truename();
string f1 = f_nump_c.falsename();
char dp2 = f_nump_1.decimal_point();
char th2 = f_nump_1.thousands_sep();
string g2 = f_nump_1.grouping();
string t2 = f_nump_1.truename();
string f2 = f_nump_1.falsename();
char dp3 = f_nump_2.decimal_point();
char th3 = f_nump_2.thousands_sep();
string g3 = f_nump_2.grouping();
string t3 = f_nump_2.truename();
string f3 = f_nump_2.falsename();
char dp4 = f_nump_fr.decimal_point();
char th4 = f_nump_fr.thousands_sep();
string g4 = f_nump_fr.grouping();
string t4 = f_nump_fr.truename();
string f4 = f_nump_fr.falsename();
#if 0
// XXX these should not be the same if named locales are working correctly.
VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 );
#endif
VERIFY( dp1 == dp3 );
VERIFY( th1 == th3 );
VERIFY( t1 == t3 );
VERIFY( f1 == f3 );
}
int main()
{
test01();
test02();
return 0;
}
// 2001-01-23 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// 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.
// 22.2.3 the numeric punctuation facet
#include <locale>
// Should be able to instantiate this for other types besides char, wchar_t
class gnu_numpunct: public std::numpunct<unsigned char>
{ };
int main()
{
gnu_numpunct facet01;
return 0;
}
// 2001-01-24 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// 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.
// 22.2.3.2 Template class numpunct_byname
#include <locale>
#include <debug_assert.h>
void test01()
{
using namespace std;
bool test = true;
string str;
locale loc_byname(locale::classic(), new numpunct_byname<char>("de_DE"));
str = loc_byname.name();
locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_de != loc_byname );
// cache the numpunct facets
const numpunct<char>& nump_byname = use_facet<numpunct<char> >(loc_byname);
const numpunct<char>& nump_de = use_facet<numpunct<char> >(loc_de);
// sanity check that the data match
char dp1 = nump_byname.decimal_point();
char th1 = nump_byname.thousands_sep();
string g1 = nump_byname.grouping();
string t1 = nump_byname.truename();
string f1 = nump_byname.falsename();
char dp2 = nump_de.decimal_point();
char th2 = nump_de.thousands_sep();
string g2 = nump_de.grouping();
string t2 = nump_de.truename();
string f2 = nump_de.falsename();
VERIFY( dp1 == dp2 );
VERIFY( th1 == th2 );
VERIFY( g1 == g2 );
VERIFY( t1 == t2 );
VERIFY( f1 == f2 );
}
int main()
{
test01();
return 0;
}
// 2001-01-17 bkoz
// Copyright (C) 2001 Free Software Foundation
//
// 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.
// 22.2.3.1.1 nunpunct members
#include <locale>
#include <debug_assert.h>
void test01()
{
using namespace std;
bool test = true;
string str;
// basic construction
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_us("en_US");
str = loc_us.name();
VERIFY( loc_c != loc_us );
locale loc_fr("fr_FR");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
VERIFY( loc_us != loc_fr );
locale loc_combo(loc_us, loc_fr, locale::numeric);
str = loc_combo.name();
VERIFY( loc_combo != loc_fr );
VERIFY( loc_combo != loc_us );
VERIFY( loc_combo != loc_c );
// cache the numpunct facets
const numpunct<char>& nump_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& nump_us = use_facet<numpunct<char> >(loc_us);
const numpunct<char>& nump_fr = use_facet<numpunct<char> >(loc_fr);
const numpunct<char>& nump_combo = use_facet<numpunct<char> >(loc_combo);
// sanity check the data is correct.
char dp1 = nump_c.decimal_point();
char th1 = nump_c.thousands_sep();
string g1 = nump_c.grouping();
string t1 = nump_c.truename();
string f1 = nump_c.falsename();
char dp2 = nump_us.decimal_point();
char th2 = nump_us.thousands_sep();
string g2 = nump_us.grouping();
string t2 = nump_us.truename();
string f2 = nump_us.falsename();
char dp3 = nump_fr.decimal_point();
char th3 = nump_fr.thousands_sep();
string g3 = nump_fr.grouping();
string t3 = nump_fr.truename();
string f3 = nump_fr.falsename();
char dp4 = nump_combo.decimal_point();
char th4 = nump_combo.thousands_sep();
string g4 = nump_combo.grouping();
string t4 = nump_combo.truename();
string f4 = nump_combo.falsename();
}
int main()
{
test01();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment