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#include <errno.h>
9#include <locale.h>
10#include <string.h>
11#include <wctype.h>
12
13#include <errno_private.h>
14
15#include "LocaleBackend.h"
16
17
18using BPrivate::Libroot::GetCurrentLocaleBackend;
19using BPrivate::Libroot::LocaleBackend;
20using BPrivate::Libroot::LocaleBackendData;
21
22
23int
24iswctype_l(wint_t wc, wctype_t charClass, locale_t l)
25{
26	LocaleBackendData* locale = (LocaleBackendData*)l;
27	LocaleBackend* backend = locale->backend;
28
29	if (backend == NULL) {
30		if (wc < 0 || wc > 127)
31			return 0;
32		return __isctype(wc, charClass);
33	}
34
35	return backend->IsWCType(wc, charClass);
36}
37
38
39int
40iswalnum_l(wint_t wc, locale_t locale)
41{
42	return iswctype_l(wc, _ISalnum, locale);
43}
44
45
46int
47iswalpha_l(wint_t wc, locale_t locale)
48{
49	return iswctype_l(wc, _ISalpha, locale);
50}
51
52
53int
54iswblank_l(wint_t wc, locale_t locale)
55{
56	return iswctype_l(wc, _ISblank, locale);
57}
58
59
60int
61iswcntrl_l(wint_t wc, locale_t locale)
62{
63	return iswctype_l(wc, _IScntrl, locale);
64}
65
66
67int
68iswdigit_l(wint_t wc, locale_t locale)
69{
70	return iswctype_l(wc, _ISdigit, locale);
71}
72
73
74int
75iswgraph_l(wint_t wc, locale_t locale)
76{
77	return iswctype_l(wc, _ISgraph, locale);
78}
79
80
81int
82iswlower_l(wint_t wc, locale_t locale)
83{
84	return iswctype_l(wc, _ISlower, locale);
85}
86
87
88int
89iswprint_l(wint_t wc, locale_t locale)
90{
91	return iswctype_l(wc, _ISprint, locale);
92}
93
94
95int
96iswpunct_l(wint_t wc, locale_t locale)
97{
98	return iswctype_l(wc, _ISpunct, locale);
99}
100
101
102int
103iswspace_l(wint_t wc, locale_t locale)
104{
105	return iswctype_l(wc, _ISspace, locale);
106}
107
108
109int
110iswupper_l(wint_t wc, locale_t locale)
111{
112	return iswctype_l(wc, _ISupper, locale);
113}
114
115
116int
117iswxdigit_l(wint_t wc, locale_t locale)
118{
119	return iswctype_l(wc, _ISxdigit, locale);
120}
121
122
123wint_t
124towlower_l(wint_t wc, locale_t l)
125{
126	LocaleBackendData* locale = (LocaleBackendData*)l;
127	LocaleBackend* backend = locale->backend;
128
129	if (backend == NULL) {
130		if (wc < 0 || wc > 127)
131			return wc;
132		return tolower(wc);
133	}
134
135	wint_t result = wc;
136	backend->ToWCTrans(wc, _ISlower, result);
137
138	return result;
139}
140
141
142wint_t
143towupper_l(wint_t wc, locale_t l)
144{
145	LocaleBackendData* locale = (LocaleBackendData*)l;
146	LocaleBackend* backend = locale->backend;
147
148	if (backend == NULL) {
149		if (wc < 0 || wc > 127)
150			return wc;
151		return toupper(wc);
152	}
153
154	wint_t result = wc;
155	backend->ToWCTrans(wc, _ISupper, result);
156
157	return result;
158}
159
160
161wint_t
162towctrans_l(wint_t wc, wctrans_t transition, locale_t l)
163{
164	LocaleBackendData* locale = (LocaleBackendData*)l;
165	LocaleBackend* backend = locale->backend;
166
167	if (backend == NULL) {
168		if (transition == _ISlower)
169			return tolower(wc);
170		if (transition == _ISupper)
171			return toupper(wc);
172
173		__set_errno(EINVAL);
174		return wc;
175	}
176
177	wint_t result = wc;
178	status_t status = backend->ToWCTrans(wc, transition, result);
179	if (status != B_OK)
180		__set_errno(EINVAL);
181
182	return result;
183}
184
185
186wctrans_t
187wctrans_l(const char *charClass, locale_t locale)
188{
189	(void)locale;
190
191	if (charClass != NULL) {
192		// we do not know any locale-specific character classes
193		if (strcmp(charClass, "tolower") == 0)
194			return _ISlower;
195		if (strcmp(charClass, "toupper") == 0)
196			return _ISupper;
197	}
198
199	__set_errno(EINVAL);
200	return 0;
201}
202
203
204wctype_t
205wctype_l(const char *property, locale_t locale)
206{
207	(void)locale;
208
209	// currently, we do not support any locale-specific properties
210	if (strcmp(property, "alnum") == 0)
211		return _ISalnum;
212	if (strcmp(property, "alpha") == 0)
213		return _ISalpha;
214	if (strcmp(property, "blank") == 0)
215		return _ISblank;
216	if (strcmp(property, "cntrl") == 0)
217		return _IScntrl;
218	if (strcmp(property, "digit") == 0)
219		return _ISdigit;
220	if (strcmp(property, "graph") == 0)
221		return _ISgraph;
222	if (strcmp(property, "lower") == 0)
223		return _ISlower;
224	if (strcmp(property, "print") == 0)
225		return _ISprint;
226	if (strcmp(property, "punct") == 0)
227		return _ISpunct;
228	if (strcmp(property, "space") == 0)
229		return _ISspace;
230	if (strcmp(property, "upper") == 0)
231		return _ISupper;
232	if (strcmp(property, "xdigit") == 0)
233		return _ISxdigit;
234
235	return 0;
236}
237