/* 
 * $Id: idrp_utils.c,v 1.3 1995/06/13 12:23:14 sjr Exp $
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

#include "include.h"
#include "iso.h"
#include "idrp.h"
/*
 * idrp_utils.c -- sjr
 */

/*  
	The comparison is based upon:

	if they are the same for whatever is the smallest length:

		0x4304 0x43045

	then the shorter should be lexigraphically BEFORE (LESS THAN) the other.

	Otherwise, take the result of bcmp() when applied with that least length.

	NOTE that this follows the manpage statement that bcmp()'s args are
	reversed with respect to strcmp(); if (b1 > b2), then bcmp(b1,b2,len) < 0.

*/
int
bcmp_bothlens __PF4(b1, const caddr_t,
		    len1, int,
		    b2, const caddr_t, 
		    len2, int)
{
	boolean b1_smaller;
	int ans;

	if (len1 == len2) {
		return(bcmp((caddr_t) b1, (caddr_t) b2, len1));
	} else {
		b1_smaller = (len1 < len2);
		if (b1_smaller) {
			ans = bcmp((caddr_t) b1, (caddr_t) b2, len1);
			/* 
			 * if bcmp == 0, then b1 is lexigraphically LESS than b2 
			 * otherwise, the result is passed through
			 */
			return(ans == 0 ? +1 : ans);
		} else {
			ans = bcmp((caddr_t) b1, (caddr_t) b2, len2);
			/* 
			 * if bcmp == 0, then b2 is lexigraphically LESS than b1 
			 * otherwise, the result is passed through
			 */
			return(ans == 0 ? +1 : ans);
		}
	}
}

/* TODO SJR
#ifdef PROTO_RDPATHS
*/
idrp_canon_rdpath *
idrp_insert_canon_rdpath __PF2(p_list, idrp_canon_rdpath *,
			       p_elem, idrp_canon_rdpath *)
{
	idrp_canon_rdpath path;
	idrp_canon_rdpath *p_path;
	idrp_canon_rdpath *p_newlist;
	
	/* as long as the next element is smaller than p_elem, keep on going */

	for (path.p_next = p_list, p_path = &path;
	     (p_path->p_next) 
	      && (bcmp_bothlens((const caddr_t) p_path->p_next->p_rdi->rdi.isoa_genaddr, 
		                p_path->p_next->p_rdi->rdi.isoa_len, 
			        (const caddr_t) p_elem->p_rdi->rdi.isoa_genaddr,
			        p_elem->p_rdi->rdi.isoa_len) > 0);
	     p_path = p_path->p_next)
	     ;

	if ((p_path->p_next)
	    && !bcmp_bothlens((const caddr_t) p_path->p_next->p_rdi->rdi.isoa_genaddr, 
		              p_path->p_next->p_rdi->rdi.isoa_len, 
			      (const caddr_t) p_elem->p_rdi->rdi.isoa_genaddr,
			      p_elem->p_rdi->rdi.isoa_len)) {
		trace_tf(idrp_trace_options, TR_NORMAL, 0, ("%s (%d)--bad rdpath; duplicate entry", __FILE__, __LINE__));
		assert(FALSE);
	}

	/*
	 * insert the element- 
	 *   if at end, this is OK, since it is just a NULL ptr 
	 *   if at beginning, this is OK, since it is just in 'path' variable
	 */
	p_elem->p_next = p_path->p_next;
	p_path->p_next = p_elem;

	/* 
	 * if we're at the head, fix up the list
	 */
	if (p_path == &path) {
		p_newlist = p_elem;
	} else {
		p_newlist = p_list;
	}

	return(p_newlist);
}
/*
#endif
*/
