xref: /netbsd-src/distrib/utils/libhack/multibyte.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
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 
15 size_t
16 mbrtowc(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 
27 size_t
28 mbrtowc_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 
33 size_t
34 wcrtomb(char *str, wchar_t wc, mbstate_t *ps)
35 {
36     *str = wc & 0xFF;
37     return 1;
38 }
39 
40 
41 size_t
42 wcrtomb_l(char *str, wchar_t wc, mbstate_t *ps, locale_t loc)
43 {
44 	return wcrtomb(str, wc, ps);
45 }
46 
47 int
48 wctob(wint_t x)
49 {
50 	return x;
51 }
52 
53 int
54 wctob_l(wint_t x, locale_t loc)
55 {
56 	return x;
57 }
58 
59 wint_t
60 btowc(int x)
61 {
62 	return x;
63 }
64 
65 wint_t
66 btowc_l(int x, locale_t loc)
67 {
68 	return x;
69 }
70 
71 size_t
72 mbrlen(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 
82 size_t
83 mbrlen_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 
89 int
90 mbsinit(const mbstate_t *s)
91 {
92 	return 0;
93 }
94 
95 size_t
96 mbsrtowcs(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 
114 size_t
115 mbsrtowcs_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 
121 size_t
122 wcsrtombs(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 
139 size_t
140 wcsrtombs_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 
146 size_t
147 _mb_cur_max_l(locale_t loc)
148 {
149 	return MB_CUR_MAX;
150 }
151 
152 wint_t
153 fgetwc(FILE *stream)
154 {
155 	return fgetc(stream);
156 }
157 
158 wint_t
159 fputwc(wchar_t wc, FILE *stream)
160 {
161 	return fputc(wc & 0xFF, stream);
162 }
163 
164 wint_t __fputwc_unlock(wchar_t wc, FILE *stream);
165 wint_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 
178 MAPSINGLE(alnum)
179 MAPSINGLE(alpha)
180 MAPSINGLE(blank)
181 MAPSINGLE(cntrl)
182 MAPSINGLE(digit)
183 MAPSINGLE(graph)
184 MAPSINGLE(lower)
185 MAPSINGLE(print)
186 MAPSINGLE(punct)
187 MAPSINGLE(space)
188 MAPSINGLE(upper)
189 MAPSINGLE(xdigit)
190 
191 int
192 iswspace_l(wint_t wc, locale_t loc)
193 {
194 	return iswspace(wc);
195 }
196 
197 struct wct_entry_hack {
198 	const char *name;
199 	int (*predicate)(wint_t);
200 };
201 
202 #define	WCTENTRY(T)	{ .name= #T , .predicate= isw##T },
203 static 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 
219 wctype_t
220 wctype(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 
230 int
231 iswctype(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 
241 size_t
242 wcslen(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 
255 int
256 wcswidth(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 
272 int
273 wcwidth(wchar_t wc)
274 {
275 	if (wc == 0)
276 		return 0;
277 	if (!isprint(wc & 0xFF))
278 		return -1;
279 	return 1;
280 }
281 
282 wchar_t *
283 wmemchr(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 
295 wchar_t *
296 wmemcpy(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 
306 wint_t
307 towlower(wint_t wc)
308 {
309 	return tolower(wc & 0xFF);
310 }
311 
312 wint_t
313 towupper(wint_t wc)
314 {
315 	return toupper(wc & 0xFF);
316 }
317 
318 
319