xref: /dflybsd-src/lib/libc/locale/ascii.c (revision 9915e371b196ef063ed0bfddd33e797cd03c61ea)
1efb570f9SJohn Marino /*
2efb570f9SJohn Marino  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
3efb570f9SJohn Marino  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
4efb570f9SJohn Marino  * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
5efb570f9SJohn Marino  * Copyright (c) 1993
6efb570f9SJohn Marino  *	The Regents of the University of California.  All rights reserved.
7efb570f9SJohn Marino  *
8efb570f9SJohn Marino  * This code is derived from software contributed to Berkeley by
9efb570f9SJohn Marino  * Paul Borman at Krystal Technologies.
10efb570f9SJohn Marino  *
11efb570f9SJohn Marino  * Copyright (c) 2011 The FreeBSD Foundation
12efb570f9SJohn Marino  * All rights reserved.
13efb570f9SJohn Marino  * Portions of this software were developed by David Chisnall
14efb570f9SJohn Marino  * under sponsorship from the FreeBSD Foundation.
15efb570f9SJohn Marino  *
16efb570f9SJohn Marino  * Redistribution and use in source and binary forms, with or without
17efb570f9SJohn Marino  * modification, are permitted provided that the following conditions
18efb570f9SJohn Marino  * are met:
19efb570f9SJohn Marino  * 1. Redistributions of source code must retain the above copyright
20efb570f9SJohn Marino  *    notice, this list of conditions and the following disclaimer.
21efb570f9SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
22efb570f9SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
23efb570f9SJohn Marino  *    documentation and/or other materials provided with the distribution.
24c66c7e2fSzrj  * 3. Neither the name of the University nor the names of its contributors
25efb570f9SJohn Marino  *    may be used to endorse or promote products derived from this software
26efb570f9SJohn Marino  *    without specific prior written permission.
27efb570f9SJohn Marino  *
28efb570f9SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29efb570f9SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30efb570f9SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31efb570f9SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32efb570f9SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33efb570f9SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34efb570f9SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35efb570f9SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36efb570f9SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37efb570f9SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38efb570f9SJohn Marino  * SUCH DAMAGE.
39efb570f9SJohn Marino  *
40efb570f9SJohn Marino  * @(#)none.c	8.1 (Berkeley) 6/4/93
41efb570f9SJohn Marino  */
42efb570f9SJohn Marino 
43efb570f9SJohn Marino #include <errno.h>
44efb570f9SJohn Marino #include <limits.h>
45efb570f9SJohn Marino #include <runetype.h>
46efb570f9SJohn Marino #include <stddef.h>
47efb570f9SJohn Marino #include <stdio.h>
48efb570f9SJohn Marino #include <stdlib.h>
49efb570f9SJohn Marino #include <string.h>
50efb570f9SJohn Marino #include <wchar.h>
51efb570f9SJohn Marino #include "mblocal.h"
52efb570f9SJohn Marino 
53efb570f9SJohn Marino static size_t	_ascii_mbrtowc(wchar_t * __restrict, const char * __restrict,
54efb570f9SJohn Marino 		    size_t, mbstate_t * __restrict);
55efb570f9SJohn Marino static int	_ascii_mbsinit(const mbstate_t *);
56efb570f9SJohn Marino static size_t	_ascii_mbsnrtowcs(wchar_t * __restrict dst,
57efb570f9SJohn Marino 		    const char ** __restrict src, size_t nms, size_t len,
58efb570f9SJohn Marino 		    mbstate_t * __restrict ps __unused);
59efb570f9SJohn Marino static size_t	_ascii_wcrtomb(char * __restrict, wchar_t,
60efb570f9SJohn Marino 		    mbstate_t * __restrict);
61efb570f9SJohn Marino static size_t	_ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict,
62efb570f9SJohn Marino 		    size_t, size_t, mbstate_t * __restrict);
63efb570f9SJohn Marino 
64efb570f9SJohn Marino int
_ascii_init(struct xlocale_ctype * l,_RuneLocale * rl)65efb570f9SJohn Marino _ascii_init(struct xlocale_ctype *l, _RuneLocale *rl)
66efb570f9SJohn Marino {
67efb570f9SJohn Marino 
68efb570f9SJohn Marino 	l->__mbrtowc = _ascii_mbrtowc;
69efb570f9SJohn Marino 	l->__mbsinit = _ascii_mbsinit;
70efb570f9SJohn Marino 	l->__mbsnrtowcs = _ascii_mbsnrtowcs;
71efb570f9SJohn Marino 	l->__wcrtomb = _ascii_wcrtomb;
72efb570f9SJohn Marino 	l->__wcsnrtombs = _ascii_wcsnrtombs;
73efb570f9SJohn Marino 	l->runes = rl;
74efb570f9SJohn Marino 	l->__mb_cur_max = 1;
75efb570f9SJohn Marino 	l->__mb_sb_limit = 128;
76efb570f9SJohn Marino 	return(0);
77efb570f9SJohn Marino }
78efb570f9SJohn Marino 
79efb570f9SJohn Marino static int
_ascii_mbsinit(const mbstate_t * ps __unused)80efb570f9SJohn Marino _ascii_mbsinit(const mbstate_t *ps __unused)
81efb570f9SJohn Marino {
82efb570f9SJohn Marino 	/*
83efb570f9SJohn Marino 	 * Encoding is not state dependent - we are always in the
84efb570f9SJohn Marino 	 * initial state.
85efb570f9SJohn Marino 	 */
86efb570f9SJohn Marino 	return (1);
87efb570f9SJohn Marino }
88efb570f9SJohn Marino 
89efb570f9SJohn Marino static size_t
_ascii_mbrtowc(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps __unused)90efb570f9SJohn Marino _ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
91efb570f9SJohn Marino     mbstate_t * __restrict ps __unused)
92efb570f9SJohn Marino {
93efb570f9SJohn Marino 	if (s == NULL)
94efb570f9SJohn Marino 		/* Reset to initial shift state (no-op) */
95efb570f9SJohn Marino 		return (0);
96efb570f9SJohn Marino 	if (n == 0)
97efb570f9SJohn Marino 		/* Incomplete multibyte sequence */
98efb570f9SJohn Marino 		return ((size_t)-2);
99efb570f9SJohn Marino 	if (*s & 0x80) {
100efb570f9SJohn Marino 		errno = EILSEQ;
101efb570f9SJohn Marino 		return ((size_t)-1);
102efb570f9SJohn Marino 	}
103efb570f9SJohn Marino 	if (pwc != NULL)
104efb570f9SJohn Marino 		*pwc = (unsigned char)*s;
105efb570f9SJohn Marino 	return (*s == '\0' ? 0 : 1);
106efb570f9SJohn Marino }
107efb570f9SJohn Marino 
108efb570f9SJohn Marino static size_t
_ascii_wcrtomb(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps __unused)109efb570f9SJohn Marino _ascii_wcrtomb(char * __restrict s, wchar_t wc,
110efb570f9SJohn Marino     mbstate_t * __restrict ps __unused)
111efb570f9SJohn Marino {
112efb570f9SJohn Marino 
113efb570f9SJohn Marino 	if (s == NULL)
114efb570f9SJohn Marino 		/* Reset to initial shift state (no-op) */
115efb570f9SJohn Marino 		return (1);
116efb570f9SJohn Marino 	if (wc < 0 || wc > 127) {
117efb570f9SJohn Marino 		errno = EILSEQ;
118efb570f9SJohn Marino 		return ((size_t)-1);
119efb570f9SJohn Marino 	}
120efb570f9SJohn Marino 	*s = (unsigned char)wc;
121efb570f9SJohn Marino 	return (1);
122efb570f9SJohn Marino }
123efb570f9SJohn Marino 
124efb570f9SJohn Marino static size_t
_ascii_mbsnrtowcs(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps __unused)125efb570f9SJohn Marino _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src,
126efb570f9SJohn Marino     size_t nms, size_t len, mbstate_t * __restrict ps __unused)
127efb570f9SJohn Marino {
128efb570f9SJohn Marino 	const char *s;
129efb570f9SJohn Marino 	size_t nchr;
130efb570f9SJohn Marino 
131efb570f9SJohn Marino 	if (dst == NULL) {
132*9915e371SJohn Marino 		s = *src;
133*9915e371SJohn Marino 		while (*s != '\0' && nms-- > 0) {
134efb570f9SJohn Marino 			if (*s & 0x80) {
135efb570f9SJohn Marino 				errno = EILSEQ;
136efb570f9SJohn Marino 				return ((size_t)-1);
137efb570f9SJohn Marino 			}
138*9915e371SJohn Marino 			++s;
139*9915e371SJohn Marino 		}
140*9915e371SJohn Marino 		return (s - *src);
141efb570f9SJohn Marino 	}
142efb570f9SJohn Marino 
143efb570f9SJohn Marino 	s = *src;
144efb570f9SJohn Marino 	nchr = 0;
145efb570f9SJohn Marino 	while (len-- > 0 && nms-- > 0) {
146efb570f9SJohn Marino 		if (*s & 0x80) {
147*9915e371SJohn Marino 			*src = s;
148efb570f9SJohn Marino 			errno = EILSEQ;
149efb570f9SJohn Marino 			return ((size_t)-1);
150efb570f9SJohn Marino 		}
151efb570f9SJohn Marino 		if ((*dst++ = (unsigned char)*s++) == L'\0') {
152efb570f9SJohn Marino 			*src = NULL;
153efb570f9SJohn Marino 			return (nchr);
154efb570f9SJohn Marino 		}
155efb570f9SJohn Marino 		nchr++;
156efb570f9SJohn Marino 	}
157efb570f9SJohn Marino 	*src = s;
158efb570f9SJohn Marino 	return (nchr);
159efb570f9SJohn Marino }
160efb570f9SJohn Marino 
161efb570f9SJohn Marino static size_t
_ascii_wcsnrtombs(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps __unused)162efb570f9SJohn Marino _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src,
163efb570f9SJohn Marino     size_t nwc, size_t len, mbstate_t * __restrict ps __unused)
164efb570f9SJohn Marino {
165efb570f9SJohn Marino 	const wchar_t *s;
166efb570f9SJohn Marino 	size_t nchr;
167efb570f9SJohn Marino 
168efb570f9SJohn Marino 	if (dst == NULL) {
169efb570f9SJohn Marino 		for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) {
170efb570f9SJohn Marino 			if (*s < 0 || *s > 127) {
171efb570f9SJohn Marino 				errno = EILSEQ;
172efb570f9SJohn Marino 				return ((size_t)-1);
173efb570f9SJohn Marino 			}
174efb570f9SJohn Marino 		}
175efb570f9SJohn Marino 		return (s - *src);
176efb570f9SJohn Marino 	}
177efb570f9SJohn Marino 
178efb570f9SJohn Marino 	s = *src;
179efb570f9SJohn Marino 	nchr = 0;
180efb570f9SJohn Marino 	while (len-- > 0 && nwc-- > 0) {
181efb570f9SJohn Marino 		if (*s < 0 || *s > 127) {
182*9915e371SJohn Marino 			*src = s;
183efb570f9SJohn Marino 			errno = EILSEQ;
184efb570f9SJohn Marino 			return ((size_t)-1);
185efb570f9SJohn Marino 		}
186efb570f9SJohn Marino 		if ((*dst++ = *s++) == '\0') {
187efb570f9SJohn Marino 			*src = NULL;
188efb570f9SJohn Marino 			return (nchr);
189efb570f9SJohn Marino 		}
190efb570f9SJohn Marino 		nchr++;
191efb570f9SJohn Marino 	}
192efb570f9SJohn Marino 	*src = s;
193efb570f9SJohn Marino 	return (nchr);
194efb570f9SJohn Marino }
195