xref: /haiku/src/system/libroot/posix/locale/wctype_l.cpp (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
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