157718be8SEnji Cooper /* $NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */
257718be8SEnji Cooper
357718be8SEnji Cooper /*-
457718be8SEnji Cooper * Copyright (c) 2011 The NetBSD Foundation, Inc.
557718be8SEnji Cooper * All rights reserved.
657718be8SEnji Cooper *
757718be8SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation
857718be8SEnji Cooper * by YAMAMOTO Takashi
957718be8SEnji Cooper *
1057718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without
1157718be8SEnji Cooper * modification, are permitted provided that the following conditions
1257718be8SEnji Cooper * are met:
1357718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright
1457718be8SEnji Cooper * notice, this list of conditions and the following disclaimer.
1557718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
1657718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the
1757718be8SEnji Cooper * documentation and/or other materials provided with the distribution.
1857718be8SEnji Cooper *
1957718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2057718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2157718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2257718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2357718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2457718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2557718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2657718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2757718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2857718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2957718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE.
3057718be8SEnji Cooper */
3157718be8SEnji Cooper
3257718be8SEnji Cooper /*-
3357718be8SEnji Cooper * Copyright (c)2003 Citrus Project,
3457718be8SEnji Cooper * All rights reserved.
3557718be8SEnji Cooper *
3657718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without
3757718be8SEnji Cooper * modification, are permitted provided that the following conditions
3857718be8SEnji Cooper * are met:
3957718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright
4057718be8SEnji Cooper * notice, this list of conditions and the following disclaimer.
4157718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
4257718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the
4357718be8SEnji Cooper * documentation and/or other materials provided with the distribution.
4457718be8SEnji Cooper *
4557718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4657718be8SEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4757718be8SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4857718be8SEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4957718be8SEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5057718be8SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5157718be8SEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5257718be8SEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5357718be8SEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5457718be8SEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5557718be8SEnji Cooper * SUCH DAMAGE.
5657718be8SEnji Cooper */
5757718be8SEnji Cooper
5857718be8SEnji Cooper #include <sys/cdefs.h>
5957718be8SEnji Cooper __COPYRIGHT("@(#) Copyright (c) 2011\
6057718be8SEnji Cooper The NetBSD Foundation, inc. All rights reserved.");
6157718be8SEnji Cooper __RCSID("$NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $");
6257718be8SEnji Cooper
6357718be8SEnji Cooper #include <errno.h>
6457718be8SEnji Cooper #include <locale.h>
6557718be8SEnji Cooper #include <stdio.h>
6657718be8SEnji Cooper #include <stdlib.h>
6757718be8SEnji Cooper #include <string.h>
6857718be8SEnji Cooper #include <vis.h>
6957718be8SEnji Cooper #include <wchar.h>
7057718be8SEnji Cooper
7157718be8SEnji Cooper #include <atf-c.h>
7257718be8SEnji Cooper
7357718be8SEnji Cooper #define SIZE 256
7457718be8SEnji Cooper
7557718be8SEnji Cooper static struct test {
7657718be8SEnji Cooper const char *locale;
7757718be8SEnji Cooper const char *data;
7857718be8SEnji Cooper const wchar_t wchars[64];
7957718be8SEnji Cooper const wchar_t widths[64];
8057718be8SEnji Cooper size_t length;
8157718be8SEnji Cooper } tests[] = {
8257718be8SEnji Cooper {
8357718be8SEnji Cooper "C",
8457718be8SEnji Cooper "ABCD01234_\\",
8557718be8SEnji Cooper { 0x41, 0x42, 0x43, 0x44, 0x30, 0x31, 0x32, 0x33, 0x34, 0x5F, 0x5C },
8657718be8SEnji Cooper { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
8757718be8SEnji Cooper 11
8857718be8SEnji Cooper }, {
8957718be8SEnji Cooper "en_US.UTF-8",
9057718be8SEnji Cooper "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200"
91*5e0069c6SJilles Tjoelker "\200\364\217\277\277]",
9257718be8SEnji Cooper { 0x5b, 0x01, 0x7f, 0x5d, 0x5b, 0x80, 0x7ff, 0x5d, 0x5b, 0x800, 0xffff,
93*5e0069c6SJilles Tjoelker 0x5d, 0x5b, 0x10000, 0x10ffff, 0x5d },
94*5e0069c6SJilles Tjoelker { 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1 },
95*5e0069c6SJilles Tjoelker 16
9657718be8SEnji Cooper }, {
9757718be8SEnji Cooper "ja_JP.ISO2022-JP2",
9857718be8SEnji Cooper "\033$BF|K\1348l\033(BA\033$B$\"\033(BB\033$B$$\033(B",
9957718be8SEnji Cooper { 0x4200467c, 0x42004b5c, 0x4200386c, 0x41, 0x42002422, 0x42, 0x42002424 },
10057718be8SEnji Cooper { 5, 2, 2, 4, 5, 4, 5 },
10157718be8SEnji Cooper 7
10257718be8SEnji Cooper }, {
10357718be8SEnji Cooper "ja_JP.SJIS",
10457718be8SEnji Cooper "\223\372\226{\214\352A\202\240B\202\242",
10557718be8SEnji Cooper { 0x93fa, 0x967b, 0x8cea, 0x41, 0x82a0, 0x42, 0x82a2 },
10657718be8SEnji Cooper { 2, 2, 2, 1, 2, 1, 2 },
10757718be8SEnji Cooper 7
10857718be8SEnji Cooper }, {
10957718be8SEnji Cooper "ja_JP.eucJP",
11057718be8SEnji Cooper "\306\374\313\334\270\354A\244\242B\244\244",
11157718be8SEnji Cooper { 0xc6fc, 0xcbdc, 0xb8ec, 0x41, 0xa4a2, 0x42, 0xa4a4 },
11257718be8SEnji Cooper { 2, 2, 2, 1, 2, 1, 2 },
11357718be8SEnji Cooper 7
11457718be8SEnji Cooper }, {
11557718be8SEnji Cooper NULL,
11657718be8SEnji Cooper NULL,
11757718be8SEnji Cooper { },
11857718be8SEnji Cooper { },
11957718be8SEnji Cooper 0
12057718be8SEnji Cooper }
12157718be8SEnji Cooper };
12257718be8SEnji Cooper
12357718be8SEnji Cooper static void
h_ctype2(const struct test * t,bool use_mbstate)12457718be8SEnji Cooper h_ctype2(const struct test *t, bool use_mbstate)
12557718be8SEnji Cooper {
12657718be8SEnji Cooper mbstate_t *stp;
12757718be8SEnji Cooper mbstate_t st;
12857718be8SEnji Cooper char buf[SIZE];
12957718be8SEnji Cooper char *str;
13057718be8SEnji Cooper size_t n;
13157718be8SEnji Cooper
13257718be8SEnji Cooper ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
133ff0ba872SEnji Cooper #ifdef __NetBSD__
13457718be8SEnji Cooper ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
135effc3698SEnji Cooper #else
136effc3698SEnji Cooper if (setlocale(LC_CTYPE, t->locale) == NULL) {
137effc3698SEnji Cooper fprintf(stderr, "Locale %s not found.\n", t->locale);
138effc3698SEnji Cooper return;
139effc3698SEnji Cooper }
140effc3698SEnji Cooper #endif
14157718be8SEnji Cooper
14257718be8SEnji Cooper (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL);
14357718be8SEnji Cooper (void)printf("Checking string: \"%s\"\n", buf);
14457718be8SEnji Cooper
14557718be8SEnji Cooper ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
14657718be8SEnji Cooper (void)printf("Using locale: %s\n", str);
14757718be8SEnji Cooper
14857718be8SEnji Cooper (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no");
14957718be8SEnji Cooper
15057718be8SEnji Cooper (void)memset(&st, 0, sizeof(st));
15157718be8SEnji Cooper // mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */
15257718be8SEnji Cooper stp = use_mbstate ? &st : 0;
15357718be8SEnji Cooper
15457718be8SEnji Cooper for (n = 9; n > 0; n--) {
15557718be8SEnji Cooper const char *src = t->data;
15657718be8SEnji Cooper wchar_t dst;
15757718be8SEnji Cooper size_t nchar = 0;
15857718be8SEnji Cooper int width = 0;
15957718be8SEnji Cooper
16057718be8SEnji Cooper ATF_REQUIRE(mbsinit(stp) != 0);
16157718be8SEnji Cooper
16257718be8SEnji Cooper for (;;) {
16357718be8SEnji Cooper size_t rv = mbrtowc(&dst, src, n, stp);
16457718be8SEnji Cooper
16557718be8SEnji Cooper if (rv == 0)
16657718be8SEnji Cooper break;
16757718be8SEnji Cooper
16857718be8SEnji Cooper if (rv == (size_t)-2) {
16957718be8SEnji Cooper src += n;
17057718be8SEnji Cooper width += n;
17157718be8SEnji Cooper
17257718be8SEnji Cooper continue;
17357718be8SEnji Cooper }
17457718be8SEnji Cooper if (rv == (size_t)-1) {
17557718be8SEnji Cooper ATF_REQUIRE_EQ(errno, EILSEQ);
17657718be8SEnji Cooper atf_tc_fail("Invalid sequence");
17757718be8SEnji Cooper /* NOTREACHED */
17857718be8SEnji Cooper }
17957718be8SEnji Cooper
18057718be8SEnji Cooper width += rv;
18157718be8SEnji Cooper src += rv;
18257718be8SEnji Cooper
18357718be8SEnji Cooper if (dst != t->wchars[nchar] ||
18457718be8SEnji Cooper width != t->widths[nchar]) {
18557718be8SEnji Cooper (void)printf("At position %zd:\n", nchar);
18657718be8SEnji Cooper (void)printf(" expected: 0x%04X (%u)\n",
18757718be8SEnji Cooper t->wchars[nchar], t->widths[nchar]);
18857718be8SEnji Cooper (void)printf(" got : 0x%04X (%u)\n",
18957718be8SEnji Cooper dst, width);
19057718be8SEnji Cooper atf_tc_fail("Test failed");
19157718be8SEnji Cooper }
19257718be8SEnji Cooper
19357718be8SEnji Cooper nchar++;
19457718be8SEnji Cooper width = 0;
19557718be8SEnji Cooper }
19657718be8SEnji Cooper
19757718be8SEnji Cooper ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: "
19857718be8SEnji Cooper "0x%04X (expected: 0x00)", dst);
19957718be8SEnji Cooper
20057718be8SEnji Cooper ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: "
20157718be8SEnji Cooper "%zd (expected: %zd)", nchar, t->length);
20257718be8SEnji Cooper }
20357718be8SEnji Cooper
20457718be8SEnji Cooper {
20557718be8SEnji Cooper wchar_t wbuf[SIZE];
20657718be8SEnji Cooper size_t rv;
20757718be8SEnji Cooper char const *src = t->data;
20857718be8SEnji Cooper int i;
20957718be8SEnji Cooper
21057718be8SEnji Cooper (void)memset(wbuf, 0xFF, sizeof(wbuf));
21157718be8SEnji Cooper
21257718be8SEnji Cooper rv = mbsrtowcs(wbuf, &src, SIZE, stp);
21357718be8SEnji Cooper
21457718be8SEnji Cooper ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd "
21557718be8SEnji Cooper "(expected: %zd)", rv, t->length);
21657718be8SEnji Cooper ATF_REQUIRE_EQ(src, NULL);
21757718be8SEnji Cooper
21857718be8SEnji Cooper for (i = 0; wbuf[i] != 0; ++i) {
21957718be8SEnji Cooper if (wbuf[i] == t->wchars[i])
22057718be8SEnji Cooper continue;
22157718be8SEnji Cooper
22257718be8SEnji Cooper (void)printf("At position %d:\n", i);
22357718be8SEnji Cooper (void)printf(" expected: 0x%04X\n", t->wchars[i]);
22457718be8SEnji Cooper (void)printf(" got : 0x%04X\n", wbuf[i]);
22557718be8SEnji Cooper atf_tc_fail("Test failed");
22657718be8SEnji Cooper }
22757718be8SEnji Cooper
22857718be8SEnji Cooper ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: "
22957718be8SEnji Cooper "%d (expected: %zd)", i, t->length);
23057718be8SEnji Cooper }
23157718be8SEnji Cooper
23257718be8SEnji Cooper (void)printf("Ok.\n");
23357718be8SEnji Cooper }
23457718be8SEnji Cooper
23557718be8SEnji Cooper ATF_TC(mbrtowc_internal);
ATF_TC_HEAD(mbrtowc_internal,tc)23657718be8SEnji Cooper ATF_TC_HEAD(mbrtowc_internal, tc)
23757718be8SEnji Cooper {
23857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
23957718be8SEnji Cooper "Checks mbrtowc(3) and mbsrtowcs(3) (using internal "
24057718be8SEnji Cooper "state) with different locales");
24157718be8SEnji Cooper }
ATF_TC_BODY(mbrtowc_internal,tc)24257718be8SEnji Cooper ATF_TC_BODY(mbrtowc_internal, tc)
24357718be8SEnji Cooper {
24457718be8SEnji Cooper struct test *t;
24557718be8SEnji Cooper
24657718be8SEnji Cooper for (t = &tests[0]; t->data != NULL; ++t)
24757718be8SEnji Cooper h_ctype2(t, false);
24857718be8SEnji Cooper }
24957718be8SEnji Cooper
25057718be8SEnji Cooper ATF_TC(mbrtowc_object);
ATF_TC_HEAD(mbrtowc_object,tc)25157718be8SEnji Cooper ATF_TC_HEAD(mbrtowc_object, tc)
25257718be8SEnji Cooper {
25357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
25457718be8SEnji Cooper "Checks mbrtowc(3) and mbsrtowcs(3) (using state "
25557718be8SEnji Cooper "object) with different locales");
25657718be8SEnji Cooper }
ATF_TC_BODY(mbrtowc_object,tc)25757718be8SEnji Cooper ATF_TC_BODY(mbrtowc_object, tc)
25857718be8SEnji Cooper {
25957718be8SEnji Cooper struct test *t;
26057718be8SEnji Cooper
26157718be8SEnji Cooper for (t = &tests[0]; t->data != NULL; ++t)
26257718be8SEnji Cooper h_ctype2(t, true);
26357718be8SEnji Cooper }
26457718be8SEnji Cooper
ATF_TP_ADD_TCS(tp)26557718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
26657718be8SEnji Cooper {
26757718be8SEnji Cooper
26857718be8SEnji Cooper ATF_TP_ADD_TC(tp, mbrtowc_internal);
26957718be8SEnji Cooper ATF_TP_ADD_TC(tp, mbrtowc_object);
27057718be8SEnji Cooper
27157718be8SEnji Cooper return atf_no_error();
27257718be8SEnji Cooper }
273