From b6288ade839f9de0cd569d091510068f0e78bb51 Mon Sep 17 00:00:00 2001 From: Scott Soule Cheloha Date: Wed, 8 Dec 2021 22:06:29 +0000 Subject: lsearch(3): reimplement using lfind(3) lsearch(3) is really just lfind(3) with an additional branch to append the key if lfind(3) fails. If we get rid of the underlying linear_base() function and move the search portion into lfind(3) and the key-copying portion into lsearch(3) we get smaller and simpler code. Misc. notes: - We do not need to keep the historical comment about errno. lsearch(3) is pure computation and does not set errno. That's really all you need to know. The specification reserves no errors, either. - We are using lfind(3) internally now, so it switches from PROTO_DEPRECATED to PROTO_NORMAL in hidden/search.h and needs DEF_WEAK in stdlib/lsearch.c. With advice from guenther@ on symbol housekeeping in libc. Thread: https://marc.info/?l=openbsd-tech&m=163885187632449&w=2 ok millert@ --- lib/libc/stdlib/lsearch.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) (limited to 'lib/libc/stdlib') diff --git a/lib/libc/stdlib/lsearch.c b/lib/libc/stdlib/lsearch.c index 93e200e1bdb..95ebf49b819 100644 --- a/lib/libc/stdlib/lsearch.c +++ b/lib/libc/stdlib/lsearch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lsearch.c,v 1.6 2021/12/07 04:01:45 cheloha Exp $ */ +/* $OpenBSD: lsearch.c,v 1.7 2021/12/08 22:06:28 cheloha Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,27 +37,27 @@ #include typedef int (*cmp_fn_t)(const void *, const void *); -static void *linear_base(const void *, const void *, size_t *, size_t, - cmp_fn_t, int); void * lsearch(const void *key, void *base, size_t *nelp, size_t width, cmp_fn_t compar) { + void *element = lfind(key, base, nelp, width, compar); - return(linear_base(key, base, nelp, width, compar, 1)); + /* + * Use memmove(3) to ensure the key is copied cleanly into the + * array, even if the key overlaps with the end of the array. + */ + if (element == NULL) { + element = memmove((char *)base + *nelp * width, key, width); + *nelp += 1; + } + return element; } void * lfind(const void *key, const void *base, size_t *nelp, size_t width, cmp_fn_t compar) -{ - return(linear_base(key, base, nelp, width, compar, 0)); -} - -static void * -linear_base(const void *key, const void *base, size_t *nelp, size_t width, - cmp_fn_t compar, int add_flag) { const char *element, *end; @@ -65,25 +65,6 @@ linear_base(const void *key, const void *base, size_t *nelp, size_t width, for (element = base; element < end; element += width) if (!compar(key, element)) /* key found */ return((void *)element); - - if (!add_flag) /* key not found */ - return(NULL); - - /* - * The UNIX System User's Manual, 1986 edition claims that - * a NULL pointer is returned by lsearch with errno set - * appropriately, if there is not enough room in the table - * to add a new item. This can't be done as none of these - * routines have any method of determining the size of the - * table. This comment isn't in the 1986-87 System V - * manual. - */ - ++*nelp; - - /* - * Use memmove(3) to ensure the key is copied cleanly into the - * array, even if the key overlaps with the end of the array. - */ - memmove((void *)end, key, width); - return((void *)end); + return NULL; } +DEF_WEAK(lfind); -- cgit v1.2.3