190 lines · cpp
1//===-- Unittests for wcstok ----------------------------------------------===//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/size_t.h"10#include "hdr/types/wchar_t.h"11#include "src/wchar/wcstok.h"12#include "test/UnitTest/Test.h"13 14TEST(LlvmLibcWCSTokReentrantTest, NoTokenFound) {15 { // Empty source and delimiter string.16 wchar_t empty[] = L"";17 wchar_t *reserve = nullptr;18 ASSERT_EQ(LIBC_NAMESPACE::wcstok(empty, L"", &reserve), nullptr);19 // Another call to ensure that 'reserve' is not in a bad state.20 ASSERT_EQ(LIBC_NAMESPACE::wcstok(empty, L"", &reserve), nullptr);21 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L"", &reserve), nullptr);22 // Subsequent searches still return nullptr.23 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L"", &reserve), nullptr);24 }25 { // Empty source and single character delimiter string.26 wchar_t empty[] = L"";27 wchar_t *reserve = nullptr;28 ASSERT_EQ(LIBC_NAMESPACE::wcstok(empty, L"_", &reserve), nullptr);29 // Another call to ensure that 'reserve' is not in a bad state.30 ASSERT_EQ(LIBC_NAMESPACE::wcstok(empty, L"_", &reserve), nullptr);31 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L"_", &reserve), nullptr);32 // Subsequent searches still return nullptr.33 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L"_", &reserve), nullptr);34 }35 { // Same character source and delimiter string.36 wchar_t single[] = L"_";37 wchar_t *reserve = nullptr;38 ASSERT_EQ(LIBC_NAMESPACE::wcstok(single, L"_", &reserve), nullptr);39 // Another call to ensure that 'reserve' is not in a bad state.40 ASSERT_EQ(LIBC_NAMESPACE::wcstok(single, L"_", &reserve), nullptr);41 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L"_", &reserve), nullptr);42 // Subsequent searches still return nullptr.43 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L"_", &reserve), nullptr);44 }45 { // Multiple character source and single character delimiter string.46 wchar_t multiple[] = L"1,2";47 wchar_t *reserve = nullptr;48 wchar_t *tok = LIBC_NAMESPACE::wcstok(multiple, L":", &reserve);49 ASSERT_TRUE(tok[0] == L'1');50 ASSERT_TRUE(tok[1] == L',');51 ASSERT_TRUE(tok[2] == L'2');52 ASSERT_TRUE(tok[3] == L'\0');53 // Another call to ensure that 'reserve' is not in a bad state.54 tok = LIBC_NAMESPACE::wcstok(multiple, L":", &reserve);55 ASSERT_TRUE(tok[0] == L'1');56 ASSERT_TRUE(tok[1] == L',');57 ASSERT_TRUE(tok[2] == L'2');58 ASSERT_TRUE(tok[3] == L'\0');59 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L":", &reserve), nullptr);60 // Subsequent searches still return nullptr.61 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L":", &reserve), nullptr);62 }63}64 65TEST(LlvmLibcWCSTokReentrantTest, DelimiterAsFirstCharacterShouldBeIgnored) {66 wchar_t src[] = L".123";67 wchar_t *reserve = nullptr;68 wchar_t *tok = LIBC_NAMESPACE::wcstok(src, L".", &reserve);69 ASSERT_TRUE(tok[0] == L'1');70 ASSERT_TRUE(tok[1] == L'2');71 ASSERT_TRUE(tok[2] == L'3');72 ASSERT_TRUE(tok[3] == L'\0');73 // Another call to ensure that 'reserve' is not in a bad state.74 tok = LIBC_NAMESPACE::wcstok(src, L".", &reserve);75 ASSERT_TRUE(tok[0] == L'1');76 ASSERT_TRUE(tok[1] == L'2');77 ASSERT_TRUE(tok[2] == L'3');78 ASSERT_TRUE(tok[3] == L'\0');79 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L".", &reserve), nullptr);80}81 82TEST(LlvmLibcWCSTokReentrantTest, DelimiterIsMiddleCharacter) {83 wchar_t src[] = L"12,34";84 wchar_t *reserve = nullptr;85 wchar_t *tok = LIBC_NAMESPACE::wcstok(src, L",", &reserve);86 ASSERT_TRUE(tok[0] == L'1');87 ASSERT_TRUE(tok[1] == L'2');88 ASSERT_TRUE(tok[2] == L'\0');89 // Another call to ensure that 'reserve' is not in a bad state.90 tok = LIBC_NAMESPACE::wcstok(src, L",", &reserve);91 ASSERT_TRUE(tok[0] == L'1');92 ASSERT_TRUE(tok[1] == L'2');93 ASSERT_TRUE(tok[2] == L'\0');94 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L",", &reserve), nullptr);95}96 97TEST(LlvmLibcWCSTokReentrantTest, DelimiterAsLastCharacterShouldBeIgnored) {98 wchar_t src[] = L"1234:";99 wchar_t *reserve = nullptr;100 wchar_t *tok = LIBC_NAMESPACE::wcstok(src, L":", &reserve);101 ASSERT_TRUE(tok[0] == L'1');102 ASSERT_TRUE(tok[1] == L'2');103 ASSERT_TRUE(tok[2] == L'3');104 ASSERT_TRUE(tok[3] == L'4');105 ASSERT_TRUE(tok[4] == L'\0');106 // Another call to ensure that 'reserve' is not in a bad state.107 tok = LIBC_NAMESPACE::wcstok(src, L":", &reserve);108 ASSERT_TRUE(tok[0] == L'1');109 ASSERT_TRUE(tok[1] == L'2');110 ASSERT_TRUE(tok[2] == L'3');111 ASSERT_TRUE(tok[3] == L'4');112 ASSERT_TRUE(tok[4] == L'\0');113 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L":", &reserve), nullptr);114}115 116TEST(LlvmLibcWCSTokReentrantTest, ShouldNotGoPastNullTerminator) {117 wchar_t src[] = {L'1', L'2', L'\0', L',', L'3'};118 wchar_t *reserve = nullptr;119 wchar_t *tok = LIBC_NAMESPACE::wcstok(src, L",", &reserve);120 ASSERT_TRUE(tok[0] == L'1');121 ASSERT_TRUE(tok[1] == L'2');122 ASSERT_TRUE(tok[2] == L'\0');123 // Another call to ensure that 'reserve' is not in a bad state.124 tok = LIBC_NAMESPACE::wcstok(src, L",", &reserve);125 ASSERT_TRUE(tok[0] == L'1');126 ASSERT_TRUE(tok[1] == L'2');127 ASSERT_TRUE(tok[2] == L'\0');128 ASSERT_EQ(LIBC_NAMESPACE::wcstok(nullptr, L",", &reserve), nullptr);129}130 131TEST(LlvmLibcWCSTokReentrantTest,132 ShouldReturnNullptrWhenBothSrcAndSaveptrAreNull) {133 wchar_t *src = nullptr;134 wchar_t *reserve = nullptr;135 // Ensure that instead of crashing if src and reserve are null, nullptr is136 // returned137 ASSERT_EQ(LIBC_NAMESPACE::wcstok(src, L",", &reserve), nullptr);138 // And that neither src nor reserve are changed when that happens139 ASSERT_EQ(src, nullptr);140 ASSERT_EQ(reserve, nullptr);141}142 143TEST(LlvmLibcWCSTokReentrantTest,144 SubsequentCallsShouldFindFollowingDelimiters) {145 wchar_t src[] = L"12,34.56";146 wchar_t *reserve = nullptr;147 wchar_t *token = LIBC_NAMESPACE::wcstok(src, L",.", &reserve);148 ASSERT_TRUE(token[0] == L'1');149 ASSERT_TRUE(token[1] == L'2');150 ASSERT_TRUE(token[2] == L'\0');151 152 token = LIBC_NAMESPACE::wcstok(nullptr, L",.", &reserve);153 ASSERT_TRUE(token[0] == L'3');154 ASSERT_TRUE(token[1] == L'4');155 ASSERT_TRUE(token[2] == L'\0');156 157 token = LIBC_NAMESPACE::wcstok(nullptr, L",.", &reserve);158 ASSERT_TRUE(token[0] == L'5');159 ASSERT_TRUE(token[1] == L'6');160 ASSERT_TRUE(token[2] == L'\0');161 token = LIBC_NAMESPACE::wcstok(nullptr, L"_:,_", &reserve);162 ASSERT_EQ(token, nullptr);163 // Subsequent calls after hitting the end of the string should also return164 // nullptr.165 token = LIBC_NAMESPACE::wcstok(nullptr, L"_:,_", &reserve);166 ASSERT_EQ(token, nullptr);167}168 169TEST(LlvmLibcWCSTokReentrantTest, DelimitersShouldNotBeIncludedInToken) {170 wchar_t src[] = L"__ab__:_cd__:__ef__:__";171 wchar_t *reserve = nullptr;172 wchar_t *token = LIBC_NAMESPACE::wcstok(src, L"_:", &reserve);173 ASSERT_TRUE(token[0] == L'a');174 ASSERT_TRUE(token[1] == L'b');175 ASSERT_TRUE(token[2] == L'\0');176 177 token = LIBC_NAMESPACE::wcstok(nullptr, L":_", &reserve);178 ASSERT_TRUE(token[0] == L'c');179 ASSERT_TRUE(token[1] == L'd');180 ASSERT_TRUE(token[2] == L'\0');181 182 token = LIBC_NAMESPACE::wcstok(nullptr, L"_:,", &reserve);183 ASSERT_TRUE(token[0] == L'e');184 ASSERT_TRUE(token[1] == L'f');185 ASSERT_TRUE(token[2] == L'\0');186 187 token = LIBC_NAMESPACE::wcstok(nullptr, L"_:,_", &reserve);188 ASSERT_EQ(token, nullptr);189}190