brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 04cf426 Raw
193 lines · cpp
1//===-- Unittests for wcsnrtombs ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "hdr/types/mbstate_t.h"10#include "src/__support/macros/null_check.h"11#include "src/string/memset.h"12#include "src/wchar/wcsnrtombs.h"13#include "test/UnitTest/ErrnoCheckingTest.h"14#include "test/UnitTest/Test.h"15 16using LlvmLibcWcsnrtombs = LIBC_NAMESPACE::testing::ErrnoCheckingTest;17 18// these tests are fairly simple as this function just calls into the internal19// wcsnrtombs which is more thoroughly tested20 21TEST_F(LlvmLibcWcsnrtombs, AllMultibyteLengths) {22  mbstate_t state;23  LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));24 25  /// clown emoji, sigma symbol, y with diaeresis, letter A26  const wchar_t src[] = {static_cast<wchar_t>(0x1f921),27                         static_cast<wchar_t>(0x2211),28                         static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),29                         static_cast<wchar_t>(0x0)};30  const wchar_t *cur = src;31  char mbs[11];32 33  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 11, &state),34            static_cast<size_t>(10));35  ASSERT_ERRNO_SUCCESS();36  ASSERT_EQ(cur, nullptr);37  ASSERT_EQ(mbs[0], '\xF0'); // clown begin38  ASSERT_EQ(mbs[1], '\x9F');39  ASSERT_EQ(mbs[2], '\xA4');40  ASSERT_EQ(mbs[3], '\xA1');41  ASSERT_EQ(mbs[4], '\xE2'); // sigma begin42  ASSERT_EQ(mbs[5], '\x88');43  ASSERT_EQ(mbs[6], '\x91');44  ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin45  ASSERT_EQ(mbs[8], '\xBF');46  ASSERT_EQ(mbs[9], '\x41'); // A begin47  ASSERT_EQ(mbs[10], '\0');  // null terminator48}49 50TEST_F(LlvmLibcWcsnrtombs, DestLimit) {51  mbstate_t state;52  LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));53 54  /// clown emoji, sigma symbol, y with diaeresis, letter A55  const wchar_t src[] = {static_cast<wchar_t>(0x1f921),56                         static_cast<wchar_t>(0x2211),57                         static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),58                         static_cast<wchar_t>(0x0)};59  const wchar_t *cur = src;60 61  char mbs[11];62  LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values63 64  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 4, &state),65            static_cast<size_t>(4));66  ASSERT_ERRNO_SUCCESS();67  ASSERT_EQ(cur, src + 1);68  ASSERT_EQ(mbs[0], '\xF0');69  ASSERT_EQ(mbs[1], '\x9F');70  ASSERT_EQ(mbs[2], '\xA4');71  ASSERT_EQ(mbs[3], '\xA1');72  ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes73 74  LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values75  LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));76  cur = src;77 78  // not enough bytes to convert the second character, so only converts one79  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 6, &state),80            static_cast<size_t>(4));81  ASSERT_ERRNO_SUCCESS();82  ASSERT_EQ(cur, src + 1);83  ASSERT_EQ(mbs[0], '\xF0');84  ASSERT_EQ(mbs[1], '\x9F');85  ASSERT_EQ(mbs[2], '\xA4');86  ASSERT_EQ(mbs[3], '\xA1');87  ASSERT_EQ(mbs[4], '\x01');88}89 90TEST(LlvmLibcWcsnrtombs, SrcLimit) {91  mbstate_t state;92  LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));93 94  /// clown emoji, sigma symbol, y with diaeresis, letter A95  const wchar_t src[] = {static_cast<wchar_t>(0x1f921),96                         static_cast<wchar_t>(0x2211),97                         static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),98                         static_cast<wchar_t>(0x0)};99  const wchar_t *cur = src;100 101  char mbs[11];102  LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values103 104  auto res = LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 2, 11, &state);105  ASSERT_ERRNO_SUCCESS();106  ASSERT_EQ(res, static_cast<size_t>(7));107  ASSERT_EQ(cur, src + 2);108  ASSERT_EQ(mbs[0], '\xF0'); // clown begin109  ASSERT_EQ(mbs[1], '\x9F');110  ASSERT_EQ(mbs[2], '\xA4');111  ASSERT_EQ(mbs[3], '\xA1');112  ASSERT_EQ(mbs[4], '\xE2'); // sigma begin113  ASSERT_EQ(mbs[5], '\x88');114  ASSERT_EQ(mbs[6], '\x91');115  ASSERT_EQ(mbs[7], '\x01');116 117  res = LIBC_NAMESPACE::wcsnrtombs(mbs + res, &cur, 100, 11, &state);118  ASSERT_ERRNO_SUCCESS();119  ASSERT_EQ(res, static_cast<size_t>(3));120  ASSERT_EQ(cur, nullptr);121  ASSERT_EQ(mbs[0], '\xF0'); // clown begin122  ASSERT_EQ(mbs[1], '\x9F');123  ASSERT_EQ(mbs[2], '\xA4');124  ASSERT_EQ(mbs[3], '\xA1');125  ASSERT_EQ(mbs[4], '\xE2'); // sigma begin126  ASSERT_EQ(mbs[5], '\x88');127  ASSERT_EQ(mbs[6], '\x91');128  ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin129  ASSERT_EQ(mbs[8], '\xBF');130  ASSERT_EQ(mbs[9], '\x41'); // A begin131  ASSERT_EQ(mbs[10], '\0');  // null terminator132}133 134TEST_F(LlvmLibcWcsnrtombs, ErrnoTest) {135  mbstate_t state;136  LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));137 138  const wchar_t src[] = {static_cast<wchar_t>(0x1f921),139                         static_cast<wchar_t>(0x2211),140                         static_cast<wchar_t>(0x12ffff), // invalid widechar141                         static_cast<wchar_t>(0x0)};142  const wchar_t *cur = src;143  char mbs[11];144 145  // n parameter ignored when dest is null146  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 7, &state),147            static_cast<size_t>(7));148  ASSERT_ERRNO_SUCCESS();149 150  LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));151  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 100, &state),152            static_cast<size_t>(-1));153  ASSERT_ERRNO_EQ(EILSEQ);154}155 156TEST_F(LlvmLibcWcsnrtombs, NullState) {157  // this test is the same as DestLimit except it uses a nullptr mbstate*158 159  /// clown emoji, sigma symbol, y with diaeresis, letter A160  const wchar_t src[] = {static_cast<wchar_t>(0x1f921),161                         static_cast<wchar_t>(0x2211),162                         static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),163                         static_cast<wchar_t>(0x0)};164  const wchar_t *cur = src;165 166  char mbs[11];167  LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values168 169  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 4, nullptr),170            static_cast<size_t>(4));171  ASSERT_ERRNO_SUCCESS();172  ASSERT_EQ(cur, src + 1);173  ASSERT_EQ(mbs[0], '\xF0');174  ASSERT_EQ(mbs[1], '\x9F');175  ASSERT_EQ(mbs[2], '\xA4');176  ASSERT_EQ(mbs[3], '\xA1');177  ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes178 179  LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values180 181  // not enough bytes to convert the second character, so only converts one182  cur = src;183  ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 6, nullptr),184            static_cast<size_t>(4));185  ASSERT_ERRNO_SUCCESS();186  ASSERT_EQ(cur, src + 1);187  ASSERT_EQ(mbs[0], '\xF0');188  ASSERT_EQ(mbs[1], '\x9F');189  ASSERT_EQ(mbs[2], '\xA4');190  ASSERT_EQ(mbs[3], '\xA1');191  ASSERT_EQ(mbs[4], '\x01');192}193