1*71db0c75SAndroid Build Coastguard Worker //===-- Tests for str{,r}chr and {,r}index functions ------------*- C++ -*-===// 2*71db0c75SAndroid Build Coastguard Worker // 3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*71db0c75SAndroid Build Coastguard Worker // 7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 8*71db0c75SAndroid Build Coastguard Worker 9*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h" 10*71db0c75SAndroid Build Coastguard Worker 11*71db0c75SAndroid Build Coastguard Worker template <auto Func> struct StrchrTest : public LIBC_NAMESPACE::testing::Test { findsFirstCharacterStrchrTest12*71db0c75SAndroid Build Coastguard Worker void findsFirstCharacter() { 13*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 14*71db0c75SAndroid Build Coastguard Worker 15*71db0c75SAndroid Build Coastguard Worker // Should return original string since 'a' is the first character. 16*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'a'), "abcde"); 17*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 18*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 19*71db0c75SAndroid Build Coastguard Worker } 20*71db0c75SAndroid Build Coastguard Worker findsMiddleCharacterStrchrTest21*71db0c75SAndroid Build Coastguard Worker void findsMiddleCharacter() { 22*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 23*71db0c75SAndroid Build Coastguard Worker 24*71db0c75SAndroid Build Coastguard Worker // Should return characters after (and including) 'c'. 25*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'c'), "cde"); 26*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 27*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 28*71db0c75SAndroid Build Coastguard Worker } 29*71db0c75SAndroid Build Coastguard Worker findsLastCharacterThatIsNotNullTerminatorStrchrTest30*71db0c75SAndroid Build Coastguard Worker void findsLastCharacterThatIsNotNullTerminator() { 31*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 32*71db0c75SAndroid Build Coastguard Worker 33*71db0c75SAndroid Build Coastguard Worker // Should return 'e' and null-terminator. 34*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'e'), "e"); 35*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 36*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 37*71db0c75SAndroid Build Coastguard Worker } 38*71db0c75SAndroid Build Coastguard Worker findsNullTerminatorStrchrTest39*71db0c75SAndroid Build Coastguard Worker void findsNullTerminator() { 40*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 41*71db0c75SAndroid Build Coastguard Worker 42*71db0c75SAndroid Build Coastguard Worker // Should return null terminator. 43*71db0c75SAndroid Build Coastguard Worker const char *nul_terminator = Func(src, '\0'); 44*71db0c75SAndroid Build Coastguard Worker ASSERT_NE(nul_terminator, nullptr); 45*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(nul_terminator, ""); 46*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 47*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 48*71db0c75SAndroid Build Coastguard Worker } 49*71db0c75SAndroid Build Coastguard Worker characterNotWithinStringShouldReturnNullptrStrchrTest50*71db0c75SAndroid Build Coastguard Worker void characterNotWithinStringShouldReturnNullptr() { 51*71db0c75SAndroid Build Coastguard Worker // Since 'z' is not within the string, should return nullptr. 52*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("123?", 'z'), nullptr); 53*71db0c75SAndroid Build Coastguard Worker } 54*71db0c75SAndroid Build Coastguard Worker theSourceShouldNotChangeStrchrTest55*71db0c75SAndroid Build Coastguard Worker void theSourceShouldNotChange() { 56*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 57*71db0c75SAndroid Build Coastguard Worker // When the character is found, the source string should not change. 58*71db0c75SAndroid Build Coastguard Worker Func(src, 'd'); 59*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 60*71db0c75SAndroid Build Coastguard Worker // Same case for when the character is not found. 61*71db0c75SAndroid Build Coastguard Worker Func(src, 'z'); 62*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 63*71db0c75SAndroid Build Coastguard Worker // Same case for when looking for nullptr. 64*71db0c75SAndroid Build Coastguard Worker Func(src, '\0'); 65*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 66*71db0c75SAndroid Build Coastguard Worker } 67*71db0c75SAndroid Build Coastguard Worker shouldFindFirstOfDuplicatesStrchrTest68*71db0c75SAndroid Build Coastguard Worker void shouldFindFirstOfDuplicates() { 69*71db0c75SAndroid Build Coastguard Worker // '1' is duplicated in the string, but it should find the first copy. 70*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func("abc1def1ghi", '1'), "1def1ghi"); 71*71db0c75SAndroid Build Coastguard Worker 72*71db0c75SAndroid Build Coastguard Worker const char *dups = "XXXXX"; 73*71db0c75SAndroid Build Coastguard Worker // Should return original string since 'X' is the first character. 74*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(dups, 'X'), dups); 75*71db0c75SAndroid Build Coastguard Worker } 76*71db0c75SAndroid Build Coastguard Worker emptyStringShouldOnlyMatchNullTerminatorStrchrTest77*71db0c75SAndroid Build Coastguard Worker void emptyStringShouldOnlyMatchNullTerminator() { 78*71db0c75SAndroid Build Coastguard Worker // Null terminator should match. 79*71db0c75SAndroid Build Coastguard Worker const char empty_string[] = ""; 80*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<const char *>(Func(empty_string, '\0')), 81*71db0c75SAndroid Build Coastguard Worker empty_string); 82*71db0c75SAndroid Build Coastguard Worker // All other characters should not match. 83*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("", 'Z'), nullptr); 84*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("", '3'), nullptr); 85*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("", '*'), nullptr); 86*71db0c75SAndroid Build Coastguard Worker } 87*71db0c75SAndroid Build Coastguard Worker }; 88*71db0c75SAndroid Build Coastguard Worker 89*71db0c75SAndroid Build Coastguard Worker template <auto Func> struct StrrchrTest : public LIBC_NAMESPACE::testing::Test { findsFirstCharacterStrrchrTest90*71db0c75SAndroid Build Coastguard Worker void findsFirstCharacter() { 91*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 92*71db0c75SAndroid Build Coastguard Worker 93*71db0c75SAndroid Build Coastguard Worker // Should return original string since 'a' is the first character. 94*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'a'), "abcde"); 95*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 96*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 97*71db0c75SAndroid Build Coastguard Worker } 98*71db0c75SAndroid Build Coastguard Worker findsMiddleCharacterStrrchrTest99*71db0c75SAndroid Build Coastguard Worker void findsMiddleCharacter() { 100*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 101*71db0c75SAndroid Build Coastguard Worker 102*71db0c75SAndroid Build Coastguard Worker // Should return characters after (and including) 'c'. 103*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'c'), "cde"); 104*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 105*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 106*71db0c75SAndroid Build Coastguard Worker } 107*71db0c75SAndroid Build Coastguard Worker findsLastCharacterThatIsNotNullTerminatorStrrchrTest108*71db0c75SAndroid Build Coastguard Worker void findsLastCharacterThatIsNotNullTerminator() { 109*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 110*71db0c75SAndroid Build Coastguard Worker 111*71db0c75SAndroid Build Coastguard Worker // Should return 'e' and null-terminator. 112*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'e'), "e"); 113*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 114*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 115*71db0c75SAndroid Build Coastguard Worker } 116*71db0c75SAndroid Build Coastguard Worker findsNullTerminatorStrrchrTest117*71db0c75SAndroid Build Coastguard Worker void findsNullTerminator() { 118*71db0c75SAndroid Build Coastguard Worker const char *src = "abcde"; 119*71db0c75SAndroid Build Coastguard Worker 120*71db0c75SAndroid Build Coastguard Worker // Should return null terminator. 121*71db0c75SAndroid Build Coastguard Worker const char *nul_terminator = Func(src, '\0'); 122*71db0c75SAndroid Build Coastguard Worker ASSERT_NE(nul_terminator, nullptr); 123*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(nul_terminator, ""); 124*71db0c75SAndroid Build Coastguard Worker // Source string should not change. 125*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(src, "abcde"); 126*71db0c75SAndroid Build Coastguard Worker } 127*71db0c75SAndroid Build Coastguard Worker findsLastBehindFirstNullTerminatorStrrchrTest128*71db0c75SAndroid Build Coastguard Worker void findsLastBehindFirstNullTerminator() { 129*71db0c75SAndroid Build Coastguard Worker static const char src[6] = {'a', 'a', '\0', 'b', '\0', 'c'}; 130*71db0c75SAndroid Build Coastguard Worker // 'b' is behind a null terminator, so should not be found. 131*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func(src, 'b'), nullptr); 132*71db0c75SAndroid Build Coastguard Worker // Same goes for 'c'. 133*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func(src, 'c'), nullptr); 134*71db0c75SAndroid Build Coastguard Worker 135*71db0c75SAndroid Build Coastguard Worker // Should find the second of the two a's. 136*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(src, 'a'), "a"); 137*71db0c75SAndroid Build Coastguard Worker } 138*71db0c75SAndroid Build Coastguard Worker characterNotWithinStringShouldReturnNullptrStrrchrTest139*71db0c75SAndroid Build Coastguard Worker void characterNotWithinStringShouldReturnNullptr() { 140*71db0c75SAndroid Build Coastguard Worker // Since 'z' is not within the string, should return nullptr. 141*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("123?", 'z'), nullptr); 142*71db0c75SAndroid Build Coastguard Worker } 143*71db0c75SAndroid Build Coastguard Worker shouldFindLastOfDuplicatesStrrchrTest144*71db0c75SAndroid Build Coastguard Worker void shouldFindLastOfDuplicates() { 145*71db0c75SAndroid Build Coastguard Worker // '1' is duplicated in the string, but it should find the last copy. 146*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func("abc1def1ghi", '1'), "1ghi"); 147*71db0c75SAndroid Build Coastguard Worker 148*71db0c75SAndroid Build Coastguard Worker const char *dups = "XXXXX"; 149*71db0c75SAndroid Build Coastguard Worker // Should return the last occurrence of 'X'. 150*71db0c75SAndroid Build Coastguard Worker ASSERT_STREQ(Func(dups, 'X'), "X"); 151*71db0c75SAndroid Build Coastguard Worker } 152*71db0c75SAndroid Build Coastguard Worker emptyStringShouldOnlyMatchNullTerminatorStrrchrTest153*71db0c75SAndroid Build Coastguard Worker void emptyStringShouldOnlyMatchNullTerminator() { 154*71db0c75SAndroid Build Coastguard Worker // Null terminator should match. 155*71db0c75SAndroid Build Coastguard Worker const char empty_string[] = ""; 156*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<const char *>(Func(empty_string, '\0')), 157*71db0c75SAndroid Build Coastguard Worker empty_string); 158*71db0c75SAndroid Build Coastguard Worker // All other characters should not match. 159*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("", 'A'), nullptr); 160*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("", '2'), nullptr); 161*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(Func("", '*'), nullptr); 162*71db0c75SAndroid Build Coastguard Worker } 163*71db0c75SAndroid Build Coastguard Worker }; 164*71db0c75SAndroid Build Coastguard Worker 165*71db0c75SAndroid Build Coastguard Worker #define STRCHR_TEST(name, func) \ 166*71db0c75SAndroid Build Coastguard Worker using LlvmLibc##name##Test = StrchrTest<func>; \ 167*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsFirstCharacter) { findsFirstCharacter(); } \ 168*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsMiddleCharacter) { \ 169*71db0c75SAndroid Build Coastguard Worker findsMiddleCharacter(); \ 170*71db0c75SAndroid Build Coastguard Worker } \ 171*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsLastCharacterThatIsNotNullTerminator) { \ 172*71db0c75SAndroid Build Coastguard Worker findsLastCharacterThatIsNotNullTerminator(); \ 173*71db0c75SAndroid Build Coastguard Worker } \ 174*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsNullTerminator) { findsNullTerminator(); } \ 175*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, CharacterNotWithinStringShouldReturnNullptr) { \ 176*71db0c75SAndroid Build Coastguard Worker characterNotWithinStringShouldReturnNullptr(); \ 177*71db0c75SAndroid Build Coastguard Worker } \ 178*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, TheSourceShouldNotChange) { \ 179*71db0c75SAndroid Build Coastguard Worker theSourceShouldNotChange(); \ 180*71db0c75SAndroid Build Coastguard Worker } \ 181*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, ShouldFindFirstOfDuplicates) { \ 182*71db0c75SAndroid Build Coastguard Worker shouldFindFirstOfDuplicates(); \ 183*71db0c75SAndroid Build Coastguard Worker } \ 184*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, EmptyStringShouldOnlyMatchNullTerminator) { \ 185*71db0c75SAndroid Build Coastguard Worker emptyStringShouldOnlyMatchNullTerminator(); \ 186*71db0c75SAndroid Build Coastguard Worker } 187*71db0c75SAndroid Build Coastguard Worker 188*71db0c75SAndroid Build Coastguard Worker #define STRRCHR_TEST(name, func) \ 189*71db0c75SAndroid Build Coastguard Worker using LlvmLibc##name##Test = StrrchrTest<func>; \ 190*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsFirstCharacter) { findsFirstCharacter(); } \ 191*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsMiddleCharacter) { \ 192*71db0c75SAndroid Build Coastguard Worker findsMiddleCharacter(); \ 193*71db0c75SAndroid Build Coastguard Worker } \ 194*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsLastCharacterThatIsNotNullTerminator) { \ 195*71db0c75SAndroid Build Coastguard Worker findsLastCharacterThatIsNotNullTerminator(); \ 196*71db0c75SAndroid Build Coastguard Worker } \ 197*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsNullTerminator) { findsNullTerminator(); } \ 198*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, FindsLastBehindFirstNullTerminator) { \ 199*71db0c75SAndroid Build Coastguard Worker findsLastBehindFirstNullTerminator(); \ 200*71db0c75SAndroid Build Coastguard Worker } \ 201*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, CharacterNotWithinStringShouldReturnNullptr) { \ 202*71db0c75SAndroid Build Coastguard Worker characterNotWithinStringShouldReturnNullptr(); \ 203*71db0c75SAndroid Build Coastguard Worker } \ 204*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, ShouldFindLastOfDuplicates) { \ 205*71db0c75SAndroid Build Coastguard Worker shouldFindLastOfDuplicates(); \ 206*71db0c75SAndroid Build Coastguard Worker } \ 207*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, EmptyStringShouldOnlyMatchNullTerminator) { \ 208*71db0c75SAndroid Build Coastguard Worker emptyStringShouldOnlyMatchNullTerminator(); \ 209*71db0c75SAndroid Build Coastguard Worker } 210