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: releng/10.2/tools/regression/lib/libc/locale/test-wcsnrtombs.c 137587 2004-11-11 19:47:55Z nik $");
36
37#include <assert.h>
38#include <errno.h>
39#include <limits.h>
40#include <locale.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <wchar.h>
45
46int
47main(int argc, char *argv[])
48{
49	wchar_t srcbuf[128];
50	char dstbuf[128];
51	wchar_t *src;
52	mbstate_t s;
53
54	/*
55	 * C/POSIX locale.
56	 */
57
58	printf("1..1\n");
59
60	/* Simple null terminated string. */
61	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
62	wcscpy(srcbuf, L"hello");
63	memset(dstbuf, 0xcc, sizeof(dstbuf));
64	src = srcbuf;
65	memset(&s, 0, sizeof(s));
66	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
67	    &s) == 5);
68	assert(strcmp(dstbuf, "hello") == 0);
69	assert((unsigned char)dstbuf[6] == 0xcc);
70	assert(src == NULL);
71
72	/* Simple null terminated string, stopping early. */
73	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
74	wcscpy(srcbuf, L"hello");
75	memset(dstbuf, 0xcc, sizeof(dstbuf));
76	src = srcbuf;
77	memset(&s, 0, sizeof(s));
78	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 4, sizeof(dstbuf),
79	    &s) == 4);
80	assert(memcmp(dstbuf, "hell", 4) == 0);
81	assert((unsigned char)dstbuf[5] == 0xcc);
82	assert(src == srcbuf + 4);
83
84	/* Not enough space in destination buffer. */
85	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
86	wcscpy(srcbuf, L"hello");
87	memset(dstbuf, 0xcc, sizeof(dstbuf));
88	src = srcbuf;
89	memset(&s, 0, sizeof(s));
90	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 4,
91	    &s) == 4);
92	assert(memcmp(dstbuf, "hell", 4) == 0);
93	assert((unsigned char)dstbuf[5] == 0xcc);
94	assert(src == srcbuf + 4);
95
96	/* Null terminated string, internal dest. buffer */
97	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
98	wcscpy(srcbuf, L"hello");
99	src = srcbuf;
100	memset(&s, 0, sizeof(s));
101	assert(wcsnrtombs(NULL, (const wchar_t **)&src, 6, sizeof(dstbuf),
102	    &s) == 5);
103
104	/* Null terminated string, internal dest. buffer, stopping early. */
105	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
106	wcscpy(srcbuf, L"hello");
107	src = srcbuf;
108	memset(&s, 0, sizeof(s));
109	assert(wcsnrtombs(NULL, (const wchar_t **)&src, 4, sizeof(dstbuf),
110	    &s) == 4);
111
112	/* Null terminated string, internal state. */
113	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
114	wcscpy(srcbuf, L"hello");
115	memset(dstbuf, 0xcc, sizeof(dstbuf));
116	src = srcbuf;
117	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
118	    NULL) == 5);
119	assert(strcmp(dstbuf, "hello") == 0);
120	assert((unsigned char)dstbuf[6] == 0xcc);
121	assert(src == NULL);
122
123	/* Null terminated string, internal state, internal dest. buffer. */
124	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
125	wcscpy(srcbuf, L"hello");
126	src = srcbuf;
127	assert(wcsnrtombs(NULL, (const wchar_t **)&src, 6, 0, NULL) == 5);
128
129	/* Empty source buffer. */
130	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
131	srcbuf[0] = L'\0';
132	memset(dstbuf, 0xcc, sizeof(dstbuf));
133	src = srcbuf;
134	memset(&s, 0, sizeof(s));
135	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 1, sizeof(dstbuf),
136	    &s) == 0);
137	assert(dstbuf[0] == L'\0');
138
139	/* Zero length destination buffer. */
140	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
141	wcscpy(srcbuf, L"hello");
142	memset(dstbuf, 0xcc, sizeof(dstbuf));
143	src = srcbuf;
144	memset(&s, 0, sizeof(s));
145	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 0, &s) == 0);
146	assert((unsigned char)dstbuf[0] == 0xcc);
147
148	/* Zero length source buffer. */
149	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
150	memset(dstbuf, 0xcc, sizeof(dstbuf));
151	src = srcbuf;
152	memset(&s, 0, sizeof(s));
153	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 0, sizeof(dstbuf),
154	    &s) == 0);
155	assert((unsigned char)dstbuf[0] == 0xcc);
156	assert(src == srcbuf);
157
158	/*
159	 * Japanese (EUC) locale.
160	 */
161
162	assert(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
163	assert(MB_CUR_MAX > 1);
164
165	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
166	srcbuf[0] = 0xA3C1;
167	srcbuf[1] = 0x0020;
168	srcbuf[2] = 0x0042;
169	srcbuf[3] = 0x0020;
170	srcbuf[4] = 0xA3C3;
171	srcbuf[5] = 0x0000;
172	memset(dstbuf, 0xcc, sizeof(dstbuf));
173	src = srcbuf;
174	memset(&s, 0, sizeof(s));
175	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
176	    &s) == 7);
177	assert(strcmp(dstbuf, "\xA3\xC1 B \xA3\xC3") == 0);
178	assert((unsigned char)dstbuf[8] == 0xcc);
179	assert(src == NULL);
180
181	/* Stopping early. */
182	memset(dstbuf, 0xcc, sizeof(dstbuf));
183	src = srcbuf;
184	memset(&s, 0, sizeof(s));
185	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 6,
186	    &s) == 5);
187	assert(memcmp(dstbuf, "\xA3\xC1 B ", 5) == 0);
188	assert((unsigned char)dstbuf[5] == 0xcc);
189	assert(src == srcbuf + 4);
190
191	printf("ok 1 - wcsnrtombs()\n");
192
193	return (0);
194}
195