1 1.5 perseant /* $NetBSD: t_wctomb.c,v 1.5 2017/07/12 17:32:51 perseant Exp $ */ 2 1.1 pgoyette 3 1.1 pgoyette /*- 4 1.1 pgoyette * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.1 pgoyette * All rights reserved. 6 1.1 pgoyette * 7 1.1 pgoyette * Redistribution and use in source and binary forms, with or without 8 1.1 pgoyette * modification, are permitted provided that the following conditions 9 1.1 pgoyette * are met: 10 1.1 pgoyette * 1. Redistributions of source code must retain the above copyright 11 1.1 pgoyette * notice, this list of conditions and the following disclaimer. 12 1.1 pgoyette * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 pgoyette * notice, this list of conditions and the following disclaimer in the 14 1.1 pgoyette * documentation and/or other materials provided with the distribution. 15 1.1 pgoyette * 16 1.1 pgoyette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 pgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 pgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 pgoyette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 pgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 pgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 pgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 pgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 pgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 pgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 pgoyette * POSSIBILITY OF SUCH DAMAGE. 27 1.1 pgoyette */ 28 1.1 pgoyette 29 1.1 pgoyette /*- 30 1.1 pgoyette * Copyright (c)2004 Citrus Project, 31 1.1 pgoyette * All rights reserved. 32 1.1 pgoyette * 33 1.1 pgoyette * Redistribution and use in source and binary forms, with or without 34 1.1 pgoyette * modification, are permitted provided that the following conditions 35 1.1 pgoyette * are met: 36 1.1 pgoyette * 1. Redistributions of source code must retain the above copyright 37 1.1 pgoyette * notice, this list of conditions and the following disclaimer. 38 1.1 pgoyette * 2. Redistributions in binary form must reproduce the above copyright 39 1.1 pgoyette * notice, this list of conditions and the following disclaimer in the 40 1.1 pgoyette * documentation and/or other materials provided with the distribution. 41 1.1 pgoyette * 42 1.1 pgoyette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 43 1.1 pgoyette * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44 1.1 pgoyette * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45 1.1 pgoyette * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 46 1.1 pgoyette * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47 1.1 pgoyette * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48 1.1 pgoyette * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49 1.1 pgoyette * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50 1.1 pgoyette * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51 1.1 pgoyette * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 1.1 pgoyette * SUCH DAMAGE. 53 1.1 pgoyette */ 54 1.1 pgoyette 55 1.1 pgoyette #include <sys/cdefs.h> 56 1.1 pgoyette __COPYRIGHT("@(#) Copyright (c) 2011\ 57 1.1 pgoyette The NetBSD Foundation, inc. All rights reserved."); 58 1.5 perseant __RCSID("$NetBSD: t_wctomb.c,v 1.5 2017/07/12 17:32:51 perseant Exp $"); 59 1.1 pgoyette 60 1.1 pgoyette #include <stdio.h> 61 1.1 pgoyette #include <stdlib.h> 62 1.1 pgoyette #include <locale.h> 63 1.1 pgoyette #include <vis.h> 64 1.1 pgoyette #include <wchar.h> 65 1.1 pgoyette #include <string.h> 66 1.3 gson #include <limits.h> 67 1.1 pgoyette 68 1.1 pgoyette #include <atf-c.h> 69 1.1 pgoyette 70 1.1 pgoyette #define TC_WCTOMB 0 71 1.1 pgoyette #define TC_WCRTOMB 1 72 1.1 pgoyette #define TC_WCRTOMB_ST 2 73 1.1 pgoyette 74 1.1 pgoyette static struct test { 75 1.1 pgoyette const char *locale; 76 1.1 pgoyette const char *data; 77 1.1 pgoyette size_t wclen; 78 1.1 pgoyette size_t mblen[16]; 79 1.4 perseant size_t stateful; 80 1.1 pgoyette } tests[] = { 81 1.1 pgoyette { 82 1.1 pgoyette "ja_JP.ISO2022-JP", 83 1.1 pgoyette "\x1b$B" /* JIS X 0208-1983 */ 84 1.1 pgoyette "\x46\x7c\x4b\x5c\x38\x6c" /* "nihongo" */ 85 1.1 pgoyette "\x1b(B" /* ISO 646 */ 86 1.1 pgoyette "ABC" 87 1.1 pgoyette "\x1b(I" /* JIS X 0201 katakana */ 88 1.1 pgoyette "\xb1\xb2\xb3" /* "aiu" */ 89 1.1 pgoyette "\x1b(B", /* ISO 646 */ 90 1.1 pgoyette 3 + 3 + 3, 91 1.4 perseant { 3+2, 2, 2, 3+1, 1, 1, 3+1, 1, 1, 3+1 }, 92 1.4 perseant 1, 93 1.1 pgoyette }, { 94 1.1 pgoyette "C", 95 1.1 pgoyette "ABC", 96 1.1 pgoyette 3, 97 1.4 perseant { 1, 1, 1, 1 }, 98 1.4 perseant 0, 99 1.4 perseant }, { NULL, NULL, 0, { }, 0 } 100 1.1 pgoyette }; 101 1.1 pgoyette 102 1.1 pgoyette static void 103 1.1 pgoyette h_wctomb(const struct test *t, char tc) 104 1.1 pgoyette { 105 1.1 pgoyette wchar_t wcs[16 + 2]; 106 1.1 pgoyette char buf[128]; 107 1.3 gson char cs[MB_LEN_MAX]; 108 1.1 pgoyette const char *pcs; 109 1.1 pgoyette char *str; 110 1.1 pgoyette mbstate_t st; 111 1.1 pgoyette mbstate_t *stp = NULL; 112 1.1 pgoyette size_t sz, ret, i; 113 1.1 pgoyette 114 1.1 pgoyette ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); 115 1.4 perseant (void)printf("Trying locale: %s\n", t->locale); 116 1.1 pgoyette ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); 117 1.1 pgoyette 118 1.4 perseant if (tc == TC_WCRTOMB_ST) { 119 1.4 perseant (void)memset(&st, 0, sizeof(st)); 120 1.4 perseant stp = &st; 121 1.4 perseant } else { 122 1.4 perseant (void)printf("Checking correct reporting of statefulness\n"); 123 1.4 perseant ret = wctomb(NULL, 0); 124 1.4 perseant ATF_REQUIRE_EQ(t->stateful, !!ret); 125 1.4 perseant } 126 1.4 perseant 127 1.1 pgoyette (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); 128 1.1 pgoyette (void)printf("Checking sequence: \"%s\"\n", buf); 129 1.1 pgoyette 130 1.1 pgoyette ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); 131 1.1 pgoyette (void)printf("Using locale: %s\n", str); 132 1.1 pgoyette 133 1.1 pgoyette wcs[t->wclen] = L'X'; /* poison */ 134 1.1 pgoyette pcs = t->data; 135 1.1 pgoyette sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL); 136 1.1 pgoyette ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: " 137 1.2 christos "%zu, expected: %zu", sz, t->wclen); 138 1.1 pgoyette ATF_REQUIRE_EQ(wcs[t->wclen], 0); 139 1.1 pgoyette 140 1.1 pgoyette for (i = 0; i < t->wclen + 1; i++) { 141 1.1 pgoyette if (tc == TC_WCTOMB) 142 1.1 pgoyette ret = wctomb(cs, wcs[i]); 143 1.1 pgoyette else 144 1.1 pgoyette ret = wcrtomb(cs, wcs[i], stp); 145 1.1 pgoyette 146 1.1 pgoyette if (ret == t->mblen[i]) 147 1.1 pgoyette continue; 148 1.1 pgoyette 149 1.1 pgoyette (void)printf("At position %zd:\n", i); 150 1.1 pgoyette (void)printf(" expected: %zd\n", t->mblen[i]); 151 1.1 pgoyette (void)printf(" got : %zd\n", ret); 152 1.5 perseant (void)strvis(buf, cs, VIS_WHITE | VIS_OCTAL); 153 1.5 perseant (void)printf(" sequence: \"%s\"\n", buf); 154 1.1 pgoyette atf_tc_fail("Test failed"); 155 1.1 pgoyette /* NOTREACHED */ 156 1.1 pgoyette } 157 1.1 pgoyette 158 1.1 pgoyette (void)printf("Ok.\n"); 159 1.1 pgoyette } 160 1.1 pgoyette 161 1.1 pgoyette ATF_TC(wctomb); 162 1.1 pgoyette ATF_TC_HEAD(wctomb, tc) 163 1.1 pgoyette { 164 1.1 pgoyette atf_tc_set_md_var(tc, "descr", "Checks wctomb(3)"); 165 1.1 pgoyette } 166 1.1 pgoyette ATF_TC_BODY(wctomb, tc) 167 1.1 pgoyette { 168 1.1 pgoyette struct test *t; 169 1.1 pgoyette 170 1.1 pgoyette (void)printf("Checking wctomb()\n"); 171 1.1 pgoyette 172 1.1 pgoyette for (t = &tests[0]; t->data != NULL; ++t) 173 1.1 pgoyette h_wctomb(t, TC_WCTOMB); 174 1.1 pgoyette } 175 1.1 pgoyette 176 1.1 pgoyette ATF_TC(wcrtomb_state); 177 1.1 pgoyette ATF_TC_HEAD(wcrtomb_state, tc) 178 1.1 pgoyette { 179 1.1 pgoyette atf_tc_set_md_var(tc, "descr", 180 1.1 pgoyette "Checks wcrtomb(3) (using state object)"); 181 1.1 pgoyette } 182 1.1 pgoyette ATF_TC_BODY(wcrtomb_state, tc) 183 1.1 pgoyette { 184 1.1 pgoyette struct test *t; 185 1.1 pgoyette 186 1.1 pgoyette (void)printf("Checking wcrtomb() (with state object)\n"); 187 1.1 pgoyette 188 1.1 pgoyette for (t = &tests[0]; t->data != NULL; ++t) 189 1.1 pgoyette h_wctomb(t, TC_WCRTOMB_ST); 190 1.1 pgoyette } 191 1.1 pgoyette 192 1.1 pgoyette ATF_TC(wcrtomb); 193 1.1 pgoyette ATF_TC_HEAD(wcrtomb, tc) 194 1.1 pgoyette { 195 1.1 pgoyette atf_tc_set_md_var(tc, "descr", 196 1.1 pgoyette "Checks wcrtomb(3) (using internal state)"); 197 1.1 pgoyette } 198 1.1 pgoyette ATF_TC_BODY(wcrtomb, tc) 199 1.1 pgoyette { 200 1.1 pgoyette struct test *t; 201 1.1 pgoyette 202 1.1 pgoyette (void)printf("Checking wcrtomb() (using internal state)\n"); 203 1.1 pgoyette 204 1.1 pgoyette for (t = &tests[0]; t->data != NULL; ++t) 205 1.1 pgoyette h_wctomb(t, TC_WCRTOMB); 206 1.1 pgoyette } 207 1.1 pgoyette 208 1.1 pgoyette ATF_TP_ADD_TCS(tp) 209 1.1 pgoyette { 210 1.1 pgoyette ATF_TP_ADD_TC(tp, wctomb); 211 1.1 pgoyette ATF_TP_ADD_TC(tp, wcrtomb); 212 1.1 pgoyette ATF_TP_ADD_TC(tp, wcrtomb_state); 213 1.1 pgoyette 214 1.1 pgoyette return atf_no_error(); 215 1.1 pgoyette } 216