diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -330,6 +330,8 @@ strstr.cpp HDRS strstr.h + DEPENDS + .memory_utils.strstr_implementation ) add_entrypoint_object( diff --git a/libc/src/string/memory_utils/CMakeLists.txt b/libc/src/string/memory_utils/CMakeLists.txt --- a/libc/src/string/memory_utils/CMakeLists.txt +++ b/libc/src/string/memory_utils/CMakeLists.txt @@ -66,3 +66,9 @@ HDRS strcmp_implementations.h ) + +add_header_library( + strstr_implementation + HDRS + strstr_implementations.h +) diff --git a/libc/src/string/memory_utils/strstr_implementations.h b/libc/src/string/memory_utils/strstr_implementations.h new file mode 100644 --- /dev/null +++ b/libc/src/string/memory_utils/strstr_implementations.h @@ -0,0 +1,33 @@ +//===-- str{,case}str implementation ----------------------------*- 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_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H +#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H + +#include + +namespace __llvm_libc { + +template +constexpr static char *strstr_implementation(const char *haystack, + const char *needle, Comp &&comp) { + // TODO: This is a simple brute force implementation. This can be + // improved upon using well known string matching algorithms. + for (size_t i = 0; comp(haystack[i], 0); ++i) { + size_t j = 0; + for (; comp(haystack[i + j], 0) && !comp(haystack[i + j], needle[j]); ++j) + ; + if (!comp(needle[j], 0)) + return const_cast(haystack + i); + } + return nullptr; +} + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H diff --git a/libc/src/string/strstr.cpp b/libc/src/string/strstr.cpp --- a/libc/src/string/strstr.cpp +++ b/libc/src/string/strstr.cpp @@ -9,21 +9,15 @@ #include "src/string/strstr.h" #include "src/__support/common.h" -#include +#include "src/string/memory_utils/strstr_implementations.h" namespace __llvm_libc { // TODO: This is a simple brute force implementation. This can be // improved upon using well known string matching algorithms. LLVM_LIBC_FUNCTION(char *, strstr, (const char *haystack, const char *needle)) { - for (size_t i = 0; haystack[i]; ++i) { - size_t j; - for (j = 0; haystack[i + j] && haystack[i + j] == needle[j]; ++j) - ; - if (!needle[j]) - return const_cast(haystack + i); - } - return nullptr; + auto comp = [](char l, char r) -> int { return l - r; }; + return strstr_implementation(haystack, needle, comp); } } // namespace __llvm_libc diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -1103,6 +1103,7 @@ "src/string/memory_utils/memmove_implementations.h", "src/string/memory_utils/memset_implementations.h", "src/string/memory_utils/strcmp_implementations.h", + "src/string/memory_utils/strstr_implementations.h", ], deps = [ ":__support_common", @@ -1315,6 +1316,7 @@ hdrs = ["src/string/strstr.h"], deps = [ ":__support_common", + ":string_memory_utils", ":string_utils", ], )