1/*
2** Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
3** Distributed under the terms of the MIT License.
4*/
5
6#include <ctype.h>
7#include <errno.h>
8#include <string.h>
9#include <wctype.h>
10
11#include <errno_private.h>
12
13#include "LocaleBackend.h"
14
15
16using BPrivate::Libroot::gLocaleBackend;
17
18/*
19 * In many of the following functions, we make use of the fact that with
20 * gLocaleBackend == NULL, the POSIX locale is active. Since the POSIX locale
21 * only contains chars 0-127 and those ASCII chars are compatible with the
22 * UTF32 values used in wint_t, we can delegate to the respective ctype
23 * function.
24 */
25
26int
27iswctype(wint_t wc, wctype_t charClass)
28{
29	if (gLocaleBackend == NULL) {
30		if (wc < 0 || wc > 127)
31			return 0;
32		return __isctype(wc, charClass);
33	}
34
35	return gLocaleBackend->IsWCType(wc, charClass);
36}
37
38
39int
40iswalnum(wint_t wc)
41{
42	return iswctype(wc, _ISalnum);
43}
44
45
46int
47iswalpha(wint_t wc)
48{
49	return iswctype(wc, _ISalpha);
50}
51
52
53int
54iswblank(wint_t wc)
55{
56	return iswctype(wc, _ISblank);
57}
58
59
60int
61iswcntrl(wint_t wc)
62{
63	return iswctype(wc, _IScntrl);
64}
65
66
67int
68iswdigit(wint_t wc)
69{
70	return iswctype(wc, _ISdigit);
71}
72
73
74int
75iswgraph(wint_t wc)
76{
77	return iswctype(wc, _ISgraph);
78}
79
80
81int
82iswlower(wint_t wc)
83{
84	return iswctype(wc, _ISlower);
85}
86
87
88int
89iswprint(wint_t wc)
90{
91	return iswctype(wc, _ISprint);
92}
93
94
95int
96iswpunct(wint_t wc)
97{
98	return iswctype(wc, _ISpunct);
99}
100
101
102int
103iswspace(wint_t wc)
104{
105	return iswctype(wc, _ISspace);
106}
107
108
109int
110iswupper(wint_t wc)
111{
112	return iswctype(wc, _ISupper);
113}
114
115
116int
117iswxdigit(wint_t wc)
118{
119	return iswctype(wc, _ISxdigit);
120}
121
122
123wint_t
124towlower(wint_t wc)
125{
126	if (gLocaleBackend == NULL) {
127		if (wc < 0 || wc > 127)
128			return wc;
129		return tolower(wc);
130	}
131
132	wint_t result = wc;
133	gLocaleBackend->ToWCTrans(wc, _ISlower, result);
134
135	return result;
136}
137
138
139wint_t
140towupper(wint_t wc)
141{
142	if (gLocaleBackend == NULL) {
143		if (wc < 0 || wc > 127)
144			return wc;
145		return toupper(wc);
146	}
147
148	wint_t result = wc;
149	gLocaleBackend->ToWCTrans(wc, _ISupper, result);
150
151	return result;
152}
153
154
155wint_t
156towctrans(wint_t wc, wctrans_t transition)
157{
158	if (gLocaleBackend == NULL) {
159		if (transition == _ISlower)
160			return tolower(wc);
161		if (transition == _ISupper)
162			return toupper(wc);
163
164		__set_errno(EINVAL);
165		return wc;
166	}
167
168	wint_t result = wc;
169	status_t status = gLocaleBackend->ToWCTrans(wc, transition, result);
170	if (status != B_OK)
171		__set_errno(EINVAL);
172
173	return result;
174}
175
176
177wctrans_t
178wctrans(const char *charClass)
179{
180	if (charClass != NULL) {
181		// we do not know any locale-specific character classes
182		if (strcmp(charClass, "tolower") == 0)
183			return _ISlower;
184		if (strcmp(charClass, "toupper") == 0)
185			return _ISupper;
186	}
187
188	__set_errno(EINVAL);
189	return 0;
190}
191
192
193wctype_t
194wctype(const char *property)
195{
196	// currently, we do not support any locale-specific properties
197	if (strcmp(property, "alnum") == 0)
198		return _ISalnum;
199	if (strcmp(property, "alpha") == 0)
200		return _ISalpha;
201	if (strcmp(property, "blank") == 0)
202		return _ISblank;
203	if (strcmp(property, "cntrl") == 0)
204		return _IScntrl;
205	if (strcmp(property, "digit") == 0)
206		return _ISdigit;
207	if (strcmp(property, "graph") == 0)
208		return _ISgraph;
209	if (strcmp(property, "lower") == 0)
210		return _ISlower;
211	if (strcmp(property, "print") == 0)
212		return _ISprint;
213	if (strcmp(property, "punct") == 0)
214		return _ISpunct;
215	if (strcmp(property, "space") == 0)
216		return _ISspace;
217	if (strcmp(property, "upper") == 0)
218		return _ISupper;
219	if (strcmp(property, "xdigit") == 0)
220		return _ISxdigit;
221
222	return 0;
223}
224