xref: /openbsd-src/lib/libc/citrus/citrus_none.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
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