blob: f6c26837c3aa6e40b835be4df41a01a744eb4127 [file] [log] [blame]
Elliott Hughes77e944f2014-04-04 17:34:51 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
Elliott Hughes05493712014-04-17 17:30:03 -070019#include <errno.h>
Elliott Hughes77e944f2014-04-04 17:34:51 -070020#include <limits.h>
Elliott Hughes3d7a0d92014-04-29 14:46:56 -070021#include <stdint.h>
Elliott Hughes77e944f2014-04-04 17:34:51 -070022#include <wchar.h>
23
24TEST(wchar, sizeof_wchar_t) {
25 EXPECT_EQ(4U, sizeof(wchar_t));
26 EXPECT_EQ(4U, sizeof(wint_t));
27}
28
29TEST(wchar, mbrlen) {
30 char bytes[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
31 EXPECT_EQ(0U, mbrlen(&bytes[0], 0, NULL));
32 EXPECT_EQ(1U, mbrlen(&bytes[0], 1, NULL));
33
34 EXPECT_EQ(1U, mbrlen(&bytes[4], 1, NULL));
35 EXPECT_EQ(0U, mbrlen(&bytes[5], 1, NULL));
36}
37
38TEST(wchar, wctomb_wcrtomb) {
39 // wctomb and wcrtomb behave differently when s == NULL.
40 EXPECT_EQ(0, wctomb(NULL, L'h'));
41 EXPECT_EQ(0, wctomb(NULL, L'\0'));
42 EXPECT_EQ(1U, wcrtomb(NULL, L'\0', NULL));
43 EXPECT_EQ(1U, wcrtomb(NULL, L'h', NULL));
44
45 char bytes[MB_LEN_MAX];
46
47 // wctomb and wcrtomb behave similarly for the null wide character.
48 EXPECT_EQ(1, wctomb(bytes, L'\0'));
49 EXPECT_EQ(1U, wcrtomb(bytes, L'\0', NULL));
50
51 // ...and for regular characters.
52 bytes[0] = 'x';
53 EXPECT_EQ(1, wctomb(bytes, L'h'));
54 EXPECT_EQ('h', bytes[0]);
55
56 bytes[0] = 'x';
57 EXPECT_EQ(1U, wcrtomb(bytes, L'h', NULL));
58 EXPECT_EQ('h', bytes[0]);
59}
Elliott Hughes05493712014-04-17 17:30:03 -070060
61TEST(wchar, wcstombs_wcrtombs) {
Elliott Hughes1b836ee2014-04-18 13:32:33 -070062 const wchar_t chars[] = { L'h', L'e', L'l', L'l', L'o', 0 };
63 const wchar_t bad_chars[] = { L'h', L'i', 666, 0 };
Elliott Hughes05493712014-04-17 17:30:03 -070064 const wchar_t* src;
65 char bytes[BUFSIZ];
66
67 // Given a NULL destination, these functions count valid characters.
68 EXPECT_EQ(5U, wcstombs(NULL, chars, 0));
69 EXPECT_EQ(5U, wcstombs(NULL, chars, 4));
70 EXPECT_EQ(5U, wcstombs(NULL, chars, 256));
71 src = chars;
72 EXPECT_EQ(5U, wcsrtombs(NULL, &src, 0, NULL));
73 EXPECT_EQ(&chars[0], src);
74 src = chars;
75 EXPECT_EQ(5U, wcsrtombs(NULL, &src, 4, NULL));
76 EXPECT_EQ(&chars[0], src);
77 src = chars;
78 EXPECT_EQ(5U, wcsrtombs(NULL, &src, 256, NULL));
79 EXPECT_EQ(&chars[0], src);
80
81 // An unrepresentable char just returns an error from wcstombs...
82 errno = 0;
83 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(NULL, bad_chars, 0));
84 EXPECT_EQ(EILSEQ, errno);
85 errno = 0;
86 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(NULL, bad_chars, 256));
87 EXPECT_EQ(EILSEQ, errno);
88
89 // And wcsrtombs doesn't tell us where it got stuck because we didn't ask it
90 // to actually convert anything...
91 errno = 0;
92 src = bad_chars;
93 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 0, NULL));
94 EXPECT_EQ(&bad_chars[0], src);
95 EXPECT_EQ(EILSEQ, errno);
96 errno = 0;
97 src = bad_chars;
98 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 256, NULL));
99 EXPECT_EQ(&bad_chars[0], src);
100 EXPECT_EQ(EILSEQ, errno);
101
102 // Okay, now let's test actually converting something...
103 memset(bytes, 'x', sizeof(bytes));
104 EXPECT_EQ(0U, wcstombs(bytes, chars, 0));
105 memset(bytes, 'x', sizeof(bytes));
106 EXPECT_EQ(4U, wcstombs(bytes, chars, 4));
107 bytes[5] = 0;
108 EXPECT_STREQ("hellx", bytes);
109 memset(bytes, 'x', sizeof(bytes));
110 EXPECT_EQ(5U, wcstombs(bytes, chars, 256));
111 EXPECT_STREQ("hello", bytes);
112 memset(bytes, 'x', sizeof(bytes));
113 EXPECT_EQ(5U, wcstombs(bytes, chars, 6));
114 EXPECT_STREQ("hello", bytes);
115 errno = 0;
116 memset(bytes, 'x', sizeof(bytes));
117 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(bytes, bad_chars, 256));
118 EXPECT_EQ(EILSEQ, errno);
119 bytes[3] = 0;
120 EXPECT_STREQ("hix", bytes);
121
122 // wcsrtombs is a bit more informative...
123 memset(bytes, 'x', sizeof(bytes));
124 src = chars;
125 EXPECT_EQ(0U, wcsrtombs(bytes, &src, 0, NULL));
126 EXPECT_EQ(&chars[0], src); // No input consumed.
127 EXPECT_EQ(EILSEQ, errno);
128
129 memset(bytes, 'x', sizeof(bytes));
130 src = chars;
131 EXPECT_EQ(4U, wcsrtombs(bytes, &src, 4, NULL));
132 EXPECT_EQ(&chars[4], src); // Some input consumed.
133 EXPECT_EQ(EILSEQ, errno);
134 bytes[5] = 0;
135 EXPECT_STREQ("hellx", bytes);
136
137 memset(bytes, 'x', sizeof(bytes));
138 src = chars;
139 EXPECT_EQ(5U, wcsrtombs(bytes, &src, 256, NULL));
140 EXPECT_EQ(NULL, src); // All input consumed!
141 EXPECT_EQ(EILSEQ, errno);
142 EXPECT_STREQ("hello", bytes);
143
144 memset(bytes, 'x', sizeof(bytes));
145 src = chars;
146 EXPECT_EQ(5U, wcsrtombs(bytes, &src, 6, NULL));
147 EXPECT_EQ(NULL, src); // All input consumed.
148 EXPECT_EQ(EILSEQ, errno);
149 EXPECT_STREQ("hello", bytes);
150
151 memset(bytes, 'x', sizeof(bytes));
152 src = bad_chars;
153 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(bytes, &src, 256, NULL));
154 EXPECT_EQ(&bad_chars[2], src);
155 EXPECT_EQ(EILSEQ, errno);
156 bytes[3] = 0;
157 EXPECT_STREQ("hix", bytes);
158}
Elliott Hughes83c07b52014-04-21 18:09:46 -0700159
160TEST(wchar, limits) {
161 ASSERT_LT(WCHAR_MIN, WCHAR_MAX);
162}
Elliott Hughesd299bcf2014-04-28 16:28:51 -0700163
164TEST(wchar, wcsstr_wcswcs) {
165 const wchar_t* haystack = L"matches hello world, not the second hello world";
166 const wchar_t* empty_needle = L"";
167 const wchar_t* good_needle = L"ll";
168 const wchar_t* bad_needle = L"wort";
169
170 ASSERT_EQ(haystack, wcsstr(haystack, empty_needle));
171 ASSERT_EQ(&haystack[10], wcsstr(haystack, good_needle));
172 ASSERT_EQ(NULL, wcsstr(haystack, bad_needle));
173
174 ASSERT_EQ(haystack, wcswcs(haystack, empty_needle));
175 ASSERT_EQ(&haystack[10], wcswcs(haystack, good_needle));
176 ASSERT_EQ(NULL, wcswcs(haystack, bad_needle));
177}
Elliott Hughes0a5e26d2014-04-28 17:51:13 -0700178
179TEST(wchar, mbtowc) {
180 wchar_t out[8];
181
182 out[0] = 'x';
183 ASSERT_EQ(0, mbtowc(out, "hello", 0));
184 ASSERT_EQ('x', out[0]);
185
186 ASSERT_EQ(0, mbtowc(out, "hello", 0));
187 ASSERT_EQ(0, mbtowc(out, "", 0));
188 ASSERT_EQ(1, mbtowc(out, "hello", 1));
189 ASSERT_EQ(L'h', out[0]);
190
191 ASSERT_EQ(0, mbtowc(NULL, "hello", 0));
192 ASSERT_EQ(0, mbtowc(NULL, "", 0));
193 ASSERT_EQ(1, mbtowc(NULL, "hello", 1));
194
195 ASSERT_EQ(0, mbtowc(NULL, NULL, 0));
196}
197
198TEST(wchar, mbrtowc) {
199 wchar_t out[8];
200
201 out[0] = 'x';
202 ASSERT_EQ(0U, mbrtowc(out, "hello", 0, NULL));
203 ASSERT_EQ('x', out[0]);
204
205 ASSERT_EQ(0U, mbrtowc(out, "hello", 0, NULL));
206 ASSERT_EQ(0U, mbrtowc(out, "", 0, NULL));
207 ASSERT_EQ(1U, mbrtowc(out, "hello", 1, NULL));
208 ASSERT_EQ(L'h', out[0]);
209
210 ASSERT_EQ(0U, mbrtowc(NULL, "hello", 0, NULL));
211 ASSERT_EQ(0U, mbrtowc(NULL, "", 0, NULL));
212 ASSERT_EQ(1U, mbrtowc(NULL, "hello", 1, NULL));
213
214 ASSERT_EQ(0U, mbrtowc(NULL, NULL, 0, NULL));
215}
Elliott Hughes3d7a0d92014-04-29 14:46:56 -0700216
217TEST(wchar, wcstod) {
218 ASSERT_DOUBLE_EQ(1.23, wcstod(L"1.23", NULL));
219}
220
221TEST(wchar, wcstof) {
222 ASSERT_FLOAT_EQ(1.23f, wcstof(L"1.23", NULL));
223}
224
225TEST(wchar, wcstol) {
226 ASSERT_EQ(123L, wcstol(L"123", NULL, 0));
227}
228
229TEST(wchar, wcstoll) {
230 ASSERT_EQ(123LL, wcstol(L"123", NULL, 0));
231}
232
233TEST(wchar, wcstold) {
234 ASSERT_DOUBLE_EQ(1.23L, wcstold(L"1.23", NULL));
235}
236
237TEST(wchar, wcstoul) {
238 ASSERT_EQ(123UL, wcstoul(L"123", NULL, 0));
239}
240
241TEST(wchar, wcstoull) {
242 ASSERT_EQ(123ULL, wcstoul(L"123", NULL, 0));
243}
244
245TEST(wchar, mbsnrtowcs) {
246 wchar_t dst[128];
247 const char* s = "hello, world!";
248 const char* src;
249
250 memset(dst, 0, sizeof(dst));
251 src = s;
252 ASSERT_EQ(0U, mbsnrtowcs(dst, &src, 0, 0, NULL));
253
254 memset(dst, 0, sizeof(dst));
255 src = s;
256 ASSERT_EQ(2U, mbsnrtowcs(dst, &src, 2, 123, NULL)); // glibc chokes on SIZE_MAX here.
257 ASSERT_EQ(L'h', dst[0]);
258 ASSERT_EQ(L'e', dst[1]);
259 ASSERT_EQ(&s[2], src);
260
261 memset(dst, 0, sizeof(dst));
262 src = s;
263 ASSERT_EQ(3U, mbsnrtowcs(dst, &src, SIZE_MAX, 3, NULL));
264 ASSERT_EQ(L'h', dst[0]);
265 ASSERT_EQ(L'e', dst[1]);
266 ASSERT_EQ(L'l', dst[2]);
267 ASSERT_EQ(&s[3], src);
268}