xref: /netbsd/lib/libc/citrus/modules/citrus_johab.c (revision 0192bd2d)
1*0192bd2dSmlelstv /* $NetBSD: citrus_johab.c,v 1.7 2019/07/08 06:45:01 mlelstv Exp $ */
22e2fc44eStnozaki 
32e2fc44eStnozaki /*-
42e2fc44eStnozaki  * Copyright (c)2006 Citrus Project,
52e2fc44eStnozaki  * All rights reserved.
62e2fc44eStnozaki  *
72e2fc44eStnozaki  * Redistribution and use in source and binary forms, with or without
82e2fc44eStnozaki  * modification, are permitted provided that the following conditions
92e2fc44eStnozaki  * are met:
102e2fc44eStnozaki  * 1. Redistributions of source code must retain the above copyright
112e2fc44eStnozaki  *    notice, this list of conditions and the following disclaimer.
122e2fc44eStnozaki  * 2. Redistributions in binary form must reproduce the above copyright
132e2fc44eStnozaki  *    notice, this list of conditions and the following disclaimer in the
142e2fc44eStnozaki  *    documentation and/or other materials provided with the distribution.
152e2fc44eStnozaki  *
162e2fc44eStnozaki  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
172e2fc44eStnozaki  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
182e2fc44eStnozaki  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
192e2fc44eStnozaki  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
202e2fc44eStnozaki  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
212e2fc44eStnozaki  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
222e2fc44eStnozaki  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232e2fc44eStnozaki  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
242e2fc44eStnozaki  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
252e2fc44eStnozaki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
262e2fc44eStnozaki  * SUCH DAMAGE.
272e2fc44eStnozaki  */
282e2fc44eStnozaki #include <sys/cdefs.h>
292e2fc44eStnozaki #if defined(LIBC_SCCS) && !defined(lint)
30*0192bd2dSmlelstv __RCSID("$NetBSD: citrus_johab.c,v 1.7 2019/07/08 06:45:01 mlelstv Exp $");
312e2fc44eStnozaki #endif /* LIBC_SCCS and not lint */
322e2fc44eStnozaki 
332e2fc44eStnozaki #include <sys/types.h>
342e2fc44eStnozaki #include <assert.h>
352e2fc44eStnozaki #include <errno.h>
362e2fc44eStnozaki #include <string.h>
372e2fc44eStnozaki #include <stdint.h>
382e2fc44eStnozaki #include <stdio.h>
392e2fc44eStnozaki #include <stdlib.h>
402e2fc44eStnozaki #include <stddef.h>
412e2fc44eStnozaki #include <wchar.h>
422e2fc44eStnozaki #include <limits.h>
432e2fc44eStnozaki 
442e2fc44eStnozaki #include "citrus_namespace.h"
452e2fc44eStnozaki #include "citrus_types.h"
462e2fc44eStnozaki #include "citrus_bcs.h"
472e2fc44eStnozaki #include "citrus_module.h"
482e2fc44eStnozaki #include "citrus_ctype.h"
492e2fc44eStnozaki #include "citrus_stdenc.h"
502e2fc44eStnozaki #include "citrus_johab.h"
512e2fc44eStnozaki 
522e2fc44eStnozaki /* ----------------------------------------------------------------------
532e2fc44eStnozaki  * private stuffs used by templates
542e2fc44eStnozaki  */
552e2fc44eStnozaki 
562e2fc44eStnozaki typedef struct {
572e2fc44eStnozaki 	int chlen;
582e2fc44eStnozaki 	char ch[2];
592e2fc44eStnozaki } _JOHABState;
602e2fc44eStnozaki 
612e2fc44eStnozaki typedef struct {
622e2fc44eStnozaki 	int dummy;
632e2fc44eStnozaki } _JOHABEncodingInfo;
642e2fc44eStnozaki 
652e2fc44eStnozaki typedef struct {
662e2fc44eStnozaki 	_JOHABEncodingInfo	ei;
672e2fc44eStnozaki 	struct {
682e2fc44eStnozaki 		/* for future multi-locale facility */
692e2fc44eStnozaki 		_JOHABState	s_mblen;
702e2fc44eStnozaki 		_JOHABState	s_mbrlen;
712e2fc44eStnozaki 		_JOHABState	s_mbrtowc;
722e2fc44eStnozaki 		_JOHABState	s_mbtowc;
732e2fc44eStnozaki 		_JOHABState	s_mbsrtowcs;
74bf2f4b3eSjoerg 		_JOHABState	s_mbsnrtowcs;
752e2fc44eStnozaki 		_JOHABState	s_wcrtomb;
762e2fc44eStnozaki 		_JOHABState	s_wcsrtombs;
77bf2f4b3eSjoerg 		_JOHABState	s_wcsnrtombs;
782e2fc44eStnozaki 		_JOHABState	s_wctomb;
792e2fc44eStnozaki 	} states;
802e2fc44eStnozaki } _JOHABCTypeInfo;
812e2fc44eStnozaki 
822e2fc44eStnozaki #define _CEI_TO_EI(_cei_)		(&(_cei_)->ei)
832e2fc44eStnozaki #define _CEI_TO_STATE(_cei_, _func_)	(_cei_)->states.s_##_func_
842e2fc44eStnozaki 
852e2fc44eStnozaki #define _FUNCNAME(m)			_citrus_JOHAB_##m
862e2fc44eStnozaki #define _ENCODING_INFO			_JOHABEncodingInfo
872e2fc44eStnozaki #define _CTYPE_INFO			_JOHABCTypeInfo
882e2fc44eStnozaki #define _ENCODING_STATE			_JOHABState
892e2fc44eStnozaki #define _ENCODING_MB_CUR_MAX(_ei_)		2
902e2fc44eStnozaki #define _ENCODING_IS_STATE_DEPENDENT		0
912e2fc44eStnozaki #define _STATE_NEEDS_EXPLICIT_INIT(_ps_)	0
922e2fc44eStnozaki 
932e2fc44eStnozaki 
942e2fc44eStnozaki static __inline void
952e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_init_state(_JOHABEncodingInfo * __restrict ei,_JOHABState * __restrict psenc)962e2fc44eStnozaki _citrus_JOHAB_init_state(_JOHABEncodingInfo * __restrict ei,
972e2fc44eStnozaki 	_JOHABState * __restrict psenc)
982e2fc44eStnozaki {
992e2fc44eStnozaki 	/* ei may be null */
1002e2fc44eStnozaki 	_DIAGASSERT(psenc != NULL);
1012e2fc44eStnozaki 
1022e2fc44eStnozaki 	psenc->chlen = 0;
1032e2fc44eStnozaki }
1042e2fc44eStnozaki 
1052e2fc44eStnozaki static __inline void
1062e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_pack_state(_JOHABEncodingInfo * __restrict ei,void * __restrict pspriv,const _JOHABState * __restrict psenc)1072e2fc44eStnozaki _citrus_JOHAB_pack_state(_JOHABEncodingInfo * __restrict ei,
1082e2fc44eStnozaki 	void * __restrict pspriv,
1092e2fc44eStnozaki 	const _JOHABState * __restrict psenc)
1102e2fc44eStnozaki {
1112e2fc44eStnozaki 	/* ei may be null */
1122e2fc44eStnozaki 	_DIAGASSERT(pspriv != NULL);
1132e2fc44eStnozaki 	_DIAGASSERT(psenc != NULL);
1142e2fc44eStnozaki 
1152e2fc44eStnozaki 	memcpy(pspriv, (const void *)psenc, sizeof(*psenc));
1162e2fc44eStnozaki }
1172e2fc44eStnozaki 
1182e2fc44eStnozaki static __inline void
1192e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_unpack_state(_JOHABEncodingInfo * __restrict ei,_JOHABState * __restrict psenc,const void * __restrict pspriv)1202e2fc44eStnozaki _citrus_JOHAB_unpack_state(_JOHABEncodingInfo * __restrict ei,
1212e2fc44eStnozaki 	_JOHABState * __restrict psenc,
1222e2fc44eStnozaki 	const void * __restrict pspriv)
1232e2fc44eStnozaki {
1242e2fc44eStnozaki 	/* ei may be null */
1252e2fc44eStnozaki 	_DIAGASSERT(psenc != NULL);
1262e2fc44eStnozaki 	_DIAGASSERT(pspriv != NULL);
1272e2fc44eStnozaki 
1282e2fc44eStnozaki 	memcpy((void *)psenc, pspriv, sizeof(*psenc));
1292e2fc44eStnozaki }
1302e2fc44eStnozaki 
1312e2fc44eStnozaki static void
1322e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_encoding_module_uninit(_JOHABEncodingInfo * ei)1332e2fc44eStnozaki _citrus_JOHAB_encoding_module_uninit(_JOHABEncodingInfo *ei)
1342e2fc44eStnozaki {
1352e2fc44eStnozaki 	/* ei may be null */
1362e2fc44eStnozaki }
1372e2fc44eStnozaki 
1382e2fc44eStnozaki static int
1392e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_encoding_module_init(_JOHABEncodingInfo * __restrict ei,const void * __restrict var,size_t lenvar)1402e2fc44eStnozaki _citrus_JOHAB_encoding_module_init(_JOHABEncodingInfo * __restrict ei,
1412e2fc44eStnozaki 	const void * __restrict var, size_t lenvar)
1422e2fc44eStnozaki {
1432e2fc44eStnozaki 	/* ei may be null */
1442e2fc44eStnozaki 	return 0;
1452e2fc44eStnozaki }
1462e2fc44eStnozaki 
1472e2fc44eStnozaki static __inline int
ishangul(int l,int t)1482e2fc44eStnozaki ishangul(int l, int t)
1492e2fc44eStnozaki {
1502e2fc44eStnozaki 
1512e2fc44eStnozaki 	return (l >= 0x84 && l <= 0xD3) &&
1522e2fc44eStnozaki 	      ((t >= 0x41 && t <= 0x7E) || (t >= 0x81 && t <= 0xFE));
1532e2fc44eStnozaki }
1542e2fc44eStnozaki 
1552e2fc44eStnozaki static __inline int
isuda(int l,int t)1562e2fc44eStnozaki isuda(int l, int t)
1572e2fc44eStnozaki {
1582e2fc44eStnozaki 	return (l == 0xD8) &&
1592e2fc44eStnozaki 	       ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE));
1602e2fc44eStnozaki }
1612e2fc44eStnozaki 
1622e2fc44eStnozaki static __inline int
ishanja(int l,int t)1632e2fc44eStnozaki ishanja(int l, int t)
1642e2fc44eStnozaki {
1652e2fc44eStnozaki 	return ((l >= 0xD9 && l <= 0xDE) || (l >= 0xE0 && l <= 0xF9)) &&
1662e2fc44eStnozaki 	       ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE));
1672e2fc44eStnozaki }
1682e2fc44eStnozaki 
1692e2fc44eStnozaki static int
1702e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_mbrtowc_priv(_JOHABEncodingInfo * __restrict ei,wchar_t * __restrict pwc,const char ** __restrict s,size_t n,_JOHABState * __restrict psenc,size_t * __restrict nresult)1712e2fc44eStnozaki _citrus_JOHAB_mbrtowc_priv(_JOHABEncodingInfo * __restrict ei,
1722e2fc44eStnozaki 	wchar_t * __restrict pwc, const char ** __restrict s, size_t n,
1732e2fc44eStnozaki 	_JOHABState * __restrict psenc, size_t * __restrict nresult)
1742e2fc44eStnozaki {
1752e2fc44eStnozaki 	const char *s0;
1762e2fc44eStnozaki 	int l, t;
1772e2fc44eStnozaki 
1782e2fc44eStnozaki 	/* ei may be unused */
1792e2fc44eStnozaki 	_DIAGASSERT(s != NULL);
1802e2fc44eStnozaki 	_DIAGASSERT(psenc != NULL);
1812e2fc44eStnozaki 	_DIAGASSERT(nresult != 0);
1822e2fc44eStnozaki 
1832e2fc44eStnozaki 	if (*s == NULL) {
1842e2fc44eStnozaki 		_citrus_JOHAB_init_state(ei, psenc);
1852e2fc44eStnozaki 		*nresult = _ENCODING_IS_STATE_DEPENDENT;
1862e2fc44eStnozaki 		return 0;
1872e2fc44eStnozaki 	}
1882e2fc44eStnozaki 	s0 = *s;
1892e2fc44eStnozaki 
1902e2fc44eStnozaki 	switch (psenc->chlen) {
1912e2fc44eStnozaki 	case 0:
1922e2fc44eStnozaki 		if (n-- < 1)
1932e2fc44eStnozaki 			goto restart;
1942e2fc44eStnozaki 		l = *s0++ & 0xFF;
195c61eef3dStnozaki 		if (l <= 0x7F) {
1962e2fc44eStnozaki 			if (pwc != NULL)
1972e2fc44eStnozaki 				*pwc = (wchar_t)l;
1982e2fc44eStnozaki 			*nresult = (l == 0) ? 0 : 1;
1992e2fc44eStnozaki 			*s = s0;
2002e2fc44eStnozaki 			return 0;
2012e2fc44eStnozaki 		}
2022e2fc44eStnozaki 		psenc->ch[psenc->chlen++] = l;
2032e2fc44eStnozaki 		break;
2042e2fc44eStnozaki 	case 1:
2052e2fc44eStnozaki 		l = psenc->ch[0] & 0xFF;
2062e2fc44eStnozaki 		break;
2072e2fc44eStnozaki 	default:
2082e2fc44eStnozaki 		return EINVAL;
2092e2fc44eStnozaki 	}
2102e2fc44eStnozaki 	if (n-- < 1) {
2112e2fc44eStnozaki restart:
2122e2fc44eStnozaki 		*nresult = (size_t)-2;
2132e2fc44eStnozaki 		*s = s0;
2142e2fc44eStnozaki 		return 0;
2152e2fc44eStnozaki 	}
2162e2fc44eStnozaki 	t = *s0++ & 0xFF;
2172e2fc44eStnozaki 	if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t)) {
2182e2fc44eStnozaki 		*nresult = (size_t)-1;
2192e2fc44eStnozaki 		return EILSEQ;
2202e2fc44eStnozaki 	}
2212e2fc44eStnozaki 	if (pwc != NULL)
2222e2fc44eStnozaki 		*pwc = (wchar_t)(l << 8 | t);
2232e2fc44eStnozaki 	*nresult = s0 - *s;
2242e2fc44eStnozaki 	*s = s0;
2252e2fc44eStnozaki 	psenc->chlen = 0;
2262e2fc44eStnozaki 
2272e2fc44eStnozaki 	return 0;
2282e2fc44eStnozaki }
2292e2fc44eStnozaki 
2302e2fc44eStnozaki static int
2312e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_wcrtomb_priv(_JOHABEncodingInfo * __restrict ei,char * __restrict s,size_t n,wchar_t wc,_JOHABState * __restrict psenc,size_t * __restrict nresult)2322e2fc44eStnozaki _citrus_JOHAB_wcrtomb_priv(_JOHABEncodingInfo * __restrict ei,
2332e2fc44eStnozaki 	char * __restrict s, size_t n, wchar_t wc,
2342e2fc44eStnozaki 	_JOHABState * __restrict psenc, size_t * __restrict nresult)
2352e2fc44eStnozaki {
2362e2fc44eStnozaki 	int l, t;
2372e2fc44eStnozaki 
2382e2fc44eStnozaki 	/* ei may be unused */
2392e2fc44eStnozaki 	_DIAGASSERT(s != NULL);
2402e2fc44eStnozaki 	_DIAGASSERT(psenc != NULL);
2412e2fc44eStnozaki 	_DIAGASSERT(nresult != NULL);
2422e2fc44eStnozaki 
2432e2fc44eStnozaki 	if (psenc->chlen != 0)
2442e2fc44eStnozaki 		return EINVAL;
2452e2fc44eStnozaki 
2462e2fc44eStnozaki 	/* XXX assume wchar_t as int */
247c61eef3dStnozaki 	if ((uint32_t)wc <= 0x7F) {
2482e2fc44eStnozaki 		if (n < 1)
2492e2fc44eStnozaki 			goto e2big;
2502e2fc44eStnozaki 		*s = wc & 0xFF;
2512e2fc44eStnozaki 		*nresult = 1;
2522e2fc44eStnozaki 	} else if ((uint32_t)wc <= 0xFFFF) {
2532e2fc44eStnozaki 		if (n < 2) {
2542e2fc44eStnozaki e2big:
2552e2fc44eStnozaki 			*nresult = (size_t)-1;
2562e2fc44eStnozaki 			return E2BIG;
2572e2fc44eStnozaki 		}
2582e2fc44eStnozaki 		l = (wc >> 8) & 0xFF;
2592e2fc44eStnozaki 		t = wc & 0xFF;
2602e2fc44eStnozaki 		if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t))
2612e2fc44eStnozaki 			goto ilseq;
2622e2fc44eStnozaki 		*s++ = l;
2632e2fc44eStnozaki 		*s = t;
2642e2fc44eStnozaki 		*nresult = 2;
2652e2fc44eStnozaki 	} else {
2662e2fc44eStnozaki ilseq:
2672e2fc44eStnozaki 		*nresult = (size_t)-1;
2682e2fc44eStnozaki 		return EILSEQ;
2692e2fc44eStnozaki 	}
2702e2fc44eStnozaki 	return 0;
2712e2fc44eStnozaki 
2722e2fc44eStnozaki }
2732e2fc44eStnozaki 
2742e2fc44eStnozaki static __inline int
2752e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_stdenc_wctocs(_JOHABEncodingInfo * __restrict ei,_csid_t * __restrict csid,_index_t * __restrict idx,wchar_t wc)2762e2fc44eStnozaki _citrus_JOHAB_stdenc_wctocs(_JOHABEncodingInfo * __restrict ei,
2772e2fc44eStnozaki 	_csid_t * __restrict csid, _index_t * __restrict idx, wchar_t wc)
2782e2fc44eStnozaki {
2792e2fc44eStnozaki 	int m, l, t, linear;
2802e2fc44eStnozaki 
2812e2fc44eStnozaki 	/* ei may be unused */
2822e2fc44eStnozaki 	_DIAGASSERT(csid != NULL);
2832e2fc44eStnozaki 	_DIAGASSERT(idx != NULL);
2842e2fc44eStnozaki 
2852e2fc44eStnozaki 	/* XXX assume wchar_t as int */
286c61eef3dStnozaki 	if ((uint32_t)wc <= 0x7F) {
2872e2fc44eStnozaki 		*idx = (_index_t)wc;
2882e2fc44eStnozaki 		*csid = 0;
289c61eef3dStnozaki 	} else if ((uint32_t)wc <= 0xFFFF) {
2902e2fc44eStnozaki 		l = (wc >> 8) & 0xFF;
2912e2fc44eStnozaki 		t = wc & 0xFF;
2922e2fc44eStnozaki 		if (ishangul(l, t) || isuda(l, t)) {
2932e2fc44eStnozaki 			*idx = (_index_t)wc;
2942e2fc44eStnozaki 			*csid = 1;
2952e2fc44eStnozaki 		} else {
2962e2fc44eStnozaki 			if (l >= 0xD9 && l <= 0xDE) {
2972e2fc44eStnozaki 				linear = l - 0xD9;
2982e2fc44eStnozaki 				m = 0x21;
2992e2fc44eStnozaki 			} else if (l >= 0xE0 && l <= 0xF9) {
3002e2fc44eStnozaki 				linear = l - 0xE0;
3012e2fc44eStnozaki 				m = 0x4A;
3022e2fc44eStnozaki 			} else {
3032e2fc44eStnozaki 				return EILSEQ;
3042e2fc44eStnozaki 			}
3052e2fc44eStnozaki 			linear *= 188;
3062e2fc44eStnozaki 			if (t >= 0x31 && t <= 0x7E) {
3072e2fc44eStnozaki 				linear += t - 0x31;
3082e2fc44eStnozaki 			} else if (t >= 0x91 && t <= 0xFE) {
3092e2fc44eStnozaki 				linear += t - 0x43;
3102e2fc44eStnozaki 			} else {
3112e2fc44eStnozaki 				return EILSEQ;
3122e2fc44eStnozaki 			}
3132e2fc44eStnozaki 			l = (linear / 94) + m;
3142e2fc44eStnozaki 			t = (linear % 94) + 0x21;
3152e2fc44eStnozaki 			*idx = (_index_t)((l << 8) | t);
3162e2fc44eStnozaki 			*csid = 2;
3172e2fc44eStnozaki 		}
318c61eef3dStnozaki 	} else {
319c61eef3dStnozaki 		return EILSEQ;
3202e2fc44eStnozaki 	}
3212e2fc44eStnozaki 	return 0;
3222e2fc44eStnozaki }
3232e2fc44eStnozaki 
3242e2fc44eStnozaki static __inline int
3252e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_stdenc_cstowc(_JOHABEncodingInfo * __restrict ei,wchar_t * __restrict wc,_csid_t csid,_index_t idx)3262e2fc44eStnozaki _citrus_JOHAB_stdenc_cstowc(_JOHABEncodingInfo * __restrict ei,
3272e2fc44eStnozaki 	wchar_t * __restrict wc, _csid_t csid, _index_t idx)
3282e2fc44eStnozaki {
3292e2fc44eStnozaki 	int m, n, l, t, linear;
3302e2fc44eStnozaki 
3312e2fc44eStnozaki 	/* ei may be unused */
3322e2fc44eStnozaki 	_DIAGASSERT(wc != NULL);
3332e2fc44eStnozaki 
3342e2fc44eStnozaki 	switch (csid) {
3352e2fc44eStnozaki 	case 0:
3362e2fc44eStnozaki 	case 1:
3372e2fc44eStnozaki 		*wc = (wchar_t)idx;
3382e2fc44eStnozaki 		break;
3392e2fc44eStnozaki 	case 2:
3402e2fc44eStnozaki 		if (idx >= 0x2121 && idx <= 0x2C71) {
3412e2fc44eStnozaki 			m = 0xD9;
3422e2fc44eStnozaki 			n = 0x21;
3432e2fc44eStnozaki 		} else if (idx >= 0x4A21 && idx <= 0x7D7E) {
3442e2fc44eStnozaki 			m = 0xE0;
3452e2fc44eStnozaki 			n = 0x4A;
3462e2fc44eStnozaki 		} else {
3472e2fc44eStnozaki 			return EILSEQ;
3482e2fc44eStnozaki 		}
3492e2fc44eStnozaki 		l = ((idx >> 8) & 0xFF) - n;
3502e2fc44eStnozaki 		t = (idx & 0xFF) - 0x21;
3512e2fc44eStnozaki 		linear = (l * 94) + t;
352*0192bd2dSmlelstv 		l = (linear / 188) + m;
3532e2fc44eStnozaki 		t = linear % 188;
3542e2fc44eStnozaki 		t += (t <= 0x4D) ? 0x31 : 0x43;
355*0192bd2dSmlelstv 		*wc = (wchar_t)((l << 8) | t);
3562e2fc44eStnozaki 		break;
3572e2fc44eStnozaki 	default:
3582e2fc44eStnozaki 		return EILSEQ;
3592e2fc44eStnozaki 	}
3602e2fc44eStnozaki 	return 0;
3612e2fc44eStnozaki }
3622e2fc44eStnozaki 
3632e2fc44eStnozaki static __inline int
3642e2fc44eStnozaki /*ARGSUSED*/
_citrus_JOHAB_stdenc_get_state_desc_generic(_JOHABEncodingInfo * __restrict ei,_JOHABState * __restrict psenc,int * __restrict rstate)3652e2fc44eStnozaki _citrus_JOHAB_stdenc_get_state_desc_generic(_JOHABEncodingInfo * __restrict ei,
3662e2fc44eStnozaki 	_JOHABState * __restrict psenc, int * __restrict rstate)
3672e2fc44eStnozaki {
3682e2fc44eStnozaki 	/* ei may be unused */
3692e2fc44eStnozaki 	_DIAGASSERT(psenc != NULL);
3702e2fc44eStnozaki 	_DIAGASSERT(rstate != NULL);
3712e2fc44eStnozaki 
3722e2fc44eStnozaki 	*rstate = (psenc->chlen == 0)
3732e2fc44eStnozaki 	    ? _STDENC_SDGEN_INITIAL
3742e2fc44eStnozaki 	    : _STDENC_SDGEN_INCOMPLETE_CHAR;
3752e2fc44eStnozaki 	return 0;
3762e2fc44eStnozaki }
3772e2fc44eStnozaki 
3782e2fc44eStnozaki /* ----------------------------------------------------------------------
3792e2fc44eStnozaki  * public interface for ctype
3802e2fc44eStnozaki  */
3812e2fc44eStnozaki 
3822e2fc44eStnozaki _CITRUS_CTYPE_DECLS(JOHAB);
3832e2fc44eStnozaki _CITRUS_CTYPE_DEF_OPS(JOHAB);
3842e2fc44eStnozaki 
3852e2fc44eStnozaki #include "citrus_ctype_template.h"
3862e2fc44eStnozaki 
3872e2fc44eStnozaki 
3882e2fc44eStnozaki /* ----------------------------------------------------------------------
3892e2fc44eStnozaki  * public interface for stdenc
3902e2fc44eStnozaki  */
3912e2fc44eStnozaki 
3922e2fc44eStnozaki _CITRUS_STDENC_DECLS(JOHAB);
3932e2fc44eStnozaki _CITRUS_STDENC_DEF_OPS(JOHAB);
3942e2fc44eStnozaki 
3952e2fc44eStnozaki #include "citrus_stdenc_template.h"
396