mbsnrtowcs_test.c revision 291178
1109998Smarkm/*-
2109998Smarkm * Copyright (c) 2002-2004 Tim J. Robbins
3109998Smarkm * All rights reserved.
4109998Smarkm *
5109998Smarkm * Redistribution and use in source and binary forms, with or without
6109998Smarkm * modification, are permitted provided that the following conditions
7109998Smarkm * are met:
8109998Smarkm * 1. Redistributions of source code must retain the above copyright
9109998Smarkm *    notice, this list of conditions and the following disclaimer.
10109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
11109998Smarkm *    notice, this list of conditions and the following disclaimer in the
12109998Smarkm *    documentation and/or other materials provided with the distribution.
13109998Smarkm *
14109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17109998Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18109998Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19109998Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23109998Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24109998Smarkm * SUCH DAMAGE.
25109998Smarkm */
26109998Smarkm
27109998Smarkm/*
28109998Smarkm * Test program for mbsnrtowcs().
29109998Smarkm *
30109998Smarkm * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
31109998Smarkm * "ja_JP.eucJP". Other encodings are not tested.
32109998Smarkm */
33109998Smarkm
34109998Smarkm#include <sys/cdefs.h>
35109998Smarkm__FBSDID("$FreeBSD: stable/10/lib/libc/tests/locale/mbsnrtowcs_test.c 291178 2015-11-23 08:31:41Z ngie $");
36109998Smarkm
37109998Smarkm#include <errno.h>
38109998Smarkm#include <limits.h>
39109998Smarkm#include <locale.h>
40109998Smarkm#include <stdio.h>
41109998Smarkm#include <stdlib.h>
42109998Smarkm#include <string.h>
43109998Smarkm#include <wchar.h>
44109998Smarkm
45109998Smarkm#include <atf-c.h>
46109998Smarkm
47109998SmarkmATF_TC_WITHOUT_HEAD(mbsnrtowcs_test);
48109998SmarkmATF_TC_BODY(mbsnrtowcs_test, tc)
49109998Smarkm{
50109998Smarkm	char srcbuf[128];
51109998Smarkm	wchar_t dstbuf[128];
52109998Smarkm	char *src;
53109998Smarkm	mbstate_t s;
54109998Smarkm
55109998Smarkm	/* C/POSIX locale. */
56109998Smarkm
57109998Smarkm	/* Simple null terminated string. */
58109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
59109998Smarkm	strcpy(srcbuf, "hello");
60109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
61109998Smarkm	src = srcbuf;
62109998Smarkm	memset(&s, 0, sizeof(s));
63109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
64109998Smarkm	    sizeof(*dstbuf), &s) == 5);
65109998Smarkm	ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
66109998Smarkm	ATF_REQUIRE(dstbuf[6] == 0xcccc);
67109998Smarkm	ATF_REQUIRE(src == NULL);
68109998Smarkm
69109998Smarkm	/* Simple null terminated string, stopping early. */
70109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
71109998Smarkm	strcpy(srcbuf, "hello");
72109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
73109998Smarkm	src = srcbuf;
74109998Smarkm	memset(&s, 0, sizeof(s));
75109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 4, sizeof(dstbuf) /
76109998Smarkm	    sizeof(*dstbuf), &s) == 4);
77109998Smarkm	ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
78109998Smarkm	ATF_REQUIRE(dstbuf[5] == 0xcccc);
79109998Smarkm	ATF_REQUIRE(src == srcbuf + 4);
80109998Smarkm
81109998Smarkm	/* Not enough space in destination buffer. */
82109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
83109998Smarkm	strcpy(srcbuf, "hello");
84109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
85109998Smarkm	src = srcbuf;
86109998Smarkm	memset(&s, 0, sizeof(s));
87109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, 4, &s) == 4);
88109998Smarkm	ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
89109998Smarkm	ATF_REQUIRE(dstbuf[5] == 0xcccc);
90109998Smarkm	ATF_REQUIRE(src == srcbuf + 4);
91109998Smarkm
92109998Smarkm	/* Null terminated string, internal dest. buffer */
93109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
94160814Ssimon	strcpy(srcbuf, "hello");
95160814Ssimon	src = srcbuf;
96109998Smarkm	memset(&s, 0, sizeof(s));
97109998Smarkm	ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 6, 0, &s) == 5);
98109998Smarkm
99109998Smarkm	/* Null terminated string, internal dest. buffer, stopping early */
100109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
101109998Smarkm	strcpy(srcbuf, "hello");
102109998Smarkm	src = srcbuf;
103109998Smarkm	memset(&s, 0, sizeof(s));
104109998Smarkm	ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 4, 0, &s) == 4);
105109998Smarkm
106109998Smarkm	/* Null terminated string, internal state. */
107109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
108109998Smarkm	strcpy(srcbuf, "hello");
109109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
110109998Smarkm	src = srcbuf;
111109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
112109998Smarkm	    sizeof(*dstbuf), NULL) == 5);
113109998Smarkm	ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
114109998Smarkm	ATF_REQUIRE(dstbuf[6] == 0xcccc);
115109998Smarkm	ATF_REQUIRE(src == NULL);
116109998Smarkm
117109998Smarkm	/* Null terminated string, internal state, internal dest. buffer. */
118109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
119160814Ssimon	strcpy(srcbuf, "hello");
120160814Ssimon	src = srcbuf;
121160814Ssimon	ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 6, 0, NULL) == 5);
122160814Ssimon
123109998Smarkm	/* Empty source buffer. */
124109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
125109998Smarkm	srcbuf[0] = '\0';
126109998Smarkm	src = srcbuf;
127109998Smarkm	memset(&s, 0, sizeof(s));
128109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
129109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, 1, &s) == 0);
130109998Smarkm	ATF_REQUIRE(dstbuf[0] == 0);
131109998Smarkm	ATF_REQUIRE(dstbuf[1] == 0xcccc);
132109998Smarkm	ATF_REQUIRE(src == NULL);
133109998Smarkm
134109998Smarkm	/* Zero length destination buffer. */
135109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
136109998Smarkm	strcpy(srcbuf, "hello");
137109998Smarkm	src = srcbuf;
138109998Smarkm	memset(&s, 0, sizeof(s));
139109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
140109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, 0, &s) == 0);
141109998Smarkm	ATF_REQUIRE(dstbuf[0] == 0xcccc);
142109998Smarkm	ATF_REQUIRE(src == srcbuf);
143109998Smarkm
144109998Smarkm	/* Zero length source buffer. */
145109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
146109998Smarkm	src = srcbuf;
147109998Smarkm	memset(&s, 0, sizeof(s));
148109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
149109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 0, 1, &s) == 0);
150109998Smarkm	ATF_REQUIRE(dstbuf[0] == 0xcccc);
151109998Smarkm	ATF_REQUIRE(src == srcbuf);
152109998Smarkm
153109998Smarkm	/*
154109998Smarkm	 * Japanese (EUC) locale.
155109998Smarkm	 */
156109998Smarkm
157109998Smarkm	ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
158109998Smarkm	ATF_REQUIRE(MB_CUR_MAX > 1);
159109998Smarkm
160109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
161109998Smarkm	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
162109998Smarkm	src = srcbuf;
163109998Smarkm	memset(&s, 0, sizeof(s));
164109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
165109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 8, sizeof(dstbuf) /
166109998Smarkm	    sizeof(*dstbuf), &s) == 5);
167109998Smarkm	ATF_REQUIRE(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
168109998Smarkm	    dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
169109998Smarkm	ATF_REQUIRE(src == NULL);
170109998Smarkm
171109998Smarkm	/* Partial character. */
172109998Smarkm	memset(srcbuf, 0xcc, sizeof(srcbuf));
173109998Smarkm	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
174109998Smarkm	src = srcbuf;
175109998Smarkm	memset(&s, 0, sizeof(s));
176109998Smarkm	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
177109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
178160814Ssimon	    sizeof(*dstbuf), &s) == 4);
179109998Smarkm	ATF_REQUIRE(src == srcbuf + 6);
180109998Smarkm	ATF_REQUIRE(!mbsinit(&s));
181109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
182109998Smarkm	    sizeof(*dstbuf), &s) == 1);
183109998Smarkm	ATF_REQUIRE(src == srcbuf + 7);
184109998Smarkm	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
185109998Smarkm	    sizeof(*dstbuf), &s) == 0);
186109998Smarkm	ATF_REQUIRE(src == NULL);
187109998Smarkm}
188109998Smarkm
189109998SmarkmATF_TP_ADD_TCS(tp)
190109998Smarkm{
191109998Smarkm
192109998Smarkm	ATF_TP_ADD_TC(tp, mbsnrtowcs_test);
193109998Smarkm
194109998Smarkm	return (atf_no_error());
195109998Smarkm}
196109998Smarkm