mbsnrtowcs_test.c revision 291178
1200062Sed/*-
2200062Sed * Copyright (c) 2002-2004 Tim J. Robbins
3200062Sed * All rights reserved.
4200062Sed *
5200062Sed * Redistribution and use in source and binary forms, with or without
6200062Sed * modification, are permitted provided that the following conditions
7200062Sed * are met:
8200062Sed * 1. Redistributions of source code must retain the above copyright
9200062Sed *    notice, this list of conditions and the following disclaimer.
10200062Sed * 2. Redistributions in binary form must reproduce the above copyright
11200062Sed *    notice, this list of conditions and the following disclaimer in the
12200062Sed *    documentation and/or other materials provided with the distribution.
13200062Sed *
14200062Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15200062Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16200062Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17200062Sed * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18200062Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19200062Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20200062Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21200062Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22200062Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23200062Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24200062Sed * SUCH DAMAGE.
25200062Sed */
26200062Sed
27200062Sed/*
28200062Sed * Test program for mbsnrtowcs().
29200062Sed *
30202215Sed * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
31200153Sed * "ja_JP.eucJP". Other encodings are not tested.
32200062Sed */
33202215Sed
34200062Sed#include <sys/cdefs.h>
35202215Sed__FBSDID("$FreeBSD: stable/10/lib/libc/tests/locale/mbsnrtowcs_test.c 291178 2015-11-23 08:31:41Z ngie $");
36202215Sed
37202215Sed#include <errno.h>
38200062Sed#include <limits.h>
39202215Sed#include <locale.h>
40202215Sed#include <stdio.h>
41200062Sed#include <stdlib.h>
42202215Sed#include <string.h>
43202215Sed#include <wchar.h>
44200062Sed
45200062Sed#include <atf-c.h>
46200062Sed
47200062SedATF_TC_WITHOUT_HEAD(mbsnrtowcs_test);
48200062SedATF_TC_BODY(mbsnrtowcs_test, tc)
49202215Sed{
50200062Sed	char srcbuf[128];
51202215Sed	wchar_t dstbuf[128];
52202215Sed	char *src;
53202215Sed	mbstate_t s;
54202215Sed
55202215Sed	/* C/POSIX locale. */
56202215Sed
57202215Sed	/* Simple null terminated string. */
58234462Sed	memset(srcbuf, 0xcc, sizeof(srcbuf));
59202215Sed	strcpy(srcbuf, "hello");
60202215Sed	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
61202215Sed	src = srcbuf;
62202215Sed	memset(&s, 0, sizeof(s));
63202215Sed	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
64202215Sed	    sizeof(*dstbuf), &s) == 5);
65202215Sed	ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
66202215Sed	ATF_REQUIRE(dstbuf[6] == 0xcccc);
67202215Sed	ATF_REQUIRE(src == NULL);
68202215Sed
69200153Sed	/* Simple null terminated string, stopping early. */
70200153Sed	memset(srcbuf, 0xcc, sizeof(srcbuf));
71200421Sed	strcpy(srcbuf, "hello");
72200421Sed	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
73202215Sed	src = srcbuf;
74200062Sed	memset(&s, 0, sizeof(s));
75200062Sed	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 4, sizeof(dstbuf) /
76200062Sed	    sizeof(*dstbuf), &s) == 4);
77200062Sed	ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
78200062Sed	ATF_REQUIRE(dstbuf[5] == 0xcccc);
79202215Sed	ATF_REQUIRE(src == srcbuf + 4);
80200062Sed
81202215Sed	/* Not enough space in destination buffer. */
82200153Sed	memset(srcbuf, 0xcc, sizeof(srcbuf));
83202215Sed	strcpy(srcbuf, "hello");
84200062Sed	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
85	src = srcbuf;
86	memset(&s, 0, sizeof(s));
87	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, 4, &s) == 4);
88	ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
89	ATF_REQUIRE(dstbuf[5] == 0xcccc);
90	ATF_REQUIRE(src == srcbuf + 4);
91
92	/* Null terminated string, internal dest. buffer */
93	memset(srcbuf, 0xcc, sizeof(srcbuf));
94	strcpy(srcbuf, "hello");
95	src = srcbuf;
96	memset(&s, 0, sizeof(s));
97	ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 6, 0, &s) == 5);
98
99	/* Null terminated string, internal dest. buffer, stopping early */
100	memset(srcbuf, 0xcc, sizeof(srcbuf));
101	strcpy(srcbuf, "hello");
102	src = srcbuf;
103	memset(&s, 0, sizeof(s));
104	ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 4, 0, &s) == 4);
105
106	/* Null terminated string, internal state. */
107	memset(srcbuf, 0xcc, sizeof(srcbuf));
108	strcpy(srcbuf, "hello");
109	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
110	src = srcbuf;
111	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
112	    sizeof(*dstbuf), NULL) == 5);
113	ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
114	ATF_REQUIRE(dstbuf[6] == 0xcccc);
115	ATF_REQUIRE(src == NULL);
116
117	/* Null terminated string, internal state, internal dest. buffer. */
118	memset(srcbuf, 0xcc, sizeof(srcbuf));
119	strcpy(srcbuf, "hello");
120	src = srcbuf;
121	ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 6, 0, NULL) == 5);
122
123	/* Empty source buffer. */
124	memset(srcbuf, 0xcc, sizeof(srcbuf));
125	srcbuf[0] = '\0';
126	src = srcbuf;
127	memset(&s, 0, sizeof(s));
128	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
129	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, 1, &s) == 0);
130	ATF_REQUIRE(dstbuf[0] == 0);
131	ATF_REQUIRE(dstbuf[1] == 0xcccc);
132	ATF_REQUIRE(src == NULL);
133
134	/* Zero length destination buffer. */
135	memset(srcbuf, 0xcc, sizeof(srcbuf));
136	strcpy(srcbuf, "hello");
137	src = srcbuf;
138	memset(&s, 0, sizeof(s));
139	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
140	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, 0, &s) == 0);
141	ATF_REQUIRE(dstbuf[0] == 0xcccc);
142	ATF_REQUIRE(src == srcbuf);
143
144	/* Zero length source buffer. */
145	memset(srcbuf, 0xcc, sizeof(srcbuf));
146	src = srcbuf;
147	memset(&s, 0, sizeof(s));
148	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
149	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 0, 1, &s) == 0);
150	ATF_REQUIRE(dstbuf[0] == 0xcccc);
151	ATF_REQUIRE(src == srcbuf);
152
153	/*
154	 * Japanese (EUC) locale.
155	 */
156
157	ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
158	ATF_REQUIRE(MB_CUR_MAX > 1);
159
160	memset(srcbuf, 0xcc, sizeof(srcbuf));
161	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
162	src = srcbuf;
163	memset(&s, 0, sizeof(s));
164	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
165	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 8, sizeof(dstbuf) /
166	    sizeof(*dstbuf), &s) == 5);
167	ATF_REQUIRE(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
168	    dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
169	ATF_REQUIRE(src == NULL);
170
171	/* Partial character. */
172	memset(srcbuf, 0xcc, sizeof(srcbuf));
173	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
174	src = srcbuf;
175	memset(&s, 0, sizeof(s));
176	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
177	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
178	    sizeof(*dstbuf), &s) == 4);
179	ATF_REQUIRE(src == srcbuf + 6);
180	ATF_REQUIRE(!mbsinit(&s));
181	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
182	    sizeof(*dstbuf), &s) == 1);
183	ATF_REQUIRE(src == srcbuf + 7);
184	ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
185	    sizeof(*dstbuf), &s) == 0);
186	ATF_REQUIRE(src == NULL);
187}
188
189ATF_TP_ADD_TCS(tp)
190{
191
192	ATF_TP_ADD_TC(tp, mbsnrtowcs_test);
193
194	return (atf_no_error());
195}
196