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);

Reply via email to