summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/localename.cc
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-30 09:18:51 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-30 09:18:51 +0000
commit2075288447ec881925fcc28e26b5b1b74944d48d (patch)
treef4cd5b7db4af6680ea3aecdacddb39448df7480b /libstdc++-v3/src/localename.cc
parenta53082e99f3957527c9cf36935f4de3e30d71613 (diff)
downloadgcc-2075288447ec881925fcc28e26b5b1b74944d48d.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39347 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src/localename.cc')
-rw-r--r--libstdc++-v3/src/localename.cc272
1 files changed, 92 insertions, 180 deletions
diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc
index f028765a61e..867b063fbfb 100644
--- a/libstdc++-v3/src/localename.cc
+++ b/libstdc++-v3/src/localename.cc
@@ -25,7 +25,6 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-
#include <bits/std_clocale.h>
#include <bits/std_locale.h>
#include <bits/std_cstring.h>
@@ -33,21 +32,21 @@
#include <bits/std_stdexcept.h>
namespace std {
-
locale::_Impl::
~_Impl() throw()
{
- std::vector<facet*>::iterator it = _M_facets->begin();
+ __vec_facet::iterator it = _M_facets->begin();
for (; it != _M_facets->end(); ++it)
- (*it)->_M_remove_reference();
+ if (*it)
+ (*it)->_M_remove_reference();
delete _M_facets;
- delete _M_category_names;
+ locale::facet::_S_destroy_c_locale(_M_c_locale);
}
+ // Clone existing _Impl object.
locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs)
- : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
- _M_has_name(__imp._M_has_name), _M_name(__imp._M_name)
+ : _M_references(__refs - 1), _M_facets(0), _M_c_locale(0) // XXX
{
try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); }
@@ -57,121 +56,89 @@ namespace std {
throw;
}
- try
- { _M_category_names = new __vec_string(*(__imp._M_category_names)); }
- catch(...)
- {
- delete _M_category_names;
- throw;
- }
+ for (size_t i = 0; i < _S_num_categories; ++i)
+ _M_names[i] = __imp._M_names[i];
- std::vector<facet*>::iterator __it = _M_facets->begin();
+ __vec_facet::iterator __it = _M_facets->begin();
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,
- // including the standard "C" locale.
+ // Construct named _Impl, including the standard "C" locale.
locale::_Impl::
- _Impl(size_t __num, size_t __refs, bool __has_name, string __str)
- : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
- _M_has_name(__has_name), _M_name(__str)
+ _Impl(string __str, size_t __refs)
+ : _M_references(__refs - 1), _M_facets(0)
{
+ // 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
- { _M_facets = new __vec_facet(__num, NULL); }
+ { _M_facets = new __vec_facet(_S_num_facets, NULL); }
catch(...)
{
delete _M_facets;
throw;
}
- try
- { _M_category_names = new __vec_string(_S_categories_num, _M_name); }
- catch(...)
- {
- delete _M_category_names;
- throw;
- }
- }
-
- // Construct specific categories, leaving unselected ones alone
- locale::_Impl::
- _Impl(const _Impl& __imp, const string& __str, category __cat, size_t __refs)
- : _M_references(__refs - 1)
- {
- __cat = _S_normalize_category(__cat); // might throw
-
- try
- { _M_facets = new __vec_facet(*(__imp._M_facets)); }
- catch(...)
- {
- 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
- };
+ // Name all the categories.
+ for (size_t i = 0; i < _S_num_categories; ++i)
+ _M_names[i] = __str;
+
+ // Construct all standard facets and add them to _M_facets.
+ // 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>);
+ _M_init_facet(new moneypunct<char, false>(_M_c_locale));
+ _M_init_facet(new moneypunct<char,true >);
+ _M_init_facet(new money_get<char>);
+ _M_init_facet(new money_put<char>);
+ _M_init_facet(new numpunct<char>(_M_c_locale));
+ _M_init_facet(new num_get<char>);
+ _M_init_facet(new num_put<char>);
+ _M_init_facet(new time_get<char>);
+ _M_init_facet(new time_put<char>);
+ _M_init_facet(new std::messages<char>);
- __vec_facet::iterator __it = _M_facets->begin();
- for (; __it != _M_facets->end(); ++__it)
- (*__it)->_M_add_reference();
-
- try
- {
- unsigned mask = (locale::all & -(unsigned)locale::all);
- for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
- {
- if (!(mask & __cat))
- continue;
-
- if (mask & __cat)
- _M_replace_category(_S_classic, _S_facet_categories[ix]);
- else
- (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 != "*";
+#ifdef _GLIBCPP_USE_WCHAR_T
+ _M_init_facet(new std::collate<wchar_t>);
+ _M_init_facet(new std::ctype<wchar_t>);
+ _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
+ _M_init_facet(new moneypunct<wchar_t, false>(_M_c_locale));
+ _M_init_facet(new moneypunct<wchar_t,true >);
+ _M_init_facet(new money_get<wchar_t>);
+ _M_init_facet(new money_put<wchar_t>);
+ _M_init_facet(new numpunct<wchar_t>(_M_c_locale));
+ _M_init_facet(new num_get<wchar_t>);
+ _M_init_facet(new num_put<wchar_t>);
+ _M_init_facet(new time_get<wchar_t>);
+ _M_init_facet(new time_put<wchar_t>);
+ _M_init_facet(new std::messages<wchar_t>);
+#endif
}
void
locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat)
{
- category __mask = locale::all & -static_cast<unsigned int>(locale::all);
- for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
+ const string __none("*");
+ category __mask;
+ for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix)
{
+ __mask = 1 << __ix;
if (__mask & __cat)
{
+ // Need to replace entry in _M_facets with other locale's info.
_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 {
locale::_Impl::
_M_install_facet(const locale::id* __idp, facet* __fp)
{
- if (__fp == 0)
- return;
-
- size_t& __index = __idp->_M_index;
- if (!__index)
- __index = ++locale::id::_S_highwater; // XXX MT
-
- if (__index >= _M_facets->size())
- _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
- }
+ if (__fp)
+ {
+ size_t& __index = __idp->_M_index;
+ if (!__index)
+ __index = ++locale::id::_S_highwater; // XXX MT
+
+ if (__index >= _M_facets->size())
+ _M_facets->resize(__index + 1, 0); // might throw
- void
- locale::_Impl::_M_construct_ctype(const char* __s)
- {
- _M_facet_init(new ctype_byname<char>(__s, 0));
- _M_facet_init(new codecvt_byname<char, char, mbstate_t>(__s));
-#ifdef _GLIBCPP_USE_WCHAR_T
- _M_facet_init(new ctype_byname<wchar_t>(__s, 0));
- _M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__s));
-#endif
- }
-
- void
- locale::_Impl::_M_construct_monetary(const char* __s)
- {
- _M_replace_facet(locale::_S_classic, &money_get<char>::id);
- _M_replace_facet(locale::_S_classic, &money_put<char>::id);
- _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
+ facet*& __fpr = (*_M_facets)[__index];
+ if (__fpr)
+ {
+ // Replacing an existing facet.
+ // Order matters, here:
+ __fp->_M_add_reference();
+ if (__fpr)
+ __fpr->_M_remove_reference();
+ __fpr = __fp;
+ }
+ else
+ {
+ // Installing a newly created facet into an empty
+ // _M_facets container, say a newly-constructed,
+ // swanky-fresh _Impl.
+ (*_M_facets)[__index] = __fp;
+ }
+ }
}
}
+