xref: /titanic_50/usr/src/lib/libc/port/locale/euc.c (revision 3fc10f8cbc2fd5dd5cd13044edf9cb68a1ef422b)
14297a3b0SGarrett D'Amore /*
22d08521bSGarrett D'Amore  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
39d04e500SGarrett D'Amore  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
44297a3b0SGarrett D'Amore  * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
54297a3b0SGarrett D'Amore  * Copyright (c) 1993
64297a3b0SGarrett D'Amore  *	The Regents of the University of California.  All rights reserved.
74297a3b0SGarrett D'Amore  *
84297a3b0SGarrett D'Amore  * This code is derived from software contributed to Berkeley by
94297a3b0SGarrett D'Amore  * Paul Borman at Krystal Technologies.
104297a3b0SGarrett D'Amore  *
114297a3b0SGarrett D'Amore  * Redistribution and use in source and binary forms, with or without
124297a3b0SGarrett D'Amore  * modification, are permitted provided that the following conditions
134297a3b0SGarrett D'Amore  * are met:
144297a3b0SGarrett D'Amore  * 1. Redistributions of source code must retain the above copyright
154297a3b0SGarrett D'Amore  *    notice, this list of conditions and the following disclaimer.
164297a3b0SGarrett D'Amore  * 2. Redistributions in binary form must reproduce the above copyright
174297a3b0SGarrett D'Amore  *    notice, this list of conditions and the following disclaimer in the
184297a3b0SGarrett D'Amore  *    documentation and/or other materials provided with the distribution.
194297a3b0SGarrett D'Amore  * 4. Neither the name of the University nor the names of its contributors
204297a3b0SGarrett D'Amore  *    may be used to endorse or promote products derived from this software
214297a3b0SGarrett D'Amore  *    without specific prior written permission.
224297a3b0SGarrett D'Amore  *
234297a3b0SGarrett D'Amore  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
244297a3b0SGarrett D'Amore  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
254297a3b0SGarrett D'Amore  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
264297a3b0SGarrett D'Amore  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
274297a3b0SGarrett D'Amore  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
284297a3b0SGarrett D'Amore  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
294297a3b0SGarrett D'Amore  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
304297a3b0SGarrett D'Amore  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
314297a3b0SGarrett D'Amore  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
324297a3b0SGarrett D'Amore  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
334297a3b0SGarrett D'Amore  * SUCH DAMAGE.
344297a3b0SGarrett D'Amore  */
354297a3b0SGarrett D'Amore 
364297a3b0SGarrett D'Amore #include "lint.h"
374297a3b0SGarrett D'Amore #include <errno.h>
384297a3b0SGarrett D'Amore #include <limits.h>
394297a3b0SGarrett D'Amore #include <stdlib.h>
404297a3b0SGarrett D'Amore #include <string.h>
414297a3b0SGarrett D'Amore #include <wchar.h>
424297a3b0SGarrett D'Amore #include <sys/types.h>
439d04e500SGarrett D'Amore #include <sys/euc.h>
444297a3b0SGarrett D'Amore #include "mblocal.h"
452d08521bSGarrett D'Amore #include "lctype.h"
464297a3b0SGarrett D'Amore 
479d04e500SGarrett D'Amore static size_t	_EUC_mbrtowc_impl(wchar_t *_RESTRICT_KYWD,
489d04e500SGarrett D'Amore     const char *_RESTRICT_KYWD,
49*50370af8SRobert Mustacchi     size_t, mbstate_t *_RESTRICT_KYWD, uint8_t, uint8_t, uint8_t, uint8_t,
50*50370af8SRobert Mustacchi     boolean_t);
519d04e500SGarrett D'Amore static size_t	_EUC_wcrtomb_impl(char *_RESTRICT_KYWD, wchar_t,
529d04e500SGarrett D'Amore     mbstate_t *_RESTRICT_KYWD, uint8_t, uint8_t, uint8_t, uint8_t);
534297a3b0SGarrett D'Amore 
549d04e500SGarrett D'Amore static size_t	_EUC_CN_mbrtowc(wchar_t *_RESTRICT_KYWD,
554297a3b0SGarrett D'Amore 		    const char *_RESTRICT_KYWD,
56*50370af8SRobert Mustacchi 		    size_t, mbstate_t *_RESTRICT_KYWD, boolean_t);
579d04e500SGarrett D'Amore static size_t	_EUC_JP_mbrtowc(wchar_t *_RESTRICT_KYWD,
589d04e500SGarrett D'Amore 		    const char *_RESTRICT_KYWD,
59*50370af8SRobert Mustacchi 		    size_t, mbstate_t *_RESTRICT_KYWD, boolean_t);
609d04e500SGarrett D'Amore static size_t	_EUC_KR_mbrtowc(wchar_t *_RESTRICT_KYWD,
619d04e500SGarrett D'Amore 		    const char *_RESTRICT_KYWD,
62*50370af8SRobert Mustacchi 		    size_t, mbstate_t *_RESTRICT_KYWD, boolean_t);
639d04e500SGarrett D'Amore static size_t	_EUC_TW_mbrtowc(wchar_t *_RESTRICT_KYWD,
649d04e500SGarrett D'Amore 		    const char *_RESTRICT_KYWD,
65*50370af8SRobert Mustacchi 		    size_t, mbstate_t *_RESTRICT_KYWD, boolean_t);
662d08521bSGarrett D'Amore 
679d04e500SGarrett D'Amore static size_t	_EUC_CN_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
684297a3b0SGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
699d04e500SGarrett D'Amore static size_t	_EUC_JP_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
709d04e500SGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
719d04e500SGarrett D'Amore static size_t	_EUC_KR_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
729d04e500SGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
739d04e500SGarrett D'Amore static size_t	_EUC_TW_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
749d04e500SGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
752d08521bSGarrett D'Amore 
762d08521bSGarrett D'Amore static size_t	_EUC_CN_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
772d08521bSGarrett D'Amore 		    const char **_RESTRICT_KYWD, size_t, size_t,
782d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
792d08521bSGarrett D'Amore static size_t	_EUC_JP_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
802d08521bSGarrett D'Amore 		    const char **_RESTRICT_KYWD, size_t, size_t,
812d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
822d08521bSGarrett D'Amore static size_t	_EUC_KR_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
832d08521bSGarrett D'Amore 		    const char **_RESTRICT_KYWD, size_t, size_t,
842d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
852d08521bSGarrett D'Amore static size_t	_EUC_TW_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
862d08521bSGarrett D'Amore 		    const char **_RESTRICT_KYWD, size_t, size_t,
872d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
882d08521bSGarrett D'Amore 
892d08521bSGarrett D'Amore static size_t	_EUC_CN_wcsnrtombs(char *_RESTRICT_KYWD,
902d08521bSGarrett D'Amore 		    const wchar_t **_RESTRICT_KYWD, size_t, size_t,
912d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
922d08521bSGarrett D'Amore static size_t	_EUC_JP_wcsnrtombs(char *_RESTRICT_KYWD,
932d08521bSGarrett D'Amore 		    const wchar_t **_RESTRICT_KYWD, size_t, size_t,
942d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
952d08521bSGarrett D'Amore static size_t	_EUC_KR_wcsnrtombs(char *_RESTRICT_KYWD,
962d08521bSGarrett D'Amore 		    const wchar_t **_RESTRICT_KYWD, size_t, size_t,
972d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
982d08521bSGarrett D'Amore static size_t	_EUC_TW_wcsnrtombs(char *_RESTRICT_KYWD,
992d08521bSGarrett D'Amore 		    const wchar_t **_RESTRICT_KYWD, size_t, size_t,
1002d08521bSGarrett D'Amore 		    mbstate_t *_RESTRICT_KYWD);
1012d08521bSGarrett D'Amore 
1029d04e500SGarrett D'Amore static int	_EUC_mbsinit(const mbstate_t *);
1034297a3b0SGarrett D'Amore 
1042d08521bSGarrett D'Amore int
_EUC_mbsinit(const mbstate_t * ps)1054297a3b0SGarrett D'Amore _EUC_mbsinit(const mbstate_t *ps)
1064297a3b0SGarrett D'Amore {
1074297a3b0SGarrett D'Amore 
1084297a3b0SGarrett D'Amore 	return (ps == NULL || ((const _EucState *)ps)->want == 0);
1094297a3b0SGarrett D'Amore }
1104297a3b0SGarrett D'Amore 
1119d04e500SGarrett D'Amore /*
1129d04e500SGarrett D'Amore  * EUC-CN uses CS0, CS1 and CS2 (4 bytes).
1139d04e500SGarrett D'Amore  */
1142d08521bSGarrett D'Amore void
_EUC_CN_init(struct lc_ctype * lct)1152d08521bSGarrett D'Amore _EUC_CN_init(struct lc_ctype *lct)
1164297a3b0SGarrett D'Amore {
1172d08521bSGarrett D'Amore 	lct->lc_mbrtowc = _EUC_CN_mbrtowc;
1182d08521bSGarrett D'Amore 	lct->lc_wcrtomb = _EUC_CN_wcrtomb;
1192d08521bSGarrett D'Amore 	lct->lc_mbsnrtowcs = _EUC_CN_mbsnrtowcs;
1202d08521bSGarrett D'Amore 	lct->lc_wcsnrtombs = _EUC_CN_wcsnrtombs;
1212d08521bSGarrett D'Amore 	lct->lc_mbsinit = _EUC_mbsinit;
1224297a3b0SGarrett D'Amore 
1232d08521bSGarrett D'Amore 	lct->lc_max_mblen = 4;
1242d08521bSGarrett D'Amore 	lct->lc_is_ascii = 0;
1254297a3b0SGarrett D'Amore }
1264297a3b0SGarrett D'Amore 
1274297a3b0SGarrett D'Amore static size_t
_EUC_CN_mbrtowc(wchar_t * _RESTRICT_KYWD pwc,const char * _RESTRICT_KYWD s,size_t n,mbstate_t * _RESTRICT_KYWD ps,boolean_t zero)1289d04e500SGarrett D'Amore _EUC_CN_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
129*50370af8SRobert Mustacchi     size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero)
1304297a3b0SGarrett D'Amore {
131*50370af8SRobert Mustacchi 	return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0, zero));
1329d04e500SGarrett D'Amore }
1339d04e500SGarrett D'Amore 
1349d04e500SGarrett D'Amore static size_t
_EUC_CN_mbsnrtowcs(wchar_t * _RESTRICT_KYWD dst,const char ** _RESTRICT_KYWD src,size_t nms,size_t len,mbstate_t * _RESTRICT_KYWD ps)1352d08521bSGarrett D'Amore _EUC_CN_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
1362d08521bSGarrett D'Amore     const char **_RESTRICT_KYWD src,
1372d08521bSGarrett D'Amore     size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
1382d08521bSGarrett D'Amore {
1392d08521bSGarrett D'Amore 	return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_CN_mbrtowc));
1402d08521bSGarrett D'Amore }
1412d08521bSGarrett D'Amore 
1422d08521bSGarrett D'Amore static size_t
_EUC_CN_wcrtomb(char * _RESTRICT_KYWD s,wchar_t wc,mbstate_t * _RESTRICT_KYWD ps)1439d04e500SGarrett D'Amore _EUC_CN_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
1449d04e500SGarrett D'Amore     mbstate_t *_RESTRICT_KYWD ps)
1459d04e500SGarrett D'Amore {
1469d04e500SGarrett D'Amore 	return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0));
1479d04e500SGarrett D'Amore }
1489d04e500SGarrett D'Amore 
1492d08521bSGarrett D'Amore static size_t
_EUC_CN_wcsnrtombs(char * _RESTRICT_KYWD dst,const wchar_t ** _RESTRICT_KYWD src,size_t nwc,size_t len,mbstate_t * _RESTRICT_KYWD ps)1502d08521bSGarrett D'Amore _EUC_CN_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
1512d08521bSGarrett D'Amore     size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
1522d08521bSGarrett D'Amore {
1532d08521bSGarrett D'Amore 	return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_CN_wcrtomb));
1542d08521bSGarrett D'Amore }
1552d08521bSGarrett D'Amore 
1569d04e500SGarrett D'Amore /*
1579d04e500SGarrett D'Amore  * EUC-KR uses only CS0 and CS1.
1589d04e500SGarrett D'Amore  */
1592d08521bSGarrett D'Amore void
_EUC_KR_init(struct lc_ctype * lct)1602d08521bSGarrett D'Amore _EUC_KR_init(struct lc_ctype *lct)
1619d04e500SGarrett D'Amore {
1622d08521bSGarrett D'Amore 	lct->lc_mbrtowc = _EUC_KR_mbrtowc;
1632d08521bSGarrett D'Amore 	lct->lc_wcrtomb = _EUC_KR_wcrtomb;
1642d08521bSGarrett D'Amore 	lct->lc_mbsnrtowcs = _EUC_KR_mbsnrtowcs;
1652d08521bSGarrett D'Amore 	lct->lc_wcsnrtombs = _EUC_KR_wcsnrtombs;
1662d08521bSGarrett D'Amore 	lct->lc_mbsinit = _EUC_mbsinit;
1679d04e500SGarrett D'Amore 
1682d08521bSGarrett D'Amore 	lct->lc_max_mblen = 2;
1692d08521bSGarrett D'Amore 	lct->lc_is_ascii = 0;
1709d04e500SGarrett D'Amore }
1719d04e500SGarrett D'Amore 
1729d04e500SGarrett D'Amore static size_t
_EUC_KR_mbrtowc(wchar_t * _RESTRICT_KYWD pwc,const char * _RESTRICT_KYWD s,size_t n,mbstate_t * _RESTRICT_KYWD ps,boolean_t zero)1739d04e500SGarrett D'Amore _EUC_KR_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
174*50370af8SRobert Mustacchi     size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero)
1759d04e500SGarrett D'Amore {
176*50370af8SRobert Mustacchi 	return (_EUC_mbrtowc_impl(pwc, s, n, ps, 0, 0, 0, 0, zero));
1779d04e500SGarrett D'Amore }
1789d04e500SGarrett D'Amore 
1799d04e500SGarrett D'Amore static size_t
_EUC_KR_mbsnrtowcs(wchar_t * _RESTRICT_KYWD dst,const char ** _RESTRICT_KYWD src,size_t nms,size_t len,mbstate_t * _RESTRICT_KYWD ps)1802d08521bSGarrett D'Amore _EUC_KR_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
1812d08521bSGarrett D'Amore     const char **_RESTRICT_KYWD src,
1822d08521bSGarrett D'Amore     size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
1832d08521bSGarrett D'Amore {
1842d08521bSGarrett D'Amore 	return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_KR_mbrtowc));
1852d08521bSGarrett D'Amore }
1862d08521bSGarrett D'Amore 
1872d08521bSGarrett D'Amore static size_t
_EUC_KR_wcrtomb(char * _RESTRICT_KYWD s,wchar_t wc,mbstate_t * _RESTRICT_KYWD ps)1889d04e500SGarrett D'Amore _EUC_KR_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
1899d04e500SGarrett D'Amore     mbstate_t *_RESTRICT_KYWD ps)
1909d04e500SGarrett D'Amore {
1919d04e500SGarrett D'Amore 	return (_EUC_wcrtomb_impl(s, wc, ps, 0, 0, 0, 0));
1929d04e500SGarrett D'Amore }
1939d04e500SGarrett D'Amore 
1942d08521bSGarrett D'Amore static size_t
_EUC_KR_wcsnrtombs(char * _RESTRICT_KYWD dst,const wchar_t ** _RESTRICT_KYWD src,size_t nwc,size_t len,mbstate_t * _RESTRICT_KYWD ps)1952d08521bSGarrett D'Amore _EUC_KR_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
1962d08521bSGarrett D'Amore     size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
1972d08521bSGarrett D'Amore {
1982d08521bSGarrett D'Amore 	return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_KR_wcrtomb));
1992d08521bSGarrett D'Amore }
2002d08521bSGarrett D'Amore 
2019d04e500SGarrett D'Amore /*
2029d04e500SGarrett D'Amore  * EUC-JP uses CS0, CS1, CS2, and CS3.
2039d04e500SGarrett D'Amore  */
2042d08521bSGarrett D'Amore void
_EUC_JP_init(struct lc_ctype * lct)2052d08521bSGarrett D'Amore _EUC_JP_init(struct lc_ctype *lct)
2069d04e500SGarrett D'Amore {
2072d08521bSGarrett D'Amore 	lct->lc_mbrtowc = _EUC_JP_mbrtowc;
2082d08521bSGarrett D'Amore 	lct->lc_wcrtomb = _EUC_JP_wcrtomb;
2092d08521bSGarrett D'Amore 	lct->lc_mbsnrtowcs = _EUC_JP_mbsnrtowcs;
2102d08521bSGarrett D'Amore 	lct->lc_wcsnrtombs = _EUC_JP_wcsnrtombs;
2112d08521bSGarrett D'Amore 	lct->lc_mbsinit = _EUC_mbsinit;
2129d04e500SGarrett D'Amore 
2132d08521bSGarrett D'Amore 	lct->lc_max_mblen = 3;
2142d08521bSGarrett D'Amore 	lct->lc_is_ascii = 0;
2159d04e500SGarrett D'Amore }
2169d04e500SGarrett D'Amore 
2179d04e500SGarrett D'Amore static size_t
_EUC_JP_mbrtowc(wchar_t * _RESTRICT_KYWD pwc,const char * _RESTRICT_KYWD s,size_t n,mbstate_t * _RESTRICT_KYWD ps,boolean_t zero)2189d04e500SGarrett D'Amore _EUC_JP_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
219*50370af8SRobert Mustacchi     size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero)
2209d04e500SGarrett D'Amore {
221*50370af8SRobert Mustacchi 	return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 2, SS3, 3, zero));
2229d04e500SGarrett D'Amore }
2239d04e500SGarrett D'Amore 
2249d04e500SGarrett D'Amore static size_t
_EUC_JP_mbsnrtowcs(wchar_t * _RESTRICT_KYWD dst,const char ** _RESTRICT_KYWD src,size_t nms,size_t len,mbstate_t * _RESTRICT_KYWD ps)2252d08521bSGarrett D'Amore _EUC_JP_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
2262d08521bSGarrett D'Amore     const char **_RESTRICT_KYWD src,
2272d08521bSGarrett D'Amore     size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
2282d08521bSGarrett D'Amore {
2292d08521bSGarrett D'Amore 	return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_JP_mbrtowc));
2302d08521bSGarrett D'Amore }
2312d08521bSGarrett D'Amore 
2322d08521bSGarrett D'Amore static size_t
_EUC_JP_wcrtomb(char * _RESTRICT_KYWD s,wchar_t wc,mbstate_t * _RESTRICT_KYWD ps)2339d04e500SGarrett D'Amore _EUC_JP_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
2349d04e500SGarrett D'Amore     mbstate_t *_RESTRICT_KYWD ps)
2359d04e500SGarrett D'Amore {
2369d04e500SGarrett D'Amore 	return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 2, SS3, 3));
2379d04e500SGarrett D'Amore }
2389d04e500SGarrett D'Amore 
2392d08521bSGarrett D'Amore static size_t
_EUC_JP_wcsnrtombs(char * _RESTRICT_KYWD dst,const wchar_t ** _RESTRICT_KYWD src,size_t nwc,size_t len,mbstate_t * _RESTRICT_KYWD ps)2402d08521bSGarrett D'Amore _EUC_JP_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
2412d08521bSGarrett D'Amore     size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
2422d08521bSGarrett D'Amore {
2432d08521bSGarrett D'Amore 	return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_JP_wcrtomb));
2442d08521bSGarrett D'Amore }
2452d08521bSGarrett D'Amore 
2469d04e500SGarrett D'Amore /*
2479d04e500SGarrett D'Amore  * EUC-TW uses CS0, CS1, and CS2.
2489d04e500SGarrett D'Amore  */
2492d08521bSGarrett D'Amore void
_EUC_TW_init(struct lc_ctype * lct)2502d08521bSGarrett D'Amore _EUC_TW_init(struct lc_ctype *lct)
2519d04e500SGarrett D'Amore {
2522d08521bSGarrett D'Amore 	lct->lc_mbrtowc = _EUC_TW_mbrtowc;
2532d08521bSGarrett D'Amore 	lct->lc_wcrtomb = _EUC_TW_wcrtomb;
2542d08521bSGarrett D'Amore 	lct->lc_mbsnrtowcs = _EUC_TW_mbsnrtowcs;
2552d08521bSGarrett D'Amore 	lct->lc_wcsnrtombs = _EUC_TW_wcsnrtombs;
2562d08521bSGarrett D'Amore 	lct->lc_mbsinit = _EUC_mbsinit;
2579d04e500SGarrett D'Amore 
2582d08521bSGarrett D'Amore 	lct->lc_max_mblen = 4;
2592d08521bSGarrett D'Amore 	lct->lc_is_ascii = 0;
2609d04e500SGarrett D'Amore }
2619d04e500SGarrett D'Amore 
2629d04e500SGarrett D'Amore static size_t
_EUC_TW_mbrtowc(wchar_t * _RESTRICT_KYWD pwc,const char * _RESTRICT_KYWD s,size_t n,mbstate_t * _RESTRICT_KYWD ps,boolean_t zero)2639d04e500SGarrett D'Amore _EUC_TW_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
264*50370af8SRobert Mustacchi     size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero)
2659d04e500SGarrett D'Amore {
266*50370af8SRobert Mustacchi 	return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0, zero));
2679d04e500SGarrett D'Amore }
2689d04e500SGarrett D'Amore 
2699d04e500SGarrett D'Amore static size_t
_EUC_TW_mbsnrtowcs(wchar_t * _RESTRICT_KYWD dst,const char ** _RESTRICT_KYWD src,size_t nms,size_t len,mbstate_t * _RESTRICT_KYWD ps)2702d08521bSGarrett D'Amore _EUC_TW_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
2712d08521bSGarrett D'Amore     const char **_RESTRICT_KYWD src,
2722d08521bSGarrett D'Amore     size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
2732d08521bSGarrett D'Amore {
2742d08521bSGarrett D'Amore 	return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_TW_mbrtowc));
2752d08521bSGarrett D'Amore }
2762d08521bSGarrett D'Amore 
2772d08521bSGarrett D'Amore static size_t
_EUC_TW_wcrtomb(char * _RESTRICT_KYWD s,wchar_t wc,mbstate_t * _RESTRICT_KYWD ps)2789d04e500SGarrett D'Amore _EUC_TW_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
2799d04e500SGarrett D'Amore     mbstate_t *_RESTRICT_KYWD ps)
2809d04e500SGarrett D'Amore {
2819d04e500SGarrett D'Amore 	return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0));
2829d04e500SGarrett D'Amore }
2839d04e500SGarrett D'Amore 
2842d08521bSGarrett D'Amore static size_t
_EUC_TW_wcsnrtombs(char * _RESTRICT_KYWD dst,const wchar_t ** _RESTRICT_KYWD src,size_t nwc,size_t len,mbstate_t * _RESTRICT_KYWD ps)2852d08521bSGarrett D'Amore _EUC_TW_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
2862d08521bSGarrett D'Amore     size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
2872d08521bSGarrett D'Amore {
2882d08521bSGarrett D'Amore 	return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_TW_wcrtomb));
2892d08521bSGarrett D'Amore }
2902d08521bSGarrett D'Amore 
2919d04e500SGarrett D'Amore /*
2929d04e500SGarrett D'Amore  * Common EUC code.
2939d04e500SGarrett D'Amore  */
2949d04e500SGarrett D'Amore 
2959d04e500SGarrett D'Amore static size_t
_EUC_mbrtowc_impl(wchar_t * _RESTRICT_KYWD pwc,const char * _RESTRICT_KYWD s,size_t n,mbstate_t * _RESTRICT_KYWD ps,uint8_t cs2,uint8_t cs2width,uint8_t cs3,uint8_t cs3width,boolean_t zero)2969d04e500SGarrett D'Amore _EUC_mbrtowc_impl(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
2979d04e500SGarrett D'Amore     size_t n, mbstate_t *_RESTRICT_KYWD ps,
298*50370af8SRobert Mustacchi     uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width,
299*50370af8SRobert Mustacchi     boolean_t zero)
3009d04e500SGarrett D'Amore {
3014297a3b0SGarrett D'Amore 	_EucState *es;
3029d04e500SGarrett D'Amore 	int i, want;
3037c4f0c86SJohn Marino 	wchar_t wc = 0;
3047c4f0c86SJohn Marino 	unsigned char ch, chs;
3054297a3b0SGarrett D'Amore 
3064297a3b0SGarrett D'Amore 	es = (_EucState *)ps;
3074297a3b0SGarrett D'Amore 
3089d04e500SGarrett D'Amore 	if (es->want < 0 || es->want > MB_CUR_MAX) {
3094297a3b0SGarrett D'Amore 		errno = EINVAL;
3104297a3b0SGarrett D'Amore 		return ((size_t)-1);
3114297a3b0SGarrett D'Amore 	}
3124297a3b0SGarrett D'Amore 
3134297a3b0SGarrett D'Amore 	if (s == NULL) {
3144297a3b0SGarrett D'Amore 		s = "";
3154297a3b0SGarrett D'Amore 		n = 1;
3164297a3b0SGarrett D'Amore 		pwc = NULL;
3174297a3b0SGarrett D'Amore 	}
3184297a3b0SGarrett D'Amore 
3194297a3b0SGarrett D'Amore 	if (n == 0)
3204297a3b0SGarrett D'Amore 		/* Incomplete multibyte sequence */
3214297a3b0SGarrett D'Amore 		return ((size_t)-2);
3224297a3b0SGarrett D'Amore 
3234297a3b0SGarrett D'Amore 	if (es->want == 0) {
3249d04e500SGarrett D'Amore 		/* Fast path for plain ASCII (CS0) */
3259d04e500SGarrett D'Amore 		if (((ch = (unsigned char)*s) & 0x80) == 0) {
3269d04e500SGarrett D'Amore 			if (pwc != NULL)
3279d04e500SGarrett D'Amore 				*pwc = ch;
328*50370af8SRobert Mustacchi 			if (zero || ch != '\0') {
329*50370af8SRobert Mustacchi 				return (1);
330*50370af8SRobert Mustacchi 			} else {
331*50370af8SRobert Mustacchi 				return (0);
332*50370af8SRobert Mustacchi 			}
3334297a3b0SGarrett D'Amore 		}
3349d04e500SGarrett D'Amore 
3359d04e500SGarrett D'Amore 		if (ch >= 0xa1) {
3369d04e500SGarrett D'Amore 			/* CS1 */
3379d04e500SGarrett D'Amore 			want = 2;
3389d04e500SGarrett D'Amore 		} else if (ch == cs2) {
3399d04e500SGarrett D'Amore 			want = cs2width;
3409d04e500SGarrett D'Amore 		} else if (ch == cs3) {
3419d04e500SGarrett D'Amore 			want = cs3width;
3429d04e500SGarrett D'Amore 		} else {
3434297a3b0SGarrett D'Amore 			errno = EILSEQ;
3444297a3b0SGarrett D'Amore 			return ((size_t)-1);
3454297a3b0SGarrett D'Amore 		}
3469d04e500SGarrett D'Amore 
3479d04e500SGarrett D'Amore 
3489d04e500SGarrett D'Amore 		es->want = want;
3499d04e500SGarrett D'Amore 		es->ch = 0;
3504297a3b0SGarrett D'Amore 	} else {
3514297a3b0SGarrett D'Amore 		want = es->want;
3524297a3b0SGarrett D'Amore 		wc = es->ch;
3534297a3b0SGarrett D'Amore 	}
3549d04e500SGarrett D'Amore 
3559d04e500SGarrett D'Amore 	for (i = 0; i < MIN(want, n); i++) {
3569d04e500SGarrett D'Amore 		wc <<= 8;
3577c4f0c86SJohn Marino 		chs = *s;
3587c4f0c86SJohn Marino 		wc |= chs;
3599d04e500SGarrett D'Amore 		s++;
3604297a3b0SGarrett D'Amore 	}
3614297a3b0SGarrett D'Amore 	if (i < want) {
3624297a3b0SGarrett D'Amore 		/* Incomplete multibyte sequence */
3634297a3b0SGarrett D'Amore 		es->want = want - i;
3644297a3b0SGarrett D'Amore 		es->ch = wc;
3654297a3b0SGarrett D'Amore 		return ((size_t)-2);
3664297a3b0SGarrett D'Amore 	}
3674297a3b0SGarrett D'Amore 	if (pwc != NULL)
3684297a3b0SGarrett D'Amore 		*pwc = wc;
3694297a3b0SGarrett D'Amore 	es->want = 0;
370*50370af8SRobert Mustacchi 	if (zero || wc != L'\0') {
371*50370af8SRobert Mustacchi 		return (want);
372*50370af8SRobert Mustacchi 	} else {
373*50370af8SRobert Mustacchi 		return (0);
374*50370af8SRobert Mustacchi 	}
3754297a3b0SGarrett D'Amore }
3764297a3b0SGarrett D'Amore 
3774297a3b0SGarrett D'Amore static size_t
_EUC_wcrtomb_impl(char * _RESTRICT_KYWD s,wchar_t wc,mbstate_t * _RESTRICT_KYWD ps,uint8_t cs2,uint8_t cs2width,uint8_t cs3,uint8_t cs3width)3789d04e500SGarrett D'Amore _EUC_wcrtomb_impl(char *_RESTRICT_KYWD s, wchar_t wc,
3799d04e500SGarrett D'Amore     mbstate_t *_RESTRICT_KYWD ps,
3809d04e500SGarrett D'Amore     uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width)
3814297a3b0SGarrett D'Amore {
3824297a3b0SGarrett D'Amore 	_EucState *es;
3834297a3b0SGarrett D'Amore 	int i, len;
3849d04e500SGarrett D'Amore 	wchar_t nm;
3854297a3b0SGarrett D'Amore 
3864297a3b0SGarrett D'Amore 	es = (_EucState *)ps;
3874297a3b0SGarrett D'Amore 
3884297a3b0SGarrett D'Amore 	if (es->want != 0) {
3894297a3b0SGarrett D'Amore 		errno = EINVAL;
3904297a3b0SGarrett D'Amore 		return ((size_t)-1);
3914297a3b0SGarrett D'Amore 	}
3924297a3b0SGarrett D'Amore 
3934297a3b0SGarrett D'Amore 	if (s == NULL)
3944297a3b0SGarrett D'Amore 		/* Reset to initial shift state (no-op) */
3954297a3b0SGarrett D'Amore 		return (1);
3964297a3b0SGarrett D'Amore 
3979d04e500SGarrett D'Amore 	if ((wc & ~0x7f) == 0) {
3989d04e500SGarrett D'Amore 		/* Fast path for plain ASCII (CS0) */
3999d04e500SGarrett D'Amore 		*s = (char)wc;
4009d04e500SGarrett D'Amore 		return (1);
4019d04e500SGarrett D'Amore 	}
4024297a3b0SGarrett D'Amore 
4039d04e500SGarrett D'Amore 	/* Determine the "length" */
4049d04e500SGarrett D'Amore 	if ((unsigned)wc > 0xffffff) {
4059d04e500SGarrett D'Amore 		len = 4;
4069d04e500SGarrett D'Amore 	} else if ((unsigned)wc > 0xffff) {
4079d04e500SGarrett D'Amore 		len = 3;
4089d04e500SGarrett D'Amore 	} else if ((unsigned)wc > 0xff) {
4099d04e500SGarrett D'Amore 		len = 2;
4109d04e500SGarrett D'Amore 	} else {
4119d04e500SGarrett D'Amore 		len = 1;
4129d04e500SGarrett D'Amore 	}
4139d04e500SGarrett D'Amore 
4149d04e500SGarrett D'Amore 	if (len > MB_CUR_MAX) {
4159d04e500SGarrett D'Amore 		errno = EILSEQ;
4169d04e500SGarrett D'Amore 		return ((size_t)-1);
4179d04e500SGarrett D'Amore 	}
4189d04e500SGarrett D'Amore 
4199d04e500SGarrett D'Amore 	/* This first check excludes CS1, which is implicitly valid. */
4209d04e500SGarrett D'Amore 	if ((wc < 0xa100) || (wc > 0xffff)) {
4219d04e500SGarrett D'Amore 		/* Check for valid CS2 or CS3 */
4229d04e500SGarrett D'Amore 		nm = (wc >> ((len - 1) * 8));
4239d04e500SGarrett D'Amore 		if (nm == cs2) {
4249d04e500SGarrett D'Amore 			if (len != cs2width) {
4259d04e500SGarrett D'Amore 				errno = EILSEQ;
4269d04e500SGarrett D'Amore 				return ((size_t)-1);
4279d04e500SGarrett D'Amore 			}
4289d04e500SGarrett D'Amore 		} else if (nm == cs3) {
4299d04e500SGarrett D'Amore 			if (len != cs3width) {
4309d04e500SGarrett D'Amore 				errno = EILSEQ;
4319d04e500SGarrett D'Amore 				return ((size_t)-1);
4324297a3b0SGarrett D'Amore 			}
4334297a3b0SGarrett D'Amore 		} else {
4349d04e500SGarrett D'Amore 			errno = EILSEQ;
4359d04e500SGarrett D'Amore 			return ((size_t)-1);
4369d04e500SGarrett D'Amore 		}
4379d04e500SGarrett D'Amore 	}
4389d04e500SGarrett D'Amore 
4399d04e500SGarrett D'Amore 	/* Stash the bytes, least significant last */
4409d04e500SGarrett D'Amore 	for (i = len - 1; i >= 0; i--) {
4419d04e500SGarrett D'Amore 		s[i] = (wc & 0xff);
4429d04e500SGarrett D'Amore 		wc >>= 8;
4434297a3b0SGarrett D'Amore 	}
4444297a3b0SGarrett D'Amore 	return (len);
4454297a3b0SGarrett D'Amore }
446