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