wchar_test.cpp revision d299bcfdad959a3a0adf1683605b15a1c3b3ab66
1/*
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
19#include <errno.h>
20#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}
59
60TEST(wchar, wcstombs_wcrtombs) {
61  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 };
63  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}
158
159TEST(wchar, limits) {
160  ASSERT_LT(WCHAR_MIN, WCHAR_MAX);
161}
162
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}
177