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 mbsnrtowcs().
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$");
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	char srcbuf[128];
50132499Stjr	wchar_t dstbuf[128];
51132499Stjr	char *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	memset(srcbuf, 0xcc, sizeof(srcbuf));
62132499Stjr	strcpy(srcbuf, "hello");
63132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
64132499Stjr	src = srcbuf;
65132499Stjr	memset(&s, 0, sizeof(s));
66132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
67132499Stjr	    sizeof(*dstbuf), &s) == 5);
68132499Stjr	assert(wcscmp(dstbuf, L"hello") == 0);
69132499Stjr	assert(dstbuf[6] == 0xcccc);
70132499Stjr	assert(src == NULL);
71132499Stjr
72132499Stjr	/* Simple null terminated string, stopping early. */
73132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
74132499Stjr	strcpy(srcbuf, "hello");
75132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
76132499Stjr	src = srcbuf;
77132499Stjr	memset(&s, 0, sizeof(s));
78132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 4, sizeof(dstbuf) /
79132499Stjr	    sizeof(*dstbuf), &s) == 4);
80132499Stjr	assert(wmemcmp(dstbuf, L"hell", 4) == 0);
81132499Stjr	assert(dstbuf[5] == 0xcccc);
82132499Stjr	assert(src == srcbuf + 4);
83132499Stjr
84132499Stjr	/* Not enough space in destination buffer. */
85132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
86132499Stjr	strcpy(srcbuf, "hello");
87132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
88132499Stjr	src = srcbuf;
89132499Stjr	memset(&s, 0, sizeof(s));
90132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, 4, &s) == 4);
91132499Stjr	assert(wmemcmp(dstbuf, L"hell", 4) == 0);
92132499Stjr	assert(dstbuf[5] == 0xcccc);
93132499Stjr	assert(src == srcbuf + 4);
94132499Stjr
95132499Stjr	/* Null terminated string, internal dest. buffer */
96132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
97132499Stjr	strcpy(srcbuf, "hello");
98132499Stjr	src = srcbuf;
99132499Stjr	memset(&s, 0, sizeof(s));
100132499Stjr	assert(mbsnrtowcs(NULL, (const char **)&src, 6, 0, &s) == 5);
101132499Stjr
102132499Stjr	/* Null terminated string, internal dest. buffer, stopping early */
103132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
104132499Stjr	strcpy(srcbuf, "hello");
105132499Stjr	src = srcbuf;
106132499Stjr	memset(&s, 0, sizeof(s));
107132499Stjr	assert(mbsnrtowcs(NULL, (const char **)&src, 4, 0, &s) == 4);
108132499Stjr
109132499Stjr	/* Null terminated string, internal state. */
110132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
111132499Stjr	strcpy(srcbuf, "hello");
112132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
113132499Stjr	src = srcbuf;
114132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
115132499Stjr	    sizeof(*dstbuf), NULL) == 5);
116132499Stjr	assert(wcscmp(dstbuf, L"hello") == 0);
117132499Stjr	assert(dstbuf[6] == 0xcccc);
118132499Stjr	assert(src == NULL);
119132499Stjr
120132499Stjr	/* Null terminated string, internal state, internal dest. buffer. */
121132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
122132499Stjr	strcpy(srcbuf, "hello");
123132499Stjr	src = srcbuf;
124132499Stjr	assert(mbsnrtowcs(NULL, (const char **)&src, 6, 0, NULL) == 5);
125132499Stjr
126132499Stjr	/* Empty source buffer. */
127132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
128132499Stjr	srcbuf[0] = '\0';
129132499Stjr	src = srcbuf;
130132499Stjr	memset(&s, 0, sizeof(s));
131132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
132132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, 1, &s) == 0);
133132499Stjr	assert(dstbuf[0] == 0);
134132499Stjr	assert(dstbuf[1] == 0xcccc);
135132499Stjr	assert(src == NULL);
136132499Stjr
137132499Stjr	/* Zero length destination buffer. */
138132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
139132499Stjr	strcpy(srcbuf, "hello");
140132499Stjr	src = srcbuf;
141132499Stjr	memset(&s, 0, sizeof(s));
142132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
143132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, 0, &s) == 0);
144132499Stjr	assert(dstbuf[0] == 0xcccc);
145132499Stjr	assert(src == srcbuf);
146132499Stjr
147132499Stjr	/* Zero length source buffer. */
148132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
149132499Stjr	src = srcbuf;
150132499Stjr	memset(&s, 0, sizeof(s));
151132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
152132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 0, 1, &s) == 0);
153132499Stjr	assert(dstbuf[0] == 0xcccc);
154132499Stjr	assert(src == srcbuf);
155132499Stjr
156132499Stjr	/*
157132499Stjr	 * Japanese (EUC) locale.
158132499Stjr	 */
159132499Stjr
160132499Stjr	assert(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
161132499Stjr	assert(MB_CUR_MAX > 1);
162132499Stjr
163132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
164132499Stjr	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
165132499Stjr	src = srcbuf;
166132499Stjr	memset(&s, 0, sizeof(s));
167132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
168132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 8, sizeof(dstbuf) /
169132499Stjr	    sizeof(*dstbuf), &s) == 5);
170132499Stjr	assert(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
171132499Stjr	    dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
172132499Stjr	assert(src == NULL);
173132499Stjr
174132499Stjr	/* Partial character. */
175132499Stjr	memset(srcbuf, 0xcc, sizeof(srcbuf));
176132499Stjr	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
177132499Stjr	src = srcbuf;
178132499Stjr	memset(&s, 0, sizeof(s));
179132499Stjr	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
180132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
181132499Stjr	    sizeof(*dstbuf), &s) == 4);
182132499Stjr	assert(src == srcbuf + 6);
183132499Stjr	assert(!mbsinit(&s));
184132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
185132499Stjr	    sizeof(*dstbuf), &s) == 1);
186132499Stjr	assert(src == srcbuf + 7);
187132499Stjr	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
188132499Stjr	    sizeof(*dstbuf), &s) == 0);
189132499Stjr	assert(src == NULL);
190132499Stjr
191137587Snik	printf("ok 1 - mbsnrtowcs()\n");
192132499Stjr
193132499Stjr	return (0);
194132499Stjr}
195