/*****************************************************************************
*   "Irit" - the 3d polygonal solid modeller.				     *
*									     *
* Written by:  Gershon Elber				Ver 0.2, Mar. 1990   *
******************************************************************************
* Module to handle floating point errors:				     *
*****************************************************************************/

#ifdef __MSDOS__
#include <graphics.h>
#include <float.h>
#endif /* __MSDOS__ */

#include <math.h>
#include <string.h>
#include <stdio.h>
#include "program.h"
#include "windowsg.h"

#ifndef __MSDOS__
#include "xgraphic.h"
#endif /* __MSDOS__ */

static int MathErrorNum = 0;
static char MathErrorFunc[LINE_LEN] = "";

#ifdef __MSDOS__

/*****************************************************************************
* Routine to trap math errors -	set GlobalMathError to error number, and     *
* GlobalMathFunc to the	math function with the error. Return TRUE to	     *
* make it believe that everything is ok. now...				     *
*****************************************************************************/
int matherr(struct exception *except)
{
    strcpy(MathErrorFunc, except -> name);
    MathErrorNum = except -> type;
    except -> retval = 1.0;		   /* return something reasonable... */

    return TRUE;
}

#endif /* __MSDOS__ */

/*****************************************************************************
* Routine to return last floating point (function) error if was one:	     *
*****************************************************************************/
int MathError(char **FuncName)
{
    int Temp;

    *FuncName = MathErrorFunc;

    Temp = MathErrorNum;
    MathErrorNum = 0;
    return Temp;
}

/*****************************************************************************
* Routine to print lower level floating point error message.		     *
* This routine should be called by SIGFPE signal trapping handler.	     *
*****************************************************************************/
void PrintFPError(int Type)
{
    char s[LINE_LEN];

    strcpy(s, "Fatal Floating Point Error: ");

    switch (Type) {
#ifdef __MSDOS__
	case FPE_INTOVFLOW:
	    strcat(s, "integer overflow");
	    break;
	case FPE_INTDIV0:
	    strcat(s, "integer divide by zero");
	    break;
	case FPE_INVALID:
	    strcat(s, "invalid operation");
	    break;
	case FPE_ZERODIVIDE:
	    strcat(s, "division by zero");
	    break;
	case FPE_OVERFLOW:
	    strcat(s, "numeric overflow");
	    break;
	case FPE_UNDERFLOW:
	    strcat(s, "numeric underflow");
	    break;
	case FPE_INEXACT:
	    strcat(s, "precision lost");
	    break;
	case FPE_EXPLICITGEN:
	    strcat(s, "explicit signal");
	    break;
#endif /* __MSDOS__ */
	default:
	    strcat(s, "Undefined error");
	    break;
    }

    WndwInputWindowPutStr(s, RED);
}
