/* (C) Copyright International Business Machines Corporation 23 January */
/* 1990.  All Rights Reserved. */
/*  */
/* See the file USERAGREEMENT distributed with this software for full */
/* terms and conditions of use. */
#ifndef lint
static char sccsinfo[] = "@(#)keycomp.c	1.6 3/13/90";
#endif

#include "li.h"


comparison
re_comparekeys(src1, src2)
object *src1, *src2;
{
    return((*src1->tsdr->comparekeys)(src1->value, src2->value));
}


/*ARGSUSED*/
comparison
cmp_noop(v1, v2)
valcell v1, v2;
{
    nilerror("cmp_noop", "Key compare not yet implemented for type.");
}


/*ARGSUSED*/
comparison
cmp_illegal(v1, v2)
valcell v1, v2;
{
    nilerror("cmp_illegal", "Key comparison not allowed for type.");
}


/*ARGSUSED*/
comparison
cmp_bottom(v1, v2)
valcell v1, v2;
{
    return(CMP_EQUAL);
}


#define compare_numeric(n1,n2) \
	((n1) is (n2) ? CMP_EQUAL : ((n1) > (n2) ? CMP_GREATER : CMP_LESS))

comparison
cmp_integer(v1, v2)
valcell v1, v2;
{
    return(compare_numeric(v1.integer, v2.integer));
}


comparison
cmp_unsigned(v1, v2)
valcell v1, v2;
{
    return(compare_numeric(v1.ord_enum, v2.ord_enum));
}


/* true is greater than false */
#define compare_boolean(b1, b2) \
	((b1) ? ((b2) ? CMP_EQUAL : CMP_GREATER) : \
		((b2) ? CMP_LESS : CMP_EQUAL))

comparison
cmp_boolean(v1, v2)
valcell v1, v2;
{
    return(compare_boolean(v1.boolean, v2.boolean));
}


comparison
cmp_real(v1, v2)
valcell v1, v2;
{
    return(compare_numeric(*v1.real, *v2.real));
}


comparison
cmp_record(v1, v2)
valcell v1, v2;
{
    comparison cmp;
    int i;

    cmp = CMP_EQUAL;		/* in case there are 0 components */

    for (i = 0; i < v1.record->info.record_size and cmp is CMP_EQUAL; i++) 
	cmp = re_comparekeys(& v1.record->data[i], & v2.record->data[i]);

    return(cmp);
}


comparison
cmp_variant(v1, v2)
valcell v1, v2;
{
    comparison cmp;


    /* ordered first by variant case (even if variant is based on an */
    /* unordered enumeration???) */
    if ((cmp = compare_numeric(v1.variant->info.variant_case,
			       v2.variant->info.variant_case))
	isnt CMP_EQUAL)
      return(cmp);

    return(re_comparekeys(& v1.variant->data[0], & v2.variant->data[0]));
}


comparison
cmp_nominal(v1,v2)
valcell v1, v2;
{
    comparison cmp;

    if (v1.nominal is v2.nominal)
      return(CMP_EQUAL);

    if (v1.nominal->time < v2.nominal->time)
      return(CMP_LESS);
    if (v1.nominal->time > v2.nominal->time)
      return(CMP_GREATER);

    cmp = compare_numeric(v1.nominal->num, v2.nominal->num);

#ifdef DISTRIBUTED
    if (cmp isnt CMP_EQUAL)
      return(cmp);

    /* compare hosts -- fix later */
#endif

    return(cmp);
}
