]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/tests/locale/c16rtomb_test.c
Integrate tools/regression/lib/libc/locale into the FreeBSD test suite
[FreeBSD/FreeBSD.git] / lib / libc / tests / locale / c16rtomb_test.c
1 /*-
2  * Copyright (c) 2002 Tim J. Robbins
3  * All rights reserved.
4  *
5  * Copyright (c) 2013 Ed Schouten <ed@FreeBSD.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 /*
30  * Test program for c16rtomb() as specified by ISO/IEC 9899:2011.
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <errno.h>
37 #include <limits.h>
38 #include <locale.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <uchar.h>
42
43 #include <atf-c.h>
44
45 ATF_TC_WITHOUT_HEAD(c16rtomb_test);
46 ATF_TC_BODY(c16rtomb_test, tc)
47 {
48         mbstate_t s;
49         char buf[MB_LEN_MAX + 1];
50
51         /* C/POSIX locale. */
52
53         /*
54          * If the buffer argument is NULL, c16 is implicitly 0,
55          * c16rtomb() resets its internal state.
56          */
57         ATF_REQUIRE(c16rtomb(NULL, L'\0', NULL) == 1);
58         ATF_REQUIRE(c16rtomb(NULL, 0xdc00, NULL) == 1);
59
60         /* Null wide character. */
61         memset(&s, 0, sizeof(s));
62         memset(buf, 0xcc, sizeof(buf));
63         ATF_REQUIRE(c16rtomb(buf, 0, &s) == 1);
64         ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
65
66         /* Latin letter A, internal state. */
67         ATF_REQUIRE(c16rtomb(NULL, L'\0', NULL) == 1);
68         ATF_REQUIRE(c16rtomb(NULL, L'A', NULL) == 1);
69
70         /* Latin letter A. */
71         memset(&s, 0, sizeof(s));
72         memset(buf, 0xcc, sizeof(buf));
73         ATF_REQUIRE(c16rtomb(buf, L'A', &s) == 1);
74         ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
75
76         /* Unicode character 'Pile of poo'. */
77         memset(&s, 0, sizeof(s));
78         memset(buf, 0xcc, sizeof(buf));
79         ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
80         ATF_REQUIRE(c16rtomb(buf, 0xdca9, &s) == (size_t)-1);
81         ATF_REQUIRE(errno == EILSEQ);
82         ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
83
84         /* ISO8859-1. */
85
86         ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "en_US.ISO8859-1"),
87             "en_US.ISO8859-1") == 0);
88
89         /* Unicode character 'Euro sign'. */
90         memset(&s, 0, sizeof(s));
91         memset(buf, 0xcc, sizeof(buf));
92         ATF_REQUIRE(c16rtomb(buf, 0x20ac, &s) == (size_t)-1);
93         ATF_REQUIRE(errno == EILSEQ);
94         ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
95
96         /* ISO8859-15. */
97
98         ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "en_US.ISO8859-15"),
99             "en_US.ISO8859-15") == 0);
100
101         /* Unicode character 'Euro sign'. */
102         memset(&s, 0, sizeof(s));
103         memset(buf, 0xcc, sizeof(buf));
104         ATF_REQUIRE(c16rtomb(buf, 0x20ac, &s) == 1);
105         ATF_REQUIRE((unsigned char)buf[0] == 0xa4 && (unsigned char)buf[1] == 0xcc);
106
107         /* UTF-8. */
108
109         ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "en_US.UTF-8"), "en_US.UTF-8") == 0);
110
111         /* Unicode character 'Pile of poo'. */
112         memset(&s, 0, sizeof(s));
113         memset(buf, 0xcc, sizeof(buf));
114         ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
115         ATF_REQUIRE(c16rtomb(buf, 0xdca9, &s) == 4);
116         ATF_REQUIRE((unsigned char)buf[0] == 0xf0 && (unsigned char)buf[1] == 0x9f &&
117             (unsigned char)buf[2] == 0x92 && (unsigned char)buf[3] == 0xa9 &&
118             (unsigned char)buf[4] == 0xcc);
119
120         /* Invalid code; 'Pile of poo' without the trail surrogate. */
121         memset(&s, 0, sizeof(s));
122         memset(buf, 0xcc, sizeof(buf));
123         ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
124         ATF_REQUIRE(c16rtomb(buf, L'A', &s) == (size_t)-1);
125         ATF_REQUIRE(errno == EILSEQ);
126         ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
127
128         /* Invalid code; 'Pile of poo' without the lead surrogate. */
129         memset(&s, 0, sizeof(s));
130         memset(buf, 0xcc, sizeof(buf));
131         ATF_REQUIRE(c16rtomb(buf, 0xdca9, &s) == (size_t)-1);
132         ATF_REQUIRE(errno == EILSEQ);
133         ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
134 }
135
136 ATF_TP_ADD_TCS(tp)
137 {
138
139         ATF_TP_ADD_TC(tp, c16rtomb_test);
140
141         return (atf_no_error());
142 }