Index: libc/config/linux/aarch64/entrypoints.txt =================================================================== --- libc/config/linux/aarch64/entrypoints.txt +++ libc/config/linux/aarch64/entrypoints.txt @@ -64,6 +64,7 @@ libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr + libc.src.string.strsep libc.src.string.strsignal libc.src.string.strspn libc.src.string.strstr Index: libc/config/linux/arm/entrypoints.txt =================================================================== --- libc/config/linux/arm/entrypoints.txt +++ libc/config/linux/arm/entrypoints.txt @@ -51,6 +51,7 @@ libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr + libc.src.string.strsep libc.src.string.strspn libc.src.string.strstr libc.src.string.strtok Index: libc/config/linux/riscv64/entrypoints.txt =================================================================== --- libc/config/linux/riscv64/entrypoints.txt +++ libc/config/linux/riscv64/entrypoints.txt @@ -65,6 +65,7 @@ libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr + libc.src.string.strsep libc.src.string.strsignal libc.src.string.strspn libc.src.string.strstr Index: libc/config/linux/x86_64/entrypoints.txt =================================================================== --- libc/config/linux/x86_64/entrypoints.txt +++ libc/config/linux/x86_64/entrypoints.txt @@ -65,6 +65,7 @@ libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr + libc.src.string.strsep libc.src.string.strsignal libc.src.string.strspn libc.src.string.strstr Index: libc/src/string/CMakeLists.txt =================================================================== --- libc/src/string/CMakeLists.txt +++ libc/src/string/CMakeLists.txt @@ -315,6 +315,16 @@ strrchr.h ) +add_entrypoint_object( + strsep + SRCS + strsep.cpp + HDRS + strsep.h + DEPENDS + .string_utils +) + add_entrypoint_object( strsignal SRCS Index: libc/src/string/strsep.h =================================================================== --- /dev/null +++ libc/src/string/strsep.h @@ -0,0 +1,18 @@ +//===-- Implementation header for strsep ------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STRING_STRSEP_H +#define LLVM_LIBC_SRC_STRING_STRSEP_H + +namespace __llvm_libc { + +char *strsep(char **stringp, const char *delim); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_STRSEP_H Index: libc/src/string/strsep.cpp =================================================================== --- /dev/null +++ libc/src/string/strsep.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of strsep ------------------------------------------===// +// +// 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/strsep.h" + +#include "src/string/string_utils.h" + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(char *, strsep, (char **stringp, const char *delim)) { + if (!*stringp) + return nullptr; + return internal::string_token(*stringp, delim, stringp); +} + +} // namespace __llvm_libc Index: libc/test/src/string/CMakeLists.txt =================================================================== --- libc/test/src/string/CMakeLists.txt +++ libc/test/src/string/CMakeLists.txt @@ -298,6 +298,16 @@ libc.src.string.strrchr ) +add_libc_unittest( + strsep_test + SUITE + libc_string_unittests + SRCS + strsep_test.cpp + DEPENDS + libc.src.string.strsep +) + add_libc_unittest( strsignal_test SUITE Index: libc/test/src/string/strsep_test.cpp =================================================================== --- /dev/null +++ libc/test/src/string/strsep_test.cpp @@ -0,0 +1,52 @@ +//===-- Unittests for strsep ----------------------------------------------===// +// +// 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/strsep.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcStrsepTest, NullSrc) { + char *string = nullptr; + EXPECT_STREQ(__llvm_libc::strsep(&string, ""), nullptr); +} + +TEST(LlvmLibcStrsepTest, NoTokenFound) { + { + char s[] = ""; + char *string = s, *orig = s; + EXPECT_STREQ(__llvm_libc::strsep(&string, ""), nullptr); + EXPECT_EQ(orig, string); + } + { + char s[] = "abcde"; + char *string = s, *orig = s; + EXPECT_STREQ(__llvm_libc::strsep(&string, ""), orig); + EXPECT_EQ(string, orig + 5); + } + { + char s[] = "abcde"; + char *string = s, *orig = s; + EXPECT_STREQ(__llvm_libc::strsep(&string, "fghijk"), orig); + EXPECT_EQ(string, orig + 5); + } +} + +TEST(LlvmLibcStrsepTest, TokenFound) { + char s[] = "abacd"; + char *string = s; + EXPECT_STREQ(__llvm_libc::strsep(&string, "c"), "aba"); + EXPECT_STREQ(string, "d"); +} + +TEST(LlvmLibcStrsepTest, DelimitersShouldNotBeIncludedInToken) { + char s[] = "__ab__:_cd__:__ef__:__"; + char *string = s; + ASSERT_STREQ(__llvm_libc::strsep(&string, "_:"), "ab"); + ASSERT_STREQ(__llvm_libc::strsep(&string, "_:"), "cd"); + ASSERT_STREQ(__llvm_libc::strsep(&string, "_:"), "ef"); + ASSERT_STREQ(__llvm_libc::strsep(&string, "_:"), nullptr); +}