Connector Switch 2025-03-19 08:40:59 +08:00 committed by GitHub
parent 9ed772cecc
commit af7c8c475a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 162 additions and 1 deletions

View File

@ -999,6 +999,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.hsearch_r
libc.src.search.insque
libc.src.search.lfind
libc.src.search.lsearch
libc.src.search.remque
# threads.h entrypoints

View File

@ -943,6 +943,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.hsearch_r
libc.src.search.insque
libc.src.search.lfind
libc.src.search.lsearch
libc.src.search.remque
# threads.h entrypoints

View File

@ -1113,6 +1113,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.hsearch_r
libc.src.search.insque
libc.src.search.lfind
libc.src.search.lsearch
libc.src.search.remque
# threads.h entrypoints

View File

@ -69,3 +69,13 @@ functions:
- type: size_t *
- type: size_t
- type: __lsearchcompare_t
- name: lsearch
standards:
- POSIX
return_type: void *
arguments:
- type: const void *
- type: void *
- type: size_t *
- type: size_t
- type: __lsearchcompare_t

View File

@ -110,3 +110,16 @@ add_entrypoint_object(
libc.src.__support.CPP.cstddef
libc.src.__support.memory_size
)
add_entrypoint_object(
lsearch
SRCS
lsearch.cpp
HDRS
lsearch.h
DEPENDS
libc.include.search
libc.src.__support.CPP.cstddef
libc.src.__support.memory_size
libc.src.string.memory_utils.inline_memcpy
)

View File

@ -1,4 +1,4 @@
//===-- Implementation of lfind -------------------------------*- C++ -*-===//
//===-- Implementation of lfind ---------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.

View File

@ -0,0 +1,39 @@
//===-- Implementation of lsearch -------------------------------*- 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
//
//===----------------------------------------------------------------------===//
#include "src/search/lsearch.h"
#include "src/__support/CPP/cstddef.h" // cpp::byte
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/memory_size.h"
#include "src/string/memory_utils/inline_memcpy.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(void *, lsearch,
(const void *key, void *base, size_t *nmemb, size_t size,
int (*compar)(const void *, const void *))) {
if (key == nullptr || base == nullptr || nmemb == nullptr ||
compar == nullptr)
return nullptr;
size_t byte_len = 0;
if (internal::mul_overflow(*nmemb, size, &byte_len))
return nullptr;
const cpp::byte *next = reinterpret_cast<const cpp::byte *>(base);
const cpp::byte *end = next + byte_len;
for (; next < end; next += size)
if (compar(key, next) == 0)
return const_cast<cpp::byte *>(next);
*nmemb += 1;
inline_memcpy(const_cast<cpp::byte *>(end), key, size);
return const_cast<cpp::byte *>(end);
}
} // namespace LIBC_NAMESPACE_DECL

20
libc/src/search/lsearch.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for lsearch -----------------------*- 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_SEARCH_LSEARCH_H
#define LLVM_LIBC_SRC_SEARCH_LSEARCH_H
#include "src/__support/macros/config.h"
#include <stddef.h> // size_t
namespace LIBC_NAMESPACE_DECL {
void *lsearch(const void *key, void *base, size_t *nmemb, size_t size,
int (*compar)(const void *, const void *));
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_SEARCH_LSEARCH_H

View File

@ -35,3 +35,13 @@ add_libc_unittest(
DEPENDS
libc.src.search.lfind
)
add_libc_unittest(
lsearch_test
SUITE
libc_search_unittests
SRCS
lsearch_test.cpp
DEPENDS
libc.src.search.lsearch
)

View File

@ -0,0 +1,66 @@
//===-- Unittests for lsearch ---------------------------------------------===//
//
// 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/search/lsearch.h"
#include "test/UnitTest/Test.h"
int compar(const void *a, const void *b) {
return *reinterpret_cast<const int *>(a) != *reinterpret_cast<const int *>(b);
}
TEST(LlvmLibcLsearchTest, SearchHead) {
int list[3] = {1, 2, 3};
size_t len = 3;
int key = 1;
void *ret = LIBC_NAMESPACE::lsearch(&key, list, &len, sizeof(int), compar);
ASSERT_TRUE(ret == &list[0]);
}
TEST(LlvmLibcLsearchTest, SearchMiddle) {
int list[3] = {1, 2, 3};
size_t len = 3;
int key = 2;
void *ret = LIBC_NAMESPACE::lsearch(&key, list, &len, sizeof(int), compar);
ASSERT_TRUE(ret == &list[1]);
}
TEST(LlvmLibcLsearchTest, SearchTail) {
int list[3] = {1, 2, 3};
size_t len = 3;
int key = 3;
void *ret = LIBC_NAMESPACE::lsearch(&key, list, &len, sizeof(int), compar);
ASSERT_TRUE(ret == &list[2]);
}
TEST(LlvmLibcLsearchTest, SearchNonExistent) {
int list[4] = {1, 2, 3, 0};
size_t len = 3;
int key = 4;
void *ret = LIBC_NAMESPACE::lsearch(&key, list, &len, sizeof(int), compar);
ASSERT_TRUE(ret == &list[3]);
ASSERT_EQ(key, list[3]);
ASSERT_EQ(len, 4UL);
}
TEST(LlvmLibcLsearchTest, SearchExceptional) {
int list[3] = {1, 2, 3};
size_t len = 3;
size_t max_len = ~0;
int key = 3;
ASSERT_EQ(LIBC_NAMESPACE::lsearch(nullptr, list, &len, sizeof(int), compar),
nullptr);
ASSERT_EQ(LIBC_NAMESPACE::lsearch(&key, nullptr, &len, sizeof(int), compar),
nullptr);
ASSERT_EQ(LIBC_NAMESPACE::lsearch(&key, list, nullptr, sizeof(int), compar),
nullptr);
ASSERT_EQ(LIBC_NAMESPACE::lsearch(&key, list, &max_len, sizeof(int), compar),
nullptr);
ASSERT_EQ(LIBC_NAMESPACE::lsearch(&key, list, &len, sizeof(int), nullptr),
nullptr);
}