/*=-=-=-=-=-=-=-=-=-=-  RCCL/RCI Notice of Copyright  -=-=-=-=-=-=-=-=-=-=-=*
 *									    *
 *	Copyright (C) 1987 by Mike Parker. Permission to use, distribute    *
 *	and copy is granted for non-commercial and research purposes only,  *
 *	providing the authors are acknowledged and this copyright notice is *
 *	displayed. The authors provide this software in hope that it will   *
 *	useful, but do not assume responsibility for its use.		    *
 *									    *
 *	This software was developed using the facilities of the McGill 	    *
 *	University Research Center for Intelligent Machines, Montreal,	    *
 *	Canada, for a project undertaken and supported by the RCA Advanced  *
 *	Technology Laboratories, Moorestown, New Jersey.		    *
 *									    *
 *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

int binsearch(ptrs,nels,cmp,el)
char **ptrs;
int nels;
int (*cmp)();
char *el;
/* the `char's should be <unknown>, but there is no such type in C */
/*
	This is a binary search routine.  ON THE ASSUMPTION THAT THE ptrs
	VECTOR IS SORTED (eg, with heapsort), this will search for the `el'
	element.  The cmp function is used for comparisons:

	cmp(ptrs[i],ptrs[j]) should be < 0 if *ptrs[i] < *ptrs[j]
	cmp(ptrs[i],ptrs[j]) should be = 0 if *ptrs[i] = *ptrs[j]
	cmp(ptrs[i],ptrs[j]) should be > 0 if *ptrs[i] > *ptrs[j]

	Under these assumptions, the return value will be the index in the
	ptrs vector of an element which compared equal to the searched-for
	element, if any was found; otherwise, it will be -1.
*/
{
 int hi;
 int lo;
 int mid;
 int cval;

 if (nels < 1)
  { return(-1);
  }
 hi = nels-1;
 lo = 0;
 cval = (*cmp)(ptrs[0],el);
 if (cval > 0)
  { return(-1);
  }
 if (cval == 0)
  { return(0);
  }
 cval = (*cmp)(ptrs[hi],el);
 if (cval < 0)
  { return(-1);
  }
 if (cval == 0)
  { return(hi);
  }
 while (hi-lo > 1)
  { mid = (hi+lo) / 2;
    cval = (*cmp)(ptrs[mid],el);
    if (cval < 0)
     { lo = mid;
     }
    else if (cval > 0)
     { hi = mid;
     }
    else
     { return(mid);
     }
  }
 return(-1);
}
