105 lines · cpp
1//===-- Unittests for mblen -----------------------------------------------===//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/errno_macros.h"10#include "src/wchar/mblen.h"11#include "test/UnitTest/ErrnoCheckingTest.h"12#include "test/UnitTest/Test.h"13 14using LlvmLibcMBLenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;15 16TEST_F(LlvmLibcMBLenTest, OneByte) {17 const char *ch = "A";18 int n = LIBC_NAMESPACE::mblen(ch, 1);19 ASSERT_ERRNO_SUCCESS();20 ASSERT_EQ(n, 1);21 22 // Should fail since we have not read enough23 n = LIBC_NAMESPACE::mblen(ch, 0);24 ASSERT_ERRNO_SUCCESS();25 ASSERT_EQ(n, -1);26}27 28TEST_F(LlvmLibcMBLenTest, TwoByte) {29 const char ch[2] = {static_cast<char>(0xC2),30 static_cast<char>(0x8E)}; // car symbol31 int n = LIBC_NAMESPACE::mblen(ch, 4);32 ASSERT_ERRNO_SUCCESS();33 ASSERT_EQ(n, 2);34 35 // Should fail since we have not read enough36 n = LIBC_NAMESPACE::mblen(ch, 1);37 ASSERT_EQ(n, -1);38 ASSERT_ERRNO_SUCCESS();39 // Should fail after trying to read next byte too40 n = LIBC_NAMESPACE::mblen(ch + 1, 1);41 ASSERT_EQ(n, -1);42 // This one should be an invalid starting byte so should set errno43 ASSERT_ERRNO_EQ(EILSEQ);44}45 46TEST_F(LlvmLibcMBLenTest, ThreeByte) {47 const char ch[3] = {static_cast<char>(0xE2), static_cast<char>(0x88),48 static_cast<char>(0x91)}; // ∑ sigma symbol49 int n = LIBC_NAMESPACE::mblen(ch, 3);50 ASSERT_EQ(n, 3);51 ASSERT_ERRNO_SUCCESS();52 53 // Should fail since we have not read enough54 n = LIBC_NAMESPACE::mblen(ch, 2);55 ASSERT_EQ(n, -1);56 ASSERT_ERRNO_SUCCESS();57}58 59TEST_F(LlvmLibcMBLenTest, FourByte) {60 const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),61 static_cast<char>(0xA4),62 static_cast<char>(0xA1)}; // 🤡 clown emoji63 int n = LIBC_NAMESPACE::mblen(ch, 4);64 ASSERT_EQ(n, 4);65 ASSERT_ERRNO_SUCCESS();66 67 // Should fail since we have not read enough68 n = LIBC_NAMESPACE::mblen(ch, 2);69 ASSERT_EQ(n, -1);70 ASSERT_ERRNO_SUCCESS();71}72 73TEST_F(LlvmLibcMBLenTest, InvalidByte) {74 const char ch[1] = {static_cast<char>(0x80)};75 int n = LIBC_NAMESPACE::mblen(ch, 1);76 ASSERT_EQ(n, -1);77 ASSERT_ERRNO_EQ(EILSEQ);78}79 80TEST_F(LlvmLibcMBLenTest, InvalidMultiByte) {81 const char ch[4] = {static_cast<char>(0x80), static_cast<char>(0x00),82 static_cast<char>(0x80),83 static_cast<char>(0x00)}; // invalid sequence of bytes84 // Trying to push all 4 should error85 int n = LIBC_NAMESPACE::mblen(ch, 4);86 ASSERT_EQ(n, -1);87 ASSERT_ERRNO_EQ(EILSEQ);88 89 // Trying to push the second and third should correspond to null wc90 n = LIBC_NAMESPACE::mblen(ch + 1, 2);91 ASSERT_EQ(n, 0);92 ASSERT_ERRNO_SUCCESS();93}94 95TEST_F(LlvmLibcMBLenTest, NullString) {96 // reading on nullptr should return 097 int n = LIBC_NAMESPACE::mblen(nullptr, 2);98 ASSERT_EQ(n, 0);99 ASSERT_ERRNO_SUCCESS();100 // reading a null terminator should return 0101 const char *ch = "\0";102 n = LIBC_NAMESPACE::mblen(ch, 1);103 ASSERT_EQ(n, 0);104}105