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