xref: /freebsd/lib/libc/locale/ascii.c (revision d3591d68a9917dfa32a615322601734afb1ac3f7)
122b87a35SBaptiste Daroussin /*
222b87a35SBaptiste Daroussin  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
322b87a35SBaptiste Daroussin  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
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
1222b87a35SBaptiste Daroussin  * All rights reserved.
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.
2422b87a35SBaptiste Daroussin  * 4. 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  * @(#)none.c	8.1 (Berkeley) 6/4/93
4122b87a35SBaptiste Daroussin  */
4222b87a35SBaptiste Daroussin 
4322b87a35SBaptiste Daroussin #include <sys/cdefs.h>
4422b87a35SBaptiste Daroussin __FBSDID("$FreeBSD$");
4522b87a35SBaptiste Daroussin 
4622b87a35SBaptiste Daroussin #include <errno.h>
4722b87a35SBaptiste Daroussin #include <limits.h>
4822b87a35SBaptiste Daroussin #include <runetype.h>
4922b87a35SBaptiste Daroussin #include <stddef.h>
5022b87a35SBaptiste Daroussin #include <stdio.h>
5122b87a35SBaptiste Daroussin #include <stdlib.h>
5222b87a35SBaptiste Daroussin #include <string.h>
5322b87a35SBaptiste Daroussin #include <wchar.h>
5422b87a35SBaptiste Daroussin #include "mblocal.h"
5522b87a35SBaptiste Daroussin 
5622b87a35SBaptiste Daroussin static size_t	_ascii_mbrtowc(wchar_t * __restrict, const char * __restrict,
5722b87a35SBaptiste Daroussin 		    size_t, mbstate_t * __restrict);
5822b87a35SBaptiste Daroussin static int	_ascii_mbsinit(const mbstate_t *);
5922b87a35SBaptiste Daroussin static size_t	_ascii_mbsnrtowcs(wchar_t * __restrict dst,
6022b87a35SBaptiste Daroussin 		    const char ** __restrict src, size_t nms, size_t len,
6122b87a35SBaptiste Daroussin 		    mbstate_t * __restrict ps __unused);
6222b87a35SBaptiste Daroussin static size_t	_ascii_wcrtomb(char * __restrict, wchar_t,
6322b87a35SBaptiste Daroussin 		    mbstate_t * __restrict);
6422b87a35SBaptiste Daroussin static size_t	_ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict,
6522b87a35SBaptiste Daroussin 		    size_t, size_t, mbstate_t * __restrict);
6622b87a35SBaptiste Daroussin 
6722b87a35SBaptiste Daroussin int
6822b87a35SBaptiste Daroussin _ascii_init(struct xlocale_ctype *l, _RuneLocale *rl)
6922b87a35SBaptiste Daroussin {
7022b87a35SBaptiste Daroussin 
7122b87a35SBaptiste Daroussin 	l->__mbrtowc = _ascii_mbrtowc;
7222b87a35SBaptiste Daroussin 	l->__mbsinit = _ascii_mbsinit;
7322b87a35SBaptiste Daroussin 	l->__mbsnrtowcs = _ascii_mbsnrtowcs;
7422b87a35SBaptiste Daroussin 	l->__wcrtomb = _ascii_wcrtomb;
7522b87a35SBaptiste Daroussin 	l->__wcsnrtombs = _ascii_wcsnrtombs;
7622b87a35SBaptiste Daroussin 	l->runes = rl;
7722b87a35SBaptiste Daroussin 	l->__mb_cur_max = 1;
7822b87a35SBaptiste Daroussin 	l->__mb_sb_limit = 128;
7922b87a35SBaptiste Daroussin 	return(0);
8022b87a35SBaptiste Daroussin }
8122b87a35SBaptiste Daroussin 
8222b87a35SBaptiste Daroussin static int
8322b87a35SBaptiste Daroussin _ascii_mbsinit(const mbstate_t *ps __unused)
8422b87a35SBaptiste Daroussin {
8522b87a35SBaptiste Daroussin 	/*
8622b87a35SBaptiste Daroussin 	 * Encoding is not state dependent - we are always in the
8722b87a35SBaptiste Daroussin 	 * initial state.
8822b87a35SBaptiste Daroussin 	 */
8922b87a35SBaptiste Daroussin 	return (1);
9022b87a35SBaptiste Daroussin }
9122b87a35SBaptiste Daroussin 
9222b87a35SBaptiste Daroussin static size_t
9322b87a35SBaptiste Daroussin _ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
9422b87a35SBaptiste Daroussin     mbstate_t * __restrict ps __unused)
9522b87a35SBaptiste Daroussin {
9622b87a35SBaptiste Daroussin 	if (s == NULL)
9722b87a35SBaptiste Daroussin 		/* Reset to initial shift state (no-op) */
9822b87a35SBaptiste Daroussin 		return (0);
9922b87a35SBaptiste Daroussin 	if (n == 0)
10022b87a35SBaptiste Daroussin 		/* Incomplete multibyte sequence */
10122b87a35SBaptiste Daroussin 		return ((size_t)-2);
10222b87a35SBaptiste Daroussin 	if (*s & 0x80) {
10322b87a35SBaptiste Daroussin 		errno = EILSEQ;
10422b87a35SBaptiste Daroussin 		return ((size_t)-1);
10522b87a35SBaptiste Daroussin 	}
10622b87a35SBaptiste Daroussin 	if (pwc != NULL)
10722b87a35SBaptiste Daroussin 		*pwc = (unsigned char)*s;
10822b87a35SBaptiste Daroussin 	return (*s == '\0' ? 0 : 1);
10922b87a35SBaptiste Daroussin }
11022b87a35SBaptiste Daroussin 
11122b87a35SBaptiste Daroussin static size_t
11222b87a35SBaptiste Daroussin _ascii_wcrtomb(char * __restrict s, wchar_t wc,
11322b87a35SBaptiste Daroussin     mbstate_t * __restrict ps __unused)
11422b87a35SBaptiste Daroussin {
11522b87a35SBaptiste Daroussin 
11622b87a35SBaptiste Daroussin 	if (s == NULL)
11722b87a35SBaptiste Daroussin 		/* Reset to initial shift state (no-op) */
11822b87a35SBaptiste Daroussin 		return (1);
11922b87a35SBaptiste Daroussin 	if (wc < 0 || wc > 127) {
12022b87a35SBaptiste Daroussin 		errno = EILSEQ;
12122b87a35SBaptiste Daroussin 		return ((size_t)-1);
12222b87a35SBaptiste Daroussin 	}
12322b87a35SBaptiste Daroussin 	*s = (unsigned char)wc;
12422b87a35SBaptiste Daroussin 	return (1);
12522b87a35SBaptiste Daroussin }
12622b87a35SBaptiste Daroussin 
12722b87a35SBaptiste Daroussin static size_t
12822b87a35SBaptiste Daroussin _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src,
12922b87a35SBaptiste Daroussin     size_t nms, size_t len, mbstate_t * __restrict ps __unused)
13022b87a35SBaptiste Daroussin {
13122b87a35SBaptiste Daroussin 	const char *s;
13222b87a35SBaptiste Daroussin 	size_t nchr;
13322b87a35SBaptiste Daroussin 
13422b87a35SBaptiste Daroussin 	if (dst == NULL) {
13522b87a35SBaptiste Daroussin 		s = memchr(*src, '\0', nms);
136*d3591d68SBaptiste Daroussin 		if (s == NULL)
137*d3591d68SBaptiste Daroussin 			return (nms);
138*d3591d68SBaptiste Daroussin 
13922b87a35SBaptiste Daroussin 		if (*s & 0x80) {
14022b87a35SBaptiste Daroussin 			errno = EILSEQ;
14122b87a35SBaptiste Daroussin 			return ((size_t)-1);
14222b87a35SBaptiste Daroussin 		}
143*d3591d68SBaptiste Daroussin 		return (s - *src);
14422b87a35SBaptiste Daroussin 	}
14522b87a35SBaptiste Daroussin 
14622b87a35SBaptiste Daroussin 	s = *src;
14722b87a35SBaptiste Daroussin 	nchr = 0;
14822b87a35SBaptiste Daroussin 	while (len-- > 0 && nms-- > 0) {
14922b87a35SBaptiste Daroussin 		if (*s & 0x80) {
15022b87a35SBaptiste Daroussin 			errno = EILSEQ;
15122b87a35SBaptiste Daroussin 			return ((size_t)-1);
15222b87a35SBaptiste Daroussin 		}
15322b87a35SBaptiste Daroussin 		if ((*dst++ = (unsigned char)*s++) == L'\0') {
15422b87a35SBaptiste Daroussin 			*src = NULL;
15522b87a35SBaptiste Daroussin 			return (nchr);
15622b87a35SBaptiste Daroussin 		}
15722b87a35SBaptiste Daroussin 		nchr++;
15822b87a35SBaptiste Daroussin 	}
15922b87a35SBaptiste Daroussin 	*src = s;
16022b87a35SBaptiste Daroussin 	return (nchr);
16122b87a35SBaptiste Daroussin }
16222b87a35SBaptiste Daroussin 
16322b87a35SBaptiste Daroussin static size_t
16422b87a35SBaptiste Daroussin _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
16522b87a35SBaptiste Daroussin     size_t nwc, size_t len, mbstate_t * __restrict ps __unused)
16622b87a35SBaptiste Daroussin {
16722b87a35SBaptiste Daroussin 	const wchar_t *s;
16822b87a35SBaptiste Daroussin 	size_t nchr;
16922b87a35SBaptiste Daroussin 
17022b87a35SBaptiste Daroussin 	if (dst == NULL) {
17122b87a35SBaptiste Daroussin 		for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) {
17222b87a35SBaptiste Daroussin 			if (*s < 0 || *s > 127) {
17322b87a35SBaptiste Daroussin 				errno = EILSEQ;
17422b87a35SBaptiste Daroussin 				return ((size_t)-1);
17522b87a35SBaptiste Daroussin 			}
17622b87a35SBaptiste Daroussin 		}
17722b87a35SBaptiste Daroussin 		return (s - *src);
17822b87a35SBaptiste Daroussin 	}
17922b87a35SBaptiste Daroussin 
18022b87a35SBaptiste Daroussin 	s = *src;
18122b87a35SBaptiste Daroussin 	nchr = 0;
18222b87a35SBaptiste Daroussin 	while (len-- > 0 && nwc-- > 0) {
18322b87a35SBaptiste Daroussin 		if (*s < 0 || *s > 127) {
18422b87a35SBaptiste Daroussin 			errno = EILSEQ;
18522b87a35SBaptiste Daroussin 			return ((size_t)-1);
18622b87a35SBaptiste Daroussin 		}
18722b87a35SBaptiste Daroussin 		if ((*dst++ = *s++) == '\0') {
18822b87a35SBaptiste Daroussin 			*src = NULL;
18922b87a35SBaptiste Daroussin 			return (nchr);
19022b87a35SBaptiste Daroussin 		}
19122b87a35SBaptiste Daroussin 		nchr++;
19222b87a35SBaptiste Daroussin 	}
19322b87a35SBaptiste Daroussin 	*src = s;
19422b87a35SBaptiste Daroussin 	return (nchr);
19522b87a35SBaptiste Daroussin }
196