1132499Stjr/*-
2132499Stjr * Copyright (c) 2002-2004 Tim J. Robbins
3132499Stjr * All rights reserved.
4132499Stjr *
5132499Stjr * Redistribution and use in source and binary forms, with or without
6132499Stjr * modification, are permitted provided that the following conditions
7132499Stjr * are met:
8132499Stjr * 1. Redistributions of source code must retain the above copyright
9132499Stjr *    notice, this list of conditions and the following disclaimer.
10132499Stjr * 2. Redistributions in binary form must reproduce the above copyright
11132499Stjr *    notice, this list of conditions and the following disclaimer in the
12132499Stjr *    documentation and/or other materials provided with the distribution.
13132499Stjr *
14132499Stjr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15132499Stjr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16132499Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17132499Stjr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18132499Stjr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19132499Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20132499Stjr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21132499Stjr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22132499Stjr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23132499Stjr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24132499Stjr * SUCH DAMAGE.
25132499Stjr */
26132499Stjr
27132499Stjr/*
28132499Stjr * Test program for wcsnrtombs().
29132499Stjr *
30132499Stjr * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
31132499Stjr * "ja_JP.eucJP". Other encodings are not tested.
32132499Stjr */
33132499Stjr
34132499Stjr#include <sys/cdefs.h>
35132499Stjr__FBSDID("$FreeBSD: releng/10.2/tools/regression/lib/libc/locale/test-wcsnrtombs.c 137587 2004-11-11 19:47:55Z nik $");
36132499Stjr
37132499Stjr#include <assert.h>
38132499Stjr#include <errno.h>
39132499Stjr#include <limits.h>
40132499Stjr#include <locale.h>
41132499Stjr#include <stdio.h>
42132499Stjr#include <stdlib.h>
43132499Stjr#include <string.h>
44132499Stjr#include <wchar.h>
45132499Stjr
46132499Stjrint
47132499Stjrmain(int argc, char *argv[])
48132499Stjr{
49132499Stjr	wchar_t srcbuf[128];
50132499Stjr	char dstbuf[128];
51132499Stjr	wchar_t *src;
52132499Stjr	mbstate_t s;
53132499Stjr
54132499Stjr	/*
55132499Stjr	 * C/POSIX locale.
56132499Stjr	 */
57132499Stjr
58137587Snik	printf("1..1\n");
59137587Snik
60132499Stjr	/* Simple null terminated string. */
61132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
62132499Stjr	wcscpy(srcbuf, L"hello");
63132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
64132499Stjr	src = srcbuf;
65132499Stjr	memset(&s, 0, sizeof(s));
66132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
67132499Stjr	    &s) == 5);
68132499Stjr	assert(strcmp(dstbuf, "hello") == 0);
69132499Stjr	assert((unsigned char)dstbuf[6] == 0xcc);
70132499Stjr	assert(src == NULL);
71132499Stjr
72132499Stjr	/* Simple null terminated string, stopping early. */
73132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
74132499Stjr	wcscpy(srcbuf, L"hello");
75132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
76132499Stjr	src = srcbuf;
77132499Stjr	memset(&s, 0, sizeof(s));
78132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 4, sizeof(dstbuf),
79132499Stjr	    &s) == 4);
80132499Stjr	assert(memcmp(dstbuf, "hell", 4) == 0);
81132499Stjr	assert((unsigned char)dstbuf[5] == 0xcc);
82132499Stjr	assert(src == srcbuf + 4);
83132499Stjr
84132499Stjr	/* Not enough space in destination buffer. */
85132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
86132499Stjr	wcscpy(srcbuf, L"hello");
87132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
88132499Stjr	src = srcbuf;
89132499Stjr	memset(&s, 0, sizeof(s));
90132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 4,
91132499Stjr	    &s) == 4);
92132499Stjr	assert(memcmp(dstbuf, "hell", 4) == 0);
93132499Stjr	assert((unsigned char)dstbuf[5] == 0xcc);
94132499Stjr	assert(src == srcbuf + 4);
95132499Stjr
96132499Stjr	/* Null terminated string, internal dest. buffer */
97132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
98132499Stjr	wcscpy(srcbuf, L"hello");
99132499Stjr	src = srcbuf;
100132499Stjr	memset(&s, 0, sizeof(s));
101132499Stjr	assert(wcsnrtombs(NULL, (const wchar_t **)&src, 6, sizeof(dstbuf),
102132499Stjr	    &s) == 5);
103132499Stjr
104132499Stjr	/* Null terminated string, internal dest. buffer, stopping early. */
105132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
106132499Stjr	wcscpy(srcbuf, L"hello");
107132499Stjr	src = srcbuf;
108132499Stjr	memset(&s, 0, sizeof(s));
109132499Stjr	assert(wcsnrtombs(NULL, (const wchar_t **)&src, 4, sizeof(dstbuf),
110132499Stjr	    &s) == 4);
111132499Stjr
112132499Stjr	/* Null terminated string, internal state. */
113132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
114132499Stjr	wcscpy(srcbuf, L"hello");
115132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
116132499Stjr	src = srcbuf;
117132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
118132499Stjr	    NULL) == 5);
119132499Stjr	assert(strcmp(dstbuf, "hello") == 0);
120132499Stjr	assert((unsigned char)dstbuf[6] == 0xcc);
121132499Stjr	assert(src == NULL);
122132499Stjr
123132499Stjr	/* Null terminated string, internal state, internal dest. buffer. */
124132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
125132499Stjr	wcscpy(srcbuf, L"hello");
126132499Stjr	src = srcbuf;
127132499Stjr	assert(wcsnrtombs(NULL, (const wchar_t **)&src, 6, 0, NULL) == 5);
128132499Stjr
129132499Stjr	/* Empty source buffer. */
130132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
131132499Stjr	srcbuf[0] = L'\0';
132132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
133132499Stjr	src = srcbuf;
134132499Stjr	memset(&s, 0, sizeof(s));
135132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 1, sizeof(dstbuf),
136132499Stjr	    &s) == 0);
137132499Stjr	assert(dstbuf[0] == L'\0');
138132499Stjr
139132499Stjr	/* Zero length destination buffer. */
140132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
141132499Stjr	wcscpy(srcbuf, L"hello");
142132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
143132499Stjr	src = srcbuf;
144132499Stjr	memset(&s, 0, sizeof(s));
145132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 0, &s) == 0);
146132499Stjr	assert((unsigned char)dstbuf[0] == 0xcc);
147132499Stjr
148132499Stjr	/* Zero length source buffer. */
149132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
150132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
151132499Stjr	src = srcbuf;
152132499Stjr	memset(&s, 0, sizeof(s));
153132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 0, sizeof(dstbuf),
154132499Stjr	    &s) == 0);
155132499Stjr	assert((unsigned char)dstbuf[0] == 0xcc);
156132499Stjr	assert(src == srcbuf);
157132499Stjr
158132499Stjr	/*
159132499Stjr	 * Japanese (EUC) locale.
160132499Stjr	 */
161132499Stjr
162132499Stjr	assert(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
163132499Stjr	assert(MB_CUR_MAX > 1);
164132499Stjr
165132499Stjr	wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
166132499Stjr	srcbuf[0] = 0xA3C1;
167132499Stjr	srcbuf[1] = 0x0020;
168132499Stjr	srcbuf[2] = 0x0042;
169132499Stjr	srcbuf[3] = 0x0020;
170132499Stjr	srcbuf[4] = 0xA3C3;
171132499Stjr	srcbuf[5] = 0x0000;
172132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
173132499Stjr	src = srcbuf;
174132499Stjr	memset(&s, 0, sizeof(s));
175132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
176132499Stjr	    &s) == 7);
177132499Stjr	assert(strcmp(dstbuf, "\xA3\xC1 B \xA3\xC3") == 0);
178132499Stjr	assert((unsigned char)dstbuf[8] == 0xcc);
179132499Stjr	assert(src == NULL);
180132499Stjr
181132499Stjr	/* Stopping early. */
182132499Stjr	memset(dstbuf, 0xcc, sizeof(dstbuf));
183132499Stjr	src = srcbuf;
184132499Stjr	memset(&s, 0, sizeof(s));
185132499Stjr	assert(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 6,
186132499Stjr	    &s) == 5);
187132499Stjr	assert(memcmp(dstbuf, "\xA3\xC1 B ", 5) == 0);
188132499Stjr	assert((unsigned char)dstbuf[5] == 0xcc);
189132499Stjr	assert(src == srcbuf + 4);
190132499Stjr
191137587Snik	printf("ok 1 - wcsnrtombs()\n");
192132499Stjr
193132499Stjr	return (0);
194132499Stjr}
195