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 wcrtomb(), 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: releng/11.0/lib/libc/tests/locale/wcrtomb_test.c 290532 2015-11-08 02:06:17Z ngie $");
37105973Stjr
38105973Stjr#include <errno.h>
39105973Stjr#include <limits.h>
40105973Stjr#include <locale.h>
41106495Stjr#include <stdio.h>
42105973Stjr#include <stdlib.h>
43105973Stjr#include <string.h>
44105973Stjr#include <wchar.h>
45105973Stjr
46290532Sngie#include <atf-c.h>
47290532Sngie
48290532SngieATF_TC_WITHOUT_HEAD(wcrtomb_test);
49290532SngieATF_TC_BODY(wcrtomb_test, tc)
50105973Stjr{
51105973Stjr	mbstate_t s;
52105973Stjr	size_t len;
53105973Stjr	char buf[MB_LEN_MAX + 1];
54105973Stjr
55290532Sngie	/* C/POSIX locale. */
56105973Stjr
57290532Sngie	ATF_REQUIRE(MB_CUR_MAX == 1);
58137587Snik
59108069Stjr	/*
60108069Stjr	 * If the buffer argument is NULL, wc is implicitly L'\0',
61108069Stjr	 * wcrtomb() resets its internal state.
62108069Stjr	 */
63290532Sngie	ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
64290532Sngie	ATF_REQUIRE(wcrtomb(NULL, UCHAR_MAX + 1, NULL) == 1);
65105973Stjr
66105973Stjr	/* Null wide character. */
67105973Stjr	memset(&s, 0, sizeof(s));
68105973Stjr	memset(buf, 0xcc, sizeof(buf));
69105973Stjr	len = wcrtomb(buf, L'\0', &s);
70290532Sngie	ATF_REQUIRE(len == 1);
71290532Sngie	ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
72105973Stjr
73108069Stjr	/* Latin letter A, internal state. */
74290532Sngie	ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
75290532Sngie	ATF_REQUIRE(wcrtomb(NULL, L'A', NULL) == 1);
76105973Stjr
77105973Stjr	/* Latin letter A. */
78105973Stjr	memset(&s, 0, sizeof(s));
79105973Stjr	memset(buf, 0xcc, sizeof(buf));
80105973Stjr	len = wcrtomb(buf, L'A', &s);
81290532Sngie	ATF_REQUIRE(len == 1);
82290532Sngie	ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
83105973Stjr
84105973Stjr	/* Invalid code. */
85290532Sngie	ATF_REQUIRE(wcrtomb(buf, UCHAR_MAX + 1, NULL) == (size_t)-1);
86290532Sngie	ATF_REQUIRE(errno == EILSEQ);
87105973Stjr
88105973Stjr	/*
89105973Stjr	 * Japanese (EUC) locale.
90105973Stjr	 */
91105973Stjr
92290532Sngie	ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
93290532Sngie	ATF_REQUIRE(MB_CUR_MAX == 3);
94105973Stjr
95108069Stjr	/*
96108069Stjr	 * If the buffer argument is NULL, wc is implicitly L'\0',
97108069Stjr	 * wcrtomb() resets its internal state.
98108069Stjr	 */
99290532Sngie	ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
100105973Stjr
101105973Stjr	/* Null wide character. */
102105973Stjr	memset(&s, 0, sizeof(s));
103105973Stjr	memset(buf, 0xcc, sizeof(buf));
104105973Stjr	len = wcrtomb(buf, L'\0', &s);
105290532Sngie	ATF_REQUIRE(len == 1);
106290532Sngie	ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
107105973Stjr
108108069Stjr	/* Latin letter A, internal state. */
109290532Sngie	ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
110290532Sngie	ATF_REQUIRE(wcrtomb(NULL, L'A', NULL) == 1);
111105973Stjr
112105973Stjr	/* Latin letter A. */
113105973Stjr	memset(&s, 0, sizeof(s));
114105973Stjr	memset(buf, 0xcc, sizeof(buf));
115105973Stjr	len = wcrtomb(buf, L'A', &s);
116290532Sngie	ATF_REQUIRE(len == 1);
117290532Sngie	ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
118105973Stjr
119105973Stjr	/* Full width letter A. */
120105973Stjr	memset(&s, 0, sizeof(s));
121105973Stjr	memset(buf, 0xcc, sizeof(buf));
122105973Stjr	len = wcrtomb(buf, 0xa3c1, &s);
123290532Sngie	ATF_REQUIRE(len == 2);
124290532Sngie	ATF_REQUIRE((unsigned char)buf[0] == 0xa3 &&
125105973Stjr		(unsigned char)buf[1] == 0xc1 &&
126105973Stjr		(unsigned char)buf[2] == 0xcc);
127290532Sngie}
128105973Stjr
129290532SngieATF_TP_ADD_TCS(tp)
130290532Sngie{
131105973Stjr
132290532Sngie	ATF_TP_ADD_TC(tp, wcrtomb_test);
133290532Sngie
134290532Sngie	return (atf_no_error());
135105973Stjr}
136