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