blob: eff845a0e21a74f955894aac5f6236b733a39f07 [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>
21#include <wchar.h>
22
23TEST(wchar, sizeof_wchar_t) {
24 EXPECT_EQ(4U, sizeof(wchar_t));
25 EXPECT_EQ(4U, sizeof(wint_t));
26}
27
28TEST(wchar, mbrlen) {
29 char bytes[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
30 EXPECT_EQ(0U, mbrlen(&bytes[0], 0, NULL));
31 EXPECT_EQ(1U, mbrlen(&bytes[0], 1, NULL));
32
33 EXPECT_EQ(1U, mbrlen(&bytes[4], 1, NULL));
34 EXPECT_EQ(0U, mbrlen(&bytes[5], 1, NULL));
35}
36
37TEST(wchar, wctomb_wcrtomb) {
38 // wctomb and wcrtomb behave differently when s == NULL.
39 EXPECT_EQ(0, wctomb(NULL, L'h'));
40 EXPECT_EQ(0, wctomb(NULL, L'\0'));
41 EXPECT_EQ(1U, wcrtomb(NULL, L'\0', NULL));
42 EXPECT_EQ(1U, wcrtomb(NULL, L'h', NULL));
43
44 char bytes[MB_LEN_MAX];
45
46 // wctomb and wcrtomb behave similarly for the null wide character.
47 EXPECT_EQ(1, wctomb(bytes, L'\0'));
48 EXPECT_EQ(1U, wcrtomb(bytes, L'\0', NULL));
49
50 // ...and for regular characters.
51 bytes[0] = 'x';
52 EXPECT_EQ(1, wctomb(bytes, L'h'));
53 EXPECT_EQ('h', bytes[0]);
54
55 bytes[0] = 'x';
56 EXPECT_EQ(1U, wcrtomb(bytes, L'h', NULL));
57 EXPECT_EQ('h', bytes[0]);
58}
Elliott Hughes05493712014-04-17 17:30:03 -070059
60TEST(wchar, wcstombs_wcrtombs) {
Elliott Hughes1b836ee2014-04-18 13:32:33 -070061 const wchar_t chars[] = { L'h', L'e', L'l', L'l', L'o', 0 };
62 const wchar_t bad_chars[] = { L'h', L'i', 666, 0 };
Elliott Hughes05493712014-04-17 17:30:03 -070063 const wchar_t* src;
64 char bytes[BUFSIZ];
65
66 // Given a NULL destination, these functions count valid characters.
67 EXPECT_EQ(5U, wcstombs(NULL, chars, 0));
68 EXPECT_EQ(5U, wcstombs(NULL, chars, 4));
69 EXPECT_EQ(5U, wcstombs(NULL, chars, 256));
70 src = chars;
71 EXPECT_EQ(5U, wcsrtombs(NULL, &src, 0, NULL));
72 EXPECT_EQ(&chars[0], src);
73 src = chars;
74 EXPECT_EQ(5U, wcsrtombs(NULL, &src, 4, NULL));
75 EXPECT_EQ(&chars[0], src);
76 src = chars;
77 EXPECT_EQ(5U, wcsrtombs(NULL, &src, 256, NULL));
78 EXPECT_EQ(&chars[0], src);
79
80 // An unrepresentable char just returns an error from wcstombs...
81 errno = 0;
82 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(NULL, bad_chars, 0));
83 EXPECT_EQ(EILSEQ, errno);
84 errno = 0;
85 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(NULL, bad_chars, 256));
86 EXPECT_EQ(EILSEQ, errno);
87
88 // And wcsrtombs doesn't tell us where it got stuck because we didn't ask it
89 // to actually convert anything...
90 errno = 0;
91 src = bad_chars;
92 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 0, NULL));
93 EXPECT_EQ(&bad_chars[0], src);
94 EXPECT_EQ(EILSEQ, errno);
95 errno = 0;
96 src = bad_chars;
97 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 256, NULL));
98 EXPECT_EQ(&bad_chars[0], src);
99 EXPECT_EQ(EILSEQ, errno);
100
101 // Okay, now let's test actually converting something...
102 memset(bytes, 'x', sizeof(bytes));
103 EXPECT_EQ(0U, wcstombs(bytes, chars, 0));
104 memset(bytes, 'x', sizeof(bytes));
105 EXPECT_EQ(4U, wcstombs(bytes, chars, 4));
106 bytes[5] = 0;
107 EXPECT_STREQ("hellx", bytes);
108 memset(bytes, 'x', sizeof(bytes));
109 EXPECT_EQ(5U, wcstombs(bytes, chars, 256));
110 EXPECT_STREQ("hello", bytes);
111 memset(bytes, 'x', sizeof(bytes));
112 EXPECT_EQ(5U, wcstombs(bytes, chars, 6));
113 EXPECT_STREQ("hello", bytes);
114 errno = 0;
115 memset(bytes, 'x', sizeof(bytes));
116 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(bytes, bad_chars, 256));
117 EXPECT_EQ(EILSEQ, errno);
118 bytes[3] = 0;
119 EXPECT_STREQ("hix", bytes);
120
121 // wcsrtombs is a bit more informative...
122 memset(bytes, 'x', sizeof(bytes));
123 src = chars;
124 EXPECT_EQ(0U, wcsrtombs(bytes, &src, 0, NULL));
125 EXPECT_EQ(&chars[0], src); // No input consumed.
126 EXPECT_EQ(EILSEQ, errno);
127
128 memset(bytes, 'x', sizeof(bytes));
129 src = chars;
130 EXPECT_EQ(4U, wcsrtombs(bytes, &src, 4, NULL));
131 EXPECT_EQ(&chars[4], src); // Some input consumed.
132 EXPECT_EQ(EILSEQ, errno);
133 bytes[5] = 0;
134 EXPECT_STREQ("hellx", bytes);
135
136 memset(bytes, 'x', sizeof(bytes));
137 src = chars;
138 EXPECT_EQ(5U, wcsrtombs(bytes, &src, 256, NULL));
139 EXPECT_EQ(NULL, src); // All input consumed!
140 EXPECT_EQ(EILSEQ, errno);
141 EXPECT_STREQ("hello", bytes);
142
143 memset(bytes, 'x', sizeof(bytes));
144 src = chars;
145 EXPECT_EQ(5U, wcsrtombs(bytes, &src, 6, NULL));
146 EXPECT_EQ(NULL, src); // All input consumed.
147 EXPECT_EQ(EILSEQ, errno);
148 EXPECT_STREQ("hello", bytes);
149
150 memset(bytes, 'x', sizeof(bytes));
151 src = bad_chars;
152 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(bytes, &src, 256, NULL));
153 EXPECT_EQ(&bad_chars[2], src);
154 EXPECT_EQ(EILSEQ, errno);
155 bytes[3] = 0;
156 EXPECT_STREQ("hix", bytes);
157}
Elliott Hughes83c07b52014-04-21 18:09:46 -0700158
159TEST(wchar, limits) {
160 ASSERT_LT(WCHAR_MIN, WCHAR_MAX);
161}
Elliott Hughesd299bcf2014-04-28 16:28:51 -0700162
163TEST(wchar, wcsstr_wcswcs) {
164 const wchar_t* haystack = L"matches hello world, not the second hello world";
165 const wchar_t* empty_needle = L"";
166 const wchar_t* good_needle = L"ll";
167 const wchar_t* bad_needle = L"wort";
168
169 ASSERT_EQ(haystack, wcsstr(haystack, empty_needle));
170 ASSERT_EQ(&haystack[10], wcsstr(haystack, good_needle));
171 ASSERT_EQ(NULL, wcsstr(haystack, bad_needle));
172
173 ASSERT_EQ(haystack, wcswcs(haystack, empty_needle));
174 ASSERT_EQ(&haystack[10], wcswcs(haystack, good_needle));
175 ASSERT_EQ(NULL, wcswcs(haystack, bad_needle));
176}