1 /* $OpenBSD: citrus_none.c,v 1.3 2012/06/06 16:58:02 matthew Exp $ */ 2 /* $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */ 3 4 /*- 5 * Copyright (c)2002 Citrus Project, 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 #include <sys/types.h> 32 33 #include <errno.h> 34 #include <limits.h> 35 #include <string.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <stddef.h> 39 #include <wchar.h> 40 41 #include "citrus_ctype.h" 42 #include "citrus_none.h" 43 44 _CITRUS_CTYPE_DEF_OPS(none); 45 46 /* 47 * Convert an unsigned char value into a char value without relying on 48 * signed overflow behavior. 49 */ 50 static inline char 51 wrapv(unsigned char ch) 52 { 53 if (ch >= 0x80) 54 return ((int)ch - 0x100); 55 else 56 return (ch); 57 } 58 59 size_t 60 /*ARGSUSED*/ 61 _citrus_none_ctype_mbrtowc(wchar_t * __restrict pwc, 62 const char * __restrict s, size_t n, 63 void * __restrict pspriv) 64 { 65 /* pwc may be NULL */ 66 /* s may be NULL */ 67 /* pspriv appears to be unused */ 68 69 if (s == NULL) 70 return 0; 71 if (n == 0) 72 return (size_t)-2; 73 if (pwc) 74 *pwc = (wchar_t)(unsigned char)*s; 75 return (*s != '\0'); 76 } 77 78 int 79 /*ARGSUSED*/ 80 _citrus_none_ctype_mbsinit(const void * __restrict pspriv) 81 { 82 return (1); /* always initial state */ 83 } 84 85 size_t 86 /*ARGSUSED*/ 87 _citrus_none_ctype_mbsnrtowcs(wchar_t * __restrict dst, 88 const char ** __restrict src, 89 size_t nmc, size_t len, 90 void * __restrict pspriv) 91 { 92 size_t i; 93 94 /* dst may be NULL */ 95 /* pspriv appears to be unused */ 96 97 if (dst == NULL) 98 return strnlen(*src, nmc); 99 100 for (i = 0; i < nmc && i < len; i++) 101 if ((dst[i] = (wchar_t)(unsigned char)(*src)[i]) == L'\0') { 102 *src = NULL; 103 return (i); 104 } 105 106 *src += i; 107 return (i); 108 } 109 110 size_t 111 /*ARGSUSED*/ 112 _citrus_none_ctype_wcrtomb(char * __restrict s, 113 wchar_t wc, void * __restrict pspriv) 114 { 115 /* s may be NULL */ 116 /* ps appears to be unused */ 117 118 if (s == NULL) 119 return (0); 120 121 if (wc < 0 || wc > 0xff) { 122 errno = EILSEQ; 123 return (-1); 124 } 125 126 *s = wrapv(wc); 127 return (1); 128 } 129 130 size_t 131 /*ARGSUSED*/ 132 _citrus_none_ctype_wcsnrtombs(char * __restrict dst, 133 const wchar_t ** __restrict src, 134 size_t nwc, size_t len, 135 void * __restrict pspriv) 136 { 137 size_t i; 138 139 /* dst may be NULL */ 140 /* pspriv appears to be unused */ 141 142 if (dst == NULL) { 143 for (i = 0; i < nwc; i++) { 144 wchar_t wc = (*src)[i]; 145 if (wc < 0 || wc > 0xff) { 146 errno = EILSEQ; 147 return (-1); 148 } 149 if (wc == L'\0') 150 return (i); 151 } 152 return (i); 153 } 154 155 for (i = 0; i < nwc && i < len; i++) { 156 wchar_t wc = (*src)[i]; 157 if (wc < 0 || wc > 0xff) { 158 *src += i; 159 errno = EILSEQ; 160 return (-1); 161 } 162 dst[i] = wrapv(wc); 163 if (wc == L'\0') { 164 *src = NULL; 165 return (i); 166 } 167 } 168 *src += i; 169 return (i); 170 } 171