lsearch(3) is just lfind(3) + append. If we write it that way we shrink lsearch.c. The third function, linear_base(), is just added complexity. The indirection buys us nothing.
I don't think we need to keep the historical comment, either. lsearch(3) is pure computation, it does not set errno: The End. The spec defines no errors, either. libc housekeeping: - lfind becomes PROTO_NORMAL because we're now using it internally. - lfind then needs DEF_WEAK because it is not ISO C. Unsure if I'm missing other libc housekeeping. If not, ok? Index: stdlib/lsearch.c =================================================================== RCS file: /cvs/src/lib/libc/stdlib/lsearch.c,v retrieving revision 1.6 diff -u -p -r1.6 lsearch.c --- stdlib/lsearch.c 7 Dec 2021 04:01:45 -0000 1.6 +++ stdlib/lsearch.c 7 Dec 2021 04:32:34 -0000 @@ -37,53 +37,34 @@ #include <search.h> 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; end = (const char *)base + *nelp * 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); Index: hidden/search.h =================================================================== RCS file: /cvs/src/lib/libc/hidden/search.h,v retrieving revision 1.1 diff -u -p -r1.1 search.h --- hidden/search.h 4 Oct 2015 08:36:57 -0000 1.1 +++ hidden/search.h 7 Dec 2021 04:32:34 -0000 @@ -24,7 +24,7 @@ PROTO_DEPRECATED(hcreate); PROTO_DEPRECATED(hdestroy); PROTO_DEPRECATED(hsearch); PROTO_DEPRECATED(insque); -PROTO_DEPRECATED(lfind); +PROTO_NORMAL(lfind); PROTO_DEPRECATED(lsearch); PROTO_DEPRECATED(remque); PROTO_DEPRECATED(tdelete);