kernel: scheduling fix for ARM
[minix.git] / lib / libc / citrus / modules / citrus_johab.c
blobbebf939a5b6980c554b54ac567232f5a0879e60a
1 /* $NetBSD: citrus_johab.c,v 1.4 2008/06/14 16:01:07 tnozaki Exp $ */
3 /*-
4 * Copyright (c)2006 Citrus Project,
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 #if defined(LIBC_SCCS) && !defined(lint)
30 __RCSID("$NetBSD: citrus_johab.c,v 1.4 2008/06/14 16:01:07 tnozaki Exp $");
31 #endif /* LIBC_SCCS and not lint */
33 #include <sys/types.h>
34 #include <assert.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <stdint.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stddef.h>
41 #include <wchar.h>
42 #include <limits.h>
44 #include "citrus_namespace.h"
45 #include "citrus_types.h"
46 #include "citrus_bcs.h"
47 #include "citrus_module.h"
48 #include "citrus_ctype.h"
49 #include "citrus_stdenc.h"
50 #include "citrus_johab.h"
52 /* ----------------------------------------------------------------------
53 * private stuffs used by templates
56 typedef struct {
57 int chlen;
58 char ch[2];
59 } _JOHABState;
61 typedef struct {
62 int dummy;
63 } _JOHABEncodingInfo;
65 typedef struct {
66 _JOHABEncodingInfo ei;
67 struct {
68 /* for future multi-locale facility */
69 _JOHABState s_mblen;
70 _JOHABState s_mbrlen;
71 _JOHABState s_mbrtowc;
72 _JOHABState s_mbtowc;
73 _JOHABState s_mbsrtowcs;
74 _JOHABState s_wcrtomb;
75 _JOHABState s_wcsrtombs;
76 _JOHABState s_wctomb;
77 } states;
78 } _JOHABCTypeInfo;
80 #define _CEI_TO_EI(_cei_) (&(_cei_)->ei)
81 #define _CEI_TO_STATE(_cei_, _func_) (_cei_)->states.s_##_func_
83 #define _FUNCNAME(m) _citrus_JOHAB_##m
84 #define _ENCODING_INFO _JOHABEncodingInfo
85 #define _CTYPE_INFO _JOHABCTypeInfo
86 #define _ENCODING_STATE _JOHABState
87 #define _ENCODING_MB_CUR_MAX(_ei_) 2
88 #define _ENCODING_IS_STATE_DEPENDENT 0
89 #define _STATE_NEEDS_EXPLICIT_INIT(_ps_) 0
92 static __inline void
93 /*ARGSUSED*/
94 _citrus_JOHAB_init_state(_JOHABEncodingInfo * __restrict ei,
95 _JOHABState * __restrict psenc)
97 /* ei may be null */
98 _DIAGASSERT(psenc != NULL);
100 psenc->chlen = 0;
103 static __inline void
104 /*ARGSUSED*/
105 _citrus_JOHAB_pack_state(_JOHABEncodingInfo * __restrict ei,
106 void * __restrict pspriv,
107 const _JOHABState * __restrict psenc)
109 /* ei may be null */
110 _DIAGASSERT(pspriv != NULL);
111 _DIAGASSERT(psenc != NULL);
113 memcpy(pspriv, (const void *)psenc, sizeof(*psenc));
116 static __inline void
117 /*ARGSUSED*/
118 _citrus_JOHAB_unpack_state(_JOHABEncodingInfo * __restrict ei,
119 _JOHABState * __restrict psenc,
120 const void * __restrict pspriv)
122 /* ei may be null */
123 _DIAGASSERT(psenc != NULL);
124 _DIAGASSERT(pspriv != NULL);
126 memcpy((void *)psenc, pspriv, sizeof(*psenc));
129 static void
130 /*ARGSUSED*/
131 _citrus_JOHAB_encoding_module_uninit(_JOHABEncodingInfo *ei)
133 /* ei may be null */
136 static int
137 /*ARGSUSED*/
138 _citrus_JOHAB_encoding_module_init(_JOHABEncodingInfo * __restrict ei,
139 const void * __restrict var, size_t lenvar)
141 /* ei may be null */
142 return 0;
145 static __inline int
146 ishangul(int l, int t)
149 return (l >= 0x84 && l <= 0xD3) &&
150 ((t >= 0x41 && t <= 0x7E) || (t >= 0x81 && t <= 0xFE));
153 static __inline int
154 isuda(int l, int t)
156 return (l == 0xD8) &&
157 ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE));
160 static __inline int
161 ishanja(int l, int t)
163 return ((l >= 0xD9 && l <= 0xDE) || (l >= 0xE0 && l <= 0xF9)) &&
164 ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE));
167 static int
168 /*ARGSUSED*/
169 _citrus_JOHAB_mbrtowc_priv(_JOHABEncodingInfo * __restrict ei,
170 wchar_t * __restrict pwc, const char ** __restrict s, size_t n,
171 _JOHABState * __restrict psenc, size_t * __restrict nresult)
173 const char *s0;
174 int l, t;
176 /* ei may be unused */
177 _DIAGASSERT(s != NULL);
178 _DIAGASSERT(psenc != NULL);
179 _DIAGASSERT(nresult != 0);
181 if (*s == NULL) {
182 _citrus_JOHAB_init_state(ei, psenc);
183 *nresult = _ENCODING_IS_STATE_DEPENDENT;
184 return 0;
186 s0 = *s;
188 switch (psenc->chlen) {
189 case 0:
190 if (n-- < 1)
191 goto restart;
192 l = *s0++ & 0xFF;
193 if (l <= 0x7F) {
194 if (pwc != NULL)
195 *pwc = (wchar_t)l;
196 *nresult = (l == 0) ? 0 : 1;
197 *s = s0;
198 return 0;
200 psenc->ch[psenc->chlen++] = l;
201 break;
202 case 1:
203 l = psenc->ch[0] & 0xFF;
204 break;
205 default:
206 return EINVAL;
208 if (n-- < 1) {
209 restart:
210 *nresult = (size_t)-2;
211 *s = s0;
212 return 0;
214 t = *s0++ & 0xFF;
215 if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t)) {
216 *nresult = (size_t)-1;
217 return EILSEQ;
219 if (pwc != NULL)
220 *pwc = (wchar_t)(l << 8 | t);
221 *nresult = s0 - *s;
222 *s = s0;
223 psenc->chlen = 0;
225 return 0;
228 static int
229 /*ARGSUSED*/
230 _citrus_JOHAB_wcrtomb_priv(_JOHABEncodingInfo * __restrict ei,
231 char * __restrict s, size_t n, wchar_t wc,
232 _JOHABState * __restrict psenc, size_t * __restrict nresult)
234 int l, t;
236 /* ei may be unused */
237 _DIAGASSERT(s != NULL);
238 _DIAGASSERT(psenc != NULL);
239 _DIAGASSERT(nresult != NULL);
241 if (psenc->chlen != 0)
242 return EINVAL;
244 /* XXX assume wchar_t as int */
245 if ((uint32_t)wc <= 0x7F) {
246 if (n < 1)
247 goto e2big;
248 *s = wc & 0xFF;
249 *nresult = 1;
250 } else if ((uint32_t)wc <= 0xFFFF) {
251 if (n < 2) {
252 e2big:
253 *nresult = (size_t)-1;
254 return E2BIG;
256 l = (wc >> 8) & 0xFF;
257 t = wc & 0xFF;
258 if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t))
259 goto ilseq;
260 *s++ = l;
261 *s = t;
262 *nresult = 2;
263 } else {
264 ilseq:
265 *nresult = (size_t)-1;
266 return EILSEQ;
268 return 0;
272 static __inline int
273 /*ARGSUSED*/
274 _citrus_JOHAB_stdenc_wctocs(_JOHABEncodingInfo * __restrict ei,
275 _csid_t * __restrict csid, _index_t * __restrict idx, wchar_t wc)
277 int m, l, t, linear;
279 /* ei may be unused */
280 _DIAGASSERT(csid != NULL);
281 _DIAGASSERT(idx != NULL);
283 /* XXX assume wchar_t as int */
284 if ((uint32_t)wc <= 0x7F) {
285 *idx = (_index_t)wc;
286 *csid = 0;
287 } else if ((uint32_t)wc <= 0xFFFF) {
288 l = (wc >> 8) & 0xFF;
289 t = wc & 0xFF;
290 if (ishangul(l, t) || isuda(l, t)) {
291 *idx = (_index_t)wc;
292 *csid = 1;
293 } else {
294 if (l >= 0xD9 && l <= 0xDE) {
295 linear = l - 0xD9;
296 m = 0x21;
297 } else if (l >= 0xE0 && l <= 0xF9) {
298 linear = l - 0xE0;
299 m = 0x4A;
300 } else {
301 return EILSEQ;
303 linear *= 188;
304 if (t >= 0x31 && t <= 0x7E) {
305 linear += t - 0x31;
306 } else if (t >= 0x91 && t <= 0xFE) {
307 linear += t - 0x43;
308 } else {
309 return EILSEQ;
311 l = (linear / 94) + m;
312 t = (linear % 94) + 0x21;
313 *idx = (_index_t)((l << 8) | t);
314 *csid = 2;
316 } else {
317 return EILSEQ;
319 return 0;
322 static __inline int
323 /*ARGSUSED*/
324 _citrus_JOHAB_stdenc_cstowc(_JOHABEncodingInfo * __restrict ei,
325 wchar_t * __restrict wc, _csid_t csid, _index_t idx)
327 int m, n, l, t, linear;
329 /* ei may be unused */
330 _DIAGASSERT(wc != NULL);
332 switch (csid) {
333 case 0:
334 case 1:
335 *wc = (wchar_t)idx;
336 break;
337 case 2:
338 if (idx >= 0x2121 && idx <= 0x2C71) {
339 m = 0xD9;
340 n = 0x21;
341 } else if (idx >= 0x4A21 && idx <= 0x7D7E) {
342 m = 0xE0;
343 n = 0x4A;
344 } else {
345 return EILSEQ;
347 l = ((idx >> 8) & 0xFF) - n;
348 t = (idx & 0xFF) - 0x21;
349 linear = (l * 94) + t;
350 l = (linear / 188) + m;
351 t = linear % 188;
352 t += (t <= 0x4D) ? 0x31 : 0x43;
353 break;
354 default:
355 return EILSEQ;
357 return 0;
360 static __inline int
361 /*ARGSUSED*/
362 _citrus_JOHAB_stdenc_get_state_desc_generic(_JOHABEncodingInfo * __restrict ei,
363 _JOHABState * __restrict psenc, int * __restrict rstate)
365 /* ei may be unused */
366 _DIAGASSERT(psenc != NULL);
367 _DIAGASSERT(rstate != NULL);
369 *rstate = (psenc->chlen == 0)
370 ? _STDENC_SDGEN_INITIAL
371 : _STDENC_SDGEN_INCOMPLETE_CHAR;
372 return 0;
375 /* ----------------------------------------------------------------------
376 * public interface for ctype
379 _CITRUS_CTYPE_DECLS(JOHAB);
380 _CITRUS_CTYPE_DEF_OPS(JOHAB);
382 #include "citrus_ctype_template.h"
385 /* ----------------------------------------------------------------------
386 * public interface for stdenc
389 _CITRUS_STDENC_DECLS(JOHAB);
390 _CITRUS_STDENC_DEF_OPS(JOHAB);
392 #include "citrus_stdenc_template.h"