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
update_locale(const char * loc)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
mbrtoc32_ascii(mbstate_t * mbs)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
mbrtoc32_ascii_internal(void)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
mbrtoc32_ascii_mbstate(void)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
mbrtoc32_badseq_utf8(void)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
mbrtoc32_roundtrip(void)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
mbrtoc32_partial(void)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
mbrtoc32_zero(void)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
mbrtoc32_zero_len(void)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
mbrtoc32_null(void)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
mbrtoc16_ascii(mbstate_t * mbs)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
mbrtoc16_ascii_internal(void)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
mbrtoc16_ascii_mbstate(void)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
mbrtoc16_null(void)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
mbrtoc16_zero(void)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
mbrtoc16_zero_len(void)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
mbrtoc16_roundtrip(void)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
mbrtoc16_partial(void)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
mbrtoc16_surrogate(void)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
c32rtomb_eilseq_iso8859(void)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
c16rtomb_eilseq_iso8859(void)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
c32rtomb_eilseq_utf8(void)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
c16rtomb_bad_first(void)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
c16rtomb_bad_second(void)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
c32rtomb_null(void)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
c16rtomb_null(void)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
main(void)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