[libc-commits] [libc] [libc][tsearch] add tsearch functions (PR #172625)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Fri Jan 30 11:01:20 PST 2026


================
@@ -0,0 +1,137 @@
+//===-- Unittests for tsearch ---------------------------------------------===//
+//
+// 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 "hdr/types/posix_tnode.h"
+#include "src/search/tdelete.h"
+#include "src/search/tdestroy.h"
+#include "src/search/tfind.h"
+#include "src/search/tsearch.h"
+#include "src/search/twalk.h"
+#include "src/search/twalk_r.h"
+#include "test/UnitTest/Test.h"
+#include <search.h>
+
+static void *encode(int val) {
+  return reinterpret_cast<void *>(static_cast<intptr_t>(val));
+}
+
+static int decode(const void *val) {
+  return static_cast<int>(reinterpret_cast<intptr_t>(val));
+}
+
+static int read_and_decode(const __llvm_libc_tnode *val) {
+  return static_cast<int>(*static_cast<const intptr_t *>(val));
+}
+
+static int compare(const void *a, const void *b) {
+  int x = decode(a);
+  int y = decode(b);
+  return (x > y) - (x < y);
+}
+
+TEST(LlvmLibcTSearchTest, TSearch) {
+  void *root = nullptr;
+  void *result;
+  int key = 10;
+
+  // Insert 10
+  result = LIBC_NAMESPACE::tsearch(encode(key), &root, compare);
+  ASSERT_NE(result, nullptr);
+  ASSERT_EQ(read_and_decode(result), key);
+
+  // Find 10
+  result = LIBC_NAMESPACE::tfind(encode(key), &root, compare);
+  ASSERT_NE(result, nullptr);
+  ASSERT_EQ(read_and_decode(result), key);
+
+  // Insert 20
+  int key2 = 20;
+  result = LIBC_NAMESPACE::tsearch(encode(key2), &root, compare);
+  ASSERT_NE(result, nullptr);
+  ASSERT_EQ(read_and_decode(result), key2);
+
+  // Find 20
+  result = LIBC_NAMESPACE::tfind(encode(key2), &root, compare);
+  ASSERT_NE(result, nullptr);
+  ASSERT_EQ(read_and_decode(result), key2);
+
+  // Delete 10
+  result = LIBC_NAMESPACE::tdelete(encode(key), &root, compare);
+  ASSERT_NE(result, nullptr);
+
+  // Find 10 should fail
+  result = LIBC_NAMESPACE::tfind(encode(key), &root, compare);
+  ASSERT_EQ(result, nullptr);
+
+  // Delete 20
+  result = LIBC_NAMESPACE::tdelete(encode(key2), &root, compare);
+  ASSERT_NE(result, nullptr);
+  // Tree should be empty
+  ASSERT_EQ(root, nullptr);
+}
+
+static void free_node(void *) {
+  // Do nothing for integer keys
+}
----------------
michaelrj-google wrote:

given this it doesn't seem we're checking that the free function is actually called. I don't think we necessarily want to allocate/free in this test, but we could have a "free" function that sets a static variable to ensure it's been called.

https://github.com/llvm/llvm-project/pull/172625


More information about the libc-commits mailing list