Home | History | Annotate | Download | only in tests
      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 <locale.h>
     22 #include <stdint.h>
     23 #include <wchar.h>
     24 
     25 #include "math_data_test.h"
     26 
     27 #define NUM_WCHARS(num_bytes) ((num_bytes)/sizeof(wchar_t))
     28 
     29 TEST(wchar, sizeof_wchar_t) {
     30   EXPECT_EQ(4U, sizeof(wchar_t));
     31   EXPECT_EQ(4U, sizeof(wint_t));
     32 }
     33 
     34 TEST(wchar, mbrlen) {
     35   char bytes[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
     36   EXPECT_EQ(0U, mbrlen(&bytes[0], 0, NULL));
     37   EXPECT_EQ(1U, mbrlen(&bytes[0], 1, NULL));
     38 
     39   EXPECT_EQ(1U, mbrlen(&bytes[4], 1, NULL));
     40   EXPECT_EQ(0U, mbrlen(&bytes[5], 1, NULL));
     41 }
     42 
     43 TEST(wchar, wctomb_wcrtomb) {
     44   // wctomb and wcrtomb behave differently when s == NULL.
     45   EXPECT_EQ(0, wctomb(NULL, L'h'));
     46   EXPECT_EQ(0, wctomb(NULL, L'\0'));
     47   EXPECT_EQ(1U, wcrtomb(NULL, L'\0', NULL));
     48   EXPECT_EQ(1U, wcrtomb(NULL, L'h', NULL));
     49 
     50   char bytes[MB_LEN_MAX];
     51 
     52   // wctomb and wcrtomb behave similarly for the null wide character.
     53   EXPECT_EQ(1, wctomb(bytes, L'\0'));
     54   EXPECT_EQ(1U, wcrtomb(bytes, L'\0', NULL));
     55 
     56   // ...and for regular characters.
     57   memset(bytes, 0, sizeof(bytes));
     58   EXPECT_EQ(1, wctomb(bytes, L'h'));
     59   EXPECT_EQ('h', bytes[0]);
     60   memset(bytes, 0, sizeof(bytes));
     61   EXPECT_EQ(1U, wcrtomb(bytes, L'h', NULL));
     62   EXPECT_EQ('h', bytes[0]);
     63 
     64   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
     65   uselocale(LC_GLOBAL_LOCALE);
     66 
     67   // 1-byte UTF-8.
     68   memset(bytes, 0, sizeof(bytes));
     69   EXPECT_EQ(1U, wcrtomb(bytes, L'h', NULL));
     70   EXPECT_EQ('h', bytes[0]);
     71   // 2-byte UTF-8.
     72   memset(bytes, 0, sizeof(bytes));
     73   EXPECT_EQ(2U, wcrtomb(bytes, 0x00a2, NULL));
     74   EXPECT_EQ('\xc2', bytes[0]);
     75   EXPECT_EQ('\xa2', bytes[1]);
     76   // 3-byte UTF-8.
     77   memset(bytes, 0, sizeof(bytes));
     78   EXPECT_EQ(3U, wcrtomb(bytes, 0x20ac, NULL));
     79   EXPECT_EQ('\xe2', bytes[0]);
     80   EXPECT_EQ('\x82', bytes[1]);
     81   EXPECT_EQ('\xac', bytes[2]);
     82   // 4-byte UTF-8.
     83   memset(bytes, 0, sizeof(bytes));
     84   EXPECT_EQ(4U, wcrtomb(bytes, 0x24b62, NULL));
     85   EXPECT_EQ('\xf0', bytes[0]);
     86   EXPECT_EQ('\xa4', bytes[1]);
     87   EXPECT_EQ('\xad', bytes[2]);
     88   EXPECT_EQ('\xa2', bytes[3]);
     89   // Invalid code point.
     90   EXPECT_EQ(static_cast<size_t>(-1), wcrtomb(bytes, 0xffffffff, NULL));
     91   EXPECT_EQ(EILSEQ, errno);
     92 }
     93 
     94 TEST(wchar, wcrtomb_start_state) {
     95   char out[MB_LEN_MAX];
     96   mbstate_t ps;
     97 
     98   // Any non-initial state is invalid when calling wcrtomb.
     99   memset(&ps, 0, sizeof(ps));
    100   EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(NULL, "\xc2", 1, &ps));
    101   EXPECT_EQ(static_cast<size_t>(-1), wcrtomb(out, 0x00a2, &ps));
    102   EXPECT_EQ(EILSEQ, errno);
    103 
    104   // If the first argument to wcrtomb is NULL or the second is L'\0' the shift
    105   // state should be reset.
    106   memset(&ps, 0, sizeof(ps));
    107   EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(NULL, "\xc2", 1, &ps));
    108   EXPECT_EQ(1U, wcrtomb(NULL, 0x00a2, &ps));
    109   EXPECT_TRUE(mbsinit(&ps));
    110 
    111   memset(&ps, 0, sizeof(ps));
    112   EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(NULL, "\xf0\xa4", 1, &ps));
    113   EXPECT_EQ(1U, wcrtomb(out, L'\0', &ps));
    114   EXPECT_TRUE(mbsinit(&ps));
    115 }
    116 
    117 TEST(wchar, wcstombs_wcrtombs) {
    118   const wchar_t chars[] = { L'h', L'e', L'l', L'l', L'o', 0 };
    119   const wchar_t bad_chars[] = { L'h', L'i', static_cast<wchar_t>(0xffffffff), 0 };
    120   const wchar_t* src;
    121   char bytes[BUFSIZ];
    122 
    123   // Given a NULL destination, these functions count valid characters.
    124   EXPECT_EQ(5U, wcstombs(NULL, chars, 0));
    125   EXPECT_EQ(5U, wcstombs(NULL, chars, 4));
    126   EXPECT_EQ(5U, wcstombs(NULL, chars, 256));
    127   src = chars;
    128   EXPECT_EQ(5U, wcsrtombs(NULL, &src, 0, NULL));
    129   EXPECT_EQ(&chars[0], src);
    130   src = chars;
    131   EXPECT_EQ(5U, wcsrtombs(NULL, &src, 4, NULL));
    132   EXPECT_EQ(&chars[0], src);
    133   src = chars;
    134   EXPECT_EQ(5U, wcsrtombs(NULL, &src, 256, NULL));
    135   EXPECT_EQ(&chars[0], src);
    136 
    137   // An unrepresentable char just returns an error from wcstombs...
    138   errno = 0;
    139   EXPECT_EQ(static_cast<size_t>(-1), wcstombs(NULL, bad_chars, 0));
    140   EXPECT_EQ(EILSEQ, errno);
    141   errno = 0;
    142   EXPECT_EQ(static_cast<size_t>(-1), wcstombs(NULL, bad_chars, 256));
    143   EXPECT_EQ(EILSEQ, errno);
    144 
    145   // And wcsrtombs doesn't tell us where it got stuck because we didn't ask it
    146   // to actually convert anything...
    147   errno = 0;
    148   src = bad_chars;
    149   EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 0, NULL));
    150   EXPECT_EQ(&bad_chars[0], src);
    151   EXPECT_EQ(EILSEQ, errno);
    152   errno = 0;
    153   src = bad_chars;
    154   EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 256, NULL));
    155   EXPECT_EQ(&bad_chars[0], src);
    156   EXPECT_EQ(EILSEQ, errno);
    157 
    158   // Okay, now let's test actually converting something...
    159   memset(bytes, 'x', sizeof(bytes));
    160   EXPECT_EQ(0U, wcstombs(bytes, chars, 0));
    161   memset(bytes, 'x', sizeof(bytes));
    162   EXPECT_EQ(4U, wcstombs(bytes, chars, 4));
    163   bytes[5] = 0;
    164   EXPECT_STREQ("hellx", bytes);
    165   memset(bytes, 'x', sizeof(bytes));
    166   EXPECT_EQ(5U, wcstombs(bytes, chars, 256));
    167   EXPECT_STREQ("hello", bytes);
    168   memset(bytes, 'x', sizeof(bytes));
    169   EXPECT_EQ(5U, wcstombs(bytes, chars, 6));
    170   EXPECT_STREQ("hello", bytes);
    171   errno = 0;
    172   memset(bytes, 'x', sizeof(bytes));
    173   EXPECT_EQ(static_cast<size_t>(-1), wcstombs(bytes, bad_chars, 256));
    174   EXPECT_EQ(EILSEQ, errno);
    175   bytes[3] = 0;
    176   EXPECT_STREQ("hix", bytes);
    177 
    178   // wcsrtombs is a bit more informative...
    179   memset(bytes, 'x', sizeof(bytes));
    180   src = chars;
    181   EXPECT_EQ(0U, wcsrtombs(bytes, &src, 0, NULL));
    182   EXPECT_EQ(&chars[0], src); // No input consumed.
    183   EXPECT_EQ(EILSEQ, errno);
    184 
    185   memset(bytes, 'x', sizeof(bytes));
    186   src = chars;
    187   EXPECT_EQ(4U, wcsrtombs(bytes, &src, 4, NULL));
    188   EXPECT_EQ(&chars[4], src); // Some input consumed.
    189   EXPECT_EQ(EILSEQ, errno);
    190   bytes[5] = 0;
    191   EXPECT_STREQ("hellx", bytes);
    192 
    193   memset(bytes, 'x', sizeof(bytes));
    194   src = chars;
    195   EXPECT_EQ(5U, wcsrtombs(bytes, &src, 256, NULL));
    196   EXPECT_EQ(NULL, src); // All input consumed!
    197   EXPECT_EQ(EILSEQ, errno);
    198   EXPECT_STREQ("hello", bytes);
    199 
    200   memset(bytes, 'x', sizeof(bytes));
    201   src = chars;
    202   EXPECT_EQ(5U, wcsrtombs(bytes, &src, 6, NULL));
    203   EXPECT_EQ(NULL, src); // All input consumed.
    204   EXPECT_EQ(EILSEQ, errno);
    205   EXPECT_STREQ("hello", bytes);
    206 
    207   memset(bytes, 'x', sizeof(bytes));
    208   src = bad_chars;
    209   EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(bytes, &src, 256, NULL));
    210   EXPECT_EQ(&bad_chars[2], src);
    211   EXPECT_EQ(EILSEQ, errno);
    212   bytes[3] = 0;
    213   EXPECT_STREQ("hix", bytes);
    214 
    215   // Any non-initial state is invalid when calling wcsrtombs.
    216   mbstate_t ps;
    217   src = chars;
    218   memset(&ps, 0, sizeof(ps));
    219   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(NULL, "\xc2", 1, &ps));
    220   EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(NULL, &src, 0, &ps));
    221   EXPECT_EQ(EILSEQ, errno);
    222 }
    223 
    224 TEST(wchar, limits) {
    225   ASSERT_LT(WCHAR_MIN, WCHAR_MAX);
    226 }
    227 
    228 TEST(wchar, wcsstr) {
    229   const wchar_t* haystack = L"matches hello world, not the second hello world";
    230   const wchar_t* empty_needle = L"";
    231   const wchar_t* good_needle = L"ll";
    232   const wchar_t* bad_needle = L"wort";
    233 
    234   ASSERT_EQ(haystack, wcsstr(haystack, empty_needle));
    235   ASSERT_EQ(&haystack[10], wcsstr(haystack, good_needle));
    236   ASSERT_EQ(NULL, wcsstr(haystack, bad_needle));
    237 }
    238 
    239 TEST(wchar, wcsstr_80199) {
    240   // https://code.google.com/p/android/issues/detail?id=80199
    241   ASSERT_TRUE(wcsstr(L"romrom", L"rom") != NULL);
    242 }
    243 
    244 TEST(wchar, mbtowc) {
    245   wchar_t out[8];
    246 
    247   out[0] = 'x';
    248   ASSERT_EQ(0, mbtowc(out, "hello", 0));
    249   ASSERT_EQ('x', out[0]);
    250 
    251   ASSERT_EQ(0, mbtowc(out, "hello", 0));
    252   ASSERT_EQ(0, mbtowc(out, "", 0));
    253   ASSERT_EQ(1, mbtowc(out, "hello", 1));
    254   ASSERT_EQ(L'h', out[0]);
    255 
    256   ASSERT_EQ(0, mbtowc(NULL, "hello", 0));
    257   ASSERT_EQ(0, mbtowc(NULL, "", 0));
    258   ASSERT_EQ(1, mbtowc(NULL, "hello", 1));
    259 
    260   ASSERT_EQ(0, mbtowc(NULL, NULL, 0));
    261 }
    262 
    263 TEST(wchar, mbrtowc) {
    264   wchar_t out[8];
    265 
    266   out[0] = 'x';
    267   ASSERT_EQ(0U, mbrtowc(out, "hello", 0, NULL));
    268   ASSERT_EQ('x', out[0]);
    269 
    270   ASSERT_EQ(0U, mbrtowc(out, "hello", 0, NULL));
    271   ASSERT_EQ(0U, mbrtowc(out, "", 0, NULL));
    272   ASSERT_EQ(1U, mbrtowc(out, "hello", 1, NULL));
    273   ASSERT_EQ(L'h', out[0]);
    274 
    275   ASSERT_EQ(0U, mbrtowc(NULL, "hello", 0, NULL));
    276   ASSERT_EQ(0U, mbrtowc(NULL, "", 0, NULL));
    277   ASSERT_EQ(1U, mbrtowc(NULL, "hello", 1, NULL));
    278 
    279   ASSERT_EQ(0U, mbrtowc(NULL, NULL, 0, NULL));
    280 
    281   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
    282   uselocale(LC_GLOBAL_LOCALE);
    283 
    284   // 1-byte UTF-8.
    285   ASSERT_EQ(1U, mbrtowc(out, "abcdef", 6, NULL));
    286   ASSERT_EQ(L'a', out[0]);
    287   // 2-byte UTF-8.
    288   ASSERT_EQ(2U, mbrtowc(out, "\xc2\xa2" "cdef", 6, NULL));
    289   ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[0]);
    290   // 3-byte UTF-8.
    291   ASSERT_EQ(3U, mbrtowc(out, "\xe2\x82\xac" "def", 6, NULL));
    292   ASSERT_EQ(static_cast<wchar_t>(0x20ac), out[0]);
    293   // 4-byte UTF-8.
    294   ASSERT_EQ(4U, mbrtowc(out, "\xf0\xa4\xad\xa2" "ef", 6, NULL));
    295   ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[0]);
    296 #if defined(__BIONIC__) // glibc allows this.
    297   // Illegal 5-byte UTF-8.
    298   ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, NULL));
    299   ASSERT_EQ(EILSEQ, errno);
    300 #endif
    301   // Illegal over-long sequence.
    302   ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf0\x82\x82\xac" "ef", 6, NULL));
    303   ASSERT_EQ(EILSEQ, errno);
    304 }
    305 
    306 static void test_mbrtowc_incomplete(mbstate_t* ps) {
    307   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
    308   uselocale(LC_GLOBAL_LOCALE);
    309 
    310   wchar_t out;
    311   // 2-byte UTF-8.
    312   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xc2", 1, ps));
    313   ASSERT_EQ(1U, mbrtowc(&out, "\xa2" "cdef", 5, ps));
    314   ASSERT_EQ(static_cast<wchar_t>(0x00a2), out);
    315   ASSERT_TRUE(mbsinit(ps));
    316   // 3-byte UTF-8.
    317   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xe2", 1, ps));
    318   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\x82", 1, ps));
    319   ASSERT_EQ(1U, mbrtowc(&out, "\xac" "def", 4, ps));
    320   ASSERT_EQ(static_cast<wchar_t>(0x20ac), out);
    321   ASSERT_TRUE(mbsinit(ps));
    322   // 4-byte UTF-8.
    323   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xf0", 1, ps));
    324   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xa4\xad", 2, ps));
    325   ASSERT_EQ(1U, mbrtowc(&out, "\xa2" "ef", 3, ps));
    326   ASSERT_EQ(static_cast<wchar_t>(0x24b62), out);
    327   ASSERT_TRUE(mbsinit(ps));
    328 
    329   // Invalid 2-byte
    330   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xc2", 1, ps));
    331   ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(&out, "\x20" "cdef", 5, ps));
    332   ASSERT_EQ(EILSEQ, errno);
    333 }
    334 
    335 TEST(wchar, mbrtowc_incomplete) {
    336   mbstate_t ps;
    337   memset(&ps, 0, sizeof(ps));
    338 
    339   test_mbrtowc_incomplete(&ps);
    340   test_mbrtowc_incomplete(NULL);
    341 }
    342 
    343 static void test_mbsrtowcs(mbstate_t* ps) {
    344   constexpr const char* VALID = "A" "\xc2\xa2" "\xe2\x82\xac" "\xf0\xa4\xad\xa2" "ef";
    345   constexpr const char* INVALID = "A" "\xc2\x20" "ef";
    346   constexpr const char* INCOMPLETE = "A" "\xc2";
    347   wchar_t out[4];
    348 
    349   const char* valid = VALID;
    350   ASSERT_EQ(4U, mbsrtowcs(out, &valid, 4, ps));
    351   ASSERT_EQ(L'A', out[0]);
    352   ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[1]);
    353   ASSERT_EQ(static_cast<wchar_t>(0x20ac), out[2]);
    354   ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[3]);
    355   // Check that valid has advanced to the next unread character.
    356   ASSERT_EQ('e', *valid);
    357 
    358   wmemset(out, L'x', NUM_WCHARS(sizeof(out)));
    359   ASSERT_EQ(2U, mbsrtowcs(out, &valid, 4, ps));
    360   ASSERT_EQ(L'e', out[0]);
    361   ASSERT_EQ(L'f', out[1]);
    362   ASSERT_EQ(L'\0', out[2]);
    363   // Check that we didn't clobber the rest of out.
    364   ASSERT_EQ(L'x', out[3]);
    365   // Check that valid has advanced to the end of the string.
    366   ASSERT_EQ(nullptr, valid);
    367 
    368   const char* invalid = INVALID;
    369   ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &invalid, 4, ps));
    370   EXPECT_EQ(EILSEQ, errno);
    371   ASSERT_EQ('\xc2', *invalid);
    372 
    373   const char* incomplete = INCOMPLETE;
    374   ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &incomplete, 2, ps));
    375   EXPECT_EQ(EILSEQ, errno);
    376   ASSERT_EQ('\xc2', *incomplete);
    377 
    378   // If dst is null, *src shouldn't be updated.
    379   // https://code.google.com/p/android/issues/detail?id=166381
    380   const char* mbs = VALID;
    381   EXPECT_EQ(6U, mbsrtowcs(nullptr, &mbs, 0, ps));
    382   EXPECT_EQ(VALID, mbs);
    383   mbs = INVALID;
    384   EXPECT_EQ(static_cast<size_t>(-1), mbsrtowcs(nullptr, &mbs, 0, ps));
    385   EXPECT_EQ(INVALID, mbs);
    386   mbs = INCOMPLETE;
    387   EXPECT_EQ(static_cast<size_t>(-1), mbsrtowcs(nullptr, &mbs, 0, ps));
    388   EXPECT_EQ(INCOMPLETE, mbs);
    389 }
    390 
    391 TEST(wchar, mbsrtowcs) {
    392   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
    393   uselocale(LC_GLOBAL_LOCALE);
    394 
    395   mbstate_t ps;
    396   memset(&ps, 0, sizeof(ps));
    397   test_mbsrtowcs(&ps);
    398   test_mbsrtowcs(NULL);
    399 
    400   // Invalid multi byte continuation.
    401   const char* invalid = "\x20";
    402   wchar_t out;
    403   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xc2", 1, &ps));
    404   ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(&out, &invalid, 1, &ps));
    405   EXPECT_EQ(EILSEQ, errno);
    406   ASSERT_EQ('\x20', *invalid);
    407 }
    408 
    409 TEST(wchar, wcstol) {
    410   ASSERT_EQ(123L, wcstol(L"123", NULL, 0));
    411 }
    412 
    413 TEST(wchar, wcstoll) {
    414   ASSERT_EQ(123LL, wcstol(L"123", NULL, 0));
    415 }
    416 
    417 TEST(wchar, wcstoul) {
    418   ASSERT_EQ(123UL, wcstoul(L"123", NULL, 0));
    419 }
    420 
    421 TEST(wchar, wcstoull) {
    422   ASSERT_EQ(123ULL, wcstoul(L"123", NULL, 0));
    423 }
    424 
    425 TEST(wchar, mbsnrtowcs) {
    426   wchar_t dst[128];
    427   const char* s = "hello, world!";
    428   const char* src;
    429 
    430   memset(dst, 0, sizeof(dst));
    431   src = s;
    432   ASSERT_EQ(0U, mbsnrtowcs(dst, &src, 0, 0, NULL));
    433 
    434   memset(dst, 0, sizeof(dst));
    435   src = s;
    436   ASSERT_EQ(2U, mbsnrtowcs(dst, &src, 2, 123, NULL)); // glibc chokes on SIZE_MAX here.
    437   ASSERT_EQ(L'h', dst[0]);
    438   ASSERT_EQ(L'e', dst[1]);
    439   ASSERT_EQ(&s[2], src);
    440 
    441   memset(dst, 0, sizeof(dst));
    442   src = s;
    443   ASSERT_EQ(3U, mbsnrtowcs(dst, &src, SIZE_MAX, 3, NULL));
    444   ASSERT_EQ(L'h', dst[0]);
    445   ASSERT_EQ(L'e', dst[1]);
    446   ASSERT_EQ(L'l', dst[2]);
    447   ASSERT_EQ(&s[3], src);
    448 
    449   memset(dst, 0, sizeof(dst));
    450   const char* incomplete = "\xc2"; // Incomplete UTF-8 sequence.
    451   src = incomplete;
    452   errno = 0;
    453   ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(dst, &src, SIZE_MAX, 3, nullptr));
    454   ASSERT_EQ(EILSEQ, errno);
    455 
    456   src = incomplete;
    457   errno = 0;
    458   ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(nullptr, &src, SIZE_MAX, 3, nullptr));
    459   ASSERT_EQ(EILSEQ, errno);
    460 }
    461 
    462 TEST(wchar, wcsftime) {
    463   setenv("TZ", "UTC", 1);
    464 
    465   struct tm t;
    466   memset(&t, 0, sizeof(tm));
    467   t.tm_year = 200;
    468   t.tm_mon = 2;
    469   t.tm_mday = 10;
    470 
    471   wchar_t buf[64];
    472 
    473   EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t));
    474   EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf);
    475 }
    476 
    477 TEST(wchar, wmemmove_smoke) {
    478   const wchar_t const_wstr[] = L"This is a test of something or other.....";
    479   wchar_t wstr[NUM_WCHARS(sizeof(const_wstr))];
    480 
    481   EXPECT_EQ(wstr, wmemmove(wstr, const_wstr, NUM_WCHARS(sizeof(const_wstr))));
    482   EXPECT_STREQ(const_wstr, wstr);
    483 
    484   EXPECT_EQ(wstr+5, wmemmove(wstr+5, wstr, NUM_WCHARS(sizeof(const_wstr)) - 6));
    485   EXPECT_STREQ(L"This This is a test of something or other", wstr);
    486 }
    487 
    488 TEST(wchar, wmemcpy_smoke) {
    489   const wchar_t src[] = L"Source string";
    490   wchar_t dst[NUM_WCHARS(sizeof(src))];
    491 
    492   EXPECT_EQ(dst, wmemcpy(dst, src, NUM_WCHARS(sizeof(src))));
    493   EXPECT_STREQ(dst, src);
    494 }
    495 
    496 TEST(wchar, wcpcpy_smoke) {
    497   const wchar_t src[] = L"Source string";
    498   wchar_t dst[NUM_WCHARS(sizeof(src))];
    499 
    500   EXPECT_EQ(dst + NUM_WCHARS(sizeof(src)) - 1, wcpcpy(dst, src));
    501   EXPECT_STREQ(dst, src);
    502 }
    503 
    504 TEST(wchar, wcpncpy_smoke) {
    505   const wchar_t src[] = L"Source string";
    506   wchar_t dst[NUM_WCHARS(sizeof(src)) + 5];
    507 
    508   size_t src_len = NUM_WCHARS(sizeof(src)) - 1;
    509   EXPECT_EQ(dst + src_len, wcpncpy(dst, src, src_len + 1));
    510   EXPECT_STREQ(dst, src);
    511 
    512   EXPECT_EQ(dst + 6, wcpncpy(dst, src, 6));
    513   dst[6] = L'\0';
    514   EXPECT_STREQ(dst, L"Source");
    515 
    516   wmemset(dst, L'x', NUM_WCHARS(sizeof(dst)));
    517   EXPECT_EQ(dst + src_len, wcpncpy(dst, src, src_len + 4));
    518   EXPECT_STREQ(dst, src);
    519   EXPECT_EQ(dst[src_len], L'\0');
    520   EXPECT_EQ(dst[src_len+1], L'\0');
    521   EXPECT_EQ(dst[src_len+2], L'\0');
    522   EXPECT_EQ(dst[src_len+3], L'\0');
    523   EXPECT_EQ(dst[src_len+4], L'x');
    524 }
    525 
    526 TEST(wchar, wcscpy_smoke) {
    527   const wchar_t src[] = L"Source string";
    528   wchar_t dst[NUM_WCHARS(sizeof(src))];
    529 
    530   EXPECT_EQ(dst, wcscpy(dst, src));
    531   EXPECT_STREQ(src, dst);
    532 }
    533 
    534 TEST(wchar, wcsncpy_smoke) {
    535   const wchar_t src[] = L"Source string";
    536   wchar_t dst[NUM_WCHARS(sizeof(src)) + 5];
    537 
    538   size_t src_len = NUM_WCHARS(sizeof(src)) - 1;
    539   EXPECT_EQ(dst, wcsncpy(dst, src, src_len + 1));
    540   EXPECT_STREQ(dst, src);
    541 
    542   EXPECT_EQ(dst, wcsncpy(dst, src, 6));
    543   dst[6] = L'\0';
    544   EXPECT_STREQ(dst, L"Source");
    545 
    546   wmemset(dst, L'x', NUM_WCHARS(sizeof(dst)));
    547   EXPECT_EQ(dst, wcsncpy(dst, src, src_len + 4));
    548   EXPECT_STREQ(dst, src);
    549   EXPECT_EQ(dst[src_len], L'\0');
    550   EXPECT_EQ(dst[src_len+1], L'\0');
    551   EXPECT_EQ(dst[src_len+2], L'\0');
    552   EXPECT_EQ(dst[src_len+3], L'\0');
    553   EXPECT_EQ(dst[src_len+4], L'x');
    554 }
    555 
    556 TEST(wchar, mbrtowc_15439554) {
    557   // http://b/15439554
    558   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
    559   uselocale(LC_GLOBAL_LOCALE);
    560 
    561   ASSERT_GE(static_cast<size_t>(MB_LEN_MAX), MB_CUR_MAX);
    562   ASSERT_GE(MB_CUR_MAX, 4U);
    563 
    564   wchar_t wc;
    565   size_t n;
    566 
    567   // 1-byte character.
    568   n = mbrtowc(&wc, "x", MB_CUR_MAX, NULL);
    569   EXPECT_EQ(1U, n);
    570   EXPECT_EQ(L'x', wc);
    571   // 2-byte character.
    572   n = mbrtowc(&wc, "\xc2\xa2", MB_CUR_MAX, NULL);
    573   EXPECT_EQ(2U, n);
    574   EXPECT_EQ(L'', wc);
    575   // 3-byte character.
    576   n = mbrtowc(&wc, "\xe2\x82\xac", MB_CUR_MAX, NULL);
    577   EXPECT_EQ(3U, n);
    578   EXPECT_EQ(L'', wc);
    579   // 4-byte character.
    580   n = mbrtowc(&wc, "\xf0\xa4\xad\xa2", MB_CUR_MAX, NULL);
    581   EXPECT_EQ(4U, n);
    582   EXPECT_EQ(L'', wc);
    583 }
    584 
    585 TEST(wchar, open_wmemstream) {
    586   wchar_t* p = nullptr;
    587   size_t size = 0;
    588   FILE* fp = open_wmemstream(&p, &size);
    589   ASSERT_NE(EOF, fputws(L"hello, world!", fp));
    590   fclose(fp);
    591 
    592   ASSERT_STREQ(L"hello, world!", p);
    593   ASSERT_EQ(wcslen(L"hello, world!"), size);
    594   free(p);
    595 }
    596 
    597 TEST(stdio, open_wmemstream_EINVAL) {
    598 #if defined(__BIONIC__)
    599   wchar_t* p;
    600   size_t size;
    601 
    602   // Invalid buffer.
    603   errno = 0;
    604   ASSERT_EQ(nullptr, open_wmemstream(nullptr, &size));
    605   ASSERT_EQ(EINVAL, errno);
    606 
    607   // Invalid size.
    608   errno = 0;
    609   ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr));
    610   ASSERT_EQ(EINVAL, errno);
    611 #else
    612   GTEST_LOG_(INFO) << "This test does nothing.\n";
    613 #endif
    614 }
    615 
    616 TEST(wchar, wcstol_EINVAL) {
    617   errno = 0;
    618   wcstol(L"123", NULL, -1);
    619   ASSERT_EQ(EINVAL, errno);
    620   errno = 0;
    621   wcstol(L"123", NULL, 1);
    622   ASSERT_EQ(EINVAL, errno);
    623   errno = 0;
    624   wcstol(L"123", NULL, 37);
    625   ASSERT_EQ(EINVAL, errno);
    626 }
    627 
    628 TEST(wchar, wcstoll_EINVAL) {
    629   errno = 0;
    630   wcstoll(L"123", NULL, -1);
    631   ASSERT_EQ(EINVAL, errno);
    632   errno = 0;
    633   wcstoll(L"123", NULL, 1);
    634   ASSERT_EQ(EINVAL, errno);
    635   errno = 0;
    636   wcstoll(L"123", NULL, 37);
    637   ASSERT_EQ(EINVAL, errno);
    638 }
    639 
    640 TEST(wchar, wcstoul_EINVAL) {
    641   errno = 0;
    642   wcstoul(L"123", NULL, -1);
    643   ASSERT_EQ(EINVAL, errno);
    644   errno = 0;
    645   wcstoul(L"123", NULL, 1);
    646   ASSERT_EQ(EINVAL, errno);
    647   errno = 0;
    648   wcstoul(L"123", NULL, 37);
    649   ASSERT_EQ(EINVAL, errno);
    650 }
    651 
    652 TEST(wchar, wcstoull_EINVAL) {
    653   errno = 0;
    654   wcstoull(L"123", NULL, -1);
    655   ASSERT_EQ(EINVAL, errno);
    656   errno = 0;
    657   wcstoull(L"123", NULL, 1);
    658   ASSERT_EQ(EINVAL, errno);
    659   errno = 0;
    660   wcstoull(L"123", NULL, 37);
    661   ASSERT_EQ(EINVAL, errno);
    662 }
    663 
    664 TEST(wchar, wcstoll_l_EINVAL) {
    665   errno = 0;
    666   wcstoll_l(L"123", NULL, -1, LC_GLOBAL_LOCALE);
    667   ASSERT_EQ(EINVAL, errno);
    668   errno = 0;
    669   wcstoll_l(L"123", NULL, 1, LC_GLOBAL_LOCALE);
    670   ASSERT_EQ(EINVAL, errno);
    671   errno = 0;
    672   wcstoll_l(L"123", NULL, 37, LC_GLOBAL_LOCALE);
    673   ASSERT_EQ(EINVAL, errno);
    674 }
    675 
    676 TEST(wchar, wcstoull_l_EINVAL) {
    677   errno = 0;
    678   wcstoull_l(L"123", NULL, -1, LC_GLOBAL_LOCALE);
    679   ASSERT_EQ(EINVAL, errno);
    680   errno = 0;
    681   wcstoull_l(L"123", NULL, 1, LC_GLOBAL_LOCALE);
    682   ASSERT_EQ(EINVAL, errno);
    683   errno = 0;
    684   wcstoull_l(L"123", NULL, 37, LC_GLOBAL_LOCALE);
    685   ASSERT_EQ(EINVAL, errno);
    686 }
    687 
    688 TEST(wchar, wmempcpy) {
    689   wchar_t dst[6];
    690   ASSERT_EQ(&dst[4], wmempcpy(dst, L"hello", 4));
    691 }
    692 
    693 template <typename T>
    694 static void CheckWcsToFloat(T fn(const wchar_t* s, wchar_t** end)) {
    695   FpUlpEq<0, T> pred;
    696 
    697   EXPECT_PRED_FORMAT2(pred, 9.0, fn(L"9.0", nullptr));
    698   EXPECT_PRED_FORMAT2(pred, 9.0, fn(L"0.9e1", nullptr));
    699   EXPECT_PRED_FORMAT2(pred, 9.0, fn(L"0x1.2p3", nullptr));
    700 
    701   const wchar_t* s = L" \t\v\f\r\n9.0";
    702   wchar_t* p;
    703   EXPECT_PRED_FORMAT2(pred, 9.0, fn(s, &p));
    704   EXPECT_EQ(s + wcslen(s), p);
    705 
    706   EXPECT_TRUE(isnan(fn(L"+nan", nullptr)));
    707   EXPECT_TRUE(isnan(fn(L"nan", nullptr)));
    708   EXPECT_TRUE(isnan(fn(L"-nan", nullptr)));
    709 
    710   EXPECT_TRUE(isnan(fn(L"+nan(0xff)", nullptr)));
    711   EXPECT_TRUE(isnan(fn(L"nan(0xff)", nullptr)));
    712   EXPECT_TRUE(isnan(fn(L"-nan(0xff)", nullptr)));
    713 
    714   EXPECT_TRUE(isnan(fn(L"+nanny", &p)));
    715   EXPECT_STREQ(L"ny", p);
    716   EXPECT_TRUE(isnan(fn(L"nanny", &p)));
    717   EXPECT_STREQ(L"ny", p);
    718   EXPECT_TRUE(isnan(fn(L"-nanny", &p)));
    719   EXPECT_STREQ(L"ny", p);
    720 
    721   EXPECT_EQ(0, fn(L"muppet", &p));
    722   EXPECT_STREQ(L"muppet", p);
    723   EXPECT_EQ(0, fn(L"  muppet", &p));
    724   EXPECT_STREQ(L"  muppet", p);
    725 
    726   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"+inf", nullptr));
    727   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"inf", nullptr));
    728   EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-inf", nullptr));
    729 
    730   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinity", nullptr));
    731   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinity", nullptr));
    732   EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinity", nullptr));
    733 
    734   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinitude", &p));
    735   EXPECT_STREQ(L"initude", p);
    736   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinitude", &p));
    737   EXPECT_STREQ(L"initude", p);
    738   EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinitude", &p));
    739   EXPECT_STREQ(L"initude", p);
    740 
    741   // Check case-insensitivity.
    742   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"InFiNiTy", nullptr));
    743   EXPECT_TRUE(isnan(fn(L"NaN", nullptr)));
    744 }
    745 
    746 TEST(wchar, wcstod) {
    747   CheckWcsToFloat(wcstod);
    748 }
    749 
    750 TEST(wchar, wcstof) {
    751   CheckWcsToFloat(wcstof);
    752 }
    753 
    754 TEST(wchar, wcstold) {
    755   CheckWcsToFloat(wcstold);
    756 }
    757