1105973Stjr/*-
2105973Stjr * Copyright (c) 2002 Tim J. Robbins
3105973Stjr * All rights reserved.
4105973Stjr *
5105973Stjr * Redistribution and use in source and binary forms, with or without
6105973Stjr * modification, are permitted provided that the following conditions
7105973Stjr * are met:
8105973Stjr * 1. Redistributions of source code must retain the above copyright
9105973Stjr *    notice, this list of conditions and the following disclaimer.
10105973Stjr * 2. Redistributions in binary form must reproduce the above copyright
11105973Stjr *    notice, this list of conditions and the following disclaimer in the
12105973Stjr *    documentation and/or other materials provided with the distribution.
13105973Stjr *
14105973Stjr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15105973Stjr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16105973Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17105973Stjr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18105973Stjr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19105973Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20105973Stjr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21105973Stjr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22105973Stjr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23105973Stjr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24105973Stjr * SUCH DAMAGE.
25105973Stjr */
26105973Stjr
27105973Stjr/*
28105973Stjr * Test program for mbrtowc(), as specified by IEEE Std. 1003.1-2001 and
29105973Stjr * ISO/IEC 9899:1999.
30105973Stjr *
31106495Stjr * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
32106495Stjr * "ja_JP.eucJP". Other encodings are not tested.
33105973Stjr */
34105973Stjr
35105973Stjr#include <sys/cdefs.h>
36105973Stjr__FBSDID("$FreeBSD$");
37105973Stjr
38105973Stjr#include <assert.h>
39105973Stjr#include <errno.h>
40105973Stjr#include <limits.h>
41105973Stjr#include <locale.h>
42106495Stjr#include <stdio.h>
43105973Stjr#include <stdlib.h>
44105973Stjr#include <string.h>
45105973Stjr#include <wchar.h>
46105973Stjr
47105973Stjrint
48105973Stjrmain(int argc, char *argv[])
49105973Stjr{
50105973Stjr	mbstate_t s;
51105973Stjr	size_t len;
52105973Stjr	wchar_t wc;
53105973Stjr	char buf[MB_LEN_MAX + 1];
54105973Stjr
55105973Stjr	/*
56105973Stjr	 * C/POSIX locale.
57105973Stjr	 */
58105973Stjr
59137587Snik	printf("1..1\n");
60137587Snik
61105973Stjr	assert(MB_CUR_MAX == 1);
62105973Stjr
63105973Stjr	/* Null wide character, internal state. */
64105973Stjr	memset(buf, 0xcc, sizeof(buf));
65105973Stjr	buf[0] = 0;
66105973Stjr	assert(mbrtowc(&wc, buf, 1, NULL) == 0);
67105973Stjr	assert(wc == 0);
68105973Stjr
69105973Stjr	/* Null wide character. */
70105973Stjr	memset(&s, 0, sizeof(s));
71105973Stjr	assert(mbrtowc(&wc, buf, 1, &s) == 0);
72105973Stjr	assert(wc == 0);
73105973Stjr
74105973Stjr	/* Latin letter A, internal state. */
75105973Stjr	assert(mbrtowc(NULL, 0, 0, NULL) == 0);
76105973Stjr	buf[0] = 'A';
77105973Stjr	assert(mbrtowc(&wc, buf, 1, NULL) == 1);
78105973Stjr	assert(wc == L'A');
79105973Stjr
80105973Stjr	/* Latin letter A. */
81105973Stjr	memset(&s, 0, sizeof(s));
82105973Stjr	assert(mbrtowc(&wc, buf, 1, &s) == 1);
83105973Stjr	assert(wc == L'A');
84105973Stjr
85105973Stjr	/* Incomplete character sequence. */
86105973Stjr	wc = L'z';
87105973Stjr	memset(&s, 0, sizeof(s));
88105973Stjr	assert(mbrtowc(&wc, buf, 0, &s) == (size_t)-2);
89105973Stjr	assert(wc == L'z');
90105973Stjr
91106726Stjr	/* Check that mbrtowc() doesn't access the buffer when n == 0. */
92106726Stjr	wc = L'z';
93106726Stjr	memset(&s, 0, sizeof(s));
94106726Stjr	buf[0] = '\0';
95106726Stjr	assert(mbrtowc(&wc, buf, 0, &s) == (size_t)-2);
96106726Stjr	assert(wc == L'z');
97106726Stjr
98105973Stjr	/*
99105973Stjr	 * Japanese (EUC) locale.
100105973Stjr	 */
101105973Stjr
102105973Stjr	assert(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
103105973Stjr	assert(MB_CUR_MAX > 1);
104105973Stjr
105105973Stjr	/* Null wide character, internal state. */
106105973Stjr	assert(mbrtowc(NULL, 0, 0, NULL) == 0);
107105973Stjr	memset(buf, 0xcc, sizeof(buf));
108105973Stjr	buf[0] = 0;
109105973Stjr	assert(mbrtowc(&wc, buf, 1, NULL) == 0);
110105973Stjr	assert(wc == 0);
111105973Stjr
112105973Stjr	/* Null wide character. */
113105973Stjr	memset(&s, 0, sizeof(s));
114105973Stjr	assert(mbrtowc(&wc, buf, 1, &s) == 0);
115105973Stjr	assert(wc == 0);
116105973Stjr
117105973Stjr	/* Latin letter A, internal state. */
118105973Stjr	assert(mbrtowc(NULL, 0, 0, NULL) == 0);
119105973Stjr	buf[0] = 'A';
120105973Stjr	assert(mbrtowc(&wc, buf, 1, NULL) == 1);
121105973Stjr	assert(wc == L'A');
122105973Stjr
123105973Stjr	/* Latin letter A. */
124105973Stjr	memset(&s, 0, sizeof(s));
125105973Stjr	assert(mbrtowc(&wc, buf, 1, &s) == 1);
126105973Stjr	assert(wc == L'A');
127105973Stjr
128105973Stjr	/* Incomplete character sequence (zero length). */
129105973Stjr	wc = L'z';
130105973Stjr	memset(&s, 0, sizeof(s));
131105973Stjr	assert(mbrtowc(&wc, buf, 0, &s) == (size_t)-2);
132105973Stjr	assert(wc == L'z');
133105973Stjr
134105973Stjr	/* Incomplete character sequence (truncated double-byte). */
135105973Stjr	memset(buf, 0xcc, sizeof(buf));
136105973Stjr	buf[0] = 0xa3;
137105973Stjr	buf[1] = 0x00;
138105973Stjr	memset(&s, 0, sizeof(s));
139105973Stjr	wc = 0;
140105973Stjr	assert(mbrtowc(&wc, buf, 1, &s) == (size_t)-2);
141105973Stjr
142105973Stjr	/* Same as above, but complete. */
143105973Stjr	buf[1] = 0xc1;
144105973Stjr	memset(&s, 0, sizeof(s));
145105973Stjr	wc = 0;
146105973Stjr	assert(mbrtowc(&wc, buf, 2, &s) == 2);
147105973Stjr	assert(wc == 0xa3c1);
148105973Stjr
149129115Stjr	/* Test restarting behaviour. */
150129115Stjr	memset(buf, 0xcc, sizeof(buf));
151129115Stjr	buf[0] = 0xa3;
152129115Stjr	memset(&s, 0, sizeof(s));
153129115Stjr	wc = 0;
154129115Stjr	assert(mbrtowc(&wc, buf, 1, &s) == (size_t)-2);
155129115Stjr	assert(wc == 0);
156129115Stjr	buf[0] = 0xc1;
157129115Stjr	assert(mbrtowc(&wc, buf, 1, &s) == 1);
158129115Stjr	assert(wc == 0xa3c1);
159129115Stjr
160137587Snik	printf("ok 1 - mbrtowc()\n");
161105973Stjr
162105973Stjr	return (0);
163105973Stjr}
164