1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino * Initial implementation:
3*86d7f5d3SJohn Marino * Copyright (c) 2002 Robert Drehmel
4*86d7f5d3SJohn Marino * All rights reserved.
5*86d7f5d3SJohn Marino *
6*86d7f5d3SJohn Marino * As long as the above copyright statement and this notice remain
7*86d7f5d3SJohn Marino * unchanged, you can do what ever you want with this file.
8*86d7f5d3SJohn Marino *
9*86d7f5d3SJohn Marino * $FreeBSD: src/lib/libc/stdlib/lsearch.c,v 1.1 2002/10/16 14:29:22 robert Exp $
10*86d7f5d3SJohn Marino * $DragonFly: src/lib/libc/stdlib/lsearch.c,v 1.1 2008/05/19 10:06:34 corecode Exp $
11*86d7f5d3SJohn Marino */
12*86d7f5d3SJohn Marino #include <sys/types.h>
13*86d7f5d3SJohn Marino
14*86d7f5d3SJohn Marino #define _SEARCH_PRIVATE
15*86d7f5d3SJohn Marino #include <search.h>
16*86d7f5d3SJohn Marino #include <stdint.h> /* for uint8_t */
17*86d7f5d3SJohn Marino #include <stdlib.h> /* for NULL */
18*86d7f5d3SJohn Marino #include <string.h> /* for memcpy() prototype */
19*86d7f5d3SJohn Marino
20*86d7f5d3SJohn Marino static void *lwork(const void *, const void *, size_t *, size_t,
21*86d7f5d3SJohn Marino int (*)(const void *, const void *), int);
22*86d7f5d3SJohn Marino
lsearch(const void * key,void * base,size_t * nelp,size_t width,int (* compar)(const void *,const void *))23*86d7f5d3SJohn Marino void *lsearch(const void *key, void *base, size_t *nelp, size_t width,
24*86d7f5d3SJohn Marino int (*compar)(const void *, const void *))
25*86d7f5d3SJohn Marino {
26*86d7f5d3SJohn Marino
27*86d7f5d3SJohn Marino return (lwork(key, base, nelp, width, compar, 1));
28*86d7f5d3SJohn Marino }
29*86d7f5d3SJohn Marino
lfind(const void * key,const void * base,size_t * nelp,size_t width,int (* compar)(const void *,const void *))30*86d7f5d3SJohn Marino void *lfind(const void *key, const void *base, size_t *nelp, size_t width,
31*86d7f5d3SJohn Marino int (*compar)(const void *, const void *))
32*86d7f5d3SJohn Marino {
33*86d7f5d3SJohn Marino
34*86d7f5d3SJohn Marino return (lwork(key, base, nelp, width, compar, 0));
35*86d7f5d3SJohn Marino }
36*86d7f5d3SJohn Marino
37*86d7f5d3SJohn Marino static void *
lwork(const void * key,const void * base,size_t * nelp,size_t width,int (* compar)(const void *,const void *),int addelem)38*86d7f5d3SJohn Marino lwork(const void *key, const void *base, size_t *nelp, size_t width,
39*86d7f5d3SJohn Marino int (*compar)(const void *, const void *), int addelem)
40*86d7f5d3SJohn Marino {
41*86d7f5d3SJohn Marino uint8_t *ep, *endp;
42*86d7f5d3SJohn Marino
43*86d7f5d3SJohn Marino /*
44*86d7f5d3SJohn Marino * Cast to an integer value first to avoid the warning for removing
45*86d7f5d3SJohn Marino * 'const' via a cast.
46*86d7f5d3SJohn Marino */
47*86d7f5d3SJohn Marino ep = (uint8_t *)(uintptr_t)base;
48*86d7f5d3SJohn Marino for (endp = (uint8_t *)(ep + width * *nelp); ep < endp; ep += width) {
49*86d7f5d3SJohn Marino if (compar(key, ep) == 0)
50*86d7f5d3SJohn Marino return (ep);
51*86d7f5d3SJohn Marino }
52*86d7f5d3SJohn Marino
53*86d7f5d3SJohn Marino /* lfind() shall return when the key was not found. */
54*86d7f5d3SJohn Marino if (!addelem)
55*86d7f5d3SJohn Marino return (NULL);
56*86d7f5d3SJohn Marino
57*86d7f5d3SJohn Marino /*
58*86d7f5d3SJohn Marino * lsearch() adds the key to the end of the table and increments
59*86d7f5d3SJohn Marino * the number of elements.
60*86d7f5d3SJohn Marino */
61*86d7f5d3SJohn Marino memcpy(endp, key, width);
62*86d7f5d3SJohn Marino ++*nelp;
63*86d7f5d3SJohn Marino
64*86d7f5d3SJohn Marino return (endp);
65*86d7f5d3SJohn Marino }
66