diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt --- a/libc/fuzzing/string/CMakeLists.txt +++ b/libc/fuzzing/string/CMakeLists.txt @@ -4,5 +4,6 @@ strcpy_fuzz.cpp DEPENDS strcpy + strlen memcpy ) 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 @@ -9,6 +9,7 @@ DEPENDS strcpy string_h + strlen ) add_entrypoint_object( @@ -19,9 +20,20 @@ strcpy.h DEPENDS string_h + strlen memcpy ) +add_entrypoint_object( + strlen + SRCS + strlen.cpp + HDRS + strlen.h + DEPENDS + string_h +) + # ------------------------------------------------------------------------------ # memcpy # ------------------------------------------------------------------------------ diff --git a/libc/src/string/strcat.cpp b/libc/src/string/strcat.cpp --- a/libc/src/string/strcat.cpp +++ b/libc/src/string/strcat.cpp @@ -7,16 +7,17 @@ //===----------------------------------------------------------------------===// #include "src/string/strcat.h" +#include "src/string/strcpy.h" +#include "src/string/strlen.h" #include "src/__support/common.h" -#include "src/string/strcpy.h" namespace __llvm_libc { char *LLVM_LIBC_ENTRYPOINT(strcat)(char *dest, const char *src) { // We do not yet have an implementaion of strlen in so we will use strlen // from another libc. - __llvm_libc::strcpy(dest + ::strlen(dest), src); + __llvm_libc::strcpy(dest + __llvm_libc::strlen(dest), src); return dest; } diff --git a/libc/src/string/strcpy.cpp b/libc/src/string/strcpy.cpp --- a/libc/src/string/strcpy.cpp +++ b/libc/src/string/strcpy.cpp @@ -8,6 +8,7 @@ #include "src/string/strcpy.h" #include "src/string/memcpy.h" +#include "src/string/strlen.h" #include "src/__support/common.h" @@ -15,7 +16,7 @@ char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) { return reinterpret_cast( - __llvm_libc::memcpy(dest, src, ::strlen(src) + 1)); + __llvm_libc::memcpy(dest, src, __llvm_libc::strlen(src) + 1)); } } // namespace __llvm_libc diff --git a/libc/src/string/strcpy.cpp b/libc/src/string/strlen.h copy from libc/src/string/strcpy.cpp copy to libc/src/string/strlen.h --- a/libc/src/string/strcpy.cpp +++ b/libc/src/string/strlen.h @@ -1,4 +1,4 @@ -//===-------------------- Implementation of strcpy -----------------------===// +//===----------------- Implementation header for strlen -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,16 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "src/string/strcpy.h" -#include "src/string/memcpy.h" +#ifndef LLVM_LIBC_SRC_STRING_STRLEN_H +#define LLVM_LIBC_SRC_STRING_STRLEN_H -#include "src/__support/common.h" +#include "include/string.h" namespace __llvm_libc { -char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) { - return reinterpret_cast( - __llvm_libc::memcpy(dest, src, ::strlen(src) + 1)); -} +size_t strlen(const char *src); } // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_STRLEN_H diff --git a/libc/src/string/strcpy.cpp b/libc/src/string/strlen.cpp copy from libc/src/string/strcpy.cpp copy to libc/src/string/strlen.cpp --- a/libc/src/string/strcpy.cpp +++ b/libc/src/string/strlen.cpp @@ -1,4 +1,4 @@ -//===-------------------- Implementation of strcpy -----------------------===// +//===-------------------- Implementation of strlen ------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,16 +6,19 @@ // //===----------------------------------------------------------------------===// -#include "src/string/strcpy.h" #include "src/string/memcpy.h" +#include "src/string/strcpy.h" #include "src/__support/common.h" namespace __llvm_libc { -char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) { - return reinterpret_cast( - __llvm_libc::memcpy(dest, src, ::strlen(src) + 1)); +size_t LLVM_LIBC_ENTRYPOINT(strlen)(const char *src) { + const char *end = src; + while (*end != '\0') { + end++; + } + return end - src; } } // namespace __llvm_libc diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt --- a/libc/test/src/string/CMakeLists.txt +++ b/libc/test/src/string/CMakeLists.txt @@ -11,6 +11,7 @@ DEPENDS strcat strcpy + strlen memcpy ) @@ -22,9 +23,20 @@ strcpy_test.cpp DEPENDS strcpy + strlen memcpy ) +add_libc_unittest( + strlen_test + SUITE + libc_string_unittests + SRCS + strlen_test.cpp + DEPENDS + strlen +) + # Tests all implementations of memcpy that can run on the host. get_property(memcpy_implementations GLOBAL PROPERTY memcpy_implementations) foreach(memcpy_config_name IN LISTS memcpy_implementations) diff --git a/libc/test/src/string/strlen_test.cpp b/libc/test/src/string/strlen_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/string/strlen_test.cpp @@ -0,0 +1,24 @@ +//===----------------------- Unittests for strlen -------------------------===// +// +// 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/strlen.h" +#include "utils/UnitTest/Test.h" + +TEST(StrLenTest, EmptyString) { + const char *empty = ""; + + size_t result = __llvm_libc::strlen(empty); + ASSERT_EQ((size_t)0, result); +} + +TEST(StrLenTest, AnyString) { + const char *any = "Hello World!"; + + size_t result = __llvm_libc::strlen(any); + ASSERT_EQ((size_t)12, result); +}