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