multibyte.c revision 1.8 1 /* $NetBSD: multibyte.c,v 1.8 2019/07/28 10:21:18 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 while (*s) {
250 s++;
251 l++;
252 }
253
254 return l;
255 }
256
257 int
258 wcswidth(const wchar_t *pwcs, size_t n)
259 {
260 int cols;
261
262 if (pwcs == NULL)
263 return 0;
264
265 if (*pwcs == 0)
266 return 0;
267
268 for (cols = 0; *pwcs && n > 0; cols++)
269 if (!isprint(*pwcs & 0xFF))
270 return -1;
271 return cols;
272 }
273
274 int
275 wcwidth(wchar_t wc)
276 {
277 if (wc == 0)
278 return 0;
279 if (!isprint(wc & 0xFF))
280 return -1;
281 return 1;
282 }
283
284 wchar_t *
285 wmemchr(const wchar_t *s, wchar_t c, size_t n)
286 {
287
288 if (s == NULL)
289 return NULL;
290 while (*s != 0 && *s != c)
291 s++;
292 if (*s != 0)
293 return __UNCONST(s);
294 return NULL;
295 }
296
297 wchar_t *
298 wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n)
299 {
300 wchar_t *p;
301
302 for (p = s1; n > 0; n--)
303 *p++ = *s2++;
304
305 return s1;
306 }
307
308 wint_t
309 towlower(wint_t wc)
310 {
311 return tolower(wc & 0xFF);
312 }
313
314 wint_t
315 towupper(wint_t wc)
316 {
317 return toupper(wc & 0xFF);
318 }
319
320
321