1/*      $NetBSD: multibyte.c,v 1.9 2019/08/01 12:28:53 martin Exp $      */
2
3/*
4 * Ignore all multibyte sequences, removes all the citrus code.
5 * Probably only used by vfprintf() when parsing the format string.
6 * And possibly from libcurses if compiled with HAVE_WCHAR.
7 */
8
9#include <stdlib.h>
10#include <string.h>
11#include <wchar.h>
12#include <wctype.h>
13#include <ctype.h>
14
15size_t
16mbrtowc(wchar_t *wc, const char *str, size_t max_sz, mbstate_t *ps)
17{
18	if (str == NULL)
19		return 0;
20
21	if (wc != NULL)
22		*wc = (unsigned char)*str;
23
24	return *str == '\0' ? 0 : 1;
25}
26
27size_t
28mbrtowc_l(wchar_t *wc, const char *str, size_t max_sz, mbstate_t *ps, locale_t loc)
29{
30	return mbrtowc(wc, str, max_sz, ps);
31}
32
33size_t
34wcrtomb(char *str, wchar_t wc, mbstate_t *ps)
35{
36    *str = wc & 0xFF;
37    return 1;
38}
39
40
41size_t
42wcrtomb_l(char *str, wchar_t wc, mbstate_t *ps, locale_t loc)
43{
44	return wcrtomb(str, wc, ps);
45}
46
47int
48wctob(wint_t x)
49{
50	return x;
51}
52
53int
54wctob_l(wint_t x, locale_t loc)
55{
56	return x;
57}
58
59wint_t
60btowc(int x)
61{
62	return x;
63}
64
65wint_t
66btowc_l(int x, locale_t loc)
67{
68	return x;
69}
70
71size_t
72mbrlen(const char * __restrict p, size_t l, mbstate_t * __restrict v)
73{
74	size_t i;
75	for (i = 0; i < l; i++)
76		if (p[i] == '\0')
77			return i;
78	return l;
79}
80
81
82size_t
83mbrlen_l(const char * __restrict p, size_t l, mbstate_t * __restrict v,
84    locale_t loc)
85{
86	return mbrlen(p, l, v);
87}
88
89int
90mbsinit(const mbstate_t *s)
91{
92	return 0;
93}
94
95size_t
96mbsrtowcs(wchar_t * __restrict pwcs, const char ** __restrict s, size_t n,
97    mbstate_t * __restrict ps)
98{
99	const char *p;
100	wchar_t *d;
101	size_t count;
102
103	for (p = *s, d = pwcs, count = 0;
104		count <= n;
105		count++, d++, p++)
106	{
107		if (mbrtowc(d, p, 1, ps) == 0)
108			break;
109	}
110	return count;
111}
112
113
114size_t
115mbsrtowcs_l(wchar_t * __restrict pwcs, const char ** __restrict s, size_t n,
116    mbstate_t * __restrict ps, locale_t loc)
117{
118	return mbsrtowcs(pwcs, s, n, ps);
119}
120
121size_t
122wcsrtombs(char * __restrict s, const wchar_t ** __restrict pwcs, size_t n,
123    mbstate_t * __restrict ps)
124{
125	char *d;
126	const wchar_t *p;
127	size_t count;
128
129	for (p = *pwcs, d = s, count = 0;
130		count <= n && *p != 0;
131		count++, d++, p++)
132	{
133		wcrtomb(d, *p, ps);
134	}
135	*d = 0;
136	return count;
137}
138
139size_t
140wcsrtombs_l(char * __restrict s, const wchar_t ** __restrict pwcs, size_t n,
141    mbstate_t * __restrict ps, locale_t loc)
142{
143	return wcsrtombs(s, pwcs, n, ps);
144}
145
146size_t
147_mb_cur_max_l(locale_t loc)
148{
149	return MB_CUR_MAX;
150}
151
152wint_t
153fgetwc(FILE *stream)
154{
155	return fgetc(stream);
156}
157
158wint_t
159fputwc(wchar_t wc, FILE *stream)
160{
161	return fputc(wc & 0xFF, stream);
162}
163
164wint_t __fputwc_unlock(wchar_t wc, FILE *stream);
165wint_t
166__fputwc_unlock(wchar_t wc, FILE *stream)
167{
168	return __sputc(wc & 0xFF, stream);
169}
170
171#define	MAPSINGLE(CT)	\
172	int	\
173	isw##CT(wint_t wc)	\
174	{	\
175		return is##CT(wc & 0xFF);	\
176	}
177
178MAPSINGLE(alnum)
179MAPSINGLE(alpha)
180MAPSINGLE(blank)
181MAPSINGLE(cntrl)
182MAPSINGLE(digit)
183MAPSINGLE(graph)
184MAPSINGLE(lower)
185MAPSINGLE(print)
186MAPSINGLE(punct)
187MAPSINGLE(space)
188MAPSINGLE(upper)
189MAPSINGLE(xdigit)
190
191int
192iswspace_l(wint_t wc, locale_t loc)
193{
194	return iswspace(wc);
195}
196
197struct wct_entry_hack {
198	const char *name;
199	int (*predicate)(wint_t);
200};
201
202#define	WCTENTRY(T)	{ .name= #T , .predicate= isw##T },
203static const struct wct_entry_hack my_wcts[] = {
204	{ .name = NULL },
205	WCTENTRY(alnum)
206	WCTENTRY(alpha)
207	WCTENTRY(blank)
208	WCTENTRY(cntrl)
209	WCTENTRY(digit)
210	WCTENTRY(graph)
211	WCTENTRY(lower)
212	WCTENTRY(print)
213	WCTENTRY(punct)
214	WCTENTRY(space)
215	WCTENTRY(upper)
216	WCTENTRY(xdigit)
217};
218
219wctype_t
220wctype(const char *charclass)
221{
222
223	for (size_t i = 1; i < __arraycount(my_wcts); i++)
224		if (strcmp(charclass, my_wcts[i].name) == 0)
225			return (wctype_t)i;
226
227	return (wctype_t)0;
228}
229
230int
231iswctype(wint_t wc, wctype_t charclass)
232{
233	size_t ndx = (size_t)charclass;
234
235	if (ndx < 1 || ndx >= __arraycount(my_wcts))
236		return 0;
237
238	return my_wcts[ndx].predicate(wc);
239}
240
241size_t
242wcslen(const wchar_t *s)
243{
244	size_t l;
245
246	if (s == NULL)
247		return 0;
248
249	for (l = 0; *s; l++)
250		s++;
251
252	return l;
253}
254
255int
256wcswidth(const wchar_t *pwcs, size_t n)
257{
258	int cols;
259
260	if (pwcs == NULL)
261		return 0;
262
263	if (*pwcs == 0)
264		return 0;
265
266	for (cols = 0; *pwcs && n > 0; cols++)
267		if (!isprint(*pwcs & 0xFF))
268			return -1;
269	return cols;
270}
271
272int
273wcwidth(wchar_t wc)
274{
275	if (wc == 0)
276		return 0;
277	if (!isprint(wc & 0xFF))
278		return -1;
279	return 1;
280}
281
282wchar_t *
283wmemchr(const wchar_t *s, wchar_t c, size_t n)
284{
285
286	if (s == NULL)
287		return NULL;
288	while (*s != 0 && *s != c)
289		s++;
290	if (*s != 0)
291		return __UNCONST(s);
292	return NULL;
293}
294
295wchar_t *
296wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n)
297{
298	wchar_t *p;
299
300	for (p = s1; n > 0; n--)
301		*p++ = *s2++;
302
303	return s1;
304}
305
306wint_t
307towlower(wint_t wc)
308{
309	return tolower(wc & 0xFF);
310}
311
312wint_t
313towupper(wint_t wc)
314{
315	return toupper(wc & 0xFF);
316}
317
318
319