lsearch.c revision 259065
140123Sdes/*
266830Sobrien * Initial implementation:
3126310Smtm * Copyright (c) 2002 Robert Drehmel
466830Sobrien * All rights reserved.
566830Sobrien *
666830Sobrien * As long as the above copyright statement and this notice remain
766830Sobrien * unchanged, you can do what ever you want with this file.
866830Sobrien */
966830Sobrien#include <sys/types.h>
1066830Sobrien#include <sys/cdefs.h>
1166830Sobrien__FBSDID("$FreeBSD: releng/10.0/lib/libc/stdlib/lsearch.c 105250 2002-10-16 14:29:23Z robert $");
1266830Sobrien
1366830Sobrien#define	_SEARCH_PRIVATE
1466830Sobrien#include <search.h>
1566830Sobrien#include <stdint.h>	/* for uint8_t */
1666830Sobrien#include <stdlib.h>	/* for NULL */
1766830Sobrien#include <string.h>	/* for memcpy() prototype */
1866830Sobrien
1966830Sobrienstatic void *lwork(const void *, const void *, size_t *, size_t,
2066830Sobrien    int (*)(const void *, const void *), int);
2166830Sobrien
2266830Sobrienvoid *lsearch(const void *key, void *base, size_t *nelp, size_t width,
2366830Sobrien    int (*compar)(const void *, const void *))
2466830Sobrien{
2566830Sobrien
2666830Sobrien	return (lwork(key, base, nelp, width, compar, 1));
2783871Sobrien}
2850472Speter
2966830Sobrienvoid *lfind(const void *key, const void *base, size_t *nelp, size_t width,
3037Srgrimes    int (*compar)(const void *, const void *))
3137Srgrimes{
3237Srgrimes
3337Srgrimes	return (lwork(key, base, nelp, width, compar, 0));
3437Srgrimes}
3537Srgrimes
3651231Ssheldonhstatic void *
3751231Ssheldonhlwork(const void *key, const void *base, size_t *nelp, size_t width,
3851231Ssheldonh    int (*compar)(const void *, const void *), int addelem)
3951231Ssheldonh{
408460Sjkh	uint8_t *ep, *endp;
4137Srgrimes
4237Srgrimes	/*
4337Srgrimes	 * Cast to an integer value first to avoid the warning for removing
44130161Smtm	 * 'const' via a cast.
4551231Ssheldonh	 */
4637Srgrimes	ep = (uint8_t *)(uintptr_t)base;
47130161Smtm	for (endp = (uint8_t *)(ep + width * *nelp); ep < endp; ep += width) {
4837Srgrimes		if (compar(key, ep) == 0)
4951231Ssheldonh			return (ep);
5092441Scjc	}
5151231Ssheldonh
5237Srgrimes	/* lfind() shall return when the key was not found. */
53114492Sdougb	if (!addelem)
54114492Sdougb		return (NULL);
55114492Sdougb
56114492Sdougb	/*
57108200Sdillon	 * lsearch() adds the key to the end of the table and increments
58114492Sdougb	 * the number of elements.
59114492Sdougb	 */
6098189Sgordon	memcpy(endp, key, width);
6198189Sgordon	++*nelp;
62145693Sbrooks
63145693Sbrooks	return (endp);
64145693Sbrooks}
65145693Sbrooks