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
18 using BPrivate::Libroot::GetCurrentLocaleBackend;
19 using BPrivate::Libroot::LocaleBackend;
20 using BPrivate::Libroot::LocaleBackendData;
21
22
23 int
iswctype_l(wint_t wc,wctype_t charClass,locale_t l)24 iswctype_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
39 int
iswalnum_l(wint_t wc,locale_t locale)40 iswalnum_l(wint_t wc, locale_t locale)
41 {
42 return iswctype_l(wc, _ISalnum, locale);
43 }
44
45
46 int
iswalpha_l(wint_t wc,locale_t locale)47 iswalpha_l(wint_t wc, locale_t locale)
48 {
49 return iswctype_l(wc, _ISalpha, locale);
50 }
51
52
53 int
iswblank_l(wint_t wc,locale_t locale)54 iswblank_l(wint_t wc, locale_t locale)
55 {
56 return iswctype_l(wc, _ISblank, locale);
57 }
58
59
60 int
iswcntrl_l(wint_t wc,locale_t locale)61 iswcntrl_l(wint_t wc, locale_t locale)
62 {
63 return iswctype_l(wc, _IScntrl, locale);
64 }
65
66
67 int
iswdigit_l(wint_t wc,locale_t locale)68 iswdigit_l(wint_t wc, locale_t locale)
69 {
70 return iswctype_l(wc, _ISdigit, locale);
71 }
72
73
74 int
iswgraph_l(wint_t wc,locale_t locale)75 iswgraph_l(wint_t wc, locale_t locale)
76 {
77 return iswctype_l(wc, _ISgraph, locale);
78 }
79
80
81 int
iswlower_l(wint_t wc,locale_t locale)82 iswlower_l(wint_t wc, locale_t locale)
83 {
84 return iswctype_l(wc, _ISlower, locale);
85 }
86
87
88 int
iswprint_l(wint_t wc,locale_t locale)89 iswprint_l(wint_t wc, locale_t locale)
90 {
91 return iswctype_l(wc, _ISprint, locale);
92 }
93
94
95 int
iswpunct_l(wint_t wc,locale_t locale)96 iswpunct_l(wint_t wc, locale_t locale)
97 {
98 return iswctype_l(wc, _ISpunct, locale);
99 }
100
101
102 int
iswspace_l(wint_t wc,locale_t locale)103 iswspace_l(wint_t wc, locale_t locale)
104 {
105 return iswctype_l(wc, _ISspace, locale);
106 }
107
108
109 int
iswupper_l(wint_t wc,locale_t locale)110 iswupper_l(wint_t wc, locale_t locale)
111 {
112 return iswctype_l(wc, _ISupper, locale);
113 }
114
115
116 int
iswxdigit_l(wint_t wc,locale_t locale)117 iswxdigit_l(wint_t wc, locale_t locale)
118 {
119 return iswctype_l(wc, _ISxdigit, locale);
120 }
121
122
123 wint_t
towlower_l(wint_t wc,locale_t l)124 towlower_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
142 wint_t
towupper_l(wint_t wc,locale_t l)143 towupper_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
161 wint_t
towctrans_l(wint_t wc,wctrans_t transition,locale_t l)162 towctrans_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
186 wctrans_t
wctrans_l(const char * charClass,locale_t locale)187 wctrans_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
204 wctype_t
wctype_l(const char * property,locale_t locale)205 wctype_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