]> git.ipfire.org Git - thirdparty/glibc.git/blame - locale/uselocale.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / locale / uselocale.c
CommitLineData
30c14c31 1/* uselocale -- fetch and set the current per-thread locale
6d7e8eda 2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
30c14c31
RM
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
30c14c31
RM
18
19#include <locale.h>
20#include "localeinfo.h"
cf684340 21#include <ctype.h>
30c14c31 22
30c14c31
RM
23/* Switch the current thread's locale to DATASET.
24 If DATASET is null, instead just return the current setting.
25 The special value LC_GLOBAL_LOCALE is the initial setting
26 for all threads, and means the thread uses the global
27 setting controlled by `setlocale'. */
28locale_t
29__uselocale (locale_t newloc)
30{
ccadf7b5 31 locale_t oldloc = _NL_CURRENT_LOCALE;
426bf3a3
RM
32
33 if (newloc != NULL)
30c14c31 34 {
1a0d874e
RM
35 const locale_t locobj
36 = newloc == LC_GLOBAL_LOCALE ? &_nl_global_locale : newloc;
af85385f 37 __libc_tsd_set (locale_t, LOCALE, locobj);
1a0d874e
RM
38
39#ifdef NL_CURRENT_INDIRECT
40 /* Now we must update all the per-category thread-local variables to
41 point into the new current locale for this thread. The magic
42 symbols _nl_current_LC_FOO_used are defined to meaningless values
43 if _nl_current_LC_FOO was linked in. By using weak references to
44 both symbols and testing the address of _nl_current_LC_FOO_used,
45 we can avoid accessing the _nl_current_LC_FOO thread-local
46 variable at all when no code referring to it was linked in. We
47 need the special bogus symbol because while TLS symbols can be
48 weak, there is no reasonable way to test for the default-zero
49 value as with a heap symbol (taking the address would just use
50 some bogus offset from our thread pointer). */
51
52# define DEFINE_CATEGORY(category, category_name, items, a) \
53 { \
54 extern char _nl_current_##category##_used; \
55 weak_extern (_nl_current_##category##_used) \
56 weak_extern (_nl_current_##category) \
57 if (&_nl_current_##category##_used != 0) \
58 _nl_current_##category = &locobj->__locales[category]; \
59 }
60# include "categories.def"
61# undef DEFINE_CATEGORY
62#endif
cf684340
RM
63
64 /* Update the special tsd cache of some locale data. */
4b23f9bd
JJ
65 __libc_tsd_set (const uint16_t *, CTYPE_B, (void *) locobj->__ctype_b);
66 __libc_tsd_set (const int32_t *, CTYPE_TOLOWER,
67 (void *) locobj->__ctype_tolower);
68 __libc_tsd_set (const int32_t *, CTYPE_TOUPPER,
69 (void *) locobj->__ctype_toupper);
30c14c31 70 }
1a0d874e 71
426bf3a3 72 return oldloc == &_nl_global_locale ? LC_GLOBAL_LOCALE : oldloc;
30c14c31 73}
73f50d5a 74libc_hidden_def (__uselocale)
30c14c31 75weak_alias (__uselocale, uselocale)