glibc/locale/uselocale.c
Roland McGrath 1a0d874ed4 Make uselocale support static linking.
* locale/xlocale.c: Revert changes putting _nl_global_locale here.
	This file again just defines _nl_C_locobj.
	(_nl_C_locobj): Use a categories.def iterator in the initializer.
	* locale/global-locale.c: New file.  Define _nl_global_locale here,
	using all weak references in the initializer.
	* locale/Makefile (aux): Add global-locale.
	* locale/localeinfo.h (_nl_global_locale, _NL_CURRENT_LOCALE): Make
	these unconditional, along with the tsd decl.
	[!SHARED && HAVE___THREAD && HAVE_WEAK_SYMBOLS] (NL_CURRENT_INDIRECT):
	Define it under these conditions.
	[NL_CURRENT_INDIRECT]: Test this instead of [! SHARED].
	Don't declare _nl_current.  Declare _nl_current_LC_FOO as
	`extern __thread struct locale_data *const *'.
	[NL_CURRENT_INDIRECT]
	(_NL_CURRENT_DATA, _NL_CURRENT, _NL_CURRENT_WSTR): Add indirection.
	[NL_CURRENT_INDIRECT] (_NL_CURRENT_DEFINE): Rewritten.  Define
	the thread variable _nl_current_LC_FOO and also a special absolute
	symbol _nl_current_LC_FOO_used.
	* locale/uselocale.c (__uselocale) [NL_CURRENT_INDIRECT]:
	Set each _nl_current_LC_FOO symbol to point into the new locale,
	using weak references to test if _nl_current_LC_FOO_used was linked in.
	* locale/setlocale.c [! SHARED]: Replace this conditional ...
	[NL_CURRENT_INDIRECT]: ... with this one.
	(_nl_current, _nl_C): Variables removed.
	[NL_CURRENT_INDIRECT] (_nl_current_used): New variable, table of
	weak references to _nl_current_LC_FOO_used.
	[NL_CURRENT_INDIRECT] (CATEGORY_USED): Define using that table.
	(free_category): New function, broken out of ...
	(free_mem): ... here.  Call that.
	(free_mem) [NL_CURRENT_INDIRECT]: Use a categories.def iterator
	instead of a loop.

	__USING_NAMESPACE_C99 depending on _GLIBCPP_USE_NAMESPACES.
2002-08-28 10:39:23 +00:00

71 lines
2.7 KiB
C

/* uselocale -- fetch and set the current per-thread locale
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <locale.h>
#include "localeinfo.h"
/* Switch the current thread's locale to DATASET.
If DATASET is null, instead just return the current setting.
The special value LC_GLOBAL_LOCALE is the initial setting
for all threads, and means the thread uses the global
setting controlled by `setlocale'. */
locale_t
__uselocale (locale_t newloc)
{
if (newloc == NULL)
{
locale_t loc = __libc_tsd_get (LOCALE);
return loc == &_nl_global_locale ? LC_GLOBAL_LOCALE : loc;
}
else
{
const locale_t locobj
= newloc == LC_GLOBAL_LOCALE ? &_nl_global_locale : newloc;
__libc_tsd_set (LOCALE, locobj);
#ifdef NL_CURRENT_INDIRECT
/* Now we must update all the per-category thread-local variables to
point into the new current locale for this thread. The magic
symbols _nl_current_LC_FOO_used are defined to meaningless values
if _nl_current_LC_FOO was linked in. By using weak references to
both symbols and testing the address of _nl_current_LC_FOO_used,
we can avoid accessing the _nl_current_LC_FOO thread-local
variable at all when no code referring to it was linked in. We
need the special bogus symbol because while TLS symbols can be
weak, there is no reasonable way to test for the default-zero
value as with a heap symbol (taking the address would just use
some bogus offset from our thread pointer). */
# define DEFINE_CATEGORY(category, category_name, items, a) \
{ \
extern char _nl_current_##category##_used; \
weak_extern (_nl_current_##category##_used) \
weak_extern (_nl_current_##category) \
if (&_nl_current_##category##_used != 0) \
_nl_current_##category = &locobj->__locales[category]; \
}
# include "categories.def"
# undef DEFINE_CATEGORY
#endif
}
return newloc;
}
weak_alias (__uselocale, uselocale)