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