home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 211.lha / Spiff / compare.c < prev    next >
C/C++ Source or Header  |  1996-02-14  |  4KB  |  210 lines

  1. /*                        Copyright (c) 1988 Bellcore
  2. **                            All Rights Reserved
  3. **       Permission is granted to copy or use this program, EXCEPT that it
  4. **       may not be sold for profit, the copyright notice must be reproduced
  5. **       on copies, and credit should be given to Bellcore where it is due.
  6. **       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7. */
  8.  
  9.  
  10. #ifndef lint
  11. static char rcsid[]= "$Header: compare.c,v 1.1 88/09/15 11:33:53 daniel Rel $";
  12. #endif
  13.  
  14. #include "misc.h"
  15. #include "flagdefs.h"
  16. #include "tol.h"
  17. #include "token.h"
  18. #include "line.h"
  19. #include "float.h"
  20. #include "compare.h"
  21.  
  22. #include <ctype.h>
  23.  
  24. X_com(a,b,flags)
  25. int a,b,flags;
  26. {
  27.     K_token atmp,btmp;
  28.  
  29.     atmp = K_gettoken(0,a);
  30.     btmp = K_gettoken(1,b);
  31.     if(flags & U_BYTE_COMPARE)
  32.     {
  33.         return(_X_strcmp(K_gettext(atmp),K_gettext(btmp),flags));
  34.     }
  35.     else
  36.     {
  37.         return(_X_cmptokens(atmp,btmp,flags));
  38.     }
  39. #ifndef lint 
  40.     Z_fatal("this line should never be reached in com");
  41.     return(-1);    /* Z_fatal never returns, but i need a this line
  42.                 here to stop lint from complaining */
  43. #endif
  44. }
  45.  
  46. /*
  47. **    same as strcmp() except that case can be optionally ignored
  48. */
  49. static int
  50. _X_strcmp(s1,s2,flags)
  51. char *s1,*s2;
  52. int flags;
  53. {
  54.     if (flags & U_NO_CASE)
  55.     {
  56.         
  57.         for (;('\0' != s1) && ('\0' !=  *s2);s1++,s2++)
  58.         {
  59.             if(isalpha(*s1) && isalpha(*s2))
  60.             {
  61.                 if(tolower(*s1) != tolower(*s2))
  62.                 {
  63.                     return(1);
  64.                 }
  65.             }
  66.             else
  67.             {
  68.                 if(*s1!=*s2)
  69.                 {
  70.                     return(1);
  71.                 }
  72.             }
  73.         }
  74.         return(*s1 != *s2);
  75.     }
  76.     else
  77.     {
  78.         return(strcmp(s1,s2));
  79.     }
  80. }
  81.  
  82.  
  83. /*
  84. **    routine to compare two tokens
  85. */
  86. static int
  87. _X_cmptokens(p1,p2,flags)
  88. K_token p1, p2;
  89. int flags;
  90. {
  91.     if (K_gettype(p1) !=  K_gettype(p2))
  92.     {
  93.         return(1);
  94.     }
  95.  
  96.     switch (K_gettype(p1))
  97.     {
  98.         case K_LIT:
  99.             return(_X_strcmp(K_gettext(p1),K_gettext(p2),flags));
  100.         case K_FLO_NUM:
  101.             return(_X_floatdiff(K_getfloat(p1),
  102.                        K_getfloat(p2),
  103.                        T_picktol(K_gettol(p1),
  104.                              K_gettol(p2))));
  105.         default:
  106.             Z_fatal("fell off switch in _X_cmptokens");
  107.             return(-1);    /* Z_fatal never returns, but i need a this line
  108.                         here to stop lint from complaining */
  109.     }
  110.  
  111. }
  112.  
  113. /*
  114. **    compare two F_floats using a tolerance
  115. */
  116. static int
  117. _X_floatdiff(p1,p2,the_tol)
  118. F_float p1,p2;
  119. T_tol the_tol;
  120. {
  121.     F_float diff, float_tmp;
  122.     T_tol tol_tmp;
  123.  
  124.     /*
  125.     **     check for null tolerance list
  126.     */
  127.     if (T_isnull(the_tol))
  128.     {
  129.         Z_fatal("_X_floatdiff called with a null tolerance");
  130.     }
  131.  
  132.     /*
  133.     **    look for an easy answer. i.e -- check
  134.     **        to see if any of the tolerances are of type T_IGNORE
  135.     **        or if the numbers are too small to exceed an absolute
  136.     **        tolerance.
  137.     **        if so, return immediately
  138.     */
  139.     for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp))
  140.     {
  141.         if ((T_IGNORE == T_gettype(tol_tmp)) || 
  142.             /*
  143.             **    take a look at the exponents before you bother
  144.             **    with the mantissas
  145.             */
  146.             ((T_ABSOLUTE == T_gettype(tol_tmp))
  147.                    && !F_zerofloat(T_getfloat(tol_tmp))
  148.                    && (F_getexp(p1) <
  149.                     F_getexp(T_getfloat(tol_tmp))-1)
  150.                    && (F_getexp(p2) <
  151.                     F_getexp(T_getfloat(tol_tmp))-1)))
  152.         {
  153.                 return(0);
  154.         }
  155.     }
  156.  
  157.     
  158.     /*
  159.     **    ok, we're going to have to do some arithmetic, so
  160.     **        first find the magnitude of the difference
  161.     */
  162.     if (F_getsign(p1) != F_getsign(p2))
  163.     {
  164.         diff = F_floatmagadd(p1,p2);
  165.     }
  166.     else
  167.     {
  168.         diff = F_floatsub(p1,p2);
  169.     }
  170.  
  171.     /*
  172.     **    now check to see if the difference exceeds any tolerance
  173.     */
  174.     for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp))
  175.     {
  176.         float_tmp = T_getfloat(tol_tmp);
  177.  
  178.         if (T_gettype(tol_tmp) == T_ABSOLUTE)
  179.         {
  180.             /* do nothing */
  181.         }
  182.         else if (T_gettype(tol_tmp) == T_RELATIVE)
  183.         {
  184.             if (F_floatcmp(p1,p2) > 0)
  185.             {
  186.                 float_tmp = F_floatmul(p1, float_tmp);
  187.             }
  188.             else
  189.             {
  190.                 float_tmp = F_floatmul(p2, float_tmp);
  191.             }
  192.         }
  193.         else
  194.         {
  195.             Z_fatal("bad value for type of tolerance in floatdiff");
  196.         }
  197.         /*
  198.         **    if we pass this tolerance, then we're done
  199.         */
  200.         if (F_floatcmp(diff,float_tmp) <= 0)
  201.         {
  202.             return(0);
  203.         }
  204.     }
  205.     /*
  206.     **    all of the tolerances were exceeded
  207.     */
  208.     return(1);
  209. }
  210.