Author: Cheng Wang Date: 2020-12-02T20:45:51+08:00 New Revision: 60cef893627be169f22dc540834c4d085847d94a
URL: https://github.com/llvm/llvm-project/commit/60cef893627be169f22dc540834c4d085847d94a DIFF: https://github.com/llvm/llvm-project/commit/60cef893627be169f22dc540834c4d085847d94a.diff LOG: [libc] Add strncpy implementation. Add libc strncpy implementation. Reviewed By: sivachandra, gchatelet Differential Revision: https://reviews.llvm.org/D91399 Added: libc/src/string/strncpy.cpp libc/src/string/strncpy.h libc/test/src/string/strncpy_test.cpp Modified: libc/config/linux/aarch64/entrypoints.txt libc/config/linux/x86_64/entrypoints.txt libc/src/string/CMakeLists.txt libc/test/src/string/CMakeLists.txt Removed: ################################################################################ diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 3a34d95b36e1..1d8e5dd83672 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -29,6 +29,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strlen + libc.src.string.strncpy libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 4eb964b2c047..d6d56f2e33a5 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -47,6 +47,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strlen + libc.src.string.strncpy libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 8a2adbe08e0b..94df8a9d2166 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -74,6 +74,14 @@ add_entrypoint_object( strstr.h ) +add_entrypoint_object( + strncpy + SRCS + strncpy.cpp + HDRS + strncpy.h +) + add_entrypoint_object( strnlen SRCS diff --git a/libc/src/string/strncpy.cpp b/libc/src/string/strncpy.cpp new file mode 100644 index 000000000000..45255e30ac52 --- /dev/null +++ b/libc/src/string/strncpy.cpp @@ -0,0 +1,28 @@ +//===-- Implementation of strncpy -----------------------------------------===// +// +// 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/strncpy.h" + +#include "src/__support/common.h" +#include <stddef.h> // For size_t. + +namespace __llvm_libc { + +char *LLVM_LIBC_ENTRYPOINT(strncpy)(char *__restrict dest, + const char *__restrict src, size_t n) { + size_t i = 0; + // Copy up until \0 is found. + for (; i < n && src[i] != '\0'; ++i) + dest[i] = src[i]; + // When n>strlen(src), n-strlen(src) \0 are appended. + for (; i < n; ++i) + dest[i] = '\0'; + return dest; +} + +} // namespace __llvm_libc diff --git a/libc/src/string/strncpy.h b/libc/src/string/strncpy.h new file mode 100644 index 000000000000..c419df990cd7 --- /dev/null +++ b/libc/src/string/strncpy.h @@ -0,0 +1,20 @@ +//===-- Implementation header for strncpy -----------------------*- 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_STRNCPY_H +#define LLVM_LIBC_SRC_STRING_STRNCPY_H + +#include <stddef.h> + +namespace __llvm_libc { + +char *strncpy(char *__restrict dest, const char *__restrict src, size_t n); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_STRNCPY_H diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt index df824cd18ecc..8b78fcfdd020 100644 --- a/libc/test/src/string/CMakeLists.txt +++ b/libc/test/src/string/CMakeLists.txt @@ -72,6 +72,16 @@ add_libc_unittest( libc.src.string.strstr ) +add_libc_unittest( + strncpy_test + SUITE + libc_string_unittests + SRCS + strncpy_test.cpp + DEPENDS + libc.src.string.strncpy +) + add_libc_unittest( strnlen_test SUITE diff --git a/libc/test/src/string/strncpy_test.cpp b/libc/test/src/string/strncpy_test.cpp new file mode 100644 index 000000000000..814870613251 --- /dev/null +++ b/libc/test/src/string/strncpy_test.cpp @@ -0,0 +1,57 @@ +//===-- Unittests for strncpy ---------------------------------------------===// +// +// 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/strncpy.h" +#include "utils/CPP/ArrayRef.h" +#include "utils/UnitTest/Test.h" +#include <stddef.h> // For size_t. + +class StrncpyTest : public __llvm_libc::testing::Test { +public: + void check_strncpy(__llvm_libc::cpp::MutableArrayRef<char> dst, + const __llvm_libc::cpp::ArrayRef<char> src, size_t n, + const __llvm_libc::cpp::ArrayRef<char> expected) { + // Making sure we don't overflow buffer. + ASSERT_GE(dst.size(), n); + // Making sure strncpy returns dst. + ASSERT_EQ(__llvm_libc::strncpy(dst.data(), src.data(), n), dst.data()); + // Expected must be of the same size as dst. + ASSERT_EQ(dst.size(), expected.size()); + // Expected and dst are the same. + for (size_t i = 0; i < expected.size(); ++i) + ASSERT_EQ(expected[i], dst[i]); + } +}; + +TEST_F(StrncpyTest, Untouched) { + char dst[] = {'a', 'b'}; + const char src[] = {'x', '\0'}; + const char expected[] = {'a', 'b'}; + check_strncpy(dst, src, 0, expected); +} + +TEST_F(StrncpyTest, CopyOne) { + char dst[] = {'a', 'b'}; + const char src[] = {'x', 'y'}; + const char expected[] = {'x', 'b'}; // no \0 is appended + check_strncpy(dst, src, 1, expected); +} + +TEST_F(StrncpyTest, CopyNull) { + char dst[] = {'a', 'b'}; + const char src[] = {'\0', 'y'}; + const char expected[] = {'\0', 'b'}; + check_strncpy(dst, src, 1, expected); +} + +TEST_F(StrncpyTest, CopyPastSrc) { + char dst[] = {'a', 'b'}; + const char src[] = {'\0', 'y'}; + const char expected[] = {'\0', '\0'}; + check_strncpy(dst, src, 2, expected); +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits