xref: /titanic_52/usr/src/test/libc-tests/tests/uchar.c (revision 9a4a12bd7ce60cd60eae508b25eb7a8dae765274)
1*9a4a12bdSRobert Mustacchi /*
2*9a4a12bdSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*9a4a12bdSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*9a4a12bdSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*9a4a12bdSRobert Mustacchi  * 1.0 of the CDDL.
6*9a4a12bdSRobert Mustacchi  *
7*9a4a12bdSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*9a4a12bdSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*9a4a12bdSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*9a4a12bdSRobert Mustacchi  */
11*9a4a12bdSRobert Mustacchi 
12*9a4a12bdSRobert Mustacchi /*
13*9a4a12bdSRobert Mustacchi  * Copyright 2020 Robert Mustacchi
14*9a4a12bdSRobert Mustacchi  */
15*9a4a12bdSRobert Mustacchi 
16*9a4a12bdSRobert Mustacchi /*
17*9a4a12bdSRobert Mustacchi  * Test the implementation of various pieces of uchar.h(3HEAD) functionality.
18*9a4a12bdSRobert Mustacchi  */
19*9a4a12bdSRobert Mustacchi 
20*9a4a12bdSRobert Mustacchi #include <locale.h>
21*9a4a12bdSRobert Mustacchi #include <err.h>
22*9a4a12bdSRobert Mustacchi #include <stdlib.h>
23*9a4a12bdSRobert Mustacchi #include <sys/types.h>
24*9a4a12bdSRobert Mustacchi #include <sys/sysmacros.h>
25*9a4a12bdSRobert Mustacchi #include <strings.h>
26*9a4a12bdSRobert Mustacchi #include <wchar.h>
27*9a4a12bdSRobert Mustacchi #include <uchar.h>
28*9a4a12bdSRobert Mustacchi #include <errno.h>
29*9a4a12bdSRobert Mustacchi 
30*9a4a12bdSRobert Mustacchi static const char *uchar_wide = "光";
31*9a4a12bdSRobert Mustacchi static const char32_t uchar_value = 0x5149;
32*9a4a12bdSRobert Mustacchi static const char *uchar_hello = "hello";
33*9a4a12bdSRobert Mustacchi 
34*9a4a12bdSRobert Mustacchi static void
35*9a4a12bdSRobert Mustacchi update_locale(const char *loc)
36*9a4a12bdSRobert Mustacchi {
37*9a4a12bdSRobert Mustacchi 	const char *newloc = setlocale(LC_CTYPE, loc);
38*9a4a12bdSRobert Mustacchi 	if (newloc == NULL) {
39*9a4a12bdSRobert Mustacchi 		err(EXIT_FAILURE, "TEST FAILED: failed to update locale to %s",
40*9a4a12bdSRobert Mustacchi 		    loc);
41*9a4a12bdSRobert Mustacchi 	}
42*9a4a12bdSRobert Mustacchi 
43*9a4a12bdSRobert Mustacchi 	if (strcmp(newloc, loc) != 0) {
44*9a4a12bdSRobert Mustacchi 		errx(EXIT_FAILURE, "TEST FAILED: locale set to %s, but got %s",
45*9a4a12bdSRobert Mustacchi 		    loc, newloc);
46*9a4a12bdSRobert Mustacchi 	}
47*9a4a12bdSRobert Mustacchi }
48*9a4a12bdSRobert Mustacchi 
49*9a4a12bdSRobert Mustacchi static boolean_t
50*9a4a12bdSRobert Mustacchi mbrtoc32_ascii(mbstate_t *mbs)
51*9a4a12bdSRobert Mustacchi {
52*9a4a12bdSRobert Mustacchi 	char32_t out;
53*9a4a12bdSRobert Mustacchi 	size_t len;
54*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
55*9a4a12bdSRobert Mustacchi 
56*9a4a12bdSRobert Mustacchi 	if ((len = mbrtoc32(&out, uchar_hello, 5, mbs)) != 1) {
57*9a4a12bdSRobert Mustacchi 		warnx("expected mbrtoc32 to return 1, returned %zu", len);
58*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
59*9a4a12bdSRobert Mustacchi 	}
60*9a4a12bdSRobert Mustacchi 
61*9a4a12bdSRobert Mustacchi 	if (out != 'h') {
62*9a4a12bdSRobert Mustacchi 		warnx("got bad char32_t, expected 0x%x, found 0x%x\n", 'h',
63*9a4a12bdSRobert Mustacchi 		    out);
64*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
65*9a4a12bdSRobert Mustacchi 	}
66*9a4a12bdSRobert Mustacchi 
67*9a4a12bdSRobert Mustacchi 	if ((len = mbrtoc32(&out, uchar_hello + 1, 4, mbs)) != 1) {
68*9a4a12bdSRobert Mustacchi 		warnx("expected mbrtoc32 to return 1, returned %zu", len);
69*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
70*9a4a12bdSRobert Mustacchi 	}
71*9a4a12bdSRobert Mustacchi 
72*9a4a12bdSRobert Mustacchi 	if (out != 'e') {
73*9a4a12bdSRobert Mustacchi 		warnx("got bad char32_t, expected 0x%x, found 0x%x\n", 'h',
74*9a4a12bdSRobert Mustacchi 		    out);
75*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
76*9a4a12bdSRobert Mustacchi 	}
77*9a4a12bdSRobert Mustacchi 
78*9a4a12bdSRobert Mustacchi 	return (ret);
79*9a4a12bdSRobert Mustacchi }
80*9a4a12bdSRobert Mustacchi 
81*9a4a12bdSRobert Mustacchi static boolean_t
82*9a4a12bdSRobert Mustacchi mbrtoc32_ascii_internal(void)
83*9a4a12bdSRobert Mustacchi {
84*9a4a12bdSRobert Mustacchi 	return (mbrtoc32_ascii(NULL));
85*9a4a12bdSRobert Mustacchi }
86*9a4a12bdSRobert Mustacchi 
87*9a4a12bdSRobert Mustacchi static boolean_t
88*9a4a12bdSRobert Mustacchi mbrtoc32_ascii_mbstate(void)
89*9a4a12bdSRobert Mustacchi {
90*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
91*9a4a12bdSRobert Mustacchi 
92*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
93*9a4a12bdSRobert Mustacchi 	return (mbrtoc32_ascii(&mbs));
94*9a4a12bdSRobert Mustacchi }
95*9a4a12bdSRobert Mustacchi 
96*9a4a12bdSRobert Mustacchi static boolean_t
97*9a4a12bdSRobert Mustacchi mbrtoc32_badseq_utf8(void)
98*9a4a12bdSRobert Mustacchi {
99*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
100*9a4a12bdSRobert Mustacchi 	size_t len;
101*9a4a12bdSRobert Mustacchi 	char32_t out;
102*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
103*9a4a12bdSRobert Mustacchi 	char *badstr;
104*9a4a12bdSRobert Mustacchi 
105*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
106*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, "\xa9", 1, &mbs);
107*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-1) {
108*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 returned %zu, not %zu", len, (size_t)-1);
109*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
110*9a4a12bdSRobert Mustacchi 	}
111*9a4a12bdSRobert Mustacchi 
112*9a4a12bdSRobert Mustacchi 	if (errno != EILSEQ) {
113*9a4a12bdSRobert Mustacchi 		warnx("found bad errno, expected %d, found %d\n", errno,
114*9a4a12bdSRobert Mustacchi 		    EILSEQ);
115*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
116*9a4a12bdSRobert Mustacchi 	}
117*9a4a12bdSRobert Mustacchi 
118*9a4a12bdSRobert Mustacchi 	badstr = strdup(uchar_wide);
119*9a4a12bdSRobert Mustacchi 	if (badstr == NULL) {
120*9a4a12bdSRobert Mustacchi 		warn("failed to duplicate uchar_wide");
121*9a4a12bdSRobert Mustacchi 		return (B_FALSE);
122*9a4a12bdSRobert Mustacchi 	}
123*9a4a12bdSRobert Mustacchi 
124*9a4a12bdSRobert Mustacchi 	badstr[1] = '?';
125*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
126*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, badstr, strlen(badstr), &mbs);
127*9a4a12bdSRobert Mustacchi 	free(badstr);
128*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-1) {
129*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 returned %zu, not %zu", len, (size_t)-1);
130*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
131*9a4a12bdSRobert Mustacchi 	}
132*9a4a12bdSRobert Mustacchi 
133*9a4a12bdSRobert Mustacchi 	if (errno != EILSEQ) {
134*9a4a12bdSRobert Mustacchi 		warnx("found bad errno, expected %d, found %d\n", errno,
135*9a4a12bdSRobert Mustacchi 		    EILSEQ);
136*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
137*9a4a12bdSRobert Mustacchi 	}
138*9a4a12bdSRobert Mustacchi 
139*9a4a12bdSRobert Mustacchi 	return (ret);
140*9a4a12bdSRobert Mustacchi }
141*9a4a12bdSRobert Mustacchi 
142*9a4a12bdSRobert Mustacchi static boolean_t
143*9a4a12bdSRobert Mustacchi mbrtoc32_roundtrip(void)
144*9a4a12bdSRobert Mustacchi {
145*9a4a12bdSRobert Mustacchi 	char32_t out;
146*9a4a12bdSRobert Mustacchi 	size_t len, clen;
147*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
148*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
149*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
150*9a4a12bdSRobert Mustacchi 
151*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
152*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, uchar_wide, strlen(uchar_wide), &mbs);
153*9a4a12bdSRobert Mustacchi 	if (len != 3) {
154*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 returned %zu, expected %u", len, 3);
155*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
156*9a4a12bdSRobert Mustacchi 	}
157*9a4a12bdSRobert Mustacchi 
158*9a4a12bdSRobert Mustacchi 	if (out != uchar_value) {
159*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 converted character to 0x%x not 0x%x",
160*9a4a12bdSRobert Mustacchi 		    out, uchar_value);
161*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
162*9a4a12bdSRobert Mustacchi 	}
163*9a4a12bdSRobert Mustacchi 
164*9a4a12bdSRobert Mustacchi 	clen = c32rtomb(buf, out, &mbs);
165*9a4a12bdSRobert Mustacchi 	if (clen != len) {
166*9a4a12bdSRobert Mustacchi 		warnx("c32rtomb returned %d bytes, but we originally used %d",
167*9a4a12bdSRobert Mustacchi 		    clen, len);
168*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
169*9a4a12bdSRobert Mustacchi 	}
170*9a4a12bdSRobert Mustacchi 
171*9a4a12bdSRobert Mustacchi 	if (strncmp(buf, uchar_wide, len) != 0) {
172*9a4a12bdSRobert Mustacchi 		warnx("round trip string comparison failed");
173*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
174*9a4a12bdSRobert Mustacchi 	}
175*9a4a12bdSRobert Mustacchi 
176*9a4a12bdSRobert Mustacchi 	return (ret);
177*9a4a12bdSRobert Mustacchi }
178*9a4a12bdSRobert Mustacchi 
179*9a4a12bdSRobert Mustacchi static boolean_t
180*9a4a12bdSRobert Mustacchi mbrtoc32_partial(void)
181*9a4a12bdSRobert Mustacchi {
182*9a4a12bdSRobert Mustacchi 	char32_t out;
183*9a4a12bdSRobert Mustacchi 	size_t len, i;
184*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
185*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
186*9a4a12bdSRobert Mustacchi 
187*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
188*9a4a12bdSRobert Mustacchi 	for (i = 0; i < strlen(uchar_wide) - 1; i++) {
189*9a4a12bdSRobert Mustacchi 		len = mbrtoc32(&out, uchar_wide + i, 1, &mbs);
190*9a4a12bdSRobert Mustacchi 		if (len != (size_t)-2) {
191*9a4a12bdSRobert Mustacchi 			warnx("partial mbrtoc32 returned %zu, not -2", len);
192*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
193*9a4a12bdSRobert Mustacchi 		}
194*9a4a12bdSRobert Mustacchi 	}
195*9a4a12bdSRobert Mustacchi 
196*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, uchar_wide + i, 1, &mbs);
197*9a4a12bdSRobert Mustacchi 	if (len != 1) {
198*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc32 returned %zu, not 1", len);
199*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
200*9a4a12bdSRobert Mustacchi 	}
201*9a4a12bdSRobert Mustacchi 
202*9a4a12bdSRobert Mustacchi 	if (out != uchar_value) {
203*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 converted character to 0x%x not 0x%x",
204*9a4a12bdSRobert Mustacchi 		    out, uchar_value);
205*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
206*9a4a12bdSRobert Mustacchi 	}
207*9a4a12bdSRobert Mustacchi 
208*9a4a12bdSRobert Mustacchi 	return (ret);
209*9a4a12bdSRobert Mustacchi }
210*9a4a12bdSRobert Mustacchi 
211*9a4a12bdSRobert Mustacchi static boolean_t
212*9a4a12bdSRobert Mustacchi mbrtoc32_zero(void)
213*9a4a12bdSRobert Mustacchi {
214*9a4a12bdSRobert Mustacchi 	char32_t out, exp = L'\0';
215*9a4a12bdSRobert Mustacchi 	size_t len;
216*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
217*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
218*9a4a12bdSRobert Mustacchi 
219*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
220*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, "", 1, &mbs);
221*9a4a12bdSRobert Mustacchi 	if (len != 0) {
222*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc32 returned %zu, not 0", len);
223*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
224*9a4a12bdSRobert Mustacchi 	}
225*9a4a12bdSRobert Mustacchi 
226*9a4a12bdSRobert Mustacchi 	if (out != exp) {
227*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 converted character to 0x%x not 0x%x",
228*9a4a12bdSRobert Mustacchi 		    out, exp);
229*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
230*9a4a12bdSRobert Mustacchi 	}
231*9a4a12bdSRobert Mustacchi 
232*9a4a12bdSRobert Mustacchi 	return (ret);
233*9a4a12bdSRobert Mustacchi }
234*9a4a12bdSRobert Mustacchi 
235*9a4a12bdSRobert Mustacchi static boolean_t
236*9a4a12bdSRobert Mustacchi mbrtoc32_zero_len(void)
237*9a4a12bdSRobert Mustacchi {
238*9a4a12bdSRobert Mustacchi 	char32_t out = 0x12345, exp = 0x12345;
239*9a4a12bdSRobert Mustacchi 	size_t len;
240*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
241*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
242*9a4a12bdSRobert Mustacchi 
243*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
244*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, uchar_wide, 0, &mbs);
245*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-2) {
246*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc32 returned %zu, not -2", len);
247*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
248*9a4a12bdSRobert Mustacchi 	}
249*9a4a12bdSRobert Mustacchi 
250*9a4a12bdSRobert Mustacchi 	if (out != exp) {
251*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 incorrectly wrote to char32_t value with "
252*9a4a12bdSRobert Mustacchi 		    "zero string, found 0x%x not 0x%x", out, exp);
253*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
254*9a4a12bdSRobert Mustacchi 	}
255*9a4a12bdSRobert Mustacchi 
256*9a4a12bdSRobert Mustacchi 	return (ret);
257*9a4a12bdSRobert Mustacchi }
258*9a4a12bdSRobert Mustacchi 
259*9a4a12bdSRobert Mustacchi static boolean_t
260*9a4a12bdSRobert Mustacchi mbrtoc32_null(void)
261*9a4a12bdSRobert Mustacchi {
262*9a4a12bdSRobert Mustacchi 	char32_t out = 0x123456, exp = 0x123456;
263*9a4a12bdSRobert Mustacchi 	size_t len;
264*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
265*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
266*9a4a12bdSRobert Mustacchi 
267*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
268*9a4a12bdSRobert Mustacchi 	len = mbrtoc32(&out, NULL, 1, &mbs);
269*9a4a12bdSRobert Mustacchi 	if (len != 0) {
270*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc32 returned %zu, not 0", len);
271*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
272*9a4a12bdSRobert Mustacchi 	}
273*9a4a12bdSRobert Mustacchi 
274*9a4a12bdSRobert Mustacchi 	if (out != exp) {
275*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 incorrectly wrote to char32_t value with "
276*9a4a12bdSRobert Mustacchi 		    "null string, found 0x%x not 0x%x", out, exp);
277*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
278*9a4a12bdSRobert Mustacchi 	}
279*9a4a12bdSRobert Mustacchi 
280*9a4a12bdSRobert Mustacchi 	return (ret);
281*9a4a12bdSRobert Mustacchi }
282*9a4a12bdSRobert Mustacchi 
283*9a4a12bdSRobert Mustacchi static boolean_t
284*9a4a12bdSRobert Mustacchi mbrtoc16_ascii(mbstate_t *mbs)
285*9a4a12bdSRobert Mustacchi {
286*9a4a12bdSRobert Mustacchi 	char16_t out;
287*9a4a12bdSRobert Mustacchi 	size_t len;
288*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
289*9a4a12bdSRobert Mustacchi 
290*9a4a12bdSRobert Mustacchi 	if ((len = mbrtoc16(&out, uchar_hello, 5, mbs)) != 1) {
291*9a4a12bdSRobert Mustacchi 		warnx("expected mbrtoc16 to return 1, returned %zu", len);
292*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
293*9a4a12bdSRobert Mustacchi 	}
294*9a4a12bdSRobert Mustacchi 
295*9a4a12bdSRobert Mustacchi 	if (out != 'h') {
296*9a4a12bdSRobert Mustacchi 		warnx("got bad char16_t, expected 0x%x, found 0x%x\n", 'h',
297*9a4a12bdSRobert Mustacchi 		    out);
298*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
299*9a4a12bdSRobert Mustacchi 	}
300*9a4a12bdSRobert Mustacchi 
301*9a4a12bdSRobert Mustacchi 	if ((len = mbrtoc16(&out, uchar_hello + 1, 4, mbs)) != 1) {
302*9a4a12bdSRobert Mustacchi 		warnx("expected mbrtoc16 to return 1, returned %zu", len);
303*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
304*9a4a12bdSRobert Mustacchi 	}
305*9a4a12bdSRobert Mustacchi 
306*9a4a12bdSRobert Mustacchi 	if (out != 'e') {
307*9a4a12bdSRobert Mustacchi 		warnx("got bad char16_t, expected 0x%x, found 0x%x\n", 'h',
308*9a4a12bdSRobert Mustacchi 		    out);
309*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
310*9a4a12bdSRobert Mustacchi 	}
311*9a4a12bdSRobert Mustacchi 
312*9a4a12bdSRobert Mustacchi 	return (ret);
313*9a4a12bdSRobert Mustacchi }
314*9a4a12bdSRobert Mustacchi 
315*9a4a12bdSRobert Mustacchi static boolean_t
316*9a4a12bdSRobert Mustacchi mbrtoc16_ascii_internal(void)
317*9a4a12bdSRobert Mustacchi {
318*9a4a12bdSRobert Mustacchi 	return (mbrtoc16_ascii(NULL));
319*9a4a12bdSRobert Mustacchi }
320*9a4a12bdSRobert Mustacchi 
321*9a4a12bdSRobert Mustacchi static boolean_t
322*9a4a12bdSRobert Mustacchi mbrtoc16_ascii_mbstate(void)
323*9a4a12bdSRobert Mustacchi {
324*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
325*9a4a12bdSRobert Mustacchi 
326*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
327*9a4a12bdSRobert Mustacchi 	return (mbrtoc16_ascii(&mbs));
328*9a4a12bdSRobert Mustacchi }
329*9a4a12bdSRobert Mustacchi 
330*9a4a12bdSRobert Mustacchi static boolean_t
331*9a4a12bdSRobert Mustacchi mbrtoc16_null(void)
332*9a4a12bdSRobert Mustacchi {
333*9a4a12bdSRobert Mustacchi 	char16_t out = 0x1234, exp = 0x1234;
334*9a4a12bdSRobert Mustacchi 	size_t len;
335*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
336*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
337*9a4a12bdSRobert Mustacchi 
338*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
339*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out, NULL, 1, &mbs);
340*9a4a12bdSRobert Mustacchi 	if (len != 0) {
341*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc16 returned %zu, not 0", len);
342*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
343*9a4a12bdSRobert Mustacchi 	}
344*9a4a12bdSRobert Mustacchi 
345*9a4a12bdSRobert Mustacchi 	if (out != exp) {
346*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 incorrectly wrote to char16_t value with "
347*9a4a12bdSRobert Mustacchi 		    "null string, found 0x%x not 0x%x", out, exp);
348*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
349*9a4a12bdSRobert Mustacchi 	}
350*9a4a12bdSRobert Mustacchi 
351*9a4a12bdSRobert Mustacchi 	return (ret);
352*9a4a12bdSRobert Mustacchi }
353*9a4a12bdSRobert Mustacchi 
354*9a4a12bdSRobert Mustacchi static boolean_t
355*9a4a12bdSRobert Mustacchi mbrtoc16_zero(void)
356*9a4a12bdSRobert Mustacchi {
357*9a4a12bdSRobert Mustacchi 	char16_t out, exp = L'\0';
358*9a4a12bdSRobert Mustacchi 	size_t len;
359*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
360*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
361*9a4a12bdSRobert Mustacchi 
362*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
363*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out, "", 1, &mbs);
364*9a4a12bdSRobert Mustacchi 	if (len != 0) {
365*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc16 returned %zu, not 0", len);
366*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
367*9a4a12bdSRobert Mustacchi 	}
368*9a4a12bdSRobert Mustacchi 
369*9a4a12bdSRobert Mustacchi 	if (out != exp) {
370*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 converted character to 0x%x not 0x%x",
371*9a4a12bdSRobert Mustacchi 		    out, exp);
372*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
373*9a4a12bdSRobert Mustacchi 	}
374*9a4a12bdSRobert Mustacchi 
375*9a4a12bdSRobert Mustacchi 	return (ret);
376*9a4a12bdSRobert Mustacchi }
377*9a4a12bdSRobert Mustacchi 
378*9a4a12bdSRobert Mustacchi static boolean_t
379*9a4a12bdSRobert Mustacchi mbrtoc16_zero_len(void)
380*9a4a12bdSRobert Mustacchi {
381*9a4a12bdSRobert Mustacchi 	char16_t out = 0x5432, exp = 0x5432;
382*9a4a12bdSRobert Mustacchi 	size_t len;
383*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
384*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
385*9a4a12bdSRobert Mustacchi 
386*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
387*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out, uchar_wide, 0, &mbs);
388*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-2) {
389*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc16 returned %zu, not -2", len);
390*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
391*9a4a12bdSRobert Mustacchi 	}
392*9a4a12bdSRobert Mustacchi 
393*9a4a12bdSRobert Mustacchi 	if (out != exp) {
394*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 incorrectly wrote to char16_t value with "
395*9a4a12bdSRobert Mustacchi 		    "zero length string, found 0x%x not 0x%x", out, exp);
396*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
397*9a4a12bdSRobert Mustacchi 	}
398*9a4a12bdSRobert Mustacchi 
399*9a4a12bdSRobert Mustacchi 	return (ret);
400*9a4a12bdSRobert Mustacchi }
401*9a4a12bdSRobert Mustacchi 
402*9a4a12bdSRobert Mustacchi static boolean_t
403*9a4a12bdSRobert Mustacchi mbrtoc16_roundtrip(void)
404*9a4a12bdSRobert Mustacchi {
405*9a4a12bdSRobert Mustacchi 	char16_t out;
406*9a4a12bdSRobert Mustacchi 	size_t len, clen;
407*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
408*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
409*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
410*9a4a12bdSRobert Mustacchi 
411*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
412*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out, uchar_wide, strlen(uchar_wide), &mbs);
413*9a4a12bdSRobert Mustacchi 	if (len != 3) {
414*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 returned %zu, expected %u", len, 3);
415*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
416*9a4a12bdSRobert Mustacchi 	}
417*9a4a12bdSRobert Mustacchi 
418*9a4a12bdSRobert Mustacchi 	if (out != uchar_value) {
419*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 converted character to 0x%x not 0x%x",
420*9a4a12bdSRobert Mustacchi 		    out, uchar_value);
421*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
422*9a4a12bdSRobert Mustacchi 	}
423*9a4a12bdSRobert Mustacchi 
424*9a4a12bdSRobert Mustacchi 	clen = c16rtomb(buf, out, &mbs);
425*9a4a12bdSRobert Mustacchi 	if (clen != len) {
426*9a4a12bdSRobert Mustacchi 		warnx("c16rtomb returned %d bytes, but we originally used %d",
427*9a4a12bdSRobert Mustacchi 		    clen, len);
428*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
429*9a4a12bdSRobert Mustacchi 	}
430*9a4a12bdSRobert Mustacchi 
431*9a4a12bdSRobert Mustacchi 	if (strncmp(buf, uchar_wide, len) != 0) {
432*9a4a12bdSRobert Mustacchi 		warnx("round trip string comparison failed");
433*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
434*9a4a12bdSRobert Mustacchi 	}
435*9a4a12bdSRobert Mustacchi 
436*9a4a12bdSRobert Mustacchi 	return (ret);
437*9a4a12bdSRobert Mustacchi }
438*9a4a12bdSRobert Mustacchi 
439*9a4a12bdSRobert Mustacchi static boolean_t
440*9a4a12bdSRobert Mustacchi mbrtoc16_partial(void)
441*9a4a12bdSRobert Mustacchi {
442*9a4a12bdSRobert Mustacchi 	char16_t out;
443*9a4a12bdSRobert Mustacchi 	size_t len, i;
444*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
445*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
446*9a4a12bdSRobert Mustacchi 
447*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
448*9a4a12bdSRobert Mustacchi 	for (i = 0; i < strlen(uchar_wide) - 1; i++) {
449*9a4a12bdSRobert Mustacchi 		len = mbrtoc16(&out, uchar_wide + i, 1, &mbs);
450*9a4a12bdSRobert Mustacchi 		if (len != (size_t)-2) {
451*9a4a12bdSRobert Mustacchi 			warnx("partial mbrtoc16 returned %zu, not -2", len);
452*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
453*9a4a12bdSRobert Mustacchi 		}
454*9a4a12bdSRobert Mustacchi 	}
455*9a4a12bdSRobert Mustacchi 
456*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out, uchar_wide + i, 1, &mbs);
457*9a4a12bdSRobert Mustacchi 	if (len != 1) {
458*9a4a12bdSRobert Mustacchi 		warnx("partial mbrtoc16 returned %zu, not 1", len);
459*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
460*9a4a12bdSRobert Mustacchi 	}
461*9a4a12bdSRobert Mustacchi 
462*9a4a12bdSRobert Mustacchi 	if (out != uchar_value) {
463*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 converted character to 0x%x not 0x%x",
464*9a4a12bdSRobert Mustacchi 		    out, uchar_value);
465*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
466*9a4a12bdSRobert Mustacchi 	}
467*9a4a12bdSRobert Mustacchi 
468*9a4a12bdSRobert Mustacchi 	return (ret);
469*9a4a12bdSRobert Mustacchi }
470*9a4a12bdSRobert Mustacchi 
471*9a4a12bdSRobert Mustacchi static boolean_t
472*9a4a12bdSRobert Mustacchi mbrtoc16_surrogate(void)
473*9a4a12bdSRobert Mustacchi {
474*9a4a12bdSRobert Mustacchi 	char16_t out0, out1;
475*9a4a12bdSRobert Mustacchi 	size_t len, clen;
476*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
477*9a4a12bdSRobert Mustacchi 	const char *surrogate = "\xF0\x9F\x92\xA9";
478*9a4a12bdSRobert Mustacchi 	char16_t exp0 = 0xd83d, exp1 = 0xdca9;
479*9a4a12bdSRobert Mustacchi 	size_t slen = strlen(surrogate);
480*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
481*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
482*9a4a12bdSRobert Mustacchi 
483*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
484*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out0, surrogate, slen, &mbs);
485*9a4a12bdSRobert Mustacchi 	if (len != slen) {
486*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 returned %zu, expected %u", len, slen);
487*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
488*9a4a12bdSRobert Mustacchi 	}
489*9a4a12bdSRobert Mustacchi 
490*9a4a12bdSRobert Mustacchi 	if (out0 != exp0) {
491*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 converted character to 0x%x not 0x%x",
492*9a4a12bdSRobert Mustacchi 		    out0, exp0);
493*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
494*9a4a12bdSRobert Mustacchi 	}
495*9a4a12bdSRobert Mustacchi 
496*9a4a12bdSRobert Mustacchi 	if (mbsinit(&mbs) != 0) {
497*9a4a12bdSRobert Mustacchi 		warnx("mb state with a surrogate character is somehow in the "
498*9a4a12bdSRobert Mustacchi 		    "initial state");
499*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
500*9a4a12bdSRobert Mustacchi 	}
501*9a4a12bdSRobert Mustacchi 
502*9a4a12bdSRobert Mustacchi 	len = mbrtoc16(&out1, uchar_wide, strlen(uchar_wide), &mbs);
503*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-3) {
504*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc16 returned %zu, expected -3", len);
505*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
506*9a4a12bdSRobert Mustacchi 	}
507*9a4a12bdSRobert Mustacchi 
508*9a4a12bdSRobert Mustacchi 	if (mbsinit(&mbs) == 0) {
509*9a4a12bdSRobert Mustacchi 		warnx("mb state with after both surrogate characters isn't "
510*9a4a12bdSRobert Mustacchi 		    "in initial state");
511*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
512*9a4a12bdSRobert Mustacchi 	}
513*9a4a12bdSRobert Mustacchi 
514*9a4a12bdSRobert Mustacchi 	if (out1 != exp1) {
515*9a4a12bdSRobert Mustacchi 		warnx("mbrtoc32 converted character to 0x%x not 0x%x",
516*9a4a12bdSRobert Mustacchi 		    out1, exp1);
517*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
518*9a4a12bdSRobert Mustacchi 	}
519*9a4a12bdSRobert Mustacchi 
520*9a4a12bdSRobert Mustacchi 	clen = c16rtomb(buf, out0, &mbs);
521*9a4a12bdSRobert Mustacchi 	if (clen != 0) {
522*9a4a12bdSRobert Mustacchi 		warnx("c16rtomb returned %d bytes, but expected zero for the "
523*9a4a12bdSRobert Mustacchi 		    "first surrogate", clen);
524*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
525*9a4a12bdSRobert Mustacchi 	}
526*9a4a12bdSRobert Mustacchi 
527*9a4a12bdSRobert Mustacchi 	if (mbsinit(&mbs) != 0) {
528*9a4a12bdSRobert Mustacchi 		warnx("mb state with a surrogate character is somehow in the "
529*9a4a12bdSRobert Mustacchi 		    "initial state");
530*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
531*9a4a12bdSRobert Mustacchi 	}
532*9a4a12bdSRobert Mustacchi 
533*9a4a12bdSRobert Mustacchi 	clen = c16rtomb(buf, out1, &mbs);
534*9a4a12bdSRobert Mustacchi 	if (clen != slen) {
535*9a4a12bdSRobert Mustacchi 		warnx("c16rtomb returned %zd, expected %u", len, slen);
536*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
537*9a4a12bdSRobert Mustacchi 	}
538*9a4a12bdSRobert Mustacchi 
539*9a4a12bdSRobert Mustacchi 	if (mbsinit(&mbs) == 0) {
540*9a4a12bdSRobert Mustacchi 		warnx("mb state with after both surrogate characters isn't "
541*9a4a12bdSRobert Mustacchi 		    "in initial state");
542*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
543*9a4a12bdSRobert Mustacchi 	}
544*9a4a12bdSRobert Mustacchi 
545*9a4a12bdSRobert Mustacchi 	if (strncmp(buf, surrogate, slen) != 0) {
546*9a4a12bdSRobert Mustacchi 		warnx("round trip string comparison failed");
547*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
548*9a4a12bdSRobert Mustacchi 	}
549*9a4a12bdSRobert Mustacchi 
550*9a4a12bdSRobert Mustacchi 	return (ret);
551*9a4a12bdSRobert Mustacchi }
552*9a4a12bdSRobert Mustacchi 
553*9a4a12bdSRobert Mustacchi static boolean_t
554*9a4a12bdSRobert Mustacchi c32rtomb_eilseq_iso8859(void)
555*9a4a12bdSRobert Mustacchi {
556*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
557*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
558*9a4a12bdSRobert Mustacchi 	size_t len;
559*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
560*9a4a12bdSRobert Mustacchi 
561*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
562*9a4a12bdSRobert Mustacchi 	len = c32rtomb(buf, uchar_value, &mbs);
563*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-1) {
564*9a4a12bdSRobert Mustacchi 		warnx("c32rtomb returned %zd, expected -1\n", len);
565*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
566*9a4a12bdSRobert Mustacchi 	}
567*9a4a12bdSRobert Mustacchi 
568*9a4a12bdSRobert Mustacchi 	if (errno != EILSEQ) {
569*9a4a12bdSRobert Mustacchi 		warnx("expected errno set to %d was %d", EILSEQ, errno);
570*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
571*9a4a12bdSRobert Mustacchi 	}
572*9a4a12bdSRobert Mustacchi 
573*9a4a12bdSRobert Mustacchi 	return (ret);
574*9a4a12bdSRobert Mustacchi }
575*9a4a12bdSRobert Mustacchi 
576*9a4a12bdSRobert Mustacchi static boolean_t
577*9a4a12bdSRobert Mustacchi c16rtomb_eilseq_iso8859(void)
578*9a4a12bdSRobert Mustacchi {
579*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
580*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
581*9a4a12bdSRobert Mustacchi 	size_t len;
582*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
583*9a4a12bdSRobert Mustacchi 
584*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
585*9a4a12bdSRobert Mustacchi 	len = c32rtomb(buf, (char16_t)uchar_value, &mbs);
586*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-1) {
587*9a4a12bdSRobert Mustacchi 		warnx("c32rtomb returned %zd, expected -1\n", len);
588*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
589*9a4a12bdSRobert Mustacchi 	}
590*9a4a12bdSRobert Mustacchi 
591*9a4a12bdSRobert Mustacchi 	if (errno != EILSEQ) {
592*9a4a12bdSRobert Mustacchi 		warnx("expected errno set to %d was %d", EILSEQ, errno);
593*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
594*9a4a12bdSRobert Mustacchi 	}
595*9a4a12bdSRobert Mustacchi 
596*9a4a12bdSRobert Mustacchi 	return (ret);
597*9a4a12bdSRobert Mustacchi }
598*9a4a12bdSRobert Mustacchi 
599*9a4a12bdSRobert Mustacchi static boolean_t
600*9a4a12bdSRobert Mustacchi c32rtomb_eilseq_utf8(void)
601*9a4a12bdSRobert Mustacchi {
602*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
603*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
604*9a4a12bdSRobert Mustacchi 	size_t len;
605*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
606*9a4a12bdSRobert Mustacchi 
607*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
608*9a4a12bdSRobert Mustacchi 	len = c32rtomb(buf, UINT32_MAX, &mbs);
609*9a4a12bdSRobert Mustacchi 	if (len != (size_t)-1) {
610*9a4a12bdSRobert Mustacchi 		warnx("c32rtomb returned %zd, expected -1\n", len);
611*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
612*9a4a12bdSRobert Mustacchi 	}
613*9a4a12bdSRobert Mustacchi 
614*9a4a12bdSRobert Mustacchi 	if (errno != EILSEQ) {
615*9a4a12bdSRobert Mustacchi 		warnx("expected errno set to %d was %d", EILSEQ, errno);
616*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
617*9a4a12bdSRobert Mustacchi 	}
618*9a4a12bdSRobert Mustacchi 
619*9a4a12bdSRobert Mustacchi 	return (ret);
620*9a4a12bdSRobert Mustacchi }
621*9a4a12bdSRobert Mustacchi 
622*9a4a12bdSRobert Mustacchi static boolean_t
623*9a4a12bdSRobert Mustacchi c16rtomb_bad_first(void)
624*9a4a12bdSRobert Mustacchi {
625*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
626*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
627*9a4a12bdSRobert Mustacchi 	size_t len, i;
628*9a4a12bdSRobert Mustacchi 	char16_t first = 0xd83d;
629*9a4a12bdSRobert Mustacchi 	char16_t bad[] = { 0x0, 0xd7ff, 0xd83d, 0xd900, 0xffff };
630*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
631*9a4a12bdSRobert Mustacchi 
632*9a4a12bdSRobert Mustacchi 	for (i = 0; i < ARRAY_SIZE(bad); i++) {
633*9a4a12bdSRobert Mustacchi 		bzero(&mbs, sizeof (mbs));
634*9a4a12bdSRobert Mustacchi 		len = c16rtomb(buf, first, &mbs);
635*9a4a12bdSRobert Mustacchi 		if (len != 0) {
636*9a4a12bdSRobert Mustacchi 			warnx("c16rtomb returned %zd, expected 0\n", len);
637*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
638*9a4a12bdSRobert Mustacchi 		}
639*9a4a12bdSRobert Mustacchi 
640*9a4a12bdSRobert Mustacchi 		len = c16rtomb(buf, bad[i], &mbs);
641*9a4a12bdSRobert Mustacchi 		if (len != (size_t)-1) {
642*9a4a12bdSRobert Mustacchi 			warnx("c16rtomb surrogate %x returned %zd, expected "
643*9a4a12bdSRobert Mustacchi 			    "-1\n", bad[i], len);
644*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
645*9a4a12bdSRobert Mustacchi 		}
646*9a4a12bdSRobert Mustacchi 
647*9a4a12bdSRobert Mustacchi 		if (errno != EILSEQ) {
648*9a4a12bdSRobert Mustacchi 			warnx("expected errno set to %d was %d", EILSEQ, errno);
649*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
650*9a4a12bdSRobert Mustacchi 		}
651*9a4a12bdSRobert Mustacchi 	}
652*9a4a12bdSRobert Mustacchi 
653*9a4a12bdSRobert Mustacchi 	return (ret);
654*9a4a12bdSRobert Mustacchi }
655*9a4a12bdSRobert Mustacchi 
656*9a4a12bdSRobert Mustacchi static boolean_t
657*9a4a12bdSRobert Mustacchi c16rtomb_bad_second(void)
658*9a4a12bdSRobert Mustacchi {
659*9a4a12bdSRobert Mustacchi 	char buf[MB_CUR_MAX];
660*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
661*9a4a12bdSRobert Mustacchi 	size_t len, i;
662*9a4a12bdSRobert Mustacchi 	char16_t bad[] = { 0xdc00, 0xdd34, 0xdfff };
663*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
664*9a4a12bdSRobert Mustacchi 
665*9a4a12bdSRobert Mustacchi 	for (i = 0; i < ARRAY_SIZE(bad); i++) {
666*9a4a12bdSRobert Mustacchi 		bzero(&mbs, sizeof (mbs));
667*9a4a12bdSRobert Mustacchi 		len = c16rtomb(buf, bad[i], &mbs);
668*9a4a12bdSRobert Mustacchi 		if (len != (size_t)-1) {
669*9a4a12bdSRobert Mustacchi 			warnx("c16rtomb surrogate %x returned %zd, expected "
670*9a4a12bdSRobert Mustacchi 			    "-1\n", bad[i], len);
671*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
672*9a4a12bdSRobert Mustacchi 		}
673*9a4a12bdSRobert Mustacchi 
674*9a4a12bdSRobert Mustacchi 		if (errno != EILSEQ) {
675*9a4a12bdSRobert Mustacchi 			warnx("expected errno set to %d was %d", EILSEQ, errno);
676*9a4a12bdSRobert Mustacchi 			ret = B_FALSE;
677*9a4a12bdSRobert Mustacchi 		}
678*9a4a12bdSRobert Mustacchi 	}
679*9a4a12bdSRobert Mustacchi 
680*9a4a12bdSRobert Mustacchi 	return (ret);
681*9a4a12bdSRobert Mustacchi }
682*9a4a12bdSRobert Mustacchi 
683*9a4a12bdSRobert Mustacchi static boolean_t
684*9a4a12bdSRobert Mustacchi c32rtomb_null(void)
685*9a4a12bdSRobert Mustacchi {
686*9a4a12bdSRobert Mustacchi 	size_t len;
687*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
688*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
689*9a4a12bdSRobert Mustacchi 
690*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
691*9a4a12bdSRobert Mustacchi 	len = c32rtomb(NULL, uchar_value, &mbs);
692*9a4a12bdSRobert Mustacchi 	if (len != 1) {
693*9a4a12bdSRobert Mustacchi 		warnx("c32rtomb returned %zd, expected %zd", len, 1);
694*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
695*9a4a12bdSRobert Mustacchi 	}
696*9a4a12bdSRobert Mustacchi 
697*9a4a12bdSRobert Mustacchi 	return (ret);
698*9a4a12bdSRobert Mustacchi }
699*9a4a12bdSRobert Mustacchi 
700*9a4a12bdSRobert Mustacchi static boolean_t
701*9a4a12bdSRobert Mustacchi c16rtomb_null(void)
702*9a4a12bdSRobert Mustacchi {
703*9a4a12bdSRobert Mustacchi 	size_t len;
704*9a4a12bdSRobert Mustacchi 	mbstate_t mbs;
705*9a4a12bdSRobert Mustacchi 	boolean_t ret = B_TRUE;
706*9a4a12bdSRobert Mustacchi 
707*9a4a12bdSRobert Mustacchi 	bzero(&mbs, sizeof (mbs));
708*9a4a12bdSRobert Mustacchi 	len = c16rtomb(NULL, uchar_value, &mbs);
709*9a4a12bdSRobert Mustacchi 	if (len != 1) {
710*9a4a12bdSRobert Mustacchi 		warnx("c16rtomb returned %zd, expected %zd", len, 1);
711*9a4a12bdSRobert Mustacchi 		ret = B_FALSE;
712*9a4a12bdSRobert Mustacchi 	}
713*9a4a12bdSRobert Mustacchi 
714*9a4a12bdSRobert Mustacchi 	return (ret);
715*9a4a12bdSRobert Mustacchi }
716*9a4a12bdSRobert Mustacchi 
717*9a4a12bdSRobert Mustacchi typedef boolean_t (*uchar_test_f)(void);
718*9a4a12bdSRobert Mustacchi 
719*9a4a12bdSRobert Mustacchi typedef struct uchar_test {
720*9a4a12bdSRobert Mustacchi 	uchar_test_f	ut_func;
721*9a4a12bdSRobert Mustacchi 	const char	*ut_test;
722*9a4a12bdSRobert Mustacchi 	const char	*ut_locale;
723*9a4a12bdSRobert Mustacchi } uchar_test_t;
724*9a4a12bdSRobert Mustacchi 
725*9a4a12bdSRobert Mustacchi static const uchar_test_t uchar_tests[] = {
726*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_ascii_mbstate, "mbrtoc32: ascii conversion" },
727*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_ascii_internal, "mbrtoc32: ascii conversion (internal "
728*9a4a12bdSRobert Mustacchi 	    "mbstate_t)" },
729*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_badseq_utf8, "mbrtoc32: bad locale sequence (UTF-8)" },
730*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_roundtrip, "mbrtoc32: round trip conversion" },
731*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_partial, "mbrtoc32: correctly consume partial sequences" },
732*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_zero, "mbrtoc32: correctly handle L'\\0'" },
733*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_zero_len, "mbrtoc32: correctly handle length of zero" },
734*9a4a12bdSRobert Mustacchi 	{ mbrtoc32_null, "mbrtoc32: correctly handle null string" },
735*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_ascii_mbstate, "mbrtoc16: ascii conversion" },
736*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_ascii_internal, "mbrtoc16: ascii conversion (internal "
737*9a4a12bdSRobert Mustacchi 	    "mbstate_t)" },
738*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_null, "mbrtoc16: correctly handle null string" },
739*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_zero, "mbrtoc16: correctly handle L'\\0'" },
740*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_zero_len, "mbrtoc16: correctly handle length of zero" },
741*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_roundtrip, "mbrtoc16: round trip conversion" },
742*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_partial, "mbrtoc16: correctly consume partial sequences" },
743*9a4a12bdSRobert Mustacchi 	{ mbrtoc16_surrogate, "mbrtoc16: correctly generate surrogate pairs "
744*9a4a12bdSRobert Mustacchi 	    "and round trip conversion" },
745*9a4a12bdSRobert Mustacchi 	{ c32rtomb_eilseq_iso8859, "c32rtomb: character outside of locale is "
746*9a4a12bdSRobert Mustacchi 	    "caught", "en_US.ISO8859-1" },
747*9a4a12bdSRobert Mustacchi 	{ c16rtomb_eilseq_iso8859, "c16rtomb: character outside of locale is "
748*9a4a12bdSRobert Mustacchi 	    "caught", "en_US.ISO8859-1" },
749*9a4a12bdSRobert Mustacchi 	{ c32rtomb_eilseq_utf8, "c32rtomb: character outside of locale is "
750*9a4a12bdSRobert Mustacchi 	    "caught" },
751*9a4a12bdSRobert Mustacchi 	{ c16rtomb_bad_first, "c16rtomb: bad first surrogate pair" },
752*9a4a12bdSRobert Mustacchi 	{ c16rtomb_bad_second, "c16rtomb: bad second surrogate pair" },
753*9a4a12bdSRobert Mustacchi 	{ c32rtomb_null, "c32rtomb: correctly handle null buffer" },
754*9a4a12bdSRobert Mustacchi 	{ c16rtomb_null, "c16rtomb: correctly handle null buffer" },
755*9a4a12bdSRobert Mustacchi };
756*9a4a12bdSRobert Mustacchi 
757*9a4a12bdSRobert Mustacchi int
758*9a4a12bdSRobert Mustacchi main(void)
759*9a4a12bdSRobert Mustacchi {
760*9a4a12bdSRobert Mustacchi 	uint_t i;
761*9a4a12bdSRobert Mustacchi 	uint_t passes = 0;
762*9a4a12bdSRobert Mustacchi 	uint_t ntests = ARRAY_SIZE(uchar_tests);
763*9a4a12bdSRobert Mustacchi 
764*9a4a12bdSRobert Mustacchi 	for (i = 0; i < ntests; i++) {
765*9a4a12bdSRobert Mustacchi 		boolean_t r;
766*9a4a12bdSRobert Mustacchi 
767*9a4a12bdSRobert Mustacchi 		/*
768*9a4a12bdSRobert Mustacchi 		 * Default to a standard UTF-8 locale if none is requested by
769*9a4a12bdSRobert Mustacchi 		 * the test.
770*9a4a12bdSRobert Mustacchi 		 */
771*9a4a12bdSRobert Mustacchi 		if (uchar_tests[i].ut_locale != NULL) {
772*9a4a12bdSRobert Mustacchi 			update_locale(uchar_tests[i].ut_locale);
773*9a4a12bdSRobert Mustacchi 		} else {
774*9a4a12bdSRobert Mustacchi 			update_locale("en_US.UTF-8");
775*9a4a12bdSRobert Mustacchi 		}
776*9a4a12bdSRobert Mustacchi 
777*9a4a12bdSRobert Mustacchi 		r = uchar_tests[i].ut_func();
778*9a4a12bdSRobert Mustacchi 		(void) fprintf(stderr, "TEST %s: %s\n", r ? "PASSED" : "FAILED",
779*9a4a12bdSRobert Mustacchi 		    uchar_tests[i].ut_test);
780*9a4a12bdSRobert Mustacchi 		if (r) {
781*9a4a12bdSRobert Mustacchi 			passes++;
782*9a4a12bdSRobert Mustacchi 		}
783*9a4a12bdSRobert Mustacchi 	}
784*9a4a12bdSRobert Mustacchi 
785*9a4a12bdSRobert Mustacchi 	(void) printf("%d/%d test%s passed\n", passes, ntests,
786*9a4a12bdSRobert Mustacchi 	    passes > 1 ? "s" : "");
787*9a4a12bdSRobert Mustacchi 	return (passes == ntests ? EXIT_SUCCESS : EXIT_FAILURE);
788*9a4a12bdSRobert Mustacchi 
789*9a4a12bdSRobert Mustacchi }
790