1/*
2 * Copyright 2022, Trung Nguyen, trungnt282910@gmail.com
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6
7#include <ctype.h>
8
9#include <tls.h>
10#include <kernel/OS.h>
11#include <ThreadLocale.h>
12
13
14// From glibc's localeinfo.h
15extern BPrivate::Libroot::GlibcLocaleStruct _nl_global_locale;
16
17
18namespace BPrivate {
19namespace Libroot {
20
21
22static void DestroyThreadLocale(void* ptr)
23{
24	ThreadLocale* threadLocale = (ThreadLocale*)ptr;
25	delete threadLocale;
26}
27
28
29ThreadLocale*
30GetCurrentThreadLocale()
31{
32	ThreadLocale* threadLocale = (ThreadLocale*)tls_get(TLS_LOCALE_SLOT);
33	if (threadLocale == NULL) {
34		threadLocale = new ThreadLocale();
35		threadLocale->glibcLocaleStruct = _nl_global_locale;
36		threadLocale->threadLocaleInfo = NULL;
37		on_exit_thread(DestroyThreadLocale, threadLocale);
38		tls_set(TLS_LOCALE_SLOT, threadLocale);
39	}
40	return threadLocale;
41}
42
43
44// Exported so that glibc could also use.
45extern "C" GlibcLocaleStruct*
46_nl_current_locale()
47{
48	return &GetCurrentThreadLocale()->glibcLocaleStruct;
49}
50
51
52extern "C" const unsigned short**
53__ctype_b_loc()
54{
55	return &GetCurrentThreadLocale()->glibcLocaleStruct.__ctype_b;
56}
57
58
59extern "C" const int**
60__ctype_tolower_loc()
61{
62	return &GetCurrentThreadLocale()->glibcLocaleStruct.__ctype_tolower;
63}
64
65
66extern "C" const int**
67__ctype_toupper_loc()
68{
69	return &GetCurrentThreadLocale()->glibcLocaleStruct.__ctype_toupper;
70}
71
72
73}	// namespace Libroot
74}	// namespace BPrivate
75