1 /* $MirOS: src/include/wchar.h,v 1.37 2014/03/26 00:13:09 tg Exp $ */
2 
3 /*-
4  * Copyright (c) 2007, 2008, 2013, 2014
5  *	Thorsten Glaser <tg@mirbsd.de>
6  *
7  * Provided that these terms and disclaimer and all copyright notices
8  * are retained or reproduced in an accompanying document, permission
9  * is granted to deal in this work without restriction, including un-
10  * limited rights to use, publicly perform, distribute, sell, modify,
11  * merge, give away, or sublicence.
12  *
13  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
14  * the utmost extent permitted by applicable law, neither express nor
15  * implied; without malicious intent or gross negligence. In no event
16  * may a licensor, author or contributor be held liable for indirect,
17  * direct, other damage, loss, or other issues arising in any way out
18  * of dealing in the work, even if advised of the possibility of such
19  * damage or existence of a defect, except proven that it results out
20  * of said person's immediate fault when using the work as intended.
21  *
22  * The author reserves the right to steward the OPTU encoding forms.
23  */
24 
25 #ifndef	_WCHAR_H_
26 #define	_WCHAR_H_
27 
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <time.h>
35 
36 /* ISO/IEC 9899:1999/Cor.3:2007(E) */
37 #ifdef __STDC_MB_MIGHT_NEQ_WC__
38 /* we really need wchar_t values to be proper Unicode */
39 #error You are crazy. Go away.
40 #endif
41 
42 #ifndef __IN_MKDEP
43 /* makedepend may not define the constants we are checking for */
44 #if __WCHAR_MAX__ != 65535U
45 #error GCC __WCHAR_MAX__ does not indicate UCS-2
46 #endif
47 #ifndef __STDC_ISO_10646__
48 #error This code assumes that wchar_t is UCS-2HE
49 #endif
50 #endif /* !__IN_MKDEP */
51 
52 #if !defined(_GCC_WCHAR_T) && !defined(__cplusplus)
53 #define	_GCC_WCHAR_T
54 typedef	__WCHAR_TYPE__	wchar_t;
55 #endif
56 
57 #if !defined(_GCC_WINT_T)
58 #define	_GCC_WINT_T
59 typedef	__WINT_TYPE__	wint_t;
60 #endif
61 
62 #if !defined(_GCC_MBSTATE_T)
63 #define	_GCC_MBSTATE_T
64 typedef struct {
65 	/*-
66 	 * 0: initial state
67 	 * 1: "value" contains one more octet worth of information
68 	 * 2: "value" contains two more octets worth of information
69 	 * 3: "value" contains the lower 6 bit of a rejected hibit-7 octet
70 	 *    (possible future extension to two rejected octets)
71 	 */
72 	unsigned int count:2;
73 	/*-
74 	 * 10 bits for mbstowcs(3) and optu8to16(3)
75 	 * 12 bits for wcstombs(3) and optu16to8(3)
76 	 * 14 bits available in total
77 	 */
78 	unsigned int value:12;
79 } __attribute__((__packed__)) mbstate_t;
80 #endif
81 
82 #undef WCHAR_MIN
83 #define WCHAR_MIN	0
84 #undef WCHAR_MAX
85 #define WCHAR_MAX	0xFFFDU
86 #undef WEOF
87 #define WEOF		0xFFFFU
88 
89 typedef unsigned int wctype_t;
90 
91 __BEGIN_DECLS
92 wint_t	btowc(int);
93 wint_t	fgetwc(FILE *);
94 wchar_t	*fgetws(wchar_t *, int, FILE *);
95 wint_t	fputwc(wchar_t, FILE *);
96 int	fputws(const wchar_t *, FILE *);
97 int	fwide(FILE *, int);
98 wint_t	getwc(FILE *);
99 wint_t	getwchar(void);
100 size_t	mbrlen(const char *, size_t, mbstate_t *);
101 size_t	mbrtowc(wchar_t *, const char *, size_t, mbstate_t *)
102     __attribute__((__bounded__(__string__, 2, 3)));
103 int	mbsinit(const mbstate_t *);
104 size_t	mbslen(const char *);
105 #if __OPENBSD_VISIBLE
106 size_t	mbsnrtowcs(wchar_t *, const char **, size_t, size_t, mbstate_t *);
107 #endif
108 size_t	mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *);
109 #if __OPENBSD_VISIBLE
110 #undef optu16to8
111 #define optu16to8 optu16to8
112 size_t	optu16to8(char *, wchar_t, mbstate_t *)
113     __attribute__((__bounded__(__minbytes__, 1, MB_CUR_MAX)));
114 #undef optu8to16
115 #define optu8to16 optu8to16
116 size_t	optu8to16(wchar_t *, const char *, size_t, mbstate_t *)
117     __attribute__((__bounded__(__string__, 2, 3)));
118 #endif
119 wint_t	putwc(wchar_t, FILE *);
120 wint_t	putwchar(wchar_t);
121 wint_t	ungetwc(wint_t, FILE *);
122 size_t	wcrtomb(char *, wchar_t, mbstate_t *)
123     __attribute__((__bounded__(__minbytes__, 1, MB_CUR_MAX)));
124 int	wcscasecmp(const wchar_t *, const wchar_t *);
125 wchar_t	*wcscat(wchar_t *, const wchar_t *);
126 wchar_t	*wcschr(const wchar_t *, wchar_t);
127 int	wcscmp(const wchar_t *, const wchar_t *);
128 int	wcscoll(const wchar_t *, const wchar_t *);
129 wchar_t	*wcscpy(wchar_t *, const wchar_t *);
130 size_t	wcscspn(const wchar_t *, const wchar_t *);
131 wchar_t *wcsdup(const wchar_t *);
132 size_t	wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
133 size_t	wcslcat(wchar_t *, const wchar_t *, size_t);
134 size_t	wcslcpy(wchar_t *, const wchar_t *, size_t);
135 size_t	wcslen(const wchar_t *);
136 int	wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
137 wchar_t	*wcsncat(wchar_t *, const wchar_t *, size_t);
138 int	wcsncmp(const wchar_t *, const wchar_t *, size_t);
139 wchar_t	*wcsncpy(wchar_t *, const wchar_t *, size_t);
140 #if __OPENBSD_VISIBLE
141 wchar_t *wcsndup(const wchar_t *, size_t);
142 size_t	wcsnrtombs(char *, const wchar_t **, size_t, size_t, mbstate_t *);
143 #endif
144 wchar_t	*wcspbrk(const wchar_t *, const wchar_t *);
145 wchar_t	*wcsrchr(const wchar_t *, wchar_t);
146 size_t	wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *);
147 size_t	wcsspn(const wchar_t *, const wchar_t *);
148 wchar_t	*wcsstr(const wchar_t *, const wchar_t *);
149 double	wcstod(const wchar_t *, wchar_t **);
150 float	wcstof(const wchar_t *, wchar_t **);
151 wchar_t	*wcstok(wchar_t *, const wchar_t *, wchar_t **);
152 long	wcstol(const wchar_t *, wchar_t **, int);
153 #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || \
154     defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) > 199901L
155 /* LONGLONG */
156 long long wcstoll(const wchar_t *, wchar_t **, int);
157 #endif
158 unsigned long wcstoul(const wchar_t *, wchar_t **, int);
159 #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || \
160     defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) > 199901L
161 /* LONGLONG */
162 unsigned long long wcstoull(const wchar_t *, wchar_t **, int);
163 #endif
164 wchar_t	*wcswcs(const wchar_t *, const wchar_t *);
165 int	wcswidth(const wchar_t *, size_t);
166 size_t	wcsxfrm(wchar_t *, const wchar_t *, size_t);
167 int	wctob(wint_t);
168 wctype_t wctype(const char *);
169 int	wcwidth(wchar_t);
170 wchar_t	*wmemchr(const wchar_t *, wchar_t, size_t);
171 int	wmemcmp(const wchar_t *, const wchar_t *, size_t);
172 wchar_t	*wmemcpy(wchar_t *, const wchar_t *, size_t);
173 wchar_t	*wmemmove(wchar_t *, const wchar_t *, size_t);
174 wchar_t	*wmemset(wchar_t *, wchar_t, size_t);
175 
176 /* these functions are currently not implemented in libc */
177 #if 0
178 int	fwprintf(FILE *, const wchar_t *, ...);
179 int	fwscanf(FILE *, const wchar_t *, ...);
180 int	swprintf(wchar_t *, size_t, const wchar_t *, ...);
181 int	swscanf(const wchar_t *, const wchar_t *, ...);
182 int	vfwprintf(FILE *, const wchar_t *, _BSD_VA_LIST_);
183 int	vfwscanf(FILE *, const wchar_t *, _BSD_VA_LIST_);
184 int	vswprintf(wchar_t *, const wchar_t *, _BSD_VA_LIST_);
185 int	vswscanf(const wchar_t *, const wchar_t *, _BSD_VA_LIST_);
186 int	vwprintf(const wchar_t *, _BSD_VA_LIST_);
187 int	vwscanf(const wchar_t *, _BSD_VA_LIST_);
188 int	wprintf(const wchar_t *, ...);
189 int	wscanf(const wchar_t *, ...);
190 #endif
191 __END_DECLS
192 
193 #define getwc(f)	fgetwc(f)
194 #define getwchar()	getwc(stdin)
195 #define putwc(wc, f)	fputwc((wc), (f))
196 #define putwchar(wc)	putwc((wc), stdout)
197 
198 #if __OPENBSD_VISIBLE && !defined(iswoctet)
199 #define iswoctet(wc)	(((wchar_t)(wc) & 0xFF80) == 0xEF80)
200 #endif
201 
202 #ifdef __GNUC__
203 #if !defined(__cplusplus)
204 #define btowc(c)	__extension__({			\
205 	wint_t __WC_tmp = (c);				\
206 							\
207 	(__WC_tmp > 0x7F ? WEOF : __WC_tmp);		\
208 })
209 #define mblen(s,n)	__extension__({			\
210 	mbstate_t __WC_ps = { 0, 0 };			\
211 	int __WC_rv;					\
212 							\
213 	(((__WC_rv = mbrtowc(NULL, (s), (n),		\
214 	    &__WC_ps)) < 0) ? -1 : __WC_rv);		\
215 })
216 #define mbsinit(c)	__extension__({			\
217 	const mbstate_t *__WC_ps = (c);			\
218 							\
219 	(__WC_ps == NULL ? -1 :				\
220 	    __WC_ps->count == 0 ? 1 : 0);		\
221 })
222 #define mbslen(c)	__extension__({			\
223 	const uint8_t *__WC_s = (c);			\
224 	size_t __WC_num = 0;				\
225 							\
226 	while (*__WC_s) {				\
227 		if ((*__WC_s & 0xC0) != 0x80)		\
228 			++__WC_num;			\
229 		++__WC_s;				\
230 	}						\
231 	(__WC_num);					\
232 })
233 #define mbstowcs(pwcs,s,n)	__extension__({		\
234 	mbstate_t __WC_ps = { 0, 0 };			\
235 	const char *__WC_sb = (s);			\
236 							\
237 	(mbsrtowcs((pwcs), &__WC_sb, (n), &__WC_ps));	\
238 })
239 #define mbtowc(pwc,s,n)		__extension__({		\
240 	mbstate_t __WC_ps = { 0, 0 };			\
241 	int __WC_rv;					\
242 							\
243 	(((__WC_rv = mbrtowc((pwc), (s), (n),		\
244 	    &__WC_ps)) < 0) ? -1 : __WC_rv);		\
245 })
246 #define wcstombs(s,pwcs,n)	__extension__({		\
247 	mbstate_t __WC_ps = { 0, 0 };			\
248 	const wchar_t *__WC_sb = (pwcs);		\
249 							\
250 	(wcsrtombs((s), &__WC_sb, (n), &__WC_ps));	\
251 })
252 #define wcswidth(s,n)	__extension__({			\
253 	int __WC_width = 0, __WC_i, __WC_n = (n);	\
254 	const wchar_t *__WC_s = (s);			\
255 							\
256 	while (__WC_n--) {				\
257 		if (*__WC_s == L'\0')			\
258 			break;				\
259 		if ((__WC_i = wcwidth(*__WC_s))	< 0) {	\
260 			__WC_width = -1;		\
261 			break;				\
262 		}					\
263 		__WC_width += __WC_i;			\
264 		__WC_s++;				\
265 	}						\
266 	(__WC_width);					\
267 })
268 #define wctob(c)	__extension__({			\
269 	wint_t __WC_tmp = (c);				\
270 							\
271 	(__WC_tmp > 0x7F ? EOF : (int)__WC_tmp);	\
272 })
273 #define wctomb(s,c)	__extension__({			\
274 	mbstate_t __WC_ps = { 0, 0 };			\
275 	char *__WC_s = (s);				\
276 							\
277 	(__WC_s ? wcrtomb(__WC_s, (c), &__WC_ps) : 0);	\
278 })
279 #endif /* !__cplusplus */
280 
281 /* roll back the middle char of a mis-done 3-byte mb->wc conversion */
282 #define mbrtowc_rollback(ps)	__extension__({		\
283 	const mbstate_t *__WC_s = (ps);			\
284 	int __WC_rv = EOF;				\
285 							\
286 	if (__WC_s->count == 1 &&			\
287 	    __WC_s->value >= 0x20)			\
288 		__WC_rv = 0x80 |			\
289 		    (__WC_s->value & 0x3F);		\
290 	(__WC_rv);					\
291 })
292 #endif
293 
294 /* initialise/set/reset a mbstate_t to empty */
295 #define mbsreset(ps)	do {				\
296 	mbstate_t *__WC_s = (ps);			\
297 							\
298 	if (__WC_s != NULL)				\
299 		__WC_s->count = 0;			\
300 } while (0)
301 
302 #endif
303