/*----------------------------------------* | File: ERROR.c - MLO 900131 V1.00 | | These routines perform error handling | | for mathematical errors, as described | | in the Lattice C library reference | | manual; AND set MathError to True, | | displaying a requester about the error | *----------------------------------------*/ #include "rpn.h" #include "herror.h" #include #include #include extern int errno; extern int _FPERR; extern int (*_SIGFPE)(); extern Boolean MathError; extern struct Window *Wrpn; static void display(char *pc1, char *pc2); int matherr( struct exception *x ) {/*------------------------------------* | Error from high-level mathematical | | functions. Determines the routine | | name and the error type, then | | displays a requester. | *------------------------------------*/ char slate[SLATE_DIM]; sprintf(slate, "routine \"%s\"", x->name); switch (x->type) { case DOMAIN: errno = EDOM; display(slate, "(domain error)"); break; case SING: errno = EDOM; display(slate, "(singularity)"); break; case OVERFLOW: errno = ERANGE; display(slate, "(floating overflow)"); break; case UNDERFLOW: errno = ERANGE; display(slate, "(floating underflow)"); break; case TLOSS: errno = ERANGE; display(slate, "(total loss of significance)"); break; case PLOSS: errno = ERANGE; display(slate, "(partial loss of significance)"); break; default: errno = ERANGE; display(slate, NULL); break; } return 0; } void __stdargs CXFERR( int code ) {/*-------------------------------------------------------* | Error from low-level floating point operations. | | Determines the error type, then displays a requester. | *-------------------------------------------------------*/ static char llfp[] = "low-level floating operation"; _FPERR = code; if ((void *) _SIGFPE != (void *) SIG_DFL && (void *) _SIGFPE != (void *) SIG_IGN) (*_SIGFPE)(SIGFPE); switch (code) { case FPEUND: display(llfp, "(floating underflow)"); break; case FPEOVF: display(llfp, "(floating overflow)"); break; case FPEZDV: display(llfp, "(division by zero)"); break; case FPENAN: display(llfp, "(not a number)"); break; case FPECOM: display(llfp, "(not comparable)"); break; default: display(llfp, NULL); break; } } static void display( char *pc1, /* First line to be displayed */ char *pc2 /* Second line, or NULL */ ) {/*---------------------------------------------* | Local function. Displays the requester with | | an header followed by the given text. Also | | sets to True the global variable MathError. | *---------------------------------------------*/ struct IntuiText IT3 = { BLUE_PEN, WHITE_PEN, JAM2, IT3X, IT3Y, NULL, NULL, NULL }; struct IntuiText IT2 = { BLUE_PEN, WHITE_PEN, JAM2, IT2X, IT2Y, NULL, NULL, NULL }; struct IntuiText IT1 = { BLUE_PEN, WHITE_PEN, JAM2, IT1X, IT1Y, NULL, "Mathematical error in", NULL }; struct IntuiText ITOK = { BLUE_PEN, WHITE_PEN, JAM2, ITOKX, ITOKY, NULL, "OK", NULL }; IT1.NextText = &IT2; IT2.IText = pc1; if (pc2 != NULL) { IT3.IText = pc2; IT2.NextText = &IT3; } else { IT2.NextText = NULL; } AutoRequest(Wrpn, &IT1, NULL, &ITOK, 0, 0, ITWID, ITHEI); MathError = True; }