This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Need locale help
- From: François Dumont <francois dot cppdevs at free dot fr>
- To: libstdc++ at gcc dot gnu dot org
- Date: Mon, 06 Dec 2010 21:49:39 +0100
- Subject: Need locale help
Hello
In order to finally have all tests running on my distrib I have
started working on locale tests that are failing on my side. I have
started with a simple one 22_locale/messages/members/char/1.cc. I
discovered that when run this test was looking for the catalog in '.'
folder. So it means that it is looking for the catalog in current test
folder so my first question is: what is the test execution folder ?
I then try to modify the test to give it an absolute path to my
test folder rather than '.'. I pass
"/home/fdt/dev/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/testsuite",
is it the place where the catalog should be taken ? At least I found a
'de' and 'fr' folder in this folder with the LC_MESSAGES/libstdc++.mo
files within it so I guessed it was the right place. However the test is
looking for 'de_DE' locale but the folder is 'de' I wonder if it was an
issue but creating a link de_DE folder didn't gave better result.
So I start to look at code of the 'gnu' mode and was surprise to
see that what is documented as 'complete and fully functional' is a
little bit limited. When you open a catalog it always return 0 so if you
want to play with 2 catalogs the second open will override the first one
and you won't have the expected result. IMO we should use dgettext
rather than gettext and keep a mapping within the lib to associate a
'catalog' value to each domain. We could then get the domain back when
we need it in do_get method to call dgettext. This is just an idea that
I haven't study in detail for the moment.
As I couldn't have the gnu mode to work I try the ieee_1003.1-2001
mode. First, it do not build, it looks like no one try it for a long
time. As far as I understand the doc the ieee mode is some kind of gnu
mode with only usage of catopen/catgets instead of testdomain/gettext.
However if you check the config/locale/ieee... folder you see that there
is also c_locale.h/c_locale.c files that are incomplete to build the
lib. In my opinion ieee mode should simply use the same files as the gnu
modes except the messages_members.h/.cc files, no ? This is what I am
trying so far but with no success. How can I tell the build system to
use everything from gnu except messages files ? I try to edit configure
script where I found definition of CLOCALE_H, CCODECVT_CC... to point to
gnu files but it still tries to get things from ieee folder when I
build. I don't know the automake/autoconf stuff but I know that the
configure script is normally generated, what file should I edit to
change this behavior ?
Additionally I notice that messages_member.h/.cc files are not
valid, especially on a 64 bits platform because it tries to cast a
nl_catd to a catalog that is to say a void* to an int. This is why you
will find attached a proposition of updated implementation based on an
internal storage similar to what should be done on gnu side. I haven't
been able to use mutex in the messages_members.cc files for the moment...
Thanks in advance for any help.
// std::messages implementation details, IEEE 1003.1-200x version -*- C++ -*-
// Copyright (C) 2001, 2009 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 22.2.7.1.2 messages virtual functions
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#include <locale>
#include <map>
//#include <mutex>
#include <nl_types.h>
namespace
{
class catd_storage
{
typedef std::messages_base::catalog catalog;
catalog _M_counter;
//std::mutex _M_mutex;
std::map<catalog, nl_catd> _M_cats;
public:
catd_storage() : _M_counter(0)
{}
catalog add(nl_catd __catd)
{
//std::lock_guard lock(_M_mutex);
return _M_cats.insert(std::make_pair(_M_counter++, __catd)).first->first;
}
std::pair<bool, nl_catd> get(catalog __cat) const
{
//std::lock_guard lock(_M_mutex);
std::map<catalog, nl_catd>::const_iterator __it =
_M_cats.find(__cat);
if (__it != _M_cats.end())
return std::make_pair(true, __it->second);
return std::make_pair(false, nl_catd());
}
std::pair<bool, nl_catd> erase(catalog __cat)
{
//std::lock_guard lock(_M_mutex);
std::map<catalog, nl_catd>::iterator __it =
_M_cats.find(__cat);
if (__it != _M_cats.end())
{
std::pair<bool, nl_catd> ret(true, __it->second);
_M_cats.erase(__it);
return ret;
}
return std::make_pair(false, nl_catd());
}
};
catd_storage& get_storage()
{
static catd_storage __storage;
return __storage;
}
}
namespace std
{
// Specializations
template<>
typename messages<char>::catalog
messages<char>::do_open(const basic_string<char>& __s,
const locale&) const
{
nl_catd __nlc = catopen(__s.c_str(), NL_CAT_LOCALE);
return get_storage().add(__nlc);
}
template<>
string
messages<char>::do_get(catalog __c, int __setid, int __msgid,
const string& __dfault) const
{
pair<bool, nl_catd> __ret = get_storage().get(__c);
if (__ret.first)
{
return string(catgets(__ret.second, __setid, __msgid,
__dfault.c_str()));
}
return __dfault;
}
template<>
void
messages<char>::do_close(catalog __c) const
{
pair<bool, nl_catd> __ret = get_storage().erase(__c);
if (__ret.first)
{
catclose(__ret.second);
}
}
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
typename messages<wchar_t>::catalog
messages<wchar_t>::do_open(const basic_string<char>& __s,
const locale&) const
{
nl_catd __nlc = catopen(__s.c_str(), NL_CAT_LOCALE);
return get_storage().add(__nlc);
}
template<>
wstring
messages<wchar_t>::do_get(catalog __c, int __setid, int __msgid,
const wstring& __dfault) const
{
pair<bool, nl_catd> __ret = get_storage().get(__c);
if (__ret.first)
{
const char* __cdflt = "";
char* __msg = catgets(__ret.second, __setid, __msgid, __cdflt);
return __msg == __cdflt
? __dfault
: _M_convert_from_char(__msg);
}
return __dfault;
}
template<>
void
messages<wchar_t>::do_close(catalog __c) const
{
pair<bool, nl_catd> __ret = get_storage().erase(__c);
if (__ret.first)
{
catclose(__ret.second);
}
}
#endif
}
// std::messages implementation details, IEEE 1003.1-200x version -*- C++ -*-
// Copyright (C) 2001, 2009 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file messages_members.h
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882: 22.2.7.1.2 messages virtual functions
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
_GLIBCXX_BEGIN_NAMESPACE(std)
// Non-virtual member functions.
template<typename _CharT>
typename messages<_CharT>::catalog
messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
const char*) const
{ return this->do_open(__s, __loc); }
// Virtual member functions.
template<typename _CharT>
messages<_CharT>::~messages()
{ }
template<>
messages<char>::catalog
messages<char>::do_open(const basic_string<char>&, const locale&) const;
template<>
void
messages<char>::do_close(catalog) const;
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
messages<wchar_t>::catalog
messages<wchar_t>::do_open(const basic_string<char>&, const locale&) const;
template<>
void
messages<wchar_t>::do_close(catalog) const;
#endif
_GLIBCXX_END_NAMESPACE