home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / MAWK113.ZIP / mawk113 / matherr.c < prev    next >
C/C++ Source or Header  |  1992-03-31  |  3KB  |  189 lines

  1.  
  2. /********************************************
  3. matherr.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /*$Log: matherr.c,v $
  14.  * Revision 5.2  1992/03/31  16:14:44  brennan
  15.  * patch2:
  16.  * TURN_ON_FPE_TRAPS() macro
  17.  * USE_IEEEFP_H macro
  18.  *
  19.  * Revision 5.1  91/12/05  07:56:18  brennan
  20.  * 1.1 pre-release
  21.  * 
  22. */
  23.  
  24. #include  "mawk.h"
  25. #include  <math.h>
  26.  
  27. #ifdef  USE_IEEEFP_H
  28. #include <ieeefp.h>
  29. #endif
  30.  
  31. #if   FPE_TRAPS_ON
  32. #include <signal.h>
  33.  
  34. /* machine dependent changes might be needed here */
  35.  
  36. static void  fpe_catch( signal, why)
  37.   int signal, why ;
  38. {
  39.  
  40. #if   NOINFO_SIGFPE
  41.  /* some systems give no hook to find out what the exception
  42.     was -- stuff like this is why people still use fortran 
  43.  
  44.     If this fits, #define NOINFO_SIGFPE 1 in  your config.h
  45. */
  46.   rt_error("floating point exception, probably overflow") ;
  47. #else
  48.  
  49.   switch(why)
  50.   {
  51.     case FPE_ZERODIVIDE :
  52.        rt_error("division by zero") ;
  53.  
  54.     case FPE_OVERFLOW  :
  55.        rt_error("floating point overflow") ;
  56.  
  57.     default :
  58.       rt_error("floating point exception") ;
  59.   }
  60. #endif  
  61. }
  62.  
  63. void   fpe_init()
  64.   TURN_ON_FPE_TRAPS() ;
  65.   (void) signal(SIGFPE, fpe_catch) ; 
  66. }
  67.  
  68. #else  /* FPE_TRAPS_ON==0 */
  69.  
  70. void  fpe_init()
  71. {
  72.   TURN_OFF_FPE_TRAPS() ;
  73. }
  74. #endif
  75.  
  76. #if  HAVE_MATHERR
  77.  
  78. #if  ! FPE_TRAPS_ON
  79.  
  80. /* If we are not trapping math errors, we will shutup the library calls
  81. */
  82.  
  83. int  matherr( e )
  84.   struct exception *e ;
  85. { return 1 ; } 
  86.  
  87. #else   /* print error message and exit */
  88.  
  89. int matherr( e )
  90.   struct exception  *e ;
  91. { char *error ;
  92.  
  93.   switch( e->type )
  94.   {
  95.     case  DOMAIN :
  96.     case  SING :
  97.             error = "domain error" ;
  98.             break ;
  99.  
  100.     case  OVERFLOW :
  101.             error = "overflow" ;
  102.             break ;
  103.  
  104.     case  TLOSS :
  105.     case  PLOSS :
  106.             error = "loss of significance" ;
  107.             break ;
  108.  
  109.     case  UNDERFLOW :
  110.             e->retval = 0.0 ;
  111.             return  1 ;  /* ignore it */
  112.   }
  113.  
  114.   if ( strcmp(e->name, "atan2") == 0 )
  115.       rt_error("atan2(%g,%g) : %s" ,
  116.          e->arg1, e->arg2, error ) ;
  117.   else
  118.       rt_error("%s(%g) : %s" , e->name, e->arg1, error) ;
  119.  
  120.   /* won't get here */
  121.   return 0 ;
  122. }
  123. #endif   /* FPE_TRAPS */
  124.  
  125. #endif   /*  HAVE_MATHERR */
  126.  
  127.  
  128. /* this is how one gets the libm calls to do the right
  129. thing on bsd43_vax
  130. */
  131.  
  132. #ifdef   BSD43_VAX
  133.  
  134. #include <errno.h>
  135.  
  136. double infnan( arg )
  137.   int arg ;
  138. {
  139.   switch(arg)
  140.   {
  141.     case  ERANGE : errno = ERANGE ; return HUGE ;
  142.     case -ERANGE : errno = EDOM ; return -HUGE ;
  143.     default :  errno = EDOM ; 
  144.   }
  145.   return 0.0 ;
  146. }
  147.  
  148. #endif  /* BSD43_VAX */
  149.  
  150. /* This routine is for XENIX-68K 2.3A.
  151.     Error check routine to be called after fp arithmetic.
  152. */
  153.  
  154. #if SW_FP_CHECK
  155. /* Definitions of bit values in iserr() return value */
  156.  
  157. #define OVFLOW        2
  158. #define UFLOW        4
  159. #define ZERODIV        8
  160. #define OVFLFIX        32
  161. #define INFNAN        64
  162.  
  163. void
  164. fpcheck()
  165. {
  166.     register int fperrval ;
  167.     char *errdesc ;
  168.  
  169.     if ((fperrval = iserr()) == 0)
  170.         return ;    /* no error */
  171.  
  172.     errdesc = (char *) 0 ;
  173.  
  174.     if (fperrval & INFNAN)
  175.         errdesc = "arg is infinity or NAN" ;
  176.     else if (fperrval & ZERODIV)
  177.         errdesc = "division by zero" ;
  178.     else if (fperrval & OVFLOW)
  179.         errdesc = "overflow" ;
  180.     else if (fperrval & UFLOW)
  181.         ;        /* ignored */
  182.  
  183.     if (errdesc)
  184.         rt_error("%s", errdesc) ;
  185. }
  186.  
  187. #endif
  188.