1 /* $OpenBSD: citrus_none.c,v 1.5 2013/03/07 18:12:31 stsp 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/types.h> 31 32 #include <errno.h> 33 #include <limits.h> 34 #include <string.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <stddef.h> 38 #include <wchar.h> 39 40 #include "citrus_ctype.h" 41 #include "citrus_none.h" 42 43 _CITRUS_CTYPE_DEF_OPS(none); 44 45 /* 46 * Convert an unsigned char value into a char value without relying on 47 * signed overflow behavior. 48 */ 49 static inline char 50 wrapv(unsigned char ch) 51 { 52 if (ch >= 0x80) 53 return ((int)ch - 0x100); 54 else 55 return (ch); 56 } 57 58 size_t 59 /*ARGSUSED*/ 60 _citrus_none_ctype_mbrtowc(wchar_t * __restrict pwc, 61 const char * __restrict s, size_t n, 62 void * __restrict pspriv) 63 { 64 /* pwc may be NULL */ 65 /* s may be NULL */ 66 /* pspriv appears to be unused */ 67 68 if (s == NULL) 69 return 0; 70 if (n == 0) 71 return (size_t)-2; 72 if (pwc) 73 *pwc = (wchar_t)(unsigned char)*s; 74 return (*s != '\0'); 75 } 76 77 int 78 /*ARGSUSED*/ 79 _citrus_none_ctype_mbsinit(const void * __restrict pspriv) 80 { 81 return (1); /* always initial state */ 82 } 83 84 size_t 85 /*ARGSUSED*/ 86 _citrus_none_ctype_mbsnrtowcs(wchar_t * __restrict dst, 87 const char ** __restrict src, 88 size_t nmc, size_t len, 89 void * __restrict pspriv) 90 { 91 size_t i; 92 93 /* dst may be NULL */ 94 /* pspriv appears to be unused */ 95 96 if (dst == NULL) 97 return strnlen(*src, nmc); 98 99 for (i = 0; i < nmc && i < len; i++) 100 if ((dst[i] = (wchar_t)(unsigned char)(*src)[i]) == L'\0') { 101 *src = NULL; 102 return (i); 103 } 104 105 *src += i; 106 return (i); 107 } 108 109 size_t 110 /*ARGSUSED*/ 111 _citrus_none_ctype_wcrtomb(char * __restrict s, 112 wchar_t wc, void * __restrict pspriv) 113 { 114 /* s may be NULL */ 115 /* ps appears to be unused */ 116 117 if (s == NULL) 118 return (1); 119 120 if (wc < 0 || wc > 0xff) { 121 errno = EILSEQ; 122 return (-1); 123 } 124 125 *s = wrapv(wc); 126 return (1); 127 } 128 129 size_t 130 /*ARGSUSED*/ 131 _citrus_none_ctype_wcsnrtombs(char * __restrict dst, 132 const wchar_t ** __restrict src, 133 size_t nwc, size_t len, 134 void * __restrict pspriv) 135 { 136 size_t i; 137 138 /* dst may be NULL */ 139 /* pspriv appears to be unused */ 140 141 if (dst == NULL) { 142 for (i = 0; i < nwc; i++) { 143 wchar_t wc = (*src)[i]; 144 if (wc < 0 || wc > 0xff) { 145 errno = EILSEQ; 146 return (-1); 147 } 148 if (wc == L'\0') 149 return (i); 150 } 151 return (i); 152 } 153 154 for (i = 0; i < nwc && i < len; i++) { 155 wchar_t wc = (*src)[i]; 156 if (wc < 0 || wc > 0xff) { 157 *src += i; 158 errno = EILSEQ; 159 return (-1); 160 } 161 dst[i] = wrapv(wc); 162 if (wc == L'\0') { 163 *src = NULL; 164 return (i); 165 } 166 } 167 *src += i; 168 return (i); 169 } 170