149c44073SBaptiste Daroussin /*-
28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni *
422b87a35SBaptiste Daroussin * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
522b87a35SBaptiste Daroussin * Copyright (c) 1993
622b87a35SBaptiste Daroussin * The Regents of the University of California. All rights reserved.
722b87a35SBaptiste Daroussin *
822b87a35SBaptiste Daroussin * This code is derived from software contributed to Berkeley by
922b87a35SBaptiste Daroussin * Paul Borman at Krystal Technologies.
1022b87a35SBaptiste Daroussin *
1122b87a35SBaptiste Daroussin * Copyright (c) 2011 The FreeBSD Foundation
12*5b5fa75aSEd Maste *
1322b87a35SBaptiste Daroussin * Portions of this software were developed by David Chisnall
1422b87a35SBaptiste Daroussin * under sponsorship from the FreeBSD Foundation.
1522b87a35SBaptiste Daroussin *
1622b87a35SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without
1722b87a35SBaptiste Daroussin * modification, are permitted provided that the following conditions
1822b87a35SBaptiste Daroussin * are met:
1922b87a35SBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright
2022b87a35SBaptiste Daroussin * notice, this list of conditions and the following disclaimer.
2122b87a35SBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright
2222b87a35SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the
2322b87a35SBaptiste Daroussin * documentation and/or other materials provided with the distribution.
24fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors
2522b87a35SBaptiste Daroussin * may be used to endorse or promote products derived from this software
2622b87a35SBaptiste Daroussin * without specific prior written permission.
2722b87a35SBaptiste Daroussin *
2822b87a35SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2922b87a35SBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3022b87a35SBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3122b87a35SBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3222b87a35SBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3322b87a35SBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3422b87a35SBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3522b87a35SBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3622b87a35SBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3722b87a35SBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3822b87a35SBaptiste Daroussin * SUCH DAMAGE.
3922b87a35SBaptiste Daroussin */
4022b87a35SBaptiste Daroussin
4122b87a35SBaptiste Daroussin #include <errno.h>
4222b87a35SBaptiste Daroussin #include <limits.h>
4322b87a35SBaptiste Daroussin #include <runetype.h>
4422b87a35SBaptiste Daroussin #include <stddef.h>
4522b87a35SBaptiste Daroussin #include <stdio.h>
4622b87a35SBaptiste Daroussin #include <stdlib.h>
4722b87a35SBaptiste Daroussin #include <string.h>
4822b87a35SBaptiste Daroussin #include <wchar.h>
4922b87a35SBaptiste Daroussin #include "mblocal.h"
5022b87a35SBaptiste Daroussin
5122b87a35SBaptiste Daroussin static size_t _ascii_mbrtowc(wchar_t * __restrict, const char * __restrict,
5222b87a35SBaptiste Daroussin size_t, mbstate_t * __restrict);
5322b87a35SBaptiste Daroussin static int _ascii_mbsinit(const mbstate_t *);
5422b87a35SBaptiste Daroussin static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst,
5522b87a35SBaptiste Daroussin const char ** __restrict src, size_t nms, size_t len,
5622b87a35SBaptiste Daroussin mbstate_t * __restrict ps __unused);
5722b87a35SBaptiste Daroussin static size_t _ascii_wcrtomb(char * __restrict, wchar_t,
5822b87a35SBaptiste Daroussin mbstate_t * __restrict);
5922b87a35SBaptiste Daroussin static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict,
6022b87a35SBaptiste Daroussin size_t, size_t, mbstate_t * __restrict);
6122b87a35SBaptiste Daroussin
6222b87a35SBaptiste Daroussin int
_ascii_init(struct xlocale_ctype * l,_RuneLocale * rl)6322b87a35SBaptiste Daroussin _ascii_init(struct xlocale_ctype *l,_RuneLocale *rl)
6422b87a35SBaptiste Daroussin {
6522b87a35SBaptiste Daroussin
6622b87a35SBaptiste Daroussin l->__mbrtowc = _ascii_mbrtowc;
6722b87a35SBaptiste Daroussin l->__mbsinit = _ascii_mbsinit;
6822b87a35SBaptiste Daroussin l->__mbsnrtowcs = _ascii_mbsnrtowcs;
6922b87a35SBaptiste Daroussin l->__wcrtomb = _ascii_wcrtomb;
7022b87a35SBaptiste Daroussin l->__wcsnrtombs = _ascii_wcsnrtombs;
7122b87a35SBaptiste Daroussin l->runes = rl;
7222b87a35SBaptiste Daroussin l->__mb_cur_max = 1;
7322b87a35SBaptiste Daroussin l->__mb_sb_limit = 128;
7422b87a35SBaptiste Daroussin return(0);
7522b87a35SBaptiste Daroussin }
7622b87a35SBaptiste Daroussin
7722b87a35SBaptiste Daroussin static int
_ascii_mbsinit(const mbstate_t * ps __unused)7822b87a35SBaptiste Daroussin _ascii_mbsinit(const mbstate_t *ps __unused)
7922b87a35SBaptiste Daroussin {
8049c44073SBaptiste Daroussin
8122b87a35SBaptiste Daroussin /*
8222b87a35SBaptiste Daroussin * Encoding is not state dependent - we are always in the
8322b87a35SBaptiste Daroussin * initial state.
8422b87a35SBaptiste Daroussin */
8522b87a35SBaptiste Daroussin return (1);
8622b87a35SBaptiste Daroussin }
8722b87a35SBaptiste Daroussin
8822b87a35SBaptiste Daroussin static size_t
_ascii_mbrtowc(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps __unused)8922b87a35SBaptiste Daroussin _ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
9022b87a35SBaptiste Daroussin mbstate_t * __restrict ps __unused)
9122b87a35SBaptiste Daroussin {
9249c44073SBaptiste Daroussin
9322b87a35SBaptiste Daroussin if (s == NULL)
9422b87a35SBaptiste Daroussin /* Reset to initial shift state (no-op) */
9522b87a35SBaptiste Daroussin return (0);
9622b87a35SBaptiste Daroussin if (n == 0)
9722b87a35SBaptiste Daroussin /* Incomplete multibyte sequence */
9822b87a35SBaptiste Daroussin return ((size_t)-2);
9922b87a35SBaptiste Daroussin if (*s & 0x80) {
10022b87a35SBaptiste Daroussin errno = EILSEQ;
10122b87a35SBaptiste Daroussin return ((size_t)-1);
10222b87a35SBaptiste Daroussin }
10322b87a35SBaptiste Daroussin if (pwc != NULL)
10422b87a35SBaptiste Daroussin *pwc = (unsigned char)*s;
10522b87a35SBaptiste Daroussin return (*s == '\0' ? 0 : 1);
10622b87a35SBaptiste Daroussin }
10722b87a35SBaptiste Daroussin
10822b87a35SBaptiste Daroussin static size_t
_ascii_wcrtomb(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps __unused)10922b87a35SBaptiste Daroussin _ascii_wcrtomb(char * __restrict s, wchar_t wc,
11022b87a35SBaptiste Daroussin mbstate_t * __restrict ps __unused)
11122b87a35SBaptiste Daroussin {
11222b87a35SBaptiste Daroussin
11322b87a35SBaptiste Daroussin if (s == NULL)
11422b87a35SBaptiste Daroussin /* Reset to initial shift state (no-op) */
11522b87a35SBaptiste Daroussin return (1);
11622b87a35SBaptiste Daroussin if (wc < 0 || wc > 127) {
11722b87a35SBaptiste Daroussin errno = EILSEQ;
11822b87a35SBaptiste Daroussin return ((size_t)-1);
11922b87a35SBaptiste Daroussin }
12022b87a35SBaptiste Daroussin *s = (unsigned char)wc;
12122b87a35SBaptiste Daroussin return (1);
12222b87a35SBaptiste Daroussin }
12322b87a35SBaptiste Daroussin
12422b87a35SBaptiste Daroussin static size_t
_ascii_mbsnrtowcs(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps __unused)12522b87a35SBaptiste Daroussin _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src,
12622b87a35SBaptiste Daroussin size_t nms, size_t len, mbstate_t * __restrict ps __unused)
12722b87a35SBaptiste Daroussin {
12822b87a35SBaptiste Daroussin const char *s;
12922b87a35SBaptiste Daroussin size_t nchr;
13022b87a35SBaptiste Daroussin
13122b87a35SBaptiste Daroussin if (dst == NULL) {
13249c44073SBaptiste Daroussin for (s = *src; nms > 0 && *s != '\0'; s++, nms--) {
13322b87a35SBaptiste Daroussin if (*s & 0x80) {
13422b87a35SBaptiste Daroussin errno = EILSEQ;
13522b87a35SBaptiste Daroussin return ((size_t)-1);
13622b87a35SBaptiste Daroussin }
13749c44073SBaptiste Daroussin }
138d3591d68SBaptiste Daroussin return (s - *src);
13922b87a35SBaptiste Daroussin }
14022b87a35SBaptiste Daroussin
14122b87a35SBaptiste Daroussin s = *src;
14222b87a35SBaptiste Daroussin nchr = 0;
14322b87a35SBaptiste Daroussin while (len-- > 0 && nms-- > 0) {
14422b87a35SBaptiste Daroussin if (*s & 0x80) {
1452f423a26SAndrey A. Chernov *src = s;
14622b87a35SBaptiste Daroussin errno = EILSEQ;
14722b87a35SBaptiste Daroussin return ((size_t)-1);
14822b87a35SBaptiste Daroussin }
14922b87a35SBaptiste Daroussin if ((*dst++ = (unsigned char)*s++) == L'\0') {
15022b87a35SBaptiste Daroussin *src = NULL;
15122b87a35SBaptiste Daroussin return (nchr);
15222b87a35SBaptiste Daroussin }
15322b87a35SBaptiste Daroussin nchr++;
15422b87a35SBaptiste Daroussin }
15522b87a35SBaptiste Daroussin *src = s;
15622b87a35SBaptiste Daroussin return (nchr);
15722b87a35SBaptiste Daroussin }
15822b87a35SBaptiste Daroussin
15922b87a35SBaptiste Daroussin static size_t
_ascii_wcsnrtombs(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps __unused)16022b87a35SBaptiste Daroussin _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
16122b87a35SBaptiste Daroussin size_t nwc, size_t len, mbstate_t * __restrict ps __unused)
16222b87a35SBaptiste Daroussin {
16322b87a35SBaptiste Daroussin const wchar_t *s;
16422b87a35SBaptiste Daroussin size_t nchr;
16522b87a35SBaptiste Daroussin
16622b87a35SBaptiste Daroussin if (dst == NULL) {
16722b87a35SBaptiste Daroussin for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) {
16822b87a35SBaptiste Daroussin if (*s < 0 || *s > 127) {
16922b87a35SBaptiste Daroussin errno = EILSEQ;
17022b87a35SBaptiste Daroussin return ((size_t)-1);
17122b87a35SBaptiste Daroussin }
17222b87a35SBaptiste Daroussin }
17322b87a35SBaptiste Daroussin return (s - *src);
17422b87a35SBaptiste Daroussin }
17522b87a35SBaptiste Daroussin
17622b87a35SBaptiste Daroussin s = *src;
17722b87a35SBaptiste Daroussin nchr = 0;
17822b87a35SBaptiste Daroussin while (len-- > 0 && nwc-- > 0) {
17922b87a35SBaptiste Daroussin if (*s < 0 || *s > 127) {
1802f423a26SAndrey A. Chernov *src = s;
18122b87a35SBaptiste Daroussin errno = EILSEQ;
18222b87a35SBaptiste Daroussin return ((size_t)-1);
18322b87a35SBaptiste Daroussin }
18422b87a35SBaptiste Daroussin if ((*dst++ = *s++) == '\0') {
18522b87a35SBaptiste Daroussin *src = NULL;
18622b87a35SBaptiste Daroussin return (nchr);
18722b87a35SBaptiste Daroussin }
18822b87a35SBaptiste Daroussin nchr++;
18922b87a35SBaptiste Daroussin }
19022b87a35SBaptiste Daroussin *src = s;
19122b87a35SBaptiste Daroussin return (nchr);
19222b87a35SBaptiste Daroussin }
19349c44073SBaptiste Daroussin
194