home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / irit / drawfuns.arc / MATHERR.C < prev    next >
Text File  |  1989-08-02  |  5KB  |  168 lines

  1. /*****************************************************************************
  2. * Module to handle floating point errors:                     *
  3. * Action taken in floating point error is set via the Action selected during *
  4. * set up (see MathErr.h for different possible actions).             *
  5. *                                         *
  6. * Written by:  Gershon Elber            IBM PC Ver 1.0,    Mar. 1989    *
  7. *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include <string.h>
  12. #include <float.h>
  13. #include <signal.h>
  14. #include <setjmp.h>
  15. #include <graphics.h>
  16. #include "MathErr.h"
  17. #include "Program.h"
  18.  
  19. #ifdef HAS_GRAPHICS
  20. #include "GraphGnG.h"
  21. #endif HAS_GRAPHICS
  22.  
  23. #ifndef TRUE
  24. #define TRUE    -1
  25. #define FALSE    0
  26. #endif TRUE
  27.  
  28. static char *MathError = NULL;
  29. static int MEAction = ME_IGNORE;
  30. static void far *MEAddr = NULL;
  31.  
  32. static void PerformMEAction(void);
  33. static void DefaultFPEHandler(int Sig, int Type, int *RegList);
  34.  
  35. /*****************************************************************************
  36. *   Routine to set up the math error traping routines:                 *
  37. * 1. redefine matherr routine, so it traps the floating points transadental  *
  38. *    functions (sin, cos, log etc.).                         *
  39. * 2. Traps and SIGFPE signals into our handler (traps lower level errors     *
  40. *    such as div by zero).                             *
  41. *****************************************************************************/
  42. void MathErrorSetUp(int Action, void far *Addr)
  43. {
  44.     signal(SIGFPE, DefaultFPEHandler);      /* Will trap floating point errors */
  45.     MEAction = Action;
  46.     MEAddr = Addr;
  47. }
  48.  
  49. /*****************************************************************************
  50. *   Routine to fetch last math error if was was or NULL otherwise and reset  *
  51. * it to the next time...                             *
  52. *****************************************************************************/
  53. char *MathErrorGet(void)
  54. {
  55.     char *p;
  56.  
  57.     p = MathError;
  58.     MathError = NULL;
  59.     return p;
  60. }
  61.  
  62. /*****************************************************************************
  63. *   Routine to kill current process after closing all open devices and         *
  64. * printing exact math error causing this death.                     *
  65. *****************************************************************************/
  66. static void PerformMEAction(void)
  67. {
  68.     void (far *PFunc)();
  69.  
  70.     switch (MEAction) {
  71.     case ME_KILL:
  72. #        ifdef HAS_GRAPHICS
  73.         GGCloseGraph();             /* Close the graphic driver */
  74. #        endif HAS_GRAPHICS
  75.         fprintf(stderr, "Fatal Math Error - %s\n", MathError);
  76.         MyExit(1);
  77.         break;
  78.     case ME_IGNORE:
  79.         break;
  80.     case ME_LONGJMP:
  81.         longjmp(*(((jmp_buf *) MEAddr)), 1);
  82.         break;
  83.     case ME_CALL:
  84.         PFunc = MEAddr;
  85.         (PFunc)();
  86.         break;
  87.     }
  88. }
  89.  
  90. /*****************************************************************************
  91. *   Routine that is called from the floating point package in case of fatal  *
  92. * floating point error. Print error message, long jump to main loop. Default *
  93. * FPE handler - must be reset after redirected to other module.             *
  94. *****************************************************************************/
  95. static void DefaultFPEHandler(int Sig, int Type, int *RegList)
  96. {
  97.     switch (Type) {
  98.     case FPE_INTOVFLOW:
  99.         MathError = "integer overflow";
  100.         break;
  101.     case FPE_INTDIV0:
  102.         MathError = "integer divide by zero";
  103.         break;
  104.     case FPE_INVALID:
  105.         MathError = "invalid operation";
  106.         break;
  107.     case FPE_ZERODIVIDE:
  108.         MathError = "division by zero";
  109.         break;
  110.     case FPE_OVERFLOW:
  111.         MathError = "numeric overflow";
  112.         break;
  113.     case FPE_UNDERFLOW:
  114.         MathError = "numeric underflow";
  115.         break;
  116.     case FPE_INEXACT:
  117.         MathError = "precision lost";
  118.         break;
  119.     case FPE_EXPLICITGEN:
  120.         MathError = "explicit signal";
  121.         break;
  122.     }
  123.     PerformMEAction();
  124. }
  125.  
  126. /*****************************************************************************
  127. * Routine to trap math errors -    set GlobalMathError to error number, and     *
  128. * GlobalMathFunc to the    math function with the error. Return TRUE to         *
  129. * make it believe that everything is ok. now...                     *
  130. *****************************************************************************/
  131. int matherr(except)
  132. struct exception *except;
  133. {
  134.     static char s[32];
  135.  
  136.     except -> retval = 1.0;           /* return something reasonable... */
  137.  
  138.     switch(except -> type) {
  139.     case DOMAIN:
  140.         strcpy(s, "DOMAIN ");
  141.         break;
  142.     case SING:
  143.         strcpy(s, "SING ");
  144.         break;
  145.     case OVERFLOW:
  146.         strcpy(s, "O.F. ");
  147.         break;
  148.     case UNDERFLOW:
  149.         strcpy(s, "U.F. ");
  150.         break;
  151.     case TLOSS:
  152.         strcpy(s, "TLOSS ");
  153.         break;
  154.     default:
  155.         strcpy(s, "Undef. ");
  156.         break;
  157.     }
  158.     strcat(s, "err, func. ");
  159.     strcat(s, except -> name);
  160.  
  161.     MathError = s;
  162.  
  163.     PerformMEAction();
  164.  
  165.     return TRUE;
  166. }
  167. 
  168.