wcsnrtombs_test.c revision 291178
1/*-
2 * Copyright (c) 2002-2004 Tim J. Robbins
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Test program for wcsnrtombs().
29 *
30 * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
31 * "ja_JP.eucJP". Other encodings are not tested.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: stable/10/lib/libc/tests/locale/wcsnrtombs_test.c 291178 2015-11-23 08:31:41Z ngie $");
36
37#include <errno.h>
38#include <limits.h>
39#include <locale.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <wchar.h>
44
45#include <atf-c.h>
46
47ATF_TC_WITHOUT_HEAD(wcsnrtombs_test);
48ATF_TC_BODY(wcsnrtombs_test, tc)
49{
50	wchar_t srcbuf[128];
51	char dstbuf[128];
52	wchar_t *src;
53	mbstate_t s;
54
55	/* C/POSIX locale. */
56
57	/* Simple null terminated string. */
58	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
59	wcscpy(srcbuf, L"hello");
60	memset(dstbuf, 0xcc, sizeof(dstbuf));
61	src = srcbuf;
62	memset(&s, 0, sizeof(s));
63	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
64	    &s) == 5);
65	ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
66	ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
67	ATF_REQUIRE(src == NULL);
68
69	/* Simple null terminated string, stopping early. */
70	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
71	wcscpy(srcbuf, L"hello");
72	memset(dstbuf, 0xcc, sizeof(dstbuf));
73	src = srcbuf;
74	memset(&s, 0, sizeof(s));
75	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 4, sizeof(dstbuf),
76	    &s) == 4);
77	ATF_REQUIRE(memcmp(dstbuf, "hell", 4) == 0);
78	ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
79	ATF_REQUIRE(src == srcbuf + 4);
80
81	/* Not enough space in destination buffer. */
82	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
83	wcscpy(srcbuf, L"hello");
84	memset(dstbuf, 0xcc, sizeof(dstbuf));
85	src = srcbuf;
86	memset(&s, 0, sizeof(s));
87	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 4,
88	    &s) == 4);
89	ATF_REQUIRE(memcmp(dstbuf, "hell", 4) == 0);
90	ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
91	ATF_REQUIRE(src == srcbuf + 4);
92
93	/* Null terminated string, internal dest. buffer */
94	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
95	wcscpy(srcbuf, L"hello");
96	src = srcbuf;
97	memset(&s, 0, sizeof(s));
98	ATF_REQUIRE(wcsnrtombs(NULL, (const wchar_t **)&src, 6, sizeof(dstbuf),
99	    &s) == 5);
100
101	/* Null terminated string, internal dest. buffer, stopping early. */
102	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
103	wcscpy(srcbuf, L"hello");
104	src = srcbuf;
105	memset(&s, 0, sizeof(s));
106	ATF_REQUIRE(wcsnrtombs(NULL, (const wchar_t **)&src, 4, sizeof(dstbuf),
107	    &s) == 4);
108
109	/* Null terminated string, internal state. */
110	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
111	wcscpy(srcbuf, L"hello");
112	memset(dstbuf, 0xcc, sizeof(dstbuf));
113	src = srcbuf;
114	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
115	    NULL) == 5);
116	ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
117	ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
118	ATF_REQUIRE(src == NULL);
119
120	/* Null terminated string, internal state, internal dest. buffer. */
121	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
122	wcscpy(srcbuf, L"hello");
123	src = srcbuf;
124	ATF_REQUIRE(wcsnrtombs(NULL, (const wchar_t **)&src, 6, 0, NULL) == 5);
125
126	/* Empty source buffer. */
127	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
128	srcbuf[0] = L'\0';
129	memset(dstbuf, 0xcc, sizeof(dstbuf));
130	src = srcbuf;
131	memset(&s, 0, sizeof(s));
132	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 1, sizeof(dstbuf),
133	    &s) == 0);
134	ATF_REQUIRE(dstbuf[0] == L'\0');
135
136	/* Zero length destination buffer. */
137	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
138	wcscpy(srcbuf, L"hello");
139	memset(dstbuf, 0xcc, sizeof(dstbuf));
140	src = srcbuf;
141	memset(&s, 0, sizeof(s));
142	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 0, &s) == 0);
143	ATF_REQUIRE((unsigned char)dstbuf[0] == 0xcc);
144
145	/* Zero length source buffer. */
146	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
147	memset(dstbuf, 0xcc, sizeof(dstbuf));
148	src = srcbuf;
149	memset(&s, 0, sizeof(s));
150	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 0, sizeof(dstbuf),
151	    &s) == 0);
152	ATF_REQUIRE((unsigned char)dstbuf[0] == 0xcc);
153	ATF_REQUIRE(src == srcbuf);
154
155	/*
156	 * Japanese (EUC) locale.
157	 */
158
159	ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
160	ATF_REQUIRE(MB_CUR_MAX > 1);
161
162	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
163	srcbuf[0] = 0xA3C1;
164	srcbuf[1] = 0x0020;
165	srcbuf[2] = 0x0042;
166	srcbuf[3] = 0x0020;
167	srcbuf[4] = 0xA3C3;
168	srcbuf[5] = 0x0000;
169	memset(dstbuf, 0xcc, sizeof(dstbuf));
170	src = srcbuf;
171	memset(&s, 0, sizeof(s));
172	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
173	    &s) == 7);
174	ATF_REQUIRE(strcmp(dstbuf, "\xA3\xC1 B \xA3\xC3") == 0);
175	ATF_REQUIRE((unsigned char)dstbuf[8] == 0xcc);
176	ATF_REQUIRE(src == NULL);
177
178	/* Stopping early. */
179	memset(dstbuf, 0xcc, sizeof(dstbuf));
180	src = srcbuf;
181	memset(&s, 0, sizeof(s));
182	ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 6,
183	    &s) == 5);
184	ATF_REQUIRE(memcmp(dstbuf, "\xA3\xC1 B ", 5) == 0);
185	ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
186	ATF_REQUIRE(src == srcbuf + 4);
187}
188
189ATF_TP_ADD_TCS(tp)
190{
191
192	ATF_TP_ADD_TC(tp, wcsnrtombs_test);
193
194	return (atf_no_error());
195}
196