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*d8e0a9a1SRobert Mustacchi size_t, mbstate_t *_RESTRICT_KYWD, uint8_t, uint8_t, uint8_t, uint8_t, 50*d8e0a9a1SRobert 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*d8e0a9a1SRobert 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*d8e0a9a1SRobert 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*d8e0a9a1SRobert 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*d8e0a9a1SRobert 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 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 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 1289d04e500SGarrett D'Amore _EUC_CN_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, 129*d8e0a9a1SRobert Mustacchi size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero) 1304297a3b0SGarrett D'Amore { 131*d8e0a9a1SRobert 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 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 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 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 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 1739d04e500SGarrett D'Amore _EUC_KR_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, 174*d8e0a9a1SRobert Mustacchi size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero) 1759d04e500SGarrett D'Amore { 176*d8e0a9a1SRobert 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 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 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 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 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 2189d04e500SGarrett D'Amore _EUC_JP_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, 219*d8e0a9a1SRobert Mustacchi size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero) 2209d04e500SGarrett D'Amore { 221*d8e0a9a1SRobert 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 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 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 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 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 2639d04e500SGarrett D'Amore _EUC_TW_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, 264*d8e0a9a1SRobert Mustacchi size_t n, mbstate_t *_RESTRICT_KYWD ps, boolean_t zero) 2659d04e500SGarrett D'Amore { 266*d8e0a9a1SRobert 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 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 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 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 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*d8e0a9a1SRobert Mustacchi uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width, 299*d8e0a9a1SRobert Mustacchi boolean_t zero) 3009d04e500SGarrett D'Amore { 3014297a3b0SGarrett D'Amore _EucState *es; 3029d04e500SGarrett D'Amore int i, want; 3037e36ededSJohn Marino wchar_t wc = 0; 3047e36ededSJohn 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*d8e0a9a1SRobert Mustacchi if (zero || ch != '\0') { 329*d8e0a9a1SRobert Mustacchi return (1); 330*d8e0a9a1SRobert Mustacchi } else { 331*d8e0a9a1SRobert Mustacchi return (0); 332*d8e0a9a1SRobert 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; 3577e36ededSJohn Marino chs = *s; 3587e36ededSJohn 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*d8e0a9a1SRobert Mustacchi if (zero || wc != L'\0') { 371*d8e0a9a1SRobert Mustacchi return (want); 372*d8e0a9a1SRobert Mustacchi } else { 373*d8e0a9a1SRobert Mustacchi return (0); 374*d8e0a9a1SRobert Mustacchi } 3754297a3b0SGarrett D'Amore } 3764297a3b0SGarrett D'Amore 3774297a3b0SGarrett D'Amore static size_t 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