158f0484fSRodney W. Grimes /*-
291fb056eSPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
3df57947fSPedro F. Giffuni *
47b247341SBaptiste Daroussin * Copyright 2013 Garrett D'Amore <garrett@damore.org>
57b247341SBaptiste Daroussin * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
6ca2dae42STim J. Robbins * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
758f0484fSRodney W. Grimes * Copyright (c) 1993
858f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved.
958f0484fSRodney W. Grimes *
1058f0484fSRodney W. Grimes * This code is derived from software contributed to Berkeley by
1158f0484fSRodney W. Grimes * Paul Borman at Krystal Technologies.
1258f0484fSRodney W. Grimes *
133c87aa1dSDavid Chisnall * Copyright (c) 2011 The FreeBSD Foundation
14*5b5fa75aSEd Maste *
153c87aa1dSDavid Chisnall * Portions of this software were developed by David Chisnall
163c87aa1dSDavid Chisnall * under sponsorship from the FreeBSD Foundation.
173c87aa1dSDavid Chisnall *
1858f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without
1958f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions
2058f0484fSRodney W. Grimes * are met:
2158f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright
2258f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer.
2358f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright
2458f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the
2558f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution.
267b247341SBaptiste Daroussin * 3. Neither the name of the University nor the names of its contributors
2758f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software
2858f0484fSRodney W. Grimes * without specific prior written permission.
2958f0484fSRodney W. Grimes *
3058f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3158f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3258f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3358f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3458f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3558f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3658f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3758f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3858f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3958f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4058f0484fSRodney W. Grimes * SUCH DAMAGE.
4158f0484fSRodney W. Grimes */
4258f0484fSRodney W. Grimes
43ca2dae42STim J. Robbins #include <sys/param.h>
4458f0484fSRodney W. Grimes #include <errno.h>
45ca2dae42STim J. Robbins #include <limits.h>
4602f4f60aSTim J. Robbins #include <runetype.h>
4758f0484fSRodney W. Grimes #include <stdlib.h>
48ca2dae42STim J. Robbins #include <string.h>
4902f4f60aSTim J. Robbins #include <wchar.h>
502051a8f2STim J. Robbins #include "mblocal.h"
5102f4f60aSTim J. Robbins
52367ed4e1SAndrey A. Chernov extern int __mb_sb_limit;
53367ed4e1SAndrey A. Chernov
547b247341SBaptiste Daroussin static size_t _EUC_mbrtowc_impl(wchar_t * __restrict, const char * __restrict,
557b247341SBaptiste Daroussin size_t, mbstate_t * __restrict, uint8_t, uint8_t, uint8_t, uint8_t);
567b247341SBaptiste Daroussin static size_t _EUC_wcrtomb_impl(char * __restrict, wchar_t,
577b247341SBaptiste Daroussin mbstate_t * __restrict, uint8_t, uint8_t, uint8_t, uint8_t);
587b247341SBaptiste Daroussin
597b247341SBaptiste Daroussin static size_t _EUC_CN_mbrtowc(wchar_t * __restrict, const char * __restrict,
60e94c6cb4SAlexey Zelkin size_t, mbstate_t * __restrict);
617b247341SBaptiste Daroussin static size_t _EUC_JP_mbrtowc(wchar_t * __restrict, const char * __restrict,
627b247341SBaptiste Daroussin size_t, mbstate_t * __restrict);
637b247341SBaptiste Daroussin static size_t _EUC_KR_mbrtowc(wchar_t * __restrict, const char * __restrict,
647b247341SBaptiste Daroussin size_t, mbstate_t * __restrict);
657b247341SBaptiste Daroussin static size_t _EUC_TW_mbrtowc(wchar_t * __restrict, const char * __restrict,
667b247341SBaptiste Daroussin size_t, mbstate_t * __restrict);
677b247341SBaptiste Daroussin
687b247341SBaptiste Daroussin static size_t _EUC_CN_wcrtomb(char * __restrict, wchar_t,
697b247341SBaptiste Daroussin mbstate_t * __restrict);
707b247341SBaptiste Daroussin static size_t _EUC_JP_wcrtomb(char * __restrict, wchar_t,
717b247341SBaptiste Daroussin mbstate_t * __restrict);
727b247341SBaptiste Daroussin static size_t _EUC_KR_wcrtomb(char * __restrict, wchar_t,
737b247341SBaptiste Daroussin mbstate_t * __restrict);
747b247341SBaptiste Daroussin static size_t _EUC_TW_wcrtomb(char * __restrict, wchar_t,
7502f4f60aSTim J. Robbins mbstate_t * __restrict);
7658f0484fSRodney W. Grimes
777b247341SBaptiste Daroussin static size_t _EUC_CN_mbsnrtowcs(wchar_t * __restrict,
787b247341SBaptiste Daroussin const char ** __restrict, size_t, size_t,
797b247341SBaptiste Daroussin mbstate_t * __restrict);
807b247341SBaptiste Daroussin static size_t _EUC_JP_mbsnrtowcs(wchar_t * __restrict,
817b247341SBaptiste Daroussin const char ** __restrict, size_t, size_t,
827b247341SBaptiste Daroussin mbstate_t * __restrict);
837b247341SBaptiste Daroussin static size_t _EUC_KR_mbsnrtowcs(wchar_t * __restrict,
847b247341SBaptiste Daroussin const char ** __restrict, size_t, size_t,
857b247341SBaptiste Daroussin mbstate_t * __restrict);
867b247341SBaptiste Daroussin static size_t _EUC_TW_mbsnrtowcs(wchar_t * __restrict,
877b247341SBaptiste Daroussin const char ** __restrict, size_t, size_t,
887b247341SBaptiste Daroussin mbstate_t * __restrict);
897b247341SBaptiste Daroussin
907b247341SBaptiste Daroussin static size_t _EUC_CN_wcsnrtombs(char * __restrict,
917b247341SBaptiste Daroussin const wchar_t ** __restrict, size_t, size_t,
927b247341SBaptiste Daroussin mbstate_t * __restrict);
937b247341SBaptiste Daroussin static size_t _EUC_JP_wcsnrtombs(char * __restrict,
947b247341SBaptiste Daroussin const wchar_t ** __restrict, size_t, size_t,
957b247341SBaptiste Daroussin mbstate_t * __restrict);
967b247341SBaptiste Daroussin static size_t _EUC_KR_wcsnrtombs(char * __restrict,
977b247341SBaptiste Daroussin const wchar_t ** __restrict, size_t, size_t,
987b247341SBaptiste Daroussin mbstate_t * __restrict);
997b247341SBaptiste Daroussin static size_t _EUC_TW_wcsnrtombs(char * __restrict,
1007b247341SBaptiste Daroussin const wchar_t ** __restrict, size_t, size_t,
1017b247341SBaptiste Daroussin mbstate_t * __restrict);
1027b247341SBaptiste Daroussin
1037b247341SBaptiste Daroussin static int _EUC_mbsinit(const mbstate_t *);
10458f0484fSRodney W. Grimes
105ca2dae42STim J. Robbins typedef struct {
106c05bd9aeSTim J. Robbins wchar_t ch;
107c05bd9aeSTim J. Robbins int set;
108c05bd9aeSTim J. Robbins int want;
109ca2dae42STim J. Robbins } _EucState;
110ca2dae42STim J. Robbins
111e94c6cb4SAlexey Zelkin static int
_EUC_mbsinit(const mbstate_t * ps)112ca2dae42STim J. Robbins _EUC_mbsinit(const mbstate_t *ps)
113ca2dae42STim J. Robbins {
114ca2dae42STim J. Robbins
115c05bd9aeSTim J. Robbins return (ps == NULL || ((const _EucState *)ps)->want == 0);
116ca2dae42STim J. Robbins }
117ca2dae42STim J. Robbins
1187b247341SBaptiste Daroussin /*
1197b247341SBaptiste Daroussin * EUC-CN uses CS0, CS1 and CS2 (4 bytes).
1207b247341SBaptiste Daroussin */
1217b247341SBaptiste Daroussin int
_EUC_CN_init(struct xlocale_ctype * l,_RuneLocale * rl)1227b247341SBaptiste Daroussin _EUC_CN_init(struct xlocale_ctype *l, _RuneLocale *rl)
12358f0484fSRodney W. Grimes {
1247b247341SBaptiste Daroussin l->__mbrtowc = _EUC_CN_mbrtowc;
1257b247341SBaptiste Daroussin l->__wcrtomb = _EUC_CN_wcrtomb;
1267b247341SBaptiste Daroussin l->__mbsnrtowcs = _EUC_CN_mbsnrtowcs;
1277b247341SBaptiste Daroussin l->__wcsnrtombs = _EUC_CN_wcsnrtombs;
1287b247341SBaptiste Daroussin l->__mbsinit = _EUC_mbsinit;
129e94c6cb4SAlexey Zelkin
1307b247341SBaptiste Daroussin l->runes = rl;
1317b247341SBaptiste Daroussin l->__mb_cur_max = 4;
132e08c3b7cSAndrey A. Chernov l->__mb_sb_limit = 128;
1337b247341SBaptiste Daroussin return (0);
13458f0484fSRodney W. Grimes }
13558f0484fSRodney W. Grimes
136e94c6cb4SAlexey Zelkin static size_t
_EUC_CN_mbrtowc(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps)1377b247341SBaptiste Daroussin _EUC_CN_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s,
1387b247341SBaptiste Daroussin size_t n, mbstate_t * __restrict ps)
1397b247341SBaptiste Daroussin {
1407b247341SBaptiste Daroussin return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0));
1417b247341SBaptiste Daroussin }
1427b247341SBaptiste Daroussin
1437b247341SBaptiste Daroussin static size_t
_EUC_CN_mbsnrtowcs(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps)1447b247341SBaptiste Daroussin _EUC_CN_mbsnrtowcs(wchar_t * __restrict dst,
1457b247341SBaptiste Daroussin const char ** __restrict src,
1467b247341SBaptiste Daroussin size_t nms, size_t len, mbstate_t * __restrict ps)
1477b247341SBaptiste Daroussin {
1487b247341SBaptiste Daroussin return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_CN_mbrtowc));
1497b247341SBaptiste Daroussin }
1507b247341SBaptiste Daroussin
1517b247341SBaptiste Daroussin static size_t
_EUC_CN_wcrtomb(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps)1527b247341SBaptiste Daroussin _EUC_CN_wcrtomb(char * __restrict s, wchar_t wc,
153ca2dae42STim J. Robbins mbstate_t * __restrict ps)
15402f4f60aSTim J. Robbins {
1557b247341SBaptiste Daroussin return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0));
1567b247341SBaptiste Daroussin }
1577b247341SBaptiste Daroussin
1587b247341SBaptiste Daroussin static size_t
_EUC_CN_wcsnrtombs(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps)1597b247341SBaptiste Daroussin _EUC_CN_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
1607b247341SBaptiste Daroussin size_t nwc, size_t len, mbstate_t * __restrict ps)
1617b247341SBaptiste Daroussin {
1627b247341SBaptiste Daroussin return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_CN_wcrtomb));
1637b247341SBaptiste Daroussin }
1647b247341SBaptiste Daroussin
1657b247341SBaptiste Daroussin /*
1667b247341SBaptiste Daroussin * EUC-KR uses only CS0 and CS1.
1677b247341SBaptiste Daroussin */
1687b247341SBaptiste Daroussin int
_EUC_KR_init(struct xlocale_ctype * l,_RuneLocale * rl)1697b247341SBaptiste Daroussin _EUC_KR_init(struct xlocale_ctype *l, _RuneLocale *rl)
1707b247341SBaptiste Daroussin {
1717b247341SBaptiste Daroussin l->__mbrtowc = _EUC_KR_mbrtowc;
1727b247341SBaptiste Daroussin l->__wcrtomb = _EUC_KR_wcrtomb;
1737b247341SBaptiste Daroussin l->__mbsnrtowcs = _EUC_KR_mbsnrtowcs;
1747b247341SBaptiste Daroussin l->__wcsnrtombs = _EUC_KR_wcsnrtombs;
1757b247341SBaptiste Daroussin l->__mbsinit = _EUC_mbsinit;
1767b247341SBaptiste Daroussin
1777b247341SBaptiste Daroussin l->runes = rl;
1787b247341SBaptiste Daroussin l->__mb_cur_max = 2;
1797b247341SBaptiste Daroussin l->__mb_sb_limit = 128;
1807b247341SBaptiste Daroussin return (0);
1817b247341SBaptiste Daroussin }
1827b247341SBaptiste Daroussin
1837b247341SBaptiste Daroussin static size_t
_EUC_KR_mbrtowc(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps)1847b247341SBaptiste Daroussin _EUC_KR_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s,
1857b247341SBaptiste Daroussin size_t n, mbstate_t * __restrict ps)
1867b247341SBaptiste Daroussin {
1877b247341SBaptiste Daroussin return (_EUC_mbrtowc_impl(pwc, s, n, ps, 0, 0, 0, 0));
1887b247341SBaptiste Daroussin }
1897b247341SBaptiste Daroussin
1907b247341SBaptiste Daroussin static size_t
_EUC_KR_mbsnrtowcs(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps)1917b247341SBaptiste Daroussin _EUC_KR_mbsnrtowcs(wchar_t * __restrict dst,
1927b247341SBaptiste Daroussin const char ** __restrict src,
1937b247341SBaptiste Daroussin size_t nms, size_t len, mbstate_t * __restrict ps)
1947b247341SBaptiste Daroussin {
1957b247341SBaptiste Daroussin return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_KR_mbrtowc));
1967b247341SBaptiste Daroussin }
1977b247341SBaptiste Daroussin
1987b247341SBaptiste Daroussin static size_t
_EUC_KR_wcrtomb(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps)1997b247341SBaptiste Daroussin _EUC_KR_wcrtomb(char * __restrict s, wchar_t wc,
2007b247341SBaptiste Daroussin mbstate_t * __restrict ps)
2017b247341SBaptiste Daroussin {
2027b247341SBaptiste Daroussin return (_EUC_wcrtomb_impl(s, wc, ps, 0, 0, 0, 0));
2037b247341SBaptiste Daroussin }
2047b247341SBaptiste Daroussin
2057b247341SBaptiste Daroussin static size_t
_EUC_KR_wcsnrtombs(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps)2067b247341SBaptiste Daroussin _EUC_KR_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
2077b247341SBaptiste Daroussin size_t nwc, size_t len, mbstate_t * __restrict ps)
2087b247341SBaptiste Daroussin {
2097b247341SBaptiste Daroussin return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_KR_wcrtomb));
2107b247341SBaptiste Daroussin }
2117b247341SBaptiste Daroussin
2127b247341SBaptiste Daroussin /*
2137b247341SBaptiste Daroussin * EUC-JP uses CS0, CS1, CS2, and CS3.
2147b247341SBaptiste Daroussin */
2157b247341SBaptiste Daroussin int
_EUC_JP_init(struct xlocale_ctype * l,_RuneLocale * rl)2167b247341SBaptiste Daroussin _EUC_JP_init(struct xlocale_ctype *l, _RuneLocale *rl)
2177b247341SBaptiste Daroussin {
2187b247341SBaptiste Daroussin l->__mbrtowc = _EUC_JP_mbrtowc;
2197b247341SBaptiste Daroussin l->__wcrtomb = _EUC_JP_wcrtomb;
2207b247341SBaptiste Daroussin l->__mbsnrtowcs = _EUC_JP_mbsnrtowcs;
2217b247341SBaptiste Daroussin l->__wcsnrtombs = _EUC_JP_wcsnrtombs;
2227b247341SBaptiste Daroussin l->__mbsinit = _EUC_mbsinit;
2237b247341SBaptiste Daroussin
2247b247341SBaptiste Daroussin l->runes = rl;
2257b247341SBaptiste Daroussin l->__mb_cur_max = 3;
226e08c3b7cSAndrey A. Chernov l->__mb_sb_limit = 128;
2277b247341SBaptiste Daroussin return (0);
2287b247341SBaptiste Daroussin }
2297b247341SBaptiste Daroussin
2307b247341SBaptiste Daroussin static size_t
_EUC_JP_mbrtowc(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps)2317b247341SBaptiste Daroussin _EUC_JP_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s,
2327b247341SBaptiste Daroussin size_t n, mbstate_t * __restrict ps)
2337b247341SBaptiste Daroussin {
2347b247341SBaptiste Daroussin return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 2, SS3, 3));
2357b247341SBaptiste Daroussin }
2367b247341SBaptiste Daroussin
2377b247341SBaptiste Daroussin static size_t
_EUC_JP_mbsnrtowcs(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps)2387b247341SBaptiste Daroussin _EUC_JP_mbsnrtowcs(wchar_t * __restrict dst,
2397b247341SBaptiste Daroussin const char ** __restrict src,
2407b247341SBaptiste Daroussin size_t nms, size_t len, mbstate_t * __restrict ps)
2417b247341SBaptiste Daroussin {
2427b247341SBaptiste Daroussin return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_JP_mbrtowc));
2437b247341SBaptiste Daroussin }
2447b247341SBaptiste Daroussin
2457b247341SBaptiste Daroussin static size_t
_EUC_JP_wcrtomb(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps)2467b247341SBaptiste Daroussin _EUC_JP_wcrtomb(char * __restrict s, wchar_t wc,
2477b247341SBaptiste Daroussin mbstate_t * __restrict ps)
2487b247341SBaptiste Daroussin {
2497b247341SBaptiste Daroussin return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 2, SS3, 3));
2507b247341SBaptiste Daroussin }
2517b247341SBaptiste Daroussin
2527b247341SBaptiste Daroussin static size_t
_EUC_JP_wcsnrtombs(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps)2537b247341SBaptiste Daroussin _EUC_JP_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
2547b247341SBaptiste Daroussin size_t nwc, size_t len, mbstate_t * __restrict ps)
2557b247341SBaptiste Daroussin {
2567b247341SBaptiste Daroussin return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_JP_wcrtomb));
2577b247341SBaptiste Daroussin }
2587b247341SBaptiste Daroussin
2597b247341SBaptiste Daroussin /*
2607b247341SBaptiste Daroussin * EUC-TW uses CS0, CS1, and CS2.
2617b247341SBaptiste Daroussin */
2627b247341SBaptiste Daroussin int
_EUC_TW_init(struct xlocale_ctype * l,_RuneLocale * rl)2637b247341SBaptiste Daroussin _EUC_TW_init(struct xlocale_ctype *l, _RuneLocale *rl)
2647b247341SBaptiste Daroussin {
2657b247341SBaptiste Daroussin l->__mbrtowc = _EUC_TW_mbrtowc;
2667b247341SBaptiste Daroussin l->__wcrtomb = _EUC_TW_wcrtomb;
2677b247341SBaptiste Daroussin l->__mbsnrtowcs = _EUC_TW_mbsnrtowcs;
2687b247341SBaptiste Daroussin l->__wcsnrtombs = _EUC_TW_wcsnrtombs;
2697b247341SBaptiste Daroussin l->__mbsinit = _EUC_mbsinit;
2707b247341SBaptiste Daroussin
2717b247341SBaptiste Daroussin l->runes = rl;
2727b247341SBaptiste Daroussin l->__mb_cur_max = 4;
273e08c3b7cSAndrey A. Chernov l->__mb_sb_limit = 128;
2747b247341SBaptiste Daroussin return (0);
2757b247341SBaptiste Daroussin }
2767b247341SBaptiste Daroussin
2777b247341SBaptiste Daroussin static size_t
_EUC_TW_mbrtowc(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps)2787b247341SBaptiste Daroussin _EUC_TW_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s,
2797b247341SBaptiste Daroussin size_t n, mbstate_t * __restrict ps)
2807b247341SBaptiste Daroussin {
2817b247341SBaptiste Daroussin return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0));
2827b247341SBaptiste Daroussin }
2837b247341SBaptiste Daroussin
2847b247341SBaptiste Daroussin static size_t
_EUC_TW_mbsnrtowcs(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps)2857b247341SBaptiste Daroussin _EUC_TW_mbsnrtowcs(wchar_t * __restrict dst,
2867b247341SBaptiste Daroussin const char ** __restrict src,
2877b247341SBaptiste Daroussin size_t nms, size_t len, mbstate_t * __restrict ps)
2887b247341SBaptiste Daroussin {
2897b247341SBaptiste Daroussin return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_TW_mbrtowc));
2907b247341SBaptiste Daroussin }
2917b247341SBaptiste Daroussin
2927b247341SBaptiste Daroussin static size_t
_EUC_TW_wcrtomb(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps)2937b247341SBaptiste Daroussin _EUC_TW_wcrtomb(char * __restrict s, wchar_t wc,
2947b247341SBaptiste Daroussin mbstate_t * __restrict ps)
2957b247341SBaptiste Daroussin {
2967b247341SBaptiste Daroussin return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0));
2977b247341SBaptiste Daroussin }
2987b247341SBaptiste Daroussin
2997b247341SBaptiste Daroussin static size_t
_EUC_TW_wcsnrtombs(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps)3007b247341SBaptiste Daroussin _EUC_TW_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
3017b247341SBaptiste Daroussin size_t nwc, size_t len, mbstate_t * __restrict ps)
3027b247341SBaptiste Daroussin {
3037b247341SBaptiste Daroussin return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_TW_wcrtomb));
3047b247341SBaptiste Daroussin }
3057b247341SBaptiste Daroussin
3067b247341SBaptiste Daroussin /*
3077b247341SBaptiste Daroussin * Common EUC code.
3087b247341SBaptiste Daroussin */
3097b247341SBaptiste Daroussin
3107b247341SBaptiste Daroussin static size_t
_EUC_mbrtowc_impl(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps,uint8_t cs2,uint8_t cs2width,uint8_t cs3,uint8_t cs3width)3117b247341SBaptiste Daroussin _EUC_mbrtowc_impl(wchar_t * __restrict pwc, const char * __restrict s,
3127b247341SBaptiste Daroussin size_t n, mbstate_t * __restrict ps,
3137b247341SBaptiste Daroussin uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width)
3147b247341SBaptiste Daroussin {
315ca2dae42STim J. Robbins _EucState *es;
3167b247341SBaptiste Daroussin int i, want;
317d8ed03efSBaptiste Daroussin wchar_t wc = 0;
318d8ed03efSBaptiste Daroussin unsigned char ch, chs;
31902f4f60aSTim J. Robbins
320ca2dae42STim J. Robbins es = (_EucState *)ps;
321ca2dae42STim J. Robbins
3227b247341SBaptiste Daroussin if (es->want < 0 || es->want > MB_CUR_MAX) {
323fc813796STim J. Robbins errno = EINVAL;
324fc813796STim J. Robbins return ((size_t)-1);
325fc813796STim J. Robbins }
326fc813796STim J. Robbins
327ca2dae42STim J. Robbins if (s == NULL) {
328ca2dae42STim J. Robbins s = "";
329ca2dae42STim J. Robbins n = 1;
330ca2dae42STim J. Robbins pwc = NULL;
331ca2dae42STim J. Robbins }
332ca2dae42STim J. Robbins
333c05bd9aeSTim J. Robbins if (n == 0)
33402f4f60aSTim J. Robbins /* Incomplete multibyte sequence */
33502f4f60aSTim J. Robbins return ((size_t)-2);
336c05bd9aeSTim J. Robbins
337c05bd9aeSTim J. Robbins if (es->want == 0) {
3387b247341SBaptiste Daroussin /* Fast path for plain ASCII (CS0) */
3397b247341SBaptiste Daroussin if (((ch = (unsigned char)*s) & 0x80) == 0) {
3407b247341SBaptiste Daroussin if (pwc != NULL)
3417b247341SBaptiste Daroussin *pwc = ch;
3427b247341SBaptiste Daroussin return (ch != '\0' ? 1 : 0);
343c05bd9aeSTim J. Robbins }
3447b247341SBaptiste Daroussin
3457b247341SBaptiste Daroussin if (ch >= 0xa1) {
3467b247341SBaptiste Daroussin /* CS1 */
3477b247341SBaptiste Daroussin want = 2;
3487b247341SBaptiste Daroussin } else if (ch == cs2) {
3497b247341SBaptiste Daroussin want = cs2width;
3507b247341SBaptiste Daroussin } else if (ch == cs3) {
3517b247341SBaptiste Daroussin want = cs3width;
3527b247341SBaptiste Daroussin } else {
353c05bd9aeSTim J. Robbins errno = EILSEQ;
354c05bd9aeSTim J. Robbins return ((size_t)-1);
355c05bd9aeSTim J. Robbins }
3567b247341SBaptiste Daroussin
3577b247341SBaptiste Daroussin
3587b247341SBaptiste Daroussin es->want = want;
3597b247341SBaptiste Daroussin es->ch = 0;
360c05bd9aeSTim J. Robbins } else {
361c05bd9aeSTim J. Robbins want = es->want;
362c05bd9aeSTim J. Robbins wc = es->ch;
363c05bd9aeSTim J. Robbins }
3647b247341SBaptiste Daroussin
3657b247341SBaptiste Daroussin for (i = 0; i < MIN(want, n); i++) {
3667b247341SBaptiste Daroussin wc <<= 8;
367d8ed03efSBaptiste Daroussin chs = *s;
368d8ed03efSBaptiste Daroussin wc |= chs;
3697b247341SBaptiste Daroussin s++;
37088af941aSTim J. Robbins }
371c05bd9aeSTim J. Robbins if (i < want) {
372c05bd9aeSTim J. Robbins /* Incomplete multibyte sequence */
373c05bd9aeSTim J. Robbins es->want = want - i;
374c05bd9aeSTim J. Robbins es->ch = wc;
375e5850478SBaptiste Daroussin errno = EILSEQ;
376c05bd9aeSTim J. Robbins return ((size_t)-2);
37758f0484fSRodney W. Grimes }
37802f4f60aSTim J. Robbins if (pwc != NULL)
37902f4f60aSTim J. Robbins *pwc = wc;
380c05bd9aeSTim J. Robbins es->want = 0;
3817b247341SBaptiste Daroussin return (wc == L'\0' ? 0 : want);
38258f0484fSRodney W. Grimes }
38358f0484fSRodney W. Grimes
384e94c6cb4SAlexey Zelkin static size_t
_EUC_wcrtomb_impl(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps,uint8_t cs2,uint8_t cs2width,uint8_t cs3,uint8_t cs3width)3857b247341SBaptiste Daroussin _EUC_wcrtomb_impl(char * __restrict s, wchar_t wc,
3867b247341SBaptiste Daroussin mbstate_t * __restrict ps,
3877b247341SBaptiste Daroussin uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width)
38858f0484fSRodney W. Grimes {
389fc813796STim J. Robbins _EucState *es;
39058f0484fSRodney W. Grimes int i, len;
3917b247341SBaptiste Daroussin wchar_t nm;
39258f0484fSRodney W. Grimes
393fc813796STim J. Robbins es = (_EucState *)ps;
394fc813796STim J. Robbins
395c05bd9aeSTim J. Robbins if (es->want != 0) {
396fc813796STim J. Robbins errno = EINVAL;
397fc813796STim J. Robbins return ((size_t)-1);
398fc813796STim J. Robbins }
399fc813796STim J. Robbins
40002f4f60aSTim J. Robbins if (s == NULL)
40102f4f60aSTim J. Robbins /* Reset to initial shift state (no-op) */
40202f4f60aSTim J. Robbins return (1);
40302f4f60aSTim J. Robbins
4047b247341SBaptiste Daroussin if ((wc & ~0x7f) == 0) {
4057b247341SBaptiste Daroussin /* Fast path for plain ASCII (CS0) */
4067b247341SBaptiste Daroussin *s = (char)wc;
4077b247341SBaptiste Daroussin return (1);
4087b247341SBaptiste Daroussin }
40902f4f60aSTim J. Robbins
4107b247341SBaptiste Daroussin /* Determine the "length" */
4117b247341SBaptiste Daroussin if ((unsigned)wc > 0xffffff) {
4127b247341SBaptiste Daroussin len = 4;
4137b247341SBaptiste Daroussin } else if ((unsigned)wc > 0xffff) {
4147b247341SBaptiste Daroussin len = 3;
4157b247341SBaptiste Daroussin } else if ((unsigned)wc > 0xff) {
4167b247341SBaptiste Daroussin len = 2;
41758f0484fSRodney W. Grimes } else {
4187b247341SBaptiste Daroussin len = 1;
4197b247341SBaptiste Daroussin }
4207b247341SBaptiste Daroussin
4217b247341SBaptiste Daroussin if (len > MB_CUR_MAX) {
4227b247341SBaptiste Daroussin errno = EILSEQ;
4237b247341SBaptiste Daroussin return ((size_t)-1);
4247b247341SBaptiste Daroussin }
4257b247341SBaptiste Daroussin
4267b247341SBaptiste Daroussin /* This first check excludes CS1, which is implicitly valid. */
4277b247341SBaptiste Daroussin if ((wc < 0xa100) || (wc > 0xffff)) {
4287b247341SBaptiste Daroussin /* Check for valid CS2 or CS3 */
4297b247341SBaptiste Daroussin nm = (wc >> ((len - 1) * 8));
4307b247341SBaptiste Daroussin if (nm == cs2) {
4317b247341SBaptiste Daroussin if (len != cs2width) {
4327b247341SBaptiste Daroussin errno = EILSEQ;
4337b247341SBaptiste Daroussin return ((size_t)-1);
4347b247341SBaptiste Daroussin }
4357b247341SBaptiste Daroussin } else if (nm == cs3) {
4367b247341SBaptiste Daroussin if (len != cs3width) {
4377b247341SBaptiste Daroussin errno = EILSEQ;
4387b247341SBaptiste Daroussin return ((size_t)-1);
4397b247341SBaptiste Daroussin }
4407b247341SBaptiste Daroussin } else {
4417b247341SBaptiste Daroussin errno = EILSEQ;
4427b247341SBaptiste Daroussin return ((size_t)-1);
4437b247341SBaptiste Daroussin }
4447b247341SBaptiste Daroussin }
4457b247341SBaptiste Daroussin
4467b247341SBaptiste Daroussin /* Stash the bytes, least significant last */
4477b247341SBaptiste Daroussin for (i = len - 1; i >= 0; i--) {
4487b247341SBaptiste Daroussin s[i] = (wc & 0xff);
4497b247341SBaptiste Daroussin wc >>= 8;
45058f0484fSRodney W. Grimes }
45158f0484fSRodney W. Grimes return (len);
45258f0484fSRodney W. Grimes }
453