//===-- Unittests for strtok_r -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "src/string/strtok_r.h" #include "utils/UnitTest/Test.h" TEST(StrTokReentrantTest, NoTokenFound) { { // Empty source and delimiter string. char empty[] = ""; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(empty, "", &reserve), nullptr); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(empty, "", &reserve), nullptr); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, "", &reserve), nullptr); } { // Empty source and single character delimiter string. char empty[] = ""; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(empty, "_", &reserve), nullptr); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(empty, "_", &reserve), nullptr); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, "_", &reserve), nullptr); } { // Same character source and delimiter string. char single[] = "_"; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(single, "_", &reserve), nullptr); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(single, "_", &reserve), nullptr); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, "_", &reserve), nullptr); } { // Multiple character source and single character delimiter string. char multiple[] = "1,2"; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(multiple, ":", &reserve), "1,2"); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(multiple, ":", &reserve), "1,2"); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ":", &reserve), nullptr); } } TEST(StrTokReentrantTest, DelimiterAsFirstCharacterShouldBeIgnored) { char src[] = ".123"; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(src, ".", &reserve), "123"); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(src, ".", &reserve), "123"); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ".", &reserve), nullptr); } TEST(StrTokReentrantTest, DelimiterIsMiddleCharacter) { char src[] = "12,34"; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12"); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12"); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ",", &reserve), nullptr); } TEST(StrTokReentrantTest, DelimiterAsLastCharacterShouldBeIgnored) { char src[] = "1234:"; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(src, ":", &reserve), "1234"); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(src, ":", &reserve), "1234"); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ":", &reserve), nullptr); } TEST(StrTokReentrantTest, ShouldNotGoPastNullTerminator) { char src[] = {'1', '2', '\0', ',', '3'}; char *reserve = nullptr; ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12"); // Another call to ensure that 'reserve' is not in a bad state. ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12"); ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ",", &reserve), nullptr); } TEST(StrTokReentrantTest, SubsequentCallsShouldFindFollowingDelimiters) { char src[] = "12,34.56"; char *reserve = nullptr; char *token = __llvm_libc::strtok_r(src, ",.", &reserve); ASSERT_STREQ(token, "12"); token = __llvm_libc::strtok_r(nullptr, ",.", &reserve); ASSERT_STREQ(token, "34"); token = __llvm_libc::strtok_r(nullptr, ",.", &reserve); ASSERT_STREQ(token, "56"); token = __llvm_libc::strtok_r(nullptr, "_:,_", &reserve); ASSERT_STREQ(token, nullptr); // Subsequent calls after hitting the end of the string should also return // nullptr. token = __llvm_libc::strtok_r(nullptr, "_:,_", &reserve); ASSERT_STREQ(token, nullptr); } TEST(StrTokReentrantTest, DelimitersShouldNotBeIncludedInToken) { char src[] = "__ab__:_cd__:__ef__:__"; char *reserve = nullptr; char *token = __llvm_libc::strtok_r(src, "_:", &reserve); ASSERT_STREQ(token, "ab"); token = __llvm_libc::strtok_r(nullptr, ":_", &reserve); ASSERT_STREQ(token, "cd"); token = __llvm_libc::strtok_r(nullptr, "_:,", &reserve); ASSERT_STREQ(token, "ef"); token = __llvm_libc::strtok_r(nullptr, "_:,_", &reserve); ASSERT_STREQ(token, nullptr); }