/* * Exception * Handles odd errors in Steel programs * * 1.00 (24 September 1993) * * © 1993-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Steel library. * * Steel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * Steel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Steel. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "msgs.h" #include "exception.h" #include "wimpt.h" #include "werr.h" #include "visdelay.h" #ifndef BOOL #define BOOL int #define TRUE 1 #define FALSE 0 #endif static BOOL exception__handled; static int *exception__handler; /* * int exception_registerHandler(exception_handler env) * * Use * Registers the current point as being a sensible place to go after an * exception. This is implemented as a macro for the simple reason that * things tend to go a tad wrong if you define your exception_handlers in a * function and then return. * * Parameters * exception_handler env == an undefined variable of the type * exception_handler. */ #ifndef exception_registerHandler #define exception_registerHandler(env) \ (exception__registerHandler((env),setjmp(env))) #endif /* * void exception_generate(char *message,...) * * Use * Generates a Steel exception, to be handled in an appropriate manner. * * Parameters * char *message == printf()-type format string */ void exception_generate(char *message,...) { char buffer[256]; va_list ap; va_start(ap,message); vsprintf(buffer,message,ap); va_end(ap); visdelay_suspend(); /* It doesn't mind if we suspend indefinitely */ if (exception__handled==FALSE) { werr(FALSE,msgs_lookup("excFATAL:Fatal internal error: '%s'"),buffer); exit(1); } else { if (werr_error((wimpt_options() & wimpt_ONOBACKTRACE) ? 2 : 3, msgs_lookup("excSEV:Internal error: '%s'. Click OK " "to continue, or Cancel to quit %s."), buffer, wimpt_programname())==0) { if (werr_error(2, msgs_lookup("excAYS:Are you sure you want to quit %s? " "Click OK to continue, or Cancel to quit."), wimpt_programname())==0) { exit(1); } else longjmp(exception__handler,1); } else longjmp(exception__handler,1); } } /* * int exception__registerHandler(jmp_buf handler) * * Use * This routine is for the use of exception segment only, and should not be * called from your code. */ int exception__registerHandler(jmp_buf handler,int result) { if (result==0) { exception__handled=TRUE; exception__handler=handler; } return (result); }