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