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