xref: /dflybsd-src/lib/libc/stdlib/lsearch.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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