home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1988 Bellcore
- ** All Rights Reserved
- ** Permission is granted to copy or use this program, EXCEPT that it
- ** may not be sold for profit, the copyright notice must be reproduced
- ** on copies, and credit should be given to Bellcore where it is due.
- ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
- */
-
-
- #ifndef lint
- static char rcsid[]= "$Header: compare.c,v 1.1 88/09/15 11:33:53 daniel Rel $";
- #endif
-
- #include "misc.h"
- #include "flagdefs.h"
- #include "tol.h"
- #include "token.h"
- #include "line.h"
- #include "float.h"
- #include "compare.h"
-
- #include <ctype.h>
-
- X_com(a,b,flags)
- int a,b,flags;
- {
- K_token atmp,btmp;
-
- atmp = K_gettoken(0,a);
- btmp = K_gettoken(1,b);
- if(flags & U_BYTE_COMPARE)
- {
- return(_X_strcmp(K_gettext(atmp),K_gettext(btmp),flags));
- }
- else
- {
- return(_X_cmptokens(atmp,btmp,flags));
- }
- #ifndef lint
- Z_fatal("this line should never be reached in com");
- return(-1); /* Z_fatal never returns, but i need a this line
- here to stop lint from complaining */
- #endif
- }
-
- /*
- ** same as strcmp() except that case can be optionally ignored
- */
- static int
- _X_strcmp(s1,s2,flags)
- char *s1,*s2;
- int flags;
- {
- if (flags & U_NO_CASE)
- {
-
- for (;('\0' != s1) && ('\0' != *s2);s1++,s2++)
- {
- if(isalpha(*s1) && isalpha(*s2))
- {
- if(tolower(*s1) != tolower(*s2))
- {
- return(1);
- }
- }
- else
- {
- if(*s1!=*s2)
- {
- return(1);
- }
- }
- }
- return(*s1 != *s2);
- }
- else
- {
- return(strcmp(s1,s2));
- }
- }
-
-
- /*
- ** routine to compare two tokens
- */
- static int
- _X_cmptokens(p1,p2,flags)
- K_token p1, p2;
- int flags;
- {
- if (K_gettype(p1) != K_gettype(p2))
- {
- return(1);
- }
-
- switch (K_gettype(p1))
- {
- case K_LIT:
- return(_X_strcmp(K_gettext(p1),K_gettext(p2),flags));
- case K_FLO_NUM:
- return(_X_floatdiff(K_getfloat(p1),
- K_getfloat(p2),
- T_picktol(K_gettol(p1),
- K_gettol(p2))));
- default:
- Z_fatal("fell off switch in _X_cmptokens");
- return(-1); /* Z_fatal never returns, but i need a this line
- here to stop lint from complaining */
- }
-
- }
-
- /*
- ** compare two F_floats using a tolerance
- */
- static int
- _X_floatdiff(p1,p2,the_tol)
- F_float p1,p2;
- T_tol the_tol;
- {
- F_float diff, float_tmp;
- T_tol tol_tmp;
-
- /*
- ** check for null tolerance list
- */
- if (T_isnull(the_tol))
- {
- Z_fatal("_X_floatdiff called with a null tolerance");
- }
-
- /*
- ** look for an easy answer. i.e -- check
- ** to see if any of the tolerances are of type T_IGNORE
- ** or if the numbers are too small to exceed an absolute
- ** tolerance.
- ** if so, return immediately
- */
- for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp))
- {
- if ((T_IGNORE == T_gettype(tol_tmp)) ||
- /*
- ** take a look at the exponents before you bother
- ** with the mantissas
- */
- ((T_ABSOLUTE == T_gettype(tol_tmp))
- && !F_zerofloat(T_getfloat(tol_tmp))
- && (F_getexp(p1) <
- F_getexp(T_getfloat(tol_tmp))-1)
- && (F_getexp(p2) <
- F_getexp(T_getfloat(tol_tmp))-1)))
- {
- return(0);
- }
- }
-
-
- /*
- ** ok, we're going to have to do some arithmetic, so
- ** first find the magnitude of the difference
- */
- if (F_getsign(p1) != F_getsign(p2))
- {
- diff = F_floatmagadd(p1,p2);
- }
- else
- {
- diff = F_floatsub(p1,p2);
- }
-
- /*
- ** now check to see if the difference exceeds any tolerance
- */
- for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp))
- {
- float_tmp = T_getfloat(tol_tmp);
-
- if (T_gettype(tol_tmp) == T_ABSOLUTE)
- {
- /* do nothing */
- }
- else if (T_gettype(tol_tmp) == T_RELATIVE)
- {
- if (F_floatcmp(p1,p2) > 0)
- {
- float_tmp = F_floatmul(p1, float_tmp);
- }
- else
- {
- float_tmp = F_floatmul(p2, float_tmp);
- }
- }
- else
- {
- Z_fatal("bad value for type of tolerance in floatdiff");
- }
- /*
- ** if we pass this tolerance, then we're done
- */
- if (F_floatcmp(diff,float_tmp) <= 0)
- {
- return(0);
- }
- }
- /*
- ** all of the tolerances were exceeded
- */
- return(1);
- }
-