/*-----------------------------------------------------------------------*
 * filename - lsearch.c
 *
 * function(s)
 *   _lsearch - searches a table
 *   lsearch  - searches and updates a table
 *   lfind    - perform a linear search
 *-----------------------------------------------------------------------*/

/*
 *      C/C++ Run Time Library - Version 6.0
 *
 *      Copyright (c) 1987, 1993 by Borland International
 *      All Rights Reserved.
 *
 */

#include <stdlib.h>
#include <mem.h>
#include <stddef.h>

/*---------------------------------------------------------------------*

Name         _lsearch - searches a table

Usage        static void *
             _lsearch(const void *key,
                   void  *base,
                   size_t  *nelem,
                   size_t  width,
                   int _USERENTRY (*fcmp)(const void *, const void *),
                   int  flag)

Description  performs lfind or lsearch depending on the value of flag.
             If flag is 1 it updates the table if no match, if flag
             is 0 it only searches.

Return value Nothing

*---------------------------------------------------------------------*/
static void * _lsearch(const void    *key,
                       register void *base,
                       size_t        *nelem,
                       size_t        width,
                       int (_USERENTRY *fcmp)(const void *, const void *),
                       int            flag)
{
    register int    Wrk;
    char *bse = (char *)base;

    for (Wrk = *nelem; Wrk > 0; Wrk--)
        {
        if (((*fcmp)(key, bse)) == 0)
           return(bse);
        bse += width;
        }
    if (flag)
       {
       (*nelem)++;
       memmove(bse, (void *)key, width);
       }
    else
       bse = NULL;
    return(bse);
}

/*--------------------------------------------------------------------------*

Name         lsearch - searches and updates a table
             lfind - perform a linear search

Usage        void *lsearch(const void *key,
             void *base,
             size_t *nelem,
             size_t width,
             int _USERENTRY (*fcmp)(const void *, const void *));

             void *lfind(const void *key,
             const void *base,
             size_t *nelem,
             size_t width,
             int _USERENTRY (*fcmp)(const void *, const void *));

Prototype in stdlib.h

Description  lfind and lsearch search  a table for information. Because
             these are linear searches, the table entries do not need to
             be sorted before a call to lfind or lsearch. If the item that
             key  points  to  is  not  in the table, lsearch appends that
             item to the table, but lfind does not.

             . key points to  the item to be searched  for. ("the search
               key")

             . base points to the base (0th element) of the search table

             . nelem points to an integer containing  number of entries
               in the table.

             . width contains the number of bytes in each entry

             . fcmp points to  a user-written  comparison routine. That
               routine compares 2  items and returns a value  based on the
               comparison.
             On each call to the comparison routine, the search function
             passes 2 arguments: key, a pointer to the item being searched
             for;  and elem,  a pointer   to the  element of  base being
             compared.
             fcmp  is free  to interpret  the search  key and  the table
             entry any way it likes.

Return value lsearch and lfind return the  address of the first entry in
             the  table that  matches the   search key.  If no  match is
             found, lfind returns 0.

             In lsearch and lfind:

             If the key is   fcmp returns
             -------------   ------------
             Not identical to *elem  An integer != 0
             Identical to *elem  0

*---------------------------------------------------------------------------*/

void * _RTLENTRY _EXPFUNC lsearch(const void *key, void *base, size_t *nelem, size_t width,
              int (_USERENTRY *fcmp)(const void *, const void *))
{
    return(_lsearch(key,base,nelem,width,fcmp,1));
}


/*---------------------------------------------------------------------*

Name            lfind - performs a linear search

Usage           void *lfind(void *key, void *base, size_t *nelem,
                            size_t width,
                            int (*fcmp)(const void *, const void *) );

Prototype in    stdlib.h

Description     see lsearch above

*---------------------------------------------------------------------*/

void * _RTLENTRY _EXPFUNC lfind(const void *key, const void *base, size_t *nelem, size_t width,
            int (_USERENTRY *fcmp)(const void *, const void *))
{
    return(_lsearch(key,(void *)base,nelem,width,fcmp,0));
}
